Manual:Creating parametric objects/ru: Difference between revisions

From FreeCAD Documentation
(Updating to match new version of source page)
(Updating to match new version of source page)
Line 1: Line 1:
<languages/>
<languages/>

{{Docnav/ru
{{Docnav/ru
|[[Manual:Creating and manipulating geometry/ru|Creating and manipulating geometry]]
|[[Manual:Creating and manipulating geometry/ru|Creating and manipulating geometry]]
Line 17: Line 18:
FreeCAD обеспечивает очень удобную систему для построения таких параметрических объектов полностью в Python. Они состоят из простых классов Python, которые определяют все нужные объекту параметры, и что случится если один из этих параметров изменится. Структура этих параметрических объектов так проста, как это:
FreeCAD обеспечивает очень удобную систему для построения таких параметрических объектов полностью в Python. Они состоят из простых классов Python, которые определяют все нужные объекту параметры, и что случится если один из этих параметров изменится. Структура этих параметрических объектов так проста, как это:


{{Code|code=
class myParametricObject:
class myParametricObject:

def __init__(self,obj):
obj.Proxy = self
def __init__(self, obj):
obj.Proxy = self
obj.addProperty("App::PropertyFloat","MyLength")
obj.addProperty("App::PropertyFloat", "MyLength")
...
...

def execute(self,obj):
def execute(self,obj):
print ("Recalculating the shape...")
print ("The value of MyLength is:")
print ("Recalculating the shape...")
print (obj.MyLength)
print ("The value of MyLength is:")
...
print (obj.MyLength)
...
}}


Все классы Python обычно имеют метод __init__. Всё, что внутри этого метода, исполняется когда создаётся экземпляр этого класса (что знает, на программистском сленге, что объект Python создаётся из этого класса. Представляйте класс как "шаблон" для создания живых копий). В наших функциях __init__ мы здесь делаем две важные вещи: 1- сохраняем наш класс в атрибут "Proxy" объекта нашего документа FreeCAD, то есть документ FreeCAD будет носить этот код в себе, и 2- создает все параметры, которые нужны нашему объекту. Доступны множество типов параметров, Вы можете получить полный список, набрав следующий код:
Все классы Python обычно имеют метод __init__. Всё, что внутри этого метода, исполняется когда создаётся экземпляр этого класса (что знает, на программистском сленге, что объект Python создаётся из этого класса. Представляйте класс как "шаблон" для создания живых копий). В наших функциях __init__ мы здесь делаем две важные вещи: 1- сохраняем наш класс в атрибут "Proxy" объекта нашего документа FreeCAD, то есть документ FreeCAD будет носить этот код в себе, и 2- создает все параметры, которые нужны нашему объекту. Доступны множество типов параметров, Вы можете получить полный список, набрав следующий код:


{{Code|code=
FreeCAD.ActiveDocument.addObject("Part::FeaturePython","dummy").supportedProperties()
FreeCAD.ActiveDocument.addObject("Part::FeaturePython", "dummy").supportedProperties()
}}


Следующая важная часть это исполняемый метод. Любой код в этом методе исполняется когда объект маркирован для пересчёта, что происходит когда объект изменяется. Это всё, что есть. Внутри исполнения требуется сделать всё, что надо, то есть вычисление новой формы, и приписывания объекту чего-то вроде obj.Shape = myNewShape. Вот почему исполняемый метод принимает аргумент "obj", которых будет самим документом FreeCAD, так что мы можем манипулировать им внутри нашего кода python.
Следующая важная часть это исполняемый метод. Любой код в этом методе исполняется когда объект маркирован для пересчёта, что происходит когда объект изменяется. Это всё, что есть. Внутри исполнения требуется сделать всё, что надо, то есть вычисление новой формы, и приписывания объекту чего-то вроде obj.Shape = myNewShape. Вот почему исполняемый метод принимает аргумент "obj", которых будет самим документом FreeCAD, так что мы можем манипулировать им внутри нашего кода python.
Line 42: Line 47:
Мы придадим нашему объекту два параметра: Length и Width, которые мы будем использовать для создания прямоугольника. Затем, поскольку наш объект уже имеет встроенный параметр Placement (все геометрические объекты имеют его по умолчанию, их не надо добавлять самостоятельно), мы поместим наш прямоугольник в положение/наклон, установленные в Placement, так что пользователь сможет перемещать прямоугольник редактированием параметра Placement.
Мы придадим нашему объекту два параметра: Length и Width, которые мы будем использовать для создания прямоугольника. Затем, поскольку наш объект уже имеет встроенный параметр Placement (все геометрические объекты имеют его по умолчанию, их не надо добавлять самостоятельно), мы поместим наш прямоугольник в положение/наклон, установленные в Placement, так что пользователь сможет перемещать прямоугольник редактированием параметра Placement.


{{Code|code=
class ParametricRectangle:
class ParametricRectangle:

def __init__(self,obj):
obj.Proxy = self
def __init__(self,obj):
obj.Proxy = self
obj.addProperty("App::PropertyFloat","Length")
obj.addProperty("App::PropertyFloat","Width")
obj.addProperty("App::PropertyFloat", "Length")
obj.addProperty("App::PropertyFloat", "Width")

def execute(self,obj):
def execute(self, obj):
# we need to import the FreeCAD module here too, because we might be running out of the Console
# (in a macro, for example) where the FreeCAD module has not been imported automatically
# We need to import the FreeCAD module here too, because we might be running out of the Console
# (in a macro, for example) where the FreeCAD module has not been imported automatically:
import Part,FreeCAD
import FreeCAD
import Part
# first we need to make sure the values of Length and Width are not 0

# otherwise the Part.Line will complain that both points are equal
# First we need to make sure the values of Length and Width are not 0
if (obj.Length == 0) or (obj.Width == 0):
# otherwise Part.LineSegment will complain that both points are equal:
# if yes, exit this method without doing anything
if (obj.Length == 0) or (obj.Width == 0):
return
# If yes, exit this method without doing anything:
# we create 4 points for the 4 corners
return

v1 = FreeCAD.Vector(0,0,0)
# We create 4 points for the 4 corners:
v2 = FreeCAD.Vector(obj.Length,0,0)
v3 = FreeCAD.Vector(obj.Length,obj.Width,0)
v1 = FreeCAD.Vector(0, 0, 0)
v4 = FreeCAD.Vector(0,obj.Width,0)
v2 = FreeCAD.Vector(obj.Length, 0, 0)
v3 = FreeCAD.Vector(obj.Length,obj.Width, 0)
v4 = FreeCAD.Vector(0, obj.Width, 0)
# we create 4 edges

e1 = Part.Line(v1,v2).toShape() # Warning. Since FC v0.17, use Part.LineSegment instead of Part.Line
# We create 4 edges:
e2 = Part.Line(v2,v3).toShape()
e3 = Part.Line(v3,v4).toShape()
e1 = Part.LineSegment(v1, v2).toShape()
e4 = Part.Line(v4,v1).toShape()
e2 = Part.LineSegment(v2, v3).toShape()
e3 = Part.LineSegment(v3, v4).toShape()
e4 = Part.LineSegment(v4, v1).toShape()
# we create a wire

w = Part.Wire([e1,e2,e3,e4])
# We create a wire:
w = Part.Wire([e1, e2, e3, e4])
# we create a face

f = Part.Face(w)
# We create a face:
f = Part.Face(w)
# All shapes have a Placement too. We give our shape the value of the placement

# set by the user. This will move/rotate the face automatically.
# All shapes have a Placement too. We give our shape the value of the placement
f.Placement = obj.Placement
# set by the user. This will move/rotate the face automatically.
f.Placement = obj.Placement
# all done, we can attribute our shape to the object!

obj.Shape = f
# All done, we can attribute our shape to the object!
obj.Shape = f
}}


Вместо того чтобы вставить вышеуказанный код в консоль Python, лучше сохраним его где-нибудь, чтобы мы могли повторно использовать и модифицировать его позднее. Например, в макросе (меню Tools -> Macros -> Create). Назовём его, например, "ParamRectangle". Тем не менее, макрос FreeCAD сохраняется с расширением .FCMacro, который Python не разспознаёт при импорте. Поэтому перед использованием этого кода нам надо переименовать ParamRectangle.FCMacro в ParamRectangle.py. Это легко делается в вашем менеджере файлов, найдя папку Macros, показанную в меню Tools -> Macros.
Вместо того чтобы вставить вышеуказанный код в консоль Python, лучше сохраним его где-нибудь, чтобы мы могли повторно использовать и модифицировать его позднее. Например, в макросе (меню Tools -> Macros -> Create). Назовём его, например, "ParamRectangle". Тем не менее, макрос FreeCAD сохраняется с расширением .FCMacro, который Python не разспознаёт при импорте. Поэтому перед использованием этого кода нам надо переименовать ParamRectangle.FCMacro в ParamRectangle.py. Это легко делается в вашем менеджере файлов, найдя папку Macros, показанную в меню Tools -> Macros.
Line 89: Line 97:
Когда это сделано, мы можем сделать это в консоли Python:
Когда это сделано, мы можем сделать это в консоли Python:


{{Code|code=
import ParamRectangle
import ParamRectangle
}}


Открывая содержимое ParamRectangle, мы убедимся, что он содержит лишь наш класс ParametricRectangle.
Открывая содержимое ParamRectangle, мы убедимся, что он содержит лишь наш класс ParametricRectangle.
Line 95: Line 105:
Для создания нового параметрического объекта с использованием нашего класса ParametricRectangle мы будем использовать следующий код. Заметьте, что мы используем Part::FeaturePython вместо Part::Feature, который мы использовали в предыдущих главах (версия Python позволяет определить наш собственное параметрическое поведение):
Для создания нового параметрического объекта с использованием нашего класса ParametricRectangle мы будем использовать следующий код. Заметьте, что мы используем Part::FeaturePython вместо Part::Feature, который мы использовали в предыдущих главах (версия Python позволяет определить наш собственное параметрическое поведение):


{{Code|code=
myObj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython","Rectangle")
myObj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython", "Rectangle")
ParamRectangle.ParametricRectangle(myObj)
ParamRectangle.ParametricRectangle(myObj)
myObj.ViewObject.Proxy = 0 # this is mandatory unless we code the ViewProvider too
myObj.ViewObject.Proxy = 0 # This is mandatory unless we code the ViewProvider too.
FreeCAD.ActiveDocument.recompute()
FreeCAD.ActiveDocument.recompute()
}}


Пока ничего на экране не появилось, поскольку параметры Length и Width равны 0, что включает наше правило "do-nothing" внутри execute. Нам надо просто изменить значения Length и Width, и наш объект волшебно появится и будет пересчитан на лету.
Пока ничего на экране не появилось, поскольку параметры Length и Width равны 0, что включает наше правило "do-nothing" внутри execute. Нам надо просто изменить значения Length и Width, и наш объект волшебно появится и будет пересчитан на лету.
Line 135: Line 147:
[[Category:Developer Documentation{{#translation:}}]]
[[Category:Developer Documentation{{#translation:}}]]
[[Category:Python Code{{#translation:}}]]
[[Category:Python Code{{#translation:}}]]
{{clear}}

Revision as of 20:48, 3 June 2022

Other languages:

В предыдущей главе мы видели создание геометрии Part, и как показать её на экране присоединением её к "пустому" (непараметрическому) объекту документа. Это муторно, когда мы хотим изменить форму объекта. Нам нужно создать новую форму, затем снова приписать её к нашему объекту.

Однако мы видели в предыдущих главах этого руководства, как велики возможности параметрических объектов. Мы можем изменить один параметр, и форма пересчитывается на лету.

Внутри параметрические объекты не делают ничего иного кроме того, что мы делали: они пересчитывают содержимое параметра Shape, раз за разом когда другие параметры изменяются.

FreeCAD обеспечивает очень удобную систему для построения таких параметрических объектов полностью в Python. Они состоят из простых классов Python, которые определяют все нужные объекту параметры, и что случится если один из этих параметров изменится. Структура этих параметрических объектов так проста, как это:

class myParametricObject:

    def __init__(self, obj):
        obj.Proxy = self
        obj.addProperty("App::PropertyFloat", "MyLength")
        ...

    def execute(self,obj):
        print ("Recalculating the shape...")
        print ("The value of MyLength is:")
        print (obj.MyLength)
        ...

Все классы Python обычно имеют метод __init__. Всё, что внутри этого метода, исполняется когда создаётся экземпляр этого класса (что знает, на программистском сленге, что объект Python создаётся из этого класса. Представляйте класс как "шаблон" для создания живых копий). В наших функциях __init__ мы здесь делаем две важные вещи: 1- сохраняем наш класс в атрибут "Proxy" объекта нашего документа FreeCAD, то есть документ FreeCAD будет носить этот код в себе, и 2- создает все параметры, которые нужны нашему объекту. Доступны множество типов параметров, Вы можете получить полный список, набрав следующий код:

FreeCAD.ActiveDocument.addObject("Part::FeaturePython", "dummy").supportedProperties()

Следующая важная часть это исполняемый метод. Любой код в этом методе исполняется когда объект маркирован для пересчёта, что происходит когда объект изменяется. Это всё, что есть. Внутри исполнения требуется сделать всё, что надо, то есть вычисление новой формы, и приписывания объекту чего-то вроде obj.Shape = myNewShape. Вот почему исполняемый метод принимает аргумент "obj", которых будет самим документом FreeCAD, так что мы можем манипулировать им внутри нашего кода python.

Последняя вещь, которую важно запомнить: когда Вы создаёте такой параметрический объект в документе FreeCAD, когда Вы сохраняете файл, вышеуказанный код python не сохраняется в файле. Это происходит из соображений безопасности, если бы файлы FreeCAD содержали код, у злоумышленников была бы возможность распространять файлы FreeCAD с вредоносным кодом, который мог бы повреждать чужие компьютеры. Так что если Вы распространяете файл, который содержит объекты, сделанные с помощью вышеуказанного года, этот код должен так же находиться на компьютерах, которые откроют файл. Простейший путь достичь этого - сохранить код в макросе, и распространять макрос вместе с файлом, или делиться своим макросом на репозитории макросов FreeCAD, где каждый сможет загрузить его.

Ниже мы выполним маленькое упражнение, создав параметрический объект - простейшая параметрическая прямоугольная грань. Более сложные примеры доступны в примере параметрического объекта и в коде самого FreeCAD.

Мы придадим нашему объекту два параметра: Length и Width, которые мы будем использовать для создания прямоугольника. Затем, поскольку наш объект уже имеет встроенный параметр Placement (все геометрические объекты имеют его по умолчанию, их не надо добавлять самостоятельно), мы поместим наш прямоугольник в положение/наклон, установленные в Placement, так что пользователь сможет перемещать прямоугольник редактированием параметра Placement.

class ParametricRectangle:

    def __init__(self,obj):
        obj.Proxy = self
        obj.addProperty("App::PropertyFloat", "Length")
        obj.addProperty("App::PropertyFloat", "Width")

    def execute(self, obj):
        # We need to import the FreeCAD module here too, because we might be running out of the Console
        # (in a macro, for example) where the FreeCAD module has not been imported automatically:
        import FreeCAD
        import Part

        # First we need to make sure the values of Length and Width are not 0
        # otherwise Part.LineSegment will complain that both points are equal:
        if (obj.Length == 0) or (obj.Width == 0):
            # If yes, exit this method without doing anything:
            return

        # We create 4 points for the 4 corners:
        v1 = FreeCAD.Vector(0, 0, 0)
        v2 = FreeCAD.Vector(obj.Length, 0, 0)
        v3 = FreeCAD.Vector(obj.Length,obj.Width, 0)
        v4 = FreeCAD.Vector(0, obj.Width, 0)

        # We create 4 edges:
        e1 = Part.LineSegment(v1, v2).toShape()
        e2 = Part.LineSegment(v2, v3).toShape()
        e3 = Part.LineSegment(v3, v4).toShape()
        e4 = Part.LineSegment(v4, v1).toShape()

        # We create a wire:
        w = Part.Wire([e1, e2, e3, e4])

        # We create a face:
        f = Part.Face(w)

        # All shapes have a Placement too. We give our shape the value of the placement
        # set by the user. This will move/rotate the face automatically.
        f.Placement = obj.Placement

        # All done, we can attribute our shape to the object!
        obj.Shape = f

Вместо того чтобы вставить вышеуказанный код в консоль Python, лучше сохраним его где-нибудь, чтобы мы могли повторно использовать и модифицировать его позднее. Например, в макросе (меню Tools -> Macros -> Create). Назовём его, например, "ParamRectangle". Тем не менее, макрос FreeCAD сохраняется с расширением .FCMacro, который Python не разспознаёт при импорте. Поэтому перед использованием этого кода нам надо переименовать ParamRectangle.FCMacro в ParamRectangle.py. Это легко делается в вашем менеджере файлов, найдя папку Macros, показанную в меню Tools -> Macros.

Когда это сделано, мы можем сделать это в консоли Python:

import ParamRectangle

Открывая содержимое ParamRectangle, мы убедимся, что он содержит лишь наш класс ParametricRectangle.

Для создания нового параметрического объекта с использованием нашего класса ParametricRectangle мы будем использовать следующий код. Заметьте, что мы используем Part::FeaturePython вместо Part::Feature, который мы использовали в предыдущих главах (версия Python позволяет определить наш собственное параметрическое поведение):

myObj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython", "Rectangle")
ParamRectangle.ParametricRectangle(myObj)
myObj.ViewObject.Proxy = 0 # This is mandatory unless we code the ViewProvider too.
FreeCAD.ActiveDocument.recompute()

Пока ничего на экране не появилось, поскольку параметры Length и Width равны 0, что включает наше правило "do-nothing" внутри execute. Нам надо просто изменить значения Length и Width, и наш объект волшебно появится и будет пересчитан на лету.

Разумеется, было бы утомительно вводить эти 4 строки кода Python каждый раз, когда нам нужно создать новый параметрический прямоугольник. Простой путь решить это - поместить эти 4 строки в наш файл ParamRectangle.py в конце, после класса ParametricRectange (Мы можем делать это в редакторе макросов).

Теперь, когда мы напишем import ParamRectangle , новый параметрический прямоугольник создастся автоматически. Даже лучше, мы можем добавить кнопку панели инструментов, которая сделает это:

  • Открыть меню Tools -> Customize
  • На вкладке "Macros" выберите наш ParamRectangle.py, заполните детали по желанию и нажмите "Add":

  • На вкладке Toolbars создайте новую панель инструментов в каком хотите верстаке (или глобально), выделите ваш макрос и добавьте его в панель инструментов:

  • Это всё, мы уже имеем новую кнопку панели инструментов, которая при клике создаст параметрический прямоугольник.

Запомните, если Вы хотите распространять файлы, созданные с помощью этого нового инструмента среди других людей, они должны так же иметь установленный на своём компьютере макрос ParamRectangle.py.

Читать далее