こちらの続きです。
複数面に線を描きたい5 - C#ATIA
良い方法が思い付かない為、素直に平面で交差を作り
その線を使うことにしました。・・・情けない。
一本は2点間を繋ぐ3D直線で、もう一本は3D直線と共有している
エッジの最短距離となる部分のベクトルです。
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
body :adsk.fusion.BRepBody = root.bRepBodies.item(0)
face1 :adsk.fusion.BRepFace = body.faces.item(0)
face2 :adsk.fusion.BRepFace = body.faces.item(1)
shareEdges = getShareEdges(face1, face2)
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)
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)
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
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])
Nurbs曲線を指定したパラメータ間のみにしている部分なのですが
どうしてもエラーになる・・・。
スケッチに入れてからトリムするの嫌だなぁ。