Import modules

Create a vector

Vectors are one of the most
important pieces of information when building shapes. They usually contain three numbers
(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 simply a container
for a vector. You access the vector of a vertex like this:

ccircle will be created at distance 10 from the X origin and will be facing
outwards along the X axis. Note: makeCircle() only accepts Base.Vector() for the position
and normal parameters, not tuples. You can also create part of the circle by giving
a start and an end angle:

Create an arc along points

Unfortunately there is no makeArc() function, but we have the Part.Arc() function to
create an arc through three points. It creates an arc object
joining the start point to the end point through the middle point.
The arc object's toShape() function must be called to get an edge object,
the same as when using Part.LineSegment instead of Part.makeLine.

Create a bézier curve

Bézier curves are used to model smooth curves using a series of poles (points) and optional weights. The function below makes a Part.BezierCurve() from a series of FreeCAD.Vector() points. Note: when "getting" and "setting" a single pole or weight, indices start at 1, not 0.

Create an ellipse

Creates an ellipse with major radius 2 and minor radius 1 with the center at (0, 0, 0).

Part.Ellipse(Ellipse)

Creates a copy of the given ellipse.

Part.Ellipse(S1,S2,Center)

Creates an ellipse centered on the point Center, where the plane of the
ellipse is defined by Center, S1 and S2, its major axis is defined by
Center and S1, its major radius is the distance between Center and S1,
and its minor radius is the distance between S2 and the major axis.

Part.Ellipse(Center,MajorRadius,MinorRadius)

Creates an ellipse with major and minor radii MajorRadius and MinorRadius,
located in the plane defined by Center and the normal (0, 0, 1)

Create a torus

Using makeTorus(radius1, radius2, [pnt, dir, angle1, angle2, angle]).
By default pnt = Vector(0, 0, 0), dir = Vector(0, 0, 1), angle1 = 0, angle2 = 360 and angle = 360.
Consider a torus as small circle sweeping along a big circle. Radius1 is the
radius of the big circle, radius2 is the radius of the small circle, pnt is the center
of the torus and dir is the normal direction. angle1 and angle2 are angles in
degrees for the small circle; the last angle parameter is to make a section of
the torus:

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

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

Once our matrix is set, we can apply it to our shape. FreeCAD provides two
methods for doing 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). We can apply our transformation like this:

Scale 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 differently. For scaling, we
cannot use the transformShape(), we must use transformGeometry():

Explore shapes

By typing the lines above in the Python interpreter, you will gain a good
understanding of the structure of Part objects. Here, our makeBox() command
created a solid shape. This solid, like all Part solids, contains faces.
Faces always contain wires, which are lists of edges that border the face.
Each face has at least one closed wire (it can have more if the face has a hole).
In the wire, we can look at each edge separately, and inside each edge, we can
see the vertices. Straight edges have only two vertices, obviously.

Edge analysis

In case of an edge, which is an arbitrary curve, it's most likely you want to
do a discretization. In FreeCAD the edges are parametrized by their lengths.
That means you can walk an edge/curve by its length:

Now you can access a lot of properties of the edge by using the length as a
position. That means if the edge is 100mm long the start position is 0 and
the end position 100.

anEdge.tangentAt(0.0)# tangent direction at the beginninganEdge.valueAt(0.0)# Point at the beginninganEdge.valueAt(100.0)# Point at the end of the edgeanEdge.derivative1At(50.0)# first derivative of the curve in the middleanEdge.derivative2At(50.0)# second derivative of the curve in the middleanEdge.derivative3At(50.0)# third derivative of the curve in the middleanEdge.centerOfCurvatureAt(50)# center of the curvature for that positionanEdge.curvatureAt(50.0)# the curvatureanEdge.normalAt(50)# normal vector at that position (if defined)

Example: The OCC bottle

A typical example found on the OpenCasCade Technology website is how to build a bottle. This is a good exercise for FreeCAD too. In fact, if you follow our example below and the OCC page simultaneously, you will see how well OCC structures are implemented in FreeCAD. The script is included in the FreeCAD installation (inside the Mod/Part folder) and can be called from the Python interpreter by typing:

The script

For the purpose of this tutorial we will consider a reduced version of the script. In this version the bottle will not be hollowed out, and the neck of the bottle will not be threaded.

importPart,mathfromFreeCADimportBasedefmakeBottleTut(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.LineSegment(aPnt1,aPnt2)aSegment2=Part.LineSegment(aPnt4,aPnt5)aEdge1=aSegment1.toShape()aEdge2=aArcOfCircle.toShape()aEdge3=aSegment2.toShape()aWire=Part.Wire([aEdge1,aEdge2,aEdge3])aTrsf=Base.Matrix()aTrsf.rotateZ(math.pi)# rotate around the z-axisaMirroredWire=aWire.copy()aMirroredWire.transformShape(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)returnmyBodyel=makeBottleTut()Part.show(el)

Here we define our makeBottleTut function. This function can be called without
arguments, like we did above, in which case default values for width, height,
and thickness will be used. Then, we define a couple of points that will be used
for building our base profile.

Remember the difference between geometry and shapes? Here we build
shapes out of our construction geometry. Three edges (edges can be straight
or curved), then a wire made of those three edges.

...aTrsf=Base.Matrix()aTrsf.rotateZ(math.pi)# rotate around the z-axisaMirroredWire=aWire.copy()aMirroredWire.transformShape(aTrsf)myWireProfile=Part.Wire([aWire,aMirroredWire])

So far we have built only a half profile. Instead of building the whole profile
the same way, we can just mirror what we did and glue both halves together.
We first create a matrix. A matrix is a very common way to apply transformations
to objects in the 3D world, since it can contain in one structure all basic
transformations that 3D objects can undergo (move, rotate and scale).
After we create the matrix we mirror it, then we create a copy of our wire
and apply the transformation matrix to it. We now have two wires, and
we can make a third wire out of them, since wires are actually lists of edges.

Now that we have a closed wire, it can be turned into a face. Once we have a face,
we can extrude it. In doing so, we make a solid. Then we apply a nice little
fillet to our object because we care about good design, don't we?