C#ATIA

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

apperを食す2

こちらの続きです。
apperを食す1 - C#ATIA
思ったより忙しくて取り組めない。

人生で初めてgithubでForkして、Pull requestしました。

1つのダイアログに複数のSelectionCommandInputが存在すると
OKボタンが制御が正しくなくなってしまう為、どうしても必要だった
Validateイベントと
apper/Fusion360CommandBase.py at add-CommandEvent · kantoku-code/apper · GitHub

SelectionCommandInputのフィルターだけでは、選択条件が不足する場合に
必要なPreSelectイベントです。
apper/Fusion360CommandBase.py at add-CommandEvent · kantoku-code/apper · GitHub

この2個は頻繁に使うので欲しいです。
他の人はそんなに要らないのかなぁ・・・。

apperを食す1

悩んだ挙句、こちらを試すことにしました。
GitHub - tapnair/apper: Fusion 360 Addin Framework


Custom Featuresを素のコードで書くにはハードルが高い。
(類似したコードを複数回書いている)
 ↓
書きやすくなるような、モジュール的なものを作成するには
知識が不足しすぎている。
 ↓
書きやすくするフレームワーク?的なものを探す。
 ↓
apperしかない。(Autodeskの方ですし)


以前のこちらの進化版なので、何となくはわかってます。
GitHub - tapnair/Fusion360AddinSkeleton: Framework to simplify the creation of Fusion 360 Addin
ちょっとイベントが足りないのでapperをいじってます。
公開する前にはpull request出さなきゃいけない気はしてます。


取りあえずCustom Featuresは諦め、以前作っていた
2回転メビウスの帯をapperで作れるようにしてみました。

出来上がる形状が、それなりに複雑なので異常なほど
時間がかかる事が分かると思います。

GUIで作るよりは早いはずですが・・・。

tokenize.generate_tokens

こちら、同じお悩みをお抱えの方です。
Re: How to get the final value of CAMParameter - Autodesk Community

式として入力された結果を得たいのですが、デザインは可能でCAMは出来ないんです。
式の文字列からパラメータを再度取得して・・・と言う感じの再帰的な事をやれば
取得出来そうな気はしていたのですが、文字列を計算式としてどう解析すれば良いのか
分かっていませんでした。(正規表現なら・・・とも思っていましたが)

tokenizeと言う標準ライブラリがある事を知りました。
regex - Pythonで数式文字列をトークンに分割する - 初心者向けチュートリアル

それっぽく修正したつもり。

import adsk.core, adsk.fusion, adsk.cam, traceback
from io import StringIO
import tokenize

_app = adsk.core.Application.cast(None)
_ui = adsk.core.UserInterface.cast(None)
_cam = None

def run(context):
    try:
        global _app, _ui, _cam
        _app = adsk.core.Application.get()
        _ui = _app.userInterface

        doc = _app.activeDocument
        products = doc.products
        product = products.itemByProductType('CAMProductType')
        _cam = adsk.cam.CAM.cast(product)

        ope :adsk.cam.Operation = _cam.allOperations[0]

        stayDownDistance :adsk.cam.CAMParameter = ope.parameters.itemByName('stayDownDistance')

        print('title:{}\nname:{}\nexpression:{}'.format(
            stayDownDistance.title,
            stayDownDistance.name,
            stayDownDistance.expression
        ))
        # 上手く行ってない
        returnValue = adsk.core.ValueInput.createByString(stayDownDistance.expression)
        
        # 正しくない
        expression = getRealValue(stayDownDistance.expression, ope.parameters)
        res = eval(''.join(expression))
        print(f'{stayDownDistance.expression} -> {res}')

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

# https://tutorialmore.com/questions-976968.htm
def getRealValue(
    formula :str,
    operation_parameters :adsk.cam.CAMParameters
    ):

    global _cam
    unitMgr =  _cam.unitsManager

    try:
        value = unitMgr.evaluateExpression(formula)
        return str(value)
    except:
        pass

    tokens = [token[1] for token in tokenize.generate_tokens(StringIO(formula).readline) if token[1]]
    operations = ('+','-','*','/','(',')')
    expression = []
    for token in tokens:

        try:
            value = unitMgr.evaluateExpression(token)
            expression.append(str(value))
            continue
        except:
            pass

        if token.isnumeric():
            expression.append(token)
        elif token in operations:
            expression.append(token)
        else:
            try:
                prm = operation_parameters.itemByName(token)

                res = getRealValue(prm.expression, operation_parameters)
                expression.extend(res)
            except:
                pass

    return  expression

10インチが64.51599999999999だと返ってきます・・・間違ってます。
恐らく単位の問題だけだろうと思うので、届く可能性が有りそう。
(肝心な方は進んでいない)

読み取り専用

遅れていた個人ライセンスの制限が始まりました。
アピールがすごい。
f:id:kandennti:20210204115543p:plain
開けないのではなく、保存が出来ないんだね。

個人的には、APIのテストデータが欲しいだけなので、
あまり影響は無いかも。

Custom Featuresに挑む6

こちらの続きです。
Custom Featuresに挑む5 - C#ATIA

Custom Featureを利用したサンプルをもう一つ見つけました。
GitHub - tapnair/FusionBoxer: Addin for creating offset bounding box features.
これからじっくり見ようとは思っているのですが、
apperを利用したサンプルです。

以前から自分が "やりにくいな・・・" と思っていた部分が
apperでは解消しているっぽい。

頑張りたい。

Custom Featuresに挑む5

こちらの続きです。
Custom Featuresに挑む4 - C#ATIA

先日まで続けていた形状を作る為のクラスは何とか完了。
・・・満足できる程では無いものの、動作はする状態になりました。

実際開発する際はスクリプトが一番簡単なので、動作確認出来た時点で
クラス化し、アドイン化するのが楽だと、気が付き始めました。

デザインパターンMVCやMVVM等でMとVを分ける気持ちが徐々に
理解出来て来ました。(CやVMは・・・イベント類が役割を果たしている
のかな?不勉強でわかってないですけど)


ここまで来てやっとCustom Featureに取り組み始め実装したつもり。
f:id:kandennti:20210130231255p:plain
実際コマンドを実行し作成は出来ています。パラメータもバグを避けつつ
正しく登録出来ています。
但し、タイムラインがいただけない。

最初のスケッチはコマンドを実行するための物なので無関係。
赤矢印は、コマンド実行した際に出来上がるタイムラインオブジェクトなので
問題無いです。
緑のスケッチとスイープが駄目です・・・。

内部的に作成しているのですが、最後に残ってしまうのがカッコ悪い為、
内部で削除しているのですが、タイムラインに残ってしまいます。
スクリプトで実行した際は、この現象出ないんですよ。
これも恐らくCustom Featureのバグだろうな。


他にも開発したいものがあるので、通常のアドインとして公開してしようかな・・・。
(弱気)

Custom Featuresに挑む4

こちらの続きです。
Custom Featuresに挑む3 - C#ATIA

昨日から上手く行かなかった部分が解消。穴も開けました。
f:id:kandennti:20210128163851p:plain
自宅の非力なPCじゃこれが限界です。

・・・Custom Featuresの手前の話なんですけどね。


よく見たら、こちらのマークはこれなんだ。気が付かなかった。
f:id:kandennti:20210128164154p:plain


追記です。
そういえば、こんな感じに出来る事を忘れてました。