Pivy

From FreeCAD Documentation
Revision as of 21:05, 4 October 2014 by Renatorivo (talk | contribs) (Created page with "[http://ru.wikipedia.org/wiki/Callback_%28%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%29 Функция обратного...")

Pivy это python библаотека привязанная к Coin3d, библиотеке 3D-рендеринга используемой FreeCAD-ом. Когда он импортирован, в запущенный python интерпритатор, он позволяет вести диалог напрямую с любым запущеным деревом сцен Coin3d, также как окна трехмерного отображения FreeCAD, или даже создавать новые. Pivy входит в стандвртную установку FreeCAD.

Библиотека coin разделена на несколько частей, собственно coin, для управления древами сцен и привязки к различным GUI системам, таким как windows или, в нашем случае, qt. Эти модули также доступны pivy, если они представлены в системе. Модуль coin всегда присутствует, и это то что мы будем использовать в любом случае, поэтому мы не должны хаботится о наших привзках нашего 3D отображения, к различным интерфейсам, это уже сделано в самом FreeCAD. Все что вам нужно, так это сделать ЭТО:

 from pivy import coin

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

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

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, также могут обладать потомками. Полный список доступных coin объектов можно найти в оффициальной документаци coin.

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

 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)
 mtCustomNode.addChild(trans)
 myCustomNode.addChild(cub)
 sg.addChild(myCustomNode)

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

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

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

 sg.removeChild(myCustomNode)

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

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

FreeCAD features an easy way to use such callbacks:

 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()

The callback has to be initiated from an object, because that object must still be running when the callback will occur. See also a complete list of possible events and their parameters, or the official coin documentation.

Documentation

Unfortunately pivy itself still doesn't have a proper documentation, but since it is an accurate translation of coin, you can safely use the coin documentation as reference, and use python style instead of c++ style (for example SoFile::getClassTypeId() would in pivy be SoFile.getClassId())

Scenegraph
PyQt