C#ATIA

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

Igesファイルの3D曲線のインポートに挑む5

こちらの続きです。
Igesファイルの3D曲線のインポートに挑む4 - C#ATIA


フォーラムでUpされたデータではどうしてもFusion360が落ちてしまい
ましたが、やっと、開いた円弧が上手くいかない原因がわかりました。

円弧の開始・終了の角度(単位 ラジアン)の精度が高すぎるとスケッチに
取り込む際にFusion360が落ちてしまっているようです。
その為、若干精度が落ちますが角度を1/1000ラジアンまでに四捨五入
することで無事取り込めるようになりました。
・・・でも、こちらではもっと精度が高いにも関わらず、出来ているので
謎が解決したわけではないのですが。
パラメトリック時のsketch.includeがおかしい - C#ATIA

他にも、パラメトリック時のナミナミ状態は、基準フューチャーモードに切り替えて
取り込めば問題無い事もわかりました。
(不要な線が消えなかったのですが、スケッチを作成するタイミングを変更する
 ことで、ノンパラメトリック時と同じ状態で取り込めるようになりました)

少し重めのデータでテストしてみました。
f:id:kandennti:20170905144756p:plain
・・・前から懸念していたのですが、処理が異常に遅いです。
800本程の線があるのですが、約1200秒程かかりました。

邪魔な制御点なのが残ってしまう処理の方が、高速なのはわかっていたので
こちらの状態で試したところ
f:id:kandennti:20170905144804p:plain
約430秒程かかります。 ・・・実用的とは思えないほどの遅さ。

高速に処理させる方法がイマイチわかりません。 NumPy使えば
速くなるってものでも無い様な気もしますし・・・、どうしよう。

Igesファイルの3D曲線のインポートに挑む4

こちらの続きです。
Igesファイルの3D曲線のインポートに挑む3 - C#ATIA

こちらの動画から進展していません。未だに開いた円弧のインポートに苦戦中。


悪い事にエラーで止まるのではなく、Fusion360自体が落ちてしまい
原因の特定に時間がかかりました。
開いた円弧(adsk.core.Arc3D.asNurbsCurve)をスケッチに取り込む
(sketchFittedSplines.addByNurbsCurve)際に、閉じた円弧では
出来ているのに、開いた円弧はNGなんです。

開いた円弧を作成すること自体は、こちらで出来ている上、
スケッチの取り込み等、その後の処理も出来ているのですが
パラメトリック時のsketch.includeがおかしい - C#ATIA

もう、こちらのダイアログ見飽きましたよ。
フリーズして落ちた際には、「報告を送信」ボタンを押しましょう! - Autodesk Community

パラメトリック時のsketch.includeがおかしい

続きのような・・・
Igesファイルの3D曲線のインポートに挑む3 - C#ATIA

上手くいかないので、開いた円弧の作成テストです。

円弧を作成し、同じ円弧をスケッチ内に3回取り込むだけのコードです。

#FusionAPI_python
#Author-kantoku
#Description-ArcTest2

import adsk.core, traceback

def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui  = app.userInterface
        
        #円弧作成
        center = [1107.3813777445, -361.18476278735, 87.096588591886]
        normal = [-0.54635392414872, -0.83754953013075, -0.00285904618013]
        referenceVector = [0.83755440991454, -0.54635074096564, -0.00186501447709]
        radius = 5.0881512938029 * 0.1
        startAngle = 3.138255565834
        endAngle = 6.2798482194238
        
        arc = adsk.core.Arc3D.createByCenter(
            create_Point(center), 
            create_Vector(normal), 
            create_Vector(referenceVector), 
            radius, 
            startAngle, 
            endAngle)
        
        #スケッチ作成
        des = adsk.fusion.Design.cast(app.activeProduct)
        comp = des.rootComponent
        skt = comp.sketches.add(comp.xYConstructionPlane)
        
        #円弧取り込み
        for i in range(3):
            sfs = include_BSc(arc.asNurbsCurve, skt)
            skt.include(sfs) #←ここの動作が違う
            sfs.deleteMe()
        
        ui.messageBox('Done')
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

def create_Vector(lst):
    return adsk.core.Vector3D.create(
        lst[0], lst[1], lst[2])
        
def create_Point(lst):
    return adsk.core.Point3D.create(
        lst[0] * 0.1, lst[1] * 0.1, lst[2] * 0.1)
        
def include_BSc(geo, skt):
    fs = skt.sketchCurves.sketchFittedSplines.addByNurbsCurve(geo)
    fs.isFixed = True
    return fs    

実はこれ、パラメトリックかノンパラメトリックかで結果が違うんです。
ノンパラメトリックはこちら
f:id:kandennti:20170825200000p:plain
1本に見えますが、同じもの3回なのでこれで正解なんです。

問題はパラメトリック
f:id:kandennti:20170825195849p:plain
結構衝撃・・・。
1本だけなら結果が同じだったのですが、2本以上になると
2本目以降がナミナミ状態に。
Nurbs曲線化する際、本来通過すべきじゃない制御点を
通過するスプラインになってしまうんです。

includeしないと両方とも同じ動作になるんですが、
f:id:kandennti:20170825200907p:plain
制御点が表示された状態になり、かなり邪魔なんです。


フォーラムに書いておけば、中の人に伝わるかな?

Igesファイルの3D曲線のインポートに挑む3

こちらの続きです。
Igesファイルの3D曲線のインポートに挑む2 - C#ATIA
相変わらず、時間が確保できないです。

Helpを良く見たら、SketchCurves.sketchArcsやらSketchCurves.sketchCirclesの
各円弧のインスタンスは "スケッチ上にある円弧" に対してって書いてありました。
3Dな円弧は駄目っぽいです。

その為、円弧もNurbs曲線化しなきゃならない事がわかりました。
(その為のasNurbsCurveメソッドなんですね…。)
修正した結果がこちら

とりあえず正しい位置・サイズでインポート出来るか確認したかったので
全て閉じた円弧として処理している為正しくないです。
が、気持ちとしてはかなり満足です。(思ったより処理が遅いのは残念)

こうなると閉じたNurbs曲線のデータが欲しい。
(CATIAは2本に分割されちゃいます)

Igesファイルの3D曲線のインポートに挑む2

こちらの続きです。
Igesファイルの3D曲線のインポートに挑む1 - C#ATIA

昨日の円弧インポートの失敗は、僕の処理が間違っている事が判りました。
(そりゃそうです・・・)
処理が面倒だった為、3点通過で円弧を作成していたのですが、
中心点と角度指定で作成した方が正しい結果になりそうです。
同じだと思ったんですけどねぇ。

円弧テスト用にデータをUpしました。
GrabCAD - CAD library
(ファイル名:open_close_arc.igs)
実はCATIAで閉じた円弧(要は円)をIgesでエクスポートすると、2つの円弧
に分割されててしまいます。(テストした感じです)
先日失敗したのは、円のままの状態のデータでした。

UpしたIgesには4つの円弧が入っており、
1:CATIAで作成した円弧
2,3:CATIAで作成した円が分割された円弧
4:先日失敗したデータ内にあった円
です。(GrabCADのビュアーで表示されているのは、順番が逆…)

このデータmruby_sirenで作成しました。2つのigesを一つにまとめられるん
です。テストデータを作成するのに便利です。

…取り組みたいのですが、時間が無いなぁ

Igesファイルの3D曲線のインポートに挑む1

こちらの続きです。
Fusion360APIで外部実行ファイルを実行 - C#ATIA

前回は、Fusion360からmruby_sirenを呼び出しデータの受け取り方が
わかったので、より実践的にIgesファイルを読み込み3D曲線の情報から
曲線を作ります。

GurbCADにUpしたデータでのテスト

こちらは、面の境界部分とインポートした曲線が一致しているようなので
うまく出来ています。(元データCATIA)

こちらにタイミング良く、こちらにIgesデータがUpされたのでテストさせて
もらいます。
IGES、X_Tからの線分データの読み込みについて - Autodesk Community

まともにインポート出来たのは直線のみです。Nurbs曲線は無かったのですが
円弧がほぼ全て失敗。特に閉じた円弧が苦労したのですが、結果に繋がらず…。

動画の最後の方の長穴にいたっては、片方の円弧が真逆に作成されています。

個人的なのですが、Parasolid系のCADからエクスポートされたIgesは上手くインポート
出来ない面が多い気がしています。
又、mruby_sirenのサンプルコードのこちら
mruby-siren/fillet-pipe.rb at master · dyama/mruby-siren · GitHub
Igesでエクスポートするように修正し、CATIAでインポートを試みたのですがエラーになりました。
Stepでエクスポートしたり、他のソフトで確認したところ円弧が逆になっている為に
インポート出来なかった事がわかったのですが、原因はOpenCASCADEのような気がするのですが…。

Fusion360APIで外部実行ファイルを実行

何となく読み込みが出来そうな気がしてきたので、Fusion360からsiren
呼び出すテストをしようと思ったのですが、大苦戦…。

まず、mruby-sirenの実行ファイルを

C:\Temp\siren_0.14d_mingw64\bin\mruby.exe

の位置になるようにしました。

続いて呼び出し用のsirenスプリクト "test.rb" をこんな感じで作成

#!/usr/bin/env siren
# test.rb
# coding: utf-8

puts "hoge"
puts "piyo"
puts "huga"

中身は、sirenとは無関係なファイルです…。
これをFusion360スプリクトと同一フォルダ内に置いておきます。

続いてFusion360スプリクトでこんな感じのものを作りました。

#FusionAPI_python
#Author-kantoku
#Description-OutprocessTest
#外部実行ファイルを実行

# -*- coding: utf-8 -*-

import adsk.core, adsk.fusion, traceback
_app = adsk.core.Application.get()
_ui = _app.userInterface
_siren_path = r"C:\Temp\siren_0.14d_mingw64\bin\mruby"

def run(context):
    try:
        global _app, _ui
        global _siren_path
        
        import os
        path = os.path.dirname(os.path.abspath(__file__))
        callpath = path + '\\test.rb'
        
        s_path =_siren_path.replace(os.path.sep, '/')
        
        import subprocess
        output = subprocess.check_output([s_path, callpath])
        _ui.messageBox(str(output))
    except:
        if _ui:
            _ui.messageBox('エラー\n{}'.format(traceback.format_exc()))

siren に test.rb を投げつつ、標準出力されたものを取得し表示させるだけです。
実行結果はこちら
f:id:kandennti:20170817171134p:plain
[b'] や [\r\n] 等が入ってますが、取得も出来てます。
・・・たったこれだけなのですが、途中で諦めようかとも思うぐらいでした。