Code snippets

From FreeCAD Documentation
Revision as of 22:46, 16 February 2011 by Psi13art (talk | contribs) (Created page with 'Эта страница содержит примеры, обрывки, куски FreeCAD python кода, собранный для получения пользователя…')
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Эта страница содержит примеры, обрывки, куски FreeCAD python кода, собранный для получения пользователями оптыта и обсуждения на форумах. Читайте и используете их как начало для ваших собственных сценариев...


Обычный файл InitGui.py

Каждый модуль должен содержать, помимо основного файла модуля, файл InitGui.py , ответственного за вставку модуля в главное Gui. Это простой пример

class ScriptWorkbench (Workbench): 
    MenuText = "Scripts"
    def Initialize(self):
        import Scripts # предполагается что Scripts.py ваш модуль
        list = ["Script_Cmd"] # Этот список должен содержать имена команд, которые были заданы в Scripts.py
        self.appendToolbar("My Scripts",list) 
        
Gui.addWorkbench(ScriptWorkbench())

Обычный файл модуля

Это пример головного файла модуля, содержащего всё что ваш модуль делает. Это Scripts.py файл вызванный в предыдущем примере. Вы можете установить здесь все ваши пользовательские команды.

import FreeCAD, FreeCADGui 

class ScriptCmd: 
   def Activated(self): 
       # Здесь вы описываете что ваш ScriptCmd делает...
       FreeCAD.Console.PrintMessage('Hello, World!')
   def GetResources(self): 
       return {'Pixmap' : 'path_to_an_icon/myicon.png', 'MenuText': 'Short text', 'ToolTip': 'More detailed text'} 
      
FreeCADGui.addCommand('Script_Cmd', ScriptCmd())

Импорт нового типа файлов

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

Это строка должна быть добавлена в InitGui.py файл для добавления нового расширения файлов в список:

# Предполагается что, Import_Ext.py это файл, который с кодом для открытия и чтения .ext файлов
FreeCAD.addImportType("Your new File Type (*.ext)","Import_Ext") 

Тогда в файле Import_Ext.py:

def open(filename): 
   doc=App.newDocument()
   # here you do all what is needed with filename, read, classify data, create corresponding FreeCAD objects
   doc.recompute()

Экспорт вашего документа в новые типы файлов работает схожим образом, исключая того что вы используете:

FreeCAD.addExportType("Your new File Type (*.ext)","Export_Ext") 

Добавление линии

Простейшая линия через две точки.

import Part,PartGui 
doc=App.activeDocument() 
# добавляет элемент линию в документ и устанавливает её точки
l=Part.Line()
l.StartPoint=(0.0,0.0,0.0)
l.EndPoint=(1.0,1.0,1.0)
doc.addObject("Part::Feature","Line").Shape=l.toShape() 
doc.recompute()

Добавление многоугольника

Многоугольник это просто набор соединенных отрезков (polyline в AutoCAD). Он необязательно должен быть замкнутым.

import Part,PartGui 
doc=App.activeDocument()
n=list() 
# создает 3D вектор, устанавливает его набор координат и добавляет их в список
v=App.Vector(0,0,0) 
n.append(v) 
v=App.Vector(10,0,0) 
n.append(v) 
#... повторяется для всех узлов
# Создает объект - многоугольник(polygon) и задает его вершины
p=doc.addObject("Part::Polygon","Polygon") 
p.Nodes=n 

doc.recompute()

Добавление и удаление объекта из группы

doc=App.activeDocument() 
grp=doc.addObject("App::DocumentObjectGroup", "Group") 
lin=doc.addObject("Part::Feature", "Line")
grp.addObject(lin) # добавление объекта lin в группу grp
grp.removeObject(lin) # удаление объекта lin из группы grp

Примечание: Вы также можете добавлять другие группы в группу...

Добавление Полигиональной модели

import Mesh
doc=App.activeDocument()
# создаем новую пустую сетку
m = Mesh.Mesh()
# строим блок из 12 граней (6 граней и по два труегольника в квадрате)
m.addFacet(0.0,0.0,0.0, 0.0,0.0,1.0, 0.0,1.0,1.0)
m.addFacet(0.0,0.0,0.0, 0.0,1.0,1.0, 0.0,1.0,0.0)
m.addFacet(0.0,0.0,0.0, 1.0,0.0,0.0, 1.0,0.0,1.0)
m.addFacet(0.0,0.0,0.0, 1.0,0.0,1.0, 0.0,0.0,1.0)
m.addFacet(0.0,0.0,0.0, 0.0,1.0,0.0, 1.0,1.0,0.0)
m.addFacet(0.0,0.0,0.0, 1.0,1.0,0.0, 1.0,0.0,0.0)
m.addFacet(0.0,1.0,0.0, 0.0,1.0,1.0, 1.0,1.0,1.0)
m.addFacet(0.0,1.0,0.0, 1.0,1.0,1.0, 1.0,1.0,0.0)
m.addFacet(0.0,1.0,1.0, 0.0,0.0,1.0, 1.0,0.0,1.0)
m.addFacet(0.0,1.0,1.0, 1.0,0.0,1.0, 1.0,1.0,1.0)
m.addFacet(1.0,1.0,0.0, 1.0,1.0,1.0, 1.0,0.0,1.0)
m.addFacet(1.0,1.0,0.0, 1.0,0.0,1.0, 1.0,0.0,0.0)
# масштабируем длинну ребер в 100 раз
m.scale(100.0)
# добавление сетки в активный документ
me=doc.addObject("Mesh::Feature","Cube")
me.Mesh=m

Добавление дуги или огружности

import Part
doc = App.activeDocument()
c = Part.Circle() 
c.Radius=10.0  
f = doc.addObject("Part::Feature", "Circle") # создает в документе функционал -окружность
f.Shape = c.toShape() # Устанавливает форму- окружность в свойство "форма"
doc.recompute()

Получение доступа и изменение представления объекта

Каждый объект в FreeCAD документе оссоциируется с визуальным представлением объекта, которое хранит все параметры , определяющие как объект представлен, такие как цвет, длина линий, и.т.д...

gad=Gui.activeDocument()   # получение доступа к активному документ содержащему все
                          # визуальные представления функционалов 
                          # соответствующего App документа

v=gad.getObject("Cube")    # получение доступа к визуальному представлению Mesh функционала 'Cube' 
v.ShapeColor               # печатает цвет в терминал
v.ShapeColor=(1.0,1.0,1.0) # устанавливает цвет формы в белый

Наблюдение за поведение мыши в 3D окне через Python

Inventor позваляет добавить оди и более узлов обратного вызова(callback) в дерево сцен просмотрщика. По умолчанию в FreeCAD один узел обратного вызова установлен в кадое окно просмотра(просмотрщик), который позволяет добавить глобальные или статические C++ функции. Соответствуюе Python привязки, некоторые методы которых позволяют использовать эту технику (callback) в Python коде.

App.newDocument()
v=Gui.activeDocument().activeView()

#Этот класс регистрирует любые событияпроисходящие с кнопкой мыши. Когда регистрируется  вызов событий  двойной 'down' и
#'up' мы должны ввести логический флаг, чтобы с этим справится(тут получился бред).
class ViewObserver:
   def logPosition(self, info):
       down = (info["State"] == "DOWN")
       pos = info["Position"]
       if (down):
           FreeCAD.Console.PrintMessage("Clicked on position: ("+str(pos[0])+", "+str(pos[0])+")\n")
      
o = ViewObserver()
c = v.addEventCallback("SoMouseButtonEvent",o.logPosition)

Теперь, выберите какую нибудь область в окне 3D-просмотра и наблюдайте сообщения в окне вывода. Для завершения наблюдения просто вызовите

v.removeEventCallback("SoMouseButtonEvent",c)

Поддерживаются следующие типы событий

  • SoEvent -- Все события
  • SoButtonEvent -- Все события клавиш клавиатуры и мыши
  • SoLocation2Event -- события 2D перемещений (обычно движение мыши)
  • SoMotion3Event -- события 3D перемещений (обычно spaceball)
  • SoKeyboradEvent -- события нажатие и отпускание клавиш клавиатуры
  • SoMouseButtonEvent -- события нажатия и отпускания клавиш мыши
  • SoSpaceballButtonEvent -- события нажатия и отпускания клавиш spaceball

Python функции которые могут быть зарегистрированы в addEventCallback() предлагающем словарь(dictionary). В зависимости от наблюдателя события словарь может содержать различные ключи.

Для всех событий существуют ключи:

  • Type -- Имя типа события т.е. SoMouseEvent, SoLocation2Event, ...
  • Time -- текущие время в виде строки
  • Position -- набор из двух целых чисел как позиция курсорa мыши
  • ShiftDown -- логическая(boolean) переменная, true если Shift нажат, в противном случае false
  • CtrlDown -- логическая(boolean) переменная, true если Ctrl нажат, в противном случае false
  • AltDown -- логическая(boolean) переменная, true если Alt нажат, в противном случае false

Для всех клавишных событий, т.e. для событий клавиатуры, мыши или spaceball

  • State -- Строка 'UP' если кнопка была вверху, 'DOWN' если кнопка была внизу или 'UNKNOWN' во всех остальных случаях

Для событий связанных с клавиатурой:

  • Key -- значение нажатоой клаывиши

Для событий связанных с мышью

  • Button -- Нажаты клавиши, могут быть BUTTON1, ..., BUTTON5 или ANY

Для событий spaceball:

  • Button -- Нажатые клавиши, могут быть BUTTON1, ..., BUTTON7 или ANY

и наконец события движения:

  • Translation -- набор из трех переменных floats
  • Rotation -- кватернион поворота, т.е. набор из четырех переменных floats

Манипулирование scenegraph в Python

Кроме того можно получить и изменить граф сцены в Python, с помощью модуля 'pivy' -- Python привязки к Coin.

from pivy.coin import *                # загрузка модуля pivy
view = Gui.ActiveDocument.ActiveView   # получение графа, активного вида
root = view.getSceneGraph()            # корень это узел SoSeparator
root.addChild(SoCube())
view.fitAll()

Python API для pivy создано используя инструмент SWIG. Так как мы используем в FreeCAD некоторые самостоятельно записанные узлы вы не можете создавать их напрямую через Python. Однако, возможно создать узел в его внутренним именем. Экземпляр типа 'SoFCSelection' может быть создан

type = SoType.fromName("SoFCSelection")
node = type.createInstance()

Добавление и удаление объектов в/из графа сцены

Добавление новых узлов в граф сцены(scenegraph) может сделать таким образом. Всегда заботтесь о добавлении SoSeparator содержащего информацию о геометрии, координатах и материалах объекта. В следующем примере добавляется красная линия из точки (0,0,0) в (10,0,0):

from pivy import coin
sg = Gui.ActiveDocument.ActiveView.getSceneGraph()
co = coin.SoCoordinate3()
pts = [[0,0,0],[10,0,0]]
co.point.setValues(0,len(pts),pts)
ma = coin.SoBaseColor()
ma.rgb = (1,0,0)
li = coin.SoLineSet()
li.numVertices.setValue(2)
no = coin.SoSeparator()
no.addChild(co)
no.addChild(ma)
no.addChild(li)
sg.addChild(no)

Чтобы удалить её, просто введите:

sg.removeChild(no)

Добавление пользовательских виджетов к интерфейсу

Вы можете содать собственные виджеты с помощью Qt designer, превратив их в сценарии на python, с помощью PyQt4, и загрузив их в FreeCAD.

Python код созданный с помощью Ui python compiler (это инструмент для конвертирования файлов ui. созданных qt-designer в python код) в основном выглядит так (это простой пример, вы также может писать этот код напряму с помощью python):

class myWidget_Ui(object):
 def setupUi(self, myWidget):
   myWidget.setObjectName("my Nice New Widget")
   myWidget.resize(QtCore.QSize(QtCore.QRect(0,0,300,100).size()).expandedTo(myWidget.minimumSizeHint())) # Установка размера виджета

   self.label = QtGui.QLabel(myWidget) # создание объекта метка(label)
   self.label.setGeometry(QtCore.QRect(50,50,200,24)) # установка размеров
   self.label.setObjectName("label") # установка значения имени, теперь его можно найти по имени

 def retranslateUi(self, draftToolbar): # built-in QT function that manages translations of widgets
   myWidget.setWindowTitle(QtGui.QApplication.translate("myWidget", "My Widget", None, QtGui.QApplication.UnicodeUTF8))
   self.label.setText(QtGui.QApplication.translate("myWidget", "Welcome to my new widget!", None, QtGui.QApplication.UnicodeUTF8))				

Тогда все что вам нужно сделать, это создать ссылку на FreeCAD Qt окно, вставить виджет в него, и "преобразовать" этот виджет в ваш с Ui кодом который мы только что сделали:

 app = QtGui.qApp
 FCmw = app.activeWindow() # активное окно qt , = freecad окну, поскольку мы находимся в нем
 myNewFreeCADWidget = QtGui.QDockWidget() # создает новый dckwidget
 myNewFreeCADWidget.ui = myWidget_Ui() # загружает Ui сценарий
 myNewFreeCADWidget.ui.setupUi(myNewFreeCADWidget) # устанавливает ui
 FCmw.addDockWidget(QtCore.Qt.RightDockWidgetArea,myNewFreeCADWidget) # добавляет виджет в главное окно
Embedding FreeCAD/ru
Line drawing function/ru
Available translations of this page: Template:Se