Detect Coplanar Faces

Detect Coplanar Faces

TrademarkCreative
Enthusiast Enthusiast
2,521 Views
10 Replies
Message 1 of 11

Detect Coplanar Faces

TrademarkCreative
Enthusiast
Enthusiast

I've seen this topic come up a few times, but as of yet there's no great solution. 

 

Essentially, when one imports a mesh from another program Fusion breaks it up into triangles, even if the mesh had nice big flat areas and rectangles. Thus, steps need to be taken to get those large flat areas and rectangle back.

 

Some of the steps suggested elsewhere are to 'Merge' the faces. (my experience was that 'merging' made my faces curved and thus unusable). Other suggestions were to simply delete faces, where by Fusion automatically heals the face, and thus regains the planar rectangles.

Both of these are time consuming, and an automatic solutions is desired.

 

In leu of a fully automatic solution, one thing that would help this process is simply a visual indication that the faces are coplanar.

 

Is there a script I can run on a body that colors the faces of body, such that faces that are coplanar are the same color? 

 

Zebra Analysis gets really close, but I'm not convinced it's worried about the same things I am.

 

I have attached a sample file that has a bunch of coplanar faces, which are broken into triangle by the Fusion import. 

 

Thoughts? Is there a way to do this?

 

 

 

 

 

 

Accepted solutions (2)
2,522 Views
10 Replies
Replies (10)
Message 2 of 11

kandennti
Mentor
Mentor
Accepted solution

Hi @TrademarkCreative .

 

I think when you work with meshes in Fusion360, they are automatically split into triangles because they are triangle meshes, except for the T-splines.

 

 

If the data does not contain any curved surfaces, as in this case, the tangentiallyConnectedFaces property may be used.

 

I found the theme interesting, so I made a script that changes the color of the surfaces on the same plane to the same color when the body is selected.

# Fusion360API Python script
import adsk.core, adsk.fusion, traceback
import random

def run(context):
    ui = adsk.core.UserInterface.cast(None)
    try:
        app :adsk.fusion.Application = adsk.core.Application.get()
        ui = app.userInterface

        # Select BrepBody
        msg :str = 'Select BRepBody'
        selFiltter :str = 'Bodies'
        sel :adsk.core.Selection = selectEnt(msg ,selFiltter)
        if not sel: return

        body :adsk.fusion.BRepBody = sel.entity

        # Get faceGroup
        faceGroup = groupByFlattenSurfaces(body)

        # Change Color
        vp :adsk.core.Viewport = app.activeViewport
        for faces in faceGroup:
            appearance = getUniqueColor()
            for face in faces:
                face.appearance = appearance
            vp.refresh()
            adsk.doEvents()

        ui.messageBox('Done')

    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

def generate_random_color():
    return [random.randint(0, 255) for _ in range(3)]

def getUniqueColor() -> adsk.core.Appearance:
    app :adsk.fusion.Application = adsk.core.Application.get()
    des :adsk.fusion.Design = app.activeProduct
    base :adsk.core.Appearance = des.appearances[0]

    while True:
        rgb = generate_random_color()
        name = '#{:X}{:X}{:X}'.format(*rgb)
        if not des.appearances.itemByName(name):
            appearance :adsk.core.Appearance = des.appearances.addByCopy(base, name)
            colorProp = appearance.appearanceProperties.itemById('surface_albedo')
            colorProp.value = adsk.core.Color.create(rgb[0], rgb[1], rgb[2], 255)
            return appearance

def groupByFlattenSurfaces(
    body :adsk.fusion.BRepBody) -> List:

    adsk.fusion.BRepFace.registerGroup = False

    flattenGroups = []
    for face in body.faces:
        if face.registerGroup:
            continue
        lst =[face]
        lst.extend([surf for surf in face.tangentiallyConnectedFaces])
        for surf in lst:
            if surf.registerGroup:
                print('Hit')
            surf.registerGroup = True
        flattenGroups.append(lst)

    return flattenGroups

def selectEnt(
        msg :str, 
        filtterStr :str) -> adsk.core.Selection :

    try:
        app = adsk.core.Application.get()
        ui = app.userInterface
        sel = ui.selectEntity(msg, filtterStr)
        return sel
    except:
        return None

1.png

I haven't tested it in detail, but I think it probably handles it correctly.
The colors are applied randomly, so there is a possibility that some colors are very close to each other.

 

If you use "the Four Color Theorem", you may only need four colors, but I don't understand it.

Message 3 of 11

TrademarkCreative
Enthusiast
Enthusiast

This is AMAZING.
But I'm getting errors when I try to run it.
Here's the error

Failed:

Traceback (most recent call last):

File "C:/Users/simon/AppData/Roaming/Autodesk/Autodesk Fusion 360/API/Scripts/CoplanarColor/CoplanarColor.py", line 15, in run

sel :adsk.core.Selection = selectEnt(msg ,selFiltter)

NameError: name 'selectEnt' is not defined

 

The way I tried to get this to work was : 

Go into Add-ins, created a new script, copy and pasted in your code, tried to run it.

What did I miss?

0 Likes
Message 4 of 11

nnikbin
Collaborator
Collaborator

I encountered the same error. I think it is related to supporting type hints in different python versions but I am not sure.

 

Doing one of the following solved the problem:

 

removing  "-> List" from line 56

 
 

or adding the following line after import statements at top of the script:

from typing import List
0 Likes
Message 5 of 11

TrademarkCreative
Enthusiast
Enthusiast

Wow! That worked. 

This is a truly beautiful script to watch color in a model. 

Let me play with this some more, but I think we're close to an accepted solution.

 

0 Likes
Message 6 of 11

nnikbin
Collaborator
Collaborator
Accepted solution

@TrademarkCreative , to simplify your workflow, I created a simple add-in (the attached file) for expanding the selection of the first selected face to adjacent tangent faces. It adds a button to SELECT panel. After running @kandennti code you can use this add-in.

Message 7 of 11

TrademarkCreative
Enthusiast
Enthusiast

AWESOME! Thank you for all the attention to this weird ask.

0 Likes
Message 8 of 11

nnikbin
Collaborator
Collaborator

Hi @TrademarkCreative 

I think the solution to your post is actually provided by @kandennti , but you have marked my reply as the solution. I would appreciate it if you choose @kandennti's main answer as the solution.

Message 9 of 11

TrademarkCreative
Enthusiast
Enthusiast

Sorry, of course. It's just that you both did work to make it happen. Thank you! 

Message 10 of 11

kandennti
Mentor
Mentor
Message 11 of 11

Swarm23
Participant
Participant

Hello, can you please show a demonstration of how to work with the scripts? Thank you very much!

0 Likes