こちらの続きです。
NURBS面を円筒面に変換する2 - C#ATIA
前回説明を忘れていましたが、任意の面に接線接続以上の隣接している面を
取得することはAPIで取得可能です。
その組み合わせた面が本当に円筒かどうか判断したいです。
あぁそうか、今気が付いたけどまぁ後のテーマにしよう。
前回同様、面上に10点作成し曲率のばらつきが一定以内であれば
円筒面と判断すれば良い様な気がしています・・・いや、球体も
含まれちゃいますね。
まぁ球体は取りあえず無視して、こんなテストコードを作りました。
記載していない関数は、前回のものと変更ありません。
# Fusion360API Python script import traceback import adsk.core as core import adsk.fusion as fusion import random import statistics def run(context): ui: core.UserInterface = None try: app: core.Application = core.Application.get() ui = app.userInterface des: fusion.Design = app.activeProduct root: fusion.Component = des.rootComponent body: fusion.BRepBody = root.bRepBodies[0] nurbss = get_nurbs_faces(body) group = group_by_faces(nurbss) # test(group[0], False) # test(group[0], True) for faces in group: print(is_cylinder(faces)) except: if ui: ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) def is_cylinder( faces: list, tolerance: float = 0.0001 ) -> bool: resLst = [] face: fusion.BRepFace = None for face in faces: eva: core.SurfaceEvaluator = face.evaluator prmRange: core.BoundingBox2D = eva.parametricRange() prms = [ core.Point2D.create( random.uniform( prmRange.minPoint.x, prmRange.maxPoint.x, ), random.uniform( prmRange.minPoint.y, prmRange.maxPoint.y, ), ) for _ in range(10) ] _, _, crvMaxs, _ = eva.getCurvatures(prms) resLst.append(statistics.variance(crvMaxs) < tolerance) return all(resLst)
数値(今回は曲率)のバラつきは分散で調べました。良いのかな・・・。
そして分散が一定の数値以下でOKとしたいのですが、数値が幾つが
適切だかわからないのですが、”0.0001”としました。
もう、不安しかありません。
念の為ですが、取得している曲率の一例はこんな感じです。
-1.2493772363329765 -1.2486900538177184 -1.2510724277907324 -1.248247343786411 -1.2503424321522778 -1.2510858088348 -1.2498398982937735 -1.2493181971087732 -1.247284520473275 -1.2510953336750845
Rサイズだと
-0.7991990137576473 -0.8007073224079025 -0.7994615674494644 -0.7987661586159905 -0.7992104618851492 -0.8012348166877553 -0.7999450894000383 -0.8011068316351571 -0.8011229784921655 -0.7996670715423259
0.02以内ぐらいでしょうか? 想像していたよりバラツキがあります。
こちらのモデルで、スクリプトを実行した結果はこちらです。
True True True True True
5か所の穴は全て円筒面として判断出来ました! って
クリアする数値を設定したので、当たり前なんですけどね。
” 0.00001”でもクリアするな・・・平均値の差の二乗だから
こっちの方が良いのかな・・・。