C#ATIA

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

フィレットの元のエッジを探せ!!3

こちらの続きです。
フィレットの元のエッジを探せ!!2 - C#ATIA

もうちょっと効率の良い探し方が分かりました。
てっきりフィーチャからは、適応された後の状態のボディから
元のエッジを探していましたが、フィーチャが作り出した面の
エッジからだけ探す様にしました。
と言いますか、作り出した面だけを取得する方法がある事に
気が付きませんでした。分かりにくいですね。

            tmpTokenSet = set()
            for body in timeEnt.bodies:
                [tmpTokenSet.add(e.entityToken) for e in body.edges]

では無く、

            tmpTokenSet = set()
            for face in timeEnt.faces:
                [tmpTokenSet.add(e.entityToken) for e in face.edges]

です。・・・やっぱり他人には伝わらないかも。


その理屈から、"子" 側を探し出すきっかけが分かりました。
目的のフィーチャの timeline.entity.faces の面・境界・頂点を
利用しているフィーチャを "子" と判断する事にします。
・・・CATIAの親子を表示させるとそうだったので。

で、"親" 側の探し方は最初の内容を盛り込みつつ、"子" 側も
探し出せるようにしました。

# 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
        des: adsk.fusion.Design = app.activeProduct
        root: adsk.fusion.Component = des.rootComponent

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

        parents, children = getReferenced_Fillet(sel.entity)

        app.log('** parents **')
        [app.log(f.name) for  f in parents]

        app.log('** children **')
        [app.log(f.name) for  f in children]


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


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


def getReferenced_Fillet(self) -> list:
        app: adsk.core.Application = adsk.core.Application.get()
        des: adsk.fusion.Design = app.activeProduct

        def getEdgeTokenSet(edgeSets: adsk.fusion.FilletEdgeSets) -> set:
            tokens = set()
            try:
                for edgeset in edgeSets:
                    [tokens.add(e.entityToken) for e in edgeset.edges]
            except:
                pass

            return tokens

        # *****
        timeline: adsk.fusion.Timeline = des.timeline
        backupMarker = timeline.markerPosition
        timeObj: adsk.fusion.TimelineObject = self.timelineObject

        # 親探し
        timeObj.rollTo(True)
        edgeTokenSet = getEdgeTokenSet(self.edgeSets)

        timeObjs = [timeline.item(idx) for idx in range(backupMarker)]

        parents = []
        for timeObj in timeObjs:
            timeEnt: adsk.fusion.Feature = timeObj.entity
            if not hasattr(timeEnt, 'faces'):
                continue

            timeObj.rollTo(False)
            tmpTokenSet = set()
            for face in timeEnt.faces:
                [tmpTokenSet.add(e.entityToken) for e in face.edges]

            intersection = edgeTokenSet.intersection(tmpTokenSet)
            if len(intersection) > 0:
                parents.append(timeEnt)
                [edgeTokenSet.discard(token) for token in intersection]

            if len(edgeTokenSet) < 1:
                break

        # 子探し
        self.timelineObject.rollTo(False)
        edgeTokenSet = getEdgeTokenSet(self.faces)

        timeObjs = [timeline.item(idx) for idx in range(timeline.markerPosition, timeline.count)]

        children = []
        for timeObj in timeObjs:
            timeEnt: adsk.fusion.Feature = timeObj.entity
            if not hasattr(timeEnt, 'edgeSets'):
                continue

            timeObj.rollTo(True)
            tmpTokenSet = getEdgeTokenSet(timeObj.entity.edgeSets)

            intersection = edgeTokenSet.intersection(tmpTokenSet)
            if len(intersection) > 0:
                children.append(timeEnt)
                [edgeTokenSet.discard(token) for token in intersection]

            if len(edgeTokenSet) < 1:
                break

        # 現状復帰
        timeline.markerPosition = backupMarker

        return parents, children

あぁ基本的にフィレットと面取りだけです。

こんなデータを用意します。
まずスケッチを描き、押し出し、フィレットを作ります。

フィレットは "フィレット1" としておきます。

続けて、"フィレット2” と "面取り1" を作ります。

"フィレット2” と "面取り1" は、 "フィレット1" で出来た
エッジを利用しています。
これは、"フィレット2” と "面取り1" を "子" と認識させたい
ためです。

先程のスクリプトを実行し "フィレット1" を選択すると

 ** parents **
 押し出し1
 ** children **
 フィレット2

一見、正しいように思えますが、 "面取り1" を "子" と認識して
くれません。何故・・・。

"フィレット2” を抑制し、再度同じ操作をすると

"面取り1" を認識してくれます。・・・何故?。


困っている。