C#ATIA

↑タイトル詐欺 主にFusion360API 偶にCATIA V5 VBA(絶賛ネタ切れ中)

板状に分割したい1

もう8月になったので、7月病は終わったみたいです。


こちらの取り組みです。
解決済み: 板状に分割したい - Autodesk Community

操作方法が確立出来れば、自動化出来ます。


念の為形状ですが、こんな感じで完全中空なボディです。

不透明度50%にしてみましたが、わかりにくいですね・・・。

条件としては、
・完全中空なボディな事
・全ての面が平らな面で構成されている事
としました。

# Fusion360API Python script

import traceback
import adsk.fusion
import adsk.core


def run(context):
    ui = adsk.core.UserInterface.cast(None)
    try:
        app: adsk.core.Application = adsk.core.Application.get()
        ui = app.userInterface

        msg: str = 'Select'
        selFilter: str = 'Bodies'
        sel: adsk.core.Selection = selectEnt(msg, selFilter)
        if not sel:
            return

        targetBody: adsk.fusion.BRepBody = sel.entity

        execDivided(targetBody)

    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

def execDivided(
    body: adsk.fusion.BRepBody) -> list:

    comp: adsk.fusion.Component = body.parentComponent

    # ******
    def getPairFaces(shell: adsk.fusion.BRepShell):
        pairFaces =[]
        face: adsk.fusion.BRepFace
        for face in shell.faces:
            pnt: adsk.core.Point3D = face.pointOnFace
            geo: adsk.core.Plane = face.geometry
            vec: adsk.core.Vector3D = geo.normal
            vec.scaleBy(-1)
            vecs = [
                vec,
                geo.normal
            ]

            nearFace: adsk.fusion.BRepFace = None
            for vec in vecs:
                res = comp.findBRepUsingRay(
                    pnt,
                    vec,
                    adsk.fusion.BRepEntityTypes.BRepFaceEntityType,
                )

                if res.count < 1:
                    continue
                else:
                    nearFace = res[0]
                    break

            if not nearFace:
                continue

            pairFaces.append(
                (
                    face,
                    nearFace
                )
            )

        return pairFaces

    def isAllPlanarFace(body: adsk.fusion.BRepBody) -> bool:
        planeType = adsk.core.Plane.classType()
        if all([f.geometry.classType() == planeType for f in body.faces]):
            return True

        return False
    # *******
    # 全て平面かチェック
    if not isAllPlanarFace(body):
        return

    # 完全な中空形状チェック
    if not body.shells.count == 2:
        return

    # 外側
    outer: adsk.fusion.BRepShell = max(body.shells, key=lambda x: x.area)

    # 外内面の組み合わせ
    pairFaces = getPairFaces(outer)

    # LoftFeatures
    loftFeats: adsk.fusion.LoftFeatures = comp.features.loftFeatures

    # 外内面でロフト
    bodies = []
    for faces in pairFaces:
        loftFeatIpt: adsk.fusion.LoftFeatureInput = loftFeats.createInput(
            # adsk.fusion.FeatureOperations.NewBodyFeatureOperation
            adsk.fusion.FeatureOperations.NewComponentFeatureOperation
        )
        loftFeatIpt.isSolid = True
        loftFeatIpt.isClosed = False

        loftSections: adsk.fusion.LoftSections = loftFeatIpt.loftSections
        [loftSections.add(f) for f in faces]

        loftFeat: adsk.fusion.LoftFeature = loftFeats.add(loftFeatIpt)

        bodies.append(loftFeat.bodies[0])

    return bodies

def selectEnt(
        msg: str,
        filterStr: str) -> adsk.core.Selection:

    try:
        app: adsk.core.Application = adsk.core.Application.get()
        ui: adsk.core.UserInterface = app.userInterface
        sel = ui.selectEntity(msg, filterStr)
        return sel
    except:
        return None

あちらのデータを選択するとこんな感じの処理を行います。

右側は分かりやすいように、上のボディを非表示にしています。
色の見栄えの為、コンポーネント毎にボディを作っていますが、
元のコンポーネントと同じところにボディだけ作りたいので
あれば、

・・・
    # 外内面でロフト
    bodies = []
    for faces in pairFaces:
        loftFeatIpt: adsk.fusion.LoftFeatureInput = loftFeats.createInput(
            adsk.fusion.FeatureOperations.NewBodyFeatureOperation # <-こっちにする
            # adsk.fusion.FeatureOperations.NewComponentFeatureOperation
        )
        loftFeatIpt.isSolid = True
        loftFeatIpt.isClosed = False
・・・

こんな感じにするとボディのみの作成になります。

キモの ""外側-内側"の組み合わせ" の見つけ方ですが、次回。