Topological data scripting/ru: Difference between revisions
(Updating to match new version of source page) |
(Updating to match new version of source page) |
||
Line 115: | Line 115: | ||
''Note: in FreeCAD 0.16 Part.Line was used, for FreeCAD 0.17 Part.LineSegment has to be used'' |
''Note: in FreeCAD 0.16 Part.Line was used, for FreeCAD 0.17 Part.LineSegment has to be used'' |
||
<div class="mw-translate-fuzzy"> |
|||
==== Соединяем все вместе ==== |
==== Соединяем все вместе ==== |
||
Последний шаг собираем все основные геометрические элементы вместе и получаем форму: |
Последний шаг собираем все основные геометрические элементы вместе и получаем форму: |
||
</div> |
|||
{{Code|code= |
{{Code|code= |
||
Line 145: | Line 147: | ||
}} |
}} |
||
<div class="mw-translate-fuzzy"> |
|||
Куча других доступных make...() методов: |
Куча других доступных make...() методов: |
||
* makeBox(l,w,h,[p,d]) -- Создает коробку расположенную в точке p и в указанном направлении d с размерами (l,w,h). По умолчанию p установлен как Vector(0,0,0) и d установлен как Vector(0,0,1) |
* makeBox(l,w,h,[p,d]) -- Создает коробку расположенную в точке p и в указанном направлении d с размерами (l,w,h). По умолчанию p установлен как Vector(0,0,0) и d установлен как Vector(0,0,1) |
||
Line 158: | Line 161: | ||
See the [[Part API]] page for a complete list of available methods of the Part module. |
See the [[Part API]] page for a complete list of available methods of the Part module. |
||
</div> |
|||
=== Подробные объяснения === |
=== Подробные объяснения === |
||
Line 170: | Line 174: | ||
==== Creating a Vector ==== |
==== Creating a Vector ==== |
||
[http://en.wikipedia.org/wiki/Euclidean_vector Vectors] are one of the most |
[http://en.wikipedia.org/wiki/Euclidean_vector Vectors] are one of the most |
||
important pieces of information when building shapes. They |
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: |
create a vector like this: |
||
Line 180: | Line 184: | ||
We just created a vector at coordinates x=3, y=2, z=0. In the Part module, |
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 |
vectors are used everywhere. Part shapes also use another kind of point |
||
representation |
representation called Vertex which is simply a container |
||
for a vector. You access the vector of a vertex like this: |
for a vector. You access the vector of a vertex like this: |
||
Line 218: | Line 222: | ||
==== Putting the shape on screen ==== |
==== Putting the shape on screen ==== |
||
So far we created an edge object, but it doesn't appear anywhere on screen. |
So far we created an edge object, but it doesn't appear anywhere on the screen. |
||
This is because |
This is because the FreeCAD 3D scene |
||
only displays what you tell it to display. To do that, we use this simple |
only displays what you tell it to display. To do that, we use this simple |
||
method: |
method: |
||
Line 227: | Line 231: | ||
}} |
}} |
||
The show function creates an object in our FreeCAD document and assigns our "edge" shape |
|||
to it. Use this whenever it is time to display your creation on screen. |
|||
creation on screen. |
|||
====Как создать ломанную кривую?==== |
====Как создать ломанную кривую?==== |
||
Line 296: | Line 299: | ||
}} |
}} |
||
<div class="mw-translate-fuzzy"> |
|||
Если вы хотите создать её с определенным положением и в определенном направлении |
Если вы хотите создать её с определенным положением и в определенном направлении |
||
</div> |
|||
{{Code|code= |
{{Code|code= |
||
Line 304: | Line 309: | ||
}} |
}} |
||
<div class="mw-translate-fuzzy"> |
|||
Окружность будет создана на расстоянии 10 от базовой(оригинальной) координаты х x и будет обращена в сторону оси x. |
Окружность будет создана на расстоянии 10 от базовой(оригинальной) координаты х x и будет обращена в сторону оси x. |
||
Примечание: makeCircleпринимает только тип Base.Vector() в качестве позиции и нормали а не кортеж. |
Примечание: makeCircleпринимает только тип Base.Vector() в качестве позиции и нормали а не кортеж. |
||
Вы также можете создать часть окружности, задав угол начальный и конечный угол, как тут: |
Вы также можете создать часть окружности, задав угол начальный и конечный угол, как тут: |
||
</div> |
|||
{{Code|code= |
{{Code|code= |
||
Line 314: | Line 321: | ||
}} |
}} |
||
<div class="mw-translate-fuzzy"> |
|||
Обе arc1 и arc2 вместе составляют окружность. |
Обе arc1 и arc2 вместе составляют окружность. |
||
Углы задаются в градусах, если вы хотите задать раддианами, просто преобразуйте используя формулу: |
Углы задаются в градусах, если вы хотите задать раддианами, просто преобразуйте используя формулу: |
||
Line 319: | Line 327: | ||
или используя pythonовский math модуль (прежде, конечно, выполнив import math): |
или используя pythonовский math модуль (прежде, конечно, выполнив import math): |
||
degrees = math.degrees(radians) |
degrees = math.degrees(radians) |
||
</div> |
|||
{{Code|code= |
{{Code|code= |
||
Line 347: | Line 356: | ||
from math import pi |
from math import pi |
||
circle = Part.Circle(Base.Vector(0,0,0),Base.Vector(0,0,1),10) |
circle = Part.Circle(Base.Vector(0,0,0),Base.Vector(0,0,1),10) |
||
arc = Part.Arc( |
arc = Part.Arc(circle,0,pi) |
||
}} |
}} |
||
Arcs are valid edges |
Arcs are valid edges like lines, so they can be used in wires also. |
||
<div class="mw-translate-fuzzy"> |
|||
====Как создать многоугольник или линию по точкам?==== |
====Как создать многоугольник или линию по точкам?==== |
||
Линия по нескольким точкам, не что иное как создание ломаной с множеством ребер. |
Линия по нескольким точкам, не что иное как создание ломаной с множеством ребер. |
||
функция makePolygon берет список точек и создает ломанную по этим точкам: |
функция makePolygon берет список точек и создает ломанную по этим точкам: |
||
</div> |
|||
{{Code|code= |
{{Code|code= |
||
Line 361: | Line 372: | ||
}} |
}} |
||
==== Creating a |
==== Creating 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.) |
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.) |
||
{{Code|code= |
{{Code|code= |
||
Line 372: | Line 383: | ||
}} |
}} |
||
<div class="mw-translate-fuzzy"> |
|||
====Как создать плоскость?==== |
====Как создать плоскость?==== |
||
Line 379: | Line 391: | ||
dir_normal=Vector(0,0,1) создат плоскость нормальную к оси z. |
dir_normal=Vector(0,0,1) создат плоскость нормальную к оси z. |
||
dir_normal=Vector(1,0,0) создат плоскость нормальную к оси х: |
dir_normal=Vector(1,0,0) создат плоскость нормальную к оси х: |
||
</div> |
|||
{{Code|code= |
{{Code|code= |
||
Line 384: | Line 397: | ||
plane |
plane |
||
><Face object at 028AF990> |
><Face object at 028AF990> |
||
plane = Part.makePlane(2,2, Base.Vector(3,0,0), Base.Vector(0,1,0)) |
plane = Part.makePlane(2, 2, Base.Vector(3,0,0), Base.Vector(0,1,0)) |
||
plane.BoundBox |
plane.BoundBox |
||
> BoundBox (3, 0, 0, 5, 0, 2) |
> BoundBox (3, 0, 0, 5, 0, 2) |
||
}} |
}} |
||
<div class="mw-translate-fuzzy"> |
|||
BoundBox является параллелепипед вмещающих плоскость с диагональю, начиная с (3,0,0) и концом в (5,0,2). |
BoundBox является параллелепипед вмещающих плоскость с диагональю, начиная с (3,0,0) и концом в (5,0,2). |
||
Здесь толщинаhe BoundBoxпо оси y равна нулю. |
Здесь толщинаhe BoundBoxпо оси y равна нулю. |
||
</div> |
|||
<div class="mw-translate-fuzzy"> |
|||
примечание: makePlane доступны только Base.Vector() для задания start_pnt и dir_normal а не кортежи |
примечание: makePlane доступны только Base.Vector() для задания start_pnt и dir_normal а не кортежи |
||
</div> |
|||
<div class="mw-translate-fuzzy"> |
|||
====Как создать эллипс?==== |
====Как создать эллипс?==== |
||
Создать эллипс можно несколькими путями: |
Создать эллипс можно несколькими путями: |
||
</div> |
|||
{{Code|code= |
{{Code|code= |
||
Line 402: | Line 421: | ||
}} |
}} |
||
<div class="mw-translate-fuzzy"> |
|||
Создает эллипс с большой полуосью 2 и малой полуосью 1 с центром |
Создает эллипс с большой полуосью 2 и малой полуосью 1 с центром |
||
в (0,0,0) |
в (0,0,0) |
||
</div> |
|||
{{Code|code= |
{{Code|code= |
||
Line 409: | Line 430: | ||
}} |
}} |
||
<div class="mw-translate-fuzzy"> |
|||
Создает копию данного эллипса |
Создает копию данного эллипса |
||
</div> |
|||
{{Code|code= |
{{Code|code= |
||
Line 425: | Line 448: | ||
}} |
}} |
||
<div class="mw-translate-fuzzy"> |
|||
Создает эллипс с большим и меньшим радиусом MajorRadius и |
Создает эллипс с большим и меньшим радиусом MajorRadius и |
||
MinorRadius, и расположенным в плоскости заданной точкой Center и |
MinorRadius, и расположенным в плоскости заданной точкой Center и |
||
нормалью (0,0,1) |
нормалью (0,0,1) |
||
</div> |
|||
{{Code|code= |
{{Code|code= |
||
Line 434: | Line 459: | ||
}} |
}} |
||
<div class="mw-translate-fuzzy"> |
|||
в приведенном выше коде мы ввели S1, S2 и center. |
в приведенном выше коде мы ввели S1, S2 и center. |
||
Аналогично Дуге, Эллипс также создает объект, а не ребро, |
Аналогично Дуге, Эллипс также создает объект, а не ребро, |
||
так что мы должны превратить его в ребро используя toShape() для отображения |
так что мы должны превратить его в ребро используя toShape() для отображения |
||
</div> |
|||
<div class="mw-translate-fuzzy"> |
|||
Примечание: Дуга допускает только Base.Vector() для задания точек, а не кортеж. |
Примечание: Дуга допускает только Base.Vector() для задания точек, а не кортеж. |
||
</div> |
|||
{{Code|code= |
{{Code|code= |
||
Line 445: | Line 474: | ||
}} |
}} |
||
<div class="mw-translate-fuzzy"> |
|||
Для верхнем конструкторе Эллипса мы ввели center, MajorRadius и MinorRadius |
Для верхнем конструкторе Эллипса мы ввели center, MajorRadius и MinorRadius |
||
</div> |
|||
<div class="mw-translate-fuzzy"> |
|||
====Как создать Тор?==== |
====Как создать Тор?==== |
||
Line 458: | Line 490: | ||
angle1 и angle2 углы в радианах для малого круга, создаст дугу |
angle1 и angle2 углы в радианах для малого круга, создаст дугу |
||
последний параметр angle создаст секцию(часть) тора: |
последний параметр angle создаст секцию(часть) тора: |
||
</div> |
|||
{{Code|code= |
{{Code|code= |
||
Line 463: | Line 496: | ||
}} |
}} |
||
<div class="mw-translate-fuzzy"> |
|||
В коде выше, был создан тор с диаметром 20(радиус 10) и толщиной 4(малая окружность радиусом 2) |
В коде выше, был создан тор с диаметром 20(радиус 10) и толщиной 4(малая окружность радиусом 2) |
||
</div> |
|||
{{Code|code= |
{{Code|code= |
||
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, 180) |
||
}} |
}} |
||
<div class="mw-translate-fuzzy"> |
|||
В приведенном выше коде, создан кусочек тора |
В приведенном выше коде, создан кусочек тора |
||
</div> |
|||
{{Code|code= |
{{Code|code= |
||
tor=Part.makeTorus(10,5,Base.Vector(0,0,0),Base.Vector(0,0,1),0,360,180) |
tor=Part.makeTorus(10, 5, Base.Vector(0,0,0), Base.Vector(0,0,1), 0, 360, 180) |
||
}} |
}} |
||
<div class="mw-translate-fuzzy"> |
|||
В приведенном выше коде, создан полу тор, изменен только последний параметр т.е. angle а остальные углы установлены по умолчанию. |
В приведенном выше коде, создан полу тор, изменен только последний параметр т.е. angle а остальные углы установлены по умолчанию. |
||
Подстановка угла 180 создаст тор от 0 до 180 т.е. половину |
Подстановка угла 180 создаст тор от 0 до 180 т.е. половину |
||
</div> |
|||
<div class="mw-translate-fuzzy"> |
|||
====Как создать блок или паралелепипед?==== |
====Как создать блок или паралелепипед?==== |
||
Line 484: | Line 524: | ||
По умолчанию pnt=Vector(0,0,0) и dir=Vector(0,0,1) |
По умолчанию pnt=Vector(0,0,0) и dir=Vector(0,0,1) |
||
</div> |
|||
{{Code|code= |
{{Code|code= |
||
Line 491: | Line 532: | ||
}} |
}} |
||
<div class="mw-translate-fuzzy"> |
|||
====Как создать Сферу?==== |
====Как создать Сферу?==== |
||
Line 497: | Line 539: | ||
angle1 и angle2 это вертиуальный минимум и максимум сферы(срезает часть сферы снизу или сверху), |
angle1 и angle2 это вертиуальный минимум и максимум сферы(срезает часть сферы снизу или сверху), |
||
angle3 определяет замкнутое ли это тело вращения или его секция |
angle3 определяет замкнутое ли это тело вращения или его секция |
||
</div> |
|||
{{Code|code= |
{{Code|code= |
||
Line 503: | Line 546: | ||
}} |
}} |
||
<div class="mw-translate-fuzzy"> |
|||
====Как создать Цилиндр?==== |
====Как создать Цилиндр?==== |
||
Line 508: | Line 552: | ||
По умолчанию pnt=Vector(0,0,0),dir=Vector(0,0,1) и angle=360 |
По умолчанию pnt=Vector(0,0,0),dir=Vector(0,0,1) и angle=360 |
||
</div> |
|||
<syntaxhighlight> |
|||
{{Code|code= |
|||
cylinder = Part.makeCylinder(5,20) |
cylinder = Part.makeCylinder(5,20) |
||
partCylinder = Part.makeCylinder(5,20,Base.Vector(20,0,0),Base.Vector(0,0,1),180) |
partCylinder = Part.makeCylinder(5,20,Base.Vector(20,0,0),Base.Vector(0,0,1),180) |
||
}} |
|||
</syntaxhighlight> |
|||
<div class="mw-translate-fuzzy"> |
|||
====Как создать Конус?==== |
====Как создать Конус?==== |
||
Line 517: | Line 563: | ||
По умолчанию pnt=Vector(0,0,0), dir=Vector(0,0,1) и angle=360 |
По умолчанию pnt=Vector(0,0,0), dir=Vector(0,0,1) и angle=360 |
||
</div> |
|||
<syntaxhighlight> |
|||
{{Code|code= |
|||
cone = Part.makeCone(10,0,20) |
cone = Part.makeCone(10,0,20) |
||
semicone = Part.makeCone(10,0,20,Base.Vector(20,0,0),Base.Vector(0,0,1),180) |
semicone = Part.makeCone(10,0,20,Base.Vector(20,0,0),Base.Vector(0,0,1),180) |
||
}} |
|||
</syntaxhighlight> |
|||
== Modifying shapes == |
== Modifying shapes == |
||
There are several ways to modify shapes. Some are simple transformation operations |
There are several ways to modify shapes. Some are simple transformation operations |
||
such as moving or rotating shapes, |
such as moving or rotating shapes, others are more complex, such as unioning and |
||
subtracting one shape from another. |
subtracting one shape from another. |
||
=== Transform operations === |
=== Transform operations === |
||
Line 531: | Line 578: | ||
Translating is the act of moving a shape from one place to another. |
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: |
Any shape (edge, face, cube, etc...) can be translated the same way: |
||
{{Code|code= |
|||
<syntaxhighlight> |
|||
myShape = Part.makeBox(2,2,2) |
myShape = Part.makeBox(2,2,2) |
||
myShape.translate(Base.Vector(2,0,0)) |
myShape.translate(Base.Vector(2,0,0)) |
||
}} |
|||
</syntaxhighlight> |
|||
This will move our shape "myShape" 2 units in the x direction. |
This will move our shape "myShape" 2 units in the x direction. |
||
Line 540: | Line 587: | ||
To rotate a shape, you need to specify the rotation center, the axis, |
To rotate a shape, you need to specify the rotation center, the axis, |
||
and the rotation angle: |
and the rotation angle: |
||
{{Code|code= |
|||
<syntaxhighlight> |
|||
myShape.rotate(Vector(0,0,0),Vector(0,0,1),180) |
myShape.rotate(Vector(0,0,0),Vector(0,0,1),180) |
||
}} |
|||
</syntaxhighlight> |
|||
The above code will rotate the shape 180 degrees around the Z Axis. |
The above code will rotate the shape 180 degrees around the Z Axis. |
||
Line 549: | Line 596: | ||
world. In a single matrix, you can set translation, rotation and scaling |
world. In a single matrix, you can set translation, rotation and scaling |
||
values to be applied to an object. For example: |
values to be applied to an object. For example: |
||
{{Code|code= |
|||
<syntaxhighlight> |
|||
myMat = Base.Matrix() |
myMat = Base.Matrix() |
||
myMat.move(Base.Vector(2,0,0)) |
myMat.move(Base.Vector(2,0,0)) |
||
myMat.rotateZ(math.pi/2) |
myMat.rotateZ(math.pi/2) |
||
}} |
|||
</syntaxhighlight> |
|||
Note: FreeCAD matrixes work in radians. Also, almost all matrix operations |
Note: FreeCAD matrixes work in radians. Also, almost all matrix operations |
||
that take a vector can also take |
that take a vector can also take three numbers, so these two lines do the same thing: |
||
{{Code|code= |
|||
<syntaxhighlight> |
|||
myMat.move(2,0,0) |
myMat.move(2,0,0) |
||
myMat.move(Base.Vector(2,0,0)) |
myMat.move(Base.Vector(2,0,0)) |
||
}} |
|||
</syntaxhighlight> |
|||
Once our matrix is set, we can apply it to our shape. FreeCAD provides two |
|||
methods |
methods for doing that: transformShape() and transformGeometry(). The difference |
||
is that with the first one, you are sure that no deformations will occur (see |
is that with the first one, you are sure that no deformations will occur (see |
||
"scaling a shape" below). |
"scaling a shape" below). We can apply our transformation like this: |
||
{{Code|code= |
|||
<syntaxhighlight> |
|||
myShape.trasformShape(myMat) |
|||
}} |
|||
</syntaxhighlight> |
|||
or |
or |
||
{{Code|code= |
|||
<syntaxhighlight> |
|||
myShape.transformGeometry(myMat) |
myShape.transformGeometry(myMat) |
||
}} |
|||
</syntaxhighlight> |
|||
==== Scaling a shape ==== |
==== Scaling a shape ==== |
||
Scaling a shape is a more dangerous operation because, unlike translation |
Scaling a shape is a more dangerous operation because, unlike translation |
||
Line 578: | Line 625: | ||
ellipse, which behaves mathematically very differently. For scaling, we |
ellipse, which behaves mathematically very differently. For scaling, we |
||
can't use the transformShape, we must use transformGeometry(): |
can't use the transformShape, we must use transformGeometry(): |
||
{{Code|code= |
|||
<syntaxhighlight> |
|||
myMat = Base.Matrix() |
myMat = Base.Matrix() |
||
myMat.scale(2,1,1) |
myMat.scale(2,1,1) |
||
myShape=myShape.transformGeometry(myMat) |
myShape=myShape.transformGeometry(myMat) |
||
}} |
|||
</syntaxhighlight> |
|||
=== Логические Операции === |
=== Логические Операции === |
||
Line 588: | Line 635: | ||
cut(...) - Вычисление различий задано в топологическом классе shape. |
cut(...) - Вычисление различий задано в топологическом классе shape. |
||
{{Code|code= |
|||
<syntaxhighlight> |
|||
cylinder = Part.makeCylinder(3,10,Base.Vector(0,0,0),Base.Vector(1,0,0)) |
cylinder = Part.makeCylinder(3,10,Base.Vector(0,0,0),Base.Vector(1,0,0)) |
||
sphere = Part.makeSphere(5,Base.Vector(5,0,0)) |
sphere = Part.makeSphere(5,Base.Vector(5,0,0)) |
||
diff = cylinder.cut(sphere) |
diff = cylinder.cut(sphere) |
||
}} |
|||
</syntaxhighlight> |
|||
<div class="mw-translate-fuzzy"> |
|||
====Как получить пересечение двух форм?==== |
====Как получить пересечение двух форм?==== |
||
common(...) - Пересечение задано в топологическом классе shape |
common(...) - Пересечение задано в топологическом классе shape |
||
</div> |
|||
<syntaxhighlight> |
|||
{{Code|code= |
|||
cylinder1 = Part.makeCylinder(3,10,Base.Vector(0,0,0),Base.Vector(1,0,0)) |
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)) |
cylinder2 = Part.makeCylinder(3,10,Base.Vector(5,0,-5),Base.Vector(0,0,1)) |
||
common = cylinder1.common(cylinder2) |
common = cylinder1.common(cylinder2) |
||
}} |
|||
</syntaxhighlight> |
|||
====Как объединить две формы?==== |
====Как объединить две формы?==== |
||
fuse(...) - Объединение задано в топологическом классе shape |
fuse(...) - Объединение задано в топологическом классе shape |
||
{{Code|code= |
|||
<syntaxhighlight> |
|||
cylinder1 = Part.makeCylinder(3,10,Base.Vector(0,0,0),Base.Vector(1,0,0)) |
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)) |
cylinder2 = Part.makeCylinder(3,10,Base.Vector(5,0,-5),Base.Vector(0,0,1)) |
||
fuse = cylinder1.fuse(cylinder2) |
fuse = cylinder1.fuse(cylinder2) |
||
}} |
|||
</syntaxhighlight> |
|||
<div class="mw-translate-fuzzy"> |
|||
====Как получить сечение тела и заданой формы?==== |
====Как получить сечение тела и заданой формы?==== |
||
Line 614: | Line 664: | ||
Вернет секущую кривую, состоящую из ребер |
Вернет секущую кривую, состоящую из ребер |
||
</div> |
|||
<syntaxhighlight> |
|||
{{Code|code= |
|||
cylinder1 = Part.makeCylinder(3,10,Base.Vector(0,0,0),Base.Vector(1,0,0)) |
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)) |
cylinder2 = Part.makeCylinder(3,10,Base.Vector(5,0,-5),Base.Vector(0,0,1)) |
||
Line 624: | Line 675: | ||
<Edge object at 0D86DE18>, <Edge object at 0D9B8E80>, <Edge object at 012A3640>, |
<Edge object at 0D86DE18>, <Edge object at 0D9B8E80>, <Edge object at 012A3640>, |
||
<Edge object at 0D8F4BB0>] |
<Edge object at 0D8F4BB0>] |
||
}} |
|||
</syntaxhighlight> |
|||
==== Extrusion ==== |
==== Extrusion ==== |
||
Extrusion is the act of "pushing" a flat shape in a certain direction resulting in |
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": |
a solid body. Think of a circle becoming a tube by "pushing it out": |
||
{{Code|code= |
|||
<syntaxhighlight> |
|||
circle = Part.makeCircle(10) |
circle = Part.makeCircle(10) |
||
tube = circle.extrude(Base.Vector(0,0,2)) |
tube = circle.extrude(Base.Vector(0,0,2)) |
||
}} |
|||
</syntaxhighlight> |
|||
If your circle is hollow, you will obtain a hollow tube. If your circle is actually |
If your circle is hollow, you will obtain a hollow tube. If your circle is actually |
||
a disc |
a disc with a filled face, you will obtain a solid cylinder: |
||
{{Code|code= |
|||
<syntaxhighlight> |
|||
wire = Part.Wire(circle) |
wire = Part.Wire(circle) |
||
disc = Part.Face(wire) |
disc = Part.Face(wire) |
||
cylinder = disc.extrude(Base.Vector(0,0,2)) |
cylinder = disc.extrude(Base.Vector(0,0,2)) |
||
}} |
|||
</syntaxhighlight> |
|||
== Исследование Форм == |
== Исследование Форм == |
||
Вы легко можете исследовать структуру топологических данных: |
Вы легко можете исследовать структуру топологических данных: |
||
{{Code|code= |
|||
<syntaxhighlight> |
|||
import Part |
import Part |
||
b = Part.makeBox(100,100,100) |
b = Part.makeBox(100,100,100) |
||
Line 656: | Line 707: | ||
v = e.Vertexes[0] |
v = e.Vertexes[0] |
||
v.Point |
v.Point |
||
}} |
|||
</syntaxhighlight> |
|||
Если ввести строчку выше в интепритатор python , вы получите хорошее представление об устройстве Part объектов. Здесь, наша команда makeBox() создает твердое тело. Это тело, как и все Part тела, содержит грани. Грани, всегда содержат ломанные, которые являются набором ребер ограничивающих грань. Каждая грань обладает ровно одной замкнутой ломаной. В ломанной, мы можем посмотреть на отдельно на каждое ребро, и по краям каждого ребра , мы можем увидеть вершины. Очевидно, что прямые ребра обладают только двумя вершинами. Вершины модуля Part являются OCC(OpenCascade) формами, но они обладают атрибутом Point который возвращает FreeCAD вектор. |
Если ввести строчку выше в интепритатор python , вы получите хорошее представление об устройстве Part объектов. Здесь, наша команда makeBox() создает твердое тело. Это тело, как и все Part тела, содержит грани. Грани, всегда содержат ломанные, которые являются набором ребер ограничивающих грань. Каждая грань обладает ровно одной замкнутой ломаной. В ломанной, мы можем посмотреть на отдельно на каждое ребро, и по краям каждого ребра , мы можем увидеть вершины. Очевидно, что прямые ребра обладают только двумя вершинами. Вершины модуля Part являются OCC(OpenCascade) формами, но они обладают атрибутом Point который возвращает FreeCAD вектор. |
||
=== Исследование Рёбер === |
=== Исследование Рёбер === |
||
В случае ребра, которое является произвольной кривой, вы наверняка захотите произвести дискретизицию. В FreeCAD ребра задаются с помощью параметра длинны. Это означает что вы можете перемещатся вдоль ребра/кривой задавая длинну: |
В случае ребра, которое является произвольной кривой, вы наверняка захотите произвести дискретизицию. В FreeCAD ребра задаются с помощью параметра длинны. Это означает что вы можете перемещатся вдоль ребра/кривой задавая длинну: |
||
{{Code|code= |
|||
<syntaxhighlight> |
|||
import Part |
import Part |
||
box = Part.makeBox(100,100,100) |
box = Part.makeBox(100,100,100) |
||
anEdge = box.Edges[0] |
anEdge = box.Edges[0] |
||
print anEdge.Length |
print anEdge.Length |
||
}} |
|||
</syntaxhighlight> |
|||
Теперь вы получить доступ ко всем свойствам ребра, с помощью длинны или позиции. Это означает, что у ребра |
Теперь вы получить доступ ко всем свойствам ребра, с помощью длинны или позиции. Это означает, что у ребра |
||
в 100mm длинной, начальная позиция это 0 а конечная это 100. |
в 100mm длинной, начальная позиция это 0 а конечная это 100. |
||
{{Code|code= |
|||
<syntaxhighlight> |
|||
anEdge.tangentAt(0.0) # tangent direction at the beginning |
anEdge.tangentAt(0.0) # tangent direction at the beginning |
||
anEdge.valueAt(0.0) # Point at the beginning |
anEdge.valueAt(0.0) # Point at the beginning |
||
Line 679: | Line 730: | ||
anEdge.curvatureAt(50.0) # the curvature |
anEdge.curvatureAt(50.0) # the curvature |
||
anEdge.normalAt(50) # normal vector at that position (if defined) |
anEdge.normalAt(50) # normal vector at that position (if defined) |
||
}} |
|||
</syntaxhighlight> |
|||
<div class="mw-translate-fuzzy"> |
|||
== Использование выделения(выбора) == |
== Использование выделения(выбора) == |
||
Здесь мы увидим как можно использовать "выделение", которое пользователь сделал в программе просмотра. |
Здесь мы увидим как можно использовать "выделение", которое пользователь сделал в программе просмотра. |
||
прежде всего мы создадим блок и отобразим его в окне просмотра |
прежде всего мы создадим блок и отобразим его в окне просмотра |
||
</div> |
|||
<syntaxhighlight> |
|||
{{Code|code= |
|||
import Part |
import Part |
||
Part.show(Part.makeBox(100,100,100)) |
Part.show(Part.makeBox(100,100,100)) |
||
Gui.SendMsgToActiveView("ViewFit") |
Gui.SendMsgToActiveView("ViewFit") |
||
}} |
|||
</syntaxhighlight> |
|||
<div class="mw-translate-fuzzy"> |
|||
Теперь выберем грани или ребра. С помощью этого сценария вы можете, поворить все выделенные объекты и их под элементы: |
Теперь выберем грани или ребра. С помощью этого сценария вы можете, поворить все выделенные объекты и их под элементы: |
||
</div> |
|||
<syntaxhighlight> |
|||
{{Code|code= |
|||
for o in Gui.Selection.getSelectionEx(): |
for o in Gui.Selection.getSelectionEx(): |
||
print o.ObjectName |
print o.ObjectName |
||
Line 696: | Line 751: | ||
for s in o.SubObjects: |
for s in o.SubObjects: |
||
print "object: ",s |
print "object: ",s |
||
}} |
|||
</syntaxhighlight> |
|||
Выделим несколько ребер и этот сценарий подсчитает их сумарную длину: |
Выделим несколько ребер и этот сценарий подсчитает их сумарную длину: |
||
{{Code|code= |
|||
<syntaxhighlight> |
|||
length = 0.0 |
length = 0.0 |
||
for o in Gui.Selection.getSelectionEx(): |
for o in Gui.Selection.getSelectionEx(): |
||
Line 704: | Line 759: | ||
length += s.Length |
length += s.Length |
||
print "Length of the selected edges:" ,length |
print "Length of the selected edges:" ,length |
||
}} |
|||
</syntaxhighlight> |
|||
<div class="mw-translate-fuzzy"> |
<div class="mw-translate-fuzzy"> |
||
=== OCC бутыль === |
=== OCC бутыль === |
||
Line 712: | Line 767: | ||
Готовый сценарий описанный ниже, также включен в установленный FreeCAD (в папке Mod/Part ) и может быть вызван интепритатором python, вводом: |
Готовый сценарий описанный ниже, также включен в установленный FreeCAD (в папке Mod/Part ) и может быть вызван интепритатором python, вводом: |
||
</div> |
</div> |
||
{{Code|code= |
|||
<syntaxhighlight> |
|||
import Part |
import Part |
||
import MakeBottle |
import MakeBottle |
||
bottle = MakeBottle.makeBottle() |
bottle = MakeBottle.makeBottle() |
||
Part.show(bottle) |
Part.show(bottle) |
||
}} |
|||
</syntaxhighlight> |
|||
==== Готовый сценарий ==== |
==== Готовый сценарий ==== |
||
Здесь представлен готовый сценарий MakeBottle: |
Здесь представлен готовый сценарий MakeBottle: |
||
{{Code|code= |
|||
<syntaxhighlight> |
|||
import Part, FreeCAD, math |
import Part, FreeCAD, math |
||
from FreeCAD import Base |
from FreeCAD import Base |
||
Line 776: | Line 831: | ||
el = makeBottle() |
el = makeBottle() |
||
Part.show(el) |
Part.show(el) |
||
}} |
|||
</syntaxhighlight> |
|||
==== Подробные объяснения ==== |
==== Подробные объяснения ==== |
||
{{Code|code= |
|||
<syntaxhighlight> |
|||
import Part, FreeCAD, math |
import Part, FreeCAD, math |
||
from FreeCAD import Base |
from FreeCAD import Base |
||
}} |
|||
</syntaxhighlight> |
|||
<div class="mw-translate-fuzzy"> |
|||
Нам ,конечно, необходимы Part модуль, а также FreeCAD.Base модуль, который содержит основные структуры FreeCAD такие как векторы и матрицы. |
Нам ,конечно, необходимы Part модуль, а также FreeCAD.Base модуль, который содержит основные структуры FreeCAD такие как векторы и матрицы. |
||
</div> |
|||
<syntaxhighlight> |
|||
{{Code|code= |
|||
def makeBottle(myWidth=50.0, myHeight=70.0, myThickness=30.0): |
def makeBottle(myWidth=50.0, myHeight=70.0, myThickness=30.0): |
||
aPnt1=Base.Vector(-myWidth/2.,0,0) |
aPnt1=Base.Vector(-myWidth/2.,0,0) |
||
Line 790: | Line 847: | ||
aPnt4=Base.Vector(myWidth/2.,-myThickness/4.,0) |
aPnt4=Base.Vector(myWidth/2.,-myThickness/4.,0) |
||
aPnt5=Base.Vector(myWidth/2.,0,0) |
aPnt5=Base.Vector(myWidth/2.,0,0) |
||
}} |
|||
</syntaxhighlight> |
|||
Здесь мы задаем нашу функцию makeBottle. Эта функция может быть вызвана без аргументов, как мы делали выше, в этом случае будут использоваться значения по умолчанию для ширины, высоты и толщины. Затем мы определили несколько точек которые будут использоваться для построения базового сечения. |
Здесь мы задаем нашу функцию makeBottle. Эта функция может быть вызвана без аргументов, как мы делали выше, в этом случае будут использоваться значения по умолчанию для ширины, высоты и толщины. Затем мы определили несколько точек которые будут использоваться для построения базового сечения. |
||
{{Code|code= |
|||
<syntaxhighlight> |
|||
aArcOfCircle = Part.Arc(aPnt2,aPnt3,aPnt4) |
aArcOfCircle = Part.Arc(aPnt2,aPnt3,aPnt4) |
||
aSegment1=Part.LineSegment(aPnt1,aPnt2) |
aSegment1=Part.LineSegment(aPnt1,aPnt2) |
||
aSegment2=Part.LineSegment(aPnt4,aPnt5) |
aSegment2=Part.LineSegment(aPnt4,aPnt5) |
||
}} |
|||
</syntaxhighlight> |
|||
<div class="mw-translate-fuzzy"> |
|||
Здесь мы фактически задаём геометрию: дугу, созданую по 3 точкам, и два линейных сегменты, созданные по 2 точкам. |
Здесь мы фактически задаём геометрию: дугу, созданую по 3 точкам, и два линейных сегменты, созданные по 2 точкам. |
||
</div> |
|||
<syntaxhighlight> |
|||
{{Code|code= |
|||
aEdge1=aSegment1.toShape() |
aEdge1=aSegment1.toShape() |
||
aEdge2=aArcOfCircle.toShape() |
aEdge2=aArcOfCircle.toShape() |
||
aEdge3=aSegment2.toShape() |
aEdge3=aSegment2.toShape() |
||
aWire=Part.Wire([aEdge1,aEdge2,aEdge3]) |
aWire=Part.Wire([aEdge1,aEdge2,aEdge3]) |
||
}} |
|||
</syntaxhighlight> |
|||
<div class="mw-translate-fuzzy"> |
|||
Запомнили раличие между геометрией и формой? Здесь мы создаем форму из нашей строительной геометрии 3 рёбер (ребра могут быть прямыми или кривыми), затем из рёбер создается ломанная. |
Запомнили раличие между геометрией и формой? Здесь мы создаем форму из нашей строительной геометрии 3 рёбер (ребра могут быть прямыми или кривыми), затем из рёбер создается ломанная. |
||
</div> |
|||
<syntaxhighlight> |
|||
{{Code|code= |
|||
aTrsf=Base.Matrix() |
aTrsf=Base.Matrix() |
||
aTrsf.rotateZ(math.pi) # rotate around the z-axis |
aTrsf.rotateZ(math.pi) # rotate around the z-axis |
||
aMirroredWire=aWire.transformGeometry(aTrsf) |
aMirroredWire=aWire.transformGeometry(aTrsf) |
||
myWireProfile=Part.Wire([aWire,aMirroredWire]) |
myWireProfile=Part.Wire([aWire,aMirroredWire]) |
||
}} |
|||
</syntaxhighlight> |
|||
<div class="mw-translate-fuzzy"> |
|||
На данный момент мы построили только половину сечения. Проще, чем строить таким же образом целое сечение, мы можем просто отразить то что мы сделали и склеить две половинки. Сначала создадим матрицу(Нео ау). Матрица является распространенным способом произвести изменения над объектом в 3D пространстве, также она может содержать в одной структуре все базовые преобразования которые позволяют 3D объекты(перемещение, вращение и масштабирование). Здесь , после создания матрицы, мы отражаем её и создаем копию нашеё ломанной, применя к ней преобразование матрицой. Теперь мы получили две ломанные и мы можем создать из них третью ломаную, так как ломанные это всего лишь список ребер. |
На данный момент мы построили только половину сечения. Проще, чем строить таким же образом целое сечение, мы можем просто отразить то что мы сделали и склеить две половинки. Сначала создадим матрицу(Нео ау). Матрица является распространенным способом произвести изменения над объектом в 3D пространстве, также она может содержать в одной структуре все базовые преобразования которые позволяют 3D объекты(перемещение, вращение и масштабирование). Здесь , после создания матрицы, мы отражаем её и создаем копию нашеё ломанной, применя к ней преобразование матрицой. Теперь мы получили две ломанные и мы можем создать из них третью ломаную, так как ломанные это всего лишь список ребер. |
||
</div> |
|||
<syntaxhighlight> |
|||
{{Code|code= |
|||
myFaceProfile=Part.Face(myWireProfile) |
myFaceProfile=Part.Face(myWireProfile) |
||
aPrismVec=Base.Vector(0,0,myHeight) |
aPrismVec=Base.Vector(0,0,myHeight) |
||
myBody=myFaceProfile.extrude(aPrismVec) |
myBody=myFaceProfile.extrude(aPrismVec) |
||
myBody=myBody.makeFillet(myThickness/12.0,myBody.Edges) |
myBody=myBody.makeFillet(myThickness/12.0,myBody.Edges) |
||
}} |
|||
</syntaxhighlight> |
|||
<div class="mw-translate-fuzzy"> |
|||
Теперь мы получили замкнутую ломаную, которую можно обратить в грань. После мы получили грань, мы можем вытянуть её. Сделаа это ,мы действительно получим твердое тело. Теперь мы добавим небольшое скругление к нашему объекту, потому что мы заботимся о качественном дизайне, разве нет? |
Теперь мы получили замкнутую ломаную, которую можно обратить в грань. После мы получили грань, мы можем вытянуть её. Сделаа это ,мы действительно получим твердое тело. Теперь мы добавим небольшое скругление к нашему объекту, потому что мы заботимся о качественном дизайне, разве нет? |
||
</div> |
|||
<syntaxhighlight> |
|||
{{Code|code= |
|||
neckLocation=Base.Vector(0,0,myHeight) |
neckLocation=Base.Vector(0,0,myHeight) |
||
neckNormal=Base.Vector(0,0,1) |
neckNormal=Base.Vector(0,0,1) |
||
Line 825: | Line 890: | ||
myNeckHeight = myHeight / 10 |
myNeckHeight = myHeight / 10 |
||
myNeck = Part.makeCylinder(myNeckRadius,myNeckHeight,neckLocation,neckNormal) |
myNeck = Part.makeCylinder(myNeckRadius,myNeckHeight,neckLocation,neckNormal) |
||
}} |
|||
</syntaxhighlight> |
|||
<div class="mw-translate-fuzzy"> |
|||
Теперь когда тело нашей бутыли создано, нам нужно создать горлышко. Так мы создаем новое твердое тело ,это цилиндр. |
Теперь когда тело нашей бутыли создано, нам нужно создать горлышко. Так мы создаем новое твердое тело ,это цилиндр. |
||
</div> |
|||
<syntaxhighlight> |
|||
{{Code|code= |
|||
myBody = myBody.fuse(myNeck) |
myBody = myBody.fuse(myNeck) |
||
}} |
|||
</syntaxhighlight> |
|||
<div class="mw-translate-fuzzy"> |
|||
Очень мощная операция слияния, которая обычно называется в других приложениях объединением. Она заботится о склеивании, о том что должно быть приклено и удаляет детали которые нужно удалить. |
Очень мощная операция слияния, которая обычно называется в других приложениях объединением. Она заботится о склеивании, о том что должно быть приклено и удаляет детали которые нужно удалить. |
||
</div> |
|||
<syntaxhighlight> |
|||
{{Code|code= |
|||
return myBody |
return myBody |
||
}} |
|||
</syntaxhighlight> |
|||
<div class="mw-translate-fuzzy"> |
<div class="mw-translate-fuzzy"> |
||
Теперь мы получаем нашу твердотельную Деталь как результат нашей функции. Это Деталь - твердотельная, как и любая другая Деталь форма, может быть свзана с объектом в документе FreeCAD, с помошью: |
Теперь мы получаем нашу твердотельную Деталь как результат нашей функции. Это Деталь - твердотельная, как и любая другая Деталь форма, может быть свзана с объектом в документе FreeCAD, с помошью: |
||
</div> |
</div> |
||
{{Code|code= |
|||
<syntaxhighlight> |
|||
el = makeBottle() |
el = makeBottle() |
||
Part.show(el) |
Part.show(el) |
||
}} |
|||
</syntaxhighlight> |
|||
<div class="mw-translate-fuzzy"> |
<div class="mw-translate-fuzzy"> |
||
или , ещё проще: |
или , ещё проще: |
||
Line 846: | Line 915: | ||
==Box pierced== |
==Box pierced== |
||
Here a complete example of building a |
Here is a complete example of building a pierced box. |
||
The construction is done side |
The construction is done one side at a time; when the cube is finished, it is hollowed out by cutting a cylinder through it. |
||
{{Code|code= |
|||
<syntaxhighlight> |
|||
import Draft, Part, FreeCAD, math, PartGui, FreeCADGui, PyQt4 |
import Draft, Part, FreeCAD, math, PartGui, FreeCADGui, PyQt4 |
||
from math import sqrt, pi, sin, cos, asin |
from math import sqrt, pi, sin, cos, asin |
||
Line 896: | Line 965: | ||
Part.show(cut_part) |
Part.show(cut_part) |
||
}} |
|||
</syntaxhighlight> |
|||
== Загрузка и Сохранение == |
== Загрузка и Сохранение == |
||
Есть несколько путей чтобы сохранения вышей работы в Part модули. Вы конечно можете сохранить ваш FreeCAD документ, а также вы можете сохранить Part(Деталь) объект напрямую в обычные CAD форматы, такие как BREP, IGS, STEP и STL. |
Есть несколько путей чтобы сохранения вышей работы в Part модули. Вы конечно можете сохранить ваш FreeCAD документ, а также вы можете сохранить Part(Деталь) объект напрямую в обычные CAD форматы, такие как BREP, IGS, STEP и STL. |
||
<div class="mw-translate-fuzzy"> |
|||
Сохраненить форму в файл , легко. Есть доступные для всех форм методы exportBrep(), exportIges(), exportStl() и exportStep() . Таким образом: |
Сохраненить форму в файл , легко. Есть доступные для всех форм методы exportBrep(), exportIges(), exportStl() и exportStep() . Таким образом: |
||
</div> |
|||
<syntaxhighlight> |
|||
{{Code|code= |
|||
import Part |
import Part |
||
s = Part.makeBox(0,0,0,10,10,10) |
s = Part.makeBox(0,0,0,10,10,10) |
||
s.exportStep("test.stp") |
s.exportStep("test.stp") |
||
}} |
|||
</syntaxhighlight> |
|||
<div class="mw-translate-fuzzy"> |
|||
это сохранит наш блок в файл формата STEP. Для загрузки BREP, IGES или STEP файлов, просто сделайте наоборот: |
это сохранит наш блок в файл формата STEP. Для загрузки BREP, IGES или STEP файлов, просто сделайте наоборот: |
||
</div> |
|||
<syntaxhighlight> |
|||
{{Code|code= |
|||
import Part |
import Part |
||
s = Part.Shape() |
s = Part.Shape() |
||
s.read("test.stp") |
s.read("test.stp") |
||
}} |
|||
</syntaxhighlight> |
|||
To convert an '''.stp''' |
To convert an '''.stp''' file to an '''.igs''' file: |
||
{{Code|code= |
|||
<syntaxhighlight> |
|||
import Part |
import Part |
||
s = Part.Shape() |
s = Part.Shape() |
||
s.read("file.stp") # incoming file igs, stp, stl, brep |
s.read("file.stp") # incoming file igs, stp, stl, brep |
||
s.exportIges("file.igs") # outbound file igs |
s.exportIges("file.igs") # outbound file igs |
||
}} |
|||
</syntaxhighlight> |
|||
<div class="mw-translate-fuzzy"> |
|||
Примечание этот импорт или открытие BREP, IGES or STEP файлов также можно сделать напрямую с помощью меню File -> Open or File -> Import. На данный момент экспорт ещё не включен, но будет там в ближайшее время. |
Примечание этот импорт или открытие BREP, IGES or STEP файлов также можно сделать напрямую с помощью меню File -> Open or File -> Import. На данный момент экспорт ещё не включен, но будет там в ближайшее время. |
||
</div> |
|||
{{docnav/ru|Mesh Scripting/ru|Mesh to Part/ru}} |
{{docnav/ru|Mesh Scripting/ru|Mesh to Part/ru}} |
||
{{Userdocnavi}} |
|||
<div class="mw-translate-fuzzy"> |
|||
[[Category:Poweruser Documentation/ru]] |
[[Category:Poweruser Documentation/ru]] |
||
[[Category:Python Code/ru]] |
[[Category:Python Code/ru]] |
||
</div> |
|||
[[Category:Python Code]] |
|||
Revision as of 14:11, 23 February 2019
Руководство |
Тема |
---|
Programming |
Уровень |
Intermediate |
Время для завершения |
Авторы |
FreeCAD версия |
Примеры файлов |
Смотрите также |
None |
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.
Introduction
We will here explain you how to control the Part Module directly from the FreeCAD python interpreter, or from any external script. The basics about Topological data scripting are described in Part Module Explaining the concepts. Be sure to browse the Scripting section and the FreeCAD Scripting Basics pages if you need more information about how python scripting works in FreeCAD.
Здесь мы объясним вам как управлять Модулем Деталей напрямую из интепритатора python FreeCAD, или из любого внешнего сценария. Для уверенности , просмотрите раздел Написание Сценариев и страницу Основ сценариев в FreeCAD если вам необходимо больше информации, о том как работает написание сценариев в FreeCAD.
Для первого использования функциональности модуля Деталей вы должны загрузить модуль Деталей в интепретатор:
import Part
Диаграмма Классов
Это UML обзор наиболее важных классов модуля Деталей:
Геометрия
Геометрические объекты являются строительными блоками для всех топологических объектов:
- GEOM Базовый класс геометрических объектов
- LINE Прямая линия в 3D, задается начальной и конечной точкой
- CIRCLE Окружность или дуга задается центром, начальной и конечной точкой
- ...... И вскоре еще немного
Топология
Доступны нижеследующие топологические типы данных:
- COMPOUND Группа из топологических объектов любого типа.
- COMPSOLID Составное твердое тело, как набор твердых тел соединенными гранями. Он расширяет понятие Ломаной кривой(WIRE) и оболочки(SHELL) для твердых тел.
- SOLID Часть пространства ограниченная оболочкой. Она трехмерная.
- SHELL Набор граней соединенных между собой через ребра. Оболочки могут быть открытыми или закрытыми.
- FACE В 2D это часть плоскости; в 3D это часть поверхности. Это геометрия ограничена (обрезана) по контуам. Она двухмерная.
- WIRE Набор ребер соединенных через вершины. Он может быть как открытым, так и закрытым в зависимости от того связаны ли крайние ребра или нет.
- EDGE Топологический элемент соответствующий ограниченной кривой. Ребро как правило ограничивается вершинами. Оно одномерное.
- VERTEX Топологический элемент соответствующий точке. Обладает нулевой размерность.
- SHAPE общий термин охватывающий все выше сказанное.
Примеры
Создание простейшей топологии
Теперь мы создадим топологию из геометрических примитивов.
Для изучения мы используем деталь(part) , как показано на
картинке состоящую из четырех вершин, двух окружностей и двух линий.
Создание Геометрии
сначала мы должны создать отдельную деталь из данной ломаной. И мы должны убедиться что вершины геометрических частей расположены на тех же позициях. В противном случае позже мы не смогли бы соеденить геометрические части в топологию!
Так мы создаем новые точки:
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
Создавая дугу из окружности мы создаем вспомогательную точку и создаем дугу через три точки:
VC1 = Base.Vector(-10,0,0)
C1 = Part.Arc(V1,VC1,V4)
# and the second one
VC2 = Base.Vector(40,0,0)
C2 = Part.Arc(V2,VC2,V3)
Line
Линия может быть очень просто создана из точек:
L1 = Part.LineSegment(V1,V2)
# and the second one
L2 = Part.LineSegment(V3,V4)
Note: in FreeCAD 0.16 Part.Line was used, for FreeCAD 0.17 Part.LineSegment has to be used
Соединяем все вместе
Последний шаг собираем все основные геометрические элементы вместе и получаем форму:
S1 = Part.Shape([C1,L1,C2,L2])
Создание призмы
Теперь вытягиваем ломанную по направлению и фактически получаем 3D форму:
W = Part.Wire(S1.Edges)
P = W.extrude(Base.Vector(0,0,10))
Show it all
Part.show(P)
Краткое описание
Вы легко можете создать базовый топологический объект с помощью методов "make...()" содержащихся в модуле Деталей:
b = Part.makeBox(100,100,100)
Part.show(b)
Куча других доступных make...() методов:
- makeBox(l,w,h,[p,d]) -- Создает коробку расположенную в точке p и в указанном направлении d с размерами (l,w,h). По умолчанию p установлен как Vector(0,0,0) и d установлен как Vector(0,0,1)
- makeCircle(radius,[p,d,angle1,angle2]) -- Создает окружность с заданным радиусом. По умолчанию p=Vector(0,0,0), d=Vector(0,0,1), angle1=0 и angle2=360
- makeCompound(list) -- Создает составное тело из списка форм
- makeCone(radius1,radius2,height,[p,d,angle]) -- Создает конус с заданным радиусами и высотой. По умолчанию p=Vector(0,0,0), d=Vector(0,0,1) и angle=360
- makeCylinder(radius,height,[p,d,angle]) -- Создает цилиндр с заданным радиусом и высотой. По умолчанию p=Vector(0,0,0), d=Vector(0,0,1) и angle=360
- makeLine((x1,y1,z1),(x2,y2,z2)) -- Создает линию проходящую через две точки
- makePlane(length,width,[p,d]) -- Создает плоскость с заданной длинной и шириной. По умолчанию p=Vector(0,0,0) и d=Vector(0,0,1)
- makePolygon(list) -- Создает многоугольник из списка точек
- makeSphere(radius,[p,d,angle1,angle2,angle3]) -- Создает сферу с заданным радиусом. По умолчанию p=Vector(0,0,0), d=Vector(0,0,1), angle1=0, angle2=90 и angle3=360
- makeTorus(radius1,radius2,[p,d,angle1,angle2,angle3]) -- Создает тор по заданными радиусамi.По умолчанию p=Vector(0,0,0), d=Vector(0,0,1), angle1=0, angle2=360 и angle3=360
See the Part API page for a complete list of available methods of the Part module.
Подробные объяснения
Сначала импортируем следующее:
import Part
from FreeCAD import Base
Creating 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:
myVertex = myShape.Vertexes[0]
print myVertex.Point
> Vector (3, 2, 0)
Как создать Ребро?
Ребра не что иное как линия с двумя вершинами:
edge = Part.makeLine((0,0,0), (10,0,0))
edge.Vertexes
> [<Vertex object at 01877430>, <Vertex object at 014888E0>]
Примечание: Вы не можете создать ребро передав две вершины.
vec1 = Base.Vector(0,0,0)
vec2 = Base.Vector(10,0,0)
line = Part.LineSegment(vec1,vec2)
edge = line.toShape()
Вы можете узнать длинну и центр ребра, вот так:
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 the screen. This is because the FreeCAD 3D scene only displays what you tell it to display. To do that, we use this simple method:
Part.show(edge)
The show function creates an object in our FreeCAD document and assigns our "edge" shape to it. Use this whenever it is 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
> [<Edge object at 016695F8>, <Edge object at 0197AED8>, <Edge object at 01828B20>, <Edge object at 0190A788>]
Part.show(wire3)
Part.show(wire3) будет отображать четыре лини как квадарат:
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(radius,[center,dir_normal,angle1,angle2]) -- Создает окружность с заданным радиусом
По умолчанию, center=Vector(0,0,0), dir_normal=Vector(0,0,1), angle1=0 and angle2=360. Окружность может быть просто создана, как здесь:
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))
Окружность будет создана на расстоянии 10 от базовой(оригинальной) координаты х x и будет обращена в сторону оси 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овский math модуль (прежде, конечно, выполнив import math): degrees = math.degrees(radians)
degrees = math.degrees(radians)
Как создать Дугу по точкам?
К сожалению нет функции makeArc но мы обладаем функцией Part.Arc для созданимя дуги проходящей через три точки. В основном эта может быть дуга соединящая начальную и конечную точку через средню точку. Part.Arc создает объект дугу on which на котором .toShape() вызванная для получения объекта ребра, которое обычно создается с помошью makeLine или makeCircle
arc = Part.Arc(Base.Vector(0,0,0),Base.Vector(0,5,0),Base.Vector(5,5,0))
arc
> <Arc object>
arc_edge = arc.toShape()
Примечание: Дуга допускает только 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(circle,0,pi)
Arcs are valid edges like lines, so they can be used in wires also.
Как создать многоугольник или линию по точкам?
Линия по нескольким точкам, не что иное как создание ломаной с множеством ребер. функция makePolygon берет список точек и создает ломанную по этим точкам:
lshape_wire = Part.makePolygon([Base.Vector(0,5,0),Base.Vector(0,0,0),Base.Vector(5,0,0)])
Creating 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.)
def makeBCurveEdge(Points):
geomCurve = Part.BezierCurve()
geomCurve.setPoles(Points)
edge = Part.Edge(geomCurve)
return(edge)
Как создать плоскость?
Плоскасть это ровная поверхность, в смысле 2D грань 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) создат плоскость нормальную к оси х:
plane = Part.makePlane(2,2)
plane
><Face object at 028AF990>
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). Здесь толщинаhe BoundBoxпо оси y равна нулю.
примечание: makePlane доступны только Base.Vector() для задания start_pnt и dir_normal а не кортежи
Как создать эллипс?
Создать эллипс можно несколькими путями:
Part.Ellipse()
Создает эллипс с большой полуосью 2 и малой полуосью 1 с центром в (0,0,0)
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 и center. Аналогично Дуге, Эллипс также создает объект, а не ребро, так что мы должны превратить его в ребро используя toShape() для отображения
Примечание: Дуга допускает только Base.Vector() для задания точек, а не кортеж.
eli = Part.Ellipse(Base.Vector(0,0,0),10,5)
Part.show(eli.toShape())
Для верхнем конструкторе Эллипса мы ввели center, 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)
В приведенном выше коде, создан полу тор, изменен только последний параметр т.е. angle а остальные углы установлены по умолчанию.
Подстановка угла 180 создаст тор от 0 до 180 т.е. половину
Как создать блок или паралелепипед?
makeBox(length,width,height,[pnt,dir]) -- Создает блок расположенный в pnt с размерами (length,width,height)
По умолчанию 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, others are more complex, such as unioning and subtracting one shape from another.
Transform operations
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 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:
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 differently. For scaling, we can't use the transformShape, we must use transformGeometry():
myMat = Base.Matrix()
myMat.scale(2,1,1)
myShape=myShape.transformGeometry(myMat)
Логические Операции
Как вырезать одну форму из других?
cut(...) - Вычисление различий задано в топологическом классе shape.
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)
Как получить пересечение двух форм?
common(...) - Пересечение задано в топологическом классе shape
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)
Как объединить две формы?
fuse(...) - Объединение задано в топологическом классе shape
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)
Как получить сечение тела и заданой формы?
section(...) - Сечение задано в топологическом классе shape.
Вернет секущую кривую, состоящую из ребер
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
> [<Edge object at 0D87CFE8>, <Edge object at 019564F8>, <Edge object at 0D998458>,
<Edge object at 0D86DE18>, <Edge object at 0D9B8E80>, <Edge object at 012A3640>,
<Edge object at 0D8F4BB0>]
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.Face(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 тела, содержит грани. Грани, всегда содержат ломанные, которые являются набором ребер ограничивающих грань. Каждая грань обладает ровно одной замкнутой ломаной. В ломанной, мы можем посмотреть на отдельно на каждое ребро, и по краям каждого ребра , мы можем увидеть вершины. Очевидно, что прямые ребра обладают только двумя вершинами. Вершины модуля Part являются OCC(OpenCascade) формами, но они обладают атрибутом Point который возвращает FreeCAD вектор.
Исследование Рёбер
В случае ребра, которое является произвольной кривой, вы наверняка захотите произвести дискретизицию. В FreeCAD ребра задаются с помощью параметра длинны. Это означает что вы можете перемещатся вдоль ребра/кривой задавая длинну:
import Part
box = Part.makeBox(100,100,100)
anEdge = box.Edges[0]
print anEdge.Length
Теперь вы получить доступ ко всем свойствам ребра, с помощью длинны или позиции. Это означает, что у ребра в 100mm длинной, начальная позиция это 0 а конечная это 100.
anEdge.tangentAt(0.0) # tangent direction at the beginning
anEdge.valueAt(0.0) # Point at the beginning
anEdge.valueAt(100.0) # Point at the end of the edge
anEdge.derivative1At(50.0) # first derivative of the curve in the middle
anEdge.derivative2At(50.0) # second derivative of the curve in the middle
anEdge.derivative3At(50.0) # third derivative of the curve in the middle
anEdge.centerOfCurvatureAt(50) # center of the curvature for that position
anEdge.curvatureAt(50.0) # the curvature
anEdge.normalAt(50) # normal vector at that position (if defined)
Использование выделения(выбора)
Здесь мы увидим как можно использовать "выделение", которое пользователь сделал в программе просмотра. прежде всего мы создадим блок и отобразим его в окне просмотра
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 Getting Started Page можно узнать как построить бутыль. Также это отличный пример для 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.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-axis
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.makeFillet(myThickness/12.0,myBody.Edges)
return myBody
el = makeBottle()
Part.show(el)
Подробные объяснения
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.LineSegment(aPnt1,aPnt2)
aSegment2=Part.LineSegment(aPnt4,aPnt5)
Здесь мы фактически задаём геометрию: дугу, созданую по 3 точкам, и два линейных сегменты, созданные по 2 точкам.
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])
На данный момент мы построили только половину сечения. Проще, чем строить таким же образом целое сечение, мы можем просто отразить то что мы сделали и склеить две половинки. Сначала создадим матрицу(Нео ау). Матрица является распространенным способом произвести изменения над объектом в 3D пространстве, также она может содержать в одной структуре все базовые преобразования которые позволяют 3D объекты(перемещение, вращение и масштабирование). Здесь , после создания матрицы, мы отражаем её и создаем копию нашеё ломанной, применя к ней преобразование матрицой. Теперь мы получили две ломанные и мы можем создать из них третью ломаную, так как ломанные это всего лишь список ребер.
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
Теперь мы получаем нашу твердотельную Деталь как результат нашей функции. Это Деталь - твердотельная, как и любая другая Деталь форма, может быть свзана с объектом в документе FreeCAD, с помошью:
el = makeBottle()
Part.show(el)
или , ещё проще:
Box pierced
Here is a complete example of building a pierced box.
The construction is done one side at a time; when the cube is finished, it is hollowed out by cutting a cylinder through it.
import Draft, Part, FreeCAD, math, PartGui, FreeCADGui, PyQt4
from math import sqrt, pi, sin, cos, asin
from FreeCAD import Base
size = 10
poly = Part.makePolygon( [ (0,0,0), (size, 0, 0), (size, 0, size), (0, 0, size), (0, 0, 0)])
face1 = Part.Face(poly)
face2 = Part.Face(poly)
face3 = Part.Face(poly)
face4 = Part.Face(poly)
face5 = Part.Face(poly)
face6 = Part.Face(poly)
myMat = FreeCAD.Matrix()
myMat.rotateZ(math.pi/2)
face2.transformShape(myMat)
face2.translate(FreeCAD.Vector(size, 0, 0))
myMat.rotateZ(math.pi/2)
face3.transformShape(myMat)
face3.translate(FreeCAD.Vector(size, size, 0))
myMat.rotateZ(math.pi/2)
face4.transformShape(myMat)
face4.translate(FreeCAD.Vector(0, size, 0))
myMat = FreeCAD.Matrix()
myMat.rotateX(-math.pi/2)
face5.transformShape(myMat)
face6.transformShape(myMat)
face6.translate(FreeCAD.Vector(0,0,size))
myShell = Part.makeShell([face1,face2,face3,face4,face5,face6])
mySolid = Part.makeSolid(myShell)
mySolidRev = mySolid.copy()
mySolidRev.reverse()
myCyl = Part.makeCylinder(2,20)
myCyl.translate(FreeCAD.Vector(size/2, size/2, 0))
cut_part = mySolidRev.cut(myCyl)
Part.show(cut_part)
Загрузка и Сохранение
Есть несколько путей чтобы сохранения вышей работы в Part модули. Вы конечно можете сохранить ваш FreeCAD документ, а также вы можете сохранить Part(Деталь) объект напрямую в обычные CAD форматы, такие как BREP, IGS, STEP и STL.
Сохраненить форму в файл , легко. Есть доступные для всех форм методы exportBrep(), exportIges(), 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")
To convert an .stp file to an .igs file:
import Part
s = Part.Shape()
s.read("file.stp") # incoming file igs, stp, stl, brep
s.exportIges("file.igs") # outbound file igs
Примечание этот импорт или открытие BREP, IGES or STEP файлов также можно сделать напрямую с помощью меню File -> Open or File -> Import. На данный момент экспорт ещё не включен, но будет там в ближайшее время.
- Getting started
- Installation: Download, Windows, Linux, Mac, Additional components, Docker, AppImage, Ubuntu Snap
- Basics: About FreeCAD, Interface, Mouse navigation, Selection methods, Object name, Preferences, Workbenches, Document structure, Properties, Help FreeCAD, Donate
- Help: Tutorials, Video tutorials
- Workbenches: Std Base, Arch, Assembly, CAM, Draft, FEM, Inspection, Mesh, OpenSCAD, Part, PartDesign, Points, Reverse Engineering, Robot, Sketcher, Spreadsheet, Surface, TechDraw, Test Framework
- Hubs: User hub, Power users hub, Developer hub