こちらの続きです。
複数面に線を描きたい5 - C#ATIA
良い方法が思い付かない為、素直に平面で交差を作り
その線を使うことにしました。・・・情けない。
一本は2点間を繋ぐ3D直線で、もう一本は3D直線と共有している
エッジの最短距離となる部分のベクトルです。
#Fusion360API Python script import adsk.core, adsk.fusion, traceback _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 # get body body :adsk.fusion.BRepBody = root.bRepBodies.item(0) # get face face1 :adsk.fusion.BRepFace = body.faces.item(0) face2 :adsk.fusion.BRepFace = body.faces.item(1) # 共有エッジ取得 shareEdges = getShareEdges(face1, face2) # get point pnt1 :adsk.fusion.ConstructionPoint = root.constructionPoints.item(1) pnt2 :adsk.fusion.ConstructionPoint = root.constructionPoints.item(0) # 直線 line :adsk.core.Line3D = adsk.core.Line3D.create(pnt1.geometry, pnt2.geometry) lineVec :adsk.core.Vector3D = pnt1.geometry.vectorTo(pnt2.geometry) # 共有エッジと直線の最短取得 - 本当は1本とは限らない mersRes :adsk.core.MeasureResults = getMinDist(line, shareEdges[0]) mersVec :adsk.core.Vector3D = mersRes.positionOne.vectorTo(mersRes.positionTwo) # 平面 plane :adsk.core.Plane = initPlane(mersRes.positionOne, mersVec, lineVec) # 交差取得 crv1 = getCurve(pnt1.geometry, shareEdges[0], plane, face1) crv2 = getCurve(pnt2.geometry, shareEdges[0], plane, face2) # add sketch skt :adsk.fusion.Sketch = root.sketches.add(root.xYConstructionPlane) skt.arePointsShown = False # 面上に線を描く drawSketch(skt, [crv1, crv2]) except: if _ui: _ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) def drawSketch( skt :adsk.fusion.Sketch, crvs :list): skt.isComputeDeferred = True sktCrvs :adsk.fusion.SketchCurves = skt.sketchCurves for crv in crvs: if hasattr(crv,'asNurbsCurve'): crv = crv.asNurbsCurve if crv.objectType == 'adsk::core::NurbsCurve3D': sktElm = sktCrvs.sketchFittedSplines.addByNurbsCurve(crv) else: s = crv.startPoint e = crv.endPoint sktElm = sktCrvs.sketchLines.addByTwoPoints(s,e) skt.isComputeDeferred = False def getCurve( pnt :adsk.core.Point3D, edge :adsk.fusion.BRepEdge, pln :adsk.core.Plane, face :adsk.fusion.BRepFace): crvs :adsk.core.ObjectCollection = getSection(pln, face) sect :adsk.core.Curve3D = crvs[0] sectEva :adsk.core.CurveEvaluator3D = sect.evaluator _, sPnt, ePnt = sectEva.getEndPoints() tgtPnts = [pnt] tgtPnts.append(sPnt if isOnCurve(edge,sPnt) else ePnt) _, prms = sectEva.getParametersAtPoints(tgtPnts) list(prms).sort() # return sect.extract(prms[0], prms[1]) # err! return sect def isOnCurve( crv :adsk.fusion.BRepEdge, pnt :adsk.core.Point3D) -> bool: eva :adsk.core.CurveEvaluator3D = crv.evaluator _, sPrm, ePrm = eva.getParameterExtents() _, prm = eva.getParameterAtPoint(pnt) return True if sPrm <= prm <= ePrm else False def getSection( pln :adsk.core.Plane, face :adsk.fusion.BRepFace) -> adsk.core.ObjectCollection: return pln.intersectWithSurface(face.geometry) def initPlane( ori :adsk.core.Point3D, vec1 :adsk.core.Vector3D, vec2 :adsk.core.Vector3D) -> adsk.core.Plane: if vec1.isParallelTo(vec2): return None return adsk.core.Plane.createUsingDirections(ori,vec1,vec2) def getMinDist( crv1 , crv2) -> adsk.core.MeasureResults: meas = _app.measureManager return meas.measureMinimumDistance(crv1, crv2) def getShareEdges( face1 :adsk.fusion.BRepFace, face2 :adsk.fusion.BRepFace) -> list: lps1 :adsk.fusion.BRepLoops = face1.loops lp1 :adsk.fusion.BRepLoop = lps1[0] cos1 = [co for co in lp1.coEdges if hasPartner(co)] lps2 :adsk.fusion.BRepLoops = face2.loops lp2 :adsk.fusion.BRepLoop = lps2[0] cos2 = [co.partner for co in lp2.coEdges if hasPartner(co)] # 共有エッジ取得 rap = [] for co1 in cos1: for co2 in cos2: if co1 == co2: rap.append(co1.edge) return rap def hasPartner( coEdge :adsk.fusion.BRepCoEdge) -> bool: try: coEdge.partner return True except: return False
段々肥大化してきた・・・。
当然、手動で作ったのと一致しますが、2点間だけで欲しいので
外側が要らないんです。
この辺にその処理を入れているのですが、エラーになっちゃいます。
return sect.extract(prms[0], prms[1]) # err!
Nurbs曲線を指定したパラメータ間のみにしている部分なのですが
どうしてもエラーになる・・・。
スケッチに入れてからトリムするの嫌だなぁ。