Fusion 360 を Pythonで動かそう その９　スケッチの交差

#はじめに
Fusion360 のAPIの理解を深めるために公式ドキュメント内のサンプルコード [**Sketch Intersect API Sample (スケッチの交差 APIサンプル)**](http://help.autodesk.com/view/fusion360/ENU/?guid=GUID-bed462f4-6b51-11e7-bc60-6c0b84aa5a3f) の内容からドキュメントを読み込んでみたメモ書きです
指定されたエンティティをスケッチ平面と交差させ、その交差を表すスケッチ ジオメトリを作成します。

#スクリプトの内容を確認する
##最初と最後のおまじないから途中まで
最初と最後のお決まりのパターンについては [**その５**] (https://qiita.com/reisyu/items/c5544f877238b70730ce)で、スプライン曲線の作成は [**その７**] (https://qiita.com/reisyu/items/0fe79a2ad224606a562d)で、長方形の作成は[**その４**] (https://qiita.com/reisyu/items/b9b8ef714495ba1c5eda)で触れたので説明を省略します。

```Python
import adsk.core, adsk.fusion, traceback

def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui = app.userInterface
        
        # Create a document.
        doc = app.documents.add(adsk.core.DocumentTypes.FusionDesignDocumentType)
 
        product = app.activeProduct
        design = adsk.fusion.Design.cast(product)

        # Get the root component of the active design
        rootComp = design.rootComponent
        
        # Create a sketch
        sketches = rootComp.sketches
        sketch1 = sketches.add(rootComp.yZConstructionPlane)
        
        # Create an object collection for the points.
        points = adsk.core.ObjectCollection.create()

        # Define the points the spline with fit through.
        points.add(adsk.core.Point3D.create(-5, 0, 0))
        points.add(adsk.core.Point3D.create(5, 1, 0))
        points.add(adsk.core.Point3D.create(6, 4, 3))
        points.add(adsk.core.Point3D.create(7, 6, 6))
        points.add(adsk.core.Point3D.create(2, 3, 0))
        points.add(adsk.core.Point3D.create(0, 1, 0))

        # Create the spline.
        spline = sketch1.sketchCurves.sketchFittedSplines.add(points)

        # Get sketch lines
        sketchLines = sketch1.sketchCurves.sketchLines
        
        # Create sketch rectangle
        startPoint = adsk.core.Point3D.create(0, 0, 0)
        endPoint = adsk.core.Point3D.create(5.0, 5.0, 0)
        sketchLines.addTwoPointRectangle(startPoint, endPoint)
       
        #
        # ここにコードを追加していく
        #

    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
```
ここまでの内容でこのようなスプライン曲線と長方形ができます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/e3c0615b-9fd8-9086-09c3-3c98aecf4ef4.png)
このサンプルではスケッチの基準平面がYZ平面になっているのですが、Point3DのXYZ座標値とスケッチ内の座標系とグローバル座標系との関係がよくわからない・・・
Point3D の X 座標値がグローバル座標の -Z に Point3D の Y 座標値 が グローバル座標の Y になっている？？？


##スケッチから line を取得して変数に代入
```python
        # Get two sketch lines
        sketchLineOne = sketchLines.item(0)
        sketchLineTwo = sketchLines.item(1)
```
[**SketchLines.item メソッド**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-46298232-54aa-4382-a2cd-692a853a696f)でインデックス 0 と 1 のラインを取得して変数に代入する

##スケッチからプロファイルを取得して変数に代入
```python
        # Get the profile
        prof = sketch1.profiles.item(0)
```
`sketch1` の [**Sketch.profiles プロパティ**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-b4b9caca-1d80-4484-87d7-2809020098c9)で [**Profiles オブジェクト**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-84ff5e47-53c8-405a-b687-6820d97fb138)を取得し、[**Profiles.item メソッド**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-24f1f355-9ec5-4f3b-8a95-705a9a6487c2)で [**Profile オブジェクト**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-c9979c8d-a239-4ced-a6d7-93db7ffdf712)を取得して `prof` に代入する

##押し出しの準備
```python
        # Create an extrusion input
        extrudes = rootComp.features.extrudeFeatures
        extInput = extrudes.createInput(prof, adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
```
[**Component オブジェクト**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-b56b394e-b9c9-4403-a78b-a186b897909c)の [**features プロパティ**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-4f9cb3a1-b0fd-4c1c-bf15-09e4f3e9650a)で [**Features オブジェクト**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-7bfd8596-4584-48b6-8b9b-1ea63e304d34)を取得して、
[**Features オブジェクト**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-7bfd8596-4584-48b6-8b9b-1ea63e304d34)の [**extrudeFeatures プロパティ**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-4010527f-7198-47ff-9c4d-509de5c595c1)で [**ExtrudeFeatures オブジェクト**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-9fb394ce-8568-4729-9bb7-ebc196c91839)を取得し、`extrudes` に代入
[**ExtrudeFeatures オブジェクト**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-9fb394ce-8568-4729-9bb7-ebc196c91839)の [**createInput メソッド**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-82259ea9-ec01-48d7-a883-32fa0b16ae3c)で [**ExtrudeFeatureInput オブジェクト**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-b2548e39-b93a-4b44-8749-4a5115f85ae8)を作成し、`extInput`に代入

##押し出し距離の設定
```python
        # Define that the extent is a distance extent of 5 cm
        distance = adsk.core.ValueInput.createByReal(5.0)
```
押し出し距離を設定するためには[**ValueInput オブジェクト**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-bdeb52e0-a6af-4909-93e8-3b13acd0e39c)を作らなきゃいけないらしい。[**ValueInput.createByReal メソッド**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-0d1e5bcd-dfb7-4937-8d98-4e0a37e25568)で実数値 (5.0) を指定している。

##ExtrudeFeatureInput の設定（setDistanceExtent プロパティ）
```python
        # Set the distance extent
        extInput.setDistanceExtent(False, distance)
```
[**ExtrudeFeatureInput オブジェクト**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-b2548e39-b93a-4b44-8749-4a5115f85ae8)の **setDistanceExtent メソッド**がリファレンスマニュアルに見当たらなかったのでVSCODEで確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/cd15fba0-6130-b97e-7b9b-b54cf832cf4b.png)
一つ目の引数は対称にするかどうかを指定している

##ExtrudeFeatureInput の設定（isSolid プロパティ）
```python
        # Set the extrude type to be solid
        extInput.isSolid = True
```
[**isSolid プロパティ**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-4ecacc48-6a75-4d2d-9ec0-fb25fffa8b4d)を`True`に設定している。デフォルトが True なので省略してもよい


##押し出し
```python
        # Create the extrusion
        ext = extrudes.add(extInput)
```
[**ExtrudeFeatures.add メソッド**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-2b3f9fbf-4b60-479c-b4f3-bce9fa679ec2)で`ext`という名前の ExtrudeFeature オブジェクトを作成。
押し出しを作成するのに結構な手数がかかるのね・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/f37b09c4-3579-3070-9e8e-30f18e6cbef3.png)

##ボディから情報を取得して変数に代入
```python
        # Get the body with the extrude
        body = ext.bodies.item(0)
        
        # Get a vertex of the body
        vertex = body.vertices.item(5)
        
        # Get a face of the vertex
        face = vertex.faces.item(0)
```
[**ExtrudeFeature オブジェクト**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-62d132d3-2ae9-4d74-91d1-f2eee3d68f5d)の [**bodies プロパティ**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-442227a2-f587-46a6-b4f3-51a20826fa60)で [**BRepBodies オブジェクト**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-a763ee95-ae76-4c68-9f5b-e36c931a75da)を取得し、[**item メソッド**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-4571aa48-16fe-449b-9461-277513671e96)で インデックス 0 の [**BRepBody オブジェクト**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-9910880d-2299-4947-917a-39b5f030eef4)を取得して `body` に代入
[**BRepBody.vertices プロパティ**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-5ece7814-618d-48ab-a424-b9fe316777ff) で [**BRepBody.vertices オブジェクト**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-f572b822-df9e-48e9-920d-1335c653e300)を取得し、[**item メソッド**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-b219b046-9da2-4a0f-a05f-46d5053e2ba9)でインデックス 5 の[**BRepVertex オブジェクト**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-fd4574b4-c304-4d7b-a5f4-a6286bd223fd)を取得し、`vertex` に代入
 [**BRepVertex オブジェクト**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-fd4574b4-c304-4d7b-a5f4-a6286bd223fd)の [**faces プロパティ**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-9128e781-3ca8-44ce-8cc6-669376c86a75)で [**BRepFaces オブジェクト**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-5f0e3ae5-2ba6-4d2b-a3fe-93d2fb3f23af)を取得し、[**item メソッド**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-1e3f6f47-06b8-4d12-a97b-8385944d2f56)でインデックス 0 の [**BRepFace オブジェクト**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-1d41bd0a-3810-45e5-b4ce-4003123685d8)を取得し、`face ` に代入

##垂直軸の作成
```python
        # Create perpendicular construction axis
        axes = rootComp.constructionAxes
        axisInput = axes.createInput()
        axisInput.setByPerpendicularAtPoint(face, vertex)
        axis = axes.add(axisInput)
```
ルートコンポーネントの[**constructionAxes プロパティ**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-60313c30-700f-4dc0-a964-41ecd1cd4ab0)で [**ConstructionAxes オブジェクト**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-40fafab3-a963-4c7a-85a0-54fb962f8dd4)を取得して `axes` に代入
[**ConstructionAxes.createInput メソッド**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-3b3ec09d-20aa-4fdf-b7ab-db1707054e9a)で[**ConstructionAxisInput オブジェクト**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-cc20ff60-c9da-415b-9d2b-f7b2f9eaab16)を作成して `axisInput` に代入
[**setByPerpendicularAtPoint メソッド**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-d151e6d6-2961-4f17-88fb-74b30245ffd8)で指定された点で面に対して法線となる軸を作成する
`axes` に add メソッドで追加し `axis` に代入
axisInput をかませた手順がややこしい・・・

##コンストラクションポイントの作成
```python
         # Create construction point
        points = rootComp.constructionPoints
        pointInput = points.createInput()
        pointInput.setByTwoEdges(sketchLineOne, sketchLineTwo)
        point = points.add(pointInput)
```
軸の作成と同じような手順
[**constructionPoints オブジェクト**](http://help.autodesk.com/view/fusion360/ENU/?guid=GUID-31ddb2ae-0231-4094-8fdf-3c69da39de37)の [**createInput メソッド**](http://help.autodesk.com/view/fusion360/ENU/?guid=GUID-100eca65-4a79-4f02-8dd2-2967a5e3f106)で [**ConstructionPointInput オブジェクト**](http://help.autodesk.com/view/fusion360/ENU/?guid=GUID-b3ffae9a-d7d7-48ee-bd66-b1138536767f)を作成
[**setByTwoEdges メソッド**](http://help.autodesk.com/view/fusion360/ENU/?guid=GUID-1f1e9330-5e25-4641-9550-a314851afeaa)で 2つの直線的なエッジまたはスケッチラインの交点に施工点を作成する
`points` に add メソッドで追加し `point` に代入する

##コンストラクションプレーンの作成
```python
        # Create construction plane
        planes = rootComp.constructionPlanes
        planeInput = planes.createInput()
        offsetValue = adsk.core.ValueInput.createByReal(3.0)
        planeInput.setByOffset(prof, offsetValue)
        plane = planes.add(planeInput)
```
こちらも軸の作成と同じような手順。Input用のオブジェクトをかませる手順の理解を深めたい

##新しいスケッチの作成
```python
        # Create another sketch
        sketch2 = sketches.add(rootComp.xZConstructionPlane)
```

##entitiesというリストを作り色々とappend
```python
        entities = []
        entities.append(body) # body
        entities.append(face) # face
        entities.append(sketchLineOne) # edge 
        entities.append(vertex) # vertex
        entities.append(spline) # sketch curve
        entities.append(axis) # construction axis
        entities.append(point) # construction point
        entities.append(plane) # construction plane
```


##新しいスケッチの作成
```python
        sketchEntities = sketch2.intersectWithSketchPlane(entities)
```
[**Sketch.intersectWithSketchPlane メソッド**](https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-1EB28A55-7250-4694-A253-582B395AB234)で指定されたエンティティをスケッチ平面と交差させ、その交差を表すスケッチ・ジオメトリを作成し、`sketchEntities` に代入します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/1586ef6c-0622-0da0-a6a8-f710b83a937d.png)

#まとめ
Intersect に関するサンプルだったはずだけど Extrude や構築平面・軸・点に関する内容がややこしかった。もっと整理しながら進めないと理解が難しそう:sob:

前の記事　[Fusion 360 を Pythonで動かそう その８　スケッチのフィレットとオフセット](https://qiita.com/reisyu/items/5e7f21d55193b9dc9894)
次の記事　[Fusion 360 を Pythonで動かそう その10　理解しづらかったことのおさらい](https://qiita.com/reisyu/items/65673ecd7661a26730c8)

# 参考
[Fusion 360 API Reference Manual](http://help.autodesk.com/view/fusion360/ENU/?guid=GUID-7B5A90C8-E94C-48DA-B16B-430729B734DC)