Pivy

From FreeCAD Documentation
Revision as of 09:44, 28 May 2020 by FuzzyBot (talk | contribs) (Updating to match new version of source page)

Введение

Pivy - это библиотека привязок Python для Coin, библиотеки 3D-рендеринга, используемой в FreeCAD для отображения вещей в трёхмерный вид. При импорте в работающий интерпретатор Python Pivy позволяет напрямую взаимодействовать с любым работающим графом сцен Coin, таким, как трёхмерный вид FreeCAD, или даже создавать новые. Pivy не требуется для компиляции FreeCAD, но требуется во время выполнения при запуске основанных на Python верстаков, которые создают фигуры на экране, такие как Draft и Arch. Из-за этого Pivy обычно устанавливается при установке дистрибутива FreeCAD.

Библиотека Coin разделена на несколько частей, собственно Coin, для управления графами сцен и привязки к различным GUI системам, таким как Windows или Qt. Эти модули также доступны Pivy, если они представлены в системе. Модуль Coin всегда присутствует, и это то что мы будем использовать в любом случае, поэтому мы не должны заботится о привязках нашего трёхмерного отображения к различным интерфейсам, это уже сделано в самом FreeCAD. Все что вам нужно, так это сделать это:

from pivy import coin

Получение доступа и изменение древа сцен

Мы видели на странице Scenegraph, как организована типичная сцена Coin. Все что появляется в трехмерный вид - это граф сцен Coin, организованный так же. У нас есть один корневой узел, и все объекты на экране его потомки.

FreeCAD обладает простым способом получит доступ к корневому узлу(вершине) древа сцена 3D вида:

sg = FreeCADGui.ActiveDocument.ActiveView.getSceneGraph()
print(sg)

Это вернет корневой узел:

<pivy.coin.SoSelection; proxy of <Swig Object of type 'SoSelection *' at 0x360cb60> >

Мы сразу же можем просмотреть потомков, нашей сцены:

for node in sg.getChildren():
    print(node)

Некоторые из этих узлов, такие как SoSeparators или SoGroups, также могут обладать потомками. Полный список доступных Сoin объектов можно найти в официальной документации Сoin.

Давайте, сейчас, попробуем добавить что-нибудь в наше древо сцены. Мы добавим милейший красный куб:

col = coin.SoBaseColor()
col.rgb = (1,0,0)
cub = coin.SoCube()
myCustomNode = coin.SoSeparator()
myCustomNode.addChild(col)
myCustomNode.addChild(cub)
sg.addChild(myCustomNode)

и здесь наш(милый) красный куб. Теперь попробуем следующее:

col.rgb = (1, 1, 0)

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

Ключ к работе с древом сцен в ваших сценариях, чтобы обладать доступом к определенным свойствам узлов вы добавляете то что вам нужно. Например, если нам нужно переместить наш куб, мы добавили бы узел SoTranslation в нашему обычному узлу, м выглядело бы это так:

col = coin.SoBaseColor()
col.rgb=(1,0,0)
trans = coin.SoTranslation()
trans.translation.setValue([0,0,0])
cub = coin.SoCube()
myCustomNode = coin.SoSeparator()
myCustomNode.addChild(col)
myCustomNode.addChild(trans)
myCustomNode.addChild(cub)
sg.addChild(myCustomNode)

Помните, что в дереве сцен openInventor, важен порядок. Узел влияет на то что будет дальше, вы можете сказать нечто вроде: цет красны, куб, цвет желтый, сфера, и вы получите красный куб и желтую сферу. Если мы добавим перемещение сейчас в нашу существующий узел, он будет стоять после куба и не будет влиять на него. Если мы вставили его до его создания, как показано выше, мы могли бы сейчас сделать:

trans.translation.setValue([2,0,0])

И наш куб прыгает на 2 единицы вправо. Наконец, удалим что-нибудь, введя:

sg.removeChild(myCustomNode)

Использование обратных вызовов

Функция обратного вызова это система, позволяет библиотекам которые вы используете, такой как наша библиотека coin , возвращать вызов, это означает, возможность вызова определенных функций с вашего запущенного python объекта. Это очень полезно, потому что это способ которыйм coin может сообщить вам , о конкретных событиях происходящих на сцене. Coin может наблюдать за множеством различных вещей, таких как положение курсора, нажатия клавиши мыши, нажатые клавиши клавиатуры, и множество других вещей.

FreeCAD способен легко использовать такие функции обратного вызова:

class ButtonTest:
    def __init__(self):
        self.view = FreeCADGui.ActiveDocument.ActiveView
        self.callback = self.view.addEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(),self.getMouseClick) 

    def getMouseClick(self,event_cb):
        event = event_cb.getEvent()
        if event.getState() == SoMouseButtonEvent.DOWN:
            print("Alert!!! A mouse button has been improperly clicked!!!")
            self.view.removeEventCallbackSWIG(SoMouseButtonEvent.getClassTypeId(),self.callback) 
 
ButtonTest()

Функция обратного вызова, должна быть инициализирована объектом, потому что объект должен по прежнему работать, когда будут происходить обратные вызовы. Смотри также полный список возможных событий и их параметров, или официальную документацию Coin.

Документация

К сожалению сам Pivy ещё не обладает собственной документацией. Однако, так как это оболочка библиотекиCoin, вы можете читать справку по C++. В этом случает Вам нужно лишь переводить стиль наименования классов C++ в стиль Python.

В C++:

SoFile::getClassTypeId()

В Pivy

SoFile.getClassId()