Topological data scripting/jp

This page describes several methods for creating and modifying Part shapes from python. Before reading this page, if you are new to python, it is a good idea to read about python scripting and how python scripting works in FreeCAD.

はじめに
FreeCADのpythonインタプリタや外部のスクリプトから、直接、Partモジュールを操作する方法を説明します. まず スクリプティングを参照してください. FreeCADでのpythonスクリプトの方法についてより詳しい情報が必要な場合は FreeCADスクリプトの基本ページを参照してください.

クラス・ダイアグラム
これはPartモジュールの最も重要なクラスに関するUML (Unified Modeling Language)の概要図です：

ジオメトリ
ジオメトリオブジェクトは、トポロジーオブジェクトを構成するための基本要素です：
 * Geom ジオメトリオブジェクトの基底クラスです.
 * Line 始点と終点で定義された3次元の直線です.
 * Circle 中心と始点と終点で定義される円や円の断片です.
 * ...... じきに増えるでしょう;-)

トポロジー
次の種類のトポロジーのデータが利用できます：
 * Compound 任意の種類のトポロジーオブジェクトのグループです.
 * Compsolid ソリッドの合成とは、フェイスで接続するソリッドの集合です. ワイヤとシェルの概念をソリッドへ拡張したものです.
 * Solid（ソリッド） シェルで区切られた空間です. 3次元です.
 * Shell（シェル） エッジで接続しているフェイスの集合です. シェルは開閉できます.
 * Face（フェイス） 2次元では平面の一部分、3次元では表面の一部分です. 形状は輪郭線で律則されています（切り取られています）. 2次元です.
 * Wire（ワイヤ） 頂点で接続するエッジの集合です. エッジの接続に応じて、輪郭線は開閉します.
 * Edge（エッジ） 制約された曲線に対応する位相要素です. エッジは一般的に頂点によって律則されます. 1次元です.
 * Vertex（頂点） 点に対応するトポロジーの要素です. 0次元です.
 * Shape（シェイプ） 上記全ての一般的な総称です.

Quick example : Creating simple topology
We will now create a topology by constructing it out of simpler geometry. As a case study we use a part as seen in the picture which consists of four vertexes, two circles and two lines.

Creating Geometry
First we have to create the distinct geometric parts of this wire. And we have to take care that the vertexes of the geometric parts are at the same position. Otherwise later on we might not be able to connect the geometric parts to a topology!

So we create first the points:

from FreeCAD import Base V1 = Base.Vector(0,10,0) V2 = Base.Vector(30,10,0) V3 = Base.Vector(30,-10,0) V4 = Base.Vector(0,-10,0)

Arc
To create an arc of circle we make a helper point and create the arc of circle through three points:

VC1 = Base.Vector(-10,0,0) C1 = Part.Arc(V1,VC1,V4) VC2 = Base.Vector(40,0,0) C2 = Part.Arc(V2,VC2,V3)
 * 1) and the second one

Line
The line can be created very simple out of the points:

L1 = Part.Line(V1,V2) L2 = Part.Line(V4,V3)
 * 1) and the second one

Putting all together
The last step is to put the geometric base elements together and bake a topological shape:

S1 = Part.Shape([C1,C2,L1,L2])

Make a prism
Now extrude the wire in a direction and make an actual 3D shape:

W = Part.Wire(S1.Edges) P = W.extrude(Base.Vector(0,0,10))

Show it all
Part.show(P)

基本的な形状の作成
Partモジュールの"make ..."メソッドを使って、簡単に基本的なトポロジーオブジェクトを作成することができます.

b=Part.makeBox(100,100,100) Part.show(b)

使用可能な他のmake...メソッドです：


 * makeBox(l,w,h): 寸法が(l,w,h)で位置pからd方向を指す箱を作ります.
 * makeCircle(radius): 指定した半径の円を作ります.
 * makeCone(radius1,radius2,height): 指定した半径と高さの円錐を作成します.
 * makeCylinder(radius,height): 指定した半径と高さを持つ円柱を作成します.
 * makeLine((x1,y1,z1),(x2,y2,z2)): 二点間を結ぶ線を作成します.
 * makePlane(length,width): 指定した幅と長さの平面を作成します.
 * makePolygon(list): 点のリストからポリゴンを作成します.
 * makeSphere(radius): 指定された半径の球を作成します.
 * makeTorus(radius1,radius2): 指定した半径のトーラスを作ります.

See the Part API page for a complete list of available methods of the Part module.

Importing the needed modules
First we need to import the Part module so we can use its contents in python. We'll also import the Base module from inside the FreeCAD module:

import Part from FreeCAD import Base

頂点を作るには？
Vectors are one of the most important pieces of information when building shapes. They contain a 3 numbers usually (but not necessarily always) the x, y and z cartesian coordinates. You create a vector like this:

myVector = Base.Vector(3,2,0)

We just created a vector at coordinates x=3, y=2, z=0. In the Part module, vectors are used everywhere. Part shapes also use another kind of point representation, called Vertex, which is acually nothing else than a container for a vector. You access the vector of a vertex like this:

myVertex = myShape.Vertexes[0] print myVertex.Point > Vector (3, 2, 0)

エッジを作るには？
エッジとは2つの頂点からなる線に他なりません：

edge = Part.makeLine((0,0,0), (10,0,0)) edge.Vertexes > [, ]

注意: You can also create an edge by passing two vectors:

vec1 = Base.Vector(0,0,0) vec2 = Base.Vector(10,0,0) line = Part.Line(vec1,vec2) edge = line.toShape

You can find the length and center of an edge like this:

edge.Length > 10.0 edge.CenterOfMass > Vector (5, 0, 0)

Putting the shape on screen
So far we created an edge object, but it doesn't appear anywhere on screen. This is because we just manipulated python objects here. The FreeCAD 3D scene only displays what you tell it to display. To do that, we use this simple method:

Part.show(edge)

An object will be created in our FreeCAD document, and our "edge" shape will be attributed to it. Use this whenever it's time to display your creation on screen.

ワイヤを作るには？
ワイヤとは複数のエッジでエッジのリスト、またはワイヤのリストから作成することができます：

edge1 = Part.makeLine((0,0,0), (10,0,0)) edge2 = Part.makeLine((10,0,0), (10,10,0)) wire1 = Part.Wire([edge1,edge2]) edge3 = Part.makeLine((10,10,0), (0,10,0)) edge4 = Part.makeLine((0,10,0), (0,0,0)) wire2 = Part.Wire([edge3,edge4]) wire3 = Part.Wire([wire1,wire2]) wire3.Edges > [, , , ] Part.show(wire3)

Part.show(wire3) will display the 4 edges that compose our wire. Other useful information can be easily retrieved:

Part.show(wire3)はワイヤーを構成する4つの線を表示します. 他にも有用な情報を簡単に取得することができます：

wire3.Length > 40.0 wire3.CenterOfMass > Vector (5, 5, 0) wire3.isClosed > True wire2.isClosed > False

フェイスを作るには？
正しいフェイスは閉じたワイヤのみから作成することができます. この例では、wire3は閉じたワイヤですが、wire2（上記参照）は閉じていません.

face = Part.Face(wire3) face.Area > 99.999999999999972 face.CenterOfMass > Vector (5, 5, 0) face.Length > 40.0 face.isValid > True sface = Part.Face(wire2) face.isValid > False

フェイスは面積を持ちますが、ワイヤやエッジは面積を持ちません.

円を作るには？
円はこのようにシンプルに作成することができます：

circle = Part.makeCircle(10) circle.Curve > Circle (Radius : 10, Position : (0, 0, 0), Direction : (0, 0, 1))

位置と方向をもった円を作るにはこのように書きます.

ccircle = Part.makeCircle(10, Base.Vector(10,0,0), Base.Vector(1,0,0)) ccircle.Curve > Circle (Radius : 10, Position : (10, 0, 0), Direction : (1, 0, 0))

ccircleは、xの原点からの距離が10で、x軸を向くように作成されています. 注：makeCircleは、位置と法線として、タプルではなくBase.Vectorのみを受けとります. また開始角と終了角を与えることによって、円の一部を作成することができます：

from math import pi arc1 = Part.makeCircle(10, Base.Vector(0,0,0), Base.Vector(0,0,1), 0, 180) arc2 = Part.makeCircle(10, Base.Vector(0,0,0), Base.Vector(0,0,1), 180, 360)

arc1とarc2の両方を合わせると円になります. 角度は度単位で指定する必要があります. ラジアンが必要な場合は次の様に変換することができます. degrees = radians * 180/PI またはpythonの数学モジュールを使用します（import mathが必要です）：

degrees = math.degrees(radians)

点に通る弧を作るには？
残念ながらmakeArc関数はありませんが、三点を通る弧を作成するPart.Arc関数があります. この関数は、基本的には、中間点を通って開始点と終了点を結ぶ弧を仮定しています. Part.Arcは弧オブジェクトを作成します. 弧オブジェクトからエッジオブジェクトを作成するには.toShapeを呼びます. これはPart.makeLineの代わりにPart.Lineを使用した時と同じです.

arc = Part.Arc(Base.Vector(0,0,0),Base.Vector(0,5,0),Base.Vector(5,5,0)) arc >  arc_edge = arc.toShape

注意：Arcは点としてタプルではなくBase.Vectorのみを受け取ります. arc_edgeはPart.show(arc_edge)によって表示することができます. 円弧として円の一部を使用することも可能です：

from math import pi circle = Part.Circle(Base.Vector(0,0,0),Base.Vector(0,0,1),10) arc = Part.Arc(c,0,pi)

Arcs are valid edges, like lines. So they can be used in wires too.

ポリゴンを作るには？
ポリゴンは複数の真っ直ぐなエッジからできたワイヤーに他なりません. makePolygon関数は点のリストを受け取り、その点を通る線を作成します：

lshape_wire = Part.makePolygon([Base.Vector(0,5,0),Base.Vector(0,0,0),Base.Vector(5,0,0)])

平面を作るには？
平面は平坦な表面です. 作成するためのメソッドはmakePlane(length,width,[start_pnt,dir_normal])です. 初期値はstart_pnt=Vector(0,0,0)とdir_normal=Vector(0,0,1)です. dir_normal=Vector(0,0,1)はz軸に面した平面を作成します. dir_normal=Vector(1,0,0)はx軸に面した平面を作成します.

plane = Part.makePlane(2,2) plane > plane = Part.makePlane(2,2, Base.Vector(3,0,0), Base.Vector(0,1,0)) plane.BoundBox > BoundBox (3, 0, 0, 5, 0, 2)

BoundBoxは、その対角線が（3,0,0）から始まり（5,0,2)で終わる平面を囲む直方体です. このBoundBoxのy軸の厚さはゼロです. 注：makePlaneは、start_pntとdir_normalとしてタプルではなくBase.Vectorのみを受け取ります.

楕円を作るには？
楕円の作成にはいくつかの方法があります： Part.Ellipse

中心が(0,0,0)で、大半径2と小半径1の楕円を作成します.

Part.Ellipse(Ellipse)

楕円のコピーを作成します.

Part.Ellipse(S1,S2,Center)

点Centerを中心とする楕円を作成します. 楕円平面は、Center、S1とS2で定義されています. 主軸はCenterとS1で定義されています. 長径はCenterとS1の間の距離です 短径はS2と主軸との距離です.

Part.Ellipse(Center,MajorRadius,MinorRadius)

長径MajorRadius、短径MinorRadiusの楕円を作成し、 Centerと法線(0,0,1)で定義された平面上に配置します.

eli = Part.Ellipse(Base.Vector(10,0,0),Base.Vector(0,5,0),Base.Vector(0,0,0)) Part.show(eli.toShape)

上記のコードでは、S1、S2、および中心を渡しています. Arcと同様に、Ellipseも楕円オブジェクトを作りますが、エッジは作成しません. このため、楕円を表示するためにはtoShapeを使い、エッジに変換する必要があります.

注意：Arcはタプルではなく、Base.Vectorのみを受け取ります.

eli = Part.Ellipse(Base.Vector(0,0,0),10,5) Part.show(eli.toShape)

上記のEllipseのコンストラクタでは、中心座標、MajorRadius、MinorRadiusを渡しています.

トーラスを作るには？
makeTorus(radius1,radius2,[pnt,dir,angle1,angle2,angle])を使用します. 初期値は、pnt=Vector(0,0,0)、dir=Vector(0,0,1)、angle1=0、angle1=360、angle=360です. トーラスは小さな円が、大きな円に沿ってスイープしているものと考えます. radius1は大きい円の半径、radius2は小さい円の半径です. pntはトーラスの中心、dirは法線方向です. angle1とangle2は小さな円のラジアンの角度です. 最後のパラメータangleはトーラスの一部を作成するためのものです：

torus = Part.makeTorus(10, 2)

上記のコードは、直径20（半径10）と厚さ4（小さい円の半径2）のトーラスを作成します.

tor=Part.makeTorus(10,5,Base.Vector(0,0,0),Base.Vector(0,0,1),0,180)

上記のコードはトーラスのスライスを作成します.

tor=Part.makeTorus(10,5,Base.Vector(0,0,0),Base.Vector(0,0,1),0,360,180)

上記のコードは半分のトーラスを作成します. このコードでは最後のパラメータが変更されただけで、あとの角度は初期値のままです. 角度へ180与えた結果、0から180、つまり半分のトーラスを作成します.

ボックスまたは直方体を作るには？
makeBox(length,width,height,[pnt,dir])を使用します. 初期値はpnt=Vector(0,0,0)、dir=Vector(0,0,1)です.

box = Part.makeBox(10,10,10) len(box.Vertexes) > 8

球を作るには？
makeSphere(radius,[pnt, dir, angle1,angle2,angle3])を使用します. 初期値はpnt=Vector(0,0,0)、dir=Vector(0,0,1)、angle1=-90、angle2=90、angle3=360です. angle1とangle2は、球の垂直方向の最小値と最大値です. angle3は球の直径です.

sphere = Part.makeSphere(10) hemisphere = Part.makeSphere(10,Base.Vector(0,0,0),Base.Vector(0,0,1),-90,90,180)

円柱を作るには？
makeCylinder(radius,height,[pnt,dir,angle])を使用します. 初期値は、pnt=Vector(0,0,0)、dir=Vector(0,0,1)、angle=360=ベクトルです.

cylinder = Part.makeCylinder(5,20) partCylinder = Part.makeCylinder(5,20,Base.Vector(20,0,0),Base.Vector(0,0,1),180)

円錐を作るには？
makeCone(radius1,radius2,height,[pnt,dir,angle])を使用します. 初期値は、pnt=Vector(0,0,0)、dir=Vector(0,0,1)、angle=360=ベクトルです.

cone = Part.makeCone(10,0,20) semicone = Part.makeCone(10,0,20,Base.Vector(20,0,0),Base.Vector(0,0,1),180)

Modifying shapes
There are several ways to modify shapes. Some are simple transformation operations such as moving or rotating shapes, other are more complex, such as unioning and subtracting one shape from another. Be aware that

Translating a shape
Translating is the act of moving a shape from one place to another. Any shape (edge, face, cube, etc...) can be translated the same way:

myShape = Part.makeBox(2,2,2) myShape.translate(Base.Vector(2,0,0))

This will move our shape "myShape" 2 units in the x direction.

Rotating a shape
To rotate a shape, you need to specify the rotation center, the axis, and the rotation angle:

myShape.rotate(Vector(0,0,0),Vector(0,0,1),180)

The above code will rotate the shape 180 degrees around the Z Axis.

Generic transformations with matrixes
A matrix is a very convenient way to store transformations in the 3D world. In a single matrix, you can set translation, rotation and scaling values to be applied to an object. For example:

myMat = Base.Matrix myMat.move(Base.Vector(2,0,0)) myMat.rotateZ(math.pi/2)

Note: FreeCAD matrixes work in radians. Also, almost all matrix operations that take a vector can also take 3 numbers, so those 2 lines do the same thing:

myMat.move(2,0,0) myMat.move(Base.Vector(2,0,0))

When our matrix is set, we can apply it to our shape. FreeCAD provides 2 methods to do that: transformShape and transformGeometry. The difference is that with the first one, you are sure that no deformations will occur (see "scaling a shape" below). So we can apply our transformation like this:

myShape.trasformShape(myMat)

or

myShape.transformGeometry(myMat)

Scaling a shape
Scaling a shape is a more dangerous operation because, unlike translation or rotation, scaling non-uniformly (with different values for x, y and z) can modify the structure of the shape. For example, scaling a circle with a higher value horizontally than vertically will transform it into an ellipse, which behaves mathematically very differenty. For scaling, we can't use the transformShape, we must use transformGeometry:

myMat = Base.Matrix myMat.scale(2,1,1) myShape=myShape.transformGeometry(myMat)

あるシェイプを他のシェイプからカットするには？
Subtracting a shape from another one is called "cut" in OCC/FreeCAD jargon and is done like this:

cylinder = Part.makeCylinder(3,10,Base.Vector(0,0,0),Base.Vector(1,0,0)) sphere = Part.makeSphere(5,Base.Vector(5,0,0)) diff = cylinder.cut(sphere)

2つのシェイプ間の積を得るには？
The same way, the intersection between 2 shapes is called "common" and is done this way:

cylinder1 = Part.makeCylinder(3,10,Base.Vector(0,0,0),Base.Vector(1,0,0)) cylinder2 = Part.makeCylinder(3,10,Base.Vector(5,0,-5),Base.Vector(0,0,1)) common = cylinder1.common(cylinder2)

２つのシェイプ間の和をとるには？
Union is called "fuse" and works the same way:

cylinder1 = Part.makeCylinder(3,10,Base.Vector(0,0,0),Base.Vector(1,0,0)) cylinder2 = Part.makeCylinder(3,10,Base.Vector(5,0,-5),Base.Vector(0,0,1)) fuse = cylinder1.fuse(cylinder2)

ソリッドを与えられたシェイプで切断するには？
A Section is the intersection between a solid shape and a plane shape. It will return an intersection curve, a compound with edges

cylinder1 = Part.makeCylinder(3,10,Base.Vector(0,0,0),Base.Vector(1,0,0)) cylinder2 = Part.makeCylinder(3,10,Base.Vector(5,0,-5),Base.Vector(0,0,1)) section = cylinder1.section(cylinder2) section.Wires > [] section.Edges > [, , , , , , ]

Extrusion
Extrusion is the act of "pushing" a flat shape in a certain direction resulting in a solid body. Think of a circle becoming a tube by "pushing it out":

circle = Part.makeCircle(10) tube = circle.extrude(Base.Vector(0,0,2))

If your circle is hollow, you will obtain a hollow tube. If your circle is actually a disc, with a filled face, you will obtain a solid cylinder:

wire = Part.Wire(circle) disc = Part.makeFace(wire) cylinder = disc.extrude(Base.Vector(0,0,2))

シェイプを調査する
トポロジーのデータ構造は簡単に調べることができます： import Part b = Part.makeBox(100,100,100) b.Wires w = b.Wires[0] w w.Wires w.Vertexes Part.show(w) w.Edges e = w.Edges[0] e.Vertexes v = e.Vertexes[0] v.Point

上記の内容をPythonインタープリタに入力することで、Partオブジェクトの構造をよく理解することができます. ここでmakeBoxコマンドはソリッド形状を作成します. このソリッドはすべてのPartソリッドと同様に複数のフェイスを含んでいます. フェイスは常にその境界となるエッジのリストであるワイヤーを持ちます. 各フェイスは少なくとも1つの閉じたワイヤーを持ちます（フェイスが穴の場合は複数のワイヤーを持ちます）. ワイヤーでは各エッジを別々に調べることができ、またそのエッジでは各頂点を調べることができます. 直線のエッジは当然2つの頂点のみを持っています.

エッジを調査する
エッジの場合、エッジは任意の曲線であるので、おそらく離散化したいと思うでしょう. FreeCADでは、エッジはその長さによってパラメータ化されています. つまりその長さでエッジ/曲線を操作できるということです： import Part import Part box = Part.makeBox(100,100,100) anEdge = box.Edges[0] print anEdge.Length

この長さを位置として使用して多くのエッジのプロパティにアクセスすることができます. つまりエッジ長が100mmであれば、エッジの開始位置は0で終了位置は100であるということです.

anEdge.tangentAt(0.0) # 初期の接線方向です anEdge.valueAt(0.0) # エッジの開始点です anEdge.valueAt(100.0) # エッジの終点です anEdge.derivative1At(50.0) #　中点での曲線の一次導関数です anEdge.derivative2At(50.0) # 中点での曲線の二次導関数です anEdge.derivative3At(50.0) # 中点での曲線の三次導関数です anEdge.centerOfCurvatureAt(50) # この位置の曲率中心です anEdge.curvatureAt（50.0）# 曲率です anEdge.normalAt(50) # この位置の法線です（定義されている場合）

選択機能を使う
ここではユーザがビューア上で行う選択操作を使用する方法についてみていきます. まず最初にボックスを作成しそれをビューアで表示します

import Part Part.show(Part.makeBox(100,100,100)) Gui.SendMsgToActiveView("ViewFit")

フェイスかエッジを選択します. このスクリプトを使うと 全ての選択したオブジェクトとその子要素を反復することができます.

for o in Gui.Selection.getSelectionEx: print o.ObjectName for s in o.SubElementNames: print "name: ",s for s in o.SubObjects: print "object: ",s

エッジを選択し、このスクリプトでその長さを計算します: length = 0.0 for o in Gui.Selection.getSelectionEx: for s in o.SubObjects: length += s.Length print "Length of the selected edges:" ,length

OCCボトル
OpenCasCadeをはじめようにはボトルの作成方法についての典型的な例があります. これはFreeCADの教材としても最適です. 実際に以下のページの例とOCCのページの内容とを同時に追うことによって、OCCの構造がどのようにFreeCADの中に実装されているか理解できるでしょう. 以下のスクリプトはFreeCADのインストールにも含まれています（Mod/Partフォルダ内）. pythonインタプリタから次のようにタイプすることで呼び出すことができます: import Part import MakeBottle bottle = MakeBottle.makeBottle Part.show(bottle)

完全なスクリプト
MakeBottleスクリプト一式です：

import Part, FreeCAD, math from FreeCAD import Base def makeBottle(myWidth=50.0, myHeight=70.0, myThickness=30.0): aPnt1=Base.Vector(-myWidth/2.,0,0) aPnt2=Base.Vector(-myWidth/2.,-myThickness/4.,0) aPnt3=Base.Vector(0,-myThickness/2.,0) aPnt4=Base.Vector(myWidth/2.,-myThickness/4.,0) aPnt5=Base.Vector(myWidth/2.,0,0) aArcOfCircle = Part.Arc(aPnt2,aPnt3,aPnt4) aSegment1=Part.Line(aPnt1,aPnt2) aSegment2=Part.Line(aPnt4,aPnt5) aEdge1=aSegment1.toShape aEdge2=aArcOfCircle.toShape aEdge3=aSegment2.toShape aWire=Part.Wire([aEdge1,aEdge2,aEdge3]) aTrsf=Base.Matrix aTrsf.rotateZ(math.pi) # z軸周りを回転 aMirroredWire=aWire.transformGeometry(aTrsf) myWireProfile=Part.Wire([aWire,aMirroredWire]) myFaceProfile=Part.Face(myWireProfile) aPrismVec=Base.Vector(0,0,myHeight) myBody=myFaceProfile.extrude(aPrismVec) myBody=myBody.makeFillet(myThickness/12.0,myBody.Edges) neckLocation=Base.Vector(0,0,myHeight) neckNormal=Base.Vector(0,0,1) myNeckRadius = myThickness / 4. myNeckHeight = myHeight / 10 myNeck = Part.makeCylinder(myNeckRadius,myNeckHeight,neckLocation,neckNormal) myBody = myBody.fuse(myNeck) faceToRemove = 0 zMax = -1.0 for xp in myBody.Faces: try: surf = xp.Surface if type(surf) == Part.Plane: z = surf.Position.z               if z > zMax: zMax = z                   faceToRemove = xp        except: continue myBody = myBody.makeThickness([faceToRemove],-myThickness/50, 1.e-3) return myBody

詳細な説明
import Part, FreeCAD, math from FreeCAD import Base

PartモジュールはもちろんですがFreeCAD.Baseモジュールも必要です. このモジュールにはベクトルや行列といったFreeCADの基本構造が含まれています. def makeBottle(myWidth=50.0, myHeight=70.0, myThickness=30.0): aPnt1=Base.Vector(-myWidth/2.,0,0) aPnt2=Base.Vector(-myWidth/2.,-myThickness/4.,0) aPnt3=Base.Vector(0,-myThickness/2.,0) aPnt4=Base.Vector(myWidth/2.,-myThickness/4.,0) aPnt5=Base.Vector(myWidth/2.,0,0)

ここではmakeBottle関数を定義します. この関数は、上記の例のように、引数無しでも呼ぶことができます. その場合には、幅、高さ、厚さの初期値が使用されます. 次に基本的なプロファイルの構築に使用する点を定義します.

aArcOfCircle = Part.Arc(aPnt2,aPnt3,aPnt4) aSegment1=Part.Line(aPnt1,aPnt2) aSegment2=Part.Line(aPnt4,aPnt5)

ここでは実際のジオメトリを定義しています. 円弧を一つ、点を三つ、そして二点で構成される線分を二つ作ります. aEdge1=aSegment1.toShape aEdge2=aArcOfCircle.toShape aEdge3=aSegment2.toShape aWire=Part.Wire([aEdge1,aEdge2,aEdge3]) ジオメトリとシェイプの違いを覚えているでしょうか？ここでは、作成したジオメトリを使ってシェイプを作り上げています. 3つのエッジ（直線や曲線です）を作り、それらを使いワイヤーを一つ作成します. aTrsf=Base.Matrix aTrsf.rotateZ(math.pi) # rotate around the z-axis aMirroredWire=aWire.transformGeometry(aTrsf) myWireProfile=Part.Wire([aWire,aMirroredWire]) ここまでで、まだプロファイルは半分しか出来上がっていません. 同じ方法でプロファイル全体を作成するよりも、これまで作成したものをミラーして、2つの半分を一つにくっつけるほうが簡単です. それにはまず行列を作成します. 行列は3次元空間のオブジェクトを変換するとても一般的な方法です. 行列を使えば、3Dオブジェクトの厄介な基本的な変換（移動、回転、スケール）が一つで済むのです. ここでは行列を作成し、それを反転します. 作成したワイヤーにこの変換行列を適用してコピーを作ります. ここまで、2本のワイヤーができました. ワイヤーは、実際にはエッジのリストですので、これらのワイヤーから3つ目のワイヤーを作ることができます. myFaceProfile=Part.Face(myWireProfile) aPrismVec=Base.Vector(0,0,myHeight) myBody=myFaceProfile.extrude(aPrismVec) myBody=myBody.makeFillet(myThickness/12.0,myBody.Edges) すでに閉じたワイヤーがあるので、これをフェイスに変換することができます. フェイスを作ってしまえば、それを押し出すことができるようになります. このようにしてソリッドができました. では、次にこのオブジェクトに素敵なフィレットを少し使ってみましょう. デザインには気を使うでしょ？ neckLocation=Base.Vector(0,0,myHeight) neckNormal=Base.Vector(0,0,1) myNeckRadius = myThickness / 4. myNeckHeight = myHeight / 10 myNeck = Part.makeCylinder(myNeckRadius,myNeckHeight,neckLocation,neckNormal) これでボトルの本体はできました. あとはボトルの首を作成する必要があります. そこで、円柱で新しいソリッドを作成します.

myBody = myBody.fuse(myNeck)

他のアプリではユニオンとも呼ばれることもあるフューズ操作はとても強力な機能です. この操作は結合処理において結合すべきものと削除すべきものを管理します. return myBody

次にこの関数の結果としてPartソリッドを返します. このPartソリッドは、他のPartシェイプと同様に以下の方法でFreeCADドキュメント内のオブジェクトの属性になります. myObject = FreeCAD.ActiveDocument.addObject("Part::Feature","myObject") myObject.Shape = bottle あるいはもっとシンプルな方法もあります: Part.show(bottle)

読み込みと保存
Partモジュールの作業内容を保存する方法はいくつかあります. もちろんFreeCADドキュメントを保存することもできますが、PartオブジェクトをBREPやIGS、STEPやSTLなどの共通CADフォーマットに直接保存することもできます.

シェイプをファイルへ保存するのは簡単です. 全てのシェイプオブジェクトで、exportBre、pexportIges、exportStl、およびexportStepメソッドが利用できます. ではやってみましょう： import Part s = Part.makeBox(0,0,0,10,10,10) s.exportStep("test.stp")

ここではSTEPファイルへボックスを保存します. BREPやIGESやSTEPファイルを読み込むには、単純に反対の操作を行います：

import Part s = Part.Shape s.read（"test.stp"）

BREPやIGES、STEPファイルのインポートは、メニューの「File -> Open」か「File -> Import」からも直接行えます. エクスポートは「File -> Export」で行えます.