Manual:Creating and manipulating geometry/ru: Difference between revisions

From FreeCAD Documentation
(Created page with "Мы всегда можем проверить, каков тип формы:")
(Updating to match new version of source page)
 
(48 intermediate revisions by 4 users not shown)
Line 1: Line 1:
<languages/>
{{Manual:TOC/ru}}

{{Docnav/ru
|[[Manual:A gentle introduction/ru|A gentle introduction]]
|[[Manual:Creating parametric objects/ru|Creating parametric objects]]
|[[Manual:Introduction/ru|Manual start]]
|IconC=Crystal Clear manual.png
}}

{{Manual:TOC}}


В предыдущих главах мы узнали о различных верстаках FreeCAD, и что каждый из них реализует свои собственные инструменты и типы геометрии. То же самое касается работы из кода Python.
В предыдущих главах мы узнали о различных верстаках FreeCAD, и как каждый из них реализует свои собственные инструменты и типы геометрии. То же самое касается работы из кода Python.


<div class="mw-translate-fuzzy">
Мы так же видели, что большинство верстаков FreeCAD зависит от находящегося в фундаменте [[Workbench/ru|верстака Part]]. Фактически, некоторые другие верстаки, [[Draft_Module|Draft]] или [[Arch_Module|Arch]], делают то, что мы делаем в этой главе: используют код Python для создания и манипуляции геометрией Part.
Мы так же видели, что большинство верстаков FreeCAD зависит от находящегося в фундаменте [[Part Workbench/ru|верстака Part]]. Фактически, некоторые другие верстаки, [[Draft_Workbench/ru|Draft]] или [[Arch_Workbench/ru|Arch]], делают то, что мы делаем в этой главе: используют код Python для создания и манипуляции геометрией Part.
</div>


Поэтому первая вещь, которую надо сделать для работы с геометрией Part, это импортирование модуля Part как эквивалент перехода к верстаку Part в Python:
Поэтому первая вещь, которую надо сделать для работы с геометрией Part, это импортирование модуля Part как эквивалент перехода к верстаку Part в Python:


{{Code|code=
import Part
import Part
}}


Уделите минутку для исследования содержимого модуля Part, напечатав Part. и просмотрев предлагаемые им методы. Модуль Part предлагает некоторые общие функции, такие как makeBox, makeCircle, и так далее, которые мгновенно создают объекты для Вас. Попробуйте это, например:
Уделите минутку для исследования содержимого модуля Part, напечатав Part. и просмотрев доступные методы. Модуль Part предлагает некоторые общие функции, такие как makeBox, makeCircle, и так далее, которые мгновенно создают объекты для Вас. Попробуйте это, например:


{{Code|code=
Part.makeBox(3,5,7)
Part.makeBox(3,5,7)
}}


Когда вы после ввода строки выше нажмёте Enter, в окне трёхмерного вида ничего не появится, но в консоли Python будет напечатано нечто вроде этого:
Когда вы после ввода строки выше нажмёте Enter, в окне трёхмерного вида ничего не появится, но в консоли Python будет напечатано нечто вроде этого:


{{Code|code=
<Solid object at 0x5f43600>
<Solid object at 0x5f43600>
}}


Здесь вступает в силу важная концепция. Мы создали форму Part. Это не объект документа FreeCAD (пока). Объекты и их геометрия в FreeCAD независимы. Считайте объект документа FreeCAD контейнером, который содержит форму. Параметрические объекты так же имеют параметры вроде Length и Width, и '''пересчитывают''' их форму на лету, когда один из параметров изменяется. Что мы сделали здесь - это вычислили форму вручную.
Здесь вступает в силу важная концепция. Мы создали форму Part. Это не объект документа FreeCAD (пока). Объекты и их геометрия в FreeCAD независимы. Считайте объект документа FreeCAD контейнером, который содержит форму. Параметрические объекты так же имеют параметры вроде Length и Width, и '''пересчитывают''' их форму на лету, когда один из параметров изменяется. Что мы сделали здесь - это вычислили форму вручную.
Line 21: Line 38:
Теперь мы можем просто сделать "общий" объект документа в текущем документе (убедитесь что у Вас открыт хотя бы один новый объект), и дать ему форму куба вроде того, что мы только что сделали:
Теперь мы можем просто сделать "общий" объект документа в текущем документе (убедитесь что у Вас открыт хотя бы один новый объект), и дать ему форму куба вроде того, что мы только что сделали:


{{Code|code=
boxShape = Part.makeBox(3,5,7)
boxShape = Part.makeBox(3,5,7)
myObj = FreeCAD.ActiveDocument.addObject("Part::Feature","MyNewBox")
myObj = FreeCAD.ActiveDocument.addObject("Part::Feature","MyNewBox")
myObj.Shape = boxShape
myObj.Shape = boxShape
FreeCAD.ActiveDocument.recompute()
FreeCAD.ActiveDocument.recompute()
}}


Обратите внимание на то, как мы обрабатывали myObj.Shape , мы сделали это в точности как в предыдущей главе мы меняли другие параметры объекта, такие как box.Height = 5 . Фактически, '''Shape''' это так же параметр, подобно '''Height'''. Но его тип Part Shape, а не число. В следующей главе мы рассмотрим глубже конструкцию этих параметрических объектов.
Обратите внимание на то, как мы обрабатывали myObj.Shape , мы сделали это в точности как в предыдущей главе мы меняли другие параметры объекта, такие как box.Height = 5 . Фактически, '''Shape''' это так же параметр, подобно '''Height'''. Но его тип Part Shape, а не число. В следующей главе мы рассмотрим глубже конструкцию этих параметрических объектов.


Теперь изучим наши формы Part детальнее. В конце главы о [Manual:Traditional modeling, the CSG way/ru|традиционном моделировании с помощью верстака Part] мы показали стол, показывающий как конструируются формы Part, и их различные компоненты (вершины, грани, рёбра и так далее). Точно такие же компоненты существуют и могут быть доступны через Python. Все формы Part всегда имеют следующие атрибуты: Vertexes, Edges, Wires, Faces, Shells и Solids. Все они списки, содержащие любое число элементов или пустые:
Теперь изучим наши формы Part детальнее. В конце главы о [[Manual:Traditional modeling, the CSG way/ru|традиционном моделировании с помощью верстака Part]] мы показали стол, показывающий как конструируются формы Part, и их различные компоненты (вершины, грани, рёбра и так далее). Точно такие же компоненты существуют и могут быть доступны через Python. Формы Part всегда имеют следующие атрибуты: Vertexes, Edges, Wires, Faces, Shells и Solids. Все они списки, содержащие любое число элементов или пустые:


{{Code|code=
print(boxShape.Vertexes)
print(boxShape.Edges)
print(boxShape.Vertexes)
print(boxShape.Wires)
print(boxShape.Edges)
print(boxShape.Faces)
print(boxShape.Wires)
print(boxShape.Shells)
print(boxShape.Faces)
print(boxShape.Solids)
print(boxShape.Shells)
print(boxShape.Solids)
}}


<div class="mw-translate-fuzzy">
Например, найдём площадь каждой грани нашей формы куба:
Например, найдём площадь каждой грани нашей формы куба:
</div>


{{Code|code=
for f in boxShape.Faces:
for f in boxShape.Faces:
print(f.Area)
print(f.Area)
}}


Или, для каждого ребра, начальную и конечную точку:
Или, для каждого ребра, начальную и конечную точку:


{{Code|code=
for e in boxShape.Edges:
for e in boxShape.Edges:
print("New edge")
print("New edge")
print("Start point:")
print("Start point:")
Line 50: Line 76:
print("End point:")
print("End point:")
print(e.Vertexes[1].Point)
print(e.Vertexes[1].Point)
}}


Как Вы видите, если boxShape имеет атрибут "Vertexes", каждый Edge в boxShape так же имеет атрибут "Vertexes". Как мы можем ожидать, у boxShape будет 8 вершин, когда ребро имеет 2, которые включены в число этих восьми.
Как Вы видите, если boxShape имеет атрибут "Vertexes", каждый Edge в boxShape так же имеет атрибут "Vertexes". Как мы можем ожидать, у boxShape будет 8 вершин, когда ребро имеет 2, которые включены в число этих восьми.
Line 55: Line 82:
Мы всегда можем проверить, каков тип формы:
Мы всегда можем проверить, каков тип формы:


{{Code|code=
print(boxShape.ShapeType)
print(boxShape.Faces[0].ShapeType)
print(boxShape.ShapeType)
print (boxShape.Vertexes[2].ShapeType)
print(boxShape.Faces[0].ShapeType)
print(boxShape.Vertexes[2].ShapeType)
}}


Так что возобновим тему Part Shape: всё начинается с вершин (Vertice). С одной или двумя вершинами (окружность имеет только одну вершину) формируется ребро (Edge). С несколькими рёбрами формируется ломаная (Wire). С одной или несколькими замкнутыми ломаными формируется грань (Face) (дополнительные ломаные образуют в грани "отверстия"). Несколько граней создают оболочку (Shell). Когда оболочка замкнута (водонепроницаемо), из неё можно создать тело (Solid). И в конце можно соединить несколько форм (Shape) различных видов, это называется соединение (Compound).
So to resume the whole diagram of Part Shapes: Everything starts with Vertices. With one or two vertices, you form an Edge (full circles have only one vertex). With one or more Edges, you form a Wire. With one or more closed Wires, you form a Face (the additional Wires become "holes" in the Face). With one or more Faces, you form a Shell. When a Shell is fully closed (watertight), you can form a Solid from it. And finally, you can join any number of Shapes of any types together, which is then called a Compound.


Теперь мы попробуем создать сложные формы с нуля, конструируя все их компоненты один за другим. Например, попробуем создать объём вроде этого:
We can now try creating complex shapes from scratch, by constructing all their components one by one. For example, let's try to create a volume like this:


[[Image:Exercise_python_03.jpg]]
[[Image:Exercise_python_03.jpg]]


Начнём с создания плоской формы вроде этой:
We will start by creating a planar shape like this:


[[Image:Wire.png]]
[[Image:Wire.png]]


Сначала создадим четыре базовые точки:
First, let's create the four base points:


{{Code|code=
V1 = FreeCAD.Vector(0,10,0)
V2 = FreeCAD.Vector(30,10,0)
V1 = FreeCAD.Vector(0,10,0)
V3 = FreeCAD.Vector(30,-10,0)
V2 = FreeCAD.Vector(30,10,0)
V4 = FreeCAD.Vector(0,-10,0)
V3 = FreeCAD.Vector(30,-10,0)
V4 = FreeCAD.Vector(0,-10,0)
}}


Затем создадим два линейных сегмента
Then we can create the two linear segments:


[[Image:Line.png]]
[[Image:Line.png]]


{{Code|code=
L1 = Part.Line(V1,V2)
L2 = Part.Line(V4,V3)
L1 = Part.LineSegment(V1,V2)
L2 = Part.LineSegment(V4,V3)
}}


Note that we didn't need to create Vertices? We could immediately create Part.Lines from FreeCAD Vectors. This is because here we haven't created Edges yet. A Part.Line (as well as Part.Circle, Part.Arc, Part.Ellipse or Part.BSpline) does not create an Edge, but rather a base geometry on which an Edge will be created. Edges are always made from such a base geometry, which is stored its Curve attribute. So if you have an Edge, doing:
Заметили, что нам не надо создавать Vertices? Мы можем сразу создать Part.LineSegments из FreeCAD Vectors, потому, что у нес ещё не созданы рёбра (Edge). Part.LineSegments (как и Part.Circle, Part.Arc, Part.Ellipse или Part.BSpline) создают не ребро (Edge), а базовую геометрию, на которой будут созданы рёбра. Рёбра всегда делаются из такой базовой геометрии, сохраняемой в её атрибуте Curve. Так что если у Вас есть Edge, команда:


{{Code|code=
print(Edge.Curve)
print(Edge.Curve)
}}


покажет Вам, какого типа этот Edge, базируется ли он на линии, дуге или ещё чем... Но вернёмся к нашему примеру, и свяжем сегменты дуги. Для этого нам нужна третья точка, поэтому мы можем использовать подходящий Part.Arc, у которого 3 точки:
will show you what kind of Edge this is, that is, if it is based on a line, an arc, etc... But let's come back to our exercise, and build the arc segments. For this, we will need a third point, so we can use the convenient Part.Arc, which takes 3 points:


[[Image:Circel.png]]
[[Image:Circel.png]]


{{Code|code=
VC1 = FreeCAD.Vector(-10,0,0)
C1 = Part.Arc(V1,VC1,V4)
VC1 = FreeCAD.Vector(-10,0,0)
VC2 = FreeCAD.Vector(40,0,0)
C1 = Part.Arc(V1,VC1,V4)
C2 = Part.Arc(V2,VC2,V3)
VC2 = FreeCAD.Vector(40,0,0)
C2 = Part.Arc(V2,VC2,V3)
}}


Now we have 2 lines (L1 and L2) and 2 arcs (C1 and C2). We need to turn them into edges:
Теперь у нас 2 линии (L1 и L2) и 2 дуги (C1 и C2). Их надо превратить в ребро (Edge):


{{Code|code=
E1 = Part.Edge(L1)
E2 = Part.Edge(L2)
E1 = Part.Edge(L1)
E3 = Part.Edge(C1)
E2 = Part.Edge(L2)
E4 = Part.Edge(C2)
E3 = Part.Edge(C1)
E4 = Part.Edge(C2)
}}


<div class="mw-translate-fuzzy">
Alternatively, base geometries also have a toShape() function that do exactly the same thing:
Иначе, базовая геометрия так же имеет функцию toShape(), которая делает то же самое:
</div>


{{Code|code=
E1 = L1.toShape()
E2 = L2.toShape()
E1 = L1.toShape()
E2 = L2.toShape()
...
...
}}


<div class="mw-translate-fuzzy">
Once we have a series of Edges, we can now form a Wire, by giving it a list of Edges. We do need to take care of the order.
Когда у нас есть последовательность рёбер, мы можем сформировать ломаную (Wire), придав ей список рёбер (Edge):
</div>


{{Code|code=
W = Part.Wire([E1,E4,E2,E3])
W = Part.Wire([E1,E4,E2,E3])
}}


И мы можем проверить, правильно ли понята наша ломаная (Wire), и корректно ли она замкнута:
And we can check if our Wire was correctly understood, and that it is correctly closed:


{{Code|code=
print( W.isClosed() )
print( W.isClosed() )
}}


Здесь будет напечатано "True" или "False". Чтобы создать грань (Face), нам нужны замкнутые ломаные (Wire), так что всегда полезно проверить это, прежде чем создать грань. Мы можем создать Face, передав ей единственную полилинию (Wire), или список полилиний, если нам нужны отверстия:
Which will print "True" or "False". In order to make a Face, we need closed Wires, so it is always a good idea to check that before creating the Face. Now we can create a Face, by giving it a single Wire (or a list of Wires if we had holes):


{{Code|code=
F = Part.Face(W)
F = Part.Face(W)
}}


Затем мы выдавим его:
Then we extrude it:


{{Code|code=
P = F.extrude(FreeCAD.Vector(0,0,10))
P = F.extrude(FreeCAD.Vector(0,0,10))
}}


Note that P is already a Solid:
Зметьте, что P уже твёрдое тело (Solid):


{{Code|code=
print(P.ShapeType)
print(P.ShapeType)
}}


Because when extruding a single Face, we always get a Solid. This wouldn't be the case, for example, if we had extruded the Wire instead:
This is because when we extrude a single Face, we always get a Solid. This wouldn't be the case, for example, if we had extruded the Wire instead:


{{Code|code=
S = W.extrude(FreeCAD.Vector(0,0,10))
S = W.extrude(FreeCAD.Vector(0,0,10))
print(s.ShapeType)
print(S.ShapeType)
}}


Это, разумеется, даст нам полую оболочку, без верхней и нижней плоскости.
Which will of course give us a hollow shell, with the top and bottom faces missing.


Теперь, когда у нас есть окончательная форма, мы с нетерпением желаем увидеть её на экране! Так что создадим общий объект, и назначим наше новое тело (Solid) к нему:
Now that we have our final Shape, we are anxious to see it on screen! So let's create a generic object, and attribute it our new Solid:


{{Code|code=
myObj2 = FreeCAD.ActiveDocument.addObject("Part::Feature","My_Strange_Solid")
myObj2 = FreeCAD.ActiveDocument.addObject("Part::Feature","My_Strange_Solid")
myObj2.Shape = P
myObj2.Shape = P
FreeCAD.ActiveDocument.recompute()
FreeCAD.ActiveDocument.recompute()
}}


Альтернативно модуль Part предлагает ярлык, делающий эту операцию быстрее (но Вы не сможете выбрать имя объекта):
Alternatively, the Part module also provides a shortcut that does the above operation quicker (but you cannot choose the name of the object):


{{Code|code=
Part.show(P)
Part.show(P)
}}


All of the above, and much more, is explained in detail on the [[Topological_data_scripting|Part Scripting]] page, together with examples.
Всё это, и многое другое, вместе с примерами детально описано на странице [[Topological_data_scripting/ru|Part Scripting]].


'''Read more''':
'''Читать далее''':


* [[Part_Workbench/ru|Верстак Part]]
* [[Part_Workbench/ru|Верстак Part]]
* [[Topological_data_scripting/ru|Написание скриптов обработки топологии]]
* [[Topological_data_scripting/ru|Написание скриптов обработки топологии]]



<languages/>
{{Docnav/ru
|[[Manual:A gentle introduction/ru|A gentle introduction]]
|[[Manual:Creating parametric objects/ru|Creating parametric objects]]
|[[Manual:Introduction/ru|Manual start]]
|IconC=Crystal Clear manual.png
}}

{{Powerdocnavi{{#translation:}}}}
[[Category:Developer Documentation{{#translation:}}]]
[[Category:Python Code{{#translation:}}]]
{{clear}}

Latest revision as of 19:28, 4 November 2023

Other languages:

В предыдущих главах мы узнали о различных верстаках FreeCAD, и как каждый из них реализует свои собственные инструменты и типы геометрии. То же самое касается работы из кода Python.

Мы так же видели, что большинство верстаков FreeCAD зависит от находящегося в фундаменте верстака Part. Фактически, некоторые другие верстаки, Draft или Arch, делают то, что мы делаем в этой главе: используют код Python для создания и манипуляции геометрией Part.

Поэтому первая вещь, которую надо сделать для работы с геометрией Part, это импортирование модуля Part как эквивалент перехода к верстаку Part в Python:

import Part

Уделите минутку для исследования содержимого модуля Part, напечатав Part. и просмотрев доступные методы. Модуль Part предлагает некоторые общие функции, такие как makeBox, makeCircle, и так далее, которые мгновенно создают объекты для Вас. Попробуйте это, например:

Part.makeBox(3,5,7)

Когда вы после ввода строки выше нажмёте Enter, в окне трёхмерного вида ничего не появится, но в консоли Python будет напечатано нечто вроде этого:

<Solid object at 0x5f43600>

Здесь вступает в силу важная концепция. Мы создали форму Part. Это не объект документа FreeCAD (пока). Объекты и их геометрия в FreeCAD независимы. Считайте объект документа FreeCAD контейнером, который содержит форму. Параметрические объекты так же имеют параметры вроде Length и Width, и пересчитывают их форму на лету, когда один из параметров изменяется. Что мы сделали здесь - это вычислили форму вручную.

Теперь мы можем просто сделать "общий" объект документа в текущем документе (убедитесь что у Вас открыт хотя бы один новый объект), и дать ему форму куба вроде того, что мы только что сделали:

boxShape = Part.makeBox(3,5,7)
myObj = FreeCAD.ActiveDocument.addObject("Part::Feature","MyNewBox")
myObj.Shape = boxShape
FreeCAD.ActiveDocument.recompute()

Обратите внимание на то, как мы обрабатывали myObj.Shape , мы сделали это в точности как в предыдущей главе мы меняли другие параметры объекта, такие как box.Height = 5 . Фактически, Shape это так же параметр, подобно Height. Но его тип Part Shape, а не число. В следующей главе мы рассмотрим глубже конструкцию этих параметрических объектов.

Теперь изучим наши формы Part детальнее. В конце главы о традиционном моделировании с помощью верстака Part мы показали стол, показывающий как конструируются формы Part, и их различные компоненты (вершины, грани, рёбра и так далее). Точно такие же компоненты существуют и могут быть доступны через Python. Формы Part всегда имеют следующие атрибуты: Vertexes, Edges, Wires, Faces, Shells и Solids. Все они списки, содержащие любое число элементов или пустые:

print(boxShape.Vertexes)
print(boxShape.Edges)
print(boxShape.Wires)
print(boxShape.Faces)
print(boxShape.Shells)
print(boxShape.Solids)

Например, найдём площадь каждой грани нашей формы куба:

for f in boxShape.Faces:
   print(f.Area)

Или, для каждого ребра, начальную и конечную точку:

for e in boxShape.Edges:
   print("New edge")
   print("Start point:")
   print(e.Vertexes[0].Point)
   print("End point:")
   print(e.Vertexes[1].Point)

Как Вы видите, если boxShape имеет атрибут "Vertexes", каждый Edge в boxShape так же имеет атрибут "Vertexes". Как мы можем ожидать, у boxShape будет 8 вершин, когда ребро имеет 2, которые включены в число этих восьми.

Мы всегда можем проверить, каков тип формы:

print(boxShape.ShapeType)
print(boxShape.Faces[0].ShapeType)
print(boxShape.Vertexes[2].ShapeType)

Так что возобновим тему Part Shape: всё начинается с вершин (Vertice). С одной или двумя вершинами (окружность имеет только одну вершину) формируется ребро (Edge). С несколькими рёбрами формируется ломаная (Wire). С одной или несколькими замкнутыми ломаными формируется грань (Face) (дополнительные ломаные образуют в грани "отверстия"). Несколько граней создают оболочку (Shell). Когда оболочка замкнута (водонепроницаемо), из неё можно создать тело (Solid). И в конце можно соединить несколько форм (Shape) различных видов, это называется соединение (Compound).

Теперь мы попробуем создать сложные формы с нуля, конструируя все их компоненты один за другим. Например, попробуем создать объём вроде этого:

Начнём с создания плоской формы вроде этой:

Сначала создадим четыре базовые точки:

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

Затем создадим два линейных сегмента

L1 = Part.LineSegment(V1,V2)
L2 = Part.LineSegment(V4,V3)

Заметили, что нам не надо создавать Vertices? Мы можем сразу создать Part.LineSegments из FreeCAD Vectors, потому, что у нес ещё не созданы рёбра (Edge). Part.LineSegments (как и Part.Circle, Part.Arc, Part.Ellipse или Part.BSpline) создают не ребро (Edge), а базовую геометрию, на которой будут созданы рёбра. Рёбра всегда делаются из такой базовой геометрии, сохраняемой в её атрибуте Curve. Так что если у Вас есть Edge, команда:

print(Edge.Curve)

покажет Вам, какого типа этот Edge, базируется ли он на линии, дуге или ещё чем... Но вернёмся к нашему примеру, и свяжем сегменты дуги. Для этого нам нужна третья точка, поэтому мы можем использовать подходящий Part.Arc, у которого 3 точки:

VC1 = FreeCAD.Vector(-10,0,0)
C1 = Part.Arc(V1,VC1,V4)
VC2 = FreeCAD.Vector(40,0,0)
C2 = Part.Arc(V2,VC2,V3)

Теперь у нас 2 линии (L1 и L2) и 2 дуги (C1 и C2). Их надо превратить в ребро (Edge):

E1 = Part.Edge(L1)
E2 = Part.Edge(L2)
E3 = Part.Edge(C1)
E4 = Part.Edge(C2)

Иначе, базовая геометрия так же имеет функцию toShape(), которая делает то же самое:

E1 = L1.toShape()
E2 = L2.toShape()
 ...

Когда у нас есть последовательность рёбер, мы можем сформировать ломаную (Wire), придав ей список рёбер (Edge):

W = Part.Wire([E1,E4,E2,E3])

И мы можем проверить, правильно ли понята наша ломаная (Wire), и корректно ли она замкнута:

print( W.isClosed() )

Здесь будет напечатано "True" или "False". Чтобы создать грань (Face), нам нужны замкнутые ломаные (Wire), так что всегда полезно проверить это, прежде чем создать грань. Мы можем создать Face, передав ей единственную полилинию (Wire), или список полилиний, если нам нужны отверстия:

F = Part.Face(W)

Затем мы выдавим его:

P = F.extrude(FreeCAD.Vector(0,0,10))

Зметьте, что P уже твёрдое тело (Solid):

print(P.ShapeType)

This is because when we extrude a single Face, we always get a Solid. This wouldn't be the case, for example, if we had extruded the Wire instead:

S = W.extrude(FreeCAD.Vector(0,0,10))
print(S.ShapeType)

Это, разумеется, даст нам полую оболочку, без верхней и нижней плоскости.

Теперь, когда у нас есть окончательная форма, мы с нетерпением желаем увидеть её на экране! Так что создадим общий объект, и назначим наше новое тело (Solid) к нему:

myObj2 = FreeCAD.ActiveDocument.addObject("Part::Feature","My_Strange_Solid")
myObj2.Shape = P
FreeCAD.ActiveDocument.recompute()

Альтернативно модуль Part предлагает ярлык, делающий эту операцию быстрее (но Вы не сможете выбрать имя объекта):

Part.show(P)

Всё это, и многое другое, вместе с примерами детально описано на странице Part Scripting.

Читать далее: