Jump to content

Создание параметрических объектов

From FreeCAD Documentation
This is the approved revision of this page, as well as being the most recent.

В предыдущей главе мы рассмотрели, как создавать геометрию Детали - 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__ мы выполняем две важнейшие задачи:

  • Храним сам класс в атрибуте Proxy объекта документа FreeCAD:

Присваивая self атрибуту Proxy объекта документа FreeCAD, мы связываем логику нашего класса Python с объектом FreeCAD. Это означает, что объект документа будет "содержать" код класса Python внутри себя, позволяя ему вести себя в соответствии с логикой, определённой в классе. Эта связь позволяет FreeCAD знать, как взаимодействовать с параметрическим объектом и пересчитывать его.

  • Создаём все свойства, необходимые объекту:

Используя метод addProperty, мы определяем пользовательские свойства, необходимые объекту. Свойства выступают в качестве параметров или переменных для объекта и могут быть доступны, изменены и отображены в редакторе свойств FreeCAD. В примере мы добавляем свойство с плавающей точкой под названием MyLength. Это свойство в дальнейшем будет влиять на форму или поведение объекта.

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

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

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

Подводя итог:

  • Метод execute вызывается каждый раз, когда объект нуждается в обновлении.
  • Он отвечает за пересчёт формы и присвоение её атрибуту Shape объекта.
  • Аргумент obj предоставляет доступ к объекту документа FreeCAD, что позволяет вносить изменения программно.

При такой системе FreeCAD делает все остальное - обеспечивает правильное обновление объекта в документе и его корректное отображение в графическом интерфейсе.

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

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

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

Мы зададим нашему объекту два свойства: Length - Длина и Width - Ширина, которые мы будем использовать для построения прямоугольника. Затем, поскольку наш объект уже имеет предварительно созданное свойство Размещение - 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, лучше сохраните его где-нибудь, чтобы потом можно было использовать и изменять его. Например, в новом макросе (меню Макросы -> Макрос... -> Создать). Назовите его, например, "ParamRectangle". Однако макросы FreeCAD сохраняются с расширением .FCMacro, которое Python не распознаёт при использовании импорта. Поэтому, прежде чем использовать приведенный выше код, нам нужно будет переименовать файл ParamRectangle.FCMacro в ParamRectangle.py. Это можно сделать просто из проводника файлов, перейдя в папку 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()

Ниже приведена разбивка предыдущих команд:

  • myObj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython", "Rectangle"): Создаёт новый объект Part::FeaturePython с именем Rectangle в активном документе FreeCAD. Этот объект специально разработан для пользовательского параметрического поведения, позволяя логике, определённой Python, управлять его свойствами и поведением.
  • ParamRectangle.ParametricRectangle(myObj): Инициализирует объект, связывая его с классом ParametricRectangle из модуля или скрипта ParamRectangle. Это связывает пользовательскую логику, определяемую Python, с объектом, позволяя ему действовать как параметрический объект.
  • myObj.ViewObject.Proxy = 0: Сбрасывает атрибут ViewObject.Proxy в 0, гарантируя, что объект использует стандартную обработку представлений FreeCAD. Этот шаг необходим, если вы не определите пользовательский ViewProvider для управления визуальным представлением объекта.
  • FreeCAD.ActiveDocument.recompute(): Пересчитывает документ для обновления геометрии и отражения изменений в графическом интерфейсе FreeCAD, делая новый объект полностью видимым и функциональным

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

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

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

  • Откройте меню Инструменты -> Настройка...
  • На вкладке "Макрос" выберите наш макрос ParamRectangle.py, заполните детали по своему усмотрению и нажмите "Добавить":

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

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

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

Читать далее