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:
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.
(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.
If the shape causes an error in the GUI, I think that an error will occur in the API too.
In this attachment, I used TemporaryBRepManager to do a Union Boolean on many bodies.
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.
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
I made a sample code and an f3d file.
Rotate such a FormBody to combine it.
#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.
This is not an API issue, but a CAD data issue.
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?
I think it takes time to combine a large number of complicated bodies.
I believe the TemporaryBRepManager is the fastest for Fusion 360.
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:
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?
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.