こちらの続きです。
メッシュをサーフェスに変換する - C#ATIA
正直、続きを書くと思っていませんでした。
キッカケはこちらです。
https://forums.autodesk.com/t5/fusion-ri-ben-yuforamu/10000wo-chaoeru-san-jiaoga-hanmaretamesshudetawosoriddomoderunishitai/m-p/13832881/highlight/true#M60583
記載した内容の類似の処理をします。
サンプルデータはこちらからお借りしました。
https://grabcad.com/library/porsche-brembo-18z-front-caliper-scan-1
ブレンボのブレーキキャリパーです。ブレーキパッド外してくれていれば、もっと良い状態で
3Dスキャン出来ていそうな気もしますが・・・
まず、3Dスキャンデータはどれも重すぎます。まず面の数をこんな条件で減らしておきます。
さっそくコードです。
# Fusion360API Python script # https://grabcad.com/library/porsche-brembo-18z-front-caliper-scan-1 import traceback import adsk import adsk.core as core import adsk.fusion as fusion import math import time def run(context): ui: core.UserInterface = None try: app: core.Application = core.Application.get() ui = app.userInterface msg: str = "Select MeshBody" selFilter: str = "MeshBodies" sel: core.Selection = select_ent(msg, selFilter) if not sel: return t = time.time() mesh: fusion.MeshBody = sel.entity angle: float = 2 meshs = exec_meshSeparate(mesh, angle) for m in meshs: adsk.doEvents() try: exec_meshConvert(m, True) app.log(f" ->{m.name}: Prismatic-OK") except: try: exec_meshConvert(m, False) app.log(f" ->{m.name}: Faceted-OK") except: app.log(f" ->{m.name}: NG") app.log(f"Done: {time.time() - t}s") except: if ui: ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) def exec_meshConvert( mesh: fusion.MeshBody, isPrismatic: bool, ) -> list[fusion.MeshBody]: comp: fusion.Component = mesh.parentComponent meshConvFeats: fusion.MeshConvertFeatures = comp.features.meshConvertFeatures meshInputs: fusion.MeshConvertFeatureInput = meshConvFeats.createInput( [mesh] ) if isPrismatic: meshInputs.meshConvertMethodType = fusion.MeshConvertMethodTypes.PrismaticMeshConvertMethodType else: meshInputs.meshConvertMethodType = fusion.MeshConvertMethodTypes.FacetedMeshConvertMethodType meshInputs.meshConvertOperationType = fusion.MeshConvertOperationTypes.ParametricFeatureMeshConvertOperationType meshConvFeats.add(meshInputs) def exec_meshSeparate( mesh: fusion.MeshBody, angle: float, ) -> list[fusion.MeshBody]: comp: fusion.Component = mesh.parentComponent # 処理前のMeshのToken ents: list[str] = [m.entityToken for m in comp.meshBodies] if mesh.faceGroups.count < 2: # 面グループ fgFeats: fusion.MeshGenerateFaceGroupsFeatures = comp.features.meshGenerateFaceGroupsFeatures fgInput: fusion.MeshGenerateFaceGroupsFeatureInput = fgFeats.createInput(mesh) fgInput.angleThreshold = core.ValueInput.createByReal(math.radians(angle)) fgFeats.add(fgInput) # 分離 separateFeats: fusion.MeshSeparateFeatures = comp.features.meshSeparateFeatures separateInput: fusion.MeshSeparateFeatureInput = separateFeats.createInput(mesh) separateInput.isKeepBody = True separateInput.meshSeparateType = fusion.MeshSeparateTypes.FaceGroupMeshSeparateType separateFeats.add(separateInput) return [m for m in comp.meshBodies if not m.entityToken in ents] 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
色々と悩んだ末にこんな感じになりましたが、ん~使い道があるものかな?
まず、面グループをチェックします。
面グループはSTL等をインポートした状態でも1個はあります。
手動で面グループを作成していない場合は、面グループ化を行い(角度5度の高速)
面グループ化されている場合は、そのまま分離処理に入ります。
但し、面グループ化は手動で行う事をお勧めします。
一つはどの様な状態で変換するかを事前に確認出来る事は、大きなメリットです。
もう一つは、何故かAPIで処理した方が処理が遅いように感じるからです。
その後サーフェスへの変換処理を行いますが、プリズマティックでチャレンジし
失敗時はファセットで変換します。(個人ライセンスの場合は恐らく全てファセットになると思います)
実際に処理後はこのようになります。
プリズマティックで成功するとそれっぽい仕上がりなんですけどね・・・
正直なところ時間はそれなりにかかりますね。事前に面グループ化した状態で321秒でした。
お役に立つかな?