こちらに挑戦中です。
Polygons to circles - Autodesk Community
同様の問い合わせがあるので、需要はあるはず。
作ってみたものの、小さなデータはまぁまぁOKです。
添付されたDXFでは、殺意を覚えるぐらい遅いです・・・。
# Fusion360API Python script import traceback import adsk.fusion import adsk.core import time def run(context): ui = adsk.core.UserInterface.cast(None) try: app: adsk.fusion.Application = adsk.core.Application.get() ui = app.userInterface # select sketch msg: str = 'Select Skectch' selFiltter: str = 'Sketches,Profiles,Texts,SketchCurves,SketchLines,SketchCircles,SketchPoints' sel: adsk.core.Selection = selectEnt(msg, selFiltter) if not sel: return # get sketch selEntity = sel.entity skt: adsk.fusion.Sketch = None if selEntity.objectType == 'adsk::fusion::Sketch': skt = sel.entity else: skt = sel.entity.parentSketch # query msg = f'Process {skt.sketchCurves.sketchLines.count} lines.' msg += '\n Are you sure?' button = adsk.core.MessageBoxButtonTypes.OKCancelButtonType icon = adsk.core.MessageBoxIconTypes.QuestionIconType query = ui.messageBox(msg, 'Polygons To Circles', button, icon) if query == adsk.core.DialogResults.DialogCancel: return # time t = time.time() # Convert Polygon to Circle converts = polygons2Circles(skt) # finish msg = f'{len(converts)} circles were created.' msg += '\n({:.3f} s)'.format(time.time() - t) ui.messageBox(msg) except: if ui: ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) def polygons2Circles( skt: adsk.fusion.Sketch) -> list: # -- Support Functions -- def updeteProgress( prog: adsk.core.ProgressDialog, msg: str): prog.progressValue += 1 prog.message = f'Processing {msg} ....' adsk.doEvents() return progress.wasCancelled def execConvertCircle( lines: adsk.core.ObjectCollection): skt: adsk.fusion.Sketch = lines[0].parentSketch circle: adsk.core.Circle3D = skt.sketchCurves.sketchCircles.addByThreePoints( lines[0].startSketchPoint.geometry, lines[1].startSketchPoint.geometry, lines[2].startSketchPoint.geometry ) for line in lines: line.isConstruction = True return circle def setCheck( lst: list, value: bool = True): for c in lst: if c.objectType != 'adsk::fusion::SketchLine': continue c.isCheck = value def isClosedChainedLines( curves: adsk.core.ObjectCollection) -> bool: objs: adsk.core.ObjectCollection = adsk.core.ObjectCollection.create() for curve in curves: if curve.objectType != 'adsk::fusion::SketchLine': continue if curve.isConstruction: continue if not curve.is2D: continue objs.add(curve) path: adsk.fusion.Path = adsk.fusion.Path.create( objs, adsk.fusion.ChainedCurveOptions.noChainedCurves) return path.isClosed def isConvertCircle( lines: adsk.core.ObjectCollection, tolerance: float = 0.001) -> bool: if lines.count < 3: return False startPoints = [l.startSketchPoint.geometry for l in lines] tempCircle: adsk.core.Circle3D = adsk.core.Circle3D.createByThreePoints( startPoints[0], startPoints[1], startPoints[2] ) eva: adsk.core.CurveEvaluator3D = tempCircle.evaluator _, prms = eva.getParametersAtPoints(startPoints) _, returnPnts = eva.getPointsAtParameters(prms) for p1, p2 in zip(startPoints, returnPnts): if not p1.isEqualToByTolerance(p2, tolerance): return False return True # ----------- # extention property adsk.fusion.SketchLine.isCheck = False # ProgressDialog app: adsk.fusion.Application = adsk.core.Application.get() progress: adsk.core.ProgressDialog = app.userInterface.createProgressDialog() progress.isCancelButtonShown = True # start skt.isComputeDeferred = True converts = [] linesCount = skt.sketchCurves.sketchLines.count line: adsk.fusion.SketchLine for idx, line in enumerate(skt.sketchCurves.sketchLines): if updeteProgress(progress, f'{idx}/{linesCount}'): break adsk.doEvents() if line.isCheck: continue if line.isConstruction: continue curves: adsk.core.ObjectCollection = skt.findConnectedCurves(line) if curves.count < 3: setCheck(curves) continue if not isClosedChainedLines(curves): setCheck(curves) continue if not isConvertCircle(curves): setCheck(curves) continue converts.append(execConvertCircle(curves)) setCheck(curves) skt.isComputeDeferred = False return converts 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
途中で中止出来るように、プロセスダイアログを付けたのですが、
それすら意味を成さないぐらい。
改善の余地しかない。