Community
Fusion API and Scripts
Got a new add-in to share? Need something specialized to be scripted? Ask questions or share what you’ve discovered with the community.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

CombineFeature Error while joining multiple bReps

11 REPLIES 11
Reply
Message 1 of 12
Anonymous
1297 Views, 11 Replies

CombineFeature Error while joining multiple bReps

Hi all,

I want the API to combine multiple, in the script created bRepBodies. So far I take a bRepBody, take a temporary copy, transform it (rotation of 1°) several times, want to combine these bodies and repeat this with another bRepBody from another occurrence.

The transformation works, but in  the "combine_bodies" function an Error occurs:

ErrorMsg.PNG

For any reason the combineFeature combines all transformed bodies from the first occurrence AND the first transformed body from the second Occurrence, but the other bodies can't get combined.

comb_bodies.PNG(the selected on the right are the combined 36 bodies from the first occurrence, and the red/dark bodies are the uncombined from the second occurrence)

 

Here's the code I used:

 

### code in run:
test_occ = root.occurrences.addNewComponent(adsk.core.Matrix3D.create())
# occ_path is a list of occurrences
# j_list is a list of joints
for i in range(6):
        occ = occ_path[i].bRepBodies.item(0)    # works
        rot_axis = j_list[i].jointMotion.rotationAxisVector    # works
        rot_origin = j_list[i].geometryOrOriginOne.origin    # works
        limits = {'min':get_joint_min_value(j_list[i], True),'max':get_joint_max_value(j_list[i], True),'cur':get_joint_curr_value(j_list[i], True)}    # works
        create_rotation_brep(tmpmgr.copy(occ), rot_axis, rot_origin, limits,test_occ, i)

def create_rotation_brep(temp_brep, rot_axis, rot_origin, rot_limits:dict, test_occ, index):
    ''' rotates a brepBody in the committed borders, combines the bodys of the occurrence to one
    '''
    cnt_bodies = 36
    app = adsk.core.Application.get()
    design = adsk.fusion.Design.cast(app.activeProduct)
    design.designType = adsk.fusion.DesignTypes.DirectDesignType
    test_comp= test_occ.component
    body_coll = adsk.core.ObjectCollection.create()
    
    # rotate temp_brep to minimum value
    if not rot_limits['cur']==rot_limits['min']:
        angleDiff = rot_limits['min'] - rot_limits['cur']
        transform_brep(temp_brep, rot_axis, rot_origin, angleDiff)
    rot_angle = (rot_limits['max'] - rot_limits['min'])/cnt_bodies

    # rotate brep 
    for i in range(cnt_bodies):
        test_comp.bRepBodies.add(temp_brep)
        transform_brep(temp_brep, rot_axis, rot_origin, rot_angle)

    # # fill obj-collection with created breps in the component
    for body in test_comp.bRepBodies[1:]:
        body_coll.add(body)
    try:
        combine_bodies(test_comp.bRepBodies[index], body_coll, test_comp)
    except:
        print('Error at create_rotation_brep')

def transform_brep(brep_body, axis:adsk.core.Vector3D, origin:adsk.core.Point3D, angle = (math.pi/180)):
    ''' transforms a brep-body by an angle (default: 1°) using TemporaryBrepManager '''
    try:
        tmpmgr = adsk.fusion.TemporaryBRepManager.get()
        mat = adsk.core.Matrix3D.create()
        mat.setToRotation(angle, axis, origin)  # rotation matrix
        tmpmgr.transform(brep_body, mat)        # command to transform the body
    except:
        ui.messageBox('transform_brep error:\n {}'.format(traceback.format_exc()))

def combine_bodies(target, tool_collection, test_comp):
    ''' combines the tool_collection with the target-brep at the test_comp'''
    start_time = time.time()        # start time
    comb_feature = test_comp.features.combineFeatures
    comb_input = comb_feature.createInput(target, tool_collection)
    comb_feature.add(comb_input)
    end_time = time.time()          # end time
    elapsed_time = time.strftime('%H:%M:%S',time.gmtime(end_time-start_time))
    ui.messageBox('Elapsed Time: ' + elapsed_time)

 

 

Can anyone help me, I'm really confused of this errormessage and can't figure a solution.

 

Labels (5)
11 REPLIES 11
Message 2 of 12
kandennti
in reply to: Anonymous

Hi @Anonymous .

 

If I do the same thing with the GUI, will I get an error?

Message 3 of 12
Anonymous
in reply to: kandennti

Yes, if I try to combine the bodies with the GUI, i get the same error.

error_gui_combine.PNG

Message 4 of 12
kandennti
in reply to: Anonymous

If the shape causes an error in the GUI, I think that an error will occur in the API too.

Message 5 of 12
Anonymous
in reply to: kandennti

Thank you @kandennti,
can you imagine why this error occurs?
I rotate a body several times, save them in a component and try to combine them. So I have a clear overlap, haven't I?
@BrianEkins do you know something about this issue?
Message 6 of 12
kandennti
in reply to: Anonymous

In this attachment, I used TemporaryBRepManager to do a Union Boolean on many bodies.

https://forums.autodesk.com/t5/fusion-360-api-and-scripts/how-to-efficiently-process-10000-individua... 


Combine until an error occurs, and when an error occurs, re-execute the combine based on the new body.
The result is multiple bodies, but it doesn't stop with an error.

 

The combine error is a CAD data problem and there should be nothing that can be solved by the API.

Message 7 of 12
Anonymous
in reply to: kandennti

I tried out your unionBodies method, but I get another error and the result is also not what I wanted.

try:
                ### does not work!!!
                # coll =adsk.core.ObjectCollection.create()
                # coll.clear()
                # coll.add(tmpmgr.copy(occ))
                # combine_bodies(temp.bRepBodies.item(0), coll, temp.component)
                temp.component.bRepBodies.add(tmpmgr.copy(occ))
                unionBodies(temp.component.bRepBodies.item(0), temp.component.bRepBodies.item(1))
            except:
                print('combination Error:\n{}'.format(traceback.format_exc()))

def unionBodies(target:adsk.fusion.BRepBody, tool:adsk.fusion.BRepBody):
    ''' uses tempbRepMngr to create a UnionBody out of two bRepBodies'''
    tmpMgr = adsk.fusion.TemporaryBRepManager.get()
    unionBool = adsk.fusion.BooleanTypes.UnionBooleanType
    tmpMgr.booleanOperation(target, tool, unionBool)

Executing this results in:

tmpMgr.booleanOperation(target, tool, unionBool)

File "C:/Users/k.trucksees/AppData/Local/Autodesk/webdeploy/production/e93c21ea16478b49c4dee1f65accf1a11ae...", line 30738, in booleanOperation

return _fusion.TemporaryBRepManager_booleanOperation(self, *args)

RuntimeError: 3 : invalid argument targetBody

 

 

Message 8 of 12
kandennti
in reply to: Anonymous

I made a sample code and an f3d file.
Rotate such a FormBody to combine it.

1.png

 

#Fusion360API Python script

import adsk.core, adsk.fusion, traceback
import math

_app = adsk.core.Application.cast(None)
_ui = adsk.core.UserInterface.cast(None)

def run(context):
    try:
        global _app, _ui
        _app = adsk.core.Application.get()
        _ui = _app.userInterface
        des  :adsk.fusion.Design = _app.activeProduct
        root :adsk.fusion.Component = des.rootComponent

        # select main body
        msg :str = 'Select Body'
        selFiltter :str = 'Bodies'
        sel :adsk.core.Selection = selectEnt(msg ,selFiltter)
        if not sel: return

        # create rotation union body
        unions = initRotationUnionBodies(
            sel.entity,
            root.zConstructionAxis.geometry.direction,
            root.originConstructionPoint.geometry,
            10)

        # add bodies
        baseFeats = root.features.baseFeatures
        baseFeat = baseFeats.add()
        baseFeat.startEdit()
        for body in unions:
            root.bRepBodies.add(body, baseFeat)
        baseFeat.finishEdit()

        _ui.messageBox('Done')

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

def initRotationUnionBodies(
    mainBody :adsk.fusion.BRepBody,
    axis :adsk.core.Vector3D,
    origin :adsk.core.Point3D,
    stepAngle :int
) -> list:

    if stepAngle == 0:
        return []

    tmpMgr = adsk.fusion.TemporaryBRepManager.get()
    unionBool = adsk.fusion.BooleanTypes.UnionBooleanType

    target :adsk.fusion.BRepBody = tmpMgr.copy(mainBody)
    unions = []
    mat = adsk.core.Matrix3D.create()

    for angle in range(stepAngle, 360, stepAngle):
        # clone body
        tool :adsk.fusion.BRepBody = tmpMgr.copy(mainBody)

        # rotation body
        rad = math.radians(angle)
        mat.setToRotation(rad, axis, origin)
        tmpMgr.transform(tool, mat)

        # try union
        try:
            tmpMgr.booleanOperation(target, tool, unionBool)
        except:
            unions.append(target)
            target = tool

    unions.append(target)

    return unions


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

    try:
        sel = _ui.selectEntity(msg, filtterStr)
        return sel
    except:
        return None

 

 

It is desirable to have one body.
However, since an error occurs on the way, it is divided into two bodies and ends.

2.png

 

This is not an API issue, but a CAD data issue.

Message 9 of 12
Anonymous
in reply to: kandennti

Thank you @kandennti for your help and the sample.
Somehow the combine-feature works now.

 

When I run my code, the RAM gets heavily loaded. In my case I have one created component with one body in it, that was created by rotating and combining temporary bReps (3*36 Breps). Does anybody knows why the combining takes so long (~20min) and fills ~9GB RAM?

Message 10 of 12
kandennti
in reply to: Anonymous

I think it takes time to combine a large number of complicated bodies.
I believe the TemporaryBRepManager is the fastest for Fusion 360.

Message 11 of 12
Anonymous
in reply to: kandennti

The combination doesn´t work anymore. I have ten bodies, but cant combine them. Neither with the combine-feature nor with the tempbRepMngr.booleanOperation method.

Here´s a screenshot of my F360:

combine_error.PNG

And thats the errormessage that occurs in Code, it´s the same as before:

Traceback (most recent call last):
  File "C:/Users/k.trucksees/AppData/Roaming/Autodesk/Autodesk Fusion 360/API/Scripts/test/test.py", line 296, in check_combine
    combine_bodies(hazard.bRepBodies[1], brep_collection, hazard.component)
  File "C:/Users/k.trucksees/AppData/Roaming/Autodesk/Autodesk Fusion 360/API/Scripts/test/test.py", line 437, in combine_bodies
    comb_feature.add(comb_input)
  File "C:/Users/k.trucksees/AppData/Local/Autodesk/webdeploy/production/2952f0c515230f17ec2841ce87417c3358452c60/Api/Python/packages\adsk\fusion.py", line 10643, in add
    return _fusion.CombineFeatures_add(self, input)
RuntimeError: 5 :   There was a problem combining geometry together.
    If attempting a Join/Cut/Intersect, try to ensure that the bodies have a clear overlap (problems can occur where faces and edges are nearly coincident). / Failed to Boolean bodies together

 

Why does this happen?

Message 12 of 12
kandennti
in reply to: Anonymous

If an error occurs in the GUI, an error will occur in the API as well.

 

I don't understand English, so I hope it will be transmitted correctly.

 

You can't do it with Fusion360, but you can create a three-dimensional line when you make an intersection between bodies.
(I use other 3D CAD in my business)
If the solid body can handle Boolean operations without any problems, the lines that can be crossed should be lines that can be drawn with a single stroke writing.
In case of an error, the intersecting line is expected to be broken or pointed.
This is not an API problem and I don't think it can be solved.

 

I think only "Shape Manager" knows the real answer.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report