I'm writing a script that creates lots of cylinders, between points in space. As far as I can tell, Lofts are the way to go for this. I have code that works, but it gets incredibly slow - I can make 10 cylinders no problem, but when I try to make 30, it hangs for several minutes. Is this just poor API performance? Is there a more efficient way to make cylinders?
def create_bond(rootComp,bond,r): start = bond.start.get_point() end = bond.end.get_point() # Create sketch #p = adsk.core.Plane.create(bond.start.get_point(), bond.start.get_point().vectorTo(bond.end.get_point())) planes = rootComp.constructionPlanes planeInput = planes.createInput() line_sketch = rootComp.sketches.add(rootComp.xYConstructionPlane) # Draw a line to use as the axis of revolution. lines = line_sketch.sketchCurves.sketchLines line = lines.addByTwoPoints(start, end) # Create a path and let it find connected curves automatically path = rootComp.features.createPath(line) planeInput = rootComp.constructionPlanes.createInput() # you could also specify the occurrence in the parameter list planeInput.setByDistanceOnPath(path, adsk.core.ValueInput.createByReal(0)) plane1 = rootComp.constructionPlanes.add(planeInput) sketch1 = rootComp.sketches.add(plane1) circles = sketch1.sketchCurves.sketchCircles circle1 = circles.addByCenterRadius(adsk.core.Point3D.create(0, 0, 0), r) # Create the End Loft Sketch Profile planeInput.setByDistanceOnPath(path, adsk.core.ValueInput.createByReal(1)) plane2 = rootComp.constructionPlanes.add(planeInput) sketch2 = rootComp.sketches.add(plane2) circles = sketch2.sketchCurves.sketchCircles skPosition = sketch2.modelToSketchSpace(end) circle2 = circles.addByCenterRadius(skPosition, r) profile0 = sketch1.profiles.item(0) profile1 = sketch2.profiles.item(0) # Create loft feature input loftFeats = rootComp.features.loftFeatures loftInput = loftFeats.createInput(adsk.fusion.FeatureOperations.NewBodyFeatureOperation) loftSectionsObj = loftInput.loftSections loftSectionsObj.add(profile0) loftSectionsObj.add(profile1) loftInput.isSolid = False try: # Create loft feature loftFeats.add(loftInput) except: print("couldn't loft {} to {}".format(bond.start, bond.end)) #print(traceback.format_exc())
Solved! Go to Solution.
Solved by ekinsb. Go to Solution.
I'm not seeing as drastic a difference in time when creating a small number of cylinders like you said. Using your code, it's taking me 0.73 seconds to create 10 and 11.59 seconds to create 50. It does get slower with each cylinder because it takes 65.55 seconds to create 100 cylinders. There are a couple of things you can do to improve the performance. The first is that instead of using a loft you can create an extrusion. In your example you end up with the same geometry. By switching to extrusions I was able to reduce the time for 100 cylinders from 65.55 to 24.8 seconds.
The second thing that you can do, but it will depend on if you require a parametric model as a result or not, is to turn off parametrics for your design. You do this by clicking the gear in the lower-right corner of the Fusion window and selecting "Do not capture design history". When I did this when creating lofts I could create 100 cylinders in 1.84 seconds. Switching to extrusions reduced it to 0.78 seconds. 500 cylinders took 18.65 seconds.
Below is the equivalent of your function where I'm creating extrusions. It's also using functionality that requires that the model not be parametric (it's creating a construction plane at an arbitrary location in space). The start and end parameters are Point3D objects.
def create_bond2(rootComp,start,end,r): planes = rootComp.constructionPlanes planeInput = adsk.fusion.ConstructionPlaneInput.cast(planes.createInput()) planeInput.setByPlane(adsk.core.Plane.create(start, start.vectorTo(end))) plane1 = rootComp.constructionPlanes.add(planeInput) sketch1 = rootComp.sketches.add(plane1) circles = sketch1.sketchCurves.sketchCircles circle1 = circles.addByCenterRadius(adsk.core.Point3D.create(0, 0, 0), r) # Create the End Loft Sketch Profile profile0 = sketch1.profiles.item(0) # Create loft feature input extFeats = adsk.fusion.ExtrudeFeatures.cast(rootComp.features.extrudeFeatures) dist = adsk.core.ValueInput.createByReal(start.distanceTo(end)) extInput = extFeats.createInput(profile0, adsk.fusion.FeatureOperations.NewBodyFeatureOperation) extInput.setOneSideExtent(adsk.fusion.DistanceExtentDefinition.create(dist), adsk.fusion.ExtentDirections.PositiveExtentDirection) extInput.isSolid = False try: # Create extrude feature extFeats.add(extInput) except: _ui.messageBox("couldn't extrude {} to {}".format(start, end)) #print(traceback.format_exc())
It does seem like the parametric modeling should have better performance than it does. I'll log defect and see if the modeling team can take a look.