<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>API | じじぃの引出し</title>
	<atom:link href="https://www.kazuban.com/blog/tag/api/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.kazuban.com/blog</link>
	<description>なにかしら、皆さんの参考になれば幸いです！</description>
	<lastBuildDate>Wed, 28 Jan 2026 07:15:54 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1</generator>

<image>
	<url>https://www.kazuban.com/blog/wp-content/uploads/2020/05/cropped-ICON-1-32x32.png</url>
	<title>API | じじぃの引出し</title>
	<link>https://www.kazuban.com/blog</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Fusion360  Python API 再挑戦！AIの力を借りて、sketchなど基本ライブラリを作ってみた。</title>
		<link>https://www.kazuban.com/blog/fusion-python-api/</link>
		
		<dc:creator><![CDATA[kazuban]]></dc:creator>
		<pubDate>Tue, 08 Jul 2025 20:01:00 +0000</pubDate>
				<category><![CDATA[AI]]></category>
		<category><![CDATA[Fusion360]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[AIとのやり取り]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Python]]></category>
		<guid isPermaLink="false">https://www.kazuban.com/blog/?p=11250</guid>

					<description><![CDATA[数年前、Fusion360のPython APIに少しだけ触れたことがあります。当時はPython自体が初めてで、構文の違いに戸惑いました。C言語に慣れていた私には、インデントでブロックを作る点や、変数・関数に型の宣言が [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">数年前、Fusion360のPython APIに少しだけ触れたことがあります。<br>当時はPython自体が初めてで、構文の違いに戸惑いました。<br>C言語に慣れていた私には、インデントでブロックを作る点や、変数・関数に型の宣言が不要な点など、なかなか馴染めませんでした。<br>さらに、Fusion独自のオブジェクトや関数の使い方を調べる必要があり、作業のハードルは思った以上でした。<br><a href="https://qiita.com/reisyu/items/84aa97117439e4962bbf">こちらのブログ記事</a>や<a href="https://kantoku.hatenablog.com/archive/category/Fusion360API?page=20">「Kantoku」さんのサイト</a>を参考にしながら少しだけ進めてみたのですが、残念ながら長続きせず中断してしまいました。</p>



<p class="wp-block-paragraph">ところが昨年、AI（生成AI）が大きく注目されるようになり、「これを使ってみるか？」と再び興味がわきました。<br>試しにFusion向けのコードをAIに聞いてみると、実際に動作するスクリプトを提案してくれて、少しやる気が復活…<br>しかしそれも一時的で、またもや放置状態に。</p>



<figure class="wp-block-embed is-type-wp-embed"><div class="wp-block-embed__wrapper">

<a href="https://www.kazuban.com/blog/generative-ai-for-fusion360/" title="話題の『生成Ai』に、Fusion360のPythonスクリプトをきいてみた" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img decoding="async" width="160" height="90" src="https://www.kazuban.com/blog/wp-content/uploads/2024/01/generative-ai-160x90.jpg" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://www.kazuban.com/blog/wp-content/uploads/2024/01/generative-ai-160x90.jpg 160w, https://www.kazuban.com/blog/wp-content/uploads/2024/01/generative-ai-120x68.jpg 120w, https://www.kazuban.com/blog/wp-content/uploads/2024/01/generative-ai-320x180.jpg 320w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">話題の『生成Ai』に、Fusion360のPythonスクリプトをきいてみた</div><div class="blogcard-snippet internal-blogcard-snippet">最近『生成Ai』を触り始めました。今までの、検索に比べても、非常に便利です。できる事の幅が広すぎて、ついていけませんが、プログラムコードも出力してくれるようです。いままで手を付けていなかった、Fusion360のPythonスクリプトを質問してみました。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img decoding="async" src="https://www.google.com/s2/favicons?domain=https://www.kazuban.com/blog" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">www.kazuban.com</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2024.01.27</div></div></div></div></a>
</div></figure>



<p class="wp-block-paragraph">そして今回！<br>AIもさらに進化してきた今こそ、もう一度挑戦してみようと思い立ちました。<br>本記事では、Fusion360 Python API に再び取り組み始めた記録と、コーディングへのAIの活用事例をレポートしています。<br>例題として、Fusion APIの基本ライブラリを作成しましたので、利用できそうであれば、利用していただければ幸いです。</p>



<p class="wp-block-paragraph">なお、より高度なスクリプトや実践的な例に興味がある方は、<a href="https://kantoku.hatenablog.com/archive/category/Fusion360API?page=20">「Kantoku」さんのサイト</a>に素晴らしい資料が公開されていますので、ぜひチェックしてみてください。</p>




  <div id="toc" class="toc tnt-number toc-center tnt-number border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-2" checked><label class="toc-title" for="toc-checkbox-2">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">今回の目標：スケッチ関連の基本ライブラリを作る</a></li><li><a href="#toc2" tabindex="0">Aiの実力を試してみる</a><ol><li><a href="#toc3" tabindex="0">fusionのpython API で直線を引くコード</a><ol><li><a href="#toc4" tabindex="0">ローカルLLM</a></li><li><a href="#toc5" tabindex="0">オンラインLLM</a></li></ol></li><li><a href="#toc6" tabindex="0">コンポネントやスケッチのアクティブな状態を把握</a><ol><li><a href="#toc7" tabindex="0">現状がスケッチモードかどうかの判定</a></li></ol></li></ol></li><li><a href="#toc8" tabindex="0">python特有な構文</a></li><li><a href="#toc9" tabindex="0">Fusion スクリプトをライブラリ化する</a><ol><li><a href="#toc10" tabindex="0">ライブラリの登録場所とpythonでの実装方法</a></li><li><a href="#toc11" tabindex="0">実行スクリプトと同じレベルのスクリプトをインポートするには？</a></li></ol></li><li><a href="#toc12" tabindex="0">ライブラリ利用方法</a></li><li><a href="#toc13" tabindex="0">ライブラリを利用して、X,Y,Zの座標軸にセンターラインを描く</a><ol><ol><li><a href="#toc14" tabindex="0">CenterLine.py</a></li><li><a href="#toc15" tabindex="0">lib_util.py</a></li><li><a href="#toc16" tabindex="0">lib_2d.py</a></li></ol></li></ol></li><li><a href="#toc17" tabindex="0">注意点</a></li><li><a href="#toc18" tabindex="0">まとめ</a></li></ol>
    </div>
  </div>

<h2 class="wp-block-heading"><span id="toc1">今回の目標：スケッチ関連の基本ライブラリを作る</span></h2>



<p class="wp-block-paragraph">Python言語は、ほとんど初心者ですが、ネット情報やAiを参考にコードをコピペするだけでは、なかなか覚えられないと思っています。<br>そこで、基本的なコードをライブラリ化する事で、少しは理解も深まるかと思い、まずはスケッチ周りの基本コードをライブラリ化してみようと思います</p>



<h2 class="wp-block-heading"><span id="toc2">Aiの実力を試してみる</span></h2>



<p class="wp-block-paragraph">さっそく、何種類かのLLMに質問してみました。</p>



<h3 class="wp-block-heading"><span id="toc3">fusionのpython API で直線を引くコード</span></h3>



<h4 class="wp-block-heading"><span id="toc4">ローカルLLM</span></h4>



<p class="wp-block-paragraph">ローカルの場合、私の環境では、レスポンス的に30bぐらいが実用できる限界です。<br>そこで、「gemma-3-27b」「qwen3-32b」で試してみます</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">「fusionのpython API で直線を引くコードをだして」</p>
</blockquote>



<p class="wp-block-paragraph">最初に、「import adsk.core, adsk.fusion, traceback」など<span class="marker-under">Fusion特有のパッケージをインポート</span>しするコードを出してくれるので、なかなかいいな！と思っていましたが、実際にFusionで実行してみても正常動作しませんでした。<br>特に、CAD画面上にメッセージを出力する場合、「ui.messageBox」を利用しますが、一般的なpythonの「print」文を使ったりしています。<br>また、私の環境で30bクラスのLLMでは、<span class="marker-under-blue">回答に５分以上</span>かかりました。<br>文章をまとめたり、翻訳したりの場合では、8bクラスでもいい回答をもらえますが、Fusion API のPython場合はちょっとマイナーなのかもしれません<br>参考にはなると思いますが、<span class="marker-under-red">私</span><span class="marker-under-red">の</span><span class="marker-under-red">環境</span><span class="marker-under-red">では</span><span class="marker-under-red">ちょっとレスポンスが悪いです</span>。</p>



<h4 class="wp-block-heading"><span id="toc5">オンラインLLM</span></h4>



<p class="wp-block-paragraph">次に、オンラインの「chatGPT」と「gemini」で試してみました。<br><span class="marker-under">「chatGPT」も「gemini」も、正常に動作しました</span>。<br>ただし、ログインしないと、会話履歴や共有できないので、ログインしたほうがいいと思います。<br>制限がある場合がありますが、そこそこ無料利用できます。<br>やはり、さすがです。回答レスポンスも早いです。<br>今回の質問では、<a href="https://www.kazuban.com/blog/generative-ai-for-fusion360/#toc6">一年前に、出してくれたコードとほとんど同じコードをだしてくれました。</a><br>一年前は、「bard(gemini)」のコードは、正常動作しないコードでしたが、現在の「gemini」は問題ないコードを出してくれます。<br>個人的は、ローカルLLMを使いたい気持ちがあるのですが、開発作業では、やはりレスポンスは重要なので、今後の学習はオンラインLLMを利用しようと思います。<br>まずは「Gemini 2.5Flash」を利用してみて、いい回答が出なかった場合には、「chatGPT」や「Gemini 2.5Pro」を使おうと思います</p>



<h3 class="wp-block-heading"><span id="toc6">コンポネントやスケッチのアクティブな状態を把握</span></h3>



<p class="wp-block-paragraph"><a href="https://www.kazuban.com/blog/generative-ai-for-fusion360/#toc6">上記の直線を描くサンプルコード</a>では、ルートコンポネントに新しいスケッチを作成し、そのスケッチに直線を引いています。<br>もう少し、実践的な動作にしたいです。</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<ul class="wp-block-list">
<li>スケッチモードであれば、そのスケッチに・・</li>



<li>スケッチモードでない場合、ルートにこだわらず、アクティブなコンポネントに新しいスケッチを作成しそのスケッチに・・</li>
</ul>
</blockquote>



<p class="wp-block-paragraph">これを実現させるには、まず<span class="marker-under">現状のアクティヴな状態を把握する</span>必要があります<br>アクティブなコンポーネントを見つける関数はすぐ見つかりましたが、<span class="marker-under-red">スケッチのモード判定方法はなかなか見つか</span><span class="marker-under-red">らず</span>Aiのお陰でどうにかなりそうです。<br>こういった汎用的だけど苦労した処理を、ライブラリ化しておくと、後々便利だと思います</p>



<h4 class="wp-block-heading"><span id="toc7">現状がスケッチモードかどうかの判定</span></h4>



<p class="wp-block-paragraph">何度かgemini に聞いてみたところ、「<strong>activeEditObject」</strong>「<strong>activeEnvironment</strong>」を使用する方法があるとの回答をもらいました。<br>ただし、Ai としては、<span class="marker-under-red">「<strong>activeEditObject</strong>」を推奨</span>するとの事でした</p>



<pre class="wp-block-code has-cocoon-white-color has-black-background-color has-text-color has-background has-link-color wp-elements-1"><code>import adsk.core
import adsk.fusion

def is_sketch_mode_active():
    """
    現在スケッチモード（いずれかのスケッチが編集中）かどうかを判定します。

    Returns:
        bool: スケッチモードであれば <strong>True</strong>、そうでなければ <strong>False</strong>。
        adsk.fusion.Sketch: アクティブなスケッチオブジェクト（スケッチモードの場合）。
    """
    try:
        app = adsk.core.Application.get()
        
        # 現在編集中のオブジェクトを取得
        active_object = app.activeEditObject

        # 編集中のオブジェクトがスケッチ（Sketch）であるかを確認
        if active_object and <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-yellow-color">isinstance(active_object, adsk.fusion.Sketch):</mark>
            return <strong>True</strong>, active_object
        else:
            return <strong>False</strong>, None

    except:
        return False, None

# --- 実行例 ---
def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui = app.userInterface

        is_active, active_sketch = is_sketch_mode_active()

        if is_active:
            ui.messageBox(f'はい、現在スケッチモードです。\nアクティブなスケッチ: {active_sketch.name}')
        else:
            ui.messageBox('いいえ、現在スケッチモードではありません。')

    except:
        if ui:
            ui.messageBox('エラーが発生しました。')</code></pre>



<p class="wp-block-paragraph">判定で、「<span class="marker-under-red">isinstance()</span>」関数を使っています。<br>これは、自力では、なかなか探せなかったと思います。恐るべし、Aiです。</p>



<h2 class="wp-block-heading"><span id="toc8">python特有な構文</span></h2>



<p class="wp-block-paragraph">Aiが出してくれた、サンプルコードを見ると、C言語とは違う書き方が結構出てきます<br>例えば</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">return<strong> True , active_object</strong></p>
</blockquote>



<p class="wp-block-paragraph">のように、複数変数を返す事ができて、取り出しは、下記のように「,」で区切って利用できるのですね</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>is_active , active_sketch</strong> = is_sketch_mode_active()</p>
</blockquote>



<p class="wp-block-paragraph">C++言語では、最近ではstd::tupleが利用できるみたいですが、それを知らない私は、classを使ったりしていますが、こちらのほうが、面倒ないですね。<br>「if文」も「<strong>三項演算子</strong>」と呼ばれている構文が結構使われていました。</p>



<pre class="wp-block-code has-cocoon-white-color has-black-background-color has-text-color has-background has-link-color wp-elements-2"><code>design = get_design()
return <strong><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-yellow-color">design.activeComponent if design else None</mark></strong></code></pre>



<p class="wp-block-paragraph">C言語にも「三項演算子」はありますが、if文のほうが、分かりやすいかも・・<br>配列系も、多種類があるようで、Aiが出してくれたサンプルでも結構多用しています</p>



<pre class="wp-block-code"><code>plane = plane.lower()
planes_map = {
    "xy": component.xYConstructionPlane,
    "xz": component.xZConstructionPlane,
    "yz": component.yZConstructionPlane
}   
base_plane = planes_map.get(plane)</code></pre>



<p class="wp-block-paragraph">この「<strong>.get(plane)</strong>」はなんだ？<br>と思いましたが、これもAiに聞くと、すぐに説明してくれました。<br><strong>planes_map[plane]</strong>でもアクセスできるようですが、<span class="marker-under-red"><strong>get()</strong>を使うと<strong>plane</strong>が存在しない場合安全に</span>デフォルト値（<code><strong>None</strong></code>または指定した値）を返してくれるようです。<br>本当にすぐに教えてくれるので、私のような独学の場合、参考書などをめくるよりも、言語の理解は数段速くなるでしょうね～</p>



<h2 class="wp-block-heading"><span id="toc9">Fusion スクリプトをライブラリ化する</span></h2>



<p class="wp-block-paragraph">Fusion では、「ユーティリティ」⇒「アドイン」⇒「スクリプトとアドイン」⇒「+」で新規にスクリプトを作成できます</p>



<figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="754" height="572" src="https://www.kazuban.com/blog/wp-content/uploads/2025/07/NewScript.png" alt="" class="wp-image-11300" srcset="https://www.kazuban.com/blog/wp-content/uploads/2025/07/NewScript.png 754w, https://www.kazuban.com/blog/wp-content/uploads/2025/07/NewScript-500x379.png 500w, https://www.kazuban.com/blog/wp-content/uploads/2025/07/NewScript-300x228.png 300w" sizes="(max-width: 754px) 100vw, 754px" /></figure>



<p class="wp-block-paragraph">このダイアログの「<strong>フォルダの場所</strong>」に「<strong>名前</strong>」に入力のフォルダを作成し、その中に「<strong>名前.py</strong>」で実行スクリプトが作成されます。<br>「フォルダの場所」はデフォルトでは、かなり深いので、私は「D:\Fusion360\Scripts」のようにシンプルな場所に変更しています。<br>また、この場所は、<span class="marker-under">「基本設定」⇒「一般」⇒「API」</span>でデフォルトを変更できます<br>ただし、ここでの設定箇所に<span class="marker-under-red">「Scripts」は自動作成</span>されるので、<span class="marker-under-red">「D:\Fusion360」</span>になります</p>



<p class="wp-block-paragraph">Fusionスクリプトは、Fusionオブジェクトモデルを介して、利用したいオブジェクトのコマンドを記述します。<br>したがって、スクリプトを作成するには、各オブジェクトの情報が必要となり、かなり複雑です。</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="677" height="437" src="https://www.kazuban.com/blog/wp-content/uploads/2025/07/Sketch-2.png" alt="" class="wp-image-11332" srcset="https://www.kazuban.com/blog/wp-content/uploads/2025/07/Sketch-2.png 677w, https://www.kazuban.com/blog/wp-content/uploads/2025/07/Sketch-2-500x323.png 500w, https://www.kazuban.com/blog/wp-content/uploads/2025/07/Sketch-2-300x194.png 300w" sizes="(max-width: 677px) 100vw, 677px" /></figure>



<p class="wp-block-paragraph"><br>今回は、Pythonの学習も兼ねて、Fusionのスケッチ関連オブジェクトをカプセル化したライブラリを作成したいと思います。</p>



<h3 class="wp-block-heading"><span id="toc10">ライブラリの登録場所とpythonでの実装方法</span></h3>



<p class="wp-block-paragraph">ライブラリフォルダは、Fusionが自動作成する、「Scripts」内の自作スクリプトと同じレベルに登録したいと思います</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">D:\Fusion360\Scripts<br>├── 新規スクリプト<br>├── CenterLine # 自作スクリプト<br>│ └── CenterLine.py # X,Y,Zの軸のセンターラインを作成する<br>│<br>├── library # 作成ライブラリ登録フォルダ<br>│ ├── <em>_init_</em>.py # 空ファイル（必要らしい）<br>│ ├── lib_util.py # Component &amp; Sketch 関連関数<br>│ └── lib_2d.py # 点や直線を作成（今後、円、円弧なども追加予定）<br></p>
</blockquote>



<p class="wp-block-paragraph">私の環境では、このようなイメージです。<br>「library」フォルダ内に「lib_util.py」「lib_2d.py」スクリプトを作成<br>「lib_util.py」は、Component や sketch を提供する基本関数を記述します<br>「lib_2d.py」は、点や直線を扱う関数を作成しますが、<span class="marker-under">「<strong>lib_util.py</strong>」の関数も利用します</span><br>今回はこの二つのライブラリを利用して、 X,Y,Zの軸のセンターラインを作成する「CenterLine /CenterLine.py」スクリプトを作成します</p>



<h3 class="wp-block-heading"><span id="toc11">実行スクリプトと同じレベルのスクリプトをインポートするには？</span></h3>



<p class="wp-block-paragraph">インポートするコードもわからないので、さっそくAiに聞いてみました<br>上記の構造をAiに渡して、実行スクリプト「CenterLine.py」から「lib_util.py」の関数を利用するコードを聞いてみました<br>この場合、正確なディレクトリ構造を取得する事が必要だと言うことで下記コードを教えてもらいました。</p>



<pre class="wp-block-code has-cocoon-white-color has-black-background-color has-text-color has-background has-link-color wp-elements-3"><code>current_dir = os.path.dirname(os.path.abspath(__file__))
script_dir = os.path.dirname(current_dir)</code></pre>



<p class="wp-block-paragraph">この構成はよくライブラリや設定ファイルを<span class="marker-under">相対パスで読み込むときの定番のコード</span>のようです<br>もう少し、詳しく説明してもらいました。</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">_file_：現在実行中のPythonスクリプトのファイルパス<br>os.path.abspath(__file__)：絶対パスに変換<br>os.path.dirname(…)：そのファイルが属するディレクトリを取得<br><br>D:/Fusion360/Scripts/<br>├── library/<br>│ └── __init__.py # モジュールの初期化用<br>│ └── lib_util.py<br>│ └── lib_2d.py<br>├── CenterLine/<br>│ └── CenterLine.py ← 実行スクリプト</p>



<p class="wp-block-paragraph">__file__ → &#8220;./CenterLine/CenterLine.py&#8221;<br>abspath(__file__) → &#8220;D:/Fusion360/Scripts/library/CenterLine/CenterLine.py&#8221;<br>current_dir → &#8220;D:/Fusion360/Scripts/library/CenterLine&#8221;<br>script_dir → &#8220;D:/Fusion360/Scripts/library&#8221;</p>
</blockquote>



<p class="wp-block-paragraph">このコードで、ライブラリのディレクトリを取り出し、<br>「sys.path.append(script_dir)」でpythonが内部でモジュール検索時に、指定ディレクトリを追加するの意味のようです<br>この設定後に、「from library import lib_util」コードで「library」ディレクトリ内の「lib_util.py」内の関数を使用できるようになります<br>具体的には、下記になります</p>



<pre class="wp-block-code has-cocoon-white-color has-black-background-color has-text-color has-background has-link-color wp-elements-4"><code>import os, sys

current_dir = os.path.dirname(os.path.abspath(__file__))
script_dir = os.path.dirname(current_dir)
sys.path.append(script_dir)
from <strong>library </strong>import <strong>lib_util</strong></code></pre>



<p class="wp-block-paragraph">これで、新規作成したスクリプトに、このコードを追加すると、「lib_util」内の関数が使えます<br>さらに「lib_2d.py」ライブラリも、「lib_util.py」の関数も利用しますが、こちらは、<span class="marker-under">「lib_util.py」と同じディレクトリ内</span>なので、「script_dir = os.path.dirname(current_dir)」のコードは<span class="marker-under-red">不要</span>になりますね</p>



<pre class="wp-block-code has-cocoon-white-color has-black-background-color has-text-color has-background has-link-color wp-elements-5"><code>import os, sys
current_dir = os.path.dirname(os.path.abspath(__file__))
<s><strong>#</strong> script_dir = os.path.dirname(current_dir)</s>
sys.path.append(current_dir)
import lib_util
</code></pre>



<p class="wp-block-paragraph">実際には結構時間がかかったのですが、これで、やっとライブラリが使えるようになりました。<br>本当、Ai様様です。<br>Aiの進歩で、コーディングの勉強は不要だとの意見もありますが、やっぱりコードの意味の理解は必要だと思います。<br>たぶん、Aiもそう思っているのでしょう！詳しいコメントを日本語で追記してくれます。<br>「あなたの言葉でコメントつけるから、覚えてね！」と言ってる気がします。<br>Ai利用でプログラミングの学習速度は、以前よりも圧倒的に速くなると思います</p>



<h2 class="wp-block-heading"><span id="toc12">ライブラリ利用方法</span></h2>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">./Scripts/<br>├── 新規スクリプト/ # &lt;&#8212;&#8212;&#8211; Fusion ダイアログで作成<br>│ └── 新規スクリプト.py<br>├── library/ #&lt;&#8212;&#8212;&#8212; Scripts/ 直下に作成<br>│ └── __init__.py # &lt;&#8212;&#8211; 空ファイル追加作成、モジュールの初期化用<br>│ └── lib_util.py # &lt;&#8212;&#8212;- ライブラリファイル<br>│ └── lib_2d.py # &lt;&#8212;&#8212;- ライブラリファイル<br>└── CenterLine/ # &lt;&#8212;&#8212;- 自作スクリプト用<br>│ └── CenterLine.py # &lt;&#8212;&#8212;- 自作スクリプトファイル<br>└─────── </p>
</blockquote>



<p class="wp-block-paragraph">イメージ的には、このようになります。<br>Fusionで「スクリプトまたはアドイン作成」を実行すると、設定ダイアログが表示され、設定した「フォルダの場所」へ設定した名前のフォルダが自動作成され、さらにその中に、設定した名前.py の実行ファイルが作成されます。</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="558" height="224" src="https://www.kazuban.com/blog/wp-content/uploads/2025/07/add-ins.png" alt="" class="wp-image-11358" srcset="https://www.kazuban.com/blog/wp-content/uploads/2025/07/add-ins.png 558w, https://www.kazuban.com/blog/wp-content/uploads/2025/07/add-ins-500x201.png 500w, https://www.kazuban.com/blog/wp-content/uploads/2025/07/add-ins-300x120.png 300w" sizes="(max-width: 558px) 100vw, 558px" /></figure>



<p class="wp-block-paragraph">今回紹介のライブラリは、Fusionで設定した「フォルダの場所」の直下に「library」の名前でフォルダを作成し、さらに「library」の直下に、「__init__.py」「lib_util.py」「lib_2d.py」を作成します<br>「__init__.py」は、空ファイルですが、Aiが言うには、ライブラリを利用する際必要みたいです。<br>「lib_util.py」「lib_2d.py」も一旦空ファイルを作っておいて、下記コードをコピペして保存します</p>



<h2 class="wp-block-heading"><span id="toc13">ライブラリを利用して、X,Y,Zの座標軸にセンターラインを描く</span></h2>



<p class="wp-block-paragraph">まずは、Fusion 「スクリプトとアドイン」で、新規スクリプトを作成します<br>ここでは「CenterLine」という名前にしました。<br>これで、「./Scripts」ディレクトリ内に、「CenterLine/CenterLine.py」が作成されています。<br>CenterLine.pyファイルの内容を、下記コードで上書きして保存します</p>



<h4 class="wp-block-heading"><span id="toc14">CenterLine.py</span></h4>



<pre class="wp-block-code has-cocoon-white-color has-black-background-color has-text-color has-background has-link-color wp-elements-6"><code>"""This file acts as the main module for this script."""

import traceback
import adsk.core
import adsk.fusion
# import adsk.cam

import os, sys, importlib
#library import
current_dir = os.path.dirname(os.path.abspath(__file__))
script_dir = os.path.dirname(current_dir)
sys.path.append(script_dir)
from library import lib_util,lib_2d

def run(context):
    try:
        lib_2d.draw_center_line(100,100,100)
 
    except:
        lib_util.disp_message('Failed:\n{}'.format(traceback.format_exc()))
</code></pre>



<p class="wp-block-paragraph">下記が、ライブラリ用スクリプトファイルです</p>



<h4 class="wp-block-heading"><span id="toc15">lib_util.py</span></h4>



<pre class="wp-block-code has-cocoon-white-color has-black-background-color has-text-color has-background has-link-color wp-elements-7"><code>import adsk.core, adsk.fusion, adsk.cam, traceback
from typing import Tuple, Optional

#このライブラリは
#Fusionが作成するスクリプトと同じディレクトリに置かれる事を想定している
#使用する場合には、下記コードにより読み込みパスを追加する
"""
import os, sys, importlib
current_dir = os.path.dirname(os.path.abspath(__file__))
script_dir = os.path.dirname(current_dir)
sys.path.append(script_dir)
from library import lib_util
"""
# ---------------------
## Get Fusion object
# ---------------------
def get_app():
    return adsk.core.Application.get()
def get_design():
    app = get_app() 
    return adsk.fusion.Design.cast(app.activeProduct)
def get_ui():
    app = get_app() 
    return app.userInterface

# ---------------------
## メッセージ表示
# ---------------------
def disp_message(msg: str):
    """ユーザーにメッセージボックスを表示"""
    ui = get_ui()
    if ui:
        ui.messageBox(msg)

# ---------------------
## Component &amp; Sketch Functions
# ---------------------
# /////////////////////////////////////////////////////////////
def get_root_component() -&gt; Optional&#91;adsk.fusion.Component]:
    """ルートコンポーネントを返す"""
    design = get_design()
    return design.rootComponent if design else None

# /////////////////////////////////////////////////////////////
def get_active_component() -&gt; Optional&#91;adsk.fusion.Component]:
    """現在アクティブなコンポーネントを返す"""
    design = get_design()
    return design.activeComponent if design else None

# /////////////////////////////////////////////////////////////
def create_new_component(name: str = 'New_Component') -&gt; Optional&#91;adsk.fusion.Component]:
    """新しいコンポーネントを作成し、アクティブなコンポーネントの配下に追加"""
    component = get_active_component()
    if not component:
        component = get_root_component()
    
    if not component:
        disp_message('コンポーネントが見つかりません。デザインがアクティブか確認してください。')
        return None
    
    try:
        occurrences = component.occurrences
        new_occurrence = occurrences.addNewComponent(adsk.core.Matrix3D.create())
        new_component = new_occurrence.component
        new_component.name = name
        return new_component
    except Exception:
        disp_message(f'新しいコンポーネントの作成に失敗しました:\n{traceback.format_exc()}')
        return None

# /////////////////////////////////////////////////////////////
def get_parent_sketch(obj: any) -&gt; Optional&#91;adsk.fusion.Sketch]:
    """指定されたオブジェクトの親スケッチを取得"""
    return obj.parentSketch if hasattr(obj, 'parentSketch') else None

# /////////////////////////////////////////////////////////////
def create_new_sketch(name: str = 'New_Sketch', plane: str = 'xy') -&gt; Optional&#91;adsk.fusion.Sketch]:
    """指定された平面に新しいスケッチを作成"""
    component = get_active_component()
    if not component:
        component = get_root_component()
    
    if not component:
        disp_message('スケッチを作成するコンポーネントが見つかりません。')
        return None
    
    plane = plane.lower()
    planes_map = {
        "xy": component.xYConstructionPlane,
        "xz": component.xZConstructionPlane,
        "yz": component.yZConstructionPlane
    }
    
    base_plane = planes_map.get(plane)
    if not base_plane:
        disp_message(f"サポートされていない平面: '{plane}' 'xy', 'xz', 'yz' のいずれかを選択してください。")
        return None
        
    try:
        sketches = component.sketches
        sketch = sketches.add(base_plane)
        sketch.name = name
        return sketch
    except Exception:
        disp_message(f'新しいスケッチの作成に失敗しました:\n{traceback.format_exc()}')
        return None

# /////////////////////////////////////////////////////////////
def is_sketch_mode_active() -&gt; Tuple&#91;bool, Optional&#91;adsk.fusion.Sketch]]:
    """現在スケッチモードがアクティブであるかを確認し、スケッチオブジェクトを返す"""
    app = get_app()
    active_object = app.activeEditObject
    # is_instance() を使うことで、より安全に型チェックを行う
    if isinstance(active_object, adsk.fusion.Sketch):
        return True, active_object
    else:
        return False, None

# /////////////////////////////////////////////////////////////
def get_sketch() -&gt; Optional&#91;adsk.fusion.Sketch]:
    """アクティブなスケッチを返す、アクティブでない場合は新しいスケッチを作成"""
    is_active, sketch = is_sketch_mode_active()
    if not is_active:
        sketch = create_new_sketch()
    return sketch
</code></pre>



<h4 class="wp-block-heading"><span id="toc16">lib_2d.py</span></h4>



<pre class="wp-block-code has-cocoon-white-color has-black-background-color has-text-color has-background has-link-color wp-elements-8"><code>import adsk.core, adsk.fusion, adsk.cam, traceback
from typing import Tuple, Optional

# 利用するlib_utilは、このライブラリと同じディレクトリ
import os, sys, importlib
current_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.append(current_dir)
import lib_util

# ---------------------
## カスタム、点基本クラス
# ---------------------
# /////////////////////////////////////////////////////////////
class kPoint:
    """3D空間の点を表す基本クラス"""
    def __init__(self, x: float, y: float, z: float = 0.0):
        self.x = x
        self.y = y
        self.z = z

# ---------------------
## カスタム、スケッチ点クラス
# ---------------------
# /////////////////////////////////////////////////////////////
class kSketchPoint(kPoint):
    """Fusion 360 のスケッチ点として使用される座標を、単位とスケッチ平面に応じて変換するクラス"""
    def __init__(self, x: float = 0.0, y: float = 0.0, z: float = 0.0, sketch: Optional&#91;adsk.fusion.Sketch] = None, unit: str = "mm"):
        unit = unit.lower()
        # 単位変換係数を辞書で管理
        scale_factors = {"mm": 0.1, "cm": 1.0, "m": 10.0}
        scale = scale_factors.get(unit, 1.0) # 存在しない単位は1.0 (cm) を使用

        if not sketch:
            sketch = lib_util.get_sketch() # スケッチが指定されていなければ、アクティブなスケッチを取得

        # スケッチ平面に応じて座標系を調整 (XZ平面はY軸が下向き)
        # 参照平面が'XZ'の場合は、y座標を反転させる
        # これはFusion 360の座標系の癖に対応
        direction_y = -1.0 if sketch and sketch.referencePlane.name == "XZ" else 1.0
        
        # 単位と座標系による方向を調整
        converted_x = x * scale
        converted_y = y * scale * direction_y
        converted_z = z * scale
        
        super().__init__(converted_x, converted_y, converted_z)
        self.sketch = sketch
        self.unit = unit
        
# ---------------------
## Sketch Geometry Creation Functions
# ---------------------
# /////////////////////////////////////////////////////////////
def is_equal_sketch_points(sp1: adsk.fusion.SketchPoint, sp2: adsk.fusion.SketchPoint, tolerance: float = 0.0001) -&gt; bool:
    """2つのスケッチ点が指定された許容差内で同じ位置にあるかどうかを判断"""
    # ジオメトリオブジェクトの距離を比較
    distance = sp1.geometry.distanceTo(sp2.geometry)
    return distance &lt; tolerance

# /////////////////////////////////////////////////////////////
def create_sketch_point(x: float = 0, y: float = 0, z: float = 0, sketch: Optional&#91;adsk.fusion.Sketch] = None) -&gt; Optional&#91;adsk.fusion.SketchPoint]:
    """指定された座標にスケッチ点を作成"""
    if not sketch:
        sketch = lib_util.get_sketch()
    
    if not sketch:
        lib_util.disp_message('スケッチがアクティブでないか、新しいスケッチの作成に失敗しました。')
        return None
        
    try:
        # kSketchPoint を使用して単位と平面を考慮した座標を取得
        converted_point = kSketchPoint(x, y, z, sketch)
        # adsk.core.Point3D オブジェクトを作成
        point3d = adsk.core.Point3D.create(converted_point.x, converted_point.y, converted_point.z)
        # スケッチに点を追加
        sketchPoint = sketch.sketchPoints.add(point3d)
        return sketchPoint
    except Exception:
        lib_util.disp_message(f'スケッチ点の作成に失敗しました:\n{traceback.format_exc()}')
        return None

# /////////////////////////////////////////////////////////////
def create_line_from_sketchpoints(sp1: adsk.fusion.SketchPoint, sp2: adsk.fusion.SketchPoint, construction: bool = False, fixed: bool = False) -&gt; Optional&#91;adsk.fusion.SketchLine]:
    """2つの既存のスケッチ点から直線を作成"""
    # 同じスケッチに属しているかチェック
    if lib_util.get_parent_sketch(sp1) != lib_util.get_parent_sketch(sp2):
        lib_util.disp_message('2つの点は異なるスケッチに属しています。')
        return None
        
    # 2つの点が同じ位置にあるかチェック
    if is_equal_sketch_points(sp1, sp2):
        lib_util.disp_message('2つの点が同じ位置にあります。直線を作成できません。')
        return None
        
    sketch = lib_util.get_parent_sketch(sp1)
    if not sketch:
        lib_util.disp_message('親スケッチが見つかりません。')
        return None
        
    try:
        line = sketch.sketchCurves.sketchLines.addByTwoPoints(sp1, sp2)
        line.isConstruction = construction
        line.isFixed = fixed
        return line
    except Exception:
        lib_util.disp_message(f'直線（スケッチ点から）の作成に失敗しました:\n{traceback.format_exc()}')
        return None

# /////////////////////////////////////////////////////////////
def create_line_from_coordinate(x1: float, y1: float, z1: float, x2: float, y2: float, z2: float, sketch: Optional&#91;adsk.fusion.Sketch] = None, construction: bool = False, fixed: bool = False) -&gt; Optional&#91;adsk.fusion.SketchLine]:
    """座標から直接、スケッチ直線を作成"""
    if not sketch:
        sketch = lib_util.get_sketch()

    if not sketch:
        return None

    # ヘルパー関数を利用して点を先に作成
    p1 = create_sketch_point(x1, y1, z1, sketch)
    p2 = create_sketch_point(x2, y2, z2, sketch)
    
    if p1 and p2:
        return create_line_from_sketchpoints(p1, p2, construction, fixed)
    else:
        lib_util.disp_message('直線を作成するための点の作成に失敗しました。')
        return None

# /////////////////////////////////////////////////////////////
def create_line_from_points(p1: kPoint, p2: kPoint, sketch: Optional&#91;adsk.fusion.Sketch] = None, construction: bool = False, fixed: bool = False) -&gt; Optional&#91;adsk.fusion.SketchLine]:
    """カスタム `kPoint` オブジェクトからスケッチ直線を作成"""
    if not sketch:
        sketch = lib_util.get_sketch()
    
    if not sketch:
        return None
        
    return create_line_from_coordinate(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, sketch, construction, fixed)

# /////////////////////////////////////////////////////////////
def draw_center_line(widthX=100,widthY=100,widthZ=100):
    """センターライン作成"""
    widthX = 100 if widthX == 0 else widthX
    widthY = 100 if widthY == 0 else widthY
    widthZ = 100 if widthZ == 0 else widthZ
    wx=widthX/2
    wy=widthY/2
    wz=widthZ/2
    sketch = lib_util.get_sketch()
    xp1 = kPoint(-wx,0)
    xp2 = kPoint(wx,0)
    yp1 = kPoint(0,-wy)
    yp2 = kPoint(0,wy)
    zp1 = kPoint(0,0,-wz)
    zp2 = kPoint(0,0,wz)
    create_line_from_points(xp1,xp2,sketch,True,True) #X Axis
    create_line_from_points(yp1,yp2,sketch,True,True) #Y Axis
    create_line_from_points(zp1,zp2,sketch,True,True) #Z Axis
</code></pre>



<h2 class="wp-block-heading"><span id="toc17">注意点</span></h2>



<p class="wp-block-paragraph">実は、まだ解決できていない注意点があります<br>通常のライブラリ使用では問題ないと思いますが、Fusionでライブラリを利用したスクリプトを実行後、<span class="marker-under-red">ライブラリ内スクリプトを編集しても、編集内容が反映されません。</span><br>Aiに聞いてみると、Fusionの仕様でキャッシュが優先されているとの事です<br>キャッシュクリアのコードも教えてもらいましたが、現状では反映されません。<br><span class="marker-under-red">ライブラリの編集を反映させるには、Fusionを再起動</span>させるとキャッシュがクリアされ反映されます<br>ライブラリを試行錯誤している場合でも、ちょっと面倒です。<br>いい方法は、ないのかなぁ～？？</p>



<h2 class="wp-block-heading"><span id="toc18">まとめ</span></h2>



<p class="wp-block-paragraph">pythonはド素人なので、勉強もかねて、Ai にコーディングを教えてもらいながら、FusionのComponentやsketch、直線作成などの関数をライブラリ化してみました。<br>Fusionオブジェクトモデルは、広範囲で奥が深いので、探すのも大変です。<br>よく使いそうな関数を、まとめたので、少しは取り組みやすくなるのではないか？と思っています。<br>今後も進化させようと思っていますが、Aiがなかったら、ここまで完成できなかったと思います。<br>ここで紹介しているコードも、一旦自分なりに作成したスクリプトを、Aiに張り付けて、添削してもらったコードを再編集したものです。<br>関数名やコメントの書き方なども、pythonの慣習を教えてもらい参考にしています</p>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
