C#ATIA

↑タイトル詐欺 主にFusion360API 偶にCATIA V5 VBA(絶賛ネタ切れ中)※記載されている内容は個人の意見であり、所属する団体等を代表する意見では御座いません・・・・よ!

見えている全ての面を取得する1

Fusion360で今見ている画面で見えている面を取得するスクリプトです。
イヤ、全てではないです・・。時間が無いのでコードだけ。

# Fusion360API Python script
# 画面で見えている全ての面をコピー
# テストデータ
# https://grabcad.com/library/pipe-assy-machine-1

import traceback
import adsk.core as core
import adsk.fusion as fusion
import time

# ピッチ(cm)
_pitch = 1

def run(context):
    ui: core.UserInterface = None
    try:
        t = time.time()

        # モロモロ
        app: core.Application = core.Application.get()
        ui = app.userInterface
        des: fusion.Design = app.activeProduct
        root: fusion.Component = des.rootComponent
        measMgr: core.MeasureManager = app.measureManager

        # tempManager
        tmpMgr: fusion.TemporaryBRepManager = fusion.TemporaryBRepManager.get()

        # 全体BBox
        rootBBox: fusion.BRepBody = tmpMgr.createBox(root.orientedMinimumBoundingBox)

        # 画面方向のベクトル
        cam: core.Camera = app.activeViewport.camera
        vecEye: core.Vector3D = cam.eye.vectorTo(cam.target)

        # 右方向ベクトル
        vecWidth: core.Vector3D = vecEye.crossProduct(cam.upVector)

        # 画面方向に対してのBBOX
        camBBox: core.OrientedBoundingBox3D = measMgr.getOrientedBoundingBox(
            rootBBox,
            vecEye,
            vecWidth,
        )

        # 画面u方向
        vecU: core.Vector3D = camBBox.widthDirection
        vecU.normalize()
        vecU.scaleBy(camBBox.width*-0.5)

        # 画面v方向
        vecV: core.Vector3D = camBBox.heightDirection
        vecV.normalize()
        vecV.scaleBy(camBBox.height*0.5)

        # 画面奥行き方向
        vecLength: core.Vector3D = vecEye.copy()
        vecLength.normalize()
        vecLength.scaleBy(camBBox.length*-0.5)

        # 最小-スタート位置
        startPnt: core.Point3D = camBBox.centerPoint.copy()
        startPnt.translateBy(vecLength)
        startPnt.translateBy(vecV)
        startPnt.translateBy(vecU)

        # dump_bbox(camBBox)
        # dump_points([startPnt])

        # ループカウント
        global _pitch
        countU = int(camBBox.width/_pitch)
        countV = int(camBBox.height/_pitch)

        # 向きサイズ修正
        vecU.normalize()
        vecU.scaleBy(_pitch*-1)

        vecV.normalize()
        vecV.scaleBy(_pitch*-1)

        # 元になる点群
        points = []
        for u in range(countU+2):
            vU: core.Vector3D = vecU.copy()
            vU.scaleBy(u)
            for v in range(countV+2):
                vV: core.Vector3D = vecV.copy()
                vV.scaleBy(v)

                pnt: core.Point3D = startPnt.copy()
                pnt.translateBy(vU)
                pnt.translateBy(vV)

                points.append(pnt)

        app.log(f"Points: {len(points)}_time: {time.time()-t}")
        # dump_points(points)

        # 点から画面方向にある面の取得-重複無し
        faceDict = {}
        for pnt in points:
            faceObjs: core.ObjectCollection = root.findBRepUsingRay(
                pnt,
                vecEye,
                fusion.BRepEntityTypes.BRepFaceEntityType,
                -1,
                True,
            )

            if faceObjs.count > 0:
                face: fusion.BRepFace = faceObjs[0]
                if not face.entityToken in faceDict:
                    faceDict.setdefault(face.entityToken, tmpMgr.copy(face))

        app.log(f"faces: {len(faceDict.keys())}_time: {time.time()-t}")

        # Join
        faceBodies: list[fusion.BRepBody] = list(faceDict.values())
        faceBody: fusion.BRepBody = faceBodies[0]
        for b in faceBodies[1:]:
            tmpMgr.booleanOperation(
                faceBody,
                b,
                fusion.BooleanTypes.UnionBooleanType,
            )

        # 新Doc
        expDoc: fusion.FusionDocument = app.documents.add(core.DocumentTypes.FusionDesignDocumentType)

        # 画面に出力
        dump_temp_faces([faceBody])

        # stepで出力
        expMgr: fusion.ExportManager = app.activeProduct.exportManager
        stpOpt: fusion.STEPExportOptions = expMgr.createSTEPExportOptions(
            "C:/TEMP/test.stp", 
            app.activeProduct.rootComponent
        )
        expMgr.execute(stpOpt)

        # 閉じる
        expDoc.close(False)

        t=time.time()-t
        app.log(f"time: {t}s")

        ui.messageBox(
            f"面数:{len(faceBodies)}\nTime:{t}s",
            "Done",
        )

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


def dump_points(ps: list[core.Point3D]):
    app: core.Application = core.Application.get()
    des: fusion.Design = app.activeProduct
    root: fusion.Component = des.rootComponent

    skt: fusion.Sketch = root.sketches.add(root.xYConstructionPlane)
    skt.isComputeDeferred = True
    [skt.sketchPoints.add(p) for p in ps]
    skt.isComputeDeferred = False


def dump_temp_faces(faces: fusion.BRepBody):
    app: core.Application = core.Application.get()
    des: fusion.Design = app.activeProduct
    root: fusion.Component = des.rootComponent

    baseFeat: fusion.BaseFeature = None
    if des.designType == fusion.DesignTypes.ParametricDesignType:
        baseFeat = root.features.baseFeatures.add()

    bodies: fusion.BRepBodies = root.bRepBodies
    if baseFeat:
        baseFeat.startEdit()
        for f in faces:
            try:
                bodies.add(f, baseFeat)
            except:
                pass
        baseFeat.finishEdit()
    else:
        for f in faces:
            try:
                bodies.add(f)
            except:
                pass


def dump_bbox(bbox: core.OrientedBoundingBox3D):
    tmpMgr: fusion.TemporaryBRepManager = fusion.TemporaryBRepManager.get()
    body: fusion.BRepBody = tmpMgr.createBox(bbox)

    app: core.Application = core.Application.get()
    des: fusion.Design = app.activeProduct
    root: fusion.Component = des.rootComponent

    baseFeat: fusion.BaseFeature = None
    if des.designType == fusion.DesignTypes.ParametricDesignType:
        baseFeat = root.features.baseFeatures.add()

    bodies: fusion.BRepBodies = root.bRepBodies
    if baseFeat:
        baseFeat.startEdit()
        bodies.add(body, baseFeat)
        baseFeat.finishEdit()
    else:
        for body in tmpBodies:
            bodies.add(body)