python

«САПР для всех, даром, и пусть никто не уйдет…» или первые шаги в программировании FreeCAD на Python

  • вторник, 20 августа 2019 г. в 00:18:36
https://habr.com/ru/post/464113/
  • Open source
  • Python
  • Программирование
  • API
  • CAD/CAM


Возможно, вам уже ранее попадались мои заметки по первым шагам в программировании САПР на примере NanoCAD.

Надо отметить, что для человека не умеющего программировать и знающего САПР на уровне «электронного кульмана» это было удивительное приключение. Однако, NanoCAD это все же в первую очередь коммерческий продукт. Его бесплатная версия не обновлялась, уже около шести лет и порядком устарела в плане возможностей для разработки.

А ведь так хотелось, чтобы как в одной замечательной повести: «Счастье для всех, даром, и пусть никто не уйдёт обиженный!» . Поэтому было принято решение, внять совету боевого товарища DrZugrik и установить себе FreeCAD.

Итак, по горячим следам пишу для вас материал, всего за один день я узнал, как подружить эту САПР с Anaconda, написал на Python простенький скрипт, который рисует квадратик с текстом и протестировал его на работоспособность в Windows и Linux. О чем я собственно готов вам по шагам рассказать и показать, чтобы вы тоже могли это сделать.

Хотите поближе познакомиться с очаровательной парочкой Python и FreeCAD? Тогда милости прошу под кат.




Содержание:

Часть I: Введение.
Часть II: Стандартная установка и первая проба
Часть III: А теперь подружим FreeCad с «Анакондой»
Часть IV: Пишем простенькую библиотеку
Часть V: Заключение

Часть I: Введение


Как ни странно на «Хабре» совсем немного публикаций посвященных FreeCAD, хорошая статья вышла у Eddy_Em «Знакомьтесь: FreeCAD», и еще несколько работ, в которых герой нашей статьи упоминается вскользь.

Для начала буквально два слова о программе. Я не буду дублировать информацию с официального сайта, а просто широкими мазками опишу почему остановил свое внимание на этой САПР.

Итак, FreeCAD это система автоматизированного проектирования с открытым исходным кодом, заточенная в первую очередь на трехмерное параметрическое моделирование. На момент написания статьи последняя версия программы 0.18.3. Пусть вас не смущает, что значение номера релиза далеко от единицы. FreeCAD долго и активно разрабатывается и на текущий момент вполне функционален. Более того как я понимаю он уже давно, имеет определенную популярность у людей занимающихся 3D моделированием и печатью, особенно у идейных самоделкиных, интересующихся open source / open hardware и всяческим DIY.

Но если вдруг вы совсем не разбираетесь в трехмерном моделировании, то это не повод обойти FreeCAD стороной. Функционал САПР разбит по своеобразным модулям — верстакам (Workbench) среди которых есть и привычное 2D черчение, в том числе верстак для оформления рамок листов и даже верстак для реализация концепции BIM.

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


Часть II: Стандартная установка и первая проба


FreeCAD доступен для всех трех распространенных операционных систем, но поскольку «Яблочной» техникой я обделен, то мы рассмотрим только варианты для Windows 10 и Linux Mint.

Самый простой способ начать программировать для FreeCAD это скачать дистрибутив и установить его стандартным для операционной системы путем. В таком случае мы получим в свое распоряжение предустановленный с программой интерпретатор Python (на момент написания статьи Python версии 3.6.6).

Начать программировать для FreeCAD, пожалуй даже проще чем для NanoCAD или AutoCAD, просто откроем вкладку Вид -> Панель -> и включим консоль Python. Собственно, вот и все, можно смело программировать.

Но давайте сначала попробуем начертить, что-нибудь штатными средствами. Например, круг.
Обратите внимание на вывод консоли

Gui.activateWorkbench("DraftWorkbench")
>>> App.newDocument("Безымянный")
>>> App.setActiveDocument("____________________")
>>> App.ActiveDocument=App.getDocument("____________________")
>>> Gui.ActiveDocument=Gui.getDocument("____________________")
>>> Gui.activeDocument().activeView().viewDefaultOrientation()
>>> import Draft
>>> pl=FreeCAD.Placement()
>>> pl.Rotation.Q=(0.0,0.0,1.5308084989341915e-17,1.0)
>>> pl.Base=FreeCAD.Vector(-1.0610677003860474,-0.31207874417305,0.0)
>>> circle = Draft.makeCircle(radius=0.8633861373365326,placement=pl,face=False,support=None)
>>> Draft.autogroup(circle



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

x=-1.0610677003860474
pl=FreeCAD.Placement()
pl.Rotation.Q=(0.0,0.0,1.5308084989341915e-17,1.0)
pl.Base=FreeCAD.Vector(x*5,-0.31207874417305,0.0)
circle = Draft.makeCircle(radius=0.8633861373365326,placement=pl,face=False,support=None)

Как видите теперь круга стало два, причем, как и планировалось один правее на координату «х» базовой точки первого круга умноженную на 5.




Часть III: А теперь подружим FreeCad с «Анакондой»


Но возможности САПР не ограничиваются стандартным использование в качестве «кульмана». С помощью API, FreeCAD можно встроить в вашу собственную программу и использовать, как с графическим интерфейсом так и без, но этот вопрос мы рассмотрим как-нибудь в другой раз.

А пока, представим себе такую ситуацию, допустим вы увлекаетесь машинным обучением и анализом данных на Python и уже поставили себе
дистрибутив Anaconda, тогда вы, наверное, сильно обрадуетесь узнав, что благодаря ребятам из conda-forge можно скомпоновать все возможности этого дистрибутива и FreeCAD.

По ссылке представлено руководство, как установить его в случае если вы используете mini-conda, а мы с вами установим его в полноценную «Анаконду» через её навигатор.

Итак, откроем Anaconda-Navigator, перейдём на вкладку Environments и создадим новое окружение, нажав на кнопку Create. Название окружению, можно дать любое, я назвал – «freecad». Выбираем нужную версию Python и создаём новое окружение.



Но этого еще недостаточно, необходимо добавить канал conda-forge, просто впечатайте в поле, которое появится после нажатия кнопки Add «conda-forge» и дайте системе обновить списки пакетов.



Почти готово теперь осталось установить сам FreeCAD

Нажимаем ЛКМ на названии пакета и выбираем какую версию хотим установить, как на картинке ниже (у меня правда уже установлен)



После томительного ожидания у вас будет полностью установлен дистрибутив FreeCad нужной версии останется его только запустить.

В самом простом случае без параметров запуска необходимо запустить консоль conda с нашим окружением, и запустить САПР одноимённой командой FreeCAD.



Откроется пустое окно FreeCAD в котором мы выберем верстак для двухмерного черчения.



Как видим, теперь версия Python совсем не та, что была при стандартной установке.


Создадим новый документ (Control+N) он нам пригодится для тестирования нашей мини библиотеки.


Часть IV: Пишем простенькую библиотеку


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

Создаем файл (я свой назвал — «drawhabr.py») и пишем в него следующий код:

#Simple lib for test Python API in FreeCad
#Tested on Python 3.7. and FreeCad 0.18.3
#Designed for article - https://habr.com/ru/post/464113/
import  FreeCAD, FreeCADGui, Part, Draft
class stamp:
    "This class creates a rectangle with text. Coordinates are set by entering into the console."
    def __init__(self):
        self.view = FreeCADGui.ActiveDocument.ActiveView
        x=float(input("set x point  "))
        y=float(input("set y point  "))
        mtext=str(input("input text  "))
        self.drawstamp(mtext, x , y )
        FreeCAD.Console.PrintMessage("\r\n Your object was successfully created")
      
    def drawstamp(self, mtext,x=0,y=0 ):
        "Method for placing a figure in model space."
        if (mtext==""):
            mtext="Hello Habr!"
        point=FreeCAD.Placement(FreeCAD.Vector(x,y,0), FreeCAD.Rotation(0,0,0), FreeCAD.Vector(0,0,0))
        text = Draft.makeText(mtext,point=FreeCAD.Vector(x+0.25,y+0.55,0.0))
        fontsize = 1.0
        textwidth=(len(mtext)*fontsize*0.6)+0.35
        textheight=fontsize+0.5
        text.ViewObject.FontSize = fontsize  
        text.ViewObject.FontName = "Courier"  
        rec = Draft.makeRectangle(length=textwidth,height=textheight,placement=point,face=False,support=None)

Или просто можете скопировать файл с
GitHub

Код очень простой, но некоторые моменты думаю стоит пояснить.

import  FreeCAD, FreeCADGui, Part, Draft

Импортируем необходимые библиотеки, после чего создаем класс.
Поскольку я еще не научился обрабатывать ввод мышкой, координаты для объекта и текст мы будем вводить напрямую в консоль с клавиатуры. Это реализуется стандартными методами Python. Потом в конструкторе класса вызываем нашу функцию (метод), которая будет это все чертить.

Из особенностей FreeCAD в конструкторе класса можно выделить две команды:

self.view = FreeCADGui.ActiveDocument.ActiveView
FreeCAD.Console.PrintMessage("\r\n Your object was successfully created")

Первая выбирает нам пространство активной рабочей области, а вторая, после установки объекта напишет нам сообщение в самом низу окна программы (на серой полоске, не путать с консолью Python)

Код метода тоже интуитивно понятен.Но все же поясню для надежности.

    def drawstamp(self, mtext,x=0,y=0 ):
        "Method for placing a figure in model space."
        if (mtext==""):
            mtext="Hello Habr!"

Необходимо на тот случай, если пользователь введет пустую строку. Без этого в текст будет вписано слово Label а прямоугольник будет иметь некорректную длину.
point=FreeCAD.Placement(FreeCAD.Vector(x,y,0), FreeCAD.Rotation(0,0,0), FreeCAD.Vector(0,0,0))


Определим координаты базовой точки дня нашей рамки, обрамляющей текст.
Напомню, что данные берутся из ввода в консоль.

Обратите внимание, что мы работаем с трехмерной координатой вида FreeCAD.Vector(x,y,z), но в данном примере координатой Z можем пренебречь. Другие параметры связанные с вращением рамки пока не трогаем.

text = Draft.makeText(mtext,point=FreeCAD.Vector(x+0.25,y+0.55,0.0))

создадим текст, командой Draft.makeText, передав ей текст, который ввели в консоль.

Координаты возьмем с небольшим смещением от базовой точки рамки.

По-хорошему надо было научиться обрабатывать рамку (границу) текста используя параметры API, после чего на основании нее рассчитывать ширину и высоту нашей обрамляющей рамки. Но поскольку я сам только-только познакомился с программой, то задачу решил рабоче-крестьянским методом. Мы зафиксируем высоту шрифта, назначим ему стиль моноширинного шрифта (Courier) и в зависимости от этого определим длину и ширину рамки которую будем чертит вокруг текста.

        text = Draft.makeText(mtext,point=FreeCAD.Vector(x+0.25,y+0.55,0.0))
        fontsize = 1.0
        textwidth=(len(mtext)*fontsize*0.6)+0.35
        textheight=fontsize+0.5
        text.ViewObject.FontSize = fontsize  
        text.ViewObject.FontName = "Courier"  

Осталось только подставить наши параметры в функции черчения прямоугольника

rec = Draft.makeRectangle(length=textwidth,height=textheight,placement=point,face=False,support=None)

вот, собственно, и все.

Осталось только подключить нашу библиотеку. Для этого её можно просто скопировать в папку, в которой лежат остальные библиотеки Python для выбранного окружения.

Например, для Windows 10 путь может быть следующим (в значимости от места установки Anaconda):

C:\Users\ВашеИмяПользователя\Anaconda3\envs\freecad\Lib

Для Linux путь будет примерно таким:

/home/ourUserName/anaconda3/envs/freecad/lib/python3.7

Все осталось загрузить нашу библиотеку.
Для этого вначале введем в консоли название нашего модуля (без расширения файла)

import drawhabr

А затем вызовем конструктор класса

drawhabr.stamp()

Вот и все осталось вести, параметры функции и наслаждаться результатом.



На всякий случай вот скриншот подтверждающий, что в Linux тоже все работает.




Часть V: Заключение


Сегодня мы вместе сделали только маленький шаг на пути познания API FreeCAD.
Несмотря на то, что на мой взгляд, для двухмерного черчения и разработки проектов, FreeCAD не так привычен как AutoCAD (NanoCAD) или другие распространенные САПР, но зато программировать его намного проще.

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

А учитывая, тот факт, что разработчики люди не жадные и при необходимости позволяют даже коммерческую разработку с помощью FreeCAD по лицензии LGPL да в сочетании со всей мощностью подключаемых библиотек Python (например, из того же дистрибутива Anaconda), разработка программ с использованием FreeCAD выглядит интересной задачей.
Если я пойму, что и вам эта тема интересна, то постараюсь сделать мини-цикл заметок по аналогии с Nanocad