#Author-Autodesk Inc. #Description-Caculate the intersections between the selected curve/surface/body/component/occurrence and curve/surface. # non planar surface does not support for now import adsk.core, adsk.fusion, traceback import os pi = 3.1415926 nearZero = 0.000001 # global set of event handlers to keep them referenced for the duration of the command handlers = [] app = adsk.core.Application.get() if app: ui = app.userInterface class IntersectionCommandExecuteHandler(adsk.core.CommandEventHandler): def __init__(self): super().__init__() def notify(self, args): try: command = args.firingEvent.sender inputs = command.commandInputs input0 = inputs[0]; sel0 = input0.selection(0); input1 = inputs[1]; sel1 = input1.selection(0); intersections = Intersections(); intersections.Execute(sel0.entity, sel1.entity); except: if ui: ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) class IntersectionCommandDestroyHandler(adsk.core.CommandEventHandler): def __init__(self): super().__init__() def notify(self, args): try: # when the command is done, terminate the script # this will release all globals which will remove all event handlers adsk.terminate() except: if ui: ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) class IntersectionValidateInputHandler(adsk.core.ValidateInputsEventHandler): def __init__(self): super().__init__() def notify(self, args): try: sels = ui.activeSelections; if len(sels) == 2: args.areInputsValid = True else: args.areInputsValid = False except: if ui: ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) class IntersectionCommandCreatedHandler(adsk.core.CommandCreatedEventHandler): def __init__(self): super().__init__() def notify(self, args): try: cmd = args.command onExecute = IntersectionCommandExecuteHandler() cmd.execute.add(onExecute) onDestroy = IntersectionCommandDestroyHandler() cmd.destroy.add(onDestroy) onValidateInput = IntersectionValidateInputHandler() cmd.validateInputs.add(onValidateInput) # keep the handler referenced beyond this function handlers.append(onExecute) handlers.append(onDestroy) handlers.append(onValidateInput) #define the inputs inputs = cmd.commandInputs i1 = inputs.addSelectionInput('entity', 'Entity One', 'Please select a curve, planear entity or a BRepBody, Component, Occurrence') i1.addSelectionFilter(adsk.core.SelectionCommandInput.Edges); i1.addSelectionFilter(adsk.core.SelectionCommandInput.PlanarFaces); i1.addSelectionFilter(adsk.core.SelectionCommandInput.SketchCurves); i1.addSelectionFilter(adsk.core.SelectionCommandInput.ConstructionLines); i1.addSelectionFilter(adsk.core.SelectionCommandInput.ConstructionPlanes); i1.addSelectionFilter(adsk.core.SelectionCommandInput.Bodies); i1.addSelectionFilter(adsk.core.SelectionCommandInput.Occurrences); i1.addSelectionFilter(adsk.core.SelectionCommandInput.RootComponents); i2 = inputs.addSelectionInput('sectionentity', 'Entity Two', 'Please select a linear or planear entity') i2.addSelectionFilter(adsk.core.SelectionCommandInput.PlanarFaces); i2.addSelectionFilter(adsk.core.SelectionCommandInput.LinearEdges); i2.addSelectionFilter(adsk.core.SelectionCommandInput.SketchLines); i2.addSelectionFilter(adsk.core.SelectionCommandInput.ConstructionLines); i2.addSelectionFilter(adsk.core.SelectionCommandInput.ConstructionPlanes); except: if ui: ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) class Intersections: def Execute(self, entityOne, entityTwo): #caculate the intersections sectionResults = adsk.core.ObjectCollection.create() def getGeometry(entity): geom = entity if isinstance(entity, adsk.fusion.BRepFace) or \ isinstance(entity, adsk.fusion.BRepEdge) or \ isinstance(entity, adsk.fusion.ConstructionAxis) or\ isinstance(entity,adsk.fusion.ConstructionPlane): geom = entity.geometry elif isinstance(entity, adsk.fusion.SketchCurve): geom = entity.worldGeometry; return geom; def intersectWith(surfaceOrCurve, section): surfaceOrCurve = getGeometry(surfaceOrCurve) section = getGeometry(section) result = None if isinstance(surfaceOrCurve, adsk.core.Curve3D): result = section.intersectWithCurve(surfaceOrCurve) elif isinstance(section, adsk.core.Curve3D): result = surfaceOrCurve.intersectWithCurve(section) else: if surfaceOrCurve.surfaceType == adsk.core.SurfaceTypes.PlaneSurfaceType and section.surfaceType == adsk.core.SurfaceTypes.PlaneSurfaceType : result = section.intersectWithPlane(surfaceOrCurve) if result: sectionResults.add(result) return if result: for resultI in result: sectionResults.add(resultI) def intersectWithBody(body, section): fs = body.faces; for fsI in fs: intersectWith(fsI, section) def intersectWithComponent(comp, occ, section): if isinstance(comp,adsk.fusion.Component): bodies = comp.bRepBodies for body in bodies: if(not body): continue if occ : body = body.createForAssemblyContext(occ) intersectWithBody(body, section) childOccs = None if occ : childOccs = occ.childOccurrences else: childOccs = comp.occurrences for childOcc in childOccs: if not childOcc: continue intersectWithComponent(childOcc.component, childOcc, section); if isinstance(entityOne,adsk.fusion.Component): intersectWithComponent(entityOne, None, entityTwo) elif isinstance(entityOne,adsk.fusion.Occurrence): intersectWithComponent(entityOne.component, entityOne, entityTwo) elif isinstance(entityOne, adsk.fusion.BRepBody): intersectWithBody(entityOne, entityTwo) else: intersectWith(entityOne, entityTwo) if len(sectionResults) == 0: if ui: ui.messageBox('No intersection found') return def isPlanearEntity(entity): planearEnt = False if isinstance(entity, adsk.fusion.ConstructionPlane): planearEnt = True elif isinstance(entity, adsk.fusion.BRepFace): sur = entity.geometry if(sur.surfaceType == adsk.core.SurfaceTypes.PlaneSurfaceType): planearEnt = True return planearEnt doc = app.activeDocument d = doc.design rootComp = d.rootComponent sketch = None if isPlanearEntity(entityTwo): sketch = rootComp.sketches.add(entityTwo) elif isPlanearEntity(entityOne): sketch = rootComp.sketches.add(entityOne) else: sketch = rootComp.sketches.add(rootComp.xYConstructionPlane) for geom in sectionResults: if not geom or not sketch: continue m = sketch.transform m.invert() geom.transformBy(m) if isinstance(geom,adsk.core.Point3D): sketch.sketchPoints.add(geom) elif isinstance(geom,adsk.core.Curve3D): sketchCurve = None if isinstance(geom, adsk.core.Line3D): sketchCurve = sketch.sketchCurves.sketchLines.addByTwoPoints(geom.startPoint, geom.endPoint); elif isinstance(geom,adsk.core.Arc3D): sweepAngle = 2 * pi if abs(geom.endAngle - geom.startAngle) < nearZero else geom.startAngle sketchCurve = sketch.sketchCurves.sketchArcs.addByCenterStartSweep(geom.center, geom.startPoint, sweepAngle) elif isinstance(geom,adsk.core.Circle3D): sketchCurve = sketch.sketchCurves.sketchCircles.addByCenterRadius(geom.center, geom.radius) elif isinstance (geom,adsk.core.Ellipse3D): curveEva = geom.evaluator startParameter = None endParameter = None curveEva.getParameterExtents(startParameter, endParameter) pointOnCurve = None curveEva.getPointAtParameter((startParameter + endParameter)/3, pointOnCurve) majorAxisPoint = geom.center majorAxisVec = geom.majorAxis majorAxisVec.scaleBy(geom.majorRadius) majorAxisPoint.translateBy(majorAxisVec) sketchCurve = sketch.sketchCurves.sketchEllipses.add(geom.center, majorAxisPoint, pointOnCurve) elif isinstance(geom, adsk.core.NurbsCurve3D): pts = geom.controlPoints ptCol = adsk.core.ObjectCollection.create() for ptsI in pts: ptCol.add(ptsI) sketchCurve = sketch.sketchCurves.SketchFittedSplines.add(ptCol) elif isinstance(geom,adsk.core.InfiniteLine3D): start = geom.origin end = geom.origin dir = geom.direction dir.scaleBy(10) end.translateBy(dir) sketchCurve = sketch.sketchCurves.sketchLines.addByTwoPoints(start, end) if sketchCurve: sketchCurve.isConstruction = True def run(context): try: product = app.activeProduct design = adsk.fusion.Design.cast(product) if not design: ui.messageBox('It is not supported in current workspace, please change to MODEL workspace and try again.') return commandDefinitions = ui.commandDefinitions # check the command exists or not cmdDef = commandDefinitions.itemById('IntersectionCMDDef') if not cmdDef: resourceDir = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'resources') # absolute resource file path is specified cmdDef = commandDefinitions.addButtonDefinition('IntersectionCMDDef', 'Intersections', 'Calculate the intersections of two selected entities', resourceDir) onCommandCreated = IntersectionCommandCreatedHandler() cmdDef.commandCreated.add(onCommandCreated) # keep the handler referenced beyond this function handlers.append(onCommandCreated) inputs = adsk.core.NamedValues.create() cmdDef.execute(inputs) # prevent this module from being terminate when the script returns, because we are waiting for event handlers to fire adsk.autoTerminate(False) except: if ui: ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))