こちらの続きです。
穴テンプレートのトーラスを考える3 - C#ATIA
テストする形状を少し複雑にしました。
ザグリ部分に面取り(赤)を付け、面取りの両側にR面(緑)を付けました。
面取り両側のR面は凸ですが、元々付けていた黄色のR面は凹です。
恐らく、これがクリア出来ればさらに複雑になっても、トーラスについては
クリア出来ると思っています。
この3個のトーラスは、穴テンプレートでは上から順にこんな出力になります。
<segment bottomAngle="0.785398" isConvex="1" isExpanding="Contracting" sweepAngle="-0.785398" topAngle="1.570796" type="Torus"/> <segment bottomAngle="0.000000" isConvex="1" isExpanding="Contracting" sweepAngle="-0.785398" topAngle="0.785398" type="Torus"/> <segment bottomAngle="4.712389" isConvex="0" isExpanding="Contracting" sweepAngle="1.570796" topAngle="3.141593" type="Torus"/>
前回、角度をVector3D.angleToメソッドで測定すると、近い方の角度を
返してくることが分かっている為、角度の取得はmath.atan2を使う事にし、
マイナス値での取得では無く、あくまで反時計回りでの角度に強制的に
直す事にしました。
又、sweepAngleとisConvexも理解出来たつもりなので、そちらも出力。
ついでに確認しやすいように、ラジアンと共に度でも出力させます。
# Fusion360API Python script import traceback import adsk.core as core import adsk.fusion as fusion import math def run(context): ui: core.UserInterface = None try: app: core.Application = core.Application.get() ui = app.userInterface msg: str = 'Select' selFilter: str = 'ToroidalFaces' sel: core.Selection = select_ent(msg, selFilter) if not sel: return face: fusion.BRepFace = sel.entity eva: core.SurfaceEvaluator = face.evaluator prmBox: core.BoundingBox2D = eva.parametricRange() for isU in (True, False): arc: core.Arc3D = core.Arc3D.cast( eva.getIsoCurve(prmBox.minPoint.x, isU)[0] ) if arc: break if not arc: return torus: core.Torus = face.geometry _, origin, _, _, _ = torus.getData() # 本当は穴軸の逆ベクトル? axis = core.Vector3D.create(0,0,-1) pnt: core.Point3D = origin.copy() normal: core.Vector3D = axis.copy() normal.scaleBy(100) pnt.translateBy(normal) plane: core.Plane = core.Plane.create(pnt, normal) pointDistanceData = [] measMgr: core.MeasureManager = app.measureManager for p in (arc.startPoint, arc.endPoint): res: core.MeasureResults = measMgr.measureMinimumDistance(plane, p) pointDistanceData.append( { "dist": res.value, "point": p, } ) pointDistanceData.sort(key = lambda x: x["dist"]) vec: core.Vector3D = arc.center.vectorTo(origin) vec.normalize() mat: core.Matrix3D = core.Matrix3D.create() axis.normalize() axis.scaleBy(-1) mat.setWithCoordinateSystem( arc.center, vec, axis, vec.crossProduct(axis), ) mat.invert() bottom: core.Point3D = pointDistanceData[0]["point"].copy() top: core.Point3D = pointDistanceData[1]["point"].copy() bottom.transformBy(mat) top.transformBy(mat) bottomAngle = math.atan2(bottom.y, bottom.x) if bottomAngle < 0: bottomAngle += (math.pi *2) topAngle = math.atan2(top.y, top.x) if topAngle < 0: topAngle += (math.pi *2) sweepAngle = bottomAngle - topAngle msg = [ f"bottomAngle:{round(bottomAngle, 6)} ", f"topAngle:{round(topAngle, 6)}", f"sweepAngle:{round(sweepAngle, 6)}", f"isConvex:{0 if sweepAngle > 0 else 1}", f"bottomDeg:{math.degrees(bottomAngle)}deg", f"topDeg:{math.degrees(topAngle)}deg", f"sweepDeg:{math.degrees(sweepAngle)}deg", ] app.log(" / ".join(msg)) except: if ui: ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) def select_ent( msg: str, filter: str ) -> core.Selection: try: app: core.Application = core.Application.get() ui: core.UserInterface = app.userInterface sel = ui.selectEntity(msg, filter) return sel except: return None
実際にテストした結果は、上から順にこんな感じです。
bottomAngle:0.785398 / topAngle:1.570796 / sweepAngle:-0.785398 / isConvex:1 / bottomDeg:45.00000000000012deg / topDeg:90.0deg / sweepDeg:-44.99999999999988deg bottomAngle:0.0 / topAngle:0.785398 / sweepAngle:-0.785398 / isConvex:1 / bottomDeg:0.0deg / topDeg:45.00000000000012deg / sweepDeg:-45.00000000000012deg bottomAngle:4.712389 / topAngle:3.141593 / sweepAngle:1.570796 / isConvex:0 / bottomDeg:270.0deg / topDeg:180.0deg / sweepDeg:90.0deg
出来てます。(自己満足)