Manual/ru

From FreeCAD Documentation
Revision as of 02:11, 27 February 2011 by Psi13art (talk | contribs) (Created page with 'This is the FreeCAD manual. It includes the essential parts out of the FreeCAD documentation wiki. It is made primarily to be printed as one big document, so, if yo…')
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

This is the FreeCAD manual. It includes the essential parts out of the FreeCAD documentation wiki. It is made primarily to be printed as one big document, so, if you are reading this online, you might prefer to head directly to the Online help version, which is easier to browse.


<translate>

150
150

Welcome to the FreeCAD on-line help

The FreeCAD help system is hosted on a wiki built, maintained and developed by the FreeCAD community of users and developers. It contains general information about FreeCAD, tutorials, precise documentation about each FreeCAD command, and programming documentation for Python and C++. It also contains translations of this documentation in several languages. We hope you will find here all the information you need. In case you have questions you can't find answers to in this documentation, have a look at the FreeCAD forum, where you might find your question answered already, or find someone able to help you.

How to use

This document is divided into several sections:

  1. Introduction and usage, for end-users who simply want to use the program.
  2. Python scripting, for power-users who are interested by the scripting capabilities of FreeCAD and would like to customize some of its aspects.
  3. Development guidelines, for developers who consider FreeCAD as a base for developing their own applications.

Many pages of this wiki are also grouped into an easier to read Manual. If you are new to FreeCAD, we suggest you start reading the manual.

Contribute

As you may have experienced sometimes, programmers are sometimes bad documentation writers! It is therefore vital that experienced users help to write, update, fix and revise the documentation. Yes, we mean you! Editing the wiki is easy. As this wiki is write-protected to reduce spamming, you will need a FreeCAD wiki account to log in. Ask on the forum and we will create an account for you. Currently, the wiki account is separate from the forum account but we will create you a wiki account with the same name as your forum account. Then you can start editing! Also, check out this page for more ways you can help FreeCAD.

</translate>

Введение

FreeCAD это универсальная параметрическая 3D САПР , чья разработка полностью базируется на принципах открытого исходного кода (LGPL License). FreeCAD непосредственно направлен на разработку в сферах машиностроения и дизайна объектов, но также подходит для более широкого круга применений в инженерных задачах, таких как архитектура, анализ методом конечных элементов, 3D печать, и других.

Во FreeCAD имеются инструменты аналогичные CATIA, SolidWorks или Solid Edge, и, следовательно, он также попадает в категорию САПР, PLM, CAx и CAE. Это параметрический моделлер с модульной программной архитектурой, которая позволяет предоставлять дополнительные функциональные возможности без изменения базовой системы.

Как и во многих пакетах САПР, в нем много 2D-компонентов для создания плоских фигур или создания рабочих чертежей. Однако прямое 2D-рисование (как например в Inkscape или AutoCAD LT) не является основным, так же как анимация или редактирование сеток (например Blender, Maya, 3ds Max, или Cinema 4D). Тем не менее, благодаря своей широкой адаптивности, FreeCAD может оказаться полезным в гораздо более широкой области, чем его текущая сфера деятельности.

FreeCAD интенсивно использует библиотеки с открытым исходным кодом, существующие в области научных вычислений. Среди них Open Cascade Technology (OCCT), мощное ядро САПР; Coin3D, инструментарий для разработки 3D-графики, совместимый с Open Inventor; Qt, всемирно известный пользовательский интерфейс; и Python, современный язык сценариев. Сам FreeCAD также может быть использован в качестве библиотеки другими программами.

FreeCAD также является мультиплатформенным и в настоящее время работает в операционных системах Linux/Unix, Windows и macOS с одинаковым внешним видом и функциональностью на всех платформах.

Более подробнее о возможностях FreeCADа, можно узнать в разделах: "Список функций", "Информация о версиях", "Начало работы". Так же вы можете посмотреть скриншоты.

О проекте FreeCAD

Проект FreeCAD начался в далёком 2001 году, как описано на странице его истории.

FreeCAD поддерживается и проектируется сообществом энтузиастов, проектировщиков и пользователей (смотри страницу contributors). Они работают на FreeCAD добровольно, в свободное время. Они не могут гарантировать, что FreeCAD содержит всё, что Вы можете пожелать, но они делают всё, что могут! Сообщество зовёт на форум FreeCAD, где обсуждается большая часть идей и пожеланий. Смело присоединяйтесь к нам здесь!

About the FPA

The FreeCAD project is also supported by a non-profit organization, the FreeCAD project association (FPA). The FPA is an independent body created by some FreeCAD veterans in 2021 to collect donations and other resources to support the project and its community, to help protect that community and allow it to continue developing in the best conditions, and to represent the project against other bodies such as companies and institutions.


Это обширный, но неполный список функций, реализованных во FreeCAD.

Информация о версиях

Основные функции

  • Полное геометрическое ядро, основанное на OpenCasCade, позволяет производить сложные трёхмерные операции над сложными типами форм, со встроенной поддержкой таких понятий, как: Граничное представление (boundary representation, BREP), Кривые и поверхности неоднородных рациональных B-сплайнов (Non-uniform rational basis spline, NURBS), широкий спектр геометрических объектов, булевы операции над фигурами или сопряжения и встроенную поддержку форматов STEP и IGES
  • Полностью параметрическая модель данных. Объекты FreeCAD параметрические в основе, то есть их форма может полностью зависеть от параметров или даже зависеть от других объектов, все изменения пересчитываются по запросу, и записываются в стеке отмен-возвратов. Легко могут быть добавлены новые объекты, которые могут быть даже написаны на python
  • Модульная архитектура, позволяющая добавлять функциональность через плагины (модули). Эти расширения могут быть комплексными и программироваться на C++, или простыми как скрипты Python или записываемые самостоятельно макросы. У Вас есть полный доступ из встроенного интерпретатора Python, макросов или внешних сценариев к практически любой части FreeCAD, позволяя создавать и изменять геометрию, двумерное и объёмное представление этой геометрии (scenegraph) или даже интерфейс FreeCAD
  • Импорт/экспорт в стандартные форматы, такие как: STEP, IGES, OBJ, файла) STL, DXF, SVG,U3D, DAE, IFC, OFF, NASTRAN, VRML, кроме собственного формата FreeCAD Fcstd. Уровень совместимости между FreeCAD и данными форматами может различаться, поскольку зависит от поддерживающего их модуля.
  • Модуль эскизирования со встроенным вычислителем ограничений, позволяющий создавать эскизы с геометрически ограниченными двухмерными формами. Создаваемые с помощью Sketcher двумерные геометрические фигуры с ограничениями могут использоваться как база для построения других объектов FreeCAD.
  • Модуль робототехники, позволяющий изучать движение роботов в графическом интерфейсе.
  • Удобный новый модуль для создания традиционных чертежей с опциями вроде видов детализации, сечений, образмеривания и других, которые позволяют создать двумерный вид вашей трёхмерной модели. Эти модули создают листы, готовые к экспорту в SVG или PDF. Так же есть более старый модуль черчения с его небогатыми возможностями графического интерфейса, но мощной функциональностью через Python.
  • Модуль рендеринга может экспортировать 3D объекты для рендеринга во внешние программы. Пока что он поддерживает только POV-Ray и LuxRender
  • Модуль архитектуры позволяет работать по процессу информационного моделирования здания (Building Information Modeling, BIM), при совместимости со спецификацией IFC.
  • Модуль Path посвящён автоматизации механической обработки (Computer-aided manufacturing, CAM), например, фрезерования, и может выводить, показывать и настраивать G-код.
  • Интегрированный обработчик электронных таблиц и выражений, который может использоваться для управления моделями через формулы и централизованной организации данных моделей.

Общие функции

  • кроссплатформенность. FreeCAD запускается и ведёт себя точно также на Windows, Linux, macOS и других платформах.
  • полностью графическое приложение. FreeCAD обладает законченным Графическим Интерфейсом Пользователя, основанном на инструментарии Qt, с 3D просмотрщиком, основанным на Open Inventor, позволяющим быстро отрисовывать 3D сцены c весьма доступным представлением SceneGraf.
  • может работать, как консольное приложение из командной строки. В режиме командной строки FreeCAD запускается без графического интерфейса, но со всеми инструментами геометрии. В этом режиме он требует относительно мало памяти и может быть использован, например, в качестве сервера для создания содержимого другим приложениям.
  • может быть импортирован как модуль Python. FreeCAD может импортироваться в любое приложение, способное запускать сценарии Python. В консольном режиме интерфейсная часть FreeCAD отсутствует, но все геометрические инструменты доступны.
  • концепция верстаков. В интерфейсе FreeCAD инструменты сгруппированы по верстакам. Это позволяет отображать только инструменты, используемые для выполнения конкретной задачи, сохраняя рабочее пространство незагромождённым и отзывчивым, а также позволяет приложению быстро загружаться.
  • фреймворк плагинов/модулей для последующей загрузки типов данных/функциональностей. FreeCAD разделён на основное приложение с модулями, которые загружаются при необходимости. Почти все инструменты и типы геометрии хранятся в модулях. Модули ведут себя как плагины, кроме отложенной загрузки, отдельные модули могут быть добавлены или удалены из существующей установленной версии FreeCAD.
  • параметрически связанные объекты документа. Все объекты в документе FreeCAD могут быть заданы параметрами. Эти параметры могут быть изменены и пересчитаны в любое время. Поскольку связи между объектами сохраняются, изменение одного объекта автоматически распространяется на все зависимые объекты.
  • создание параметрических примитивов. Примитивы вроде куба, сферы, цилиндра и т.д. могут создаваться определением их геометрических ограничений.
  • операции по графическому изменению. FreeCAD может выполнять перемещение, вращение, масштабирование, отражение, смещение (простое или описанное в Jung/Shin/Choi) или изменение формы в любой плоскости трёхмерного пространства.
  • создание планарной геометрии. Отрезки, ломаные, прямоугольники, сплайны, дуги и окружности могут создаваться через графический интерфейс на любой плоскости трехмерного пространства.
  • моделирование с прямым или круговым выдавливанием, сечением и скруглением сопряжений.
  • топологические компоненты вроде вершин, ребер, ломаных и плоскостей.
  • тестирование и восстановление. В FreeCAD есть инструменты для тестирования сеток (тест на твёрдотельность, тест non-two-manifolds, тест на самопересечение) и для их починки (заполнение пустот и исправление ориентации сегментов).
  • аннотации. В FreeCAD можно вставлять аннотации (пояснения) к надписям или размерам.
  • инфраструктура отмены/возврата. В FreeCADе всё отменяемо/возвращаемо, с пользовательским доступом к стэку выполненных действий. Множество шагов может быть отменено единовременно.
  • ориентация на транзакции. Стек отмен/возвратов хранит транзакции документа, а не одиночные действия, что позволяет каждому инструменту точно определить, что должно быть отменено или переделано.
  • встроенная инфраструктура сценариев. FreeCAD обладает встроенными Python интерпретатором, с API, которые охватывают практически любую часть предложения, интерфейса, геометрии и представления этой геометрии в 3D просмотрщике. Интерпретатор может запускать как сложные сценарии, так и одиночные команды, целые модули могут быть полностью запрограммированы на Python.
  • встроенная консоль Python. Интерпретатор Python включает консоль с подсвечиванием синтаксиса, автодополнением и просмотром классов. Команды Python могут быть выполнены прямо в FreeCAD и напрямую возвращать результаты, позволяя программистам тестировать работу на ходу, раскрывая содержимое модулей FreeCAD'а и легко изучая его внутренности.
  • отражение действий пользователя в Python консоли. Всё, что пользователь делает в интерфейсе FreeCAD, выполняется в виде кода Python, который может быть выведен в консоль и записан в макрос.
  • полная запись и редактирование макросов. Команды Python, которые вызываются при манипулировании пользовательским интерфейсом, могут быть записаны, отредактированы и сохранены для дальнейшего использования.
  • составной (основанный на ZIP) формат хранения документов. Документы FreeCAD сохраняются с расширением .FCStd. Он может содержать множество различных типов информации, таких как геометрия, сценарии или иконки миниатюр. Файл .FCStd представляет собой архив zip, так что сохранённый файл FreeCAD уже сжат по умолчанию.
  • полностью настраиваемый/сценарируемый Графический Интерфейс Пользователя. Основанный на Qt интерфейс FreeCAD полностью доступен из интерпретатора Python. Помимо простых функций самого FreeCAD предоставляются инструментарии, а также полный доступ к структуре Qt. Пользователь может выполнять любые операции с ГИП, такие как создание, документирование, изменение и удаление виджетов и панелей инструментов.
  • миниатюры. (пока только в Linux системах) Значки документа FreeCAD, показывающие содержимое файла в большинстве файловых менеджеров таких как Nautilus в Gnome.
  • модульный установщик MSI. Установщик FreeCAD производит гибкую установку в системе Windows. Также поддерживаются пакеты системы Ubuntu.

Внешние верстаки

Опытные пользователи создали различные пользовательские внешние верстаки.


Установка

Установка Windows


Стандартная установка

Самый простой способ установить последнюю стабильную версию FreeCAD - использовать программу установки:

Если вы хотите загрузить версию для разработчиков (которая может быть нестабильной), смотрите страницу Еженедельных сборок.

После загрузки программы установки, дважды щёлкните по ней, чтобы запустить процесс установки.

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

Installation for all users of the Windows system

By default FreeCAD will be installed for the user that executes the installer. If this user only has user permissions, the default installation path is:

C:\Users\<username>\AppData\Local\Programs\FreeCAD X.YY

If the installer is executed by an admin user, or you execute it as admin, you can choose if FreeCAD should be installed for all users of the system or just for you. The default is for all users.

If installed for all users, the default installation path is:

C:\Program Files\FreeCAD X.YY

Тихая (автоматическая) установка

To install FreeCAD silently, you can execute the installer from the command line:

FreeCAD-~.exe /S

Default settings will be used for all options. A custom installation path can be specified in this manner:

FreeCAD-~.exe /S /D=A path to FreeCAD with spaces

By default, even with silent installations, there will be a short popup when the installer is checked for corruption. This so-called cyclic redundancy check only takes a few seconds at most. To disable this corruption check:

FreeCAD-~.exe /S /NCRC

Note that this /NCRC flag is not recommended since the corruption check assures that the installer was e.g. completely downloaded.

Chocolatey

Using the Chocolatey package manager is currently not recommended as that repository is no longer kept up-to-date.

Удаление

To uninstall FreeCAD it is preferable to use the Windows tools for uninstalling software. Alternatively you can execute the uninstaller directly. This is the file:

Uninstall-FreeCAD.exe

You can find it in the folder where FreeCAD is installed.

The uninstaller can also be executed silently using the command line:

Uninstall-FreeCAD.exe /S

Note that (silent) uninstallation will fail if there is a running instance of FreeCAD, even if that instance is not the version being uninstalled.


Установка на Unix/Linux


Обзор

Установка FreeCAD на наиболее известных системах Linux теперь поддерживается сообществом и FreeCAD должен быть доступен напрямую через диспетчер пакетов вашего дистрибутива. Команда FreeCAD также предоставляет:

Ubuntu и Ubuntu подобные системы

Многие дистрибутивы Linux базируются на Ubuntu и используют их репозитории. Кроме официальных вариантов (Kubuntu, Lubuntu и Xubuntu), существуют неофициальные дистрибутивы, такие как Mint, Voyager и другие. Приведенные ниже опции установки должны быть совместимыми с этими системами.

Официальная версия

FreeCAD доступен в репозиториях Ubuntu Universe и может быть установлен через Центр управления программным обеспечением или через терминал:

sudo apt install freecad

Примечание: пакет Ubuntu Universe может быть устаревшим, так как упаковка может отставать от последнего стабильного исходного кода. В этом случае рекомендуется установить пакет из PPA -stable ниже. Кроме того, для тестирования ветки разработки можно установить пакет -daily.

Стабильная PPA версия

Предупреждение: FreeCAD PPA в настоящее время не поддерживается и ищет добровольцев. Пожалуйста, используйте альтернативу (snap, appimage), пока проблема не будет устранена!

Персанальный Архив Пакетов (Personal Package Archive (PPA)) для стабильной версии FreeCAD поддерживается сообществом FreeCAD на Launchpad community. Launchpad репозиторий называется как FreeCAD Stable Releases .

С помощью графического интерфеса

Установка стабильного PPA с помощью графического интерфейса (GUI):

1. Перейдите на Ubuntu Software → Software & Updates → Software Sources → Other Software
2. Кликните на Add, затем скопируйте и вставьте следующую строку
ppa:freecad-maintainers/freecad-stable
3. Добавьте источник, закройте диалоговое окно, и перезагрузите свои источники софта, если нужно.

Теперь вы можете найти и установить последнюю стабильную версию FreeCAD из Ubuntu Software Center.

Через командную строку

Установите стабильный PPA через коммандную строку:

1. Добавьте PPA в свои источники программного обеспечения:
sudo add-apt-repository ppa:freecad-maintainers/freecad-stable
2. Извлеките обновленные списки пакетов:
sudo apt update
3. Затем установите FreeCAD вместе с комплектом оффлайн документации:
sudo apt install freecad freecad-doc

Note: из-за проблем с упаковкой в некоторых версиях Ubuntu у пакета freecad-doc возникают коллизии с пакетом самого FreeCAD или одной из его зависимостей; в этом случае удалите пакет freecad-doc и установите только пакет freecad. Если пакет freecad-doc не существует, проигнорируйте его установку.

Проверка Установки

4. Как только вы добавите стабильный PPA в свои исходные файлы одним из вышеперечисленных методов, пакет freecad установит эту версию PPA поверх версии, предоставленной репозиторием Ubuntu Universe. Вы можете просмотреть доступные версии с помощью следующей команды apt-cache :
apt-cache policy freecad
Результат должен выглядеть примерно так (конечно, информация о версии будет отличаться):
freecad:
  Installed: (none)
  Candidate: 2:0.18.4+dfsg1~201911060029~ubuntu18.04.1
  Version table:
     2:0.18.4+dfsg1~201911060029~ubuntu18.04.1 500
        500 http://ppa.launchpad.net/freecad-maintainers/freecad-stable/ubuntu bionic/main amd64 Packages
     0.16.6712+dfsg1-1ubuntu2 500
        500 http://archive.ubuntu.com/ubuntu bionic/universe amd64 Packages
ubuntu@ubuntu:~$ apt-cache policy freecad-doc
5. Вызовите стабильную (PPA) версию FreeCAD через графический интерфейс или через командную строку. Последний метод заключается в следующем:
./freecad

Development PPA (Daily)

Поскольку FreeCAD находится в постоянном развитии, вы можете установить пакет daily, чтобы быть в курсе последних улучшений и исправлений ошибок. Репозиторий также размещен на Launchpad и называется freecad-daily.

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

Добавьте PPA типа "daily" к вашим источникам программного обеспечения, обновите списки пакетов и установите ежедневный пакет:

sudo add-apt-repository ppa:freecad-maintainers/freecad-daily
sudo apt-get update
sudo apt-get install freecad-daily

Каждый день вы можете обновлять до последней ежедневной:

sudo apt-get update
sudo apt-get install freecad-daily

Примечание: в некоторых случаях новый код или зависимости, добавленные в FreeCAD, вызывают ошибки упаковки; в этом случае пакет "daily" может не создаваться до тех пор, пока майнтайнеры не исправят проблемы вручную.

Запустите ежедневную (PPA) версию FreeCAD:

freecad-daily

Примечание: в одной системе можно установить как пакеты -stable, так и -daily.Это полезно, если вы хотите работать со стабильной версией и при этом иметь возможность тестировать новейшие функции в разработке. Обратите внимание, что исполняемый файл для ежедневной версии - это freecad-daily, а для стабильной версии это просто freecad.

Debian и прочие базирующиеся на нём системы

Начиная с Debian Lenny, FreeCAD доступен прямо из программных репозиториев Debian и может быть установлен через synaptic или просто через:

sudo apt-get install freecad

OpenSUSE

FreeCAD обычно устанавливается через YAST (сокр. Yet another Setup Tool, Еще один инструмент установки), инструмент установки и настройки операционной системы Linux, или в терминале/консоли (нужны права root) с помощью:

zypper install FreeCAD

Примечание: Эта процедура распространяется только на установку официально выпущенных стабильных версий программы FreeCAD, в зависимости от установленных ссылок на репозитории программных пакетов вашей версии ОС. Пакет openSUSE «может быть устаревшим», так как упаковка может отставать от последнего стабильного исходного кода.В этом случае рекомендуется установить пакет вручную из отмеченных (Expand) репозиториев исходников.

Предлагается обширная программа выпуска для сборок пакетов FreeCAD. Посетите для обзора:

[1]

Обычно для выбора правильного дистрибутива openSUSE необходимо щелкнуть по особой кнопке View.

Стабильная версия

Стабильная версия пакета: Стабильные репозитории на openSUSE. Требуемая версия дистрибутива openSUSE должна быть выбрана в нижней части веб-страницы.

Примечание: openSUSE имеет несколько вариантов на выбор при загрузке FreeCAD. Чтобы просмотреть эти варианты, посетите Обзор стабильных репозиториев на openSUSE.

В разработке

Последние выпуски разработчика unstable: Списки нестабильных репозиториев в openSUSE

Рекомендуется загружать бинарные пакеты напрямую. Затем выберите правильный дистрибутив для установленной вами ОС openSUSE.

Gentoo

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

emerge freecad

Fedora

FreeCAD выл включён в официальные пакеты начиная с Fedora 20. Он может быть установлен из командной строки:

sudo dnf install freecad

Для предыдущих выпусков Fedora:

sudo yum install freecad

Также может быть использован менеджер пакетов с графическим интерфейсом. Задайте поиск "freecad". Версия пакета официального релиза как правило сильно отстает от релизов FreeCAD. Package: freecad показывает версии, включенные в репозитории Fedora с течением времени и версии.

Более свежие версии можно получить, загрузив один из .AppImageрелизов из репозитория github. Они отлично работают на Fedora.

Если вы хотите быть в курсе самых последних ежедневных сборок, FreeCAD также доступен на coprЧтобы установить сборку оттуда введите в терминале:

sudo dnf copr enable @freecad/nightly
sudo dnf install freecad

Это оставляет copr хранилище активным, так что

sudo dnf upgrade

или эквивалентной, обновится до последней сборки FreeCAD вместе с обновлениями из любых других активных репозиториев. Если вы хотите что-то более стабильное, вы можете отключить @freecad/nightly снова после первоначальной установки. Репозиторий copr сохраняет только сборки за последние 2 недели. Это не подходит, если вы хотите выбрать более старую конкретную версию.

Инструкции также доступны на компиляция FreeCAD самостоятельно, включая сценарий специально для Fedora. С небольшим изменением, чтобы проверить конкретную фиксацию из git, любая версия начиная примерно с FreeCAD 0.15 может быть построена на любом дистрибутиве начиная с Fedora 21.

Arch

Установка FreeCAD в Arch Linux и производных (например, Manjaro):

pacman -S freecad

Прочие

Если Вы обнаружите, что Ваша система использует FreeCAD, но не описана на этой странице, пожалуйста сообщите нам на форум!

В сети доступны многие альтернативные, неофициальные пакеты FreeCAD, например для систем вроде slackware или fedora. Поиск в сети быстро даст Вам какие-нибудь результаты.

Установка в других Linux/Unix системах

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

apt-get install freecad
dnf install freecad
emerge freecad
slackpkg install freecad
yum install freecad
zypper install freecad
pacman -Sy freecad

Имя пакета чувствительно к регистру, поэтому попробуйте `FreeCAD`, а также `freecad`. Если это не работает для вас, либо из-за того, что у вашего менеджера пакетов нет предварительно скомпилированной версии FreeCAD, либо из-за того, что доступная версия устарела для ваших нужд, вы можете попробовать загрузить один из .AppImage релизов из репозитория github. Они работают на большинстве 64-битных дистрибутивов Linux без какой-либо специальной установки. Просто убедитесь, что загруженный файл помечен как исполняемый, а затем запустите его.

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

Следующий Шаг

После того, как вы установили FreeCAD, пора приступить к работе!


Установка на Mac


FreeCAD можно установить на macOS из пакета .dmg, который вы можете просто перетащить в вашу папку приложений:

If you would like to download a development version, which may be unstable, see the Weekly builds download page.

Для обновления программного обеспечения, Вы также можете использовать менеджер пакетов, например такой как HomeBrew. Инструкции по установке HomeBrew можно посмотреть здесь. После установки HomeBrew вы можете просто установить FreeCAD 0.18.4 через свой bash терминал

brew install --cask freecad

и чтобы использовать последнюю доступную версию (0.19 pre) на HomeBrew, вы должны запустить

brew install freecad

Если у вас есть какие-либо проблемы с HomeBrew Cask или Formula, вы можете сообщить о них здесь.

На этой странице описано использование и функции установщика FreeCAD. Есть также инструкция по удалению. После установки вы можете начать работать!

Простая установка

Установщик FreeCAD предоставляется в виде пакета приложения (.app), помещенного в файл образа.

Установщик FreeCAD предоставляется в виде пакета приложений (.app), заключенного в файл образа диска.

Вы можете загрузить последнюю версию установщика со страницы Download. После загрузки файла просто смонтируйте образ диска, затем перетащите его в папку «Приложение» или в папку по вашему выбору.

Вот и все. Просто нажмите на приложение, чтобы запустить FreeCAD. Если у вас появляется сообщение «FreeCAD не может быть запущен, так как его разработчик неизвестен». Откройте папку (Приложение) и щелкните правой кнопкой мыши на приложении, затем нажмите «Открыть» и «Подтвердить», чтобы открыть приложение.

Удаление

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

  • В /Приложения:
    • FreeCAD

Если вы установили FreeCAD вместе с homebrew, просто используйте команду brew uninstall freecad. Это все, что требуется.


Обзор FreeCAD


Предисловие

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

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

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

Смотри так же:

Установка

Чтобы приступить к работе скачайте и установите FreeCAD. Информацию о текущей версии и последних обновлениях можно получить на странице загрузки. Инструкции по установке под определенные операционные системы изложены на следующих страницах: (Windows, Linux, Mac). Так же имеются готовые пакеты установки для Windows (.msi), Ubuntu и Debian (.deb), openSUSE (.rpm) и Mac OSX. FreeCAD доступен в менеджерах пакетов множества других дистрибутивов Linux. Существует исполняемый файл формата AppImage, который пригоден для запуска на большинстве современных 64-битных Linux систем. FreeCAD является программным обеспечением с открытым исходным кодом, что дает возможность, любому пользователю скачать исходный код и скомпилировать его самостоятельно.

Обзор интерфейса

Стандартный интерфейс FreeCAD

Более подробное описание находится на странице интерфейс.

1. Главный вид - может содержать различные окна с вкладками, в данном случае открыта вкладка трёхмерного вида.
2. Вкладки главного вида - список всех открытых объектов и документов в виде вкладок.
3. Древо проекта (часть комбинированной панели) - показывающее иерархию и историю проектирования объектов в документе, может так же отображать панель задач активных команд.
4. Редактор свойств (часть комбинированной панели) - позволяет просматривать и изменять свойства выделенных объектов.
5. Вид выделения - отображает объекты или под элементы выбранных объектов (вершины, ребра, грани).
6. Отчёт (или окно вывода Python) - в данной панели отображаются сообщения, предупреждения и ошибки в работе FreeCAD.
7. Консоль Python - консоль для ввода Python кода и просмотра результатов его исполнения.
8. Cтрока состояния - отображает некоторые сообщения и подсказки.
9. Раздел панелей инструментов - область в которой расположены панели инструментов.
10. Переключатель верстаков - позволяет переключить верстак.
11. Стандартное меню - содержит базовые операции программы.

Основная концепция интерфейса FreeCAD в разделении её на верстаки. Верстаки представляют собой набор инструментов, приспособленных для отдельной задачи, такой как работа с сетками, или черчение двумерных объектов, или эскизов с направляющими. Текущий верстак можно переключить с помощью селектора верстаков. Есть возможность настроить инструменты каждого верстака, добавить их из другого верстака или даже создать самим, которые мы называем макросы. Широко используются в качестве стартовых точек верстаки PartDesign и Part.

Когда вы впервые запускаете FreeCAD, открывается Стартовая страница. Вот как это выглядит для версии 0.19:

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

Навигация в трехмерном пространстве

В FreeCAD есть несколько режимов навигации, которые меняют способ использования мыши для взаимодействия с объектами в трёхмерном окне и сам вид. Один из них сделан под тачпады, где средняя кнопка не используется. Нижеследующая таблица показывает режим по умолчанию, называемый CAD' (Можно быстро сменить текущий режим навигации правым кликом на пустом месте трёхмерного вида):

Вы так же можете выбрать несколько стандартных видов(вид сверху, спереди и т.д.) из меню Вид, на панели инструментов Вид, а также с помощью горячих клавиш (1, 2, и т.д.), а правым кликом на пустом месте трёхмерного вида Вы получите доступ к некоторым частым операциям, таким как выбор отдельного вида или нахождение объекта в Дереве проекта.

Первые шаги в FreeCAD

FreeCAD ориентирован на создание высокоточных трёхмерных моделей, сохранение четкого контроля над этими моделями (сохранение возможности вернуться назад по истории модели и изменить параметры), и при необходимости изготовить эти модели (через трёхзмерную печать, станками с ЧПУ или на заводе). Поэтому он отличается от некоторых других трёхмерных приложений, сделанных для других целей, таких как создание анимации или игр. Его кривая обучения может быть сложной для освоения, особенно если это ваш первый контакт с 3D-моделированием. Если Вы застряли на каком-то месте, не забудьте, что дружественное сообщество пользователей на форуме FreeCAD способно быстро подсказать Вам решение.

Верстак, с которого Вы начнёте использование FreeCAD, зависит от типа работы, которую Вам надо выполнить: если Вам нужно работать над механической моделью, или вообще над любым небольшим объектом, Вам возможно подойдёт верстак PartDesign. Если Вы работаете на плоскости, то переключитесь на верстак Draft, или верстак Sketcher, который позволяет работу с ограничениями. Если Вам требуется разработка здания по BIM, переключитесь на Arch_Workbench. А если Вы привыкли к OpenSCAD, попробуйте верстак OpenSCAD. Также доступно множество внешних верстаков, разработанных сообществом.

Верстак можно переключить в любой момент, а так же настроить ваш верстак и добавить инструменты с других верстаков.

Работа с верстаками PartDesign и Sketcher

Верстак PartDesign спроектирован для создания сложных объектов, начиная с простых форм и добавляя и удаляя элементы (так называемые "features"), пока Вы не получите итоговый объект. Все элементы, которые Вы добавите во время моделирования, сохраняются в отдельном виде, называемом древом проекта, который так же содержит другие объекты вашего документа. Объект PartDesign можно понимать как последовательность операций, применяемых к результатам предыдущих, создавая одну большую цепочку. В древе проекта виден финальный объект, но Вы можете раскрыть его и восстановить все предшествующие стадии и изменить любые их параметры, которые автоматических обновят финальный объект.

Верстак PartDesign широко использует другой верстак, Sketcher. Он позволяет рисовать плоские эскизы, которые определяются установкой ограничений (Constraints) к двумерной форме. Например, Вы можете нарисовать прямоугольник и установить размер стороны применением ограничений к одной из сторон. Размеры этой стороны теперь могут быть изменены лишь при изменении ограничений.

Эти двумерные формы, созданные в верстаке эскизов, широко используются в верстаке PartDesign, например, для создания трёхмерных объёмов или черчения полей на гранях вашего объекта, которые затем будут выдолблены из вашего объёма. Вот типичный рабочий процесс PartDesign:

  1. Создать новый эскиз
  2. Нарисовать замкнутую фигуру (необходимо убедиться, что все точки соединены)
  3. Закрыть эскиз
  4. Растянуть эскиз в твердое тело с помощью pad tool
  5. Выбрать одну грань твердого тела
  6. Создать второй эскиз (на этот раз он будет нарисован на выбранной грани)
  7. Нарисовать замкнутую фигуру
  8. Закрыть эскиз
  9. Создать карман из второго эскиза на первом объекте

Что создаст объект вроде этого:

В любой момент Вы можете выделить оригинальный эскиз и изменить его или или изменить параметр выдавливания операции pad или pocket, что изменит итоговый проект.

Работа с верстаками Draft и Arch

Верстаки Draft и Arch действуют немного по-разному, хотя они следуют общим правилам для FreeCAD. Если коротко, Sketcher и PartDesign созданы в первую очередь для проектирования единых деталей, а Draft и Arch для работы с несколькими простыми объектами.

Верстак Draft предоставляет двумерные инструменты вроде тех, что можно найти в традиционных двумерных САПР вроде AutoCAD. Тем не менее двумерное черчение находится вне задач FreeCAD, и не ожидайте найти здесь полное множество инструментов, которые предлагают эти специализированные инструменты. Большинство инструментов верстака Draft работают не только на плоскости, но и в объёме, и получают пользу от специальных вспомогательных систем вроде выбора плоскости и привязки к объектам.

Верстак Arch добавляет FreeCAD инструмент BIM, позволяя создавать архитектурные модели через параметрические объекты. Верстак Arch зависит от других модулей, таких как Draft и Sketcher. Все инструменты Draft так же имеются в верстаке Arch, и большинство инструментов Arch используют вспомогательные системы Draft.

Типичный рабочий процесс с верстаками Arch и Draft может быть таким:

  1. Нарисовать набор лилий с помощью инструментаDraft Line
  2. Выбрать каждую линию и использовать инструмент Wall, чтобы создать стену на каждом из них
  3. Соединить стены, выбрав их и нажав на инструмент Arch Add
  4. Создать объект floor (пол), и поместить Ваши стены на него из древа проекта
  5. Создать объект building, и переместить ваш пол и в него из древа проекта
  6. Создать окно, нажав на инструмент Window, выбрать предустановки в его панели, затем нажать на поверхность стены
  7. Добавить размеры, сначала установив рабочую плоскость если необходимо, затем испольжуя инструмент Draft Dimension

В результате получится следующее:

Дальнейшее на странице Учебники (то же на английском).

Дополнения, макросы и сторонние верстаки

Принцип дополнений основан на разработке дополнений верстаков. Любой пользователь может разработать функцию, которая, по его или её мнению, отсутствует для нужд его/её, или даже сообщества. На форуме пользователь может запросить оценку, помощь форума. Он может поделиться, или нет, объектом его разработки, в соответствии с установленным им копирайтом. Это его выбор. Для разработки пользователю доступны функции для скриптов.

Есть два типа расширений:

  1. Макросы: небольшие отрезки кода Python, дающие дополнительные инструменты или функциональность. макросы обычно начинаются как способ упростить или автоматизировать задачи рисования или редактирования отдельных объектов. Если многие из этих макросов собраны в каталоге, весь каталог может распространяться как новый верстак.
  2. Сторонние верстаки: собрание инструментов, запрограммированных на Python или C++, которые существенно расширяют FreeCAD. Если верстак успешно разработан и хорошо документирован, он может быть включён одним из верстаков FreeCAD. На странице External workbenches можно найти принципы и список существующих библиотек.

Программирование

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

Что нового?


Работа в FreeCAD

Навигация в трехмерном пространстве


Обзор

Каждый стиль навигации определяет собой методы для навигации в трёхмерном пространстве, а так же методы взаимодействия с трехмерными объектами (перемещение, вращение и т.п.). FreeCAD поддерживает несколько стилей навигации и управления. По умолчанию установлен CAD стиль навигации, он очень простой и практичный, но FreeCAD так же предлагает альтернативные стили навигации, которые вы можете выбрать по своим предпочтениям. Назначенный пользователем стиль навигации будет использоваться для всех верстаков.

Дополнительные сведения о способах выбора объектов см. в разделе Методы выбора объектов.

Дополнительные сведения о способах преобразования объектов см. на странице описания команды Преобразование.

Выбор стиля навигации

  1. Выполните одно из следующих действий:
    • Нажмите на кнопку в Строке состояния.
    • Щелкните правой кнопкой мыши в пустую область в 3D Виде, и выберите Стили навигации в контекстном меню.
    • Откройте Редактор настроек через пункт главного меню Редактировать → Настройки... В нем выберите раздел Отображение → вкладку Навигация → пункт Трехмерная навигация.
  2. Выберите стиль из списка.
  3. При необходимости укажите стиль Ващения: нажмите на кнопку в Строке состояния и выберите в контекстом меню пункт Настройки → Вращение. Подробности см. в описании Редактора настроек.
  4. При необходимости укажите Режим вращения. Подробности см. в описании Редактора настроек.
  5. Если выбран стиль навигации CAD: при необходимости укажите параметр настроек Включить анимацию. Подробности см. в описании Редактора настроек.

Доступные стили навигации

With all navigation styles, unless selecting objects from a sketch in edit mode, you must hold Ctrl to select multiple objects.

Навигация Blender

Стиль навигации Blender основан на модели управления используемой в редакторе Blender.

Выбор Перемещение Масштабирование Вращение
Shift+
Нажмите левую кнопку мыши над объектом, который хотите выбрать. Удерживайте Shift и среднюю кнопку мыши для перемещения объекта.

Либо, удерживайте левую и правую кнопки мыши, а затем переместите указатель.

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

Навигация CAD

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

Выбор Перемещение Масштабирование Вращение
обычное
Вращение
альтернативным методом
Нажмите левую кнопку мыши над объектом, который вы хотите выбрать.

При нажатии средней кнопки мыши вид центрируется по положению указателя.

{{{Pan_text}}} {{{Zoom_text}}} Удерживая среднюю кнопку мыши, нажмите и удерживайте левую кнопку мыши, затем перемещайте указатель.

Если кнопки будут отпущены до того, как вы остановите движение мыши, Вид продолжит вращение, в случае если включен поворотный просмотр объекта.

Двойное нажатие средней кнопкой мыши устанавливает новый центр вращения.

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

При этом методе средняя кнопка мыши может быть отпущена после того как правая кнопка осталась нажатой.

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

Ctrl+ Ctrl+Shift+ Shift+
{{{Pan_mode_text}}} Режим приближения: удерживая клавиши Ctrl и Shift, нажмите правую кнопку, и перемещайте указатель. Режим вращения: удерживая клавишу Shift, нажмите правую кнопку мыши, затем перемещайте указатель.

Навигация Gesture (Жестами)

Этот стиль был разработан специально для работы с сенсорным экраном с помощью стилуса или жестами. Тем не менее он также может применяться при управлении мышью, кроме того данный стиль управления рекомендуется использовать при управлении трекпадом в Mac.

Выбор Перемещение Масштабирование Вращение Наклонить вид
Нажмите левую кнопку мыши над объектом, который хотите выбрать. Удерживайте правую кнопку мыши и перемещайте указатель. Используйте колёсико мыши для масштабирования. Удерживайте левую кнопку мыши и тяните указатель.

В режиме Sketcher и некоторых других это действие заблокировано. Удерживайте Alt при нажатии кнопки мыши для перехода в режим вращения.

Чтобы установить точку фокуса камеры для вращения, кликните новую точку средней кнопкой мыши. Взамен, нацельте указатель в новую точку и нажмите кнопку H на клавиатуре.

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

Или, коснитесь экрана одним пальцем, удерживайте его некоторое время, а потом перемещайте в нужном направлении. Это равносильно перемещению с помощью правой кнопки мыши.

Сдвиньте пальцы для масштабирования (т.е. потяните два пальца к/от друг друга). Потяните одним пальцем для вращения.

Удерживайте вдобавок Alt в режиме Sketcher.

Вращайте воображаемую линию между двумя точками касания.

Начиная с версии v0.18 этот метод по умолчанию отключён. Для разрешения Правка → Настройки → Отображение, и снимите метку "Отключить жест наклона для сенсорного экрана".

Навигация Maya-Gesture (Жестами в стиле Maya)

В стиле навигации MayaGesture, перемещение, масштабирование и вращение Вида выполняется при зажатой клавише ALT и нажатии одной из трех кнопок мыши, поэтому этот стиль навигации полноценно можно использовать только с трехкнопочной мышью. В данном стиле также можно использовать жесты из обычного стиля навигации жестами, так как этот стиль был разработан на его основе.

Выбор Перемещение Масштабирование Вращение
Alt+ Alt+ Alt+
Нажмите левую кнопку мыши над объектом который вы хотите выбрать. Удерживая клавишу Alt и среднюю кнопку мыши, перемещайте указатель. Удерживая клавишу Alt и правую кнопку мыши, перемещайте указатель.

Или, используйте для приближения и отдаления колёсико мыши.

Удерживая Alt и левую кнопку мыши, перемещайте указатель.

Навигация OpenCascade

Стиль навигации OpenCascade основан на модели управления используемой в OpenCascade.

Выбор Перемещение Масштабирование Вращение
Ctrl+ Ctrl+ Ctrl+


Нажмите левую кнопку мыши над объектом, который хотите выбрать. Удерживая среднюю кнопку мыши, перемещайте указатель. Используйте колёсико мыши для приближения и отдаления.

Или, удерживая Ctrl и левую кнопку мыши, перемещайте указатель.

Удерживая Ctrl и правую кнопку мыши, перемещайте указатель.

Навигация OpenInventor

Стиль навигации OpenInventor основан на модели управления используемой в редакторе Open Inventor. Для выбора объектов, необходимо удерживать нажатой клавишу Shift или Ctrl.

Данный стиль управления отличен от того, что применен в Autodesk Inventor.

Выбор Перемещение Масштабирование Вращение
Shift+
Удерживая Shift, нажмите левую кнопку мыши над объектом, который хотите выбрать.

Вместо этого удерживайте нажатой клавишу Ctrl, чтобы выбрать несколько объектов.

Удерживая среднюю кнопку мыши, перемещайте указатель. Используем колёсико мыши для приближения и отдаления.

Или, зажмите и удерживайте среднюю и левую кнопку мыши, затем перемещайте указатель.

Удерживая левую кнопку мыши, перемещайте указатель.

Навигация OpenSCAD

Стиль навигации OpenSCAD основан на модели управления используемой в редакторе OpenSCAD.

представлено в версии 0.20

Выбор Перемещение Масштабирование Вращение
Shift+
Нажмите левую кнопку мыши над объектом, который хотите выбрать. Удерживайте правую кнопку мыши и перемещайте указатель. Удерживая среднюю кнопку мыши, перемещайте указатель.

Или, удерживая Shift и правую кнопку мыши, перемещайте указатель.

Удерживайте левую кнопку мыши и перемещайте указатель.

version 0.21 and below Hold Ctrl and Shift when pressing the mouse button to drag an object in a sketch in edit mode. |Pan_text=Hold the right mouse button, then move the pointer. |Zoom_text=Hold the middle mouse button, then move the pointer. Alternatively, hold Shift and the right mouse button, then move the pointer. |Rotate_view_text=Hold the left mouse button, then move the pointer.

Alternatively, and when a sketch is in edit mode, hold the middle mouse button, then press and hold the right mouse button, then move the pointer. }}

Навигация Revit

Стиль навигации Revit основан на модели управления используемой в редакторе Revit.

Выбор Перемещение Масштабирование Вращение
Shift+


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

Или, удерживая левую и правую кнопку мыши, перемещайте указатель.

Используйте для приближения и отдаления колёсико мыши. Удерживая Shift и среднюю кнопку мыши, перемещайте указатель.

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

Навигация TinkerCAD

Стиль навигации TinkerCAD основан на модели управления используемой в редакторе TinkerCAD.

представлено в версии 0.20

Выбор Перемещение Масштабирование Вращение
Нажмите левую кнопку мыши над объектом, который хотите выбрать. Удерживая среднюю кнопку мыши, перемещайте указатель. Используйте колёсико мыши для приближения и отдаления. Удерживая правую кнопку мыши, перемещайте указатель.

Навигация Touchpad

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

Выбор Перемещение Масштабирование Вращение
Shift+ PageUp, PageDown Alt+
Нажмите левую кнопку над объектом, который хотите выбрать. Удерживайте Shift и двигайте объект. Используйте PageUp и PageDown для приближения или отдаления. Удерживайте клавишу Alt и перемещайте указатель.
Ctrl+Shift+ Shift+
Или, зажмите Ctrl + Shift и нажмите левую кнопку мыши, после чего перемещайте указатель. Или, удерживайте клавиши Shift стрелку влево, после чего перемещайте указатель.

Поддержка оборудования

В FreeCAD так же поддерживает некоторые устройства 3D ввода.

Рекомендуемый стиль управления для MacOS

На MacBook с трекпадом навигация жестами работает хорошо, но жесты имеют особое значение:

  • Масштабирование: касание и перемещение двумя пальцами.
  • Вращение: касание и перемещение тремя пальцами.
  • Перемещение: Ctrl + касание и перемещение тремя пальцами.

Разработка собственного стиля навигации

Руководство по добавлению нового стиля навигации с помощью мыши в FreeCAD ориентирует разработчиков, которые хотят разработать собственный стиль навигации с помощью мыши. Требуется знание синтаксиса C++.


Документ FreeCAD


Документ FreeCAD содержит все объекты проекта. Он может содержать группы, и предметы, сделанные с любого инструментария(workbench). Поэтому вы можете переключаться между инструментариями, и до сих пор работать на том же документе. Получившийся документ будет сохранён на диске при сохранении работы. В FreeCAD, вы также можете открывать несколько документов одновременно и открыть несколько видов одного и того же документа.

В документе объекты могут быть помещены в группы и им можно присвоить уникальные имена. Управлять группами, объектами и именами объектов осуществляется главным образом с помощью древовидного списка. примечание: Также это можно сделать, как и всё в FreeCAD, с помощью интерпретатора Python. В древовидном списке вы можете создавать группы, перемещать объекты в группы, удалять объекты или группы, кликнув правой клавишей на объект в древовидном списке, переименуйте объекты. Также можно переименовать объект выделив его в древовидном списке и нажав F2, также возможны другие комбинации в зависимости от текущего инструментария.

Объекты входящие в FreeCAD документ могут быть различных типов. Каждый инструментарий может создать свои собственные типы объектов, для примера Верстак полигонального моделирования создаёт объекты состоящие из полигонов, Верстак Деталей создает детали, Чертежный Верстак также создаёт детали, и т.д.

Если есть по крайней мере один документ открытый в FreeCAD, всегда есть один и только один активный документ. Этот документ отображается в текущем окне 3D просмотра, это документ над которым вы сейчас работаете.

Приложения и интерфейс пользователя

Как почти все в FreeCAD, графический пользовательский интерфейс(GUI) отделен от основной части приложения(App). Также и с документами. Документы также состоят из двух частей: документ Приложение, содержащий ваши объекты, и документ как Вид, который содержит представление на экране наших объектов.

Думайте об этом как о двух местах, где определены ваши объекты. Их конструктивные параметры (это куб? конус? его размер?) хранятся в документе Приложении, а их графическое представление (отображать его в черных линиях? с синими гранями?) хранятся в части документ Вид. Зачем это сделано? Потому что FreeCAD может быть использован без графического интерфейса, например в других программах, и мы должны быть в состоянии управлять нашими объектами, даже если ничего не будет отображаться на экране.

Еще в части документа Вид содержатся объёмные виды. Один документ может иметь несколько открытых видов, так что вы можете просматривать ваш документ одновременно с нескольких точек зрения. Может быть вы хотели бы одновременно смотреть на ваш объект спереди и сверху? Тогда в вашем документе будет две части Вид документа. Создать новые виды или закрыть старые виды можно с помощью меню Вид или кликнув правой кнопкой мыши по закладке вида.

Программирование

Документы легко могут быть созданы и изменены с помощью интерпретатора Python. Например:

FreeCAD.ActiveDocument

Вернет текущий (активный) документ

FreeCAD.ActiveDocument.Blob

Даст доступ к объекту с именем "Blob" внутри вашего документа

FreeCADGui.ActiveDocument

Вернет вид-документ связаный с текущим документом

FreeCADGui.ActiveDocument.Blob

Получить доступ к графическому представлению (виду) объекта с именем Blob

FreeCADGui.ActiveDocument.ActiveView

Вернет текущий активный вид.


Настройка пользовательских предпочтений


Введение

Чтобы запустить Редактор настроек выберите пункт меню Правка → Настройки.... В Mac OS пункт Настройки... может находиться в меню FreeCAD (это типичное расположение для большинства приложений Mac).

FreeCAD использует концепцию верстаков, в которой каждый верстак отвечает за свои конкретные задачи и функции. Верстак может иметь свой собственный раздел с настройками. Раздел этот появляется в редакторе настроек только после того, как верстак был открыт (загружен) хотя-бы один раз после запуска FreeCAD. Подробнее об этом можно узнать в разделе Рабочее окружение.

To preserve resources, FreeCAD does not automatically load all available workbenches. See Workbenches for more information. For a list of workbench related preferences see Workbench related preferences.

Изначально в Редакторе настроек доступны четыре секции (даже если ни один верстак не был загружен). Это секции: Основные, Отображение, Рабочее окружение и Импорт/Экспорт. Верстаки которые могут быть загружены в процессе работы, имеют свою вкладку настроек и будут рассмотрены далее.

Обратите внимание, что нажатие кнопки Reset в левом нижнем углу диалога Настроек сбросит все настройки FreeCAD к значениям по умолчанию.

Некоторые дополнительные настройки можно изменить только в Редакторе параметров. На странице Точных настроек перечислены некоторые из них.

Основные

Этот раздел настроек имеет 9 вкладок: Основные, Документ, Выделение, Кэш, Редактор кода, Консоль Python, Просмотр отчёта, Макрос, Единицы измерения. И 10 вкладка "Помощь", будет добавлена если дополнение Помощь включено. Это дополнение может быть установлено через Менеджер дополнений.

In version 0.21 and below the seventh tab, Help, is only available if the Help Addon has been installed.

Основные

Вкладка Основные позволяет настроить следующие параметры:

Название Описание
Изменить язык Выберите язык пользовательского интерфейса FreeCAD
Размер списка последних файлов Укажите, сколько файлов должно быть указано в списке последних файлов.
Включить фон из повторяющегося узора Если этот флажок установлен, фон главного окна FreeCAD по умолчанию будет состоять из плиток этого изображения:

Optionally, imported files can be excluded from this list, and exported files can be included. See Fine-tuning.

Enable tiled background If checked, the background of FreeCAD's main window will by default consist of tiles of this image:

Этот параметр действует только в том случае, если Таблица стилей не выделенна.

Изображение можно изменить, добавив папки Gui/Images в папку:

%APPDATA%/FreeCAD (в Windows),

$HOME/.FreeCAD (в Linux) или

$HOME/Library/Preferences/FreeCAD (в MacOS).

Поместите туда файл с именем background.png и включите/отключите этот параметр, чтобы увидеть измененный файл.

Enable cursor blinking If checked the text cursor in the Python console and the Macro editor will blink.
Стиль интерфейса Выбор стиля оформления. Стиль оформления определяют внешний вид пользовательского интерфейса FreeCAD.
Размер значков на панелях инструментов Выбор размера значков панели инструментов:
  • Small (16px)
  • Medium (24px)
  • Large (32px)
  • Extra large (48px)
Режим отображения древовидного представления документа Настройка отображения панели древовидного представления документа. Для того, чтобы настройки вступили в силу, требуется перезапуск FreeCAD. Возможны следующие варианты представления:
  • Одна комбопанель: древовидное представление и раздел свойств скомбинированы в одну панель.
  • TreeView и PropertyView: древовидное представление и раздел свойств разделены на две панели.
  • Оба: древовидное представление и раздел свойств скомбинированы в одну панель и дополнительно еще есть одна панель свойств.
При запуске автоматически загружать верстак Выбор того, какой верстак будет использоваться сразу после запуска FeeCAD
Включение экрана-заставки при запуске Если пункт выбран, при запуске отображается заставка FreeCAD.

Изображение экрана-заставки можно изменить, поместив файл с именем splash_image.png в папку Images, уже упомянутую в разделе Включить фон из повторяющегося узора.

Включить перенос слов Слова будут перенесены, когда они превысят доступное горизонтальное пространство в консоли Python. Эта консоль отображается с помощью меню Вид → Панели → Консоль Python.

Документ

Вкладка Документ позволяет настроить следующие параметры:

Название Описание
Создавать новый документ при запуске Если отмечено, FreeCAD создаст новый документ при запуске
Уровень сжатия сохраняемого документа Спецификация уровня сжатия для файлов FCStd. Файлы FCStd являются сжатыми файлами ZIP. Поэтому вы можете переименовать их суффикс .FCStd в .zip и открыть их с помощью программы ZIP-архива.
Отмены/Повторы Если пункт выбран, все изменения в документах сохраняются, чтобы их можно было отменить/повторить.
Максимум шагов отмен/повторов Укажите, сколько шагов Отмена/Повтор нужно записать
Разрешить отмену перерасчета Allow to aborting the document recomputation by pressing Esc. This may slightly increase the recomputation time.
Запуск автоматического восстановления при запуске Если файл восстановления доступен, FreeCAD автоматически запустит восстановление файла при запуске. Таким образом, файлы могут быть восстановлены в случае сбоя.
Автосохранение каждые Определяет, как часто будет записывается файл автосохранния.
Сохранить миниатюру в файл проекта при сохранении документа Если пункт выбран, то при сохранении документа также будет сохранена его миниатюра. Например, миниатюра будет отображаться в списке последних файлов в Верстаке Start. It is possible to select a Size between 128×128 and 512×512 pixels for the thumbnail. Common sizes are the powers of two: 128, 256, 512.
Добавить логотип программы в генерируемую миниатюру Если пункт выбран, логотип программы FreeCAD будет добавлен к миниатюре. Этот параметр действует только в том случае, если используется Сохранить миниатюру в файл проекта при сохранении документа.
Максимальное количество файлов резервных копий, при пересохранении документа Если пункт выбран, файлы резервных копий будут сохраняться при сохранении документа. Вы можете указать количество сохраняемых файлов резервных копий. Они содержат ранее сохраненную версию документа. Первый файл резервной копии будет иметь суффикс файла .FCStd1, второй .FCStd2 и т.д.
Use date and FCBak extension If checked, backup files will get the extension .FCbak and their file names get a date suffix according to the specified date format. For a description of the date format see this site.

With the default settings the backup file will get for example this name TD-Cube.20200315-215654.FCBak (original filename is TD-Cube.FCStd).

Разрешить идентичные метки объектов в одном документе Если пункт выбран, объекты могут иметь одинаковую метку/имя. Например, разные части или элементы могут иметь одинаковое имя в одном и том же документе.
Disable partial loading of external linked objects Enable partial loading of external linked document. When enabled, only the referenced objects and their dependencies will be loaded when a linked document is auto opened together with the main document. A partially loaded document cannot be edited. Double click the document icon in the tree view to reload it in full. A more detailed explanation of the feature can be found on the Assembly3 documentation page
Имя автора Все документы, которые будут созданы, получат указанное имя автора. Оставьте поле автора пустым для анонимного автора. Если опция Устанавливать при сохранении отмечена, поле Last updated by будет установлено для указанного автора при сохранении файла. Это поле можно просмотреть с помощью меню Файл → Информация о проекте.
Компания Все документы, которые будут созданы, получат указанное название компании
Лицензия по умолчанию Выбор лицензии по умолчанию для новых документов. Для предопределенной лицензии URL-адрес лицензии будет автоматически установлен соответствующим образом. Выберите «Другое» для собственной или специальной лицензии.
URL адрес лицензии Указание URL-адреса, описывающего лицензию, выбранного в Лицензия по умолчанию

Выделение

Вкладка Выделение (представлено в версии 0.19) позволяет настроить следующие параметры:

Название Описание
Автопереключение в 3D вид, содержащий выбранный элемент Включает/выключает опцию Синхронизировать вид
Автоматический разворачивать элемент дерева при выделении соответствующего объекта в 3D виде Включает/выключает опцию Синхронизировать выделение
Выделить объект в режиме 3D при наведении курсора на элемент дерева Включает/выключает опцию Предвыборка
Записывать выделение в древе для перехода назад/вперед с помощью кнопки навигации Включает/выключает опцию Записать выделение
Добавить флажки для выделения в древе документов Если пункт выбран, то каждый элемент древа документа получает флажок. Это к примеру может быть удобно для выбора нескольких элементов при работе на сенсорном экране.

Кэш

These preferences are related to the cache directory where FreeCAD stores temporary files.

On the Cache tab (introduced in version 0.20) you can specify the following:

Name Description
Location Specifies the path of the cache directory.
Check periodically at program start Controls the frequency with which the directory size is checked. The options are:
  • Always
  • Daily
  • Weekly
  • Monthly
  • Yearly
  • Never
Cache size limit Specifies the maximum size of the directory. You will be notified if a check is performed and the size exceeds this value. The options are:
  • 100 MB
  • 300 MB
  • 500 MB
  • 1 GB
  • 2 GB
  • 3 GB
Current cache size Shows the current size of the directory, if available. Press the Check now... button to update the value.

Notification Area

These preferences control the Notification Area and its notifications.

On the Notification Area tab (introduced in version 0.21) you can specify the following:

Name Description
Enable Notification Area If checked, the Notification Area will appear in the status bar.
Enable non-intrusive notifications If checked, non-intrusive notifications will appear next to the Notification Area in the status bar.
Errors If checked, errors will appear in the Notification Area.
Warnings If checked, warnings will appear in the Notification Area.
Maximum Duration Maximum duration during which notifications are shown (unless mouse buttons are clicked).
Minimum Duration Minimum duration (idem).
Maximum Number of Notifications Maximum number of notifications shown simultaneously.
Notification width Width of the Notification Area in pixels.
Hide when other window is activated If checked, open notifications will disappear when another window is activated.
Do not show when inactive If checked, notifications will not appear if the FreeCAD window is not the active window.
Maximum Messages (0 = no limit) The maximum number of messages kept in the list. Set to 0 for no limit.
Auto-remove User Notifications If checked, notifications will be removed from the message list when the Maximum Duration has elapsed.

Report view

Параметры вывода влияют на поведение Представление отчета. Эта панель отображается с помощью меню Вид → Панели → Отчет.

Вкладка Просмотр отчёта позволяет настроить следующие параметры:

Название Описание
Выводить обычные сообщения (normal) Если пункт выбран, обычные сообщения будут записываться в отчёт. Они будут выделены в отчёте цветом указанным в пункте Выделение сообщений → Обычные сообщения.
Выводить информационные сообщения (log) Если пункт выбран, то также будут отображаться информационные сообщения. Они будут выведены на панель Отчет цветом, установленным в Журнал (logs). Эта панель активируется с помощью меню Вид → Панели → Отчет.
Выводить предупреждения (warnings) Если пункт выбран, то предупреждения будут отображаться. Они будут выведены на панель Отчет цветом, установленным в Предупреждения (warnings).
Выводить сообщения об ошибках (errors) Если пункт выбран, то будут отображаться сообщения об ошибках. Они будут выведены на панель Отчет цветом, установленным в Ошибки (errors)
Показать отчёт в случае ошибки Если пункт выбран, то the Report view will be shown automatically when an error is recorded
Показать отчёт в случае предупреждения Если пункт выбран, то the Report view will be shown automatically when a warning is recorded
Показать отчет при выводе обычного сообщения Если пункт выбран, то the Report view will be shown automatically when a normal message is recorded
Показать отчёт в журнале Если пункт выбран, то the Report view will be shown automatically when a log message is recorded
Включить код времени для каждой записи Если пункт выбран, то each message and warning will receive a timecode
Обычные сообщения (normal) Задание цвета шрифта для обычных сообщений на панели Отчет.
Информационные сообщения (log) Задание цвета шрифта для сообщений журнала на панели Отчет.
Предупреждения (warnings) Задание цвета шрифта для предупреждающих сообщений на панели Отчет.
Сообщения об Ошибках (errors) Задание цвета шрифта для сообщений об ошибках на панели Отчет.
Перенаправлять внутренний вывод Python в отчёт Если пункт выбран, то внутренний вывод Python будет перенаправляться из консоли Python в отчёт
Перенаправлять внутренние сообщения об ошибках Python в отчёт Если пункт выбран, то внутренние сообщения об ошибках Python будут перенаправляться из консоли Python в отчёт

Справка

On the Help tab you can specify the following:

Name Description
Help location Specifies the location of the Help files. The options are:
  • Online: Enter the URL or leave blank to use the automatic GitHub URL.
Translation suffix: If https://wiki.freecad.org/ is used, a language suffix can be specified. Use for example fr for the French translation. Must be blank for the GitHub URL.
  • From disk location: Enter the path where the downloaded FreeCAD documentation can be found. To download the documentation select the offline-documentation addon from the Workbenches list in the Addon Manager.
Display Specifies where the documentation should be displayed. The options are:
  • In a new FreeCAD tab: The documentation is displayed on a new tab in the Main view area.
  • In your default web browser: The documentation is displayed in the default web browser.
  • In a separate, embeddable, dialog: The documentation is displayed in a separate dialog. This dialog can be docked on top of the Combo view for example.
Custom stylesheet Specifies an optional custom stylesheet. Not used for the Wiki URL.

Отображение

Этот раздел настроек имеет три стандартные вкладки: 3D Вид, Навигация и Цвета. Четвертая вкладка, Отображение Mesh, добавляется, если верстак Mesh был загружен.

3D Вид

Вкладка 3D Вид позволяет настроить следующие параметры:

Название Описание
Показывать систему координат в углу Если пункт выбран, то основная система координат всегда будет отображаться в правом нижнем углу в открытых файлах
Показывать перекрестие осей по умолчанию представлено в версии 0.19 Если пункт выбран, то пересечение осей будет показано по умолчанию при создании или открытии файла
Показывать счетчик кадров в секунду Если пункт выбран, то время, необходимое для последней операции, и полученная частота кадров [2] всегда будут отображаться в нижнем левом углу в открытых файлах.
Запомнить активный верстак вкладкой представлено в версии 0.19 Если пункт выбран, то приложение запомнит текущий активный верстак для независимо каждой вкладки в Main view area. При переключении на вкладку этот верстак будет автоматически восстановлен.
Использовать програмное обеспечение OpenGL представлено в версии 0.19 Если пункт выбран, то OpenGL will use the CPU instead of the GPU. This option is useful for troubleshooting graphics card and driver problems. Changing this option requires a restart of the application.
Использовать OpenGL VBO (объекты буфера вершин) Если пункт выбран, то будут использоваться объекты буфера вершин (VBO). VBO - это функция OpenGL, которая предоставляет методы для загрузки данных вершин (положение, вектор нормали, цвет и т.д.) на видеокарту. VBO обеспечивает существенный выигрыш в производительности, потому что данные находятся в графической памяти, а не в системной памяти, и поэтому они могут отображаться непосредственно графическим процессором. Для получения дополнительной информации см. эту веб-страницу.
Кэш рендера представлено в версии 0.19 "Кэш рендера" или "Render Acceleration" is explained in more detail in Link#render-caching. There are 3 options:
  • Авто (default), let Coin3D decide where to cache.
  • Распределенный, manually turn on cache for all view provider root nodes.
  • Централизованный, manually turn off cache in all nodes of all view providers, and only cache at the scene graph root node. This offers the fastest rendering speed, but slower response to any scene changes.
Сглаживание Выбор используемого типа Multisample сглаживания
Прозрачные объекты представлено в версии 0.19 Render type of transparent objects. The types are:
  • Один проход (default), rendering is done in one pass. For non-solid objects like faces or meshes this can lead to artifacts. This image shows such an artifact (black triangle) and that the type Проход фона avoids this.
  • Проход фона, has only an effect for non-solid objects. They are then rendered in two passes: Back-facing polygons are rendered in the first pass and the front-facing in the second pass.
Размер метки Выбор размера вершины (точки) в верстаке Sketcher. The clickable area of points can be additionally enlarged by increasing Pick radius (on Colors tab).
Расстояние между глаз для стерео режима Спецификация расстояния между глазами, используемого для стереопроекции. Указанное значение является коэффициентом, который будет умножен на размер ограничивающего прямоугольника трехмерного объекта, который отображается в данный момент.
Цвет подсветки Если пункт выбран, то подсветка включена с заданным цветом. Backlight is used for rendering back sides of faces (usually, you don't see them in solids, unless you slice one with a clipping plane, or if the faces aren't oriented correctly). It is only active for objects whose Lighting property (on View tab) is set to "One side". If disabled, back sides of faces of objects in "One side" lighting mode will be black.

The related Intensity setting specifies the intensity of the backlight.

Тип камеры Выбор типа проекции камеры.

Навигация

Вкладка Навигация позволяет настроить следующие параметры:

Название Описание
Куб навигации Если значение установлено, то Навигационный куб будет отображаться.

Шаги вращения Определяет количество шагов требуемых для полного оборота навигационного куба при использовании стрелок поворота.

Если Поворачивать к ближайшему включенно, the 3D view is rotated to the nearest most logical state when a cube face is clicked. When it is off, clicking to a cube face will and up always to the same position, no matter in what cube state you were when you clicked the face. представлено в версии 0.20

Размер куба Определяет размер навигационного куба. представлено в версии 0.20

Трехмерная навигация Selection of a navigation settings set. To see what each set defines, select it and then press the Mouse... button.
Стиль вращения Selection of the rotation orbit style. When viewing a part in the x-y plane and being in the rotation mode of the 3D navigation, the difference is: If Trackball is selected, moving the mouse horizontally will rotate the part around the y-axis, if Turntable is selected the part will be rotated around the z-axis.
Режим вращения Определяет центр вращения. Можно выбрать Центр окна, Перенести к курсору или Центр объекта.
Ориентация камеры по умолчанию Selection of the camera orientation for new documents. This setting is also used by the Std ViewHome command.
Масштаб нового документа Affects the initial camera zoom level for new documents. The value you set is the diameter of a sphere that fits in 3D view. Default is 100 mm. It also sets the initial size of origin features (base planes in new PartDesign Bodies).
Включить анимацию If checked, rotations can be animated. If for example the 3D Navigation set CAD is used and the mouse is moved while the scroll wheel and the right mouse button are pressed, parts are rotated. If one keeps the mouse moving while releasing e.g. the right mouse button, the rotation will continue as animation. To end the animation left-click with the mouse.
Зум туда, где мышь If checked, zoom operations will be performed at the position of the mouse pointer. Otherwise zoom operations will be performed at the center of the current view. The Zoom step defines how much will be zoomed. A zoom step of 1 means a factor of 7.5 for every zoom step.
Инвертировать зум If checked, the direction of zoom operations will be inverted
Отключить жест наклона для сенсорного экрана If checked, the tilting gesture will be disabled for pinch-zooming (two-finger zooming). This only affects the 3D Navigation set Gesture.

Color sets the base color for all elements. introduced in version 0.21

Угол Определяет место положение Навигационного куба на экране.

Font name specifies the font used for the cube's texts. introduced in version 0.21

Font size sets the size of the font used for the cube's texts. introduced in version 0.21

|- | 3D Navigation | Specifies a mouse navigation style. To see the details of each style, select it and then press the Mouse... button. |- | Orbit style | Specifies the rotation orbit style used when in rotation mode. The options are:

  • Turntable: Moving the mouse will divide the rotation in steps, rotations around the different axes are performed sequentially.
  • Trackball: Rotations around the different axes are performed simultaneously.
  • Free Turntable: Like Trackball, but if possible the rotation axis is kept collinear with the global 3D view axis. introduced in version 0.21

|- | Rotation mode | Defines the rotation center. The options are:

  • Window center
  • Drag at cursor
  • Object center

|- | Default camera orientation | Specifies the camera orientation for new documents. This setting is also used by the Std ViewHome command. |- | Camera zoom | Affects the initial camera zoom level for new documents. The value you set is the diameter of a sphere that fits in 3D view. The default is 100 mm. It also sets the initial size of origin features (base planes in new PartDesign Bodies and Std Parts). |- | Enable animation | If checked, and 3D Navigation is set to CAD, rotations can be animated. If the mouse is moved while the scroll wheel and the right mouse button are pressed, the view is rotated. If one keeps the mouse moving while releasing the right mouse button, the rotation will continue. To end this animation left-click with the mouse. |- | Zoom at cursor | If checked, zoom operations will be performed at the position of the mouse pointer. Otherwise zoom operations will be performed at the center of the current view. The Zoom step defines how much will be zoomed. A zoom step of 1 means a factor of 7.5 for every zoom step. |- | Invert zoom | If checked, the direction of zoom operations will be inverted. |- | Disable touchscreen tilt gesture | If checked, and 3D Navigation is set to Gesture, the tilting gesture will be disabled for pinch-zooming (two-finger zooming). |- | Enable rotation center indication | If checked, the rotation center of the view is shown when dragging. introduced in version 0.22 |}

Цвета

Вкладка Цвета позволяет настроить следующие параметры:

Название Описание
Включить подсвечивание при наведении курсора Если этот флажок установлен, предварительный выбор включен и будет выделен указанным цветом. Предварительный выбор означает, что, например, ребра в деталях будут выделены при наведении курсора на них, чтобы указать, что они могут быть выбраны.
Включить подсвечивание выделенного Если флажок установлен, подсветка выделения включена и для нее будет использоваться указанный цвет
Один цвет Если пункт выбран, то фон 3D Вида для деталей будет иметь выбранный цвет
Цветовой градиент Если пункт выбран, то фон 3D Вида для деталей будет иметь выбранный вертикальный цветовой градиент. Первый цвет будет цветом верха фона, второй будет цветом низа.
Средний цвет Доступно только если выбрано Цветовой градиент. Если этот флажок установлен, цветовой градиент получит выбранный цвет как средний цвет.
Объект редактируется Выбор цвета фона для объектов в виде дерева, которые в данный момент редактируются
Активный контейнер Выбор цвета фона для активных контейнеров в виде дерева. Например, если в древовидном представлении есть несколько частей и одна часть переключается как активное тело, она получит выбранный цвет фона в древовидном представлении.

Просмотр в виде полигональной сетки

Данная вкладка становится доступной, только после загрузки Верстака Mesh.

Вкладка Просмотр в виде полигональной сетки позволяет настроить следующие параметры:

Название Описание
Цвет полигональной сетки по умолчанию Определяет цвет полигонов полигональной сетки по умолчанию
Цвет линии по умолчанию Определяет цвет линий полигональной сетки по умолчанию
Прозрачность полигональной сетки Определяет прозрачность полигонов полигональной сетки по умолчанию
Прозрачность линии Определяет прозрачность линий полигонов полигональной сетки по умолчанию
Двустороннее отображение Если пункт выбран, цвет внутренних сторон граней будет таким же, как и на внешней стороне. Иначе внутренние стороны граней будут подсвечены цветом подсветки или будут отображены просто черным цветом если подсветка будет отключена.
Отображать границы габаритных размеров для подсвеченных или выбранных полигональных сеток Если пункт выбран, тогда будет отображаться желтый прямоугольный каркас отображающий границы габаритных размеров для подсвеченных или выбранных полигональных сеток.
Задавать нормаль для каждой вершины Если пункт выбран, тогда вместо плоского затенения будет применяться затенение по Фонгу. Тип затенения определяет внешний вид поверхностей. При плоском затенении нормали поверхности не определяются для каждой вершины. Это приводит к нереалистичному внешнему виду криволинейных поверхностей. В то время, как затенение по Фонгу приводит к более реалистичному внешнему виду.
Угол сгиба Угол сгиба-это пороговый угол между двумя гранями. Он может быть установлен только в том случае, если включена опция: задавать нормаль доля каждой вершины.
Если угол грани ≥ угла сгиба, применяется затенение без размытия
Если угол грани < угла сгиба, применяется плавное затенение

Рабочее окружение

В этом разделе настроек есть одна вкладка: Доступные верстаки.

Доступные Верстаки

These preferences control workbench loading.

On the Available Workbenches tab you can specify the following:

Name Description
Workbench list The list displays all installed workbenches. The list can be reordered by drag and drop (introduced in version 0.21) and sorted by right-clicking the list and selecting Sort alphabetically (introduced in version 0.22). The order of the list also determines the order of the Workbench selector.
  • introduced in version 0.21: First checkbox in each row: If checked, the workbench will be available in the Workbench selector in the next FreeCAD session. The start up workbench cannot be unchecked. Unchecked workbenches are moved to the bottom of the list.
  • Auto-load: If checked, the workbench will auto-load when FreeCAD starts. Loading more workbenches will make the start up slower, but switching between workbenches that have already been loaded is faster.
  • Load: Press this button to load the workbench in the current FreeCAD session.
Start up workbench The workbench that is activated when FreeCAD starts.
Workbench selector position introduced in version 0.21 Defines where the Workbench selector appears. The options are:
  • Toolbar: In a dedicated toolbar.
  • Left corner: In the left corner of the menubar.
  • Right corner: In the right corner of the menubar.
Remember active workbench by tab If checked, FreeCAD will remember and restore the workbench that was active for each tab in the Main view area.

Python

This preferences section (introduced in version 0.21) has three tabs: Macro, Python console and Editor.

Макрос

Вкладка Макрос позволяет настроить следующие параметры:

Название Описание
Запуск макросов в локальном окружении Если параметр включен, переменные, определенные макросами, создаются как локальные переменные, в противном случае они создаются как глобальные переменные Python
Куда записывать макросы Путь к папке в которой находятся макросы
Записать команды интерфейса Если параметр включен, записанные макросы также будет содержать команды интерфейса пользователя
Записывать как комментарий Если параметр включен, записанные макросы также будет содержать команды интерфейса пользователя, но в виде комментариев. Это полезно, если вы не хотите выполнять видимые действия при запуске макроса, а видеть, что можно сделать визуально.
Показать команды скрипта в консоли Python Если параметр включен, команды, выполняемые макросами, отображаются в консоли Python. Эта консоль отображается с помощью меню Вид → Панели → Консоль Python.
Размер списка недавних макросов Значение определяет длину списка недавно открытых макросов.
Количество ярлыков Значение определяет длину списка недавно открытых макросов которые можно запустить с помощью комбинации клавиш
Комбинация клавиш Определяет, какая комбинация клавиш клавиатуры используются для запуска макросов, например если значение равно Ctrl+Shift+ это означает что маеросы можно запустить с помощью комбинаций клавиш Ctrl+Shift+1, Ctrl+Shift+2 и так далее.

Консоль Python

These preferences control the behavior of the Python console. This console can be opened using the View → Panels → Python console menu option.

Note that the color and font settings for the console are defined on the Editor tab.

On the Python console tab (introduced in version 0.20) you can specify the following:

Name Description
Enable word wrap If checked, words will be wrapped if they exceed the available horizontal space in the console.
Enable block cursor If checked, the cursor will have a block shape.
Save history If checked, Python history is saved across sessions.

Редактор кода

Настройки предпочтений редактора влияют на поведение редактора макросов. Этот редактор можно открыть с помощью меню Макрос → Макросы... → Редактировать/Создать.

Настройки цвета и шрифта также оказывают влияние на консоль Python. Эта консоль отображается с помощью меню Вид → Панели → Консоль Python.

Вкладка Редактор кода позволяет настроить следующие параметры:

Название Описание
Показывать номера строк Если пункт выбран, то строки кода будут пронумерованы
Шаг табуляции Определение шага табулятора (количество пробелов). Если, например, установлено значение «6», при нажатии Tab будет выполнен переход к символу 7, 13, 19 и т.д., в зависимости от текущей позиции курсора. Этот параметр используется только в том случае, если выбран Символы табуляции.
Размер отступа Указывает, сколько пробелов будет вставлено при нажатии Tab. Этот параметр используется только в том случае, если выбран Заменять на пробелы.
Символы табуляции Если пункт выбран, то нажатие Tab вставит табулятор с растром, определяемым Шаг табуляции
Заменять на пробелы Если пункт выбран, то нажатие Tab вставит количество пробелов, определяемых Размер отступа
Показать пункты Выбор типа кода. Настройки цвета и шрифта будут применены к выбранному типу. Результат можно проверить в окне "Предпросмотр".
Шрифт Выбор типа шрифта, который должен использоваться для выбранного типа кода
Размер Выбор размера шрифта, который должен использоваться для выбранного типа кода
Цвет Определение цвета, который должен использоваться для выбранного типа кода

Менеджер Дополнений

This preferences section has a single tab: Addon manager options.

Настройки менеджера дополнений

These preferences control the behavior of the Addon manager.

On the Addon manager options tab (introduced in version 0.20) you can specify the following:

Name Description
Automatically check for updates at start (requires git) If checked, the Addon manager will check for updates when it is launched. Git must be installed for this to work.
Download Macro metadata (approximately 10MB) If checked, macro metadata is downloaded for display in the Addon manager's main addon listing. This data is cached locally.
Cache update frequency Controls the frequency with which the locally cached addon availability and metadata information is updated. The options are:
  • Manual (no automatic updates)
  • Daily
  • Weekly
Hide Addons marked Python 2 Only If checked, addons marked as "Python 2 Only" are not included in the listing. These addons are unlikely to work in the current FreeCAD version.
Hide Addons marked Obsolete If checked, addons marked as "Obsolete" are not included in the listing.
Hide Addons that require a newer version of FreeCAD If checked, addons that require a newer FreeCAD version are not included in the listing.
Custom repositories Custom repositories can be specified here.

To add a repository press the button. Both the Repository URL and the Branch, typically master or main, must be specifies in the dialog that opens. introduced in version 0.21

To remove a repository select it in the list and press the button. introduced in version 0.21

Proxy The Addon manager includes experimental support for proxies requiring authentication, set up as user-defined proxies.
Python executable (optional) The Addon manager attempts to determine the Python executable that should be used for the automatic pip-based installation of Python dependencies. To override this selection, the path to the executable can be set here.
git executable (optional) The Addon manager attempts to determine the git executable. To override this selection, the path to the executable can be set here. introduced in version 0.21
Show option to change branches (requires git) If checked, the Addon manager provides an interface on the addon's details screen that allows switching which git branch is currently checked out. This is intended for advanced users only, as it is possible that a non-primary-branch version of an addon may result in instability and compatibility issues. Git must be installed for this to work. Use with caution.
Disable git (fall back to ZIP downloads only) If checked, git downloads are disabled. introduced in version 0.21
Addon developer mode If checked, Addon manager options intended for developers of addons are activated. introduced in version 0.21

Импорт/Экспорт

The Import-Export preferences affect how files are imported and exported. They are described on the Import Export Preferences page.

Настройки верстаков

Настройки для более распространенных верстаков приведены ниже. У некоторых верстаков нет настроек. Другие дополнительные верстаки могут быть не перечислены. Эти ссылки так же перечислены в Category:Preferences

Программирование

См. так же: Основы составления скриптов в FreeCAD.

For a scripting example see Std DlgParameter.

Сопутствующая информация


Customizing the Interface


Введение

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

introduced in version 0.21: The Workbenches tab is no longer available. Its functionality has been moved to the Available Workbenches tab in the Workbenches section of the Preferences Editor.

Диалоговое окно настройки

Применение

  1. The commands available in the Customize dialog box depend on the workbenches that have been loaded in the current FreeCAD session. So you should first load all workbenches whose commands you want to have access to.
  2. There are several ways to invoke the Std DlgCustomize command:
    • Select the Tools → Customize... option from the menu.
    • Right-click a toolbar area and choose Customize... from the context menu.
  3. The Customize dialog box opens. For more information see Options.
  4. The Help button starts the Std WhatsThis command.
  5. Press the Close button to close the dialog box.

Опции

In the Customize dialog box the following tabs are available:

Клавиатура

Вкладка "Клавиатура"

On this tab custom keyboard shortcuts can be defined. Shortcuts for macro commands can be defined on the Macros tab.

Search

You can search for commands by entering at least 3 characters of their menu text or name in the search field. The search is case-insensitive.

It is also possible to search for shortcuts:

  • In the search field special keys in shortcuts must be entered as strings. For example to search for commands that use Ctrl in their shortcut enter ctrl (4 letters).
  • Add parenthesis to search for single character shortcuts, for example: (c).
  • Add a comma and space between the characters of multi-character shortcuts, for example: g, b, b.

Добавление пользовательской комбинации клавиш

  1. Select a command category from the Category dropdown list.
  2. Select a command from the Commands panel.
    • Optionally click the Command, Shortcut or Default column headings to reorder the list.
    • Optionally drag the splitter to the right of the panel to resize it.
  3. The Current shortcut box displays the current short cut, if available.
  4. Enter a new shortcut in the New shortcut input box. Shortcuts can be up to 4 inputs long. Each input is either a single character, a combination of one or more special keys or a combination of one or more special keys and a character. Use Backspace to correct mistakes.
  5. Other active commands (see Notes) that already use the shortcut will be listed in the Shortcut priority list.
  6. Press the Assign button to assign the new shortcut.
  7. If the Shortcut priority list contains more than one command: optionally change its order by selecting individual commands and pressing the Up button or the Down button. If active commands share the same shortcut, the shortcut will trigger the one that is highest in the list.

Remove a shortcut

  1. Select a command category from the Category dropdown list.
  2. Select a command from the Commands panel.
  3. Press the Clear button.

Restore a default shortcut

  1. Select a command category from the Category dropdown list.
  2. Select a command from the Commands panel.
  3. Press the Reset button.

Restore all default shortcuts

  1. Нажмите на кнопку Reset All.

Notes

  • Shortcuts only work for active commands. Active commands are commands that appear in the standard menu, or in the menu of the active workbench, or commands that appear in a visible toolbar.

наверх

Панели инструментов

Вкладка "Панели инструментов"

На этой вкладке можно создать и изменить специальные панели инструментов.

Search

See Keyboard.

Выбор верстака

  1. In the dropdown list on the right select the workbench whose custom toolbars you want to modify. The Global option is there for custom toolbars that should be available in all workbenches.

Создание панели инструментов

  1. Press the New... button.
  2. Enter a name in the dialog box that opens.
  3. Press the OK button.
  4. The new toolbar will appear in the panel on the right.

Переименование панели инструментов

  1. Select a toolbar in the panel on the right.
  2. Press the Rename... button.
  3. Enter a new name in the dialog box that opens.
  4. Press the OK button.

Удаление панели инструментов

  1. Select a toolbar in the panel on the right.
  2. Press the Delete button.

Disable a toolbar

  1. Uncheck the checkbox in front of the toolbar name in the panel on the right.
  2. A disabled toolbar will be invisible in the FreeCAD interface.

Добавление команды

  1. At least one custom toolbar is required. See Create a toolbar.
  2. Select the correct toolbar in the panel on the right. If no toolbar is selected, the command will be added to the first toolbar in the list.
  3. Select a command category from the Category dropdown list. Macro commands that have been set up on the Macros tab appear in the Macros category.
  4. Select a command from the Commands panel, or select <Separator> to add a separator (a line between two toolbar buttons).
    • Optionally drag the splitter to the right of the panel to resize it.
  5. Press button.

Переименовывание команды

  1. If required, expand the toolbar in the panel on the right.
  2. Select a command.
  3. Press button.

Изменение расположения команд на панели инструментов

  1. If required, expand the toolbar in the panel on the right.
  2. Select a command.
  3. Press the button or the button.
  4. Optionally repeat this until the command is in the correct position.

Notes

  • Toolbars belonging to the current workbench are updated immediately, but after disabling/re-enabling a toolbar a workbench change is required (switch to a different workbench and then switch back).
  • To update global toolbars a workbench change (if commands have been added or removed) or a restart (if the order of a toolbar has changed or a toolbar was renamed) is required.

наверх

Макросы

Вкладка "Макросы"

On this tab macro commands can be set up. Once set up, they can be added to custom toolbars. Macros installed with the Addon Manager are set up automatically, and added to a Global toolbar (see Toolbars), if you confirm the Add button popup during the installation process.

If you want to use a macro downloaded from a different source you will have to install it manually. See How to install macros for more information. Note that FreeCAD uses a dedicated folder for macros and only macros in that folder can be set up. Use the Std DlgMacroExecute command to find this folder on your system.

Добавление макро команды

  1. In the Macro dropdown list select a macro.
  2. Enter a Menu text. This will be the name used to identify the macro command and will also appear in the toolbar if there is no icon.
  3. Optionally enter a Tool tip. This text will appear near the location of the mouse when you hover the toolbar icon.
  4. Optionally enter a Status text. This text will appear in the status bar when you hover the toolbar icon.
  5. Optionally enter the wiki page for the macro, if available, in the What's this input box. Enter the page name, not the full URL.
  6. Optionally enter a shortcut in the Accelerator input box. See Keyboard for more information.
  7. To add an icon:
    1. Press the Pixmap ... button.
    2. The Choose Icon dialog box opens.
    3. If required press the Icon folders... button to add an icon folder.
    4. Select an icon from the panel. The Choose Icon dialog box closes automatically.
  8. Press the Add button.
  9. The macro command appears in the panel on the left.
  10. The macro command can now be selected on the Toolbars tab.

Переименовывание макро команды

  1. Select the macro command in the panel on the left.
  2. Press the Remove button.

Изменение макро команды

  1. Double-click the macro command in the panel on the left.
  2. Make the required changes. Note that you cannot remove the icon, you can only replace it.
  3. Press the Replace button.

наверх

Spaceball Motion

This tab is blank if no Spaceball is detected. See: 3Dconnexion input devices.

наверх

Spaceball Buttons

This tab is blank if no Spaceball is detected. See: 3Dconnexion input devices.

наверх

Темы

FreeCAD supports complete theming of the interface, via .qss stylesheets. The qss format is very similar to the css format used in web pages, it basically adds methods to reference the different widgets and elements of the Qt interface. You can change the default theme (which simply takes the style defined by your desktop system) by selecting a style sheet in the FreeCAD preferences.

You can also create your own theme if you are not satisfied with the themes that are bundled with FreeCAD, for example by editing an existing style sheet. Your new style must be placed in a specific folder for it to be found by FreeCAD:

  • %APPDATA%/FreeCAD/Gui/Stylesheets (on Windows). The %APPDATA% folder can be retrieved by entering App.getUserAppDataDir() in the Python console.
  • $HOME/.FreeCAD/Gui/Stylesheets (on Linux).
  • $HOME/Library/Application Support/FreeCAD/Gui/Stylesheets (on macOS).

наверх

Дополнения

Addons from the Addon Manager offer yet another way to customize the user interface. Several Preference Packs to change the theme are available.

In the Workbenches category of the Addon Manager some addons by user triplus can be found:

наверх

Object properties

<translate>

Introduction

A property is a piece of information like a number or a text string that is attached to a FreeCAD document or an object in a document. Public properties can be viewed and modified in the Property editor.

Properties play a very important role in FreeCAD. As objects in FreeCAD are "parametric", this means that their behavior is defined by their properties, and how these properties are used as input for their class methods. See also FeaturePython Custom Properties and PropertyLink: InList and OutList

All property types

Custom scripted objects can use any of the property types defined in the base system:

</translate>

Name Unit (if any) Remark
Acceleration m/s^2
AmountOfSubstance mol
Angle °
Area m^2
Bool
BoolList
Color
ColorList
CurrentDensity A/m^2 introduced in version 0.21
Density kg/m^3
Direction
DissipationRate m^2/s^3 introduced in version 0.21
Distance m
DynamicViscosity Pa*s introduced in version 0.21
ElectricalCapacitance F introduced in version 0.21
ElectricalConductance S introduced in version 0.21
ElectricalConductivity S/m introduced in version 0.21
ElectricalInductance H introduced in version 0.21
ElectricalResistance Ohm introduced in version 0.21
ElectricCharge C introduced in version 0.21
ElectricCurrent A introduced in version 0.21
ElectricPotential V introduced in version 0.20
Enumeration
ExpressionEngine
File
FileIncluded
Float
FloatConstraint
FloatList
Font
Force N
Frequency Hz
HeatFlux W/m^2 introduced in version 0.21
Integer
IntegerConstraint
IntegerList
IntegerSet
InverseArea 1/m^2 introduced in version 0.21
InverseLength 1/m introduced in version 0.21
InverseVolume 1/m^3 introduced in version 0.21
KinematicViscosity m^2/s introduced in version 0.21
Length m
Link
LinkChild
LinkGlobal
LinkHidden
LinkList
LinkListChild
LinkListGlobal
LinkListHidden
LinkSub
LinkSubChild
LinkSubGlobal
LinkSubHidden
LinkSubList
LinkSubListChild
LinkSubListGlobal
LinkSubListHidden
LuminousIntensity cd introduced in version 0.21
MagneticFieldStrength A/m introduced in version 0.21
MagneticFlux Wb or V*s introduced in version 0.21
MagneticFluxDensity T introduced in version 0.21
Magnetization A/m introduced in version 0.21
Map
Mass kg introduced in version 0.21
Material
MaterialList
Matrix
PartShape a Part property, is accessed as
Part::PropertyPartShape
Path
Percent
PersistentObject
Placement
PlacementLink
PlacementList
Position
Power W introduced in version 0.21
Precision
Pressure Pa
PythonObject
Quantity
QuantityConstraint
Rotation
ShearModulus Pa introduced in version 0.21
SpecificEnergy m^2/s^2 or J/kg introduced in version 0.21
SpecificHeat J/kg/K introduced in version 0.21
Speed m/s
Stiffness m/s^2
Stress Pa introduced in version 0.21
String
StringList
Temperature K introduced in version 0.21
ThermalConductivity W/m/K introduced in version 0.21
ThermalExpansionCoefficient 1/K introduced in version 0.21
ThermalTransferCoefficient W/m^2/K introduced in version 0.21
Time s introduced in version 0.21
UltimateTensileStrength Pa introduced in version 0.21
UUID
VacuumPermittivity s^4*A^2 / (m^3*kg)
Vector
VectorDistance
VectorList
Velocity m/s introduced in version 0.21
Volume l or m^3
VolumeFlowRate l/s or m^3/s introduced in version 0.21
VolumetricThermalExpansionCoefficient 1/K introduced in version 0.21
Work J introduced in version 0.21
XLink
XLinkList
XLinkSub
XLinkSubList
YieldStrength Pa introduced in version 0.21
YoungsModulus Pa introduced in version 0.21

<translate>

Internally, the property name is prefixed with App::Property: </translate>

App::PropertyBool
App::PropertyFloat
App::PropertyFloatList
...

<translate>

Remember that these are property types. A single object may have many properties of the same type, but with different names.

For example:

</translate>

obj.addProperty("App::PropertyFloat", "Length")
obj.addProperty("App::PropertyFloat", "Width")
obj.addProperty("App::PropertyFloat", "Height")

<translate>

This indicates an object with three properties of type "Float", named "Length", "Width", and "Height", respectively.

Scripting

See also: FreeCAD scripting basics

A scripted object is created first, and then properties are assigned. </translate>

obj = App.ActiveDocument.addObject("Part::Feature", "CustomObject")

obj.addProperty("App::PropertyFloat", "Velocity", "Parameter", "Body speed")
obj.addProperty("App::PropertyBool", "VelocityEnabled", "Parameter", "Enable body speed")

<translate>

In general, Data properties are assigned by using the object's addProperty() method. On the other hand, View properties are normally provided automatically by the parent object from which the scripted object is derived.

For example:

  • Deriving from App::FeaturePython provides only 4 View properties: "Display Mode", "On Top When Selected", "Show In Tree", and "Visibility".
  • Deriving from Part::Feature provides 17 View properties: the previous four, plus "Angular Deflection", "Bounding Box", "Deviation", "Draw Style", "Lighting", "Line Color", "Line Width", "Point Color", "Point Size", "Selectable", "Selection Style", "Shape Color", and "Transparency".

Nevertheless, View properties can also be assigned using the view provider object's addProperty() method.

</translate>

obj.ViewObject.addProperty("App::PropertyBool", "SuperVisibility", "Base", "Make the object glow")

<translate>

Source code

In the source code, properties are located in various src/App/Property* files.

They are imported and initialized in src/App/Application.cpp.

</translate>

#include "Property.h"
#include "PropertyContainer.h"
#include "PropertyUnits.h"
#include "PropertyFile.h"
#include "PropertyLinks.h"
#include "PropertyPythonObject.h"
#include "PropertyExpressionEngine.h"

<translate>


</translate>

Working with workbenches

<translate>

FreeCAD, like many modern design applications such as Revit or CATIA, is based on the concept of Workbench. A workbench can be considered as a set of tools specially grouped for a certain task. In a traditional furniture workshop, you would have a work table for the person who works with wood, another one for the one who works with metal pieces, and maybe a third one for the guy who mounts all the pieces together.

In FreeCAD, the same concept applies. Tools are grouped into workbenches according to the tasks they are related to.

When you switch from one workbench to another, the tools available on the interface change. Toolbars, command bars and possibly other parts of the interface switch to the new workbench, but the contents of your scene doesn't change. You could, for example, start drawing 2D shapes with the Draft Workbench, then work further on them with the Part Workbench.

Note that sometimes a Workbench is referred to as a Module. However, Workbenches and Modules are different entities. A Module is any extension of FreeCAD, while a Workbench is a special type of Module with a GUI configuration (toolbars and menus).

Built-in workbenches

Current

The following workbenches are bundled with every FreeCAD installation:

  • Std Base. This is not really a workbench, but rather a category of 'standard' commands and tools that can be used in all workbenches.
  • The CAM Workbench is used to produce G-Code instructions. This workbench was called "Path Workbench" in version 0.21 and below.
  • The FEM Workbench provides Finite Element Analysis (FEA) workflow.
  • The Inspection Workbench is made to give you specific tools for examination of shapes. Still in the early stages of development.
  • The Part Workbench for working with geometric primitives and boolean operations.
  • The Reverse Engineering Workbench is intended to provide specific tools to convert shapes/solids/meshes into parametric FreeCAD-compatible features.
  • The Start Workbench allows you to quickly jump to one of the most common workbenches.

Obsolete

The following workbenches are no longer included after version 0.20:

External workbenches

FreeCAD workbenches are easy to program in Python, there are therefore many people developing additional workbenches outside of the FreeCAD main development area.

The external workbenches page lists all that are known to this community. Most are easily installable from within FreeCAD, using the Addon Manager, found under menu Tools → Addon manager.


</translate>

The Mesh workbench

<translate>

Mesh workbench icon

</translate>

<translate>

Introduction

The Mesh Workbench handles triangle meshes. Meshes are a special type of 3D object, composed of triangular faces connected by their vertices and edges.

Many 3D applications, like Sketchup, Blender, Maya and 3D Studio Max, use meshes as their primary type of 3D object. Since meshes are very simple objects, containing only vertices (points), edges and triangular faces, they are very easy to create, modify, subdivide, stretch, and can easily be passed from one application to another without any loss of details. In addition, since meshes contain very simple data, 3D applications can usually manage very large quantities of them without using a lot of resources. For these reasons, meshes are often the 3D object type of choice for applications dealing with movies, animation, and image creation.

However, in the field of engineering meshes present a big limitation: they cannot accurately define curved surfaces. This is why FreeCAD relies on Brep instead. The Mesh Workbench offers some commands to directly manipulate meshes, but it is most often used to import 3D mesh data and convert it to a solid for use with the Part Workbench or PartDesign Workbench.

</translate> <translate>

Tools

All Mesh Workbench tools can be accessed from the Meshes menu. Almost all are also available in one of the Mesh toolbars.

  • Close hole: Fills selected holes in mesh objects.
  • Add triangle: Adds faces along a boundary of an open mesh object.
  • Boolean
    • Union: Creates a mesh object that is the union of two mesh objects.
    • Intersection: Creates a mesh object that is the intersection of two mesh objects.
    • Difference: Creates a mesh object that is the difference of two mesh objects.
  • Merge: Creates a mesh object by combining the meshes of two or more mesh objects.
  • Unwrap mesh: Creates a flat representation of a mesh object.
  • Unwrap face: Creates a flat representation of a face of a shape object.

Preferences

There are some export preferences related to Mesh Formats but these are not used by commands belonging to this workbench. They are used by the Std Export command.

Mesh Workbench preferences can be found in the following categories of the Preferences Editor:

Notes


</translate>

The Part workbench

<translate>

Part workbench icon

</translate>

<translate>

Introduction

The solid modelling capabilities of FreeCAD are based on the OpenCASCADE Technology (OCCT) kernel, a professional-grade CAD system that features advanced 3D geometry creation and manipulation. The Part Workbench is a layer sitting on top of the OCCT libraries, that gives the user access to OCCT geometric primitives and functions. Essentially all 2D and 3D drawing functions in every workbench ( Draft, Sketcher, PartDesign, etc.), are based on these functions exposed by the Part Workbench. Therefore, the Part Workbench is considered the core component of the modelling capabilities of FreeCAD.

A more detailed discussion of Part workbench versus Part Design workbench can be found here: Part and Part Design.

The objects created with the Part Workbench are relatively simple; they are intended to be used with boolean operations (unions and cuts) in order to build more complex shapes. This modeling paradigm is known as the constructive solid geometry (CSG) workflow, and it was the traditional methodology used in early CAD systems. On the other hand, the PartDesign Workbench provides a more modern workflow to constructing shapes: it uses a parametrically defined sketch, that is extruded to form a basic solid body, which is then modified by parametric transformations (feature editing), until the final object is obtained.

Part objects are more complex than mesh objects created with the Mesh Workbench, as they permit more advanced operations like coherent boolean operations, modifications history, and parametric behaviour.

</translate> <translate>

The Part Workbench is the basic layer that exposes the OCCT drawing functions to all workbenches in FreeCAD.

Tools

The tools are located in the Part menu or the Measure menu.

Primitives

These are tools for creating primitive objects.

  • Box: Creates a box.
  • Cone: Creates a cone.
  • Tube: Creates a tube.
  • Create primitives...: A tool to create one of the following primitives:
    • Plane: Creates a plane.
    • Box: Creates a box. This object can also be created with the Box tool.
    • Cylinder: Creates a cylinder. This object can also be created with the Cylinder tool.
    • Cone: Creates a cone. This object can also be created with the Cone tool.
    • Sphere: Creates a sphere. This object can also be created with the Sphere tool.
    • Ellipsoid: Creates a ellipsoid.
    • Torus: Creates a torus. This object can also be created with the Torus tool.
    • Prism: Creates a prism.
    • Wedge: Creates a wedge.
    • Helix: Creates a helix.
    • Spiral: Creates a spiral.
    • Circle: Creates a circular arc.
    • Ellipse: Creates an elliptical arc.
    • Point: Creates a point.
    • Line: Creates a line.
    • Regular polygon: Creates a regular polygon.

Creation and modification

These are tools for creating new and modifying existing objects.

  • Revolve: Creates a solid by revolving an object (not a solid) around an axis.
  • Mirror: Mirrors the selected object across a mirror plane.
  • Fillet: Fillets (rounds) edges of an object.
  • Chamfer: Chamfers edges of an object.
  • Loft: Lofts from one profile to another.
  • Sweep: Sweeps one or more profiles along a path.
  • Section: Creates a section by intersecting an object with a section plane.
  • Offset tools:
    • 3D Offset: Constructs a parallel shape at a certain distance from an original.
    • 2D Offset: Constructs a parallel wire at certain distance from an original, or enlarges/shrinks a planar face.
  • Attachment: Attaches an object to another object.

Boolean

These tools perform boolean operations.

  • Boolean: Performs boolean operations on objects.
  • Cut: Cuts (subtracts) one object from another.
  • Fuse: Fuses (unions) two or more objects.
  • Common: Extracts the common (intersection) part of two objects.
  • Join features:
    • Connect: Connects interiors of walled objects.
    • Embed: Embeds a walled object into another walled object.
    • Cutout: Creates a cutout in a wall of an object for another walled object.
  • Splitting tools:
    • Boolean fragments: Creates all pieces obtained from Boolean operations.
    • Slice apart: Slices and splits an object by intersecting it with other objects.
    • Slice: Slices an object by intersecting it with other objects.
    • XOR: Removes space shared by an even number of objects.

Measure

Other tools

  • Import: Imports from *.IGES, *.STEP, or *.BREP files.
  • Export: Exports to *.IGES, *.STEP, or *.BREP files.

Context menu items

  • Appearance: Determines the appearance of a whole object (color, transparency etc.).
  • Set colors: Assigns colors to individual faces of objects.

Preferences

  • Preferences: Preferences available for Part Tools (the Part workbench also uses the PartDesign Preferences).
  • Import Export Preferences: Preferences available for importing from and exporting to different file formats.
  • Fine-tuning: Some extra parameters to fine-tune Part behavior.

Scripting

See Part scripting.

Tutorials


</translate>

The Drawing workbench

<translate>

The Drawing Workbench is no longer included after version 0.20.
The TechDraw Workbench is its more advanced replacement.
Drawing workbench icon

Introduction

The Drawing module allows you to put your 3D work on paper. That is, to put views of your models in a 2D window and to insert that window in a drawing, for example a sheet with a border, a title and your logo and finally print that sheet.

</translate>

<translate>

Tools

These are tools for creating, configuring and exporting 2D drawing sheets

  • Insert a view: Inserts a view of the selected object in the active drawing sheet
  • Annotation: Adds an annotation to the current drawing sheet
  • Clip: Adds a clip group to the current drawing sheet
  • Open Browser: Opens a preview of the current sheet in the browser
  • Ortho Views: Automatically creates orthographic views of an object on the current drawing sheet
  • Symbol: Adds the contents of a SVG file as a symbol on the current drawing sheet
  • Draft View: Inserts a special Draft view of the selected object in the current drawing sheet
  • Spreadsheet View: Inserts a view of a selected spreadsheet in the current drawing sheet
  • Save sheet: Saves the current sheet as a SVG file
  • Project Shape: Creates a projection of the selected object (Source) in the 3D view.

Workflow

The document contains a 3D shape object (leg) from which we want to produce a drawing. Therefore a "Page" is created. A page it's instantiated from a template, for example, the "A3_Landscape" template. The template is an SVG document which can hold a page frame, a logo, and other elements.

In this page we can insert one or more views. Each view has a position on the page, a scale factor, and additional properties. Every time the page or the view or the referenced object changes, the page is regenerated and the page display updated.

Scripting

At the moment the graphical user interface workflow is very limited, so the scripting API is more interesting.

See the Drawing API example page for a description of the functions used to create drawing pages and views.

Templates

FreeCAD comes bundled with a set of default templates, but you can find more on the Drawing templates page.

Extending the Drawing Module

Some notes on the programming side of the drawing module will be added to the Drawing Documentation page. This is to help quickly understand how the drawing module works, enabling programmers to rapidly start programming for it.

Tutorials

Macros

  • Macro Automatic drawing: Allows the user to get the view of his object in a drawing with 4 different position (front,top,iso,right). Needs some modification to be perfectly effective.
  • Macro CartoucheFC: This GUI macro to fill simply all fields of the cartridge of the plan implementation worksheet FreeCAD, the format of the date and the symbol of the projection mode adapt to the EU region or US selected.
  • Macro CartoucheFC 2: This GUI macro to fill simply all fields of the cartridge model 2 of the plan implementation worksheet FreeCAD.
  • Macro CartoucheFC Full: This GUI macro to fill simply all fields of the cartridge Misc templates Full of the plan implementation worksheet FreeCAD, the format of the date and the symbol of the projection mode adapt to the EU region or US selected.
  • Macro Corner shapes wizard/update: Pops up a dialog asking for the dimensions of your corner piece, then creates the object in the document and creates a page view with top, front and lateral views of the piece.

External links


</translate>

The Raytracing workbench

<translate>

The Raytracing Workbench is no longer included after version 0.20.
The external Render Workbench should be used instead.
Raytracing workbench icon

Introduction

</translate>

<translate>

The Raytracing Workbench is used to generate photorealistic images of your models by processing them with an external renderer.

The Raytracing Workbench works with templates, which are project files that define a scene for your 3D model. You can place lights and geometry such as ground planes, and it also contains placeholders for the position of the camera, and for the material information of the objects in the scene. The project can then be exported to a ready-to-render file, or be rendered directly within FreeCAD.

Currently, two renderers are supported: POV-Ray and LuxRender. To be able to render from within FreeCAD, at least one of these programs must be installed and configured in your system. However, if no renderer is installed, you will still be able to export a project file to be rendered at another time.

The Raytracing workbench is obsolete, the external Render Workbench is its replacement. Nevertheless, the information on this page is generally useful for the new workbench, as both basically work in the same way.

</translate> <translate>

Typical workflow

  1. Create or open a FreeCAD project, add some solid objects (Part-based or PartDesign-based); meshes are currently not supported.
  2. Create a Raytracing project (povray or luxrender).
  3. Select the objects that you wish to add to the Raytracing project and add them.
  4. Export the project file or render it directly.



Workflow of the Raytracing Workbench; the workbench prepares a project file from a given template, and then calls an external program to produce the actual rendering of the scene. The external renderer can be used independently of FreeCAD.

Tools

Project tools

These are the main tools for exporting your 3D work to external renderers.

  • New PovRay project: Insert new PovRay project in the document
  • New LuxRender project: Insert new LuxRender project in the document
  • Insert part: Insert a view of a Part in a raytracing project
  • Reset camera: Matches the camera position of a raytracing project to the current view
  • Export project: Exports a raytracing project to a scene file for rendering in an external renderer
  • Render: Renders a raytracing project with an external renderer

Utilities

These are helper tools to perform specific tasks manually.

Preferences

  • Preferences: Preferences available in for the Raytracing tools.

Tutorials

Creating a povray file manually

The utility tools described above allow you to export the current 3D view and all of its content to a Povray file. First, you must load or create your CAD data and position the 3D View orientation as you wish. Then choose "Utilities → Export View..." from the raytracing menu.

</translate>

<translate>

You will be asked for a location to save the resulting *.pov file. After that you can open it in Povray and render: </translate>

<translate>

As usual in a renderer you can make big and nice pictures: </translate>

<translate>

Scripting

See the Raytracing API example for information on writing scenes programmatically.

Links

POV-Ray

LuxRender

Future possible renderers to implement

Exporting to Kerkythea

Although direct export to the Kerkythea XML-File-Format is not supported yet, you can export your Objects as Mesh-Files (.obj) and then import them in Kerkythea.

  • if using Kerkythea for Linux, remember to install the WINE-Package (needed by Kerkythea for Linux to run)
  • you can convert your models with the help of the mesh workbench to meshes and then export these meshes as .obj-files
  • If your mesh-export resulted in errors (flip of normals, holes ...) you may try your luck with netfabb studio basic
Free for personal use, available for Windows, Linux and Mac OSX.
It has standard repair tools which will repair you model in most cases.
  • another good program for mesh analysing/repairing is Meshlab
Open Source, available for Windows, Linux and Mac OSX.
It has standard repair tools which will repair you model in most cases (fill holes, re-orient normals, etc.)
  • you can use "make compound" and then "make single copy" or you can fuse solids to group them before converting to meshes
  • remember to set in Kerkythea an import-factor of 0.001 for obj-modeler, since Kerkythea expects the obj-file to be in m (but standard units-scheme in FreeCAD is mm)
Within WIndows 7 64-bit Kerkythea does not seem to be able to save these settings.
So remember to do that each time you start Kerkythea
  • if importing multiple objects in Kerkythea you can use the "File → Merge" command in Kerkythea

Development

These pages refer to the new workbench, programmed in Python, meant to replace the current Raytracing Workbench.


</translate>

The Image workbench

<translate>

The Image Workbench is no longer included after version 0.20.
Its functionality has been integrated in Std Base. See Std Import and Std ViewLoadImage.
Image workbench icon

</translate>

<translate>

Introduction

The Image Workbench manages different types of bitmap images, and allows you to open them in FreeCAD.

Tools

Features

  • Like a Sketch, an imported image can be attached to one of the main planes XY, XZ, or YZ, and given a positive or negative offset.
  • The image is imported with relation of 1 pixel to 1 millimeter.
  • The recommendation is to have the imported image at a reasonable resolution.

Workflow

A major use of this workbench is tracing over the image, with the Draft or Sketcher tools, in order to generate a solid body based on the contours of the image.

Tracing over an image works best if the image has a small negative offset, for example, -0.1 mm, from the working plane. This means that the image will be slightly behind the plane where you draw your 2D geometry, so you won't draw on the image itself.

The offset of the image can be set during import, or changed later through its properties.


</translate>

The Draft workbench

2d Drafting Module/ru

Scripting and Macros

Macros

<translate>

</translate>

<translate>

Introduction

Macros are a convenient way to reproduce complex actions in FreeCAD. You simply record actions as you do them, then save those actions under a name, and replay them whenever you want. Since macros are in reality a list of Python commands, you can also edit them, and create very complex scripts.

While Python scripts normally have the .py extension, FreeCAD macros should have the .FCMacro extension. A collection of macros written by experienced users is found in the macros recipes page.

See the Power users hub to learn more about the Python programming language, and about writing macros. In particular, you should start with these pages:

How it works

Enable the console output in the menu Edit → Preferences → Python → Macro → Show scripts commands in python console. You will see that in FreeCAD, every action you do, such as pressing a button, outputs a Python command. Those commands are what can be recorded in a macro. The main tool for making macros is the macros toolbar: . On it you have 4 buttons: Record, stop recording, edit and play the current macro.

It is very simple to use: Press the record button, you will be asked to give a name to your macro, then perform some actions. When you are done, click the stop recording button, and your actions will be saved. You can now access the macro dialog with the edit button.

Macro dialog, listing the macros available in the system

There you can manage your macros, delete, edit, duplicate, install or create new ones from scratch. If you edit a macro, it will be opened in an editor window where you can make changes to its code. New macros can be installed using the Addons... button, which links to the Addon Manager.

Example

Press the record button, give a name, let's say "cylinder 10x10", then, in the Part Workbench, create a cylinder with radius = 10 and height = 10. Then, press the "stop recording" button. In the edit macros dialog, you can see the python code that has been recorded, and, if you want, make alterations to it. To execute your macro, simply press the execute button on the toolbar while your macro is in the editor. You macro is always saved to disk, so any change you make, or any new macro you create, will always be available next time you start FreeCAD.

Customizing

Of course it is not practical to load a macro in the editor in order to use it. FreeCAD provides much better ways to use your macro, such as assigning a keyboard shortcut to it or putting an entry in the menu. Once your macro is created, all this can be done via the Tools → Customize menu.

This way you can make your macro become a real tool, just like any standard FreeCAD tool. This, added to the power of python scripting within FreeCAD, makes it possible to easily add your own tools to the interface.

See Customize Toolbars for a more detailed description.

Creating macros without recording

You can also directly copy/paste python code into a macro, without recording GUI action. Simply create a new macro, edit it, and paste your code. You can then save your macro the same way as you save a FreeCAD document. Next time you start FreeCAD, the macro will appear under the "Installed Macros" item of the Macro menu.

See How to install macros for a more detailed description.

Macro repositories

There are two main places for macros. The first one is the official peer-reviewed macro repository on GitHub. The second one is the Macros recipes page from which you can pick some useful macros to add to your FreeCAD installation. Macros from both repositories can be installed via the Addon Manager directly from FreeCAD.

Additional information

Tutorials

You can manually install extensions, however, it is much simpler to just use the Addon Manager.


</translate>

Introduction to Python

Introduction to python

<translate>

</translate>

<translate>

Python scripting in FreeCAD

FreeCAD is built from scratch to be totally controlled by Python scripts. Almost all parts of FreeCAD, such as the interface, the scene contents, and even the representation of this content in the 3D views, are accessible from the built-in Python interpreter or from your own scripts. As a result, FreeCAD is probably one of the most deeply customizable engineering applications available today.

If you are not familiar with Python, we recommend you search for tutorials on the internet and have a quick look at its structure. Python is a very easy language to learn, especially because it can be run inside an interpreter, where simple commands, right up to complete programs, can be executed on the fly without the need to compile anything. FreeCAD has a built-in Python interpreter. If you don't see the window labeled Python console as shown below, you can activate it under the View → Panels → Python console.

The interpreter

From the interpreter, you can access all your system-installed Python modules, as well as the built-in FreeCAD modules, and all additional FreeCAD modules you installed later. The screenshot below shows the Python interpreter:

The FreeCAD Python interpreter

From the interpreter, you can execute Python code and browse through the available classes and functions. FreeCAD provides a very handy class browser for exploration of the FreeCAD world: When you type the name of a known class followed by a period (meaning you want to add something from that class), a class browser window opens, where you can navigate between available subclasses and methods. When you select something, an associated help text (if it exists) is displayed:

The FreeCAD class browser

So, start here by typing App. or Gui. and see what happens. Another more generic Python way of exploring the content of modules and classes is to use the print(dir()) command. For example, typing print(dir()) will list all modules currently loaded in FreeCAD. print(dir(App)) will show you everything inside the App module, etc.

Another useful feature of the interpreter is the possibility to go back through the command history and retrieve a line of code that you already typed earlier. To navigate through the command history, just use Up arrow or Down arrow.

By right-clicking in the interpreter window, you also have several other options, such as copy the entire history (useful when you want to experiment with things before making a full script of them), or insert a filename with complete path.

</translate>

наверх

<translate>

Python Help

In the FreeCAD Help menu, you'll find an entry labeled Automatic python modules documentation, which will open a browser window containing a complete, realtime-generated documentation of all Python modules available to the FreeCAD interpreter, including Python and FreeCAD built-in modules, system-installed modules, and FreeCAD additional modules. The documentation available there depends on how much effort each module developer put into documenting his code, but Python modules have a reputation for being fairly well documented. Your FreeCAD window must stay open for this documentation system to work. The entry Python scripting documentation will give you a quick link to the Power users hub wiki section.

</translate>

наверх

<translate>

Built-in modules

Since FreeCAD is designed so that it can also be run without a Graphical User Interface (GUI), almost all its functionality is separated into two groups: Core functionality, named App, and GUI functionality, named Gui. These two modules can also be accessed from scripts outside of the interpreter, by the names FreeCAD and FreeCADGui respectively.

  • In the App module you'll find everything related to the application itself, like methods for opening or closing files, and to the documents, like setting the active document or listing their contents.
  • In the Gui module, you'll find tools for accessing and managing Gui elements, like the workbenches and their toolbars, and, more interestingly, the graphical representation of all FreeCAD content.

Listing the content of these modules is not very useful because they grow quite fast as FreeCAD develops. But the two browsing tools provided (the class browser and the Python help) should give you complete and up-to-date documentation at any moment.

</translate>

наверх

<translate>

The App and Gui objects

As already mentioned, in FreeCAD everything is separated into core and representation. This includes the 3D objects. You can access defining properties of objects (called features in FreeCAD) via the App module, and change the way they are represented on screen via the Gui module. For example, a cube has properties that define it (like width, length, height) that are stored in an App object, and representation properties (like faces color, drawing mode) that are stored in a corresponding Gui object.

This way of doing things allows a very wide range of uses, like having algorithms work only on the definition part of features, without the need to care about any visual part, or even redirect the content of the document to non-graphical application, such as lists, spreadsheets, or element analysis.

For every App object in your document, there exists a corresponding Gui object. In fact the document itself has both an App and a Gui object. This, of course, only applies when you run FreeCAD with its full interface. In the command-line version no GUI exists, so only App objects are available. Note that the Gui part of objects is re-generated every time an App object is marked as 'to be recomputed' (for example when one of its parameters changes), so any changes made directly to the Gui object may be lost.

To access the App part of something, you type:

</translate>

myObject = App.ActiveDocument.getObject("ObjectName")

<translate>

where "ObjectName" is the name of your object. You can also type:

</translate>

myObject = App.ActiveDocument.ObjectName

<translate>

To access the Gui part of the same object, you type:

</translate>

myViewObject = Gui.ActiveDocument.getObject("ObjectName")

<translate>

where "ObjectName" is the name of your object. You can also type:

</translate>

myViewObject = App.ActiveDocument.ObjectName.ViewObject

<translate>

If you are in command-line mode and have no GUI, the last line will return None.

</translate>

наверх

<translate>

The Document objects

In FreeCAD all your work resides inside documents. A document contains your geometry and can be saved to a file. Several documents can be opened at the same time. The document, like the geometry contained inside, has App and Gui objects. The App object contains your actual geometry definitions, while the Gui object contains the different views of your document. You can open several windows, each one viewing your work with a different zoom factor or from a different direction. These views are all part of your document's Gui object.

To access the App part of the currently open (active) document, you type:

</translate>

myDocument = App.ActiveDocument

<translate>

To create a new document, type:

</translate>

myDocument = App.newDocument("Document Name")

<translate>

To access the Gui part of the currently open (active) document, you type:

</translate>

myGuiDocument = Gui.ActiveDocument

<translate>

To access the current view, you type:

</translate>

myView = Gui.ActiveDocument.ActiveView

<translate>

</translate>

наверх

<translate>

Using additional modules

The FreeCAD and FreeCADGui modules are only responsible for creating and managing objects in the FreeCAD document. They don't actually do anything more such as creating or modifying geometry. This is because that geometry can be of several types, and therefore requires additional modules, each responsible for managing a certain geometry type. For example, the Part Workbench, using the OpenCascade kernel, is able to create and manipulate BRep type geometry. Whereas the Mesh Workbench is able to build and modify mesh objects. In this manner FreeCAD is able to handle a wide variety of object types, that can all coexist in the same document, and new types can easily be added in the future.

</translate>

наверх

<translate>

Creating objects

Each module has its own way of dealing with geometry, but one thing they usually all can do is create objects in the document. But the FreeCAD document is also aware of the available object types provided by the modules:

</translate>

FreeCAD.ActiveDocument.supportedTypes()

<translate>

will list all possible objects you can create. For example, let's create a mesh (handled by the Mesh module) and a part (handled by the Part module):

</translate>

myMesh = FreeCAD.ActiveDocument.addObject("Mesh::Feature", "myMeshName")
myPart = FreeCAD.ActiveDocument.addObject("Part::Feature", "myPartName")

<translate>

The first argument is the object type, the second the name of the object. Our two objects look almost the same: They don't contain any geometry yet, and most of their properties are the same when you inspect them with dir(myMesh) and dir(myPart). Except for one thing, myMesh has a Mesh property and myPart has a Shape property. That is where the Mesh and Part data are stored. For example, let's create a Part cube and store it in our myPart object:

</translate>

import Part
cube = Part.makeBox(2, 2, 2)
myPart.Shape = cube

<translate>

You could try storing the cube inside the Mesh property of the myMesh object, but it will return an error. That is because each properties is made to store only a certain type. In a Mesh property, you can only save stuff created with the Mesh module. Note that most modules also have a shortcut to add their geometry to the document:

</translate>

import Part
cube = Part.makeBox(2, 2, 2)
Part.show(cube)

<translate>

</translate>

наверх

<translate>

Modifying objects

Modifying an object is done in the same way:

</translate>

import Part
cube = Part.makeBox(2, 2, 2)
myPart.Shape = cube

<translate>

Now let's change the shape by a bigger one:

</translate>

biggercube = Part.makeBox(5, 5, 5)
myPart.Shape = biggercube

<translate>

</translate>

наверх

<translate>

Querying objects

You can always look at the type of an object like this:

</translate>

myObj = FreeCAD.ActiveDocument.getObject("myObjectName")
print(myObj.TypeId)

<translate>

or check if an object is derived from one of the basic ones (Part Feature, Mesh Feature, etc):

</translate>

print(myObj.isDerivedFrom("Part::Feature"))

<translate>

Now you can really start playing with FreeCAD! For a complete list of available modules and their tools, visit the Category:API section.

</translate>

наверх

<translate>


</translate>

<translate>

</translate>

<translate>

Introduction

To get access to the Mesh module you have to import it first:

</translate>

import Mesh

<translate>

Creation

To create an empty mesh object just use the standard constructor:

</translate>

mesh = Mesh.Mesh()

<translate>

You can also create an object from a file:

</translate>

mesh = Mesh.Mesh("D:/temp/Something.stl")

<translate>

Or create it out of a set of triangles described by their corner points:

</translate>

triangles = [
# triangle 1
[-0.5000, -0.5000, 0.0000], [0.5000, 0.5000, 0.0000], [-0.5000, 0.5000, 0.0000],
#triangle 2
[-0.5000, -0.5000, 0.0000], [0.5000, -0.5000, 0.0000], [0.5000, 0.5000, 0.0000],
]
meshObject = Mesh.Mesh(triangles)
Mesh.show(meshObject)

<translate>

The Mesh-Kernel takes care of creating a topologically correct data structure by sorting coincident points and edges.

</translate>

наверх

<translate>

Modeling

To create regular geometries you can use one of the create*() methods. A torus, for instance, can be created as follows:

</translate>

m = Mesh.createTorus(8.0, 2.0, 50)
Mesh.show(m)

<translate>

The first two parameters define the radii of the torus and the third parameter is a sub-sampling factor for how many triangles are created. The higher this value the smoother the mesh.

The Mesh module also provides three Boolean methods: union(), intersection() and difference():

</translate>

m1, m2              # are the input mesh objects
m3 = Mesh.Mesh(m1)  # create a copy of m1
m3.unite(m2)        # union of m1 and m2, the result is stored in m3
m4 = Mesh.Mesh(m1)
m4.intersect(m2)    # intersection of m1 and m2
m5 = Mesh.Mesh(m1)
m5.difference(m2)   # the difference of m1 and m2
m6 = Mesh.Mesh(m2)
m6.difference(m1)   # the difference of m2 and m1, usually the result is different to m5

<translate>

Here is an example that creates a pipe using the difference() method:

</translate>

import FreeCAD, Mesh
cylA = Mesh.createCylinder(2.0, 10.0, True, 1.0, 36)
cylB = Mesh.createCylinder(1.0, 12.0, True, 1.0, 36)
cylB.Placement.Base = (FreeCAD.Vector(-1, 0, 0)) # move cylB to avoid co-planar faces
pipe = cylA
pipe = pipe.difference(cylB)
pipe.flipNormals() # somehow required
doc = FreeCAD.ActiveDocument
obj = d.addObject("Mesh::Feature", "Pipe")
obj.Mesh = pipe
doc.recompute()

<translate>

</translate>

наверх

<translate>

Notes

An extensive, though hard to use, source of mesh related scripting are the unit test scripts of the Mesh module. In these unit tests literally all methods are called and all properties/attributes are tweaked. So if you are bold enough, take a look at the Unit Test module.

See also: Mesh API.

</translate>

наверх

<translate>

</translate>

<translate>

</translate>

<translate>

Introduction

Here we will explain to you how to control the Part module directly from the FreeCAD Python interpreter, or from any external script. Be sure to browse the Scripting section and the FreeCAD Scripting Basics pages if you need more information about how Python scripting works in FreeCAD. If you are new to Python, it is a good idea to first read the Introduction to Python.

See also

Class diagram

This is a Unified Modeling Language (UML) overview of the most important classes of the Part module: Python classes of the Part module

</translate>

наверх

<translate>

Geometry

The geometric objects are the building blocks of all topological objects:

  • Geom Base class of the geometric objects.
  • Line A straight line in 3D, defined by starting point and end point.
  • Circle Circle or circle segment defined by a center point and start and end point.
  • Etc.

</translate>

наверх

<translate>

Topology

The following topological data types are available:

  • Compound A group of any type of topological objects.
  • Compsolid A composite solid is a set of solids connected by their faces. It expands the notions of WIRE and SHELL to solids.
  • Solid A part of space limited by shells. It is three dimensional.
  • Shell A set of faces connected by their edges. A shell can be open or closed.
  • Face In 2D it is part of a plane; in 3D it is part of a surface. Its geometry is constrained (trimmed) by contours. It is two dimensional.
  • Wire A set of edges connected by their vertices. It can be an open or closed contour depending on whether the edges are linked or not.
  • Edge A topological element corresponding to a restrained curve. An edge is generally limited by vertices. It has one dimension.
  • Vertex A topological element corresponding to a point. It has zero dimension.
  • Shape A generic term covering all of the above.

</translate>

наверх

<translate>

Example: Create simple topology

Wire

We will now create a topology by constructing it out of simpler geometry. As a case study we will use a part as seen in the picture which consists of four vertices, two arcs and two lines.

</translate>

наверх

<translate>

Create geometry

First we create the distinct geometric parts of this wire. Making sure that parts that have to be connected later share the same vertices.

So we create the points first:

</translate>

import FreeCAD as App
import Part
V1 = App.Vector(0, 10, 0)
V2 = App.Vector(30, 10, 0)
V3 = App.Vector(30, -10, 0)
V4 = App.Vector(0, -10, 0)

<translate>

</translate>

наверх

<translate>

Arc

Circle


For each arc we need a helper point:

</translate>

VC1 = App.Vector(-10, 0, 0)
C1 = Part.Arc(V1, VC1, V4)
VC2 = App.Vector(40, 0, 0)
C2 = Part.Arc(V2, VC2, V3)

<translate>

</translate>

наверх

<translate>

Line

Line


The line segments can be created from two points:

</translate>

L1 = Part.LineSegment(V1, V2)
L2 = Part.LineSegment(V3, V4)

<translate>

</translate>

наверх

<translate>

Put it all together

The last step is to put the geometric base elements together and bake a topological shape:

</translate>

S1 = Part.Shape([C1, L1, C2, L2])

<translate>

</translate>

наверх

<translate>

Make a prism

Now extrude the wire in a direction and make an actual 3D shape:

</translate>

W = Part.Wire(S1.Edges)
P = W.extrude(App.Vector(0, 0, 10))

<translate>

</translate>

наверх

<translate>

Show it all

</translate>

Part.show(P)

<translate>

</translate>

наверх

<translate>

Create basic shapes

You can easily create basic topological objects with the make...() methods from the Part module:

</translate>

b = Part.makeBox(100, 100, 100)
Part.show(b)

<translate>

Some available make...() methods:

  • makeBox(l, w, h, [p, d]) Makes a box located in p and pointing into the direction d with the dimensions (l,w,h).
  • makeCircle(radius) Makes a circle with a given radius.
  • makeCone(radius1, radius2, height) Makes a cone with the given radii and height.
  • makeCylinder(radius, height) Makes a cylinder with a given radius and height.
  • makeLine((x1, y1, z1), (x2, y2, z2)) Makes a line from two points.
  • makePlane(length, width) Makes a plane with length and width.
  • makePolygon(list) Makes a polygon from a list of points.
  • makeSphere(radius) Makes a sphere with a given radius.
  • makeTorus(radius1, radius2) Makes a torus with the given radii.

See the Part API page or this autogenerated Python Part API documentation for a complete list of available methods of the Part module.

</translate>

наверх

<translate>

Import modules

First we need to import the FreeCAD and Part modules so we can use their contents in Python:

</translate>

import FreeCAD as App
import Part

<translate>

</translate>

наверх

<translate>

Create a vector

Vectors are one of the most important pieces of information when building shapes. They usually contain three numbers (but not necessarily always): the X, Y and Z cartesian coordinates. You create a vector like this:

</translate>

myVector = App.Vector(3, 2, 0)

<translate>

We just created a vector at coordinates X = 3, Y = 2, Z = 0. In the Part module, vectors are used everywhere. Part shapes also use another kind of point representation called Vertex which is simply a container for a vector. You access the vector of a vertex like this:

</translate>

myVertex = myShape.Vertexes[0]
print(myVertex.Point)
> Vector (3, 2, 0)

<translate>

</translate>

наверх

<translate>

Create an edge

An edge is nothing but a line with two vertices:

</translate>

edge = Part.makeLine((0, 0, 0), (10, 0, 0))
edge.Vertexes
> [<Vertex object at 01877430>, <Vertex object at 014888E0>]

<translate>

Note: You can also create an edge by passing two vectors:

</translate>

vec1 = App.Vector(0, 0, 0)
vec2 = App.Vector(10, 0, 0)
line = Part.LineSegment(vec1, vec2)
edge = line.toShape()

<translate>

You can find the length and center of an edge like this:

</translate>

edge.Length
> 10.0
edge.CenterOfMass
> Vector (5, 0, 0)

<translate>

</translate>

наверх

<translate>

Put the shape on screen

So far we created an edge object, but it doesn't appear anywhere on the screen. This is because the FreeCAD 3D scene only displays what you tell it to display. To do that, we use this simple method:

</translate>

Part.show(edge)

<translate>

The show function creates an object in our FreeCAD document and assigns our "edge" shape to it. Use this whenever it is time to display your creation on screen.

</translate>

наверх

<translate>

Create a wire

A wire is a multi-edge line and can be created from a list of edges or even a list of wires:

</translate>

edge1 = Part.makeLine((0, 0, 0), (10, 0, 0))
edge2 = Part.makeLine((10, 0, 0), (10, 10, 0))
wire1 = Part.Wire([edge1, edge2]) 
edge3 = Part.makeLine((10, 10, 0), (0, 10, 0))
edge4 = Part.makeLine((0, 10, 0), (0, 0, 0))
wire2 = Part.Wire([edge3, edge4])
wire3 = Part.Wire([wire1, wire2])
wire3.Edges
> [<Edge object at 016695F8>, <Edge object at 0197AED8>, <Edge object at 01828B20>, <Edge object at 0190A788>]
Part.show(wire3)

<translate>

Part.show(wire3) will display the 4 edges that compose our wire. Other useful information can be easily retrieved:

</translate>

wire3.Length
> 40.0
wire3.CenterOfMass
> Vector (5, 5, 0)
wire3.isClosed()
> True
wire2.isClosed()
> False

<translate>

</translate>

наверх

<translate>

Create a face

Only faces created from closed wires will be valid. In this example, wire3 is a closed wire but wire2 is not (see above):

</translate>

face = Part.Face(wire3)
face.Area
> 99.99999999999999
face.CenterOfMass
> Vector (5, 5, 0)
face.Length
> 40.0
face.isValid()
> True
sface = Part.Face(wire2)
sface.isValid()
> False

<translate>

Only faces will have an area, wires and edges do not.

</translate>

наверх

<translate>

Create a circle

A circle can be created like this:

</translate>

circle = Part.makeCircle(10)
circle.Curve
> Circle (Radius : 10, Position : (0, 0, 0), Direction : (0, 0, 1))

<translate>

If you want to create it at a certain position and with a certain direction:

</translate>

ccircle = Part.makeCircle(10, App.Vector(10, 0, 0), App.Vector(1, 0, 0))
ccircle.Curve
> Circle (Radius : 10, Position : (10, 0, 0), Direction : (1, 0, 0))

<translate>

ccircle will be created at distance 10 from the X origin and will be facing outwards along the X axis. Note: makeCircle() only accepts App.Vector() for the position and normal parameters, not tuples. You can also create part of the circle by giving a start and an end angle:

</translate>

from math import pi
arc1 = Part.makeCircle(10, App.Vector(0, 0, 0), App.Vector(0, 0, 1), 0, 180)
arc2 = Part.makeCircle(10, App.Vector(0, 0, 0), App.Vector(0, 0, 1), 180, 360)

<translate>

Angles should be provided in degrees. If you have radians simply convert them using the formula: degrees = radians * 180/pi or by using Python's math module:

</translate>

import math
degrees = math.degrees(radians)

<translate>

</translate>

наверх

<translate>

Create an arc along points

Unfortunately there is no makeArc() function, but we have the Part.Arc() function to create an arc through three points. It creates an arc object joining the start point to the end point through the middle point. The arc object's toShape() function must be called to get an edge object, the same as when using Part.LineSegment instead of Part.makeLine.

</translate>

arc = Part.Arc(App.Vector(0, 0, 0), App.Vector(0, 5, 0), App.Vector(5, 5, 0))
arc
> <Arc object>
arc_edge = arc.toShape()
Part.show(arc_edge)

<translate>

Arc() only accepts App.Vector() for points and not tuples. You can also obtain an arc by using a portion of a circle:

</translate>

from math import pi
circle = Part.Circle(App.Vector(0, 0, 0), App.Vector(0, 0, 1), 10)
arc = Part.Arc(circle,0,pi)

<translate>

Arcs are valid edges like lines, so they can be used in wires also.

</translate>

наверх

<translate>

Create a polygon

A polygon is simply a wire with multiple straight edges. The makePolygon() function takes a list of points and creates a wire through those points:

</translate>

lshape_wire = Part.makePolygon([App.Vector(0, 5, 0), App.Vector(0, 0, 0), App.Vector(5, 0, 0)])

<translate>

</translate>

наверх

<translate>

Create a Bézier curve

Bézier curves are used to model smooth curves using a series of poles (points) and optional weights. The function below makes a Part.BezierCurve() from a series of FreeCAD.Vector() points. Note: when "getting" and "setting" a single pole or weight, indices start at 1, not 0.

</translate>

def makeBCurveEdge(Points):
   geomCurve = Part.BezierCurve()
   geomCurve.setPoles(Points)
   edge = Part.Edge(geomCurve)
   return(edge)

<translate>

</translate>

наверх

<translate>

Create a plane

A Plane is a flat rectangular surface. The method used to create one is makePlane(length, width, [start_pnt, dir_normal]). By default start_pnt = Vector(0, 0, 0) and dir_normal = Vector(0, 0, 1). Using dir_normal = Vector(0, 0, 1) will create the plane facing in the positive Z axis direction, while dir_normal = Vector(1, 0, 0) will create the plane facing in the positive X axis direction:

</translate>

plane = Part.makePlane(2, 2)
plane
> <Face object at 028AF990>
plane = Part.makePlane(2, 2, App.Vector(3, 0, 0), App.Vector(0, 1, 0))
plane.BoundBox
> BoundBox (3, 0, 0, 5, 0, 2)

<translate>

BoundBox is a cuboid enclosing the plane with a diagonal starting at (3, 0, 0) and ending at (5, 0, 2). Here the BoundBox thickness along the Y axis is zero, since our shape is totally flat.

Note: makePlane() only accepts App.Vector() for start_pnt and dir_normal and not tuples.

</translate>

наверх

<translate>

Create an ellipse

There are several ways to create an ellipse:

</translate>

Part.Ellipse()

<translate>

Creates an ellipse with major radius 2 and minor radius 1 with the center at (0, 0, 0).

</translate>

Part.Ellipse(Ellipse)

<translate>

Creates a copy of the given ellipse.

</translate>

Part.Ellipse(S1, S2, Center)

<translate>

Creates an ellipse centered on the point Center, where the plane of the ellipse is defined by Center, S1 and S2, its major axis is defined by Center and S1, its major radius is the distance between Center and S1, and its minor radius is the distance between S2 and the major axis.

</translate>

Part.Ellipse(Center, MajorRadius, MinorRadius)

<translate>

Creates an ellipse with major and minor radii MajorRadius and MinorRadius, located in the plane defined by Center and the normal (0, 0, 1)

</translate>

eli = Part.Ellipse(App.Vector(10, 0, 0), App.Vector(0, 5, 0), App.Vector(0, 0, 0))
Part.show(eli.toShape())

<translate>

In the above code we have passed S1, S2 and center. Similar to Arc, Ellipse creates an ellipse object not an edge, so we need to convert it into an edge using toShape() for display.

Note: Ellipse() only accepts App.Vector() for points and not tuples.

</translate>

eli = Part.Ellipse(App.Vector(0, 0, 0), 10, 5)
Part.show(eli.toShape())

<translate>

For the above Ellipse constructor we have passed center, MajorRadius and MinorRadius.

</translate>

наверх

<translate>

Create a torus

Using makeTorus(radius1, radius2, [pnt, dir, angle1, angle2, angle]). By default pnt = Vector(0, 0, 0), dir = Vector(0, 0, 1), angle1 = 0, angle2 = 360 and angle = 360. Consider a torus as small circle sweeping along a big circle. Radius1 is the radius of the big circle, radius2 is the radius of the small circle, pnt is the center of the torus and dir is the normal direction. angle1 and angle2 are angles in degrees for the small circle; the last angle parameter is to make a section of the torus:

</translate>

torus = Part.makeTorus(10, 2)

<translate>

The above code will create a torus with diameter 20 (radius 10) and thickness 4 (small circle radius 2)

</translate>

tor=Part.makeTorus(10, 5, App.Vector(0, 0, 0), App.Vector(0, 0, 1), 0, 180)

<translate>

The above code will create a slice of the torus.

</translate>

tor=Part.makeTorus(10, 5, App.Vector(0, 0, 0), App.Vector(0, 0, 1), 0, 360, 180)

<translate>

The above code will create a semi torus; only the last parameter is changed. i.e the remaining angles are defaults. Giving the angle 180 will create the torus from 0 to 180, that is, a half torus.

</translate>

наверх

<translate>

Create a box or cuboid

Using makeBox(length, width, height, [pnt, dir]). By default pnt = Vector(0, 0, 0) and dir = Vector(0, 0, 1).

</translate>

box = Part.makeBox(10, 10, 10)
len(box.Vertexes)
> 8

<translate>

</translate>

наверх

<translate>

Create a sphere

Using makeSphere(radius, [pnt, dir, angle1, angle2, angle3]). By default pnt = Vector(0, 0, 0), dir = Vector(0, 0, 1), angle1 = -90, angle2 = 90 and angle3 = 360. Angle1 and angle2 are the vertical minimum and maximum of the sphere, angle3 is the sphere diameter.

</translate>

sphere = Part.makeSphere(10)
hemisphere = Part.makeSphere(10, App.Vector(0, 0, 0), App.Vector(0, 0, 1), -90, 90, 180)

<translate>

</translate>

наверх

<translate>

Create a cylinder

Using makeCylinder(radius, height, [pnt, dir, angle]). By default pnt = Vector(0, 0, 0), dir = Vector(0, 0, 1) and angle = 360.

</translate>

cylinder = Part.makeCylinder(5, 20)
partCylinder = Part.makeCylinder(5, 20, App.Vector(20, 0, 0), App.Vector(0, 0, 1), 180)

<translate>

</translate>

наверх

<translate>

Create a cone

Using makeCone(radius1, radius2, height, [pnt, dir, angle]). By default pnt = Vector(0, 0, 0), dir = Vector(0, 0, 1) and angle = 360.

</translate>

cone = Part.makeCone(10, 0, 20)
semicone = Part.makeCone(10, 0, 20, App.Vector(20, 0, 0), App.Vector(0, 0, 1), 180)

<translate>

</translate>

наверх

<translate>

Modify shapes

There are several ways to modify shapes. Some are simple transformation operations such as moving or rotating shapes, others are more complex, such as unioning and subtracting one shape from another.

</translate>

наверх

<translate>

Transform operations

Translate a shape

Translating is the act of moving a shape from one place to another. Any shape (edge, face, cube, etc...) can be translated the same way:

</translate>

myShape = Part.makeBox(2, 2, 2)
myShape.translate(App.Vector(2, 0, 0))

<translate>

This will move our shape "myShape" 2 units in the X direction.

</translate>

наверх

<translate>

Rotate a shape

To rotate a shape, you need to specify the rotation center, the axis, and the rotation angle:

</translate>

myShape.rotate(App.Vector(0, 0, 0),App.Vector(0, 0, 1), 180)

<translate>

The above code will rotate the shape 180 degrees around the Z Axis.

</translate>

наверх

<translate>

Matrix transformations

A matrix is a very convenient way to store transformations in the 3D world. In a single matrix, you can set translation, rotation and scaling values to be applied to an object. For example:

</translate>

myMat = App.Matrix()
myMat.move(App.Vector(2, 0, 0))
myMat.rotateZ(math.pi/2)

<translate>

Note: FreeCAD matrixes work in radians. Also, almost all matrix operations that take a vector can also take three numbers, so these two lines do the same thing:

</translate>

myMat.move(2, 0, 0)
myMat.move(App.Vector(2, 0, 0))

<translate>

Once our matrix is set, we can apply it to our shape. FreeCAD provides two methods for doing that: transformShape() and transformGeometry(). The difference is that with the first one, you are sure that no deformations will occur (see Scaling a shape below). We can apply our transformation like this:

</translate>

myShape.transformShape(myMat)

<translate>

or

</translate>

myShape.transformGeometry(myMat)

<translate>

</translate>

наверх

<translate>

Scale a shape

Scaling a shape is a more dangerous operation because, unlike translation or rotation, scaling non-uniformly (with different values for X, Y and Z) can modify the structure of the shape. For example, scaling a circle with a higher value horizontally than vertically will transform it into an ellipse, which behaves mathematically very differently. For scaling, we cannot use the transformShape(), we must use transformGeometry():

</translate>

myMat = App.Matrix()
myMat.scale(2, 1, 1)
myShape=myShape.transformGeometry(myMat)

<translate>

</translate>

наверх

<translate>

Boolean operations

Subtraction

Subtracting a shape from another one is called "cut" in FreeCAD and is done like this:

</translate>

cylinder = Part.makeCylinder(3, 10, App.Vector(0, 0, 0), App.Vector(1, 0, 0))
sphere = Part.makeSphere(5, App.Vector(5, 0, 0))
diff = cylinder.cut(sphere)

<translate>

</translate>

наверх

<translate>

Intersection

The same way, the intersection between two shapes is called "common" and is done this way:

</translate>

cylinder1 = Part.makeCylinder(3, 10, App.Vector(0, 0, 0), App.Vector(1, 0, 0))
cylinder2 = Part.makeCylinder(3, 10, App.Vector(5, 0, -5), App.Vector(0, 0, 1))
common = cylinder1.common(cylinder2)

<translate>

</translate>

наверх

<translate>

Union

Union is called "fuse" and works the same way:

</translate>

cylinder1 = Part.makeCylinder(3, 10, App.Vector(0, 0, 0), App.Vector(1, 0, 0))
cylinder2 = Part.makeCylinder(3, 10, App.Vector(5, 0, -5), App.Vector(0, 0, 1))
fuse = cylinder1.fuse(cylinder2)

<translate>

</translate>

наверх

<translate>

Section

A "section" is the intersection between a solid shape and a plane shape. It will return an intersection curve, a compound curve composed of edges.

</translate>

cylinder1 = Part.makeCylinder(3, 10, App.Vector(0, 0, 0), App.Vector(1, 0, 0))
cylinder2 = Part.makeCylinder(3, 10, App.Vector(5, 0, -5), App.Vector(0, 0, 1))
section = cylinder1.section(cylinder2)
section.Wires
> []
section.Edges
> [<Edge object at 0D87CFE8>, <Edge object at 019564F8>, <Edge object at 0D998458>, 
 <Edge  object at 0D86DE18>, <Edge object at 0D9B8E80>, <Edge object at 012A3640>, 
 <Edge object at 0D8F4BB0>]

<translate>

</translate>

наверх

<translate>

Extrusion

Extrusion is the act of "pushing" a flat shape in a certain direction, resulting in a solid body. Think of a circle becoming a tube by "pushing it out":

</translate>

circle = Part.makeCircle(10)
tube = circle.extrude(App.Vector(0, 0, 2))

<translate>

If your circle is hollow, you will obtain a hollow tube. If your circle is actually a disc with a filled face, you will obtain a solid cylinder:

</translate>

wire = Part.Wire(circle)
disc = Part.Face(wire)
cylinder = disc.extrude(App.Vector(0, 0, 2))

<translate>

</translate>

наверх

<translate>

Explore shapes

You can easily explore the topological data structure:

</translate>

import Part
b = Part.makeBox(100, 100, 100)
b.Wires
w = b.Wires[0]
w
w.Wires
w.Vertexes
Part.show(w)
w.Edges
e = w.Edges[0]
e.Vertexes
v = e.Vertexes[0]
v.Point

<translate>

By typing the lines above in the Python interpreter, you will gain a good understanding of the structure of Part objects. Here, our makeBox() command created a solid shape. This solid, like all Part solids, contains faces. Faces always contain wires, which are lists of edges that border the face. Each face has at least one closed wire (it can have more if the face has a hole). In the wire, we can look at each edge separately, and inside each edge, we can see the vertices. Straight edges have only two vertices, obviously.

</translate>

наверх

<translate>

Edge analysis

In case of an edge, which is an arbitrary curve, it's most likely you want to do a discretization. In FreeCAD the edges are parametrized by their lengths. That means you can walk an edge/curve by its length:

</translate>

import Part
box = Part.makeBox(100, 100, 100)
anEdge = box.Edges[0]
print(anEdge.Length)

<translate>

Now you can access a lot of properties of the edge by using the length as a position. That means if the edge is 100mm long the start position is 0 and the end position 100.

</translate>

anEdge.tangentAt(0.0)          # tangent direction at the beginning
anEdge.valueAt(0.0)            # Point at the beginning
anEdge.valueAt(100.0)          # Point at the end of the edge
anEdge.derivative1At(50.0)     # first derivative of the curve in the middle
anEdge.derivative2At(50.0)     # second derivative of the curve in the middle
anEdge.derivative3At(50.0)     # third derivative of the curve in the middle
anEdge.centerOfCurvatureAt(50) # center of the curvature for that position
anEdge.curvatureAt(50.0)       # the curvature
anEdge.normalAt(50)            # normal vector at that position (if defined)

<translate>

</translate>

наверх

<translate>

Use a selection

Here we see now how we can use a selection the user did in the viewer. First of all we create a box and show it in the viewer.

</translate>

import Part
Part.show(Part.makeBox(100, 100, 100))
Gui.SendMsgToActiveView("ViewFit")

<translate>

Now select some faces or edges. With this script you can iterate over all selected objects and their sub elements:

</translate>

for o in Gui.Selection.getSelectionEx():
    print(o.ObjectName)
    for s in o.SubElementNames:
        print("name: ", s)
        for s in o.SubObjects:
            print("object: ", s)

<translate>

Select some edges and this script will calculate the length:

</translate>

length = 0.0
for o in Gui.Selection.getSelectionEx():
    for s in o.SubObjects:
        length += s.Length

print("Length of the selected edges: ", length)

<translate>

</translate>

наверх

<translate>

Example: The OCC bottle

A typical example found on the OpenCasCade Technology website is how to build a bottle. This is a good exercise for FreeCAD too. In fact, if you follow our example below and the OCC page simultaneously, you will see how well OCC structures are implemented in FreeCAD. The script is included in the FreeCAD installation (inside the Mod/Part folder) and can be called from the Python interpreter by typing:

</translate>

import Part
import MakeBottle
bottle = MakeBottle.makeBottle()
Part.show(bottle)

<translate>

</translate>

наверх

<translate>

The script

For the purpose of this tutorial we will consider a reduced version of the script. In this version the bottle will not be hollowed out, and the neck of the bottle will not be threaded.

</translate>

import FreeCAD as App
import Part, math

def makeBottleTut(myWidth = 50.0, myHeight = 70.0, myThickness = 30.0):
    aPnt1=App.Vector(-myWidth / 2., 0, 0)
    aPnt2=App.Vector(-myWidth / 2., -myThickness / 4., 0)
    aPnt3=App.Vector(0, -myThickness / 2., 0)
    aPnt4=App.Vector(myWidth / 2., -myThickness / 4., 0)
    aPnt5=App.Vector(myWidth / 2., 0, 0)

    aArcOfCircle = Part.Arc(aPnt2, aPnt3, aPnt4)
    aSegment1=Part.LineSegment(aPnt1, aPnt2)
    aSegment2=Part.LineSegment(aPnt4, aPnt5)

    aEdge1=aSegment1.toShape()
    aEdge2=aArcOfCircle.toShape()
    aEdge3=aSegment2.toShape()
    aWire=Part.Wire([aEdge1, aEdge2, aEdge3])

    aTrsf=App.Matrix()
    aTrsf.rotateZ(math.pi) # rotate around the z-axis

    aMirroredWire=aWire.copy()
    aMirroredWire.transformShape(aTrsf)
    myWireProfile=Part.Wire([aWire, aMirroredWire])

    myFaceProfile=Part.Face(myWireProfile)
    aPrismVec=App.Vector(0, 0, myHeight)
    myBody=myFaceProfile.extrude(aPrismVec)

    myBody=myBody.makeFillet(myThickness / 12.0, myBody.Edges)

    neckLocation=App.Vector(0, 0, myHeight)
    neckNormal=App.Vector(0, 0, 1)

    myNeckRadius = myThickness / 4.
    myNeckHeight = myHeight / 10.
    myNeck = Part.makeCylinder(myNeckRadius, myNeckHeight, neckLocation, neckNormal)
    myBody = myBody.fuse(myNeck)

    return myBody

el = makeBottleTut()
Part.show(el)

<translate>

</translate>

наверх

<translate>

Detailed explanation

</translate>

import FreeCAD as App
import Part, math

<translate>

We will, of course, need the FreeCAD and Part modules.

</translate>

def makeBottleTut(myWidth = 50.0, myHeight = 70.0, myThickness = 30.0):
    aPnt1=App.Vector(-myWidth / 2., 0, 0)
    aPnt2=App.Vector(-myWidth / 2., -myThickness / 4., 0)
    aPnt3=App.Vector(0, -myThickness / 2., 0)
    aPnt4=App.Vector(myWidth / 2., -myThickness / 4., 0)
    aPnt5=App.Vector(myWidth / 2., 0, 0)

<translate>

Here we define our makeBottleTut function. This function can be called without arguments, like we did above, in which case default values for width, height, and thickness will be used. Then, we define a couple of points that will be used for building our base profile.

</translate>

...
    aArcOfCircle = Part.Arc(aPnt2, aPnt3, aPnt4)
    aSegment1=Part.LineSegment(aPnt1, aPnt2)
    aSegment2=Part.LineSegment(aPnt4, aPnt5)

<translate>

Here we define the geometry: an arc, made of three points, and two line segments, made of two points.

</translate>

...
    aEdge1=aSegment1.toShape()
    aEdge2=aArcOfCircle.toShape()
    aEdge3=aSegment2.toShape()
    aWire=Part.Wire([aEdge1, aEdge2, aEdge3])

<translate>

Remember the difference between geometry and shapes? Here we build shapes out of our construction geometry. Three edges (edges can be straight or curved), then a wire made of those three edges.

</translate>

...
    aTrsf=App.Matrix()
    aTrsf.rotateZ(math.pi) # rotate around the z-axis

    aMirroredWire=aWire.copy()
    aMirroredWire.transformShape(aTrsf)
    myWireProfile=Part.Wire([aWire, aMirroredWire])

<translate>

So far we have built only a half profile. Instead of building the whole profile the same way, we can just mirror what we did and glue both halves together. We first create a matrix. A matrix is a very common way to apply transformations to objects in the 3D world, since it can contain in one structure all basic transformations that 3D objects can undergo (move, rotate and scale). After we create the matrix we mirror it, then we create a copy of our wire and apply the transformation matrix to it. We now have two wires, and we can make a third wire out of them, since wires are actually lists of edges.

</translate>

...
    myFaceProfile=Part.Face(myWireProfile)
    aPrismVec=App.Vector(0, 0, myHeight)
    myBody=myFaceProfile.extrude(aPrismVec)

    myBody=myBody.makeFillet(myThickness / 12.0, myBody.Edges)

<translate>

Now that we have a closed wire, it can be turned into a face. Once we have a face, we can extrude it. In doing so, we make a solid. Then we apply a nice little fillet to our object because we care about good design, don't we?

</translate>

...
    neckLocation=App.Vector(0, 0, myHeight)
    neckNormal=App.Vector(0, 0, 1)

    myNeckRadius = myThickness / 4.
    myNeckHeight = myHeight / 10.
    myNeck = Part.makeCylinder(myNeckRadius, myNeckHeight, neckLocation, neckNormal)

<translate>

At this point, the body of our bottle is made, but we still need to create a neck. So we make a new solid, with a cylinder.

</translate>

...
    myBody = myBody.fuse(myNeck)

<translate>

The fuse operation is very powerful. It will take care of gluing what needs to be glued and remove parts that need to be removed.

</translate>

...
    return myBody

<translate>

Then, we return our Part solid as the result of our function.

</translate>

el = makeBottleTut()
Part.show(el)

<translate>

Finally, we call the function to actually create the part, then make it visible.

</translate>

наверх

<translate>

Example: Pierced box

Here is a complete example of building a pierced box.

The construction is done one side at a time. When the cube is finished, it is hollowed out by cutting a cylinder through it.

</translate>

import FreeCAD as App
import Part, math

size = 10
poly = Part.makePolygon([(0, 0, 0), (size, 0, 0), (size, 0, size), (0, 0, size), (0, 0, 0)])

face1 = Part.Face(poly)
face2 = Part.Face(poly)
face3 = Part.Face(poly)
face4 = Part.Face(poly)
face5 = Part.Face(poly)
face6 = Part.Face(poly)
     
myMat = App.Matrix()

myMat.rotateZ(math.pi / 2)
face2.transformShape(myMat)
face2.translate(App.Vector(size, 0, 0))

myMat.rotateZ(math.pi / 2)
face3.transformShape(myMat)
face3.translate(App.Vector(size, size, 0))

myMat.rotateZ(math.pi / 2)
face4.transformShape(myMat)
face4.translate(App.Vector(0, size, 0))

myMat = App.Matrix()

myMat.rotateX(-math.pi / 2)
face5.transformShape(myMat)

face6.transformShape(myMat)               
face6.translate(App.Vector(0, 0, size))

myShell = Part.makeShell([face1, face2, face3, face4, face5, face6])   
mySolid = Part.makeSolid(myShell)

myCyl = Part.makeCylinder(2, 20)
myCyl.translate(App.Vector(size / 2, size / 2, 0))

cut_part = mySolid.cut(myCyl)

Part.show(cut_part)

<translate>

</translate>

наверх

<translate>

Loading and saving

There are several ways to save your work. You can of course save your FreeCAD document, but you can also save Part objects directly to common CAD formats, such as BREP, IGS, STEP and STL.

Saving a shape to a file is easy. There are exportBrep(), exportIges(), exportStep() and exportStl() methods available for all shape objects. So, doing:

</translate>

import Part
s = Part.makeBox(10, 10, 10)
s.exportStep("test.stp")

<translate>

will save our box into a STEP file. To load a BREP, IGES or STEP file:

</translate>

import Part
s = Part.Shape()
s.read("test.stp")

<translate>

To convert a STEP file to an IGS file:

</translate>

import Part
 s = Part.Shape()
 s.read("file.stp")       # incoming file igs, stp, stl, brep
 s.exportIges("file.igs") # outbound file igs

<translate>

</translate>

наверх

<translate>


</translate>

<translate>

</translate>

<translate>

Convert Part objects to meshes

Converting higher-level objects such as Part shapes to simpler objects such as meshes is a pretty straightforward operation where all faces of a Part object get triangulated. The result of that triangulation (tessellation) is then used to construct a mesh:

</translate>

import Mesh

obj = FreeCADGui.Selection.getSelection()[0] # a Part object must be preselected
shp = obj.Shape
faces = []

triangles = shp.tessellate(1) # the number represents the precision of the tessellation
for tri in triangles[1]:
    face = []
    for i in tri:
        face.append(triangles[0][i])
    faces.append(face)

m = Mesh.Mesh(faces)
Mesh.show(m)

<translate>

Alternative example:

</translate>

import Mesh
import MeshPart

obj = FreeCADGui.Selection.getSelection()[0] # a Part object must be preselected
shp = obj.Shape

mesh = FreeCAD.ActiveDocument.addObject("Mesh::Feature", "Mesh")
mesh.Mesh = MeshPart.meshFromShape(
        Shape=shp,
        LinearDeflection=0.01,
        AngularDeflection=0.025,
        Relative=False)

<translate>

Convert meshes to Part objects

Converting meshes to Part objects is a common operation. Very often you will receive 3D data in a mesh format. Meshes are quite practical for representing free-form geometry and big visual scenes, as they are very lightweight. But in FreeCAD we generally prefer higher-level objects, solids, that can carry much more information and allow for curved faces.

Converting meshes to those higher-level objects (handled by the Part Workbench in FreeCAD) is not an easy operation. Meshes can contain thousands of triangles (for example when generated by a 3D scanner), and solids made of the same number of faces would be extremely difficult to manipulate. So you generally want to optimize the object when converting.

FreeCAD currently offers two methods to convert meshes to Part objects. The first method is a simple, direct conversion without any optimization:

</translate>

import Mesh
import Part

mesh = Mesh.createTorus()
shape = Part.Shape()
shape.makeShapeFromMesh(mesh.Topology, 0.05) # the second arg is the tolerance for sewing
solid = Part.makeSolid(shape)
Part.show(solid)

<translate>

The second method offers the possibility to consider mesh facets co-planar when the angle between them is under a certain value, reducing the number of faces in the final result:

</translate>

import Mesh
import Part
import MeshPart

obj = FreeCADGui.Selection.getSelection()[0] # a Mesh object must be preselected
mesh = obj.Mesh
segments = mesh.getPlanarSegments(0.00001) # use rather strict tolerance here
faces = []

for i in segments:
    if len(i) > 0:
        # a segment can have inner holes
        wires = MeshPart.wireFromSegment(mesh, i)
        # we assume that the exterior boundary is that one with the biggest bounding box
        if len(wires) > 0:
            ext = None
            max_length=0
            for i in wires:
                if i.BoundBox.DiagonalLength > max_length:
                    max_length = i.BoundBox.DiagonalLength
                    ext = i

            wires.remove(ext)
            # all interior wires mark a hole and must reverse their orientation, otherwise Part.Face fails
            for i in wires:
                i.reverse()

            # make sure that the exterior wires comes as first in the list
            wires.insert(0, ext)
            faces.append(Part.Face(wires))

solid = Part.Solid(Part.Shell(faces))
Part.show(solid)

<translate>


</translate>

<translate>

</translate>

<translate>

Introduction

The geometry that appears in the 3D views of FreeCAD is rendered by the Coin3D library. Coin3D is an implementation of the Open Inventor standard. The OpenCASCADE software also provides the same functionality, but it was decided at the very early stages of FreeCAD not to use the built-in OpenCASCADE viewer, but rather switch to the more performant Coin3D software. A good way to learn about that library is the book Open Inventor Mentor.

Description

Open Inventor is a 3D scene description language. The scene described in Open Inventor is then rendered in OpenGL on your screen. Coin3D takes care of doing this, so programmers do not need to deal with complex OpenGL calls, and may just provide valid Open Inventor code. The big advantage is that Open Inventor is a very well-known and well documented standard.

One of the big jobs FreeCAD does for you is translating OpenCASCADE geometry information into Open Inventor language.

Open Inventor describes a 3D scene in the form of a scene graph, like the one below:

</translate> <translate>

Image taken from Inventor mentor

An Open Inventor scenegraph describes everything that is part of a 3D scene, such as geometry, colors, materials, lights, etc, and organizes all that data in a convenient and clear structure. Everything can be grouped into sub-structures, allowing you to organize your scene contents pretty much the way you like. Here is an example of an Open Inventor file:

</translate>

#Inventor V2.0 ascii
 
Separator { 
    RotationXYZ {	
       axis Z
       angle 0
    }
    Transform {
       translation 0 0 0.5
    }
    Separator {	
       Material {
          diffuseColor 0.05 0.05 0.05
       }
       Transform {
          rotation 1 0 0 1.5708
          scaleFactor 0.2 0.5 0.2
       }
       Cylinder {
       }
    }
}

<translate>

As you can see, the structure is very simple. You use separators to organize your data into blocks, a bit like you would organize your files into folders. Each statement affects what comes next, for example the first two items of our root separator are a rotation and a translation, both will affect the next item, which is a separator. In that separator a material is defined and another transformation. Our cylinder will therefore be affected by both transformations, the one applied directly to it and the one that was applied to its parent separator.

We also have many other types of elements to organize our scene, such as groups, switches or annotations. We can define very complex materials for our objects, with colors, textures, shading modes and transparency. We can also define lights, cameras, and even movement. It is even possible to embed pieces of scripting in Open Inventor files to define more complex behaviors.

If you are interested in learning more about Open Inventor head directly to its most famous reference: the Inventor mentor.

In FreeCAD, normally, we don't need to interact directly with the Open Inventor scenegraph. Every object in a FreeCAD document, being a mesh, a part shape or anything else, gets automatically converted to Open Inventor code and inserted in the main scenegraph that you see in a 3D view. That scenegraph gets updated continuously when you modify, add or remove objects. In fact every object (in App space) has a view provider (a corresponding object in Gui space) responsible for issuing Open Inventor code.

But there are many advantages to being able to access the scenegraph directly. For example, we can temporarily change the appearance of an object, or we can add objects to the scene that have no real existence in the FreeCAD document, such as construction geometry, helpers, graphical hints or tools such as manipulators or on-screen information.

FreeCAD itself features several tools to see or modify Open Inventor code. For example, the following Python code will show the Open Inventor representation of a selected object:

</translate>

obj = FreeCAD.ActiveDocument.ActiveObject
viewprovider = obj.ViewObject
print viewprovider.toString()

<translate>

But we also have a Python module that allows complete access to anything managed by Coin3D, such as our FreeCAD scenegraph. So, read on to Pivy.

Coding examples

See Coin3d snippets courtesy of MariwanJ's research for the Design456 Workbench. The code repository can be found at https://github.com/MariwanJ/COIN3D_Snippet.

</translate>

наверх

<translate>


</translate>

<translate>

</translate>

<translate>

Introduction

Pivy is a Python binding library for Coin, the 3D-rendering library used in FreeCAD to display things in a 3D view. Coin is an open source implementation of the "Open Inventor" specification to handle graphics. Therefore, in FreeCAD, the terms "Pivy", "Coin" or "Open Inventor" refer to the same thing essentially.

When imported in a running Python interpreter, Pivy allows us to communicate directly with any running Coin scenegraph, such as the 3D view, or even to create new ones. Pivy is not required to compile FreeCAD, but it is required at runtime when running Python-based workbenches that create shapes on screen, like Draft and Arch. Because of this, Pivy is normally installed when installing a distribution of FreeCAD.

The Coin library is divided into several pieces, Coin itself for manipulating scenegraphs, and bindings for several GUI systems, such as Windows and Qt. If present on the system, those modules are available to Pivy as well. The Coin module is always present, and it is what we will use anyway, since we won't need to care about anchoring our 3D display in any interface, that is already done by FreeCAD. All we need to do is this:

</translate>

from pivy import coin

<translate>

Scenegraph

We saw on the Scenegraph page how a typical Coin scene is organized. Everything that appears in a 3D view is a Coin scenegraph, organized in the same way. We have one root node, and all objects on the screen are its children.

FreeCAD has an easy way to access the root node of a 3D view scenegraph:

</translate>

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

<translate>

This will return the root node:

</translate>

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

<translate>

We can inspect the immediate children of our scene:

</translate>

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

<translate>

Some of those nodes, such as SoSeparator or SoGroup nodes, can have children themselves. The complete list of the available Coin objects can be found in the official Coin documentation.

Let's try to add something to our scenegraph now. We'll add a nice red cube:

</translate>

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

<translate>

Now, let's try this:

</translate>

col.rgb = (1, 1, 0)

<translate>

As you can see everything is still accessible and modifiable on-the-fly. No need to recompute or redraw anything, Coin takes care of everything. You can add stuff to your scenegraph, change properties, hide stuff, show temporary objects, anything. Of course, this only concerns the display in the 3D view. That display gets recomputed by FreeCAD on file open, and when an object needs recomputing. So, if you change the aspect of an existing FreeCAD object, those changes will be lost if the object gets recomputed or when you reopen the file.

As already mentioned, in an openInventor scenegraph the order is important. A node affects what comes next. For example, if we want to have the ability to move our cube we will need to add a SoTranslation node before the cube:

</translate>

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)

<translate>

To move our cube we can now do:

</translate>

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

<translate>

Finally, removing something is done with:

</translate>

sg.removeChild(myCustomNode)

<translate>

</translate>

наверх

<translate>

Callbacks

A callback mechanism is a system that permits a library, such as our Coin library, to call you back, that is, to call a certain function from your currently running Python object. That way Coin can notify you that some specific event occurred in the scene. Coin can watch very different things, such as mouse position, mouse button clicks, keyboard keys being pressed, and many more.

FreeCAD features an easy way to use such callbacks:

</translate>

from pivy import coin

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

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

ButtonTest()

<translate>

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

</translate>

наверх

<translate>

Documentation

Unfortunately, Pivy doesn't have its own documentation. However, since it is an accurate wrapper of the Coin library, you can read the C++ reference for information. In this case, you need to translate the C++ class naming style to Python style.

In C++:

</translate>

SoFile::getClassTypeId()

<translate>

In Pivy:

</translate>

SoFile.getClassId()

<translate>

Older

These links provide reference documentation for Coin v3.x. The differences with v4.x are minimal, so they may still be useful.

</translate>

наверх

<translate>


</translate>

<translate>

</translate>

<translate>

Introduction

The PySide library gives access to the cross-platform graphical user interface (GUI) toolkit Qt from Python. Qt is a collection of C++ libraries, but with the help of PySide, the same components can be used from Python. Every graphical interface that can be created in C++, can also be created and modified in Python. An advantage of using Python is that Qt interfaces can be developed and tested live, as we don't need to compile the source files.

When you install FreeCAD, you should get both Qt and PySide as part of the package. If you are compiling yourself then you must verify that these two libraries are installed in order for FreeCAD to run correctly. Of course, PySide will only work if Qt is present.

In the past, FreeCAD used PyQt, another Qt binding for Python, but in 2013 (commit 1dc122dc9a) the project migrated to PySide because it has a more permissible license.

For more information see:

</translate> <translate>

Examples created with PySide. Left: a simple dialog. Right: a more complex dialog with graphs.

PySide in FreeCAD with Qt5

FreeCAD was developed to be used with Python 2 and Qt4. As these two libraries became obsolete, FreeCAD transitioned to Python 3 and Qt5. In most cases this transition was done without needing to break backwards compatibility.

Normally, the PySide module provides support for Qt4, while PySide2 provides support for Qt5. However, in FreeCAD there is no need to use PySide2 directly, as a special PySide module is included to handle Qt5.

This PySide module is located in the Ext/ directory of an installation of FreeCAD compiled for Qt5. </translate>

/usr/share/freecad/Ext/PySide

<translate>

This module just imports the necessary classes from PySide2, and places them in the PySide namespace. This means that in most cases the same code can be used with both Qt4 and Qt5, as long as we use the single PySide module. </translate>

PySide2.QtCore -> PySide.QtCore
PySide2.QtGui -> PySide.QtGui
PySide2.QtSvg -> PySide.QtSvg
PySide2.QtUiTools -> PySide.QtUiTools

<translate>

The only unusual aspect is that the PySide2.QtWidgets classes are placed in the PySide.QtGui namespace. </translate>

PySide2.QtWidgets.QCheckBox -> PySide.QtGui.QCheckBox

<translate>

</translate>

наверх

<translate>

Examples of PySide use

The examples of PySide are divided into 3 parts, differentiated by level of exposure to PySide, Python and the FreeCAD internals. The first page has an overview on PySide; the second and third pages are mostly code examples at different levels.

It is expected that these examples are useful to get started, and afterwards the user can consult other resources online, or the official documentation.

</translate>

наверх

<translate>

Documentation

There are some differences in handling of widgets in Qt4 (PySide) and Qt5 (PySide2). The programmer should be aware of these incompatibilities, and should consult the official documentation if something doesn't seem to work as expected on a given platform. Nevertheless, Qt4 is considered obsolete, so most development should target Qt5 and Python 3.

The PySide documentation refers to the Python-style classes; however, since Qt is originally a C++ library, the same information should be available in the corresponding C++ reference.

</translate>

наверх

<translate>


</translate>

<translate>

</translate>

<translate>

Introduction

Besides the standard object types such as annotations, meshes and parts objects, FreeCAD also offers the amazing possibility to build 100% python-scripted parametric objects, called Python Features. Those objects will behave exactly as any other FreeCAD object, and are saved and restored automatically on file save/load.

One particularity must be understood: For security reasons, FreeCAD files never carry any embedded code. The Python code that you write to create parametric objects is never saved inside a file. This means that if you open a file containing such an object on another machine, if that python code is not available on that machine, the object won't be fully recreated. If you distribute such objects to others, you will need to distribute your Python script too, for example as a Macro.

Note: It is possible to pack python code inside a FreeCAD file using json serializing with an App::PropertyPythonObject, but that code can never directly be run, and therefore has little use for our purpose here.

Python Features follow the same rule as all FreeCAD features: they are separated into App and GUI parts. The app part, the Document Object, defines the geometry of our object, while its GUI part, the View Provider Object, defines how the object will be drawn on screen. The View Provider Object, as any other FreeCAD feature, is only available when you run FreeCAD in its own GUI. There are several properties and methods available to build your object. Properties must be of any of the predefined properties types that FreeCAD offers, and will appear in the property view window, so they can be edited by the user. This way, FeaturePython objects are truly and totally parametric. you can define properties for the Object and its ViewObject separately.

Basic example

The following sample can be found in the src/Mod/TemplatePyMod/FeaturePython.py file, together with several other examples:

</translate>

'''Examples for a feature class and its view provider.'''

import FreeCAD, FreeCADGui
from pivy import coin

class Box:
    def __init__(self, obj):
        '''Add some custom properties to our box feature'''
        obj.addProperty("App::PropertyLength", "Length", "Box", "Length of the box").Length = 1.0
        obj.addProperty("App::PropertyLength", "Width", "Box", "Width of the box").Width = 1.0
        obj.addProperty("App::PropertyLength", "Height", "Box", "Height of the box").Height = 1.0
        obj.Proxy = self

    def onChanged(self, fp, prop):
        '''Do something when a property has changed'''
        FreeCAD.Console.PrintMessage("Change property: " + str(prop) + "\n")

    def execute(self, fp):
        '''Do something when doing a recomputation, this method is mandatory'''
        FreeCAD.Console.PrintMessage("Recompute Python Box feature\n")

class ViewProviderBox:
    def __init__(self, obj):
        '''Set this object to the proxy object of the actual view provider'''
        obj.addProperty("App::PropertyColor","Color", "Box", "Color of the box").Color = (1.0, 0.0, 0.0)
        obj.Proxy = self

    def attach(self, obj):
        '''Setup the scene sub-graph of the view provider, this method is mandatory'''
        self.shaded = coin.SoGroup()
        self.wireframe = coin.SoGroup()
        self.scale = coin.SoScale()
        self.color = coin.SoBaseColor()

        data=coin.SoCube()
        self.shaded.addChild(self.scale)
        self.shaded.addChild(self.color)
        self.shaded.addChild(data)
        obj.addDisplayMode(self.shaded, "Shaded");
        style=coin.SoDrawStyle()
        style.style = coin.SoDrawStyle.LINES
        self.wireframe.addChild(style)
        self.wireframe.addChild(self.scale)
        self.wireframe.addChild(self.color)
        self.wireframe.addChild(data)
        obj.addDisplayMode(self.wireframe, "Wireframe");
        self.onChanged(obj,"Color")

    def updateData(self, fp, prop):
        '''If a property of the handled feature has changed we have the chance to handle this here'''
        # fp is the handled feature, prop is the name of the property that has changed
        l = fp.getPropertyByName("Length")
        w = fp.getPropertyByName("Width")
        h = fp.getPropertyByName("Height")
        self.scale.scaleFactor.setValue(float(l), float(w), float(h))
        pass

    def getDisplayModes(self,obj):
        '''Return a list of display modes.'''
        modes=[]
        modes.append("Shaded")
        modes.append("Wireframe")
        return modes

    def getDefaultDisplayMode(self):
        '''Return the name of the default display mode. It must be defined in getDisplayModes.'''
        return "Shaded"

    def setDisplayMode(self,mode):
        '''Map the display mode defined in attach with those defined in getDisplayModes.\
                Since they have the same names nothing needs to be done. This method is optional'''
        return mode

    def onChanged(self, vp, prop):
        '''Here we can do something when a single property got changed'''
        FreeCAD.Console.PrintMessage("Change property: " + str(prop) + "\n")
        if prop == "Color":
            c = vp.getPropertyByName("Color")
            self.color.rgb.setValue(c[0], c[1], c[2])

    def getIcon(self):
        '''Return the icon in XPM format which will appear in the tree view. This method is\
                optional and if not defined a default icon is shown.'''
        return """
            /* XPM */
            static const char * ViewProviderBox_xpm[] = {
            "16 16 6 1",
            "   c None",
            ".  c #141010",
            "+  c #615BD2",
            "@  c #C39D55",
            "#  c #000000",
            "$  c #57C355",
            "        ........",
            "   ......++..+..",
            "   .@@@@.++..++.",
            "   .@@@@.++..++.",
            "   .@@  .++++++.",
            "  ..@@  .++..++.",
            "###@@@@ .++..++.",
            "##$.@@$#.++++++.",
            "#$#$.$$$........",
            "#$$#######      ",
            "#$$#$$$$$#      ",
            "#$$#$$$$$#      ",
            "#$$#$$$$$#      ",
            " #$#$$$$$#      ",
            "  ##$$$$$#      ",
            "   #######      "};
            """

    def dumps(self):
        '''When saving the document this object gets stored using Python's json module.\
                Since we have some un-serializable parts here -- the Coin stuff -- we must define this method\
                to return a tuple of all serializable objects or None.'''
        return None

    def loads(self,state):
        '''When restoring the serialized object from document we have the chance to set some internals here.\
                Since no data were serialized nothing needs to be done here.'''
        return None

def makeBox():
    FreeCAD.newDocument()
    a=FreeCAD.ActiveDocument.addObject("App::FeaturePython", "Box")
    Box(a)
    ViewProviderBox(a.ViewObject)

makeBox()

<translate>

Things to note

If your object relies on being recomputed as soon as it is created, you must do this manually in the __init__ function as it is not called automatically. This example does not require it because the onChanged method of the Box class has the same effect as the execute function, but the examples below rely on being recomputed before anything is displayed in the 3D view. In the examples, this is done manually with ActiveDocument.recompute() but in more complex scenarios you need to decide where to recompute either the whole document or the FeaturePython object.

This example produces a number of exception stack traces in the report view window. This is because the onChanged method of the Box class is called each time a property is added in __init__. When the first one is added, the Width and Height properties don't exist yet and so the attempt to access them fails.

An explanation of __getstate__ and __setstate__ which have been replaced by dumps and loads is in the forum thread obj.Proxy.Type is a dict, not a string.

obj.addProperty(...) returns obj, so that the value of the property can be set on the same line:

obj.addProperty("App::PropertyLength", "Length", "Box", "Length of the box").Length = 1.0

Which is equivalent to:

obj.addProperty("App::PropertyLength", "Length", "Box", "Length of the box")
obj.Length = 1.0

Other more complex example

This example makes use of the Part module to create an octahedron, then creates its coin representation with pivy.

First is the Document object itself:

</translate>

import FreeCAD, FreeCADGui, Part
import pivy
from pivy import coin

class Octahedron:
  def __init__(self, obj):
     "Add some custom properties to our box feature"
     obj.addProperty("App::PropertyLength","Length","Octahedron","Length of the octahedron").Length=1.0
     obj.addProperty("App::PropertyLength","Width","Octahedron","Width of the octahedron").Width=1.0
     obj.addProperty("App::PropertyLength","Height","Octahedron", "Height of the octahedron").Height=1.0
     obj.addProperty("Part::PropertyPartShape","Shape","Octahedron", "Shape of the octahedron")
     obj.Proxy = self

  def execute(self, fp):
     # Define six vetices for the shape
     v1 = FreeCAD.Vector(0,0,0)
     v2 = FreeCAD.Vector(fp.Length,0,0)
     v3 = FreeCAD.Vector(0,fp.Width,0)
     v4 = FreeCAD.Vector(fp.Length,fp.Width,0)
     v5 = FreeCAD.Vector(fp.Length/2,fp.Width/2,fp.Height/2)
     v6 = FreeCAD.Vector(fp.Length/2,fp.Width/2,-fp.Height/2)

     # Make the wires/faces
     f1 = self.make_face(v1,v2,v5)
     f2 = self.make_face(v2,v4,v5)
     f3 = self.make_face(v4,v3,v5)
     f4 = self.make_face(v3,v1,v5)
     f5 = self.make_face(v2,v1,v6)
     f6 = self.make_face(v4,v2,v6)
     f7 = self.make_face(v3,v4,v6)
     f8 = self.make_face(v1,v3,v6)
     shell=Part.makeShell([f1,f2,f3,f4,f5,f6,f7,f8])
     solid=Part.makeSolid(shell)
     fp.Shape = solid

  # helper mehod to create the faces
  def make_face(self,v1,v2,v3):
     wire = Part.makePolygon([v1,v2,v3,v1])
     face = Part.Face(wire)
     return face

<translate>

Then, we have the view provider object, responsible for showing the object in the 3D scene:

</translate>

class ViewProviderOctahedron:
  def __init__(self, obj):
     "Set this object to the proxy object of the actual view provider"
     obj.addProperty("App::PropertyColor","Color","Octahedron","Color of the octahedron").Color=(1.0,0.0,0.0)
     obj.Proxy = self

  def attach(self, obj):
     "Setup the scene sub-graph of the view provider, this method is mandatory"
     self.shaded = coin.SoGroup()
     self.wireframe = coin.SoGroup()
     self.scale = coin.SoScale()
     self.color = coin.SoBaseColor()

     self.data=coin.SoCoordinate3()
     self.face=coin.SoIndexedFaceSet()

     self.shaded.addChild(self.scale)
     self.shaded.addChild(self.color)
     self.shaded.addChild(self.data)
     self.shaded.addChild(self.face)
     obj.addDisplayMode(self.shaded,"Shaded");
     style=coin.SoDrawStyle()
     style.style = coin.SoDrawStyle.LINES
     self.wireframe.addChild(style)
     self.wireframe.addChild(self.scale)
     self.wireframe.addChild(self.color)
     self.wireframe.addChild(self.data)
     self.wireframe.addChild(self.face)
     obj.addDisplayMode(self.wireframe,"Wireframe");
     self.onChanged(obj,"Color")

  def updateData(self, fp, prop):
     "If a property of the handled feature has changed we have the chance to handle this here"
     # fp is the handled feature, prop is the name of the property that has changed
     if prop == "Shape":
        s = fp.getPropertyByName("Shape")
        self.data.point.setNum(6)
        cnt=0
        for i in s.Vertexes:
           self.data.point.set1Value(cnt,i.X,i.Y,i.Z)
           cnt=cnt+1

        self.face.coordIndex.set1Value(0,0)
        self.face.coordIndex.set1Value(1,1)
        self.face.coordIndex.set1Value(2,2)
        self.face.coordIndex.set1Value(3,-1)

        self.face.coordIndex.set1Value(4,1)
        self.face.coordIndex.set1Value(5,3)
        self.face.coordIndex.set1Value(6,2)
        self.face.coordIndex.set1Value(7,-1)

        self.face.coordIndex.set1Value(8,3)
        self.face.coordIndex.set1Value(9,4)
        self.face.coordIndex.set1Value(10,2)
        self.face.coordIndex.set1Value(11,-1)

        self.face.coordIndex.set1Value(12,4)
        self.face.coordIndex.set1Value(13,0)
        self.face.coordIndex.set1Value(14,2)
        self.face.coordIndex.set1Value(15,-1)

        self.face.coordIndex.set1Value(16,1)
        self.face.coordIndex.set1Value(17,0)
        self.face.coordIndex.set1Value(18,5)
        self.face.coordIndex.set1Value(19,-1)

        self.face.coordIndex.set1Value(20,3)
        self.face.coordIndex.set1Value(21,1)
        self.face.coordIndex.set1Value(22,5)
        self.face.coordIndex.set1Value(23,-1)

        self.face.coordIndex.set1Value(24,4)
        self.face.coordIndex.set1Value(25,3)
        self.face.coordIndex.set1Value(26,5)
        self.face.coordIndex.set1Value(27,-1)

        self.face.coordIndex.set1Value(28,0)
        self.face.coordIndex.set1Value(29,4)
        self.face.coordIndex.set1Value(30,5)
        self.face.coordIndex.set1Value(31,-1)

  def getDisplayModes(self,obj):
     "Return a list of display modes."
     modes=[]
     modes.append("Shaded")
     modes.append("Wireframe")
     return modes

  def getDefaultDisplayMode(self):
     "Return the name of the default display mode. It must be defined in getDisplayModes."
     return "Shaded"

  def setDisplayMode(self,mode):
     return mode

  def onChanged(self, vp, prop):
     "Here we can do something when a single property got changed"
     FreeCAD.Console.PrintMessage("Change property: " + str(prop) + "\n")
     if prop == "Color":
        c = vp.getPropertyByName("Color")
        self.color.rgb.setValue(c[0],c[1],c[2])

  def getIcon(self):
     return """
        /* XPM */
        static const char * ViewProviderBox_xpm[] = {
        "16 16 6 1",
        "    c None",
        ".   c #141010",
        "+   c #615BD2",
        "@   c #C39D55",
        "#   c #000000",
        "$   c #57C355",
        "        ........",
        "   ......++..+..",
        "   .@@@@.++..++.",
        "   .@@@@.++..++.",
        "   .@@  .++++++.",
        "  ..@@  .++..++.",
        "###@@@@ .++..++.",
        "##$.@@$#.++++++.",
        "#$#$.$$$........",
        "#$$#######      ",
        "#$$#$$$$$#      ",
        "#$$#$$$$$#      ",
        "#$$#$$$$$#      ",
        " #$#$$$$$#      ",
        "  ##$$$$$#      ",
        "   #######      "};
        """

  def dumps(self):
     return None

  def loads(self,state):
     return None

<translate>

Finally, once our object and its viewobject are defined, we just need to call them (The Octahedron class and viewprovider class code could be copied in the FreeCAD python console directly):

</translate>

FreeCAD.newDocument()
a=FreeCAD.ActiveDocument.addObject("App::FeaturePython","Octahedron")
Octahedron(a)
ViewProviderOctahedron(a.ViewObject)

<translate>

Making objects selectable

If you want to make your object selectable, or at least part of it, by clicking on it in the viewport, you must include its coin geometry inside a SoFCSelection node. If your object has complex representation, with widgets, annotations, etc, you might want to include only a part of it in a SoFCSelection. Everything that is a SoFCSelection is constantly scanned by FreeCAD to detect selection/preselection, so it makes sense try not to overload it with unneeded scanning.

Once the parts of the scenegraph that are to be selectable are inside SoFCSelection nodes, you then need to provide two methods to handle the selection path. The selection path can take the form of a string giving the names of each element in the path, or of an array of scenegraph objects. The two methods you provide are getDetailPath, which converts from a string path to an array of scenegraph objects, and getElementPicked, which takes an element which has been clicked on in the scenegraph and returns its string name (note, not its string path).

Here is the molecule example above, adapted to make the elements of the molecule selectable:

</translate>

class Molecule:
    def __init__(self, obj):
        ''' Add two point properties '''
        obj.addProperty("App::PropertyVector","p1","Line","Start point")
        obj.addProperty("App::PropertyVector","p2","Line","End point").p2=FreeCAD.Vector(5,0,0)

        obj.Proxy = self

    def onChanged(self, fp, prop):
        if prop == "p1" or prop == "p2":
            ''' Print the name of the property that has changed '''
            fp.Shape = Part.makeLine(fp.p1,fp.p2)

    def execute(self, fp):
        ''' Print a short message when doing a recomputation, this method is mandatory '''
        fp.Shape = Part.makeLine(fp.p1,fp.p2)

class ViewProviderMolecule:
    def __init__(self, obj):
        ''' Set this object to the proxy object of the actual view provider '''
        obj.Proxy = self
        self.ViewObject = obj
        sep1=coin.SoSeparator()
        sel1 = coin.SoType.fromName('SoFCSelection').createInstance()
        # sel1.policy.setValue(coin.SoSelection.SHIFT)
        sel1.ref()
        sep1.addChild(sel1)
        self.trl1=coin.SoTranslation()
        sel1.addChild(self.trl1)
        sel1.addChild(coin.SoSphere())
        sep2=coin.SoSeparator()
        sel2 = coin.SoType.fromName('SoFCSelection').createInstance()
        sel2.ref()
        sep2.addChild(sel2)
        self.trl2=coin.SoTranslation()
        sel2.addChild(self.trl2)
        sel2.addChild(coin.SoSphere())
        obj.RootNode.addChild(sep1)
        obj.RootNode.addChild(sep2)
        self.updateData(obj.Object, 'p2')
        self.sel1 = sel1
        self.sel2 = sel2

    def getDetailPath(self, subname, path, append):
        vobj = self.ViewObject
        if append:
            path.append(vobj.RootNode)
            path.append(vobj.SwitchNode)

            mode = vobj.SwitchNode.whichChild.getValue()
            if mode >= 0:
                mode = vobj.SwitchNode.getChild(mode)
                path.append(mode)
                sub = Part.splitSubname(subname)[-1]
                if sub == 'Atom1':
                    path.append(self.sel1)
                elif sub == 'Atom2':
                    path.append(self.sel2)
                else:
                    path.append(mode.getChild(0))
        return True

    def getElementPicked(self, pp):
        path = pp.getPath()
        if path.findNode(self.sel1) >= 0:
            return 'Atom1'
        if path.findNode(self.sel2) >= 0:
            return 'Atom2'
        raise NotImplementedError

    def updateData(self, fp, prop):
        "If a property of the handled feature has changed we have the chance to handle this here"
        # fp is the handled feature, prop is the name of the property that has changed
        if prop == "p1":
            p = fp.getPropertyByName("p1")
            self.trl1.translation=(p.x,p.y,p.z)
        elif prop == "p2":
            p = fp.getPropertyByName("p2")
            self.trl2.translation=(p.x,p.y,p.z)

    def dumps(self):
        return None

    def loads(self,state):
        return None

def makeMolecule():
    FreeCAD.newDocument()
    a=FreeCAD.ActiveDocument.addObject("Part::FeaturePython","Molecule")
    Molecule(a)
    ViewProviderMolecule(a.ViewObject)
    FreeCAD.ActiveDocument.recompute()

<translate>

Working with simple shapes

If your parametric object simply outputs a shape, you don't need to use a view provider object. The shape will be displayed using FreeCAD's standard shape representation:

</translate>

import FreeCAD as App
import FreeCADGui
import FreeCAD
import Part
class Line:
    def __init__(self, obj):
        '''"App two point properties" '''
        obj.addProperty("App::PropertyVector","p1","Line","Start point")
        obj.addProperty("App::PropertyVector","p2","Line","End point").p2=FreeCAD.Vector(1,0,0)
        obj.Proxy = self

    def execute(self, fp):
        '''"Print a short message when doing a recomputation, this method is mandatory" '''
        fp.Shape = Part.makeLine(fp.p1,fp.p2)

a=FreeCAD.ActiveDocument.addObject("Part::FeaturePython","Line")
Line(a)
a.ViewObject.Proxy=0 # just set it to something different from None (this assignment is needed to run an internal notification)
FreeCAD.ActiveDocument.recompute()

<translate>

Same code with use ViewProviderLine

</translate>

import FreeCAD as App
import FreeCADGui
import FreeCAD
import Part

class Line:
    def __init__(self, obj):
         '''"App two point properties" '''
         obj.addProperty("App::PropertyVector","p1","Line","Start point")
         obj.addProperty("App::PropertyVector","p2","Line","End point").p2=FreeCAD.Vector(100,0,0)
         obj.Proxy = self

    def execute(self, fp):
        '''"Print a short message when doing a recomputation, this method is mandatory" '''
        fp.Shape = Part.makeLine(fp.p1,fp.p2)

class ViewProviderLine:
   def __init__(self, obj):
      ''' Set this object to the proxy object of the actual view provider '''
      obj.Proxy = self

   def getDefaultDisplayMode(self):
      ''' Return the name of the default display mode. It must be defined in getDisplayModes. '''
      return "Flat Lines"

a=FreeCAD.ActiveDocument.addObject("Part::FeaturePython","Line")
Line(a)
ViewProviderLine(a.ViewObject)
App.ActiveDocument.recompute()

<translate>

Scenegraph Structure

You may have noticed that the examples above construct their scenegraphs in slightly different ways. Some use obj.addDisplayMode(node, "modename") while others use obj.SwitchNode.getChild(x).addChild(y).

Each feature in a FreeCAD document is based the following scenegraph structure:

</translate>

RootNode
 \- SwitchNode
     \- Shaded
      - Wireframe
      - etc

<translate>

The SwitchNode displays only one of its children, depending on which display mode is selection in FreeCAD.

The examples which use addDisplayMode are constructing their scenegraphs solely out of coin3d scenegraph elements. Under the covers, addDisplayMode adds a new child to the SwitchNode; the name of that node will match the display mode it was passed.

The examples which use SwitchNode.getChild(x).addChild also construct part of their geometry using functions from the Part workbench, such as fp.Shape = Part.makeLine(fp.p1,fp.p2). This constructs the different display mode scenegraphs under the SwitchNode; when we later come to add coin3d elements to the scenegraph, we need to add them to the existing display mode scenegraphs using addChild rather than creating a new child of the SwitchNode.

When using addDisplayMode() to add geometry to the scenegraph, each display mode should have its own node which is passed to addDisplayMode(); don't reuse the same node for this. Doing so will confuse the selection mechanism. It's okay if each display mode's node has the same geometry nodes added below it, just the root of each display mode needs to be distinct.

Here is the above molecule example, adapted to be drawn only with Coin3D scenegraph objects instead of using objects from the Part workbench:

</translate>

import Part
from pivy import coin

class Molecule:
    def __init__(self, obj):
        ''' Add two point properties '''
        obj.addProperty("App::PropertyVector","p1","Line","Start point")
        obj.addProperty("App::PropertyVector","p2","Line","End point").p2=FreeCAD.Vector(5,0,0)

        obj.Proxy = self

    def onChanged(self, fp, prop):
        pass

    def execute(self, fp):
        ''' Print a short message when doing a recomputation, this method is mandatory '''
        pass

class ViewProviderMolecule:
    def __init__(self, obj):
        ''' Set this object to the proxy object of the actual view provider '''
        self.constructed = False
        obj.Proxy = self
        self.ViewObject = obj

    def attach(self, obj):
        material = coin.SoMaterial()
        material.diffuseColor = (1.0, 0.0, 0.0)
        material.emissiveColor = (1.0, 0.0, 0.0)
        drawStyle = coin.SoDrawStyle()
        drawStyle.pointSize.setValue(10)
        drawStyle.style = coin.SoDrawStyle.LINES
        wireframe = coin.SoGroup()
        shaded = coin.SoGroup()
        self.wireframe = wireframe
        self.shaded = shaded

        self.coords = coin.SoCoordinate3()
        self.coords.point.setValues(0, 2, [FreeCAD.Vector(0, 0, 0), FreeCAD.Vector(1, 0, 0)])
        wireframe += self.coords
        wireframe += drawStyle
        wireframe += material
        shaded += self.coords
        shaded += drawStyle
        shaded += material

        g = coin.SoGroup()
        sel1 = coin.SoType.fromName('SoFCSelection').createInstance()
        sel1.style = 'EMISSIVE_DIFFUSE'
        p1 = coin.SoType.fromName('SoIndexedPointSet').createInstance()
        p1.coordIndex.set1Value(0, 0)
        sel1 += p1
        g += sel1
        wireframe += g
        shaded += g

        g = coin.SoGroup()
        sel2 = coin.SoType.fromName('SoFCSelection').createInstance()
        sel2.style = 'EMISSIVE_DIFFUSE'
        p2 = coin.SoType.fromName('SoIndexedPointSet').createInstance()
        p2.coordIndex.set1Value(0, 1)
        sel2 += p2
        g += sel2
        wireframe += g
        shaded += g

        g = coin.SoGroup()
        sel3 = coin.SoType.fromName('SoFCSelection').createInstance()
        sel3.style = 'EMISSIVE_DIFFUSE'
        p3 = coin.SoType.fromName('SoIndexedLineSet').createInstance()
        p3.coordIndex.setValues(0, 2, [0, 1])
        sel3 += p3
        g += sel3
        wireframe += g
        shaded += g

        obj.addDisplayMode(wireframe, 'Wireframe')
        obj.addDisplayMode(shaded, 'Shaded')

        self.sel1 = sel1
        self.sel2 = sel2
        self.sel3 = sel3
        self.constructed = True
        self.updateData(obj.Object, 'p2')

    def getDetailPath(self, subname, path, append):
        vobj = self.ViewObject
        if append:
            path.append(vobj.RootNode)
            path.append(vobj.SwitchNode)

            mode = vobj.SwitchNode.whichChild.getValue()
            FreeCAD.Console.PrintWarning("getDetailPath: mode {} is active\n".format(mode))
            if mode >= 0:
                mode = vobj.SwitchNode.getChild(mode)
                path.append(mode)
                sub = Part.splitSubname(subname)[-1]
                print(sub)
                if sub == 'Atom1':
                    path.append(self.sel1)
                elif sub == 'Atom2':
                    path.append(self.sel2)
                elif sub == 'Line':
                    path.append(self.sel3)
                else:
                    path.append(mode.getChild(0))
        return True

    def getElementPicked(self, pp):
        path = pp.getPath()
        if path.findNode(self.sel1) >= 0:
            return 'Atom1'
        if path.findNode(self.sel2) >= 0:
            return 'Atom2'
        if path.findNode(self.sel3) >= 0:
            return 'Line'
        raise NotImplementedError

    def updateData(self, fp, prop):
        "If a property of the handled feature has changed we have the chance to handle this here"
        # fp is the handled feature, prop is the name of the property that has changed
        if not self.constructed:
            return
        if prop == "p1":
            p = fp.getPropertyByName("p1")
            self.coords.point.set1Value(0, p)
        elif prop == "p2":
            p = fp.getPropertyByName("p2")
            self.coords.point.set1Value(1, p)

    def getDisplayModes(self, obj):
        return ['Wireframe', 'Shaded']

    def getDefaultDisplayMode(self):
        return 'Shaded'

    def setDisplayMode(self, mode):
        return mode

    def dumps(self):
        return None

    def loads(self,state):
        return None

def makeMolecule():
    FreeCAD.newDocument()
    a=FreeCAD.ActiveDocument.addObject("App::FeaturePython","Molecule")
    Molecule(a)
    b=ViewProviderMolecule(a.ViewObject)
    a.touch()
    FreeCAD.ActiveDocument.recompute()
    return a,b

a,b = makeMolecule()

<translate>

Part Design scripted objects

When making scripted objects in Part Design the process is similar to the scripted objects discussed above, but with a few additional considerations. We must handle 2 shape properties, one for the shape we see in the 3D view and another for the shape used by the pattern tools, such as polar pattern features. The object shapes also needs to be fused to any existing material already in the Body (or cut from it in the case of Subtractive features). And we must account for the placement and attachment of our objects a little bit differently.

Part Design scripted solid object features should be based on either PartDesign::FeaturePython, PartDesign::FeatureAdditivePython, or PartDesign::FeatureSubtractivePython rather than Part::FeaturePython. Only the Additive and Subtractive variants can be used in pattern features, and if based on Part::FeaturePython when the user drops the object into a Part Design Body it becomes a BaseFeature rather than being treated by the Body as a native Part Design object. Note: all of these are expected to be solids, so if you are making a non-solid feature it should be based on Part::FeaturePython or else the next feature in the tree will attempt to fuse to as a solid and it will fail.

Here is a simple example of making a Tube primitive, similar to the Tube primitive in Part Workbench except this one will be a Part Design solid feature object. For this we will 2 separate files: pdtube.FCMacro and pdtube.py. The .FCMacro file will be executed by the user to create the object. The .py file will hold the class definitions, imported by the .FCMacro. The reason for doing it this way is to maintain the parametric nature of the object after restarting FreeCAD and opening a document containing one of our Tubes.

First, the class definition file:

</translate>

# -*- coding: utf-8 -*-
#classes should go in pdtube.py
import FreeCAD, FreeCADGui, Part
class PDTube:
    def __init__(self,obj):
        obj.addProperty("App::PropertyLength","Radius1","Tube","Radius1").Radius1 = 5
        obj.addProperty("App::PropertyLength","Radius2","Tube","Radius2").Radius2 = 10
        obj.addProperty("App::PropertyLength","Height","Tube","Height of tube").Height = 10
        self.makeAttachable(obj)
        obj.Proxy = self

    def makeAttachable(self, obj):

        if int(FreeCAD.Version()[1]) >= 19:
            obj.addExtension('Part::AttachExtensionPython')
        else:
            obj.addExtension('Part::AttachExtensionPython', obj)

        obj.setEditorMode('Placement', 0) #non-readonly non-hidden

    def execute(self,fp):
        outer_cylinder = Part.makeCylinder(fp.Radius2, fp.Height)
        inner_cylinder = Part.makeCylinder(fp.Radius1, fp.Height)
        if fp.Radius1 == fp.Radius2: #just make cylinder
            tube_shape = outer_cylinder
        elif fp.Radius1 < fp.Radius2:
            tube_shape = outer_cylinder.cut(inner_cylinder)
        else: #invert rather than error out
            tube_shape = inner_cylinder.cut(outer_cylinder)

        if not hasattr(fp, "positionBySupport"):
            self.makeAttachable(fp)
        fp.positionBySupport()
        tube_shape.Placement = fp.Placement

        #BaseFeature (shape property of type Part::PropertyPartShape) is provided for us
        #with the PartDesign::FeaturePython and related classes, but it might be empty
        #if our object is the first object in the tree.  it's a good idea to check
        #for its existence in case we want to make type Part::FeaturePython, which won't have it

        if hasattr(fp, "BaseFeature") and fp.BaseFeature != None:
            if "Subtractive" in fp.TypeId:
                full_shape = fp.BaseFeature.Shape.cut(tube_shape)
            else:
                full_shape = fp.BaseFeature.Shape.fuse(tube_shape)
            full_shape.transformShape(fp.Placement.inverse().toMatrix(), True) #borrowed from gears workbench
            fp.Shape = full_shape
        else:
            fp.Shape = tube_shape
        if hasattr(fp,"AddSubShape"): #PartDesign::FeatureAdditivePython and
                                      #PartDesign::FeatureSubtractivePython have this
                                      #property but PartDesign::FeaturePython does not
                                      #It is the shape used for copying in pattern features
                                      #for example in making a polar pattern
            tube_shape.transformShape(fp.Placement.inverse().toMatrix(), True)
            fp.AddSubShape = tube_shape

class PDTubeVP:
    def __init__(self, obj):
        '''Set this object to the proxy object of the actual view provider'''
        obj.Proxy = self

    def attach(self,vobj):
        self.vobj = vobj

    def updateData(self, fp, prop):
        '''If a property of the handled feature has changed we have the chance to handle this here'''
        pass

    def getDisplayModes(self,obj):
        '''Return a list of display modes.'''
        modes=[]
        modes.append("Flat Lines")
        modes.append("Shaded")
        modes.append("Wireframe")
        return modes

    def getDefaultDisplayMode(self):
        '''Return the name of the default display mode. It must be defined in getDisplayModes.'''
        return "Flat Lines"

    def setDisplayMode(self,mode):
        '''Map the display mode defined in attach with those defined in getDisplayModes.\
                Since they have the same names nothing needs to be done. This method is optional'''
        return mode

    def onChanged(self, vp, prop):
        '''Here we can do something when a single property got changed'''
        #FreeCAD.Console.PrintMessage("Change property: " + str(prop) + "\n")
        pass

    def getIcon(self):
        '''Return the icon in XPM format which will appear in the tree view. This method is\
                optional and if not defined a default icon is shown.'''
        return """
            /* XPM */
            static const char * ViewProviderBox_xpm[] = {
            "16 16 6 1",
            "   c None",
            ".  c #141010",
            "+  c #615BD2",
            "@  c #C39D55",
            "#  c #000000",
            "$  c #57C355",
            "        ........",
            "   ......++..+..",
            "   .@@@@.++..++.",
            "   .@@@@.++..++.",
            "   .@@  .++++++.",
            "  ..@@  .++..++.",
            "###@@@@ .++..++.",
            "##$.@@$#.++++++.",
            "#$#$.$$$........",
            "#$$#######      ",
            "#$$#$$$$$#      ",
            "#$$#$$$$$#      ",
            "#$$#$$$$$#      ",
            " #$#$$$$$#      ",
            "  ##$$$$$#      ",
            "   #######      "};
            """

    def dumps(self):
        '''When saving the document this object gets stored using Python's json module.\
                Since we have some un-serializable parts here -- the Coin stuff -- we must define this method\
                to return a tuple of all serializable objects or None.'''
        return None

    def loads(self,state):
        '''When restoring the serialized object from document we have the chance to set some internals here.\
                Since no data were serialized nothing needs to be done here.'''
        return None

<translate>

And now the macro file to create the object:

</translate>

# -*- coding: utf-8 -*-

#pdtube.FCMacro
import pdtube
#above line needed if the class definitions above are place in another file: PDTube.py
#this is needed if the tube object is to remain parametric after restarting FreeCAD and loading
#a document containing the object

body = FreeCADGui.ActiveDocument.ActiveView.getActiveObject("pdbody")
if not body:
    FreeCAD.Console.PrintError("No active body.\n")
else:
    from PySide import QtGui
    window = FreeCADGui.getMainWindow()
    items = ["Additive","Subtractive","Neither additive nor subtractive"]
    item,ok =QtGui.QInputDialog.getItem(window,"Select tube type","Select whether you want additive, subtractive, or neither:",items,0,False)
    if ok:
        if item == items[0]:
            className = "PartDesign::FeatureAdditivePython"
        elif item == items[1]:
            className = "PartDesign::FeatureSubtractivePython"
        else:
            className = "PartDesign::FeaturePython" #not usable in pattern features, such as polar pattern

        tube = FreeCAD.ActiveDocument.addObject(className,"Tube")
        pdtube.PDTube(tube)
        pdtube.PDTubeVP(tube.ViewObject)
        body.addObject(tube) #optionally we can also use body.insertObject() for placing at particular place in tree

<translate>

Available object types

The list of all object types you can create with FreeCAD.ActiveDocument.addObject() can be obtained with FreeCAD.ActiveDocument.supportedTypes(). Only object types with a name ending in Python can be used for scripted objects. These are listed here (for FreeCAD v0.21): </translate>

  • App::DocumentObjectGroupPython
  • App::FeaturePython
  • App::GeometryPython
  • App::LinkElementPython
  • App::LinkGroupPython
  • App::LinkPython
  • App::MaterialObjectPython
  • App::PlacementPython
  • Part::CustomFeaturePython
  • Part::FeaturePython
  • Part::Part2DObjectPython
  • Path::FeatureAreaPython
  • Path::FeatureAreaViewPython
  • Path::FeatureCompoundPython
  • Path::FeaturePython
  • Path::FeatureShapePython
  • Sketcher::SketchObjectPython
  • TechDraw::DrawComplexSectionPython
  • TechDraw::DrawLeaderLinePython
  • TechDraw::DrawPagePython
  • TechDraw::DrawRichAnnoPython
  • TechDraw::DrawTemplatePython
  • TechDraw::DrawTilePython
  • TechDraw::DrawTileWeldPython
  • TechDraw::DrawViewPartPython
  • TechDraw::DrawViewPython
  • TechDraw::DrawViewSectionPython
  • TechDraw::DrawViewSymbolPython
  • TechDraw::DrawWeldSymbolPython

<translate>

Available methods

See FeaturePython methods for the complete reference.

Available properties

Properties are the true building blocks of FeaturePython objects. Through them, you will be able to interact and modify your object. After creating a new FeaturePython object in your document, you can get a list of the available properties:

</translate>

obj = FreeCAD.ActiveDocument.addObject("App::FeaturePython", "Box")
obj.supportedProperties()

<translate>

See FeaturePython Custom Properties for an overview.

When adding properties to your custom objects, take care of this:

  • Do not use characters < or > in the properties descriptions (that would break the xml pieces in the .FCStd file).
  • Properties are stored alphabetically in a .FCStd file. If you have a shape in your properties, any property whose name comes after "Shape" in alphabetic order, will be loaded AFTER the shape, which can cause strange behaviors.

The properties are defined in the PropertyStandard C++ header file.

Property types

By default properties can be updated, but it is possible to make properties read-only, for instance if one wants to show the result of a method. It is also possible to hide a property. The property type can be set using:

</translate>

obj.setEditorMode("MyPropertyName", mode)

<translate>

where mode is a short int that can be set to:

 0 -- default mode, read and write
 1 -- read-only
 2 -- hidden

The mode can also be set using a list of strings, e.g. obj.setEditorMode("Placement", ["ReadOnly", "Hidden"]).

The EditorModes are not set at FreeCAD file reload. This could to be done by the loads function. See http://forum.freecadweb.org/viewtopic.php?f=18&t=13460&start=10#p108072. By using the setEditorMode the properties are only read-only in the Property editor. They can still be changed from Python. To really make them read-only the setting has to be passed directly inside the addProperty function. See http://forum.freecadweb.org/viewtopic.php?f=18&t=13460&start=20#p109709 for an example.

Using the direct setting in the addProperty function, you also have more possibilities. In particular, an interesting one is mark a property as an output property. This way FreeCAD won't mark the feature as touched when changing it (so no need to recompute).

Example of output property (see also https://forum.freecadweb.org/viewtopic.php?t=24928):

</translate>

obj.addProperty("App::PropertyString", "MyCustomProperty", "", "", 8)

<translate>

The property types that can be set at last parameter of the addProperty function are:

  0 -- Prop_None, No special property type
  1 -- Prop_ReadOnly, Property is read-only in the editor
  2 -- Prop_Transient, Property won't be saved to file
  4 -- Prop_Hidden, Property won't appear in the editor
  8 -- Prop_Output, Modified property doesn't touch its parent container
 16 -- Prop_NoRecompute, Modified property doesn't touch its container for recompute
 32 -- Prop_NoPersist, Property won't be saved to file at all

The property types are defined in the PropertyContainer C++ header file.

Available extensions

The list of available extensions can be obtained with grep -RI EXTENSION_PROPERTY_SOURCE_TEMPLATE in the repository of the source code and is given here (for FreeCAD v0.21).

For objects: </translate>

  • App::GeoFeatureGroupExtensionPython
  • App::GroupExtensionPython
  • App::LinkBaseExtensionPython
  • App::LinkExtensionPython
  • App::OriginGroupExtensionPython
  • Part::AttachExtensionPython
  • TechDraw::CosmeticExtensionPython

<translate>

For view objects: </translate>

  • Gui::ViewProviderExtensionPython
  • Gui::ViewProviderGeoFeatureGroupExtensionPython
  • Gui::ViewProviderGroupExtensionPython
  • Gui::ViewProviderOriginGroupExtensionPython
  • PartGui::ViewProviderAttachExtensionPython
  • PartGui::ViewProviderSplineExtensionPython

<translate>

There exist other extensions but they do not work as-is: </translate>

  • App::ExtensionPython
  • TechDrawGui::ViewProviderCosmeticExtensionPython
  • TechDrawGui::ViewProviderDrawingViewExtensionPython
  • TechDrawGui::ViewProviderPageExtensionPython
  • TechDrawGui::ViewProviderTemplateExtensionPython

<translate>

Further information

Additional pages:

Interesting forum threads about scripted objects:

</translate>

<translate>

In addition to the examples presented here have a look at FreeCAD source code src/Mod/TemplatePyMod/FeaturePython.py for more examples.


</translate>

<translate>

</translate>

<translate>

Introduction

FreeCAD can be imported as a Python module in other programs or in a standalone Python console, together with all its modules and components. It's even possible to import the FreeCAD user interface as a python module but with some restrictions indicated in Caveats.

Using FreeCAD without GUI

The first, direct, easy, and useful application you can make of this is to import FreeCAD documents into your program. In the following example, we'll import the Part geometry of a FreeCAD document into blender. Here is the complete script. I hope you'll be impressed by its simplicity: </translate>

FREECADPATH = '/usr/lib/freecad-python3/lib/' # path to your FreeCAD.so or FreeCAD.pyd file,
# for Windows you must either use \\ or / in the path, using a single \ is problematic
# FREECADPATH = 'C:\\FreeCAD\\bin'
import Blender, sys
sys.path.append(FREECADPATH)
 
def import_fcstd(filename):
   try:
       import FreeCAD
   except ValueError:
       Blender.Draw.PupMenu('Error%t|FreeCAD library not found. Please check the FREECADPATH variable in the import script is correct')
   else:
       scene = Blender.Scene.GetCurrent()
       import Part
       doc = FreeCAD.open(filename)
       objects = doc.Objects
       for ob in objects:
           if ob.Type[:4] == 'Part':
               shape = ob.Shape
               if shape.Faces:
                   mesh = Blender.Mesh.New()
                   rawdata = shape.tessellate(1)
                   for v in rawdata[0]:
                       mesh.verts.append((v.x,v.y,v.z))
                   for f in rawdata[1]:
                       mesh.faces.append.append(f)
                   scene.objects.new(mesh,ob.Name)
       Blender.Redraw()

def main():
   Blender.Window.FileSelector(import_fcstd, 'IMPORT FCSTD', 
                        Blender.sys.makename(ext='.fcstd'))    
 
# This lets you import the script without running it
if __name__=='__main__':
   main()

<translate>

The first and important part is to make sure python will find our FreeCAD library. Once it finds it, all FreeCAD modules such as Part (that we'll use as well) will be available automatically. So we simply take the sys.path variable, which is where python searches for modules, and we append the FreeCAD library path. This modification is only temporary, and will be lost when we'll close our python interpreter. An alternate way could be: making a link to your FreeCAD library in one of the python search paths. I stored the path in a constant (FREECADPATH) so it'll be easier for another user of the script to configure it to their own system. For Windows users it is important that the path be specified using \\ or / as separator instead of just \ since it is an escape character.

</translate>

FREECADPATH = 'C:\\FreeCAD\\bin' # path to your FreeCAD.so or FreeCAD.pyd file
import sys
sys.path.append(FREECADPATH)

<translate>

Once we are sure the library is loaded (the try/except sequence), we can now work with FreeCAD, the same way as we would inside FreeCAD's own python interpreter. We open the FreeCAD document that is passed to us by the main() function, and we make a list of its objects. Then, as we chose only to care about Part geometry, we check if the Type property of each object contains "Part", then we tesselate it.

</translate>

import Part
       doc = FreeCAD.open(filename)
       objects = doc.Objects
       for ob in objects:
           if ob.Type[:4] == 'Part':

<translate>

The tesselation produce a list of vertices and a list of faces defined by vertices indexes. This is perfect, since it is exactly the same way as blender defines meshes. So, our task is ridiculously simple, we just add both lists contents to the verts and faces of a blender mesh. When everything is done, we just redraw the screen, and that's it!

</translate>

if ob.Type[:4] == 'Part':
               shape = ob.Shape
               if shape.Faces:
                   mesh = Blender.Mesh.New()
                   rawdata = shape.tessellate(1)
                   for v in rawdata[0]:
                       mesh.verts.append((v.x,v.y,v.z))
                   for f in rawdata[1]:
                       mesh.faces.append.append(f)
                   scene.objects.new(mesh,ob.Name)
       Blender.Redraw()

<translate>

Of course this script is very simple (in fact I made a more advanced FreeCAD to Blender importer), you might want to extend it, for example importing mesh objects too, or importing Part geometry that has no faces, or import other file formats that FreeCAD can read. You might also want to export geometry to a FreeCAD document, which can be done the same way. You might also want to build a dialog, so the user can choose what to import, etc... The beauty of all this actually lies in the fact that you let FreeCAD do the ground work while presenting its results in the program of your choice.

Note: checkout Headless FreeCAD for running FreeCAD without the GUI.

Using FreeCAD with GUI

From version 4.2 on Qt has the intriguing ability to embed Qt-GUI-dependent plugins into non-Qt host applications and share the host's event loop.

Especially, for FreeCAD this means that it can be imported from within another application with its whole user interface where the host application has full control over FreeCAD, then.

The whole python code to achieve that has only two lines

</translate>

import FreeCADGui 
FreeCADGui.showMainWindow()

<translate>

If the host application is based on Qt then this solution should work on all platforms which Qt supports. However, the host should link the same Qt version as FreeCAD because otherwise you could run into unexpected runtime errors.

For non-Qt applications, however, there are a few limitations you must be aware of. This solution probably doesn't work together with all other toolkits. For Windows it works as long as the host application is directly based on Win32 or any other toolkit that internally uses the Win32 API such as wxWidgets, MFC or WinForms. In order to get it working under X11 the host application must link the "glib" library.

Note, for any console application this solution of course doesn't work because there is no event loop running.

Caveats

Although it is possible to import FreeCAD to an external Python interpreter, this is not a common usage scenario and requires some care. Generally, it is better to use the Python included with FreeCAD, run FreeCAD via command line, or as a subprocess. See Start up and Configuration for more on the last two options.

Since the FreeCAD Python module is compiled from C++ (rather than being a pure Python module), it can only be imported from a compatible Python interpreter. Generally this means that the Python interpreter must be compiled with the same C compiler as was used to build FreeCAD. Information about the compiler used to build a Python interpreter (including the one built with FreeCAD) can be found as follows: </translate>

>>> import sys
>>> sys.version
'2.7.13 (default, Dec 17 2016, 23:03:43) \n[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)]'

<translate>

Related


</translate>

<translate>

</translate>

<translate>

Introduction

This page contains examples, pieces, chunks of FreeCAD python code collected from users experiences and discussions on the forums. Read and use it as a start for your own scripts...

Snippets

A typical InitGui.py file

Every module must contain, besides your main module file, an InitGui.py file, responsible for inserting the module in the main Gui. This is an example of a simple one.

</translate>

class ScriptWorkbench (Workbench): 
    MenuText = "Scripts"
    def Initialize(self):
        import Scripts # assuming Scripts.py is your module
        list = ["Script_Cmd"] # That list must contain command names, that can be defined in Scripts.py
        self.appendToolbar("My Scripts",list) 
        
Gui.addWorkbench(ScriptWorkbench())

<translate>

</translate>

наверх

<translate>

A typical module file

This is an example of a main module file, containing everything your module does. It is the Scripts.py file invoked by the previous example. You can have all your custom commands here.

</translate>

import FreeCAD, FreeCADGui 
 
class ScriptCmd: 
   def Activated(self): 
       # Here your write what your ScriptCmd does...
       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())

<translate>

</translate>

наверх

<translate>

Import a new filetype

Making an importer for a new filetype in FreeCAD is easy. FreeCAD doesn't consider that you import data in an opened document, but rather that you simply can directly open the new filetype. So what you need to do is to add the new file extension to FreeCAD's list of known extensions, and write the code that will read the file and create the FreeCAD objects you want:

This line must be added to the InitGui.py file to add the new file extension to the list:

</translate>

# Assumes Import_Ext.py is the file that has the code for opening and reading .ext files
FreeCAD.addImportType("Your new File Type (*.ext)","Import_Ext")

<translate>

Then in the Import_Ext.py file:

</translate>

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

<translate>

To export your document to some new filetype works the same way, except that you use:

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

</translate>

наверх

<translate>

Add a line

A line simply has 2 points.

</translate>

import Part,PartGui 
doc=App.activeDocument() 
# add a line element to the document and set its points 
l=Part.LineSegment()
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()

<translate>

</translate>

наверх

<translate>

Add a polygon

A polygon is simply a set of connected line segments (a polyline in AutoCAD). It doesn't need to be closed.

</translate>

import Part, PartGui 
doc = App.activeDocument()
n = list() 

# create a 3D vector, set its coordinates and add it to the list 
v = App.Vector(0,0,0) 
n.append(v) 
v = App.Vector(10,0,0) 
n.append(v) 
#... repeat for all nodes 

# Create a polygon object and set its nodes 
p = doc.addObject("Part::Polygon","Polygon") 
p.Nodes = n 
doc.recompute()

<translate>

</translate>

наверх

<translate>

Add and remove an object to/from a group

</translate>

doc=App.activeDocument() 
grp=doc.addObject("App::DocumentObjectGroup", "Group") 
lin=doc.addObject("Part::Feature", "Line")
grp.addObject(lin) # adds the lin object to the group grp
grp.removeObject(lin) # removes the lin object from the group grp

<translate>

Note: You can even add other groups to a group...

</translate>

наверх

<translate>

Add a Mesh

</translate>

import Mesh
doc=App.activeDocument()
# create a new empty mesh
m = Mesh.Mesh()
# build up box out of 12 facets
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)
# scale to a edge langth of 100
m.scale(100.0)
# add the mesh to the active document
me=doc.addObject("Mesh::Feature","Cube")
me.Mesh=m

<translate>

</translate>

наверх

<translate>

Add an arc or a circle

</translate>

import Part
doc = App.activeDocument()
c = Part.Circle() 
c.Radius=10.0  
f = doc.addObject("Part::Feature", "Circle") # create a document with a circle feature 
f.Shape = c.toShape() # Assign the circle shape to the shape property 
doc.recompute()

<translate>

</translate>

наверх

<translate>

Access and change the representation of an object

Each object in a FreeCAD document has an associated view representation object that stores all the parameters that define how that object appears: i.e. color, linewidth, etc... See also List the components of an object snippet below

</translate>

gad = Gui.activeDocument() # access the active document containing all 
                           # view representations of the features in the
                           # corresponding App document 

v = gad.getObject("Cube")  # access the view representation to the Mesh feature 'Cube' 
v.ShapeColor               # prints the color to the console 
v.ShapeColor=(1.0,1.0,1.0) # sets the shape color to white

<translate>

</translate>

наверх

<translate>

Replace the form of mouse with one image

</translate>

import PySide2
from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtWidgets import QApplication
from PySide2.QtGui import QColor, QPixmap, QImage, QPainter, QCursor
from PySide2.QtCore import Qt

myImage = QtGui.QPixmap("Complete_Path_to_image.bmp")
cursor = QtGui.QCursor(myImage)
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(cursor))

<translate>

</translate>

наверх

<translate>

Replace the form of mouse with one image (cross) include

The image is created by Gimp exported in a .XPM file. Copy and use the code between the bracket "{" code to copy "}"

</translate>

import PySide2
from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtWidgets import QApplication
from PySide2.QtGui import QColor, QPixmap, QImage, QPainter, QCursor
from PySide2.QtCore import Qt

cross32x32Icon = [
"32 32 2 1",
" 	c None",
".	c #FF0000",
"                .               ",
"                .               ",
"                .               ",
"                .               ",
"                .               ",
"                .               ",
"                .               ",
"                .               ",
"                .               ",
"                .               ",
"                .               ",
"                .               ",
"                .               ",
"                .               ",
"                .               ",
"                                ",
"............... . ..............",
"                                ",
"                .               ",
"                .               ",
"                .               ",
"                .               ",
"                .               ",
"                .               ",
"                .               ",
"                .               ",
"                .               ",
"                .               ",
"                .               ",
"                .               ",
"                .               ",
"                .               "
]

myImage = QtGui.QPixmap(cross32x32Icon)
cursor = QtGui.QCursor(myImage)
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(cursor))

<translate>

</translate>

наверх

<translate>

Observe camera change in the 3D viewer via Python

This can be done adding a Node sensor to the camera:

</translate>

from pivy import coin
def callback(*args):
    cam, sensor = args
    print()
    print("Cam position : {}".format(cam.position.getValue().getValue()))
    print("Cam rotation : {}".format(cam.orientation.getValue().getValue()))

camera_node = Gui.ActiveDocument.ActiveView.getCameraNode()
node_sensor = coin.SoNodeSensor(callback, camera_node)
node_sensor.attach(camera_node)

<translate>

</translate>

наверх

<translate>

Observe mouse events in the 3D viewer via Python

The Inventor framework allows to add one or more callback nodes to the scenegraph of the viewer. By default in FreeCAD one callback node is installed per viewer which allows to add global or static C++ functions. In the appropriate Python binding some methods are provided to make use of this technique from within Python code.

</translate>

App.newDocument()
v=Gui.activeDocument().activeView()
 
#This class logs any mouse button events. As the registered callback function fires twice for 'down' and
#'up' events we need a boolean flag to handle this.
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[1])+")\n")
       
o = ViewObserver()
c = v.addEventCallback("SoMouseButtonEvent",o.logPosition)

<translate>


Now, pick somewhere on the area in the 3D viewer and observe the messages in the output window. To finish the observation just call

</translate>

v.removeEventCallback("SoMouseButtonEvent",c)

<translate>

The following event types are supported

  • SoEvent -- all kind of events
  • SoButtonEvent -- all mouse button and key events
  • SoLocation2Event -- 2D movement events (normally mouse movements)
  • SoMotion3Event -- 3D movement events (normally spaceball)
  • SoKeyboardEvent -- key down and up events
  • SoMouseButtonEvent -- mouse button down and up events
  • SoSpaceballButtonEvent -- spaceball button down and up events

The Python function that can be registered with addEventCallback() expects a dictionary. Depending on the watched event the dictionary can contain different keys.

For all events it has the keys:

  • Type -- the name of the event type i.e. SoMouseEvent, SoLocation2Event, ...
  • Time -- the current time as string
  • Position -- a tuple of two integers, mouse position
  • ShiftDown -- a boolean, true if Shift was pressed otherwise false
  • CtrlDown -- a boolean, true if Ctrl was pressed otherwise false
  • AltDown -- a boolean, true if Alt was pressed otherwise false

For all button events, i.e. keyboard, mouse or spaceball events

  • State -- A string 'UP' if the button was up, 'DOWN' if it was down or 'UNKNOWN' for all other cases

For keyboard events:

  • Key -- a character of the pressed key

For mouse button event

  • Button -- The pressed button, could be BUTTON1, ..., BUTTON5 or ANY

For spaceball events:

  • Button -- The pressed button, could be BUTTON1, ..., BUTTON7 or ANY

And finally motion events:

  • Translation -- a tuple of three floats
  • Rotation -- a quaternion for the rotation, i.e. a tuple of four floats

</translate>

наверх

<translate>

Display keys pressed and Events command

This macro displays in the report view the keys pressed and all events command

</translate>

App.newDocument()
v=Gui.activeDocument().activeView()
class ViewObserver:
   def logPosition(self, info):
       try:
           down = (info["Key"])
           FreeCAD.Console.PrintMessage(str(down)+"\n") # here the character pressed
           FreeCAD.Console.PrintMessage(str(info)+"\n") # list all events command
           FreeCAD.Console.PrintMessage("_______________________________________"+"\n")
       except Exception:
           None
 
o = ViewObserver()
c = v.addEventCallback("SoEvent",o.logPosition)

#v.removeEventCallback("SoEvent",c) # remove ViewObserver

<translate>

</translate>

наверх

<translate>

Manipulate the scenegraph in Python

It is also possible to get and change the scenegraph in Python, with the 'pivy' module -- a Python binding for Coin.

</translate>

from pivy.coin import *                # load the pivy module
view = Gui.ActiveDocument.ActiveView   # get the active viewer
root = view.getSceneGraph()            # the root is an SoSeparator node
root.addChild(SoCube())
view.fitAll()

<translate>

The Python API of pivy is created by using the tool SWIG. As we use in FreeCAD some self-written nodes you cannot create them directly in Python. However, it is possible to create a node by its internal name. An instance of the type 'SoFCSelection' can be created with

</translate>

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

<translate>

</translate>

наверх

<translate>

Add and remove objects to/from the scenegraph

Adding new nodes to the scenegraph can be done this way. Take care of always adding a SoSeparator to contain the geometry, coordinates and material info of a same object. The following example adds a red line from (0,0,0) to (10,0,0):

</translate>

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)

<translate>

To remove it, simply issue: </translate>

sg.removeChild(no)

<translate>

</translate>

наверх

<translate> </translate>

<translate>

Save the sceneGraph in 3 series of 36 files

View the code snippet by expanding this section

</translate>
<translate>

</translate>

import math
import time
from FreeCAD import Base
from pivy import coin

size=(1000,1000)
dirname = "C:/Temp/animation/"
steps=36
angle=2*math.pi/steps

matX=Base.Matrix()
matX.rotateX(angle)
stepsX=Base.Placement(matX).Rotation

matY=Base.Matrix()
matY.rotateY(angle)
stepsY=Base.Placement(matY).Rotation

matZ=Base.Matrix()
matZ.rotateZ(angle)
stepsZ=Base.Placement(matZ).Rotation

view=Gui.ActiveDocument.ActiveView
cam=view.getCameraNode()
rotCamera=Base.Rotation(*cam.orientation.getValue().getValue())

# this sets the lookat point to the center of circumsphere of the global bounding box
view.fitAll()

# the camera's position, i.e. the user's eye point
position=Base.Vector(*cam.position.getValue().getValue())
distance=cam.focalDistance.getValue()

# view direction
vec=rotCamera.multVec(Base.Vector(0,0,-1))

# this is the point on the screen the camera looks at
# when rotating the camera we should make this point fix
lookat=position+vec*distance

# around x axis
for i in range(steps):
    rotCamera=stepsX.multiply(rotCamera)
    cam.orientation.setValue(*rotCamera.Q)
    vec=rotCamera.multVec(Base.Vector(0,0,-1))
    pos=lookat-vec*distance
    cam.position.setValue(pos.x,pos.y,pos.z)
    Gui.updateGui()
    time.sleep(0.3)
    view.saveImage(dirname+"x-%d.png" % i,*size)

# around y axis
for i in range(steps):
    rotCamera=stepsY.multiply(rotCamera)
    cam.orientation.setValue(*rotCamera.Q)
    vec=rotCamera.multVec(Base.Vector(0,0,-1))
    pos=lookat-vec*distance
    cam.position.setValue(pos.x,pos.y,pos.z)
    Gui.updateGui()
    time.sleep(0.3)
    view.saveImage(dirname+"y-%d.png" % i,*size)

# around z axis
for i in range(steps):
    rotCamera=stepsZ.multiply(rotCamera)
    cam.orientation.setValue(*rotCamera.Q)
    vec=rotCamera.multVec(Base.Vector(0,0,-1))
    pos=lookat-vec*distance
    cam.position.setValue(pos.x,pos.y,pos.z)
    Gui.updateGui()
    time.sleep(0.3)
    view.saveImage(dirname+"z-%d.png" % i,*size)

<translate>

</translate>

наверх

<translate>

Add custom widgets to the interface

You can create custom widgets with Qt designer, transform them into a python script, and then load them into the FreeCAD interface with PySide.

The python code produced by the Ui python compiler (the tool that converts qt-designer .ui files into python code) generally looks like this (it is simple, you can also code it directly in python):

</translate>

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())) # sets size of the widget
 
        self.label = QtGui.QLabel(myWidget) # creates a label
        self.label.setGeometry(QtCore.QRect(50,50,200,24)) # sets its size
        self.label.setObjectName("label") # sets its name, so it can be found by name

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

<translate>

Then, all you need to do is to create a reference to the FreeCAD Qt window, insert a custom widget into it, and "transform" this widget into yours with the Ui code we just made:

</translate>

app = QtGui.qApp
FCmw = app.activeWindow() # the active qt window, = the freecad window since we are inside it
# FCmw = FreeCADGui.getMainWindow() # use this line if the 'addDockWidget' error is declared
myNewFreeCADWidget = QtGui.QDockWidget() # create a new dckwidget
myNewFreeCADWidget.ui = myWidget_Ui() # load the Ui script
myNewFreeCADWidget.ui.setupUi(myNewFreeCADWidget) # setup the ui
FCmw.addDockWidget(QtCore.Qt.RightDockWidgetArea,myNewFreeCADWidget) # add the widget to the main window

<translate>

</translate>

наверх

<translate>

Add a Tab to the Combo View

The following code allows you to add a tab to the Combo view, separate from the preexisting "Model" and "Tasks" tabs. It also uses the uic module to load an UI file directly in that tab.

</translate>

# create new Tab in ComboView
from PySide import QtGui,QtCore
#from PySide import uic

def getMainWindow():
   "returns the main window"
   # using QtGui.qApp.activeWindow() isn't very reliable because if another
   # widget than the mainwindow is active (e.g. a dialog) the wrong widget is
   # returned
   toplevel = QtGui.qApp.topLevelWidgets()
   for i in toplevel:
       if i.metaObject().className() == "Gui::MainWindow":
           return i
   raise Exception("No main window found")

def getComboView(mw):
   dw=mw.findChildren(QtGui.QDockWidget)
   for i in dw:
       if str(i.objectName()) == "Combo View":
           return i.findChild(QtGui.QTabWidget)
       elif str(i.objectName()) == "Python Console":
           return i.findChild(QtGui.QTabWidget)
   raise Exception ("No tab widget found")

mw = getMainWindow()
tab = getComboView(getMainWindow())
tab2=QtGui.QDialog()
tab.addTab(tab2,"A Special Tab")

#uic.loadUi("/myTaskPanelforTabs.ui",tab2)
tab2.show()
#tab.removeTab(2)

<translate>

</translate>

наверх

<translate>

Enable or disable a window

This script give the ability to manipulate the UI from the Python console to show/hide different components in the FreeCAD interface such as:

</translate>

from PySide import QtGui
mw = FreeCADGui.getMainWindow()
dws = mw.findChildren(QtGui.QDockWidget)

# objectName may be :
# "Report view"
# "Tree view"
# "Property view"
# "Selection view"
# "Combo View"
# "Python console"
# "draftToolbar"

for i in dws:
  if i.objectName() == "Report view":
    dw = i
    break

va = dw.toggleViewAction()
va.setChecked(True)        # True or False
dw.setVisible(True)        # True or False

<translate>

</translate>

наверх

<translate>

Open a custom webpage

</translate>

import WebGui
WebGui.openBrowser("http://www.example.com")

<translate>

</translate>

наверх

<translate>

Get the HTML contents of an opened webpage

</translate>

from PySide import QtGui,QtWebKit
a = QtGui.qApp
mw = a.activeWindow()
v = mw.findChild(QtWebKit.QWebFrame)
html = unicode(v.toHtml())
print( html)

<translate>

</translate>

наверх

<translate>

Retrieve the coordinates of 3 selected points or objects

</translate>

# -*- coding: utf-8 -*-
# the line above to put the accentuated in the remarks
# If this line is missing, an error will be returned
# extract and use the coordinates of 3 objects selected
import Part, FreeCAD, math, PartGui, FreeCADGui
from FreeCAD import Base, Console
sel = FreeCADGui.Selection.getSelection() # " sel " contains the items selected
if len(sel)!=3 :
  # If there are no 3 objects selected, an error is displayed in the report view
  # The \r and \n at the end of line mean return and the newline CR + LF.
  Console.PrintError("Select 3 points exactly\r\n")
else :
  points=[]
  for obj in sel:
    points.append(obj.Shape.BoundBox.Center)

  for pt in points:
    # display of the coordinates in the report view
    Console.PrintMessage(str(pt.x)+"\r\n")
    Console.PrintMessage(str(pt.y)+"\r\n")
    Console.PrintMessage(str(pt.z)+"\r\n")

  Console.PrintMessage(str(pt[1]) + "\r\n")

<translate>

</translate>

наверх

<translate>

List all objects

</translate>

# -*- coding: utf-8 -*-
import FreeCAD,Draft
# List all objects of the document
doc = FreeCAD.ActiveDocument
objs = FreeCAD.ActiveDocument.Objects
#App.Console.PrintMessage(str(objs) + "\n")
#App.Console.PrintMessage(str(len(FreeCAD.ActiveDocument.Objects)) + " Objects"  + "\n")

for obj in objs:
    a = obj.Name                                             # list the Name  of the object  (not modifiable)
    b = obj.Label                                            # list the Label of the object  (modifiable)
    try:
        c = obj.LabelText                                    # list the LabeText of the text (modifiable)
        App.Console.PrintMessage(str(a) +" "+ str(b) +" "+ str(c) + "\n") # Displays the Name the Label and the text
    except:
        App.Console.PrintMessage(str(a) +" "+ str(b) + "\n") # Displays the Name and the Label of the object

#doc.removeObject("Box") # Clears the designated object

<translate>

</translate>

наверх

<translate>

List the dimensions of an object, given its name

</translate>

for edge in FreeCAD.ActiveDocument.MyObjectName.Shape.Edges: # replace "MyObjectName" for list
    print( edge.Length)

<translate>

</translate>

наверх

<translate>

Function resident with the mouse click action

Here with SelObserver on a object select

</translate>

# -*- coding: utf-8 -*-
# causes an action to the mouse click on an object
# This function remains resident (in memory) with the function "addObserver(s)"
# "removeObserver(s) # Uninstalls the resident function
class SelObserver:
    def setPreselection(self,doc,obj,sub):                # Preselection object
        App.Console.PrintMessage(str(sub)+ "\n")          # The part of the object name

    def addSelection(self,doc,obj,sub,pnt):               # Selection object
        App.Console.PrintMessage("addSelection"+ "\n")
        App.Console.PrintMessage(str(doc)+ "\n")          # Name of the document
        App.Console.PrintMessage(str(obj)+ "\n")          # Name of the object
        App.Console.PrintMessage(str(sub)+ "\n")          # The part of the object name
        App.Console.PrintMessage(str(pnt)+ "\n")          # Coordinates of the object
        App.Console.PrintMessage("______"+ "\n")

    def removeSelection(self,doc,obj,sub):                # Remove the selection
        App.Console.PrintMessage("removeSelection"+ "\n")

    def setSelection(self,doc):                           # Set selection
        App.Console.PrintMessage("setSelection"+ "\n")

    def clearSelection(self,doc):                         # If click on the screen, clear the selection
        App.Console.PrintMessage("clearSelection"+ "\n")  # If click on another object, clear the previous object
s =SelObserver()
FreeCADGui.Selection.addObserver(s)                       # install the function mode resident
#FreeCADGui.Selection.removeObserver(s)                   # Uninstall the resident function

<translate>

Other example with ViewObserver on a object select or view

</translate>

App.newDocument()
v=Gui.activeDocument().activeView()
 
#This class logs any mouse button events. As the registered callback function fires twice for 'down' and
#'up' events we need a boolean flag to handle this.
class ViewObserver:
   def __init__(self, view):
       self.view = view
   
   def logPosition(self, info):
       down = (info["State"] == "DOWN")
       pos = info["Position"]
       if (down):
           FreeCAD.Console.PrintMessage("Clicked on position: ("+str(pos[0])+", "+str(pos[1])+")\n")
           pnt = self.view.getPoint(pos)
           FreeCAD.Console.PrintMessage("World coordinates: " + str(pnt) + "\n")
           info = self.view.getObjectInfo(pos)
           FreeCAD.Console.PrintMessage("Object info: " + str(info) + "\n")

o = ViewObserver(v)
c = v.addEventCallback("SoMouseButtonEvent",o.logPosition)

<translate>

</translate>

наверх

<translate>

Display the active document

</translate>

class DocObserver:                      # document Observer
    def slotActivateDocument(self,doc):
        print(doc.Name)

obs=DocObserver()
App.addDocumentObserver(obs)
#App.removeDocumentObserver(obs)                 # desinstalle la fonction residente

<translate>

To remove the observer call:

</translate>

App.removeDocumentObserver(obs)                 # desinstalle la fonction residente

<translate>

</translate>

наверх

<translate>

Find/select all elements below the cursor

</translate>

from pivy import coin
import FreeCADGui

def mouse_over_cb( event_callback):
    event = event_callback.getEvent()
    pos = event.getPosition().getValue()
    listObjects = FreeCADGui.ActiveDocument.ActiveView.getObjectsInfo((int(pos[0]),int(pos[1])))
    obj = []
    if listObjects:
        FreeCAD.Console.PrintMessage("\n *** Objects under mouse pointer ***")
        for o in listObjects:
            label = str(o["Object"])
            if not label in obj:
                obj.append(label)
        FreeCAD.Console.PrintMessage("\n"+str(obj))


view = FreeCADGui.ActiveDocument.ActiveView

mouse_over = view.addEventCallbackPivy( coin.SoLocation2Event.getClassTypeId(), mouse_over_cb )

# to remove Callback :
#view.removeEventCallbackPivy( coin.SoLocation2Event.getClassTypeId(), mouse_over)

####
#The easy way is probably to use FreeCAD's selection.
#FreeCADGui.ActiveDocument.ActiveView.getObjectsInfo(mouse_coords)

####
#you get that kind of result :
#'Document': 'Unnamed', 'Object': 'Box', 'Component': 'Face2', 'y': 8.604081153869629, 'x': 21.0, 'z': 8.553047180175781

####
#You can use this data to add your element to FreeCAD's selection :
#FreeCADGui.Selection.addSelection(FreeCAD.ActiveDocument.Box,'Face2',21.0,8.604081153869629,8.553047180175781)

<translate>

</translate>

наверх

<translate> </translate>

<translate>

List the components of an object

This function list the components of an object and extracts:

  • this object its XYZ coordinates,
  • its edges and their lengths center of mass and coordinates
  • its faces and their center of mass
  • its faces and their surfaces and coordinates
</translate>
<translate>

</translate>

# -*- coding: utf-8 -*-
# This function list the components of an object
# and extract this object its XYZ coordinates,
# its edges and their lengths center of mass and coordinates
# its faces and their center of mass
# its faces and their surfaces and coordinates
# 8/05/2014

import Draft,Part
def detail():
    sel = FreeCADGui.Selection.getSelection()   # Select an object
    if len(sel) != 0:                           # If there is a selection then
        Vertx=[]
        Edges=[]
        Faces=[]
        compt_V=0
        compt_E=0
        compt_F=0
        pas    =0
        perimetre = 0.0   
        EdgesLong = []

        # Displays the "Name" and the "Label" of the selection
        App.Console.PrintMessage("Selection > " + str(sel[0].Name) + "  " + str(sel[0].Label) +"\n"+"\n")

        for j in enumerate(sel[0].Shape.Edges):                                     # Search the "Edges" and their lengths
            compt_E+=1
            Edges.append("Edge%d" % (j[0]+1))
            EdgesLong.append(str(sel[0].Shape.Edges[compt_E-1].Length))
            perimetre += (sel[0].Shape.Edges[compt_E-1].Length)                     # calculates the perimeter

            # Displays the "Edge" and its length
            App.Console.PrintMessage("Edge"+str(compt_E)+" Length > "+str(sel[0].Shape.Edges[compt_E-1].Length)+"\n")

            # Displays the "Edge" and its center mass
            App.Console.PrintMessage("Edge"+str(compt_E)+" Center > "+str(sel[0].Shape.Edges[compt_E-1].CenterOfMass)+"\n")

            num = sel[0].Shape.Edges[compt_E-1].Vertexes[0]
            Vertx.append("X1: "+str(num.Point.x))
            Vertx.append("Y1: "+str(num.Point.y))
            Vertx.append("Z1: "+str(num.Point.z))
            # Displays the coordinates 1
            App.Console.PrintMessage("X1: "+str(num.Point[0])+" Y1: "+str(num.Point[1])+" Z1: "+str(num.Point[2])+"\n")

            try:
                num = sel[0].Shape.Edges[compt_E-1].Vertexes[1]
                Vertx.append("X2: "+str(num.Point.x))
                Vertx.append("Y2: "+str(num.Point.y))
                Vertx.append("Z2: "+str(num.Point.z))
            except:
                Vertx.append("-")
                Vertx.append("-")
                Vertx.append("-")
            # Displays the coordinates 2
            App.Console.PrintMessage("X2: "+str(num.Point[0])+" Y2: "+str(num.Point[1])+" Z2: "+str(num.Point[2])+"\n")

            App.Console.PrintMessage("\n")
        App.Console.PrintMessage("Perimeter of the form  : "+str(perimetre)+"\n") 

        App.Console.PrintMessage("\n")
        FacesSurf = []
        for j in enumerate(sel[0].Shape.Faces):                                      # Search the "Faces" and their surface
            compt_F+=1
            Faces.append("Face%d" % (j[0]+1))
            FacesSurf.append(str(sel[0].Shape.Faces[compt_F-1].Area))

            # Displays 'Face' and its surface
            App.Console.PrintMessage("Face"+str(compt_F)+" >  Surface "+str(sel[0].Shape.Faces[compt_F-1].Area)+"\n")

            # Displays 'Face' and its CenterOfMass
            App.Console.PrintMessage("Face"+str(compt_F)+" >  Center  "+str(sel[0].Shape.Faces[compt_F-1].CenterOfMass)+"\n")

            # Displays 'Face' and its Coordinates
            FacesCoor = []
            fco = 0
            for f0 in sel[0].Shape.Faces[compt_F-1].Vertexes:                        # Search the Vertexes of the face
                fco += 1
                FacesCoor.append("X"+str(fco)+": "+str(f0.Point.x))
                FacesCoor.append("Y"+str(fco)+": "+str(f0.Point.y))
                FacesCoor.append("Z"+str(fco)+": "+str(f0.Point.z))

            # Displays 'Face' and its Coordinates
            App.Console.PrintMessage("Face"+str(compt_F)+" >  Coordinate"+str(FacesCoor)+"\n")

            # Displays 'Face' and its Volume
            App.Console.PrintMessage("Face"+str(compt_F)+" >  Volume  "+str(sel[0].Shape.Faces[compt_F-1].Volume)+"\n")
            App.Console.PrintMessage("\n")

        # Displays the total surface of the form
        App.Console.PrintMessage("Surface of the form    : "+str(sel[0].Shape.Area)+"\n")

        # Displays the total Volume of the form
        App.Console.PrintMessage("Volume  of the form    : "+str(sel[0].Shape.Volume)+"\n")

detail()

<translate>

</translate>

наверх

<translate>

List the PropertiesList

</translate>

import FreeCADGui
from FreeCAD import Console
o = App.ActiveDocument.ActiveObject
op = o.PropertiesList
for p in op:
    Console.PrintMessage("Property: "+ str(p)+ " Value: " + str(o.getPropertyByName(p))+"\r\n")

<translate>

</translate>

наверх

<translate>

Add a single Property Comment

</translate>

import Draft
obj = FreeCADGui.Selection.getSelection()[0]
obj.addProperty("App::PropertyString","GComment","Draft","Font name").GComment = "Comment here"
App.activeDocument().recompute()

<translate>

</translate>

наверх

<translate>

Search and data extraction

Examples of research and decoding information on an object.

Each section is independently and is separated by "############" can be copied directly into the Python console, or in a macro or use this macro. The description of the macro in the commentary.

Displaying it in the "Report View" window (View > Views > Report view)

</translate>

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
 
# Exemples de recherche et de decodage d'informations sur un objet
# Chaque section peut etre copiee directement dans la console Python ou dans une macro ou utilisez la macro tel quel
# Certaines commandes se repetent seul l'approche est differente
# L'affichage se fait dans la Vue rapport : Menu Affichage > Vues > Vue rapport
#
# Examples of research and decoding information on an object
# Each section can be copied directly into the Python console, or in a macro or uses this macro
# Certain commands as repeat alone approach is different
# Displayed in Report view: View > Views > report view
#
# rev:30/08/2014:29/09/2014:17/09/2015 22/11/2019 30/12/2022
 
from FreeCAD import Base
import DraftVecUtils, Draft, Part

##################################################################################
# info in the object

box = App.ActiveDocument.getObject('Box')                                 # object 
####
print(dir(box))                                                           # all options disponible in the object
####
print(box.Name)                                                           # object name
####
print(box.Content)                                                        # content of the object in XML format
##################################################################################
#
# example of using the information listed
#
# search the name of the active document 
mydoc = FreeCAD.activeDocument().Name                                     # Name of active Document
App.Console.PrintMessage("Active docu    : "+(mydoc)+"\n")
##################################################################################

# search the document name and the name of the object selected
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
object_FullName = sel[0].FullName                                         # file Name and Name of the object selected
App.Console.PrintMessage("object_FullName: "+(object_FullName)+"\n")
##################################################################################

# search the label of the object selected
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
object_Label = sel[0].Label                                               # Label of the object (modifiable)
App.Console.PrintMessage("object_Label   : "+(object_Label)+"\n")
##################################################################################

#TypeID object FreeCAD selected
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
App.Console.PrintMessage("sel            : "+str(sel[0])+"\n\n")          # sel[0] first object selected
##################################################################################

# search the Name of the object selected
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
object_Name  = sel[0].Name                                                # Name of the object (not modifiable)
App.Console.PrintMessage("object_Name    : "+str(object_Name)+"\n\n")
##################################################################################

# search the Sub Element Name of the sub object selected
try:
    SubElement = FreeCADGui.Selection.getSelectionEx()                    # sub element name with getSelectionEx()
    element_ = SubElement[0].SubElementNames[0]                           # name of 1 element selected
    App.Console.PrintMessage("elementSelec   : "+str(element_)+"\n\n")            
except:
    App.Console.PrintMessage("Oups"+"\n\n")            
##################################################################################

# give the length of the subObject selected
SubElementLength = Gui.Selection.getSelectionEx()[0].SubObjects[0].Length # sub element or element name with getSelectionEx()
App.Console.PrintMessage("SubElement length: "+str(SubElementLength)+"\n")# length
##################################################################################

# list the edges and the coordinates of the object[0] selected
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
i = 0
for j in enumerate(sel[0].Shape.Edges):                                   # list all Edges
    i += 1
    App.Console.PrintMessage("Edges n : "+str(i)+"\n")
    a = sel[0].Shape.Edges[j[0]].Vertexes[0]
    App.Console.PrintMessage("X1             : "+str(a.Point.x)+"\n")     # coordinate XYZ first point
    App.Console.PrintMessage("Y1             : "+str(a.Point.y)+"\n")     #
    App.Console.PrintMessage("Z1             : "+str(a.Point.z)+"\n")     #
    try:
        a = sel[0].Shape.Edges[j[0]].Vertexes[1]
        App.Console.PrintMessage("X2             : "+str(a.Point.x)+"\n") # coordinate XYZ second point
        App.Console.PrintMessage("Y2             : "+str(a.Point.y)+"\n") #
        App.Console.PrintMessage("Z2             : "+str(a.Point.z)+"\n") #
    except:
        App.Console.PrintMessage("Oups"+"\n")    
App.Console.PrintMessage("\n")    
##################################################################################

# give the sub element name, length, coordinates, BoundBox, BoundBox.Center, Area of the SubObjects selected
try:
    SubElement = FreeCADGui.Selection.getSelectionEx()                                        # sub element name with getSelectionEx()
    subElementName = Gui.Selection.getSelectionEx()[0].SubElementNames[0]                     # sub element name with getSelectionEx()
    App.Console.PrintMessage("subElementName : "+str(subElementName)+"\n")
    
    subObjectLength = Gui.Selection.getSelectionEx()[0].SubObjects[0].Length                  # sub element Length
    App.Console.PrintMessage("subObjectLength: "+str(subObjectLength)+"\n\n")
    
    subObjectX1 = Gui.Selection.getSelectionEx()[0].SubObjects[0].Vertexes[0].Point.x         # sub element coordinate X1
    App.Console.PrintMessage("subObject_X1   : "+str(subObjectX1)+"\n")
    subObjectY1 = Gui.Selection.getSelectionEx()[0].SubObjects[0].Vertexes[0].Point.y         # sub element coordinate Y1
    App.Console.PrintMessage("subObject_Y1   : "+str(subObjectY1)+"\n")
    subObjectZ1 = Gui.Selection.getSelectionEx()[0].SubObjects[0].Vertexes[0].Point.z         # sub element coordinate Z1
    App.Console.PrintMessage("subObject_Z1   : "+str(subObjectZ1)+"\n\n")

    try:
        subObjectX2 = Gui.Selection.getSelectionEx()[0].SubObjects[0].Vertexes[1].Point.x     # sub element coordinate X2
        App.Console.PrintMessage("subObject_X2   : "+str(subObjectX2)+"\n")
        subObjectY2 = Gui.Selection.getSelectionEx()[0].SubObjects[0].Vertexes[1].Point.y     # sub element coordinate Y2
        App.Console.PrintMessage("subObject_Y2   : "+str(subObjectY2)+"\n")
        subObjectZ2 = Gui.Selection.getSelectionEx()[0].SubObjects[0].Vertexes[1].Point.z     # sub element coordinate Z2
        App.Console.PrintMessage("subObject_Z2   : "+str(subObjectZ2)+"\n\n")
    except:
        App.Console.PrintMessage("Oups"+"\n\n")            

    subObjectBoundBox = Gui.Selection.getSelectionEx()[0].SubObjects[0].BoundBox              # sub element BoundBox coordinates
    App.Console.PrintMessage("subObjectBBox  : "+str(subObjectBoundBox)+"\n")
    
    subObjectBoundBoxCenter = Gui.Selection.getSelectionEx()[0].SubObjects[0].BoundBox.Center # sub element BoundBoxCenter
    App.Console.PrintMessage("subObjectBBoxCe: "+str(subObjectBoundBoxCenter)+"\n")
    
    surfaceFace = Gui.Selection.getSelectionEx()[0].SubObjects[0].Area                        # Area of the face selected
    App.Console.PrintMessage("surfaceFace    : "+str(surfaceFace)+"\n\n")
except:
    App.Console.PrintMessage("Oups"+"\n\n")            
##################################################################################

# give the area of the object
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
surface = sel[0].Shape.Area                                               # Area object complete
App.Console.PrintMessage("surfaceObjet   : "+str(surface)+"\n\n")
##################################################################################

# give the Center Of Mass and coordinates of the object
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
CenterOfMass = sel[0].Shape.CenterOfMass                                  # Center of Mass of the object
App.Console.PrintMessage("CenterOfMass   : "+str(CenterOfMass)+"\n")
App.Console.PrintMessage("CenterOfMassX  : "+str(CenterOfMass[0])+"\n")   # coordinates [0]=X [1]=Y [2]=Z
App.Console.PrintMessage("CenterOfMassY  : "+str(CenterOfMass[1])+"\n")   # or CenterOfMass.x, CenterOfMass.y, CenterOfMass.z
App.Console.PrintMessage("CenterOfMassZ  : "+str(CenterOfMass[2])+"\n\n")
##################################################################################

# list the all faces of the object selected
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
for j in enumerate(sel[0].Shape.Faces):                                   # List alles faces of the object
    App.Console.PrintMessage("Face           : "+str("Face%d" % (j[0]+1))+"\n")
App.Console.PrintMessage("\n\n")
##################################################################################

# give the volume of the object selected
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
volume_ = sel[0].Shape.Volume                                             # Volume of the object
App.Console.PrintMessage("volume_        : "+str(volume_)+"\n\n")
##################################################################################
 
# give the BoundBox of the oject selected all type
objs = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
if len(objs) >= 1:                                                         # serch the object type
    if hasattr(objs[0], "Shape"):
        s = objs[0].Shape
    elif hasattr(objs[0], "Mesh"):      # upgrade with wmayer thanks #http://forum.freecadweb.org/viewtopic.php?f=13&t=22331
        s = objs[0].Mesh
    elif hasattr(objs[0], "Points"):
        s = objs[0].Points

boundBox_= s.BoundBox                                                     # BoundBox of the object
App.Console.PrintMessage("boundBox_      : "+str(boundBox_)+"\n")         # 
 
boundBoxLX   = boundBox_.XLength                                          # Length x boundBox rectangle
boundBoxLY   = boundBox_.YLength                                          # Length y boundBox rectangle
boundBoxLZ   = boundBox_.ZLength                                          # Length z boundBox rectangle

boundBoxXMin = boundBox_.XMin                                             # coordonate XMin
boundBoxYMin = boundBox_.YMin                                             # coordonate YMin
boundBoxZMin = boundBox_.ZMin                                             # coordonate ZMin
boundBoxXMax = boundBox_.XMax                                             # coordonate XMax
boundBoxYMax = boundBox_.YMax                                             # coordonate YMax
boundBoxZMax = boundBox_.ZMax                                             # coordonate ZMax

boundBoxDiag= boundBox_.DiagonalLength                                    # Diagonal Length boundBox rectangle
boundBoxCenter = boundBox_.Center                                         # BoundBox Center
boundBoxCenterOfGravity = boundBox_.CenterOfGravity                       # BoundBox CenterOfGravity

App.Console.PrintMessage("boundBoxLX     : "+str(boundBoxLX)+"\n")
App.Console.PrintMessage("boundBoxLY     : "+str(boundBoxLY)+"\n")
App.Console.PrintMessage("boundBoxLZ     : "+str(boundBoxLZ)+"\n\n")

App.Console.PrintMessage("boundBoxXMin   : "+str(boundBoxXMin)+"\n")
App.Console.PrintMessage("boundBoxYMin   : "+str(boundBoxYMin)+"\n")
App.Console.PrintMessage("boundBoxZMin   : "+str(boundBoxZMin)+"\n")
App.Console.PrintMessage("boundBoxXMax   : "+str(boundBoxXMax)+"\n")
App.Console.PrintMessage("boundBoxYMax   : "+str(boundBoxYMax)+"\n")
App.Console.PrintMessage("boundBoxZMax   : "+str(boundBoxZMax)+"\n\n")

App.Console.PrintMessage("boundBoxDiag   : "+str(boundBoxDiag)+"\n")
App.Console.PrintMessage("boundBoxCenter : "+str(boundBoxCenter)+"\n")

App.Console.PrintMessage("boundBox Center of Gravity : "+str(boundBoxCenterOfGravity )+"\n\n")

##################################################################################

# give the complete placement of the object selected
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
pl = sel[0].Shape.Placement                                               # Placement Vector XYZ and Yaw-Pitch-Roll
App.Console.PrintMessage("Placement      : "+str(pl)+"\n")
##################################################################################

# give the placement Base (xyz) of the object selected
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
pl = sel[0].Shape.Placement.Base                                          # Placement Vector XYZ
App.Console.PrintMessage("PlacementBase  : "+str(pl)+"\n\n")
##################################################################################
 
# give the placement Base (xyz) of the object selected
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
oripl_X = sel[0].Placement.Base[0]                                        # decode Placement X
oripl_Y = sel[0].Placement.Base[1]                                        # decode Placement Y
oripl_Z = sel[0].Placement.Base[2]                                        # decode Placement Z

# same 
#oripl_X = sel[0].Placement.Base.x                                        # decode Placement X
#oripl_Y = sel[0].Placement.Base.y                                        # decode Placement Y
#oripl_Z = sel[0].Placement.Base.z                                        # decode Placement Z
 
App.Console.PrintMessage("oripl_X        : "+str(oripl_X)+"\n")
App.Console.PrintMessage("oripl_Y        : "+str(oripl_Y)+"\n")
App.Console.PrintMessage("oripl_Z        : "+str(oripl_Z)+"\n\n")
##################################################################################

# give the placement rotation of the object selected (x, y, z, angle rotation)
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
rotation = sel[0].Placement.Rotation                                      # decode Placement Rotation
App.Console.PrintMessage("rotation              : "+str(rotation)+"\n\n")
##################################################################################

# give the placement rotation of the object selected (x, y, z, angle rotation)
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
pl = sel[0].Shape.Placement.Rotation                                      # decode Placement Rotation other method
App.Console.PrintMessage("Placement Rot         : "+str(pl)+"\n\n")
##################################################################################

# give the rotation of the object selected (angle rotation)
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
pl = sel[0].Shape.Placement.Rotation.Angle                                # decode Placement Rotation Angle
App.Console.PrintMessage("Placement Rot Angle   : "+str(pl)+"\n\n")
##################################################################################

# give the rotation.Q of the object selected (angle rotation in Radian) for convert: math.degrees(angleInRadian)
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
Rot   = sel[0].Placement.Rotation.Q                                       # Placement Rotation Q
App.Console.PrintMessage("Rot           : "+str(Rot)+ "\n")
 
Rot_0 = sel[0].Placement.Rotation.Q[0]                                    # decode Placement Rotation Q
App.Console.PrintMessage("Rot_0         : "+str(Rot_0)+ " rad ,  "+str(180 * Rot_0 / 3.1416)+" deg "+"\n") # or math.degrees(angle)
 
Rot_1 = sel[0].Placement.Rotation.Q[1]                                    # decode Placement Rotation 1
App.Console.PrintMessage("Rot_1         : "+str(Rot_1)+ " rad ,  "+str(180 * Rot_1 / 3.1416)+" deg "+"\n") # or math.degrees(angle)
 
Rot_2 = sel[0].Placement.Rotation.Q[2]                                    # decode Placement Rotation 2
App.Console.PrintMessage("Rot_2         : "+str(Rot_2)+ " rad ,  "+str(180 * Rot_2 / 3.1416)+" deg "+"\n") # or math.degrees(angle)

Rot_3 = sel[0].Placement.Rotation.Q[3]                                    # decode Placement Rotation 3
App.Console.PrintMessage("Rot_3         : "+str(Rot_3)+"\n\n")

Rot_Axis = sel[0].Placement.Rotation.Axis                                 # Placement Rotation .Axis
App.Console.PrintMessage("Rot_Axis      : "+str(Rot_Axis)+ "\n")
 
Rot_Angle = sel[0].Placement.Rotation.Angle                               # Placement Rotation .Angle
App.Console.PrintMessage("Rot_Angle     : "+str(Rot_Angle)+ "\n\n")
##################################################################################

# give the rotation of the object selected toEuler (angle rotation in degrees)
sel = FreeCADGui.Selection.getSelection()                             # select object with getSelection()
angle   = sel[0].Shape.Placement.Rotation.toEuler()                   # angle Euler
App.Console.PrintMessage("Angle          : "+str(angle)+"\n")
Yaw   = sel[0].Shape.Placement.Rotation.toEuler()[0]                  # decode angle Euler Yaw (Z) lacet (alpha)
App.Console.PrintMessage("Yaw            : "+str(Yaw)+"\n")
Pitch = sel[0].Shape.Placement.Rotation.toEuler()[1]                  # decode angle Euler Pitch (Y) tangage (beta)
App.Console.PrintMessage("Pitch          : "+str(Pitch)+"\n")
Roll  = sel[0].Shape.Placement.Rotation.toEuler()[2]                  # decode angle Euler Roll (X) roulis (gamma)
App.Console.PrintMessage("Roll           : "+str(Roll)+"\n\n")

rot = App.Rotation()
rot.setYawPitchRoll(45,45,0)
print("Angle: ", rot.Angle)
print("Axis: ", rot.Axis)
print("RawAxis: ", rot.RawAxis)
print("YawPitchRoll: ", rot.getYawPitchRoll())
print("Rotation: ", rot)
print("Quaternion: ", rot.Q)

##################################################################################

# find Midpoint of the selected line
import Draft, DraftGeomUtils
sel = FreeCADGui.Selection.getSelection()
vecteur = DraftGeomUtils.findMidpoint(sel[0].Shape.Edges[0])              # find Midpoint
App.Console.PrintMessage(vecteur)
Draft.makePoint(vecteur)
##################################################################################

<translate>

</translate>

наверх

<translate>

Manual search of an element with label

</translate>

# Extract the coordinate X,Y,Z and Angle giving the label (here "Cylindre")
App.Console.PrintMessage("Base.x       : "+str(FreeCAD.ActiveDocument.getObjectsByLabel("Cylindre")[0].Placement.Base.x)+"\n")
App.Console.PrintMessage("Base.y       : "+str(FreeCAD.ActiveDocument.getObjectsByLabel("Cylindre")[0].Placement.Base.y)+"\n")
App.Console.PrintMessage("Base.z       : "+str(FreeCAD.ActiveDocument.getObjectsByLabel("Cylindre")[0].Placement.Base.z)+"\n")
App.Console.PrintMessage("Base.Angle   : "+str(FreeCAD.ActiveDocument.getObjectsByLabel("Cylindre")[0].Placement.Rotation.Angle)+"\n\n")
##################################################################################

<translate>

Note: Usually the angles are given in Radian. To convert them:

  1. angle in Degrees to Radians :
    • Angle in radian = pi * (angle in degree) / 180
    • Angle in radian = math.radians(angle in degree)
  2. angle in Radians to Degrees :
    • Angle in degree = 180 * (angle in radian) / pi
    • Angle in degree = math.degrees(angle in radian)

</translate>

наверх

<translate>

Cartesian coordinates

This code displays the Cartesian coordinates of the selected item.

Change the value of "numberOfPoints" if you want a different number of points (precision)

</translate>

numberOfPoints = 100                                                         # Decomposition number (or precision you can change)
selectedEdge = FreeCADGui.Selection.getSelectionEx()[0].SubObjects[0].copy() # select one element
points  = selectedEdge.discretize(numberOfPoints)                            # discretize the element
i=0
for p in points:                                                             # list and display the coordinates
    i+=1
    print( i, " X", p.x, " Y", p.y, " Z", p.z)

<translate>

Other method display on "Int" and "Float"

</translate>

import Part
from FreeCAD import Base

c=Part.makeCylinder(2,10)        # create the circle
Part.show(c)                     # display the shape

# slice accepts two arguments:
#+ the normal of the cross section plane
#+ the distance from the origin to the cross section plane. Here you have to find a value so that the plane intersects your object
s=c.slice(Base.Vector(0,1,0),0)  # 

# here the result is a single wire
# depending on the source object this can be several wires
s=s[0]

# if you only need the vertexes of the shape you can use
v=[]
for i in s.Vertexes:
    v.append(i.Point)

# but you can also sub-sample the section to have a certain number of points (int) ...
p1=s.discretize(20)
ii=0
for i in p1:
    ii+=1
    print( i )                                             # Vector()
    print( ii, ": X:", i.x, " Y:", i.y, " Z:", i.z )       # Vector decode
Draft.makeWire(p1,closed=False,face=False,support=None)    # to see the difference accuracy (20)

## uncomment to use
#import Draft
#Draft.downgrade(App.ActiveDocument.ActiveObject,delete=True)  # first transform the DWire in Wire         "downgrade"
#Draft.downgrade(App.ActiveDocument.ActiveObject,delete=True)  # second split the Wire in single objects   "downgrade"
#
##Draft.upgrade(FreeCADGui.Selection.getSelection(),delete=True) # to attach lines contiguous SELECTED use "upgrade"


# ... or define a sampling distance (float)
p2=s.discretize(0.5)
ii=0
for i in p2:
    ii+=1
    print( i )                                             # Vector()
    print( ii, ": X:", i.x, " Y:", i.y, " Z:", i.z )       # Vector decode 
Draft.makeWire(p2,closed=False,face=False,support=None)  # to see the difference accuracy (0.5)

## uncomment to use
#import Draft
#Draft.downgrade(App.ActiveDocument.ActiveObject,delete=True)  # first transform the DWire in Wire         "downgrade"
#Draft.downgrade(App.ActiveDocument.ActiveObject,delete=True)  # second split the Wire in single objects   "downgrade"
#
##Draft.upgrade(FreeCADGui.Selection.getSelection(),delete=True) # to attach lines contiguous SELECTED use "upgrade"

<translate>

</translate>

наверх

<translate>

Select all objects in the document

</translate>

import FreeCAD
for obj in FreeCAD.ActiveDocument.Objects:
    print( obj.Name )                               # display the object Name
    objName = obj.Name
    obj = App.ActiveDocument.getObject(objName)
    Gui.Selection.addSelection(obj)                 # select the object

<translate>

</translate>

наверх

<translate>

Select a face of an object by Name object and Face number

</translate>

# select one face of the object
import FreeCAD, Draft
App=FreeCAD
nameObject = "Box"                             # objet
faceSelect = "Face3"                           # face to selection
loch=App.ActiveDocument.getObject(nameObject)  # objet
Gui.Selection.clearSelection()                 # clear all selection
Gui.Selection.addSelection(loch,faceSelect)    # select the face specified
s = Gui.Selection.getSelectionEx()
#Draft.makeFacebinder(s)                       #

<translate>

</translate>

наверх

<translate>

Get the normal vector of a face of an object by Name object and number Face (r.Q)

</translate>

## normal of a face by giving the number of the face and the name of the object (rotation Q with yL, uV) = (App.Vector (x, y, z), angle))
## normal d'une face en donnant le numero de la face et le nom de l'objet (rotation Q avec yL, uV) = (App.Vector(x, y, z),angle))
from FreeCAD import Vector

numero_Face = 2      # number of the face searched (begin 0, 1, 2, 3 .....)
nomObjet    = "Box"  # object name
yL = Gui.ActiveDocument.getObject(nomObjet).Object.Shape.Faces[numero_Face].CenterOfMass
uv = Gui.ActiveDocument.getObject(nomObjet).Object.Shape.Faces[numero_Face].Surface.parameter(yL)

nv = Gui.ActiveDocument.getObject(nomObjet).Object.Shape.Faces[numero_Face].normalAt(uv[0], uv[1])
direction = yL.sub(nv + yL)
print("Direction  : ",direction)

r = App.Rotation(App.Vector(0,0,1),direction)
print("Rotation   : ", r)
print("Rotation Q : ", r.Q)

<translate>

</translate>

наверх

<translate>

Get the normal vector of a face of an object by Name object and number of Face

</translate>

numero_Face = 2       # number of the face searched (begin 0, 1, 2, 3 .....)
nomObjet    = "Box"   # object name
normal      = Gui.ActiveDocument.getObject(nomObjet).Object.Shape.Faces[numero_Face].normalAt(0,0)
print("Face"+str(numero_Face), " : ", normal)

<translate>

</translate>

наверх

<translate>

Get the normal vector of an object selected and number of Face

</translate>

## normal of a face by giving the number of the face of the selected object
selectionObjects = FreeCADGui.Selection.getSelection()     
numero_Face = 3    # numero de la face recherchee
normal = selectionObjects[0].Shape.Faces[numero_Face].normalAt(0,0)
print(normal)
# selectionne la face numerotee
Gui.Selection.clearSelection()
Gui.Selection.addSelection(selectionObjects[0],"Face"+str(numero_Face))

<translate>

</translate>

наверх

<translate>

Get the normal vector on the surface

This example show how to find normal vector on the surface by find the u,v parameters of one point on the surface and use u,v parameters to find normal vector

</translate>

def normal(self):
   ss=FreeCADGui.Selection.getSelectionEx()[0].SubObjects[0].copy()#SubObjects[0] is the edge list
   points  = ss.discretize(3.0)#points on the surface edge, 
             #this example just use points on the edge for example. 
             #However point is not necessary on the edge, it can be anywhere on the surface. 
   face=FreeCADGui.Selection.getSelectionEx()[0].SubObjects[1]
   for pp in points:
      pt=FreeCAD.Base.Vector(pp.x,pp.y,pp.z)#a point on the surface edge
      uv=face.Surface.parameter(pt)# find the surface u,v parameter of a point on the surface edge
      u=uv[0]
      v=uv[1]
      normal=face.normalAt(u,v)#use u,v to find normal vector
      print( normal)
      line=Part.makeLine((pp.x,pp.y,pp.z), (normal.x,normal.y,normal.z))
      Part.show(line)

<translate>

</translate>

наверх

<translate>

Get the normal vector of the face and create a line at the point mouse clicked

</translate>

import PySide2
import Draft, Part, FreeCAD, FreeCADGui
import FreeCADGui as Gui
from FreeCAD import Base

FreeCAD.ActiveDocument.openTransaction("Tyty")    # memorise les actions (avec annuler restore)
selectedFace = FreeCADGui.Selection.getSelectionEx()[0].SubObjects[0]
pointClick = FreeCADGui.Selection.getSelectionEx()[0].PickedPoints[0]

########## section direction
plr = FreeCAD.Placement()
yL = pointClick
uv = selectedFace.Surface.parameter(yL)
nv = direction = selectedFace.normalAt(uv[0], uv[1])
r = App.Rotation(App.Vector(0,0,1),nv)
plr.Rotation.Q = r.Q
plr.Base = pointClick
########## section direction

line = Draft.make_wire([App.Vector(0.0,0.0,0.0), App.Vector(0.0,0.0,20.0)] )    # create line
line.Placement=plr
FreeCAD.ActiveDocument.recompute()
print( "Direction (radian) : ",direction )    # direction in radian

<translate>

</translate>

наверх

<translate>

Get the normal vector of a surface from a STL file

</translate>

def getNormal(cb):
    if cb.getEvent().getState() == coin.SoButtonEvent.UP:
        pp = cb.getPickedPoint()
        if pp:
            vec = pp.getNormal().getValue()
            index = coin.cast(pp.getDetail(), "SoFaceDetail").getFaceIndex()
            print("Normal: {}, Face index: {}".format(str(vec), index))

from pivy import coin
meth=Gui.ActiveDocument.ActiveView.addEventCallbackPivy(coin.SoMouseButtonEvent.getClassTypeId(), getNormal)

<translate> you are done then run for quit:

</translate>

Gui.ActiveDocument.ActiveView.removeEventCallbackPivy(coin.SoMouseButtonEvent.getClassTypeId(), meth)

<translate>

</translate>

наверх

<translate>

Create one object to the position of the Camera

</translate>

# create one object of the position to camera with "getCameraOrientation()"
# the object is still facing the screen
import Draft

plan = FreeCADGui.ActiveDocument.ActiveView.getCameraOrientation()
plan = str(plan)
###### extract data
a    = ""
for i in plan:
    if i in ("0123456789e.- "):
        a+=i
a = a.strip(" ")
a = a.split(" ")
####### extract data

#print( a)
#print( a[0])
#print( a[1])
#print( a[2])
#print( a[3])

xP = float(a[0])
yP = float(a[1])
zP = float(a[2])
qP = float(a[3])

pl = FreeCAD.Placement()
pl.Rotation.Q = (xP,yP,zP,qP)         # rotation of object
pl.Base = FreeCAD.Vector(0.0,0.0,0.0) # here coordinates XYZ of Object
rec = Draft.makeRectangle(length=10.0,height=10.0,placement=pl,face=False,support=None) # create rectangle
#rec = Draft.makeCircle(radius=5,placement=pl,face=False,support=None)                   # create circle
print( rec.Name)

<translate>

here same code simplified

</translate>

import Draft
pl = FreeCAD.Placement()
pl.Rotation = FreeCADGui.ActiveDocument.ActiveView.getCameraOrientation()
pl.Base = FreeCAD.Vector(0.0,0.0,0.0)
rec = Draft.makeRectangle(length=10.0,height=10.0,placement=pl,face=False,support=None)

<translate>

</translate>

наверх

<translate>

Read And write one Expression

</translate>

import Draft
doc = FreeCAD.ActiveDocument

pl=FreeCAD.Placement()
pl.Rotation.Q=(0.0,-0.0,-0.0,1.0)
pl.Base=FreeCAD.Vector(0.0,0.0,0.0)
obj = Draft.makeCircle(radius=1.0,placement=pl,face=False,support=None)    # create circle

print( obj.PropertiesList )                                                  # properties disponible in the obj

doc.getObject(obj.Name).setExpression('Radius', u'2mm')                    # modify the radius
doc.getObject(obj.Name).setExpression('Placement.Base.x', u'10mm')         # modify the placement 
doc.getObject(obj.Name).setExpression('FirstAngle', u'90')                 # modify the first angle
doc.recompute()

expressions = obj.ExpressionEngine                                         # read the expression list
print( expressions)

for i in expressions:                                                      # list and separate the data expression
    print( i[0]," = ",i[1])

<translate>

</translate>

наверх

<translate>

Create a Sketch on a Surface in PartDesign

This snippet can be useful, if you want to create a sketch on a surface in PartDesign from inside a macro. Note, that body might be None, if no active body is selected and that the Selection might be empty.

</translate>

body = Gui.ActiveDocument.ActiveView.getActiveObject('pdbody')
first_selection = Gui.Selection.getSelectionEx()[0]

feature = first_selection.Object
face_name = first_selection.SubElementNames[0]

sketch = App.ActiveDocument.addObject('Sketcher::SketchObject','MySketch')
body.addObject(sketch)
sketch.MapMode = 'FlatFace'
sketch.Support = (feature, face_name)

App.ActiveDocument.recompute()

<translate>

</translate>

наверх

<translate>

How to Simulate a Mouse Click at a given Coordinate

The position is relative to the GL widget. See forum thread.

</translate>

from PySide2 import QtCore
from PySide2 import QtGui
from PySide2 import QtWidgets

mw = Gui.getMainWindow()
gl = mw.findChild(QtWidgets.QOpenGLWidget)
me = QtGui.QMouseEvent(QtCore.QEvent.MouseButtonRelease, QtCore.QPoint(800,300), QtCore.Qt.LeftButton, QtCore.Qt.LeftButton, QtCore.Qt.NoModifier)

app = QtWidgets.QApplication.instance()
app.sendEvent(gl, me)

<translate>

If you have a 3d point and want to get the 2d point on the opengl widget then use this:

</translate>

from PySide2 import QtCore
from PySide2 import QtGui
from PySide2 import QtWidgets
from FreeCAD import Base

x, y, z, = 10,10,10
v = Gui.ActiveDocument.ActiveView
point3d = Base.Vector(x, y, z)
point2d = v.getPointOnScreen(point3d)
size = v.getSize()
coordX = point2d[0]
coordY = size[1] - point2d[1]

me = QtGui.QMouseEvent(QtCore.QEvent.MouseButtonRelease, QtCore.QPoint(coordX,coordY), QtCore.Qt.LeftButton, QtCore.Qt.LeftButton, QtCore.Qt.NoModifier)

<translate>

</translate>

наверх

<translate>

How to create a face with holes using Python API

This snippet demonstrates how to create a face with internal holes through the Python API. See forum thread.

</translate>

import FreeCAD, Part

# Create poles that will define the Face
pts = [(-2, 2, 0),
       (0, 2, 1),
       (2, 2, 0),
       (2, -2, 0),
       (0, -2, 1),
       (-2, -2, 0)]

bs = Part.BSplineCurve()
bs.buildFromPoles(pts, True)  # True makes this periodic/closed

# Make the Face from the curve
myFace = Part.makeFilledFace([bs.toShape()])

# Create geometry for holes that will be cut in the surface
hole0 = Part.Geom2d.Circle2d(FreeCAD.Base.Vector2d(0,0), 1.0)
hole1 = Part.Geom2d.Circle2d(FreeCAD.Base.Vector2d(0,1.5), 0.1)

edge0 = hole0.toShape(myFace)
edge1 = hole1.toShape(myFace)
wireb = Part.Wire(bs.toShape())
wire0 = Part.Wire(edge0)
wire1 = Part.Wire(edge1)

# Cut holes in the face
myFace.cutHoles([wire0])
myFace.validate()  # This is required
myFace.cutHoles([wire1])
myFace.validate()

Part.show(myFace)

<translate>

</translate>

наверх

<translate>

Close and restart FreeCAD

</translate>

import PySide2 
from PySide2 import QtWidgets, QtCore, QtGui

def restart_freecad():
    """Shuts down and restarts FreeCAD"""

    args = QtWidgets.QApplication.arguments()[1:]
    if FreeCADGui.getMainWindow().close():
        QtCore.QProcess.startDetached(
            QtWidgets.QApplication.applicationFilePath(), args
        )

<translate>

</translate>

наверх

<translate>

Coin3D

See Coin3d snippets

</translate>

наверх

<translate>

Related

</translate>

наверх

<translate>


</translate>

<translate>

</translate>

<translate>

Introduction

This page shows how advanced functionality can easily be created in Python. In this exercise, we will build a new tool that draws a line. This tool can then be linked to a FreeCAD command, and that command can be called by any element in the interface, like a menu item or a toolbar button.

The main script

First we will write a script containing all our functionality. Then we will save this in a file and import it in FreeCAD to make all its classes and functions available. Launch your favorite code editor and type the following lines:

</translate>

import FreeCADGui, Part
from pivy.coin import *

class line:

    """This class will create a line after the user clicked 2 points on the screen"""

    def __init__(self):
        self.view = FreeCADGui.ActiveDocument.ActiveView
        self.stack = []
        self.callback = self.view.addEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(), self.getpoint)

    def getpoint(self, event_cb):
        event = event_cb.getEvent()
        if event.getState() == SoMouseButtonEvent.DOWN:
            pos = event.getPosition()
            point = self.view.getPoint(pos[0], pos[1])
            self.stack.append(point)
            if len(self.stack) == 2:
                l = Part.LineSegment(self.stack[0], self.stack[1])
                shape = l.toShape()
                Part.show(shape)
                self.view.removeEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(), self.callback)

<translate>

</translate>

наверх

<translate>

Detailed explanation

</translate>

import Part, FreeCADGui
from pivy.coin import *

<translate>

In Python when you want to use functions from another module you need to import it. In our case we will need functions from the Part module, for creating the line, and from the Gui module FreeCADGui, for accessing the 3D view. We also need the complete contents of the Coin library so we can directly use all Coin objects like SoMouseButtonEvent, etc.

</translate>

class line:

<translate>

Here we define our main class. Why do we use a class and not a function? The reason is that we need our tool to stay "alive" while we are waiting for the user to click on the screen. A function ends when its task has been done, but an object (a class defines an object) stays alive until it is destroyed.

</translate>

"""This class will create a line after the user clicked 2 points on the screen"""

<translate>

In Python, every class or function can have a documentation string (docstring). This is particularly useful in FreeCAD, because when you call that class in the interpreter, the description string will be displayed as a tooltip.

</translate>

def __init__(self):

<translate>

Python classes can always contain an __init__ function, which is executed when the class is called to create an object. Here we will put everything we want to happen when our line tool begins.

</translate>

self.view = FreeCADGui.ActiveDocument.ActiveView

<translate>

In a class you usually want to prepend self. to variable names to make the variables easily accessible to all functions inside and outside the class. Here we will use self.view to access and manipulate the active 3D view.

</translate>

self.stack = []

<translate>

Here we create an empty list that will contain the 3D points sent by the getpoint() function.

</translate>

self.callback = self.view.addEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(), self.getpoint)

<translate>

This is the important part. Since we are dealing with a Coin3D scene, we use a Coin callback mechanism that allows a function to be called every time a certain scene event happens. In our case we are creating a callback for SoMouseButtonEvent events, and we bind it to the getpoint() function. Now every time a mouse button is pressed or released the getpoint() function will be executed.

Note that there is also an alternative to addEventCallbackPivy() called addEventCallback() which does not rely on pivy. But since pivy is a very efficient and natural way to access any part of a Coin scene, it is the better choice.

</translate>

наверх

<translate>

</translate>

def getpoint(self, event_cb):

<translate>

Now we define the getpoint() function that will be executed when a mouse button is pressed in a 3D view. This function will receive an argument that we will call event_cb. From this event callback we can access the event object, which contains several pieces of information (more info here).

</translate>

if event.getState() == SoMouseButtonEvent.DOWN:

<translate>

The getpoint() function will be called when a mouse button is pressed or released. But we only want to pick a 3D point when a button is pressed, otherwise we would end up with two 3D points very close together. So we must check for that here.

</translate>

pos = event.getPosition()

<translate>

Here we get the screen coordinates of the mouse cursor.

</translate>

point = self.view.getPoint(pos[0], pos[1])

<translate>

This function gives us a FreeCAD vector (x,y,z) containing the 3D point that lies on the focal plane, just under our mouse cursor. If you are in camera view, imagine a ray coming from the camera, passing through the mouse cursor, and hitting the focal plane. That is the location of our 3D point. If we are in orthogonal view, the ray is parallel to the view direction.

</translate>

self.stack.append(point)

<translate>

We add our new point to the stack.

</translate>

if len(self.stack) == 2:

<translate>

Do we have enough points already? if yes, then let's draw the line!

</translate>

l = Part.LineSegment(self.stack[0], self.stack[1])

<translate>

Here we use the LineSegment() function from the Part module that creates a line from two FreeCAD vectors. The line is not bound to any object in our active document, so nothing appears on the screen.

</translate>

shape = l.toShape()

<translate>

The FreeCAD document can only accept shapes from the Part module. Shapes are the most generic type of the Part module. So we must convert our line to a shape before adding it to the document.

</translate>

Part.show(shape)

<translate>

The Part module has a very handy show() function that creates a new object in the document and binds a shape to it. We could also have created a new object in the document first and then bound the shape to it manually.

</translate>

self.view.removeEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(), self.callback)

<translate>

Since we are done with our line we remove the callback mechanism here.

</translate>

наверх

<translate>

Testing the script

Now let's save our script in a folder where the FreeCAD Python interpreter can find it. When importing modules, the interpreter will look in the following places: the Python installation paths, the FreeCAD bin folder, and all FreeCAD Mod (module) folders. So the best solution is to create a new folder in one of the Mod folders. Let's create a MyScripts folder there and save our script in it as exercise.py.

Now everything is ready. Let's start FreeCAD, create a new document, and in the Python interpreter issue:

</translate>

import exercise

<translate>

If no error message appears our exercise script has been loaded successfully. We can now check its contents with:

</translate>

dir(exercise)

<translate>

The command dir() is a built-in Python command that lists the contents of a module. We can check that our line() class is there with:

</translate>

'line' in dir(exercise)

<translate>

Now let's test it:

</translate>

exercise.line()

<translate>

Click two times in the 3D view and bingo: here is our line! To repeat it just type exercise.line() again.

</translate>

наверх

<translate>

Registering the script

For our new line tool to be really useful, and to avoid having to type all that stuff, it should have a button in the interface. One way to do this is to transform our new MyScripts folder into a full FreeCAD workbench. This is easy, all that is needed is to put a file called InitGui.py inside the MyScripts folder. InitGui.py will contain the instructions to create a new workbench, and add our new tool to it. Besides that we will also need to change our exercise code a bit, so the line() tool is recognized as an official FreeCAD command. Let's start by creating an InitGui.py file, and writing the following code in it:

</translate>

class MyWorkbench (Workbench):

    MenuText = "MyScripts"

    def Initialize(self):
        import exercise
        commandslist = ["line"]
        self.appendToolbar("My Scripts", commandslist)

Gui.addWorkbench(MyWorkbench())

<translate>

By now you probably understand the above script. We create a new class that we call MyWorkbench, we give it a title MenuText, and we define an Initialize() function that will be executed when the workbench is loaded into FreeCAD. In that function, we load the contents of our exercise file, and append the FreeCAD commands found inside to a command list. Then, we make a toolbar called "My Scripts" and we assign our command list to it. Currently, of course, we only have one tool, so our command list contains only one element. Then, once our workbench is ready, we add it to the main interface.

But this still won't work because a FreeCAD command must be formatted in a certain manner to work, we will need to change our line() tool. Our new exercise.py script should look like this:

</translate>

import FreeCADGui, Part
from pivy.coin import *

class line:

    """This class will create a line after the user clicked 2 points on the screen"""

    def Activated(self):
        self.view = FreeCADGui.ActiveDocument.ActiveView
        self.stack = []
        self.callback = self.view.addEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(), self.getpoint)

    def getpoint(self, event_cb):
        event = event_cb.getEvent()
        if event.getState() == SoMouseButtonEvent.DOWN:
            pos = event.getPosition()
            point = self.view.getPoint(pos[0], pos[1])
            self.stack.append(point)
            if len(self.stack) == 2:
                l = Part.LineSegment(self.stack[0], self.stack[1])
                shape = l.toShape()
                Part.show(shape)
                self.view.removeEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(), self.callback)

    def GetResources(self):
        return {'Pixmap': 'path_to_an_icon/line_icon.png', 'MenuText': 'Line', 'ToolTip': 'Creates a line by clicking 2 points on the screen'}

FreeCADGui.addCommand('line', line())

<translate>

What we did here is transform our __init__() function into an Activated() function. When FreeCAD commands are run, they automatically execute the Activated() function. We also added a GetResources() function, that informs FreeCAD where it can find the icon for the tool, and what will be the name and tooltip of our tool. Any jpg, png or svg image will work as an icon, it can be any size, but it is best to use a size that is close to the final aspect, like 16x16, 24x24 or 32x32. Then we add the line() class as an official FreeCAD command with the addCommand() method.

That's it, now we just need to restart FreeCAD and we'll have a nice new workbench with our brand new line tool!

</translate>

наверх

<translate>

So you want more?

If you liked this exercise, why not try to improve this little tool? There are many things that can be done, for example:

  • Add user feedback: until now we did a very bare tool, the user might be a bit lost when using it. So we could add some feedback, telling the user what to do next. You could issue messages to the FreeCAD console. Have a look in the FreeCAD.Console module.
  • Add a possibility to type the 3D points coordinates manually. Look at the Python input() function for example.
  • Add the possibility to add more than 2 points.
  • Add events for other things: Now we just check for Mouse button events, what if we would also do something when the mouse is moved, like displaying current coordinates?
  • Give a name to the created object.

Don't hesitate to ask questions or share ideas on the forum!

</translate>

наверх

<translate>

</translate>

<translate>

</translate>

<translate>

Introduction

In this page we will show how to build a simple graphical interface with Qt Designer, Qt's official tool for designing interfaces; the dialog will be converted to Python code, then it will be used inside FreeCAD. We'll assume that the user knows how to edit and run Python generally.

In this example, the entire interface is defined in Python. Although this is possible for small interfaces, for larger interfaces the recommendation is to load the created .ui files directly into the program.

Two general methods to create interfaces, by including the interface in the Python file, or by using .ui files.

Designing the dialog

In CAD applications, designing a good UI (User Interface) is very important. About everything the user will do will be through some piece of interface: reading dialog boxes, pressing buttons, choosing between icons, etc. So it is very important to think carefully to what you want to do, how you want the user to behave, and how will be the workflow of your action.

There are a couple of concepts to know when designing interface:

  • Modal/non-modal dialogs: A modal dialog appears in front of your screen, stopping the action of the main window, forcing the user to respond to the dialog, while a non-modal dialog doesn't stop you from working on the main window. In some case the first is better, in other cases not.
  • Identifying what is required and what is optional: Make sure the user knows what he must do. Label everything with proper description, use tooltips, etc.
  • Separating commands from parameters: This is usually done with buttons and text input fields. The user knows that clicking a button will produce an action while changing a value inside a text field will change a parameter somewhere. Nowadays, though, users usually know well what is a button, what is an input field, etc. The interface toolkit we are using, Qt, is a state-of-the-art toolkit, and we won't have to worry much about making things clear, since they will already be very clear by themselves.

So, now that we have well defined what we will do, it's time to open the qt designer. Let's design a very simple dialog, like this:

We will then use this dialog in FreeCAD to produce a nice rectangular plane. You might find it not very useful to produce nice rectangular planes, but it will be easy to change it later to do more complex things. When you open it, Qt Designer looks like this:

Creating the dialog

Qt Designer is very simple to use. On the left bar you have elements that can be dragged on your widget. On the right side you have properties panels displaying all kinds of editable properties of selected elements. So, begin with creating a new widget.

  1. Select "Dialog without buttons", since we don't want the default OK/Cancel buttons.
  2. We need 'Labels. Labels are simple text strings that appear on your widget to inform the end user. If you select a label, notice that on the right side there will appear several properties that you can modify such as: font style, height, etc... So lets drag 3 separate labels on to our widget:
    • One label for the title
    • Another label for writing "Height"
    • Another label for writing "Width"
  3. We now need LineEdits (2 of them actually). Drag two of them on to the widget. LineEdits are text fields that the end user can fill in. So we need one LineEdit for the Height and one for the Width. Here too, we can edit properties. For example, why not set a default value say for example: 1.00 for each. This way, when the user will see the dialog, both values will be filled already. If the end user is satisfied, they can directly press the button, saving precious time.
  4. Next lets add a PushButton. This is the button the end user will need to press after they've filled both fields.

Note: that we chose very simple controls here. Qt has many more options, for example one could use Spinboxes instead of LineEdits, etc... Have a look at what is available, explore...you will surely have other ideas.

That's about all we need to do in Qt Designer. One last thing, though, let's rename all our elements with simpler names, so it will be easier to identify them in our scripts:

</translate> <translate>

Converting our dialog to python

</translate> <translate> Now, let's save our widget somewhere. It will be saved as an .ui file, that we will easily convert to python script with pyuic. On windows, the pyuic program is bundled with pyqt (to be verified), on linux you probably will need to install it separately from your package manager (on debian-based systems, it is part of the pyqt4-dev-tools package). To do the conversion, you'll need to open a terminal window (or a command prompt window on windows), navigate to where you saved your .ui file, and issue: </translate>

pyuic mywidget.ui > mywidget.py

<translate> In Windows pyuic.py is located in "C:\Python27\Lib\site-packages\PyQt4\uic\pyuic.py" For conversion create a batch file called "compQt4.bat: </translate>

@"C:\Python27\python" "C:\Python27\Lib\site-packages\PyQt4\uic\pyuic.py" -x %1.ui > %1.py

<translate> In the DOS console type without extension </translate>

compQt4 myUiFile

<translate> In macOS, you can retrieve the appropriate version (the same that is used internally in FreeCAD 0.19) of QT and Pyside with these commands (pip required) </translate>

python3 -m pip install pyqt5
python3 -m pip install pySide2

<translate> This will install uic in the folder "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/PySide2/uic", and Designer in "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/PySide2/Designer.app". For convenience you can create a link of uic in /usr/local/bin to be able to call it simply with uic -g python ... instead of typing the whole path of the program, and a link to Designer to retrieve it in the mac's Applications folder with </translate>

sudo ln -s /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/PySide2/uic /usr/local/bin
ln -s /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/PySide2/Designer.app /Applications

<translate> Into Linux : to do </translate>

<translate> Since FreeCAD progressively moved away from PyQt after version 0.13, in favour of PySide (Choose your PySide install building PySide), to make the file based on PySide now you have to use:

</translate>

pyside-uic mywidget.ui -o mywidget.py

<translate> In Windows uic.py are located in "C:\Python27\Lib\site-packages\PySide\scripts\uic.py" For create batch file "compSide.bat": </translate>

@"C:\Python27\python" "C:\Python27\Lib\site-packages\PySide\scripts\uic.py" %1.ui > %1.py

<translate> In the DOS console type without extension </translate>

compSide myUiFile

<translate> Into Linux : to do

On some systems the program is called pyuic4 instead of pyuic. This will simply convert the .ui file into a python script. If we open the mywidget.py file, its contents is very easy to understand: </translate>

from PySide import QtCore, QtGui

class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(187, 178)
        self.title = QtGui.QLabel(Dialog)
        self.title.setGeometry(QtCore.QRect(10, 10, 271, 16))
        self.title.setObjectName("title")
        self.label_width = QtGui.QLabel(Dialog)
        ...

        self.retranslateUi(Dialog)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

   def retranslateUi(self, Dialog):
        Dialog.setWindowTitle(QtGui.QApplication.translate("Dialog", "Dialog", None, QtGui.QApplication.UnicodeUTF8))
        self.title.setText(QtGui.QApplication.translate("Dialog", "Plane-O-Matic", None, QtGui.QApplication.UnicodeUTF8))
        ...

<translate> As you see it has a very simple structure: a class named Ui_Dialog is created, that stores the interface elements of our widget. That class has two methods, one for setting up the widget, and one for translating its contents, which is part of the general Qt mechanism for translating interface elements. The setup method simply creates, one by one, the widgets as we defined them in Qt Designer, and sets their options as we decided earlier. Then, the whole interface gets translated, and finally, the slots get connected (we'll talk about that later).

We can now create a new widget and use this class to create its interface. We can already see our widget in action, by putting our mywidget.py file in a place where FreeCAD will find it (in the FreeCAD bin directory, or in any of the Mod subdirectories), and, in the FreeCAD python interpreter, issue: </translate>

from PySide import QtGui
import mywidget
d = QtGui.QWidget()
d.ui = mywidget.Ui_Dialog()
d.ui.setupUi(d)
d.show()

<translate> And our dialog will appear! Note that our Python interpreter is still working, we have a non-modal dialog. So, to close it, we can (apart from clicking its close icon, of course) issue: </translate>

d.hide()

<translate>

Making our dialog do something

Now that we can show and hide our dialog, we just need to add one last part: To make it do something! If you play a bit with Qt designer, you'll quickly discover a whole section called "signals and slots". Basically, it works like this: elements on your widgets (in Qt terminology, those elements are themselves widgets) can send signals. Those signals differ according to the widget type. For example, a button can send a signal when it is pressed and when it is released. Those signals can be connected to slots, which can be special functionality of other widgets (for example a dialog has a "close" slot to which you can connect the signal from a close button), or can be custom functions. The PyQt Reference Documentation lists all the qt widgets, what they can do, what signals they can send, etc...

What we will do here, is to create a new function that will create a plane based on height and width, and to connect that function to the pressed signal emitted by our "Create!" button. So, let's begin with importing our FreeCAD modules, by putting the following line at the top of the script, where we already import QtCore and QtGui: </translate>

import FreeCAD, Part

<translate> Then, let's add a new function to our Ui_Dialog class: </translate>

def createPlane(self):
    try:
        # first we check if valid numbers have been entered
        w = float(self.width.text())
        h = float(self.height.text())
    except ValueError:
        print("Error! Width and Height values must be valid numbers!")
    else:
        # create a face from 4 points
        p1 = FreeCAD.Vector(0,0,0)
        p2 = FreeCAD.Vector(w,0,0)
        p3 = FreeCAD.Vector(w,h,0)
        p4 = FreeCAD.Vector(0,h,0)
        pointslist = [p1,p2,p3,p4,p1]
        mywire = Part.makePolygon(pointslist)
        myface = Part.Face(mywire)
        Part.show(myface)
        self.hide()

<translate> Then, we need to inform Qt to connect the button to the function, by placing the following line just before QtCore.QMetaObject.connectSlotsByName(Dialog): </translate>

QtCore.QObject.connect(self.create,QtCore.SIGNAL("pressed()"),self.createPlane)

<translate> This, as you see, connects the pressed() signal of our create object (the "Create!" button), to a slot named createPlane, which we just defined. That's it! Now, as a final touch, we can add a little function to create the dialog, it will be easier to call. Outside the Ui_Dialog class, let's add this code: </translate>

class plane():
   def __init__(self):
       self.d = QtGui.QWidget()
       self.ui = Ui_Dialog()
       self.ui.setupUi(self.d)
       self.d.show()

<translate> (Python reminder: the __init__ method of a class is automatically executed whenever a new object is created!) Then, from FreeCAD, we only need to do: </translate>

import mywidget
myDialog = mywidget.plane()

<translate> That's all Folks... Now you can try all kinds of things, like for example inserting your widget in the FreeCAD interface (see the Code snippets page), or making much more advanced custom tools, by using other elements on your widget.

The complete script

This is the complete script, for reference: </translate>

# Form implementation generated from reading ui file 'mywidget.ui'
#
# Created: Mon Jun  1 19:09:10 2009
#      by: PyQt4 UI code generator 4.4.4
# Modified for PySide 16:02:2015 
# WARNING! All changes made in this file will be lost!

from PySide import QtCore, QtGui
import FreeCAD, Part 

class Ui_Dialog(object):
   def setupUi(self, Dialog):
       Dialog.setObjectName("Dialog")
       Dialog.resize(187, 178)
       self.title = QtGui.QLabel(Dialog)
       self.title.setGeometry(QtCore.QRect(10, 10, 271, 16))
       self.title.setObjectName("title")
       self.label_width = QtGui.QLabel(Dialog)
       self.label_width.setGeometry(QtCore.QRect(10, 50, 57, 16))
       self.label_width.setObjectName("label_width")
       self.label_height = QtGui.QLabel(Dialog)
       self.label_height.setGeometry(QtCore.QRect(10, 90, 57, 16))
       self.label_height.setObjectName("label_height")
       self.width = QtGui.QLineEdit(Dialog)
       self.width.setGeometry(QtCore.QRect(60, 40, 111, 26))
       self.width.setObjectName("width")
       self.height = QtGui.QLineEdit(Dialog)
       self.height.setGeometry(QtCore.QRect(60, 80, 111, 26))
       self.height.setObjectName("height")
       self.create = QtGui.QPushButton(Dialog)
       self.create.setGeometry(QtCore.QRect(50, 140, 83, 26))
       self.create.setObjectName("create")

       self.retranslateUi(Dialog)
       QtCore.QObject.connect(self.create,QtCore.SIGNAL("pressed()"),self.createPlane)
       QtCore.QMetaObject.connectSlotsByName(Dialog)

   def retranslateUi(self, Dialog):
       Dialog.setWindowTitle("Dialog")
       self.title.setText("Plane-O-Matic")
       self.label_width.setText("Width")
       self.label_height.setText("Height")
       self.create.setText("Create!")
       print("tyty")
   def createPlane(self):
       try:
           # first we check if valid numbers have been entered
           w = float(self.width.text())
           h = float(self.height.text())
       except ValueError:
           print("Error! Width and Height values must be valid numbers!")
       else:
           # create a face from 4 points
           p1 = FreeCAD.Vector(0,0,0)
           p2 = FreeCAD.Vector(w,0,0)
           p3 = FreeCAD.Vector(w,h,0)
           p4 = FreeCAD.Vector(0,h,0)
           pointslist = [p1,p2,p3,p4,p1]
           mywire = Part.makePolygon(pointslist)
           myface = Part.Face(mywire)
           Part.show(myface)

class plane():
  def __init__(self):
      self.d = QtGui.QWidget()
      self.ui = Ui_Dialog()
      self.ui.setupUi(self.d)
      self.d.show()

<translate>

More examples

Relevant links


</translate>

Developing applications for FreeCAD

<translate>

</translate>

<translate>

Licences used in FreeCAD

FreeCAD uses two different licenses, one for the application itself, and one for the documentation:

Lesser General Public Licence, version 2 or superior (LGPL2+) For all of the FreeCAD source code found in the official Git repository. The + means you can also, at your option, use FreeCAD under the terms of a later version of the license, such as LGPL3

Creative Commons Attribution 3.0 License (CC-BY-3.0) For the documentation and the website.

See FreeCAD's debian copyright file for more details about the licenses used by the different open-source components used in FreeCAD

Impact of the licences

Below is a friendlier explanation of what the LGPL license means for you:

All users

Anybody can download, use and redistribute FreeCAD free of charge, without any restriction. Your copy of FreeCAD is truly yours, as are the files you produce with FreeCAD. You will not be forced to update FreeCAD after a certain time, nor change your usage of FreeCAD. Using FreeCAD doesn't bind you to any kind of contract or obligation. The FreeCAD source code is public and can be inspected, so it is possible to verify that it doesn't do things without your knowledge such as sending your private data somewhere.

Professional users

FreeCAD can be used freely for any kind of purpose, being private, commercial or institutional. Any version of FreeCAD can be deployed and installed anywhere, any number of times. You can also modify and adapt FreeCAD for your own purposes without any restriction. However, you cannot make the FreeCAD developers liable for possible damage or business loss that could occur from using FreeCAD.

Open-source software developers

You can use FreeCAD as a base to develop your own application, or simply extend it by creating new modules for it. If FreeCAD is embedded into your own application, you can choose either the GPL or the LGPL license, or any other license that is compatible with LGPL, to allow the use of your work in proprietary software or not. If you are developing a module to be used as an extension, and don't include any of the FreeCAD code in it, then you can choose any license you want. However, if you wish to see your module integrated into FreeCAD one day, it is a good idea to use the same LGPL license as FreeCAD itself, as FreeCAD will only accept code with LGPL, MIT or BSD licenses.

Closed-source software developers

The LGPL license allows you to use FreeCAD as a component for your own application, and you are not forced to make your application open source. You will get support from the FreeCAD developers as long as it is not a 'one way street'. The license states however two important conditions:

1) You must clearly inform your users that your application is using FreeCAD and that FreeCAD is LGPL.

2) The LGPL license also stipulate your users must be able to swap your modified FreeCAD component with the original FreeCAD equivalent. That is would be done by dynamically linking to the FreeCAD components, so users are allowed to change it. However, this is often hard to achieve by today's requirements. At FreeCAD, we understand that the important point here is to not restrict the freedom given to FreeCAD users by the LGPL license. So an equivalent to dynamic linking is to offer the choice to your users, by making your users aware of the possibility to use FreeCAD for free. This can be done in a number of ways.

If any of the two conditions above are unacceptable to you or cannot be implemented, then you must make your FreeCAD component LGPL too and release the source code with all the modifications you made to it.

There is a special case called derivatives, which is when you publish basically a "rebranded" version of FreeCAD. Derivatives which are not open-source are prohibited by the LGPL license. The FreeCAD community is active and efficient in finding rebranded versions, reporting them to the platforms where they were found and exposing them until they are taken down.

Files

The models and other files produced with FreeCAD are not subject to any license stated above, nor bound to any kind of restriction or ownership. Your files are truly yours. You can set the owner of the file and specify your own license terms for the files you produce inside FreeCAD, via menu File → Project Information.

The FreeCAD logo is a trademark owned by the FPA (FreeCAD project association). This means the FPA is the sole body authorized to say who has the right to use the FreeCAD logo or not. The logo files, which are part of the FreeCAD source code or available elsewhere, for example on this wiki, are still all under the same licenses as the rest of FreeCAD (LGPL for the source code and Creative Commons for this wiki). You are still free to use the FreeCAD logo anywhere, on the same terms as the rest of FreeCAD, which means, basically, that you must use it to reference FreeCAD, and not use it, for example, for your own product, or any other way that is not referencing FreeCAD.

Statement of the main developer

I know that the discussion on the "right" licence for open source occupied a significant portion of internet bandwidth and so is here the reason why, in my opinion, FreeCAD should have this one.

I chose the LGPL for the project and I know the pro and cons about the LGPL and will give you some reasons for that decision.

FreeCAD is a mixture of a library and an application, so the GPL would be a little bit strong for that. It would prevent writing commercial modules for FreeCAD because it would prevent linking with the FreeCAD base libs. You may ask why commercial modules at all? Therefore Linux is good example. Would Linux be so successful when the GNU C Library would be GPL and therefore prevent linking against non-GPL applications? And although I love the freedom of Linux, I also want to be able to use the very good NVIDIA 3D graphic driver. I understand and accept the reason NVIDIA does not wish to give away driver code. We all work for companies and need payment or at least food. So for me, a coexistence of open source and closed source software is not a bad thing, when it obeys the rules of the LGPL. I would like to see someone writing a Catia import/export processor for FreeCAD and distribute it for free or for some money. I don't like to force him to give away more than he wants to. That wouldn't be good neither for him nor for FreeCAD.

Nevertheless this decision is made only for the core system of FreeCAD. Every writer of an application module may make his own decision.

Jürgen Riegel

—15 October 2006


</translate>

<translate>

</translate>

<translate>

In February 2022 FreeCAD bug tracking was migrated to GitHub Issues. The Mantis bug tracker described below is now in read-only mode.
link=https://freecadweb.org/tracker/MantisBT is the bugtracker framework FreeCAD uses
link=https://freecadweb.org/tracker/MantisBT is the bugtracker framework FreeCAD uses

The FreeCAD BugTracker is the place toː report bugs, submit feature requests, patches, or request to merge your branch if you developed something using Git. The tracker is divided into 'Workbenches', so please be specific and file your request in the appropriate subsection. In case of doubt, leave it in the "FreeCAD" section.


Recommended Workflow

As shown in the above flowchart, before creating tickets, please always first search the forums and bugtracker to discover if your issue is a known issue. This saves a lot of time/work for developers and volunteers that could be spending said time making FreeCAD even more awesome.

Reporting bugs

If you think you might have found a bug, you are welcome to report it as long as you have followed our step-by-step guidelinesː

  • Make sure you're using the most up to date version of FreeCAD. NOTEː your bug may be fixed in the Development (unstable) version. The average user runs the stable version of FC.
  • Make sure your bug is really a bug, that is, something that should be working but isn't. Make sure the same bug hasn't been reported before by first searching the bugtracker and forum.
    • Rememberː if you aren't sure, please don't hesitate to explain your problem/bug in the Help forum and ask what to do.
    • Noteː before posting to the forum please read the Forum Guidelines.
  • Describe as clearly as possible the problem, and how it can be reproduced. If we can not verify the bug, we might not be able to fix it.
    • This means reporting in a clear, well-formatted, step-by-step fashion so even an amateur user could reproduce.
    • Recommendedː Screenshots of the bug are also very helpful to include. Windows users: please do not attach screen captures in Word or PDF format. Use the Windows Snipping tool to save your capture as a PNG image.
    • Recommendedː Even better, an Animated gif or Screencast would also increase the likelihood of reproducing the issue.
  • Add an example FreeCAD file (.FCStd file) so devs/testers can quickly reproduce the bug.
    • Please don't zip your *.FCStd file, it is already zipped.
    • File attachments are limited in size. If your *.FCStd file is too big to attach, you can use an online storage service (many are free like Google Drive, Microsoft OneDrive, Dropbox).
  • Include all the information from the "Copy to Clipboard" button in the Help (menu) -> About FreeCAD dialogue. Make sure your data includes your OCC or OCE version.
  • Please file one separate report for each bug.
  • If your bug causes a crash in FreeCAD and you're on a system that supports it you can try running a debug backtrace and attach said trace to the ticket. This can save devs a lot of time pinpointing the source of the crash. See Debugging for more details.

Requesting features

If you want something to appear in FreeCAD that is not implemented yet, it is not a bug but a feature request.

  1. IMPORTANTː Before requesting a potential Feature Request please be certain that you are the first one doing so by searching the forums and the bugtracker. If you have concluded that there are no pre-existing tickets/discussions the next step is toː
  2. Start a forum thread to discuss your feature request with the community via the Open Discussion forum.
  3. Once the community agrees that this is a valid Feature, you then can open a ticket on the tracker (file it under feature request instead of bug).
  • NOTE #1 To keep things organized please remember to link the forum thread URL into the ticket and the ticket number (as a link) in to the forum thread.
  • NOTE #2 Keep in mind there are no guarantees that your wish will be fulfilled.
FreeCAD Bugtracker report page - use the dropdown to correctly designate what the ticket is

Submitting patches

In case you have programmed a bug fix, an extension or something else that can be of public use in FreeCAD, submit your patch as a "Pull Request" at GitHub.

  1. For a large, complex, or behavior-changing submission, open a forum thread in the Developer subforum to announce and discuss your patch. For small bugfixes this is not necessary.
  2. Submit your Pull Request (PR) to the FreeCAD GitHub repo. The PR submission message will be pre-filled with a checklist for you to follow to ensure that your submission has the best chance at speedy acceptance. If you haven't worked with git before or are unfamiliar with submitting a PR to github, please read our introduction to github wiki page.
  3. Be present for the discussion, both in the forum and in the GitHub pull request, so that your code can potentially be merged more effectively.

Requesting merge

(Same guidelines as Submiting patches)

If you have created a git branch containing changes that you would like to see merged into the FreeCAD code, you can ask there to have your branch reviewed and merged if the FreeCAD developers are OK with it. You must first publish your branch to a public git repository (github, gitlab, bitbucket, sourceforge etc...) and then give the URL of your branch in your merge request.

MantisBT Tips and Tricks

MantisBT Markup

MantisBT (Mantis Bug Tracker) has it's own unique markup.

  • @mention - works just like on GitHub where if you prepend '@' to someone's username they will receive an email that they have been 'mentioned' in a ticket thread
  • #1234 - By adding a hash tag in front of a number a shortcut to link to another ticket within MantisBT will present.
    Note: if you hover over a ticket it will show you the summary + if the ticket is closed, it will be struck-through like #1234.
  • ~5678 - a shortcut that links to a bug note within a ticket. This can be used to reference someone's response within the thread. Each person that posts will show a unique ~#### number next to their username. If you look at the image in the example, you see that the shortcut is referencing the ticket number:comment number of said ticket
  • <del></del> - Using these tags will strikeout text.
  • <code></code> - To present a line or block of code, use this tag and it will colorize and differentiate it elegantly.

MantisBT BBCode

In addition to the above MantisBT Markup one also has the possibility to use BBCode format. For a comprehensive list see the BBCode plus plugin page. Here is a list of supported BBCode tagsː
[img][/img] - Images
[url][/url] - Links
[email][/email] - Email addresses
[color=red][/color] - Colored text
[highlight=yellow][/highlight] - Highlighted text
[size][/size] - Font size
[list][/list] - Lists
[list=1][/list] - Numbered lists (number is starting number)
[*] - List items
[b][/b] - Bold
[u][/u] - underline
[i][/i] - Italic
[s][/s] - Strikethrough
[left][/left] - Left align
[center][/center] - Center
[right][/right] - Right align
[justify][/justify] - Justify
[hr] - Horizontal rule
[sub][/sub] - Subscript
[sup][/sup] - Superscript
[table][/table] - Table
[table=1][/table] - Table with border of specified width
[tr][/tr] - Table row
[td][/td] - Table column
[code][/code] - Code block
[code=sql][/code] - Code block with language definition
[code start=3][/code] - Code block with line numbers starting at number
[quote][/quote] - Quote by *someone* (no name)
[quote=name][/quote] - Quote by *name*

MantisBT <=> GitHub Markup

Below are special MantisBT Source-Integration plugin keywords which will link to the FreeCAD GitHub repo. See GitHub and MantisBT.

  • c:FreeCAD:git commit hash: - c stands for 'commit'. FreeCAD stands for the FreeCAD GitHub repo. 'git commit hash' is the specific git commit hash to reference. Note: the trailing colon is necessary. Exampleː cːFreeCADː709d2f325db0490016807b8fa6f49d1c867b6bd8ː
  • d:FreeCAD:git commit hash: - similar to the above, d stands for 'diff' which will provide a Diff view of the commit. Exampleː dːFreeCADː709d2f325db0490016807b8fa6f49d1c867b6bd8ː
  • p:FreeCAD:pullrequest: - similar to the above, p stands for Pull Request. Exampleː pːFreeCADː498ː

GitHub and MantisBT

The FreeCAD bugtracker has a plug-in called Source Integration which essentially ties both the FreeCAD GitHub repo to our MantisBT tracker. It makes it easier to track and associate git commits with their respective MantisBT tickets. The Source Integration plugin scans the git commit messages for specific keywords in order to execute the following actions:

Note The below keywords need to be added in the git commit message and not the PR subject

Remotely referencing a ticket

Using this pattern will automagically associate a git commit to a ticket (Note: this will not close the ticket.) The format MantisBT will recognize:

  • bug #1234
  • bugs #1234, #5678
  • issue #1234
  • issues #1234, #5678
  • report #1234
  • reports #1234, #5678

For the inquisitive here is the regex MantisBT uses for this operation:
/(?:bugs?|issues?|reports?)+\s*:?\s+(?:#(?:\d+)[,\.\s]*)+/i

Remotely resolving a ticket

The format MantisBT will recognize:

  • fix #1234
  • fixed #1234
  • fixes #1234
  • fixed #1234, #5678
  • fixes #1234, #5678
  • resolve #1234
  • resolved #1234
  • resolves #1234
  • resolved #1234, #5678
  • resolves #1234, #5678

For the inquisitive here is the regex MantisBT uses for this operation:
/(?:fixe?d?s?|resolved?s?)+\s*:?\s+(?:#(?:\d+)[,\.\s]*)+/i


</translate>

<translate>

</translate>

<translate>

This page explains step by step how to compile FreeCAD 0.19 or newer on Windows using Microsoft's MSVC compiler. For information on using MSYS2/MinGW see Compile on MinGW. For other platforms see Compiling.

Prerequisites

Compiling FreeCAD on Windows requires several tools and libraries.

Required

  • A compiler. FreeCAD is tested with Visual Studio (MSVC)—other compilers may work, but instructions for use are not included here. Fore more details, see the section Compiler below.
  • Git (There are also GUI frontends available for Git, see the next section.)
  • CMake version 3.11.x or newer.
    Hint: Choosing the option Add CMake to the system PATH for all users when installing CMake will make CMake accessible from the Windows command prompt, which can be useful.
  • The LibPack. This is a single package containing all of the libraries necessary to compile FreeCAD on Windows. Download the version of the LibPack that corresponds to the version of FreeCAD you want to compile. To compile FreeCAD 0.20 download the LibPack version 2.6, for FreeCAD 0.19 download the LibPack version 1.0. Extract the LibPack to a convenient location. (If your computer does not recognize the .7z extension, you must install the program 7-zip.)
    Note: It is highly recommended to compile FreeCAD with the compiler version the LibPack is designed for. For example, you might run into problems compiling FreeCAD 0.20 using MSVC 2017 because the LibPack is designed to be built with MSVC 2019 or newer.
    To update your LibPack later, see the section Updating the LibPack.

Optional programs

  • A GUI frontend for Git. There are several frontends available, see this list. The main benefit of a frontend is that you don't have to learn the Git commands to get the source code of FreeCAD or to send patches to the GitHub repository of FreeCAD.

In the following we describe source code handling using the TortoiseGit frontend. This frontend integrates directly into Windows file explorer and has a large user community to get help in case you have problems.

  • NSIS is used to generate the FreeCAD Windows installer.

Source code

Now you can get the source code of FreeCAD:

Using a frontend

When using the Git frontend TortoiseGit:

  1. Create a new folder where the source code will be downloaded.
  2. Right-click on this folder in the Windows file explorer and select Git Clone in the context menu.
  3. A dialog will appear. In it, enter the URL for the FreeCAD Git repository

</translate> https://github.com/FreeCAD/FreeCAD.git <translate>

and click OK.

The latest source code will be downloaded from the FreeCAD Git repository and the folder will be tracked by Git.

Using the command line

To create a local tracking branch and download the source code, open a terminal (command prompt) and switch there to the directory you want the source, then type:

</translate>

git clone https://github.com/FreeCAD/FreeCAD.git

<translate>

Compiler

The default (recommended) compiler is MS Visual Studio (MSVC). Though it may be possible to use other compilers, for example gcc via Cygwin or MinGW, it is not tested or covered here.

You can get a free version of MSVC (for individual usage) by downloading the Community edition of MS Visual Studio.

For those who want to avoid installing the huge MSVC for the mere purpose of having a compiler, see CompileOnWindows - Reducing Disk Footprint.

Note: Although the Community edition of MSVC is free, to use the IDE for more than a 30-day trial period you must create a Microsoft account. If you will only compile using the command line, you don't need the IDE and thus no Microsoft account.

As a free and OpenSource alternative IDE you can use KDevelop. You can use KDevelop to modify and write C++ code but must use the command line to compile.

Optional system path configuration

Optionally you can include the paths to some folders to the system PATH variable. This is helpful if you want to access programs in these folders from the command line/powershell or if you want special programs to be found by the compiler or CMake. Besides this, adding folders to the PATH might be necessary if you did not use the corresponding options when installing the program.

  • You can include the folder of your LibPack in your system PATH variable. This is useful if you plan to build multiple configurations/versions of FreeCAD.
  • If you did not use the option to add CMake to the PATH while installing it, add its installation folder

C:\Program Files\CMake\bin to the PATH.

  • If you did not use the option to add TortoiseGit to the PATH while installing it, add its installation folder

C:\Program Files\TortoiseGit\bin to the PATH.

To add folder paths to the PATH variable:

  1. In the Windows Start menu Right click on Computer and choose Properties.
  2. In the appearing dialog click on Advanced system settings.
  3. Another dialog will open. Click there in the tab Advanced on Environment Variables.
  4. Again another dialog will open. Select then the variable Path and click on Edit.
  5. And again another dialog will open. Click there on New and add to path to the folder of Git or the LibPack.
  6. Finally press OK and close all dialogs by pressing OK as well.

Configuration

Once you have all of the necessary tools, libraries, and FreeCAD source code, you are ready to begin the configuration and compilation process. This process will proceed in five steps:

  1. Run CMake once to examine your system and begin the configuration progress (this will report that it failed).
  2. Adjust necessary CMake settings to set the locations of the LibPack and enable Qt5.
  3. Re-run CMake to finalize the configuration (this time it should succeed).
  4. Use CMake to generate the Visual Studio build system.
  5. Use Visual Studio to build FreeCAD.

CMake

First, configure the build environment using CMake:

  1. Open the CMake GUI
  2. Specify the source folder of FreeCAD.
  3. Specify a build folder. This can be build in the folder you cloned the repo because this path is ignored by git. Do not use the source folder. CMake will create this folder if it does not exist.
  4. Click Configure.
  5. In the dialog that appears specify the generator you want to use: in most cases you will use the defaults in this dialog. For the standard MS Visual Studio use Visual Studio xx 2yyy where xx is the compiler version and 2yyy the year of its release. It is recommended to use the default option Use default native compilers.

Note: It is important to specify the correct bit variant. If you have the 64-bit variant of the LibPack you must also use the x64 compiler.

This will begin the configuration and will fail because of missing settings. This is normal, you have not yet specified the location of the LibPack. However, there are other failures that might occur that require some further action on your part.

If it fails with the message that Visual Studio could not be found, the CMake support in MSVC is not yet installed. To do this:

  1. Open the MSVC IDE
  2. Use the menu Tools → Get Tools and Features
  3. In the Workloads tab enable Desktop development with C++
  4. On the right side you should now see that the component Visual C++ tools for CMake will be installed.
  5. Install it.

If it fails with a message about the wrong Python version or missing Python, then:

  1. Use the "Search:" box in CMake to search for the string "Python"
  2. If you see there a path like C:/Program Files/Python38/python.exe, CMake recognized the Python that is already installed on your PC, but that version is not compatible with the LibPack. Since the LibPack includes a compatible version of Python, modify the following Python settings in CMake to its paths (assuming the LibPack is in the folder D:/FreeCAD-build/FreeCADLibs_2_8_x64_VC2019):

If there is no error about Visual Studio or Python, everything is fine, but CMake does not yet know all necessary settings. Therefore now:

  1. Search in CMake for the variable FREECAD_LIBPACK_DIR and specify the location of the LibPack folder you downloaded earlier.
  2. (If building FreeCAD 0.19) Search for the variable BUILD_QT5 and enable this option.
  3. (If planning on running directly from the build folder such as for debugging) Search for and enable the following options:
    • FREECAD_COPY_DEPEND_DIRS_TO_BUILD
    • FREECAD_COPY_LIBPACK_BIN_TO_BUILD
    • FREECAD_COPY_PLUGINS_BIN_TO_BUILD
  4. Click Configure again.

There should now be no errors. If you continue to encounter errors that you cannot diagnose, visit the Install/Compile forum on the FreeCAD forum website. If CMake proceeded correctly, click on Generate. After this is done you can close CMake and start the compilation of FreeCAD using Visual Studio. However, for the first compilation keep it open in case you want or need to change some options for the build process.

Options for the build process

The CMake build system gives you control over some aspects of the build process. In particular, you can switch on and off some features or modules using CMake variables.

Here is a description of some of these variables:

Variable name Description Default
BUILD_XXX Build FreeCAD with the component XXX. If you don't want/need to compile e.g. the workbench OpenSCAD, disable the variable BUILD_OPENSCAD. FreeCAD will then not have this workbench.

Note: Some components are required for other components. If you for example uncheck BUILD_ROBOT CMake will inform you that then the component Path cannot be compiled correctly. Therefore check the CMake output after you changed a BUILD_XXX option!

depends
BUILD_ENABLE_CXX_STD The version of the C++ language standard. C++14 is the highest possible for FreeCAD 0.19 while at least C++17 is required for FreeCAD 0.20. See also the note in the section Building with Visual Studio 15 (2017) and 16 (2019) depends
BUILD_DESIGNER_PLUGIN To build the Qt Designer plugin, see this section below OFF
BUILD_FLAT_MESH Necessary to have a build that includes the CreateFlatMesh feature OFF
CMAKE_INSTALL_PREFIX The output folder when building the target INSTALL, see also the section Running and installing FreeCAD Windows default program installation folder
FREECAD_COPY_DEPEND_DIRS_TO_BUILD Copies depending libraries needed to execute the FreeCAD.exe to the build folder. See also the section Running and installing FreeCAD.
Note: the options FREECAD_COPY_XXX only appear if the libraries were not already copied. If you only need to upgrade/change to another LibPack version, see the section Updating the LibPack. If you want to bring back the options for some reason, you need to delete all folders in your build folder, except for the LibPack folder. In CMake delete the cache and start as if you compile for the first time.
OFF
FREECAD_COPY_LIBPACK_BIN_TO_BUILD Copies the LibPack binaries needed to execute the FreeCAD.exe to the build folder. See also the section Running and installing FreeCAD. OFF
FREECAD_COPY_PLUGINS_BIN_TO_BUILD Copies Qt's plugin files needed to execute the FreeCAD.exe to the build folder. See also the section Running and installing FreeCAD. OFF
FREECAD_LIBPACK_USE Switch the usage of the FreeCAD LibPack on or off ON
FREECAD_LIBPACK_DIR Directory where the LibPack is FreeCAD's source code folder
FREECAD_RELEASE_PDB Create debug libraries (*.pdb) also for release builds. It doesn't affect the speed (like a real debug build would do) and can be very useful to locate crashes in FreeCAD code. In case FreeCAD crashes a crash.dmp file will be created that can be loaded with MSVC and if you have the corresponding PDB files plus the source code of that version you can debug through the code. Without the PDB files it's not possible to debug the code and all what the debugger shows is the name of the DLL where the crash has occurred. ON
FREECAD_USE_MP_COMPILE_FLAG Adds the /MP (multiprocessor) option to the Visual Studio projects, enabling speedups on multi-core CPUs. This can greatly accelerate builds on modern processors.
Note: If you turn off FREECAD_USE_PCH, the compilation can quickly overload your heap space, even if you have 16 GB RAM.
ON
FREECAD_USE_PCH Precompiles the headers in order to save compilation time. ON
FREECAD_USE_PYBIND11 Includes the PyBind11 library. Necessary to have a build that includes the CreateFlatMesh feature.
Note: after turning it on you might get a configuration error. Just configure again and the problem should go away.
OFF

Building FreeCAD

Depending on your compiler, the process for building FreeCAD will be slightly different. In the following sections known workflows are described. If you are building with Qt Creator, jump to Building with Qt Creator (outdated), otherwise proceed directly:

</translate>

<translate>

Building with Visual Studio 15 (2017) or newer

</translate>

<translate>

Release Build

  1. Start the Visual Studio IDE. This can either be done by pressing the button Open Project in the CMake GUI or by double-clicking on the file FreeCAD.sln that you find in your build folder.
  2. In the toolbar of the MSVC IDE assure that you use for the first compilation Release.
  3. There is a window called Solution Explorer. It lists all possible compilation targets. To start a full compilation, right-click on the target ALL_BUILD and then choose Build.

This will now take quite a long time.

To compile a ready-to use FreeCAD, compile the target INSTALL, see the section Running and installing FreeCAD.

If you don't get any errors you are done. Congratulations! You can exit MSVC or keep it open.

Important: Since Visual Studio 17.4 you cannot use the code optimization that is on by default for the target SketcherGui. If you do, angle constraints will be misplaced in sketches. To fix this, right-click on this target in the MSVC solution explorer and select the last entry Properties in the context menu. In the appearing dialog go to C/C++ → Optimization and there disable the setting Optimization. Finally build the target ALL_BUILD again.

Debug Build

For a debug build it is necessary that the Python is used that is included in the LibPack. To assure this:

  1. Search in the CMake GUI for "Python"
  2. If you see there a path like C:/Program Files/Python38/python.exe, CMake recognized the Python that is installed on your PC and not the one of the LibPack. In this case adapt these different Python settings in CMake to this (assuming the LibPack is in the folder D:\FreeCAD-build\FreeCADLibs_12.5.2_x64_VC17):

As prerequisite for the debug build, you need to do this:

  1. Copy the content of the LibPack folder bind to the bin folder of the FreeCAD build folder (overwrite the existing files).
  2. Copy the content of the LibPack folder libd to the lib folder of the FreeCAD build folder.

Now you can compile:

  1. Start the Visual Studio IDE. This can either be done by pressing the button Open Project in the CMake GUI or by double-clicking on the file FreeCAD.sln that you find in your build folder.
  2. In the toolbar of the MSVC IDE assure that you use for the first compilation Debug.
  3. There is a window called Solution Explorer. It lists all possible compilation targets. To start a full compilation, right-click on the target ALL_BUILD and then choose Build in the context menu.

This will now take quite a long time.

If there were no compilation errors, and if the FREECAD_COPY_* options mentioned in the CMake Configuration step above were enabled, you can start the debug build:

  1. Right-click on the target FreeCADMain and then choose Set as Startup Project in the context menu.
  2. Finally click in the toolbar on the button with the green triangle named Local Windows Debugger.

This will start the debug build of FreeCAD and you can use the MSVC IDE to debug it.

Video Resource

An English language tutorial that begins with configuration in CMake Gui and continues to the `Build` command in Visual Studio 16 2019 is available unlisted on YouTube at Tutorial: Build FreeCAD from source on Windows 10. </translate>

<translate>

Building with Qt Creator (outdated)

</translate>

<translate>

Installation and configuration of Qt Creator

  • Download and install Qt Creator
  • Tools → Options → Text Editor → Behavior tab:
    • File Encodings → Default Encodings:
    • Set to: ISO-8859-1 /...csISOLatin1 (Certain characters create errors/warnings with Qt Creator if left set to UTF-8. This seems to fix it.)
  • Tools → Options → Build & Run:
    • CMake tab
      • Fill Executable box with path to cmake.exe
    • Kits tab
      • Name: MSVC 2008
      • Compiler: Microsoft Visual C++ Compiler 9.0 (x86)
      • Debugger: Auto detected...
      • Qt version: None
    • General tab
      • Uncheck: Always build project before deploying it
      • Uncheck: Always deploy project before running it

Import project and building

  • File → Open File or Project
  • Open CMakeLists.txt which is in the top level of the source
  • This will start CMake
  • Choose build directory and click next
  • Set generator to NMake Generator (MSVC 2008)
  • Click Run CMake. Follow the instructions depicted above to configure CMake to your liking.

Now FreeCAD can be built

  • Build → Build All
  • This will take a long time...

Once complete, it can be run: There are 2 green triangles at the bottom left. One is debug. The other is run. Pick whichever you want. </translate>

<translate>

Command line build

</translate>

<translate>

The steps how to compile from the command line depends on the compiler. For MSVC 2017 the steps are:

  1. In Windows start menu go to Visual Studio 2017 → Visual Studio Tools and choose Developer Command Prompt for VS 2017
  2. Change to your build folder.
  3. Execute the command

</translate>

msbuild ALL_BUILD.vcxproj /p:Configuration=Release

<translate>

or

</translate>

msbuild INSTALL.vcxproj /p:Configuration=Release

<translate>

These steps can also be automaized. Here is for example a solution for MSVC 2017:

  1. Download the script compile-FC.txt.
  2. Rename it to compile-FC.bat
  3. In Windows file explorer Shift+Right-click on your build folder and use from the context menu Command prompt here.
  4. Execute the command

</translate>

compile-FC install

<translate>

Instead of calling compile-FC with the option install you can also use debug or release:

debug   - compile FreeCAD in debug configuration

release - compile FreeCAD in release configuration

install    - compile FreeCAD in release configuration and create an install setup

</translate>

<translate>

Running and installing FreeCAD

There are 2 methods to run the compiled FreeCAD:

Method 1: You execute the FreeCAD.exe that you find in your build folder in the subfolder bin

Method 2: You build the target INSTALL

Method 2 is the simpler one because it automatically assures that all libraries needed to run the FreeCAD.exe are in the correct folder. The FreeCAD.exe and the libraries will be output in the folder you specified in the CMake variable CMAKE_INSTALL_PREFIX.

For Method 1 you need to enable the FREECAD_COPY_* options mentioned in the CMake Configuration step above.

Troubleshooting

When running FreeCAD you may encounter missing DLLs when using certain workbenches or features of workbenches. The error message in FreeCAD's console will not tell you what DLL is missing. To find this out you must use an external tool:

import os
os.system(r"~\DependenciesGui.exe")

Note: Instead of the ~ you must specify the full path to the DependenciesGui.exe on your system.

  • Now drag in the *.pyd file of the workbench with which you get missing DLLs reported.

Updating the build

FreeCAD is very actively developed. Therefore its source code changes almost daily. New features are added and bugs are fixed. To benefit from these source code changes, you must rebuild your FreeCAD. This is done in two steps:

  1. Updating the source code
  2. Recompilation

Updating the source code

Using a frontend

When using the Git frontend TortoiseGit:

  1. Right-click on your FreeCAD source code folder in the Windows file explorer and select Pull in the context menu.
  2. A dialog will appear. Select there what development branch you want to get. master is the main branch. Therefore use this unless you want to compile a special new feature from a branch that has not yet been merged to master. (For more about Git branches, see Git development process.)

Finally click OK.

Using the command line

Open a terminal (command prompt) and switch there to your source directory. Then type:

</translate>

git pull https://github.com/FreeCAD/FreeCAD.git master

<translate>

where master the the name of the main development branch. If you want to get code from another branch, use its name instead of master.

Recompilation

  1. Open the MSVC IDE by double-clicking either on the file FreeCAD.sln or on the file ALL_BUILD.vcxproj in your build folder.
  2. Continue with step 2 from the section Building with Visual Studio 15 2017.

Updating the LibPack

If a new major version of a third-party dependency like Open Cascade is released, or if a third-party dependency has important bug fixes, a new LibPack is released. You can find the latest version here.

To update your LibPack the following recipe is best practice:

  1. Delete the bin folder in your build folder.
  2. Switch to your local LibPack folder and delete everything there.
  3. Extract the content of the new LibPack ZIP file into the existing, but now empty, local LibPack folder.
  4. Open CMake and there press the button Configure and then the button Generate. This recreates the bin folder you just deleted and also copies the new LibPack files into it.
  5. In CMake click the button Open Project and the MSVC IDE will open.
  6. In the MSVC IDE build the target INSTALL.

Tools

In order to join the FreeCAD development you should compile and install the following tools:

Qt Designer plugin

FreeCAD uses Qt as toolkit for its user interface. All dialogs are setup in UI-files that can be edited using the program Qt Designer that is part of any Qt installation and also included in the LibPack. FreeCAD has its own set of Qt widgets to provide special features like adding a unit to input fields and to set preferences properties.

Compilation

The plugin cannot be loaded by the Qt Designer if it was compiled using another Qt version than the one your Qt Designer/Qt Creator is based on. Therefore the plugin must be compiled together with FreeCAD:

  • In the CMake options (see this section above) enable the option BUILD_DESIGNER_PLUGIN and reconfigure.
  • open MSVC and build the target FreeCAD_widgets

As result you will get the plugin file 'FreeCAD_widgets.dll in the folder
~\src\Tools\plugins\widget\Release

Installation

To install the plugin, copy the DLL either to:

  • If you use the LibPack: to the folder
    ~\FreeCADLibs_2_8_x64_VC2019\plugins\designer
  • If you have a full Qt installation: you can choose between the folder
    C:\Qt\5.15.2\msvc2019_64\plugins\designer
    or
    C:\Qt\5.15.2\msvc2019_64\bin\designer (you must first create the designer subfolder.)
    (adapt the paths to your installation!).

Finally (re)start Qt Designer and check its menu Help → Plugins. If the plugin FreeCAD_widgets.dll is listed as being loaded, you can now design and change FreeCAD's .ui files. If not, you must compile the DLL by yourself.

If you prefer using Qt Creator instead of Qt Designer, the plugin file must be placed in this folder:
C:\Qt\Qt5.15.2\Tools\QtCreator\bin\plugins\designer
Then (re)start Qt Creator, switch to the mode Design and then check the menu Tools → Form Editor → About Qt Designer Plugins. If the plugin FreeCAD_widgets.dll is listed as being loaded, you can now design and change FreeCAD's .ui files. If not, you must compile the DLL by yourself.

Thumbnail Provider

FreeCAD has the feature to provide preview thumbnails for *.FCStd files. That means that in the Windows file explorer *.FCStd files are shown with a screenshot of the model it contains. To provide this feature, FreeCAD needs to have the file FCStdThumbnail.dll installed to Windows.

Installation

The DLL is installed this way:

  1. Download this ZIP file and extract it.
  2. Open a Windows command prompt with administrator privileges (these privileges are a requirement).
  3. Change to the folder where the DLL is.
  4. Execute this command
    regsvr32 FCStdThumbnail.dll

So check if it works, assure that in FreeCAD the preferences option Save thumbnail into project file when saving document is enabled and save a model. Then view in Windows Explorer the folder of the saved model using a symbol view. You should now see a screenshot of the model in the folder view.

Compilation

To compile the FCStdThumbnail.dll

  1. Change to the FreeCAD source folder
    ~\src\Tools\thumbs\ThumbnailProvider
  2. Open the CMake GUI
  3. Specify there as source folder the one you are currently in.
  4. Use the same folder as build folder.
  5. Click Configure
  6. In the appearing dialog, specify the generator according to the one you want to use. For the standard MS Visual Studio use Visual Studio xx 2yyy where xx is the compiler version and 2yyy the year of its release. It is recommended to use the default option Use default native compilers.
    Note: It is important to specify the correct bit variant. If you have the 64bit variant of LibPack you must also use the x64 compiler.
  7. Click on Generate.
  8. You should now have the file ALL_BUILD.vcxproj in the folder ~\src\Tools\thumbs\ThumbnailProvider. Double-click on it and the MSVC IDE will open.
  9. In the toolbar of the MSVC IDE assure that you use the compilation target Release.
  10. There is a window called Solution Explorer. Right-click there on ALL_BUILD and then choose Build.
  11. As result you should now have a FCStdThumbnail.dll in the folder ~\src\Tools\thumbs\ThumbnailProvider\release that you can install as described above.

Compiling Open Cascade

The LibPack comes with a version of Open Cascade that is suitable for general use. However, under some circumstances you may wish to compile against an alternate version of Open Cascade, such as one of their official releases, or a patched fork.

When compiling Open Cascade for FreeCAD note that there is no guarantee that FreeCAD will work with all versions of Open Cascade. Note also that when you are using the Netgen library, you must use the a NetGen version that it approved to compile with the Open Cascade version you like to compile.

To compile:

  • Then open the CMake GUI to configure the build system in a similar manner to building FreeCAD. These CMake options have to be set (or explicitly not set):
Variable name Description Default
3RDPARTY_DIR The path to 3rdparty components. It is recommended to use the folder as input where your used LibPack is. Explicitly leave this field empty. empty
3RDPARTY_DOXYGEN_EXECUTABLE The path to the executable of the 3rdparty component Doxygen. It is recommended to install Doxygen. CMake will then find it automatically. empty
3RDPARTY_FREETYPE_DIR The path to the necessary 3rdparty component Freetype. It is recommended to use the folder as input where your used LibPack is. empty
3RDPARTY_RAPIDJSON_DIR Only available if USE_RAPIDJSON is used. The path to the 3rdparty component RapidJSON. It is recommended NOT to use an existing LibPack folder as input. You can use the RapidJSOn folder from a LibPack, but copy it to a new folder and use this new folder as input. empty
3RDPARTY_TCL_DIR The path to the necessary 3rdparty component TCL. It is recommended NOT to use an existing LibPack folder as input. Take for example one of these releases, extract it and take this as input folder for CMake. empty
3RDPARTY_TK_DIR The path to the necessary 3rdparty component TK. It is recommended NOT to use an existing LibPack folder as input. Take for example one of these releases, extract it and take this as input folder for CMake. empty
3RDPARTY_VTK_DIR Only available if USE_VTK is used. The path to the necessary 3rdparty component VTK. It is recommended to use the folder as input where your used LibPack is. If you use another folder please assure that you don't use VTK 9.x or newer. empty
BUILD_RELEASE_DISABLE_EXCEPTIONS Disables exception handling for release builds. For FreeCAD you must set it to OFF. ON
INSTALL_DIR The output folder when building the target INSTALL. If the build was successful, take the files from this folder to update your LibPack. Windows default program installation folder
INSTALL_DIR_BIN The output subfolder for the DLL when building the target INSTALL. You must change it to bin win64/vc14/bin
INSTALL_DIR_LIB The output subfolder for the .lib files when building the target INSTALL. You must change it to lib win64/vc14/lib
USE_RAPIDJSON To compile Open Cascade with support for RapidJSON. Enabling this is mandatory in order to get support for the file format glTF. OFF
USE_VTK To compile Open Cascade with support for VTK. Enabling this is optimal. You can use this to build Open Cascade's VTK bridge. OFF
  • Open the project in Visual Studio and first build the ALL_BUILD and then INSTALL targets in the Release mode.
  • Repeat building the two targets in the Debug mode.

To build FreeCAD using the self-compiled Open Cascade, you must do the following:

  • Copy all folders from the INSTALL_DIR to your LibPack folder (overwrite the existing files)
  • Switch to the LibPack folder and go there to the subfolder cmake
  • Open there the file OpenCASCADEDrawTargets.cmake with a text editor
  • Search there for absolute paths to your LibPack folder and remove them. So e.g. the absolute path
    D:/FreeCADLibs_12.5.4_x64_VC17/lib/freetype.lib
    becomes just
    freetype.lib
  • Do the same for the file OpenCASCADEVisualizationTargets.cmake

Compiling Netgen

The LibPack comes with a version of Netgen that will was tested to be build with the Open Cascade version of the LibPack. The problem is that every new release of Netgen changes the API. Also every new release of Open Cascade does the same. Therefore one cannot just easily change the Netgen version.

However, you might build Netgen nevertheless. This is an easy task:

  • First obtain the Netgen source code, either directly from Netgen 's git repository.
  • Then open the CMake GUI to configure the build system in a similar manner to building FreeCAD. These CMake options have to be set:
Variable name Description Default
CMAKE_INSTALL_PREFIX The output folder when building the target INSTALL. If the build was successful, take the files from this folder to update your LibPack. C:/netgen
OpenCasCade_DIR The path to the CMake files of Open Cascade. If you built Open Cascade as described in the section Compiling Open Cascade you can use the subfolder cmake of there folder you used as INSTALL_DIR. If not, use the subfolder cmake of your LibPack. Note hereby that the LibPack must then already contain a proper Open Cascade build. Independent what folder you use, you must now also create there a subfolder lib and copy in the files freetype.lib and freetyped.lib from your LibPack. empty
USE_GUI set it to OFF ON
USE_NATIVE_ARCH set it to OFF; this is only necessary important to support older CPU that don't have the AVX2 instruction set ON
USE_OCC set it to ON OFF
USE_PYTHON set it to OFF ON
USE_SUPERBUILD set it to OFF ON
ZLIB_INCLUDE_DIR The path to the necessary 3rdparty component zlib. It is recommended to use the folder as input where your used LibPack is. empty
ZLIB_LIBRARY_DEBUG The path to the ZLib file zlibd.lib. It is located in the subfolder lib of your LibPack folder. empty
ZLIB_LIBRARY_RELEASE The path to the ZLib file zlib.lib. It is located in the subfolder lib of your LibPack folder. empty
  • Additionally you need to add a new CMake entry:

name: CMAKE_DEBUG_POSTFIX, type: string, content: _d
This assures that he file names of the debug libraries get another name than the release libraries and can later not be accidentally exchanged.

  • Press the Configure button in CMake to generate the *.cmake files.
  • Only necessary if older CPU should be supported that don't have the AVX2 instruction set:
    • Search your Netgen build folder for the file netgen-targets.cmake and open it with a text editor. Remove the setting ;/arch:AVX2 in the Option INTERFACE_COMPILE_OPTIONS.
    • Press the Configure button in CMake again.
  • Press the Generate button in CMake.
  • Open the project in Visual Studio and first build the ALL_BUILD and then INSTALL targets in the Release mode.
  • Repeat building the two targets in the Debug mode.

To build FreeCAD using the self-compiled Netgen, you must do the following:

  • Copy all folders from the CMAKE_INSTALL_PREFIX to your LibPack folder (overwrite the existing files)

References

See also


</translate>

CompileOnUnix

<translate>

There is an experimental FreeCAD Docker container that is being tested for FreeCAD development. Read more about it at Compile on Docker

</translate>

<translate>

Overview

This page describes how to compile the FreeCAD source code on macOS. For other platforms, see Compiling.

These instructions have been tested on macOS Catalina with standard XCode 11.6. It is known to work on macOS BigSur Beta with XCode 12.0 beta. If you plan to use XCode Beta, please be sure to download Command Line Tools add on through a dmg package to workaround some libz dependency issues.

This page serves as a quick start, and is not intended to be comprehensive with regard to describing all the available build options.

If you just want to evaluate the latest pre-release build of FreeCAD, you can download pre-built binaries from here.

Install Prerequisites

The following software must be installed to support the build process.

Homebrew Package Manager

Homebrew is a command line based package manager for macOS. The Homebrew main page provides an installation command line that you simply paste into a terminal window.

CMake

CMake is a build tool that generates a build configuration based on variables you specify. You then issue the 'make' command to actually build that configuration. The command-line version of CMake is automatically installed as part of the Homebrew installation, above. If you prefer to use a GUI version of CMake, you can download it from here.

Install Dependencies

FreeCAD maintains a Homebrew 'cask' which installs the required formulas and dependencies. Issue the following brew commands in your terminal.

</translate>

brew tap freecad/freecad
brew install eigen
brew install --only-dependencies freecad

<translate>

brew install may take quite a while, so you may want go grab a beverage. :-).

Alternately, you can install the individual dependencies manually by installing the following packages using brew install ...:

  • cmake
  • swig
  • boost
  • boost-python3
  • eigen
  • gts
  • vtk
  • xerces-c
  • qt@5 - Only Qt5 is currently supported, support for Qt6 is a work-in-progress
  • opencascade
  • doxygen
  • pkgconfig
  • coin3d - Note that as of this writing (Nov. 2022) this will install an unusable version of pyside@2 as a dependency.

There are several packages that are only available when you have tapped the freecad cask: you must do that (brew tap freecad/freecad). Due to some historical bug workarounds, at the time of this writing (Nov. 2022) the versions of PySide2 and Shiboken2 installed by Homebrew are not usable because they force the use of Py_Limited_API, which FreeCAD does not support. It is expected that this workaround will be removed in the coming months, but in the meantime you must use the FreeCAD cask versions of PySide and Shiboken. Use brew install ..., install the following packages:

  • freecad/freecad/pyside2@5.15.5
  • freecad/freecad/shiboken2@5.15.5
  • freecad/freecad/med-file
  • freecad/freecad/netgen

You will also need to "link" PySide and Shiboken:

brew link freecad/freecad/pyside2@5.15.5 freecad/freecad/shiboken2@5.15.5

In some cases the packages installed by Homebrew do not use the same Python version: for example, at the time of this writing PySide2 uses Python 3.10, but boost-python3 uses Python 3.11. While it is possible to "roll back" the more advanced version (so that in this case boost-python3 uses Python 3.10) this is an advanced operation, and in many cases it is best to wait for an update to the other package. If you want to pursue that path anyway, look at the "brew extract" command, which you can use to extract a formula into a new cask (typically freecad/freecad). You can then edit that formula as needed.

You will need to set the path to Qt: Qt5 is currently supported, while support for Qt6 is a work-in-progress. Set FREECAD_QT_VERSION to "Auto" or "5" to select Qt5 (the default). On the command line, use something like:

cmake \
  -DCMAKE_BUILD_TYPE="Release" \
  -DPYTHON_EXECUTABLE="/usr/local/bin/python3" \
  -DQt5_DIR="/usr/local/Cellar/qt@5/5.15.7/lib/cmake/Qt5" \
  -DPySide2_DIR="/usr/local/Cellar/pyside2@5.15.5/5.15.5/lib/cmake/PySide2-5.15.5" \
  -DShiboken2_DIR="/usr/local/Cellar/shiboken2@5.15.5/5.15.5_1/lib/cmake/Shiboken2-5.15.5" \
  ../freecad-source

Get the source

In the following instructions, the source and build folders are created side-by-side under

</translate>

/Users/username/FreeCAD

<translate>

but you can use whatever folders you want.

</translate>

mkdir ~/FreeCAD
cd ~/FreeCAD

<translate>

The following command will clone the FreeCAD git repository into a directory called FreeCAD-git.

</translate>

git clone https://github.com/FreeCAD/FreeCAD FreeCAD-git

<translate>

Create the build folder.

</translate>

mkdir ~/FreeCAD/build

<translate>

Run CMake

Next, we will run CMake to generate the build configuration. Several options must be passed to CMake. The following table describes the options and gives some background.

CMake Options

Name Value Notes
CMAKE_BUILD_TYPE Release (STRING) Release or Debug. Debug is generally used for developer-level testing but may also be required for user-level testing and troubleshooting.
CMAKE_PREFIX_PATH "/usr/local/opt/qt5152;" ... (PATH) Required to build with Qt5. See note below. You also need to add path to VTK libraries and NGLIB libraries cmake configuration file.
FREECAD_CREATE_MAC_APP 1 (BOOL) Create a FreeCAD.app bundle at the location specified in CMAKE_INSTALL_PREFIX, when the 'make install' command issued.
CMAKE_INSTALL_PREFIX "./.." (PATH) Path where you want to generate the FreeCAD.app bundle.
FREECAD_USE_EXTERNAL_KDL 1 (BOOL) Required.
BUILD_FEM_NETGEN 1 (BOOL) Required if choosing to build the FEM tools.

Note: Command line to generate CMAKE_PREFIX_PATH:

</translate>

ls -d $(brew list -1 | grep qt | tail -1 | xargs brew --cellar)/*/lib/cmake

<translate>

CMake GUI

Open the CMake app, and fill in the source and build folder fields. In this example, it would be /Users/username/FreeCAD/FreeCAD-git for the source, and /Users/username/FreeCAD/build for the build folder.

Next, click the Configure button to populate the list of configuration options. This will display a dialog asking you to specify what generator to use. Leave it at the default Unix Makefiles. Configuring will fail the first time because there are some options that need to be changed. Note: You will need to check the Advanced checkbox to get all of the options.

Set options from the table above, then click Configure again and then Generate.

CMake command line

Enter the following in the terminal.

</translate>

export PREFIX_PATH="/usr/local/opt/qt5152;\
/usr/local/Cellar/nglib/v6.2.2007/Contents/Resources;\
/usr/local/Cellar/vtk@8.2/8.2.0_1/lib/cmake;"

<translate>

</translate>

$cd ~/FreeCAD/build
$cmake \
  -DCMAKE_BUILD_TYPE="Release"   \
  -DBUILD_QT5=1                  \
  -DWITH_PYTHON3=1               \
  -DCMAKE_PREFIX_PATH="$PREFIX_PATH" \
  -DPYTHON_EXECUTABLE="/usr/local/bin/python3" \
  -DFREECAD_USE_EXTERNAL_KDL=1   \
  -DCMAKE_CXX_FLAGS='-std=c++14' \
  -DBUILD_FEM_NETGEN=1           \
  -DFREECAD_CREATE_MAC_APP=1     \
  -DCMAKE_INSTALL_PREFIX="./.."  \
  ../FreeCAD-git/

<translate>

Run make

Finally, from a terminal run make to compile and link FreeCAD, and generate the app bundle.

</translate>

cd ~/FreeCAD/build
make -j5 install

<translate>

The -j option specifies how many make processes to run at once. One plus the number of CPU cores is usually a good number to use. However, if compiling fails for some reason, it is useful to rerun make without the -j option, so that you can see exactly where the error occurred.

See also Compiling - Speeding up.

If make finishes without any errors, you can now launch FreeCAD by double clicking the executable in the Finder.

Updating from Github

FreeCAD development happens fast; every day or so there are bug fixes or new features. To get the latest changes, use git to update the source directory (see Source code management), then re-run the CMake and make steps above. It is not usually necessary to start with a clean build directory in this case, and subsequent compiles will generally go much faster than the first one.

Building with Qt4 and Python 2.7

FreeCAD has transitioned from Qt 4 to Qt 5 as well as homebrew. Qt 4 is no longer available as an option for new build on macOS following Qt 5 transition. Python 2.7 has been deprecated within homebrew and upcoming macOS and we do not support it anymore for macOS build either.

Troubleshooting

Segfault on Qt5 launch

If Qt4 was previously installed via brew, and you then build with Qt5, you may get a EXC_BAD_ACCESS (SEGSEGV) exception when launching the new Qt5 build. The fix for this is to manually uninstall Qt4.

</translate>

brew uninstall --ignore-dependencies --force cartr/qt4/shiboken@1.2 cartr/qt4/pyside@1.2 cartr/qt4/pyside-tools@1.2 cartr/qt4/qt-legacy-formula

<translate>

Fortran

"No CMAKE_Fortran_COMPILER could be found." during configuration - Older versions of FreeCAD will need a fortran compiler installed. With Homebrew, do "brew install gcc" and try configuring again, giving cmake the path to Fortran ie -DCMAKE_Fortran_COMPILER=/opt/local/bin/gfortran-mp-4.9 . Or, preferably use a more current version of FreeCAD source!

FreeType

When using CMake versions older than 3.1.0, it's necessary to set CMake variable FREETYPE_INCLUDE_DIR_freetype2 manually, eg /usr/local/include/freetype2

Additional Build Instructions

FreeCAD can be built against the latest git master hosted on github, and launched from a CLI using libraries provided by the homebrew-freecad tap. For a complete list of build instructions see here.

</translate>

<translate>

</translate>

<translate>

Overview

These are libraries which FreeCAD uses as third party dependencies during compilation. They are usually dynamically linked libraries and have an extension .so in Linux/MacOS and .dll in Windows, and are accompanied by their header files .h or .hpp or similar. If a modified library is necessary, or a wrapper class is needed, the code of the modified library, or the wrapper, has to become part of the FreeCAD source code, and compiled together with it.

The dependencies need to be installed in the system before proceeding with compilation; see compile on Linux, compile on Windows, and compile on MacOS for more information.

If you are compiling using Windows, consider using the LibPack instead of trying to install the libraries individually.

Links

Library name Version needed Link to get it
Python >= 3.6 http://www.python.org/
Boost >= 1.33 http://www.boost.org/
OpenCASCADE >= 7.3 http://www.opencascade.org
Qt >= 5.4 https://www.qt.io/
Shiboken2 same as Qt https://wiki.qt.io/Qt_for_Python/Shiboken
PySide2 same as Qt https://wiki.qt.io/Qt_for_Python/Shiboken
Coin3D >= 3.x https://github.com/coin3d/coin
SoQt (deprecated) >= 1.2 https://github.com/coin3d/soqt
Quarter >= 1.0 https://github.com/coin3d/quarter
Pivy >= 0.6.5 https://github.com/coin3d/pivy/
FreeType >= XXX XXX
PyCXX >= XXX XXX
KDL >= XXX https://orocos.org/wiki/orocos/kdl-wiki.html
Point Cloud Library >= XXX XXX
Salome SMESH >= XXX XXX
VTK >= 6.0 XXX
Ply >= 3.11 https://www.dabeaz.com/ply/
Xerces-C++ >= 3.0 https://xerces.apache.org/xerces-c/
Eigen3 >= 3.0 http://eigen.tuxfamily.org/index.php?title=Main_Page
Zipios++ >= 0.1.5 https://snapwebsites.org/project/zipios, https://github.com/Zipios/Zipios
Zlib >= 1.0 http://www.zlib.net/, https://github.com/madler/zlib
libarea >= 0.0.20140514-1 https://github.com/danielfalck/libarea

Details

Python

Version: 3.3 or higher

License: Python 3.3 license

Python 2 became obsolete in 2019. Further development of FreeCAD will use exclusively Python 3; compatibility with Python 2 won't be tested, so old workbenches and macros that use this version will have to be updated or they may stop working. Please post on the FreeCAD forum if you encounter problems with Python 3.

Python is a popular all-purpose scripting language that is widely used in Linux and open source software. In FreeCAD, Python is used during compilation and also at runtime in different ways. It is used

  • to write test scripts to test for different conditions, such as memory leaks, to ensure functionality of the software after changes, for post build checks, and test coverage tests,
  • to write macros and macro recording,
  • to implement application logic for standard packages,
  • to implement auxiliary tools such as the Addon Manager,
  • to implement entire workbenches like Draft and Arch,
  • to dynamically load packages,
  • to implement rules for design (knowledge engineering),
  • to do fancy Internet interactions like work groups and PDM

On Linux, Python is usually already installed in your distribution. For Windows you can get a precompiled binary from Python.org or use ActiveState Python, though it is harder to get the debug libraries from the latter one.

Python was chosen as the scripting language for FreeCAD for different reasons:

  • It is more object oriented than Perl and Tcl.
  • The code is more readable than Perl and Visual Basic.
  • It is easier to embed in another application, unlike, say, Java.

In summary, Python is well documented, and it's easy to embed and extend in a C++ application. It is also well tested and has strong support from the open source community. Read more about Python and browse the official documentation at Python.org.

Boost

Version: 1.33 or higher

License: Boost Software License - Version 1.0

The Boost C++ libraries are collections of peer-reviewed, open source libraries that extend the functionality of C++. They are intended to be widely useful across a broad spectrum of applications, and to work well with the C++ Standard Library. The Boost license is designed to encourage their use in both open source and closed source projects.

Due to their popularity and stability, many Boost libraries have been accepted for incorporation into the C++11 standard, and more are planned for inclusion in subsequent C++ standards.

In order to ensure efficiency and flexibility, Boost makes extensive use of templates. Boost has been a source of extensive work and research into generic programming and meta-programming in C++. Read more about Boost by visiting the Boost homepage.

OpenCASCADE Technology

Version: 6.7 or higher

License: version 6.7.0 and later are governed by the GNU Lesser General Public License (LGPL) version 2.1 with additional exception. Earlier versions use the Open CASCADE Technology Public License.

OpenCASCADE Technology (OCCT) is a full-featured, professional grade CAD kernel. It was developed in 1993 and originally called CAS.CADE, by Matra Datavision in France for the Strim (Styler) and Euclid Quantum applications. In 1999 it was released as open source software, and since then it's been called OpenCASCADE.

OCCT is a big and complex set of C++ libraries that provide functionality required by a CAD application:

  • A complete STEP compliant geometry kernel.
  • A topological data model and needed functions to work with shapes (cut, fuse, extrude, and many others).
  • Standard import and export processors for files like STEP, IGES, VRML.
  • A 2D and 3D viewer with selection support.
  • A document and project data structure with support for save and restore, external linking of documents, recalculation of design history (parametric modeling) and a facility to load new data types as an extension package dynamically.

There are two main versions of OpenCASCADE in existence in different Linux distributions. One is distributed by the original developers; it is known as OCCT, and is packaged under the names occ or occt. The other version is the "community edition", abbreviated OCE, and is normally found with the oce name. FreeCAD can compile against either version, however, since 2016 FreeCAD recommends compiling against the official OCCT libraries rather than the OCE ones. The reason is that the community edition lacks important bug fixes and functions that make using FreeCAD better.

To learn more visit the OpenCASCADE website.

Qt

Version: 4.1 or higher

License: GPL v2.0/v3.0 or Commercial; from version 4.5 on also LPGL v2.1.

Qt is one of the most popular graphical user interface (GUI) toolkits available in the open source world. FreeCAD uses this toolkit to draw the interface of the program. For this, the Qt Designer application is very useful as it allows developers to quickly draw the dialogs and windows, export them as XML resource files, and then load these interfaces at runtime.

Further information about Qt libraries and their programming documentation are available at Qt Documentation.

Shiboken2 and Pyside2

Shiboken is the Python binding generator that Qt for Python uses to create the PySide module, in other words, it is the system that is used to expose the Qt C++ API to the Python language.

The original Shiboken and PySide packages were meant to be used with Python 2 and Qt4; since these two versions are considered obsolete in 2019, please use Shiboken2 and PySide2, which work with Python 3 and Qt5. New development of FreeCAD is done with Python 3 and Qt5, so compatibility with Python 2 and Qt4 is not guaranteed after FreeCAD 0.18.

Read more about Shiboken and Pyside on Qt for Python.

Coin3D

Version: 3.0 or higher

License: BSD 3-clause license

Coin3D is a high-level 3D graphics library with a C++ application programming interface. It uses scenegraph data structures to render real-time graphics suitable for all kinds of scientific and engineering visualization applications.

Coin3D is built on the industry-standard OpenGL immediate mode rendering library, and adds abstractions for higher-level primitives, provides 3D interactivity, and contains many complex optimization features for fast rendering that are transparent for the application programmer.

Coin3D is compatible with SGI's Open Inventor 2.1 API. This API has become the de facto standard graphics interface for 3D visualization in the scientific and engineering community. It has proved its worth since the year 2000 as a major building block in thousands of engineering applications around the world.

Coin3D (Open Inventor) is used as the 3D viewer in FreeCAD because the OpenCASCADE viewer (AIS and Graphics3D) has limitations and performance bottlenecks, especially with large-scale engineering rendering; other things like textures or volumetric rendering are not entirely supported by the OpenCASCADE viewer.

Coin3D is portable over a wide range of platforms: UNIX, Linux, BSD, macOS, and Microsoft Windows operating systems. To read more about this library visit Coin3D homepage.

SoQt (deprecated)

Version: 1.2.0 or higher

License: BSD 3-clause license

SoQt is the Coin3D (Open Inventor) binding to the Qt GUI toolkit.

SoQt is no longer used in FreeCAD, it was replaced by Quarter which is a more recent Qt binding.

Quarter

Version: 1.0 or higher

License: BSD 3-clause license

Quarter is a newer Coin3D binding to the Qt toolkit. A version of it is included in the source code of FreeCAD so it is compiled together with it.

Pivy

Version: 0.6.3 or higher

License: BSD 3-clause license

Pivy is a library that wraps the Coin3d library for use in Python. It is not needed to build FreeCAD or to start it, but it is needed as a runtime dependency by the Draft Workbench, and by other workbenches that use it internally, like Arch and BIM.

If you are not going to use these workbenches, you won't need Pivy.

Ply

Version: 3.11 or higher

License: BSD 3-clause license

Ply is the Python-Lex-Yacc parser. It is used as a runtime dependency by the OpenSCAD Workbench. If you don't use this workbench, you may not need this package.

For more information see Ply homepage

Xerces-C++

Version: 3.0 or higher

License: Apache Software License Version 2.0

Xerces-C++ is a validating XML parser written in a portable subset of C++. Xerces-C++ makes it easy to give your application the ability to read and write XML data. A shared library is provided for parsing, generating, manipulating, and validating XML documents. Xerces-C++ is faithful to the XML 1.0 recommendation and associated standards.

The parser is used for saving and restoring parameters in FreeCAD. For more information see Xerces-C++ homepage.

Eigen3

Version: 3.0 or higher

License: Starting from the 3.1.1 version, it is licensed under the Mozilla Public License 2.0. Earlier versions were licensed under the GNU Lesser General Public License 3.

Eigen is a C++ template library for linear algebra: matrices, vectors, numerical solvers, and related algorithms.

If you just want to use Eigen, you can use the header files right away. There is no binary library to link to, and no configured header file. Eigen is a pure template library defined in the headers.

Eigen is used in FreeCAD for many vector operations in 3D space. To learn more, visit Eigen homepage.

Zipios++

Version: 0.1.5 or higher

License: GNU Lesser General Public License 2.1

Zipios++ is a C++ library for reading and writing .zip files. Access to individual entries is provided through standard C++ iostreams. A simple read-only virtual file system that mounts regular directories and .zip files is also provided. The structure and public interface of Zipios++ are loosely based on the java.util.zip package of Java.

FreeCAD's native file format .FCstd is in reality a .zip file that stores and compresses other types of data within it, such as BREP and XML files. Therefore, Zipios++ is used to save and open compressed archives, including FreeCAD files.

A copy of Zipios++ is included in the source code of FreeCAD so it is compiled together with it. If you want to use an external Zipios++ library, provided by your operating system, you may set -DFREECAD_USE_EXTERNAL_ZIPIOS=ON with cmake.

Zipios++ uses the Zlib library to perform the actual decompression of files.

Zlib

Version: 1.0 or higher

License: zlib license

Zlib is designed to be a free, general-purpose, lossless data-compression library for use on any computer hardware and operating system. It implements the DEFLATE compression algorithm commonly used in .zip and .gzip files.

A copy of this library is included in the source code of FreeCAD so it is compiled together with it.

libarea

Version: 0.0.20140514-1 or higher

License: BSD 3-clause license

Libarea is a software library to compute profile and pocket operations which are used in computer aided manufacturing (CAM) software. It was created by Dan Heeks for his HeeksCNC project.

A copy of the library is included with the source code of the Path Workbench, so it is compiled together with it.

LibPack

LibPack is a convenient package with FreeCAD's build dependencies collected together. It is only needed if you are compiling FreeCAD on Windows with Visual Studio 2015 and above. You can find the latest LibPack on the releases page.

If you're working under Linux, you don't need the LibPack, as you can get the dependencies from your distribution's repositories as mentioned in the compile on Linux page.

FreeCAD 12.1.2

See the announcement in the forum: New libpacks for Windows with Qt5.12, OCC7.3 and Python 3.6 by apeltauer

It includes among other things: Boost 1.67, Coin3D 4.0.0a, Eigen3, Open CASCADE Technology 7.3.0, Python 3.6.8, PySide2, Qt 5.12.1, Salome SMESH, Shiboken2, vtk7, Xerces-C, Zipios++, zlib 1.2.11


</translate>

<translate>

</translate>

<translate>

Tool Page

For every serious software development you need tools. Here is a list of tools we use to develop FreeCAD:

Platform independent tools

Qt-Toolkit

The Qt-toolkit is a state of the art, platform independent user interface design tool. It is contained in the LibPack of FreeCAD, but can also be downloaded at Qt project.

Inkscape

This is a great vector drawing program. It adheres to the SVG standard and is used to draw Icons and Pictures. Inkscape is Free and Open Source Software licensed under the GPL. Get it at www.inkscape.org.

Doxygen

A very good and stable tool to generate source documentation from the .h and .cpp files.

Gimp

Not much to say about the GNU Image Manipulation Program. It can manipulate .xpm files which is a very convenient way to handle Icons in QT programs. XPM is basically C-Code which can be compiled into a program. Gimp supports the free .png file format used in the wiki.

Get the GIMP here: www.gimp.org

Gitkraken

This is a proprietary git GUI that is very helpful to learn how git works if you're interested in wanting to contribute to FreeCAD. Relevant pages to research:

OBS Studio

Free and open source software for video recording and live streaming. More details on official website: obsproject.com

OpenCamLib

OpenCamLib (OCL) is an open source library aiming to provide computer aided manufacturing (CAM) algorithms. FreeCAD uses OCL in the experimental 3D surface path operations and other experimental features.

StarUML

A full featured but proprietary UML program. It has a lot of major features, including reverse engineering C++ source code.

Download here: staruml.io

Tools on Windows

Visual Studio Community

Visual Studio Community is free for open source projects and small structures. Installation is modular. You can add support for a large number of languages including C++ and Python.

It can be downloaded at Visual Studio Community.

CamStudio

Is an Open Source tool to record Screen-casts (Webcasts). It is a very good tool to create tutorials by recording them. Its far not so boring as writing documentation.

See camstudio.org for details.

Tools on Linux

TODO


</translate>

<translate>

In FreeCAD version 0.20 the default location of the program's configuration, data and cache files was changed for Linux.
See Release notes 0.20 for more information. This page has not yet been updated accordingly.

</translate>

<translate>

Overview

This page shows the different ways to start FreeCAD and the most important configuration features.

Starting FreeCAD from the Command line

FreeCAD can be started normally by double-clicking on its desktop icon or selecting it from the start menu, but it can also be started directly from the command line. This allows you to change some of the default startup options.

Using command line options without a command line shell

  • On Ubuntu you can create a desktop icon and edit its properties. Add the command line options separated by spaces behind the program name in the "Command" field.
  • On Windows create a shortcut and edit the properties. Add the command line options separated by spaces to "Target" field.

Command line options

The command line options are subject to frequent changes.Therefore, it is a good idea to check the current options by typing:

</translate>

FreeCAD --help

<translate>

From the response you can read the possible parameters:

</translate>

 Usage: FreeCAD [options] File1 File2 ...
 
 Allowed options:
 
 Generic options:
   -v [ --version ]          Prints version string
   -h [ --help ]             Prints help message
   -c [ --console ]          Starts in console mode
   --response-file arg       Can be specified with '@name', too
   --dump-config             Dumps configuration
   --get-config arg          Prints the value of the requested configuration key
 
 Configuration:
   -l [ --write-log ]        Writes a log file to:
                             /home/username/.FreeCAD/FreeCAD.log
   --log-file arg            Unlike --write-log this allows logging to an 
                             arbitrary file
   -u [ --user-cfg ] arg     User config file to load/save user settings
   -s [ --system-cfg ] arg   System config file to load/save system settings
   -t [ --run-test ] arg     Test case - or 0 for all
   -M [ --module-path ] arg  Additional module paths
   -P [ --python-path ] arg  Additional python paths
   --single-instance         Allow to run a single instance of the application

<translate>

In the following table, selected options are described in more detail:

Long option Corresponding config var name Synopsis
--user-cfg <filename> UserParameter Filename or relative path that ends with a filename. Defaults to user.cfg.
--module-path <dir> Prepends to AdditionalModulePaths Directory that contains modules. This option can be given repeatedly to specify multiple directories.
--get-config <config-var-name> most Outputs the requested value in a popup dialog. Exits upon confirmation with OK. Cannot be used repeatedly. If an unknown/illegal variable name is used, the response is empty. The --console flag is not honored.

Options can written in two forms: --long-option arg and --long-option=arg.

Response and config files

FreeCAD can read some of these options from a config file. This file must be in the bin path and must be named FreeCAD.cfg. Be aware that options specified in the command line override the config file!

Some operating systems have a very low limit of characters on the command line. The common way to work around those limitations is using response files. A response file is just a configuration file which uses the same syntax as the command line. If the command line specifies a response file, it's loaded and parsed in addition to the command line:

</translate>

FreeCAD @ResponseFile.txt 

<translate>

or:

</translate>

FreeCAD --response-file=ResponseFile.txt

<translate>

or:

</translate>

FreeCAD --response-file ResponseFile.txt

<translate>

Hidden options

There are a couple of options not visible to the user. These options are e.g. the X-Window parameters parsed by the Windows system:

  • -display - Sets the X display (default is $DISPLAY).
  • -geometry - Sets the client geometry of the first window that is shown.
  • -fn or -font - Defines the application font. The font should be specified using an X logical font description.
  • -bg or -background - Sets the default background color and an application palette (light and dark shades are calculated).
  • -fg or -foreground - Sets the default foreground color.
  • -btn or -button - Sets the default button color.
  • -name - Sets the application name.
  • -title - Sets the application title.
  • -visual - Forces the application to use a TrueColor visual on an 8-bit display.
  • -ncols - Limits the number of colors allocated in the color cube on an 8-bit display, if the application is using the QApplication::ManyColor color specification. If count is 216 then a 6x6x6 color cube is used (i.e. 6 levels of red, 6 of green, and 6 of blue); for other values, a cube approximately proportional to a 2x3x1 cube is used.
  • -cmap - Causes the application to install a private color map on an 8-bit display.

Running FreeCAD without GUI (headless)

FreeCAD is usually built with two executables: a GUI-capable one called FreeCAD or freecad, and a headless one, called FreeCADCmd or freecadcmd. FreeCAD can be used in console mode using the --console switch (which is the default behavior of FreeCADCmd):

</translate>

FreeCAD --console

<translate>

In console mode, no graphical user interface will be displayed, and you will be presented with a Python interpreter prompt: >>>. From that prompt, you have the same functionality as the Python interpreter that runs inside the FreeCAD GUI, and access to all modules and plugins of FreeCAD, except the FreeCADGui module. Be aware that modules that depend on FreeCADGui might also be unavailable.

To read more about console or headless mode, refer to Headless FreeCAD.

Running modules, macros and scripts

File type System Command line example
Module Windows "C:\Program Files\FreeCAD\bin\FreeCAD.exe" -M "C:\FreeCAD\Mod\Draft"
Linux FreeCAD_0.19 -M ~/.FreeCAD/Mod/Draft
Linux (AppImage) path/to/FreeCADXXX.AppImage -M ~/.FreeCAD/Mod/Draft
.FCMacro or .py Windows "C:\Program Files\FreeCAD\bin\FreeCAD.exe" "C:\Users\userName\AppData\Roaming\FreeCAD\Mod\WorkFeature\start_WF.FCMacro"
Linux FreeCAD_0.19 ~/.FreeCAD/Mod/WorkFeature/start_WF.FCMacro
Linux (AppImage) path/to/FreeCADXXX.AppImage ~/.FreeCAD/Mod/WorkFeature/start_WF.FCMacro

See Macro at Startup on how to set up a macro to automatically run at FreeCAD startup.

Environment variables

FreeCAD supports the following environment variables, which can be used to configure directories: introduced in version 0.19

Environment variable Corresponding config var name Synopsis
FREECAD_USER_HOME UserHomePath FreeCAD's "base" directory for keeping local user data.
FREECAD_USER_DATA UserAppData If not set, defaults to FREECAD_USER_HOME/.FreeCAD, but only if FREECAD_USER_HOME is set.
FREECAD_USER_TEMP AppTempPath If not set, defaults to FREECAD_USER_HOME/temp, but only if FREECAD_USER_HOME is set.

If the specified path does not exist, the setting is ignored!

The above environment variables are meant to be used to realize a portable FreeCAD environment. For an example how environment variables can be used from the command line on Linux refer to the notes for Linux users on the downloads page.

HOME

FreeCAD uses Qt, which does honor the HOME environmental variable. Thus, setting HOME can be used to specify the base directory of Qt-related configuration files (.config/FreeCAD/FreeCAD.conf).

FreeCad itself does not honor the HOME environmental variable (because it determines the user's home directory from a lower-level system API). Use FREECAD_USER_HOME for this pupose.

TMPDIR

The default temporary directory is /tmp/. The TMPDIR environmental variable can be used to override the default. (Editor: precedence?).

Libraries

Some libraries need to call system environment variables. Sometimes when there is a problem with a FreeCAD installation, it is because some environment variable is absent or incorrect. Therefore, some important variables get duplicated in the Config and saved in the log file.

Python

</translate>

  • PYTHONPATH
  • PYTHONHOME
  • TCL_LIBRARY
  • TCLLIBPATH

<translate>

OpenCascade

</translate>

  • CSF_MDTVFontDirectory
  • CSF_MDTVTexturesDirectory
  • CSF_UnitsDefinition
  • CSF_UnitsLexicon
  • CSF_StandardDefaults
  • CSF_PluginDefaults
  • CSF_LANGUAGE
  • CSF_SHMessage
  • CSF_XCAFDefaults
  • CSF_GraphicShr
  • CSF_IGESDefaults
  • CSF_STEPDefaults

<translate>

Configuration set

On every startup FreeCAD examines its surrounding and the command line parameters. It builds up a configuration set which holds the essence of the runtime information. This information is later used to determine the place where to save user data or log files. It is also very important for postmortem analyzes. Therefore it is saved in the log file.

User related information

Config var name Synopsis Example Windows Example Linux
UserAppData Path where FreeCAD stores User Related application data. C:\Documents and Settings\username\AppData\FreeCAD
Short path : %APPDATA%\FreeCAD
/home/username/.FreeCAD
Short path : ~/.FreeCAD
UserParameter File where FreeCAD stores User Related application data. C:\Documents and Settings\username\AppData\FreeCAD\user.cfg
Short path : %APPDATA%\FreeCAD\user.cfg
/home/username/.config/FreeCAD/user.cfg
Short path : ~/.config/FreeCAD/user.cfg or $HOME/.config/FreeCAD/user.cfg
SystemParameter File where FreeCAD stores Application Related data. C:\Documents and Settings\username\AppData\FreeCAD\system.cfg
Short path : %APPDATA%\FreeCAD\system.cfg
/home/username/.config/FreeCAD/system.cfg
Short path : ~/.FreeCAD/system.cfg or $HOME/.FreeCAD/system.cfg
UserHomePath Home path of the current user C:\Documents and Settings\username
Short path : %USERPROFILE%
/home/username
Short path : ~

Note: For Linux distributions, an additional configuration file that relates to Qt may exist at path /home/username/.config/FreeCAD/FreeCAD.conf.

Command line arguments

Config var name Synopsis Example
LoggingFile 1 if the logging is switched on 1
LoggingFileName File name where the log is placed C:\Documents and Settings\username\AppData\FreeCAD\FreeCAD.log
RunMode This indicates how the main loop will work. "Script" means that the given script is called and then exit. "Cmd" runs the command line interpreter. "Internal" runs an internal script. "Gui" enters the Gui event loop. "Module" loads a given python module. "Cmd"
FileName Meaning depends on the RunMode
ScriptFileName Meaning depends on the RunMode
Verbose Verbosity level of FreeCAD "" or "strict"
OpenFileCount Holds the number of files opened through command line arguments "12"
AdditionalModulePaths Holds the additional Module paths given in the cmd line "extraModules/"

System related

Config var name Synopsis Example Windows Example Linux
AppHomePath Path where FreeCAD is installed c:/Progam Files/FreeCAD_0.19 /user/local/FreeCAD_0.19
PythonSearchPath Holds a list of paths which python search modules. This is at startup can change during execution
AppTempPath Path of the temporary directory. Can be given with TMPDIR environment variable, or with the Parameter Editor: Tools → Edit parameters... → BaseApp → Preferences → General → TempPath /tmp/ (default)

Build related information

The table below shows the available information about the Build version. Most of it comes from the Subversion repository. This stuff is needed to exactly rebuild a version!

Config var name Synopsis Example
BuildVersionMajor Major Version number of the Build. Defined in src/Build/Version.h.in 0
BuildVersionMinor Minor Version number of the Build. Defined in src/Build/Version.h.in 7
BuildRevision SVN Repository Revision number of the src in the Build. Generated by SVN 356
BuildRevisionRange Range of different changes 123-356
BuildRepositoryURL Repository URL https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk/src
BuildRevisionDate Date of the above Revision 2007/02/03 22:21:18
BuildScrClean Indicates if the source was changed after checkout Src modified
BuildScrMixed Src not mixed

Branding related

These Config entries are related to the branding mechanism of FreeCAD. See Branding for more details.

Config var name Synopsis Example
ExeName Name of the build Executable file. Can differ from FreeCAD if a different main.cpp is used. FreeCAD.exe
ExeVersion Over all Version shows up at start time "0.19"
AppIcon Icon which is used for the Executable, shows in Application MainWindow. "FCIcon"
ConsoleBanner Banner which is prompted in console mode
SplashPicture Name of the Icon used for the Splash Screen "FreeCADSplasher"
SplashAlignment Alignment of the Text in the Splash dialog "Bottom" or "Left"
SplashTextColor Color of the splasher Text "#000000"
StartWorkbench Name of the Workbench which get started automatically after Startup "Part Design"
HiddenDockWindow List of dockwindows (separated by a semicolon) which will be disabled "Property editor"

Querying the configuration

From FreeCAD's Python console

Entries of the configuration set can be queried with the config var name (see tables above) from the Python console. For example:

 >>> FreeCAD.ConfigGet("ExeVersion")
 '0.19'

If the name is not found, an empty string is returned.

From command line

Use the --get-config <config-var-name> option to query a single name. Not all names are supported. For example:

 FreeCAD --get-config ExeVersion

Use the --dump-config option to get a list of names and their values. Not all names are supported.

From FreeCAD console

Start FreeCAD in console mode with --console and query with Python code. For example:

 $ FreeCAD --console
 [FreeCAD Console mode <Use Ctrl-D (i.e. EOF) to exit.>]
 >>> FreeCAD.ConfigGet("ExeVersion")
 '0.19'
 >>> exit()

For Linux (bash shell) you can modify the following command line to suit your needs:

 $ FreeCAD --console <<EOF
 print( "FREECAD_USER_HOME: " + ( "not set" if ( os.environ.get('FREECAD_USER_HOME') is None ) else os.environ.get('FREECAD_USER_HOME') ) )
 print( "UserHomePath: " + FreeCAD.ConfigGet("UserHomePath") )
 exit()
 EOF

Starting FreeCAD from the desktop

Linux: Creating an additional start option

The following assumes that your desktop is configured such that you can launch FreeCAD from it. Depending on your Linux distribution and desktop environment, you may have to adapt the following steps:

  1. Copy the freedesktop entry file for FreeCAD from /usr/share/applications/freecad.desktop to ~/.local/share/applications.
  2. Change the name from freecad.desktop to something else (e.g. MyFreeCADConfig.desktop).
  3. Open the file with a text editor and change how FreeCAD is invoked by modifying the line starting with Exec.
  4. As a result, an additional entry in your start menu/application launcher is available. This way, you can have multiple FreeCAD entries with various launch options.

Starting FreeCAD from a portable USB medium

Windows

Put the FreeCAD executable, FreeCAD.exe, on the USB medium. Create a batch file, FreeCAD.bat, and put it into the same directory as FreeCAD.exe. Inside the batch file write: </translate>

set CURRENTDIR=%cd%
set FREECAD_USER_HOME=%CURRENTDIR%
start FreeCAD.exe -u FreeCAD/user.cfg -s FreeCAD/system.cfg --write-log

Or with FREECAD_USER_DATA (see):

set CURRENTDIR="%cd%"
set FREECAD_USER_DATA=%CURRENTDIR%/..
start FreeCAD.exe -u %FREECAD_USER_DATA%/user.cfg -s %FREECAD_USER_DATA%/system.cfg

<translate>

With the batch in the root of the USB medium:

</translate>

set CURRENTDIR=%cd%
set FREECAD_USER_DATA=%CURRENTDIR%FreeCAD\
start %cd%FreeCAD\bin\FreeCAD.exe -u %FREECAD_USER_DATA%user.cfg -s %FREECAD_USER_DATA%system.cfg

<translate>

Now double-click the batch file to start FreeCAD. (see)


</translate>

Build Support Tools

<translate>

</translate>

<translate>

Overview

The FreeCAD build tool or fcbt is a python script located at </translate>

trunc/src/Tools/fcbt.py

<translate> It can be used to simplify some frequent tasks in building, distributing and extending FreeCAD.

Usage

With Python correctly installed, fcbt can be invoked by the command </translate>

python fbct.py

<translate> It displays a menu, where you can select the task you want to use it for: </translate>

FreeCAD Build Tool
 Usage:
    fcbt <command name> [command parameter]
 possible commands are:
  - DistSrc         (DS)   Build a source Distr. of the current source tree
  - DistBin         (DB)   Build a binary Distr. of the current source tree
  - DistSetup       (DI)   Build a Setup Distr. of the current source tree
  - DistSetup       (DUI)  Build a User Setup Distr. of the current source tree
  - DistAll         (DA)   Run all three above modules
  - NextBuildNumber (NBN)  Increase the Build Number of this Version
  - CreateModule    (CM)   Insert a new FreeCAD Module (Workbench) in the module directory
 
 For help on the modules type:
   fcbt <command name> ?

<translate> At the input prompt enter the abbreviated command you want to call. For example type "CM" for creating a module.

DistSrc

The command "DS" creates a source distribution of the current source tree.

DistBin

The command "DB" creates a binary distribution of the current source tree.

DistSetup

The command "DI" creates a setup distribution of the current source tree.

DistSetup

The command "DUI" creates a user setup distribution of the current source tree.

DistAll

The command "DA" executes "DS", "DB" and "DI" in sequence.

NextBuildNumber

The "NBN" command increments the build number to create a new release version of FreeCAD.

CreateModule

The "CM" command creates a new application module (Workbench).


</translate>

<translate>

</translate>

<translate>

Introduction

This page will show you how to add a new workbench to the FreeCAD interface. Workbenches are containers for FreeCAD commands. They can be coded in Python, in C++, or in a mix of both, which has the advantage to ally the speed of C++ to the flexibility of Python. In all cases, though, your workbench will be launched by a set of two Python files. They can be "internal" workbenches, included with FreeCAD's distribution, or "external" workbenches, distributed via the Addon Manager or installed manually by downloading from some online repository. Internal workbenches may be coded in either C++, Python, or a combination of the two, whereas external workbenches must be Python-only.

The workbench structure

You need a folder, with any name you like, placed in the user Mod directory, with an Init.py file, and, optionally an InitGui.py file. The Init file is executed when FreeCAD starts, and the InitGui.py file is executed immediately after, but only when FreeCAD starts in GUI mode. That's all it needs for FreeCAD to find your workbench at startup and add it to its interface.

The user Mod directory is a sub-directory of the user application data directory (you can find the latter by typing App.getUserAppDataDir() in the Python console):

  • On Linux it is usually /home/<username>/.local/share/FreeCAD/Mod/ (version 0.20 and above) or /home/<username>/.FreeCAD/Mod/ (version 0.19 and below).
  • On Windows it is %APPDATA%\FreeCAD\Mod\, which is usually C:\Users\<username>\Appdata\Roaming\FreeCAD\Mod\.
  • On macOS it is usually /Users/<username>/Library/Application Support/FreeCAD/Mod/.

The Mod directory should look like this:

</translate>

/Mod/
 +-- MyWorkbench/
     +-- Init.py
     +-- InitGui.py

<translate>

Inside those files you can do whatever you want. Usually they are used like this:

  • In the Init.py file you just add a couple of things used even when FreeCAD works in console mode, for example the file importers and exporters
  • In the InitGui.py file you usually define a workbench, which contains a name, an icon, and a series of FreeCAD commands (see below). That python file also defines functions that are executed when FreeCAD loads (you try to do as little as possible there, so you don't slow down the startup), another that gets executed when the workbench is activated (that's where you'll do most of the work), and a third one when the workbench is deactivated (so you can remove things if needed).

The structure and file content for a workbench described here is the classic way of creating a new workbench. One can use a slight variation in the structure of files when making a new Python workbench, that alternative way is best described as a "namespaced workbench", opening up the possibility to use pip to install the workbench. Both structures work, so it is more a question of preference when creating a new workbench. The style and structure for workbenches presented here are available in the global namespace of FreeCAD, whereas for the alternative style and structure the workbench resides in a dedicated namespace. For further readings on the topic see Related.

C++ workbench structure

If you are going to code your workbench in python, you don't need to take special care, and can simply place your other python files together with your Init.py and InitGui.py files. When working with C++, however, you should take greater care, and start with respecting one fundamental rule of FreeCAD: The separation of your workbench between an App part (that can run in console mode, without any GUI element), and a Gui part, which will only be loaded when FreeCAD runs with its full GUI environment. So when developing a C++ workbench, you will actually most likely create two modules, an App and a Gui. These two modules must of course be callable from python. Any FreeCAD module (App or Gui) consists, at the very least, of a module init file. This is a typical AppMyModuleGui.cpp file:

</translate>

extern "C" {
    void MyModuleGuiExport initMyModuleGui()  
    {
         if (!Gui::Application::Instance) {
            PyErr_SetString(PyExc_ImportError, "Cannot load Gui module in console application.");
            return;
        }
        try {
            // import other modules this one depends on
            Base::Interpreter().runString("import PartGui");
            // run some python code in the console
            Base::Interpreter().runString("print('welcome to my module!')");
        }
        catch(const Base::Exception& e) {
            PyErr_SetString(PyExc_ImportError, e.what());
            return;
        }
        (void) Py_InitModule("MyModuleGui", MyModuleGui_Import_methods);   /* mod name, table ptr */
        Base::Console().Log("Loading GUI of MyModule... done\n");
    
        // initializes the FreeCAD commands (in another cpp file)
        CreateMyModuleCommands();
    
        // initializes workbench and object definitions
        MyModuleGui::Workbench::init();
        MyModuleGui::ViewProviderSomeCustomObject::init();
    
         // add resources and reloads the translators
        loadMyModuleResource();
    }
}

<translate>

The Init.py file

</translate>

"""FreeCAD init script of XXX module"""

# ***************************************************************************
# *   Copyright (c) 2015 John Doe john@doe.com                              *   
# *                                                                         *
# *   This file is part of the FreeCAD CAx development system.              *
# *                                                                         *
# *   This program is free software; you can redistribute it and/or modify  *
# *   it under the terms of the GNU Lesser General Public License (LGPL)    *
# *   as published by the Free Software Foundation; either version 2 of     *
# *   the License, or (at your option) any later version.                   *
# *   for detail see the LICENCE text file.                                 *
# *                                                                         *
# *   FreeCAD is distributed in the hope that it will be useful,            *
# *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
# *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
# *   GNU Lesser General Public License for more details.                   *
# *                                                                         *
# *   You should have received a copy of the GNU Library General Public     *
# *   License along with FreeCAD; if not, write to the Free Software        *
# *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
# *   USA                                                                   *
# *                                                                         *
# ***************************************************************************/

FreeCAD.addImportType("My own format (*.own)", "importOwn")
FreeCAD.addExportType("My own format (*.own)", "exportOwn")
print("I am executing some stuff here when FreeCAD starts!")

<translate>

You can choose any license you like for your workbench, but be aware that if you wish to see your workbench integrated into and distributed with the FreeCAD source code at some point, it needs to be LGPL2+ like the example above. See Licence.

The FreeCAD.addImportType() and addEXportType() functions allow you to give the name and extension of a file type, and a Python module responsible for its import. In the example above, an importOwn.py module will handle .own files. See Code snippets for more examples.

Python workbenches

This is the InitGui.py file:

</translate>

class MyWorkbench (Workbench):

    MenuText = "My Workbench"
    ToolTip = "A description of my workbench"
    Icon = """paste here the contents of a 16x16 xpm icon"""

    def Initialize(self):
        """This function is executed when the workbench is first activated.
        It is executed once in a FreeCAD session followed by the Activated function.
        """
        import MyModuleA, MyModuleB # import here all the needed files that create your FreeCAD commands
        self.list = ["MyCommand1", "MyCommand2"] # a list of command names created in the line above
        self.appendToolbar("My Commands", self.list) # creates a new toolbar with your commands
        self.appendMenu("My New Menu", self.list) # creates a new menu
        self.appendMenu(["An existing Menu", "My submenu"], self.list) # appends a submenu to an existing menu

    def Activated(self):
        """This function is executed whenever the workbench is activated"""
        return

    def Deactivated(self):
        """This function is executed whenever the workbench is deactivated"""
        return

    def ContextMenu(self, recipient):
        """This function is executed whenever the user right-clicks on screen"""
        # "recipient" will be either "view" or "tree"
        self.appendContextMenu("My commands", self.list) # add commands to the context menu

    def GetClassName(self): 
        # This function is mandatory if this is a full Python workbench
        # This is not a template, the returned string should be exactly "Gui::PythonWorkbench"
        return "Gui::PythonWorkbench"
       
Gui.addWorkbench(MyWorkbench())

<translate>

Other than that, you can do anything you want: you could put your whole workbench code inside the InitGui.py if you want, but it is usually more convenient to place the different functions of your workbench in separate files. So those files are smaller and easier to read. Then you import those files into your InitGui.py file. You can organize those files the way you want, a good example is one for each FreeCAD command you add.

Preferences

You can add a Preferences page for your Python workbench. The Preferences pages look for a preference icon with a specific name in the Qt Resource system. If your icon isn't in the resource system or doesn't have the correct name, your icon won't appear on the Preferences page.

Adding your workbench icon:

  • the preferences icon needs to be named "preferences-" + "modulename" + ".svg" (all lowercase)
  • make a qrc file containing all icon names
  • in the main *.py directory, run pyside-rcc -o myResources.py myqrc.qrc
  • in InitGui.py, add import myResource(.py)
  • update your repository(git) with myResources.py and myqrc.qrc

You'll need to redo the steps if you add/change icons.

@kbwbe has created a nice script to compile resources for the A2Plus workbench. See below.

Adding your preference page(s):

  • You need to compile the Qt designer plugin that allows you to add preference settings with Qt Designer
  • Create a blank widget in Qt Designer (no buttons or anything)
  • Design your preference page, any setting that must be saved (preferences) must be one of the Gui::Pref* widgets that were added by the plugin)
  • In any of those, make sure you fill the PrefName (the name of your preference value) and PrefPath (ex: Mod/MyWorkbenchName), which will save your value under BaseApp/Preferences/Mod/MyWorkbenchName
  • Save the ui file in your workbench, make sure it's handled by cmake
  • In your workbench, for ex. inside the InitGui file, inside the Initialize method (but any other place works too), add: FreeCADGui.addPreferencePage("/path/to/myUiFile.ui","MyGroup"), "MyGroup" being one of the preferences groups on the left. FreeCAD will automatically look for a "preferences-mygroup.svg" file in its known locations (which you can extend with FreeCADGui.addIconPath())
  • Make sure the addPreferencePage() method is called only once, otherwise your pref page will be added several times

Distribution

To distribute your Python workbench, you may either simply host the files in some location and instruct your users to download them and place them in their Mod directory manually, or you may host them in an online git repository (GitHub, GitLab, Framagit, and Debian Salsa are currently supported locations) and configure them for the Addon Manager to install. Instructions for inclusion on FreeCAD's official Addons list can be found on the FreeCAD Addons GitHub repository. To use the Addon Manager, a package.xml metadata file should be included, which instructs the Addon Manager how to find your workbench's icon, and allows display of a description, version number, etc. It can also be used to specify other workbenches or Python packages that your Workbench either depends on, is blocked by, or is intended to replace.

For a quick guide on how to create a basic package.xml file and add a workbench to the Addon Manager see: Add Workbench to Addon Manager.

Optionally, you can include a separate metadata file describing your Python dependencies. This may be either a file called metadata.txt describing your workbench's external dependencies (on either other Addons, Workbenches, or Python modules), or a requirements.txt describing your Python dependencies. Note that if using a requirements.txt file, only the names of the specified packages are used for dependency resolution: pip command options, include options and version information are not supported by the Addon Manager. Users may manually run the requirements file using pip if those features are required.

The format of the metadata.txt file is plain text, with three optional lines:

</translate>

workbenches=
pylibs=
optionalpylibs=

<translate>

Each line should consist of a comma-separated list of items your Workbench depends on. Workbenches may be either an internal FreeCAD Workbench, e.g. "FEM", or an external Addon, for example "Curves". The required and optional Python libraries should be specified with their canonical Python names, such as you would use with pip install. For example:

</translate>

workbenches=FEM,Curves
pylibs=ezdxf
optionalpylibs=metadata,git

<translate>

You may also include a script that is run when your package is uninstalled. This is a file called "uninstall.py" located at the top level of your Addon. It is executed when a user uninstalls your Addon using the Addon Manager. Use it to clean up anything your Addon may have done to the users system that should not persist when the Addon is gone (e.g. removing cache files, etc.).

To ensure that your addon is being read correctly by the Addon Manager, you can enable a "developer mode" in which the Addon Manager examines all available addons and ensures their metadata contains the required elements. To enable this mode select: Edit → Preferences... → Addon Manager → Addon manager options → Addon developer mode, see Preferences Editor.

C++ workbenches

If you are going to code your workbench in C++, you will probably want to code the workbench definition itself in C++ too (although it is not necessary: you could also code only the tools in C++, and leave the workbench definition in Python). In that case, the InitGui.py file becomes very simple: It might contain just one line:

</translate>

import MyModuleGui

<translate>

where MyModule is your complete C++ workbench, including the commands and workbench definition.

Coding C++ workbenches works in a pretty similar way. This is a typical Workbench.cpp file to include in the Gui part of your module:

</translate>

namespace MyModuleGui {
    class MyModuleGuiExport Workbench : public Gui::StdWorkbench
    {
        TYPESYSTEM_HEADER();

    public:
        Workbench();
        virtual ~Workbench();

        virtual void activated();
        virtual void deactivated();

    protected:
        Gui::ToolBarItem* setupToolBars() const;
        Gui::MenuItem*    setupMenuBar() const;
    };
}

<translate>

Preferences

You can add a Preferences page for C++ workbenches too. The steps are similar to those for Python.

Distribution

There are two options to distribute a C++ workbench, you can either host precompiled versions for the different operating systems yourself, or you can request for your code to be merged into the FreeCAD source code. As mentioned above this requires a LGPL2+ license, and you must first present your workbench to the community in the FreeCAD forum for review.

FreeCAD commands

FreeCAD commands are the basic building block of the FreeCAD interface. They can appear as a button on toolbars, and as a menu entry in menus. But it is the same command. A command is a simple Python class, that must contain a couple of predefined attributes and functions, that define the name of the command, its icon, and what to do when the command is activated.

Python command definition

</translate>

class My_Command_Class():
    """My new command"""

    def GetResources(self):
        return {"Pixmap"  : "My_Command_Icon", # the name of a svg file available in the resources
                "Accel"   : "Shift+S", # a default shortcut (optional)
                "MenuText": "My New Command",
                "ToolTip" : "What my new command does"}

    def Activated(self):
        """Do something here"""
        return

    def IsActive(self):
        """Here you can define if the command must be active or not (greyed) if certain conditions
        are met or not. This function is optional."""
        return True

FreeCADGui.addCommand("My_Command", My_Command_Class())

<translate>

C++ command definition

Similarly, you can code your commands in C++, typically in a Commands.cpp file in your Gui module. This is a typical Commands.cpp file:

</translate>

DEF_STD_CMD_A(CmdMyCommand);

CmdMyCommand::CmdMyCommand()
  :Command("My_Command")
{
  sAppModule    = "MyModule";
  sGroup        = QT_TR_NOOP("MyModule");
  sMenuText     = QT_TR_NOOP("Runs my command...");
  sToolTipText  = QT_TR_NOOP("Describes what my command does");
  sWhatsThis    = QT_TR_NOOP("Describes what my command does");
  sStatusTip    = QT_TR_NOOP("Describes what my command does");
  sPixmap       = "some_svg_icon_from_my_resource";
}

void CmdMyCommand::activated(int iMsg)
{
    openCommand("My Command");
    doCommand(Doc,"print('Hello, world!')");
    commitCommand();
    updateActive();
}

bool CmdMyCommand::isActive(void)
{
  if( getActiveGuiDocument() )
    return true;
  else
    return false;
}

void CreateMyModuleCommands(void)
{
    Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();
    rcCmdMgr.addCommand(new CmdMyCommand());
}

<translate>

"Compiling" your resource file

compileA2pResources.py from the A2Plus workbench:

</translate>

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#***************************************************************************
#*                                                                         *
#*   Copyright (c) 2019 kbwbe                                              *
#*                                                                         *
#*   Portions of code based on hamish's assembly 2                         *
#*                                                                         *
#*   This program is free software; you can redistribute it and/or modify  *
#*   it under the terms of the GNU Lesser General Public License (LGPL)    *
#*   as published by the Free Software Foundation; either version 2 of     *
#*   the License, or (at your option) any later version.                   *
#*   for detail see the LICENCE text file.                                 *
#*                                                                         *
#*   This program is distributed in the hope that it will be useful,       *
#*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
#*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
#*   GNU Library General Public License for more details.                  *
#*                                                                         *
#*   You should have received a copy of the GNU Library General Public     *
#*   License along with this program; if not, write to the Free Software   *
#*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
#*   USA                                                                   *
#*                                                                         *
#***************************************************************************

# This script compiles the A2plus icons for py2 and py3
# For Linux only
# Start this file in A2plus main directory
# Make sure pyside-rcc is installed

import os, glob

qrc_filename = 'temp.qrc'
if os.path.exists(qrc_filename):
    os.remove(qrc_filename)

qrc = '''<RCC>
\t<qresource prefix="/">'''
for fn in glob.glob('./icons/*.svg'):
    qrc = qrc + '\n\t\t<file>%s</file>' % fn
qrc = qrc + '''\n\t</qresource>
</RCC>'''

print(qrc)

f = open(qrc_filename,'w')
f.write(qrc)
f.close()

os.system(
    'pyside-rcc -o a2p_Resources2.py {}'.format(qrc_filename))
os.system(
    'pyside-rcc -py3 -o a2p_Resources3.py {}'.format(qrc_filename))

os.remove(qrc_filename)

<translate>

Related


</translate>

<translate>

</translate>

<translate>

Test First

Before you go through the pain of debugging use the Test framework to check if the standard tests work properly. If they do not run complete there is possibly a broken installation.

Command Line

The debugging of FreeCAD is supported by a few internal mechanisms. The command line version of FreeCAD provides some options for debugging support.

These are the currently recognized options in FreeCAD 0.19:

Generic options:

 -v [ --version ]          Prints version string
 -h [ --help ]             Prints help message
 -c [ --console ]          Starts in console mode
 --response-file arg       Can be specified with '@name', too
 --dump-config             Dumps configuration
 --get-config arg          Prints the value of the requested configuration key

Configuration:

 -l [ --write-log ]        Writes a log file to:
                           $HOME/.local/share/FreeCAD/FreeCAD.log (Linux)
                           $HOME/Library/Application\ Support/FreeCAD/FreeCAD.log (macOS)
                           %APPDATA%\FreeCAD\FreeCAD.log (Windows)
 --log-file arg            Unlike to --write-log this allows to log to an 
                           arbitrary file
 -u [ --user-cfg ] arg     User config file to load/save user settings
 -s [ --system-cfg ] arg   System config file to load/save system settings
 -t [ --run-test ] arg     Test case - or 0 for all
 -M [ --module-path ] arg  Additional module paths
 -P [ --python-path ] arg  Additional Python paths
 --single-instance         Allow to run a single instance of the application

Generating a Backtrace

If you are running a version of FreeCAD from the bleeding edge of the development curve, it may "crash". You can help solve such problems by providing the developers with a "backtrace". To do this, you need to be running a "debug build" of the software. "Debug build" is a parameter that is set at compile time, so you'll either need to compile FreeCAD yourself, or obtain a pre-compiled "debug" version.

For Linux

</translate>

<translate>

Linux Debugging →

</translate>

<translate>

Prerequisites:

  • software package gdb installed
  • a debug build of FreeCAD (at this time only available by building from source)
  • a FreeCAD model that causes a crash

Steps: Enter the following in your terminal window:

Find FreeCAD binary on your system:

</translate>

$ whereis freecad
freecad: /usr/local/freecad <--- for example

$ cd /usr/local/freecad/bin
$ gdb FreeCAD

<translate>

GNUdebugger will output some initializing information. The (gdb) shows GNUDebugger is running in the terminal, now input:

</translate>

(gdb) handle SIG33 noprint nostop
(gdb) run

<translate>

FreeCAD will now start up. Perform the steps that cause FreeCAD to crash or freeze, then enter in the terminal window:

</translate>

(gdb) bt

<translate>

This will generate a lengthy listing of exactly what the program was doing when it crashed or froze. Include this with your problem report.

</translate>

(gdb) bt full

<translate>

Print the values of the local variables also. This can be combined with a number to limit the number of frames shown.

</translate>

<translate>

For macOS

</translate>

<translate>

macOS Debugging →

</translate>

<translate>

Prerequisites:

  • software package lldb installed
  • a debug build of FreeCAD
  • a FreeCAD model that causes a crash

Steps: Enter the following in your terminal window:

</translate>

$ cd FreeCAD/bin
$ lldb FreeCAD

<translate>

LLDB will output some initializing information. The (lldb) shows the debugger is running in the terminal, now input:

</translate>

(lldb) run

<translate>

FreeCAD will now start up. Perform the steps that cause FreeCAD to crash or freeze, then enter in the terminal window:

</translate>

(lldb) bt

<translate>

This will generate a lengthy listing of exactly what the program was doing when it crashed or froze. Include this with your problem report.

</translate>

<translate>

List Libraries Loaded by FreeCAD

(Applicable to Linux and macOS)

Sometimes it's helpful to understand what libraries FreeCAD is loading, specifically if there are multiple libraries being loaded of the same name but different versions (version collision). In order to see which libraries are loaded by FreeCAD when it crashes you should open a terminal and run it in the debugger. In a second terminal window, find out the process id of FreeCAD:

ps -A | grep FreeCAD

Use the returned id and pass it to lsof:

lsof -p process_id

This prints a long list of loaded resources. So for example, if trying to ascertain if more than one Coin3d library versions is loaded, scroll through the list or search directly for Coin in the output:

lsof -p process_id | grep Coin

Python Debugging

For a more modern approach to debugging Python, see these posts:

winpdb

</translate>

<translate>

winpdb Debugging →

</translate>

<translate>

Here is an example of using Winpdb inside FreeCAD:

We need the Python debugger: Winpdb. If you do not have it installed, on Ubuntu/Debian install it with:

</translate>

sudo apt-get install winpdb

<translate>

Now lets setup the debugger.

  1. Start Winpdb.
  2. Set the debugger password to "test": Go to menu FilePassword" and set the password.

Now we will run a test Python script in FreeCAD step by step.

  1. Run winpdb and set the password (e.g. test)
  2. Create a Python file with this content

</translate>

import rpdb2
rpdb2.start_embedded_debugger("test")
import FreeCAD
import Part
import Draft
print "hello"
print "hello"
import Draft
points=[FreeCAD.Vector(-3.0,-1.0,0.0),FreeCAD.Vector(-2.0,0.0,0.0)]
Draft.makeWire(points,closed=False,face=False,support=None)

<translate>

  1. Start FreeCAD and load the above file into FreeCAD
  2. Press F6 to execute it
  3. Now FreeCAD will become unresponsive because the Python debugger is waiting
  4. Switch to the Windpdb GUI and click on "Attach". After a few seconds an item "<Input>" appears where you have to double-click
  5. Now the currently executed script appears in Winpdb.
  6. Set a break at the last line and press F5
  7. Now press F7 to step into the Python code of Draft.makeWire

</translate>

<translate>

Visual Studio Code (VS Code)

</translate>

<translate>

VS Code Debugging →

</translate>

<translate>

Prerequisites:

  • The ptvsd package needs to be installed in a Python 3 outside of FreeCAD, then the module must be copied to FreeCAD's Python library folder.

</translate>

# In a cmd window that has a path to you local Python 3:
pip install ptvsd
# Then if your Python is installed in C:\Users\<userid>\AppData\Local\Programs\Python\Python37
# and your FreeCAD is installed in C:\freecad\bin
xcopy "C:\Users\<userid>\AppData\Local\Programs\Python\Python37\Lib\site-packages\ptvsd" "C:\freecad\bin\Lib\site-packages\ptvsd"

<translate>

pypi page

Visual Studio Code documentation for remote debugging

Steps:

  • Add following code at the beginning of your script

</translate>

import ptvsd
print("Waiting for debugger attach")
# 5678 is the default attach port in the VS Code debug configurations
ptvsd.enable_attach(address=('localhost', 5678), redirect_output=True)
ptvsd.wait_for_attach()

<translate>

  • Add a debug configuration in Visual Studio Code Debug → Add Configurations….
  • The config should look like this:

</translate>

    "configurations": [
        {
            "name": "Python: Attacher",
            "type": "python",
            "request": "attach",
            "port": 5678,
            "host": "localhost",
            "pathMappings": [
                {
                    "localRoot": "${workspaceFolder}",
                    "remoteRoot": "."
                }
            ]
        },

<translate>

  • In VS Code add a breakpoint anywhere you want.
  • Launch the script in FreeCAD. FreeCAD freeze waiting for attachment.
  • In VS Code start debugging using created configuration. You should see variables in debugger area.
  • When setting breakpoints, VS Code will complain about not finding the .py file opened in the VS Code editor.
    • Change "remoteRoot": "." to "remoteRoot": "<directory of file>"
      • For example, if the Python file resides in /home/FC_myscripts/myscript.py
      • Change to: "remoteRoot": "/home/FC_myscripts"
    • If you're just debugging FreeCAD macros from the FreeCAD macro folder, and that folder is "C:/Users/<userid>/AppData/Roaming/FreeCAD/Macro", then use:
      • "localRoot": "C:/Users/<userid>/AppData/Roaming/FreeCAD/Macro",
      • "remoteRoot": "C:/Users/<userid>/AppData/Roaming/FreeCAD/Macro"
  • If your macro can't find ptvsd despite having installed it somewhere precede 'import ptvsd' with

</translate>

from sys import path
sys.path.append('/path/to/site-packages')

<translate>

Where the path is to the directory where ptvsd was installed.

  • On the left bottom edge of VSCode you can choose the Python executable - it's best to make this the version packaged with FreeCAD.

In the Mac package it is /Applications/FreeCAD.App/Contents/Resources/bin/python.

You can locate it on your system by typing

</translate>

import sys
print(sys.executable)

<translate>

into FreeCAD's Python console.

</translate>

<translate>

With LiClipse and AppImage

</translate>

<translate>

LiClipse Debugging →

</translate>

<translate>

  • Extract AppImage.

</translate>

> ./your location/FreeCAD_xxx.AppImage --appimage-extract
> cd squashfs-root/

<translate>

  • The sqashfs-root location is where the debugger later on is hooked up to.
  • Make sure you can start a FreeCAD session from within the squashfs-root location.

</translate>

squashfs-root> ./usr/bin/freecadcmd

<translate>

  • Should start up a FreeCAD commandline session.
  • Install LiClipse.
    • Comes ready with pydev and has installers for all platforms.
    • For linux it is just to extract (to any location) and run.
  • Configure liclipse for debugging.
    • Right-click pydev icon (upper right corner) and choose customize.
      • Activate "PyDev Debug" (through checkbox, or it might be needed to go to tab "Action Set Availability" and activate there first).
      • In the pydev menu you can now choose "start debug server".
    • Use menu window/open perspective/other > debug.
      • Right-click debug icon (upper right corner) and choose customize.
      • Checking "Debug" brings the debugging navigation tools to the toolbar.
    • Open preferences through menu window/preferences.
      • In PyDev/Interpreters add "new Interpreter by browsing".
      • The added interpreter should be: your loc/squashfs-root/usr/bin/python.
      • If you are only using this for fc, you can add AddOn workbench folders as well, or do that in a pydev-project later on.
  • Find path to pydevd.py in your liclipse installation.
    • Something along the lines of: your location/liclipse/plugins/org.python.pydev.xx/pysrc.
  • Create a regular pydev-project in liclipse.
    • Import external sources, for example a macro that you want to debug, or an external workbench.
    • In that macro (or workbench .py file) add the code lines:

</translate>

import sys; sys.path.append("path ending with /pysrc")
import pydevd; pydevd.settrace()

<translate>

  • This is where the execution will halt when the macro is run.
  • Start the liclipse debug server (menu pydev).
  • Start FreeCAD.

</translate>

squashfs-root> ./usr/bin/freecad

<translate>

  • Run the macro (or any other file with a pydevd.settrace() trigger) from within freecad, as you would normally do.
  • Happy debugging.
  • The use of LiClipse for remote debugging, and the steps described here related to liclipse, should work on any platform. The parts related to AppImage is for linux only.

</translate>

<translate>

Pyzo

See the main article about Pyzo.

Debugging OpenCasCade

For developers needing to dig deeper in to the OpenCasCade kernel, user @abdullah has created a thread orientation discussing how to do so.


</translate>

<translate>

Test workbench icon

</translate>

<translate>

Introduction

The Test Framework Workbench is not really a modelling workbench, but it contains a set of Python scripts to perform different tests on the core components of FreeCAD, in order to debug problems. See also debugging.

You can run the tests from the command line, by using the -t or --run-test options.

Run all tests:

</translate>

freecad --run-test 0

<translate>

Run only some the specified unit test, for example:

</translate>

freecad -t TestDraft

<translate>

If a test does not need the GUI, it can also be executed in console mode by setting the -c or --console option in addition. This usually results in much faster startup time as the GUI is not loaded. For example:

</translate>

freecad -c -t TestPartDesignApp

<translate>

Test menu

Each top level directory in FreeCAD should have a file with the tests that can be run for that particular workbench or module. The file usually starts with the word Test.

To run a test from within FreeCAD, switch to the Test Workbench, then Test commands → TestToolsGui → Self test → Select test name, then enter the name of the Python file with the tests; for example, for the Draft Workbench, this would be TestDraft, then press Start.

Test functions

This is the list of test apps as of 0.15 git 4207:

TestAPP.All

Add test function

BaseTests

Add test function

UnitTests

Add test function

Document

Add test function

UnicodeTests

Add test function

MeshTestsApp

Add test function

TestDraft

Add test function

TestSketcherApp

Add test function

TestPartApp

Add test function

TestPartDesignApp

Add test function

TestPathApp

Path workbench test cases:

  • depthTestCases:
  • PathTestUtils:
  • TestDressupDogbone: Test functionality of Dogbone dressup.
  • TestHoldingTags: Test functionality of Holding Tags dressup.
  • TestPathAdaptive: Test selection capability of Adaptive operation.
  • TestPathCore: Test core functionality of Path workbench.
  • TestPathDeburr: Test general functionality of Deburr operation.
  • TestPathGeom: Test various functions available in the PathGeom module.
  • TestPathHelix: Test general functionality of Helix operation.
  • TestPathLog: Test various functions available in the PathLog debugging and feedback module.
  • TestPathOpTools:
  • TestPathPreferences: Test various functions available in the PathPreferences module.
  • TestPathPropertyBag:
  • TestPathSetupSheet:
  • TestPathStock:
  • TestPathThreadMilling:
  • TestPathTool:
  • TestPathToolBit:
  • TestPathToolController:
  • TestPathTooltable:
  • TestPathUtil: Test various functions available in the PathUtil module.
  • TestPathVcarve: Test general functionality of Vcarve operation.
  • TestPathVoronoi:

Workbench

Add test function

Menu

Add test function

Menu.MenuDeleteCases

Add test function

Menu.MenuCreateCases

Add test function

Scripting

See also: FreeCAD Scripting Basics.

Get a list of all top-level test modules

</translate>

FreeCAD.__unit_test__

<translate>

Note that the test modules returned here depend on whether a GUI available or not. I.e. when executed in console mode, various tests ending in "Gui" are missing.

Run specific tests

There are various ways of running tests using Python's unittest library. FreeCAD's test framework removes some of the boiler plate for the most common cases.

Run all tests defined in a Python module: </translate>

import Test, TestFemApp
Test.runTestsFromModule(TestFemApp)

<translate>

Run all tests defined in a Python class: </translate>

import Test, femtest.app.test_solver_calculix
Test.runTestsFromClass(femtest.app.test_solver_calculix.TestSolverCalculix)

<translate>

Example 1

Within the Python Console of FreeCAD, the following code format may be used to run built-in tests. Replace the red "TestFem" text in the code below with the desired module test name.

  • For example, use "TestPathApp" to run all unit tests for the Path workbench unit test framework.
  • Submodules are available using dot notation, like "TestPathApp.TestPathAdaptive" to only run the Adaptive unit tests within the greater Path workbench test framework.
  • Multiple test modules or submodules may be combined by adding another `suite.addTest(...)` method call just like the one in the code below, but with a different module or submodule reference.
  • Output for the code below will be in the Report View panel within the FreeCAD GUI.
  • Code source is copied from post by FreeCAD forum user, sgrogan, in the unit tests per python topic, with credit there given to forum user, wmayer.

</translate>

import unittest
suite = unittest.TestSuite()
suite.addTest(unittest.defaultTestLoader.loadTestsFromName("TestFem"))
r = unittest.TextTestRunner()
r.run(suite)

<translate>

Additional Resources

Forum Topics


</translate>

<translate>

</translate>

<translate>

Overview

This article describes the Branding of FreeCAD. Branding means to create your own application based on FreeCAD. That can be only your own executable or splash screen till a complete reworked program. On base of the flexible architecture of FreeCAD it's easy to use it as base for your own special purpose program.

Warning

Although FreeCAD is offered to you free of charge, and the FreeCAD community is happy to see other applications emerging, that are based on FreeCAD, we have on the other hand seen a lot of unfair use of the information contained on this page by people who simply rebranded FreeCAD into a closed-source application to make profit from it.

Although the LGPL license allows to use the FreeCAD source code in closed-source applications, it also gives strict rules to do so, and does not allow simply taking FreeCAD, renaming it and stripping it of its license.

Would you be interested in using FreeCAD in a closed-source application, be sure to check thoroughly the implications of the LGPL license, and, even better, contact any FreeCAD developer, administrator or moderator before doing so.

General

Most of the branding is done in the MainCmd.cpp or MainGui.cpp. These Projects generate the executable files of FreeCAD. To make your own Brand just copy the Main or MainGui projects and give the executable its own name, e.g. FooApp.exe. The most important settings for a new look are made in one place in the main() function. Here is the code section that controls the branding:

</translate>

int main( int argc, char ** argv )
{
    // Name and Version of the Application
    App::Application::Config()["ExeName"] = "FooApp";
    App::Application::Config()["ExeVersion"] = "0.7";

    // set the banner (for loging and console)
    App::Application::Config()["CopyrightInfo"] = sBanner;
    App::Application::Config()["AppIcon"] = "FooAppIcon";
    App::Application::Config()["SplashScreen"] = "FooAppSplasher";
    App::Application::Config()["StartWorkbench"] = "Part design";
    App::Application::Config()["HiddenDockWindow"] = "Property editor";
    App::Application::Config()["SplashAlignment" ] = "Bottom|Left";
    App::Application::Config()["SplashTextColor" ] = "#000000"; // black

    // Inits the Application 
    App::Application::Config()["RunMode"] = "Gui";
    App::Application::init(argc,argv);

    Gui::BitmapFactory().addXPM("FooAppSplasher", ( const char** ) splash_screen);

    Gui::Application::initApplication();
    Gui::Application::runApplication();
    App::Application::destruct();

    return 0;
}

<translate>

The first Config entry defines the program name. This is not the executable name, which can be changed by renaming or by compiler settings, but the name that is displayed in the task bar on windows or in the program list on Unix systems.

The next lines define the Config entries of your FooApp Application. A description of the Config and its entries you find in Start up and Configuration.

Images

Image resources are compiled into FreeCAD using Qt's resource system. Therefore you have to write a .qrc file, an XML-based file format that lists image files on the disk but also any other kind of resource files. To load the compiled resources inside the application you have to add a line

</translate>

Q_INIT_RESOURCE(FooApp);

<translate>

into the main() function. Alternatively, if you have an image in XPM format you can directly include it into your main.cpp and add the following line to register it:

</translate>

Gui::BitmapFactory().addXPM("FooAppSplasher", ( const char** ) splash_screen);

<translate>

Branding XML

In FreeCAD there is also a method supported without writing a customized main() function. For this method you must write a file name called branding.xml and put it into the installation directory of FreeCAD. Here is an example with all supported tags:

</translate>

<?xml version="1.0" encoding="utf-8"?>
<Branding>
    <Application>FooApp</Application>
    <WindowTitle>Foo App in title bar</WindowTitle>
    <BuildVersionMajor>1</BuildVersionMajor>
    <BuildVersionMinor>0</BuildVersionMinor>
    <BuildRevision>1234</BuildRevision>
    <BuildRevisionDate>2014/1/1</BuildRevisionDate>
    <CopyrightInfo>(c) My copyright</CopyrightInfo>
    <MaintainerUrl>Foo App URL</MaintainerUrl>
    <ProgramLogo>Path to logo (appears in bottom right corner)</ProgramLogo>
    <WindowIcon>Path to icon file</WindowIcon>
    <ProgramIcons>Path to program icons</ProgramIcons>
    <SplashScreen>splashscreen.png</SplashScreen>
    <SplashAlignment>Bottom|Left</SplashAlignment>
    <SplashTextColor>#ffffff</SplashTextColor>
    <SplashInfoColor>#c8c8c8</SplashInfoColor>
    <StartWorkbench>PartDesignWorkbench</StartWorkbench>
</Branding>

<translate>

All listed tags are optional.


</translate>

<translate>

</translate>

<translate>

Overview

Localisation is in general the process of providing a Software with a multiple language user interface. In FreeCAD you can set the language of the user interface under Edit → Preferences → General. FreeCAD uses Qt to enable multiple language support. On Unix/Linux systems, FreeCAD uses the current locale settings of your system by default.

Helping to translate FreeCAD

One of the very important things users can contribute to FreeCAD (if for example they don't have programming skills) is to help translate its different aspects (source code, wiki, website, documentation etc...) in to another language. Here are the ways to do that.

Translate the FreeCAD source code

FreeCAD utilizes a third party collaborative on-line translation system called Crowdin.

It is proprietary software but free to FOSS projects. Below are instructions on how to use it:

  • Go to the FreeCAD translation project page on Crowdin
  • Login by creating a new profile, or using a third-party account (GitHub, GitLab, GMail etc...)
  • Click on the language you wish to translate
  • Start translating by clicking on the Translate button next to one of the files. For example, FreeCAD.ts contains the text strings for the FreeCAD main GUI.
  • You can vote for existing translations, or you can create your own.
If you are actively taking part in translating FreeCAD and want to be informed before next release is ready to be launched, so there is time to review your translation, please subscribe to one of the Crowdin FreeCAD translation teams.


Note: Details on how to use crowdin can be found on the Crowdin Administration page.

Translating external workbenches

Visit Translating an external workbench.

FreeCAD Preferences for Translators

Starting with FreeCAD 0.20, the following variables can be manually added to the BaseApp/Preferences/General section of the user.cfg file to assist with the development of new translations:

AdditionalLanguageDomainEntries - to add entirely new languages to FreeCAD that are not currently supported by the source code, you can use this user preference to add to the list of available languages. The format of the languages is "Language Name"="code"; for example:

</translate>

<FCText Name="AdditionalLanguageDomainEntries">"Esperanto"="eo";"French"="fr";</FCText>

<translate>

AdditionalTranslationsDirectory - add an additional directory for FreeCAD to search for *.qm files. This location will take precedence over $userAppDataDir/translations and $resourceDir/translations. For example:

</translate>

<FCText Name="AdditionalTranslationsDirectory">C:/Users/FreeCADUser/TestTranslations</FCText>

<translate>

Translate the FreeCAD wiki

This wiki hosts a lot of contents, the majority of which build up the manual. You can browse the documentation starting from the Main Page, or have a look at the user's manual Online Help Toc.

To translate the wiki, you must have wiki edit permissions; see How can I get edit permission on the wiki?.

You should also have enough knowledge of wiki markup and follow the general styling guidelines described on WikiPages.

Mediawiki Translation Extension

When the wiki moved away from SourceForge, Yorik installed MediaWiki's Translation extension which facilitates translating pages. Advantages of the translation extension are that the page title can now be translated, it keeps track of translations, it notifies if the original page has been updated, and it maintains translations in sync with the original English page.

The tool is documented in Help:Extension:Translate, and is part of MediaWiki Language Extension Bundle.

To quickly get started on preparing a page for translation, please read the Page translation example. Essentially, a pair of

</translate>

<translate> ... </translate>

<translate>

tags need to surround the entire page to activate the translation system, and the page needs to be marked for translation.

To see an example of how the translation tool works, visit the Main Page. You will see an automatically generated language bar at the top. Click on Deutsch (German), it will get you to Main Page/de. Right under the title, "Hauptseite" (in English "Main Page"), you can read This page is a translated version of the page Main Page and the translation is XX% complete, XX being the current percentage of translation. Click on "Translate" at the top of the page to start the translation utility to update, correct and review the existing translation.

If you go to Main Page, you will notice that you cannot edit the page directly anymore by clicking the [Edit] tags, and the top link "Edit" has been substituted by the "Translate" link that opens the translation utility.

When adding new content, the English page should be created first, then translated into another language. If someone wants to change or add content in a page, the English page should be modified first.

If you are unsure on how to proceed with the translations, don't hesitate to ask for help in the Development → Wiki subforum or in the specific language subforum in the FreeCAD forum.

Important notes

Every wiki user that has "Editor" permissions is able to launch the translate utility to write, save and review translations.

However, only users with "Administrator" permissions are able to mark pages for translation. A page that is not marked for translation won't make use of the translation extension and won't be correctly synchronized to the English information.

The left sidebar is also translatable, but only Administrators can modify this element of the site. Please follow the dedicated instructions on Localisation Sidebar.

The first time you switch a page to the new translation system, it loses all its old "manual" translations. To recover a translation, you should save an offline copy of the old text before the switch. Then you can use this old translated text to fill in the translation units in the new system. You can also open an earlier version from the history, and get the old text in this way. This has to be done for every language that had a translated page.

Translate the FreeCAD documentation

As per general consensus, the reference page in the wiki is the English page, which should be created first. If you want to change or add content to a page, you should do it to the English page first, and only once the update is completed, port the modification to the translated page.

Old translation instructions

These instructions are for historical background only. Translations should use the new system with the #Mediawiki Translation Extension described above.

So the first step is to check if the manual translation has already been started for your language (look in the left sidebar, under "manual").
If not, head to the forum and say that you want to start a new translation, we'll create the basic setup for the language you want to work on.
You must then gain wiki edit permission.
If your language is already listed, see what pages are still missing a translation (they will be listed in red). The technique is simple: go into a red page, and copy/paste the contents of the corresponding English page, and start translating.
Do not forget to include all the tags and templates from the original English page. Some of those templates will have an equivalent in your language (for example, there is a French Docnav template called Docnav/fr). You should use a slash and your language code in almost all the links. Look at other already translated pages to see how they did it.
Add a slash and your language code in the categories, like [[Category:Developer Documentation/fr]]
And if you are unsure, head to the forums and ask people to check what you did and tell you if it's right or not.
Four templates are commonly used in manual pages. These 4 templates have localized versions (Template:Docnav/fr, Template:fr, etc...)

  • Template:GuiCommand : is the Gui Command information block in upper-right of command documentation.
  • Template:Docnav : it is the navigation bar at the bottom of the pages, showing previous and next pages.
  • Template:Userdocnavi : gives direct links to the main base pages

Page Naming Convention
Please take note that, due to limitations in the Sourceforge implementation of the MediaWiki engine, we require that your pages all keep their original English counterpart's name, appending a slash and your language code. For example, the translated page for About FreeCAD should be About Freecad/es for Spanish, About FreeCAD/pl for polish, etc. The reason is simple: so that if translators go away, the wiki's administrators, who do not speak all languages, will know what these pages are for. This will facilitate maintenance and avoid lost pages.
If you want the Docnav template to show linked pages in your language, you can use redirect pages. They are basically shortcut links to the actual page. Here is an example with the French page for About FreeCAD.

  • The page About FreeCAD/fr is the page with content
  • The page À propos de FreeCAD contains this code:
#REDIRECT [[About_FreeCAD/fr]]
  • In the About FreeCAD/fr page, the Docnav code will look like this:
{{docnav/fr|[[Online_Help_Startpage/fr|Bienvenue dans l'aide en ligne de FreeCAD]]|[[Feature_list/fr|Fonctionnalités]]}}

The page "Bienvenue dans l'aide en ligne de FreeCAD" redirects to Online_Help_Startpage/fr, and the page "Fonctionnalités" redirects to Feature_list/fr.

Translate the FreeCAD website

Translation of the FreeCAD website is now done through Crowdin. The file is named homepage.po.

Development - How to Add Localisation

This section is for developers who want to add localisation to their code.

Preparing your FreeCAD/master modules for translation

These are the parts to the FreeCAD translation process:

  • extract text strings from source code into *.ts files
  • load *.ts files into FreeCAD Crowdin.
  • translation of strings within Crowdin
  • extract modified/new *.ts files from Crowdin
  • convert *.ts files into *.qm files and update each module's *.qrc file
  • update FreeCAD master

All of the above steps are performed by the "translation scripts" which are run by an administrator periodically.

Preparing your module for translation is quite easy. First, you need to ensure that you have a "translations" directory in myModule/Gui/Resources. Then open a terminal window (or Windows/OSX equivalent) in your "translations" directory and enter the following command:

lupdate -ts myModule.ts

This creates an empty translation file. Once this is done, you need to ensure that the translation scripts are updated as in this pull request.

Everything after this is automatic as far as a developer is concerned. The administrator will extract the text strings, the translators will translate them, then the administrator will extract the translations and update FreeCAD/master.

Preparing your 3rd party module or macro for translation

3rd party modules or macros are translated in much the same fashion, except that you must do some of the work yourself. This forum discussion describes the details.

Update: see Translating an external workbench

Older module translation techniques

Localization Older Methods describes the use of translation tools such as Qt Linguist, lupdate, lrelease, pylupdate4, etc in detail. Most of this is no longer required for FreeCAD/master modules, but may be helpful preparing and updating 3rd party modules.

Automating Crowdin Translation Updates

Currently FreeCAD maintainers use the Crowdin API via Crowdin Scripts to pull and push translations in to Crowdin and back in to the Github repo. The Crowdin API gives FreeCAD maintainers the ability to automate aspects of the project's translation workflow, for more info refer to the Crowdin API documentation.

Related Pages

Scripting

See also: FreeCAD Scripting Basics.

To get a dictionary with the languages the FreeCAD interface supports, use the supportedLocales method of the FreeCADGui module.

</translate>

locales = FreeCADGui.supportedLocales()

<translate>

After execution locales will contain:

</translate>

{'English': 'en', 'Afrikaans': 'af', 'Arabic': 'ar', 'Basque': 'eu', 'Catalan': 'ca', 'Chinese Simplified': 'zh-CN', 'Chinese Traditional': 'zh-TW', 'Croatian': 'hr', 'Czech': 'cs', 'Dutch': 'nl', 'Filipino': 'fil', 'Finnish': 'fi', 'French': 'fr', 'Galician': 'gl', 'German': 'de', 'Hungarian': 'hu', 'Indonesian': 'id', 'Italian': 'it', 'Japanese': 'ja', 'Kabyle': 'kab', 'Korean': 'ko', 'Lithuanian': 'lt', 'Norwegian': 'no', 'Polish': 'pl', 'Portuguese': 'pt-PT', 'Portuguese, Brazilian': 'pt-BR', 'Romanian': 'ro', 'Russian': 'ru', 'Slovak': 'sk', 'Slovenian': 'sl', 'Spanish': 'es-ES', 'Swedish': 'sv-SE', 'Turkish': 'tr', 'Ukrainian': 'uk', 'Valencian': 'val-ES', 'Vietnamese': 'vi'}

<translate>

To get the current interface language use the getLocale method of the same module:

</translate>

locale = FreeCADGui.getLocale()

<translate>

If the current language is English locale will contain:

</translate>

'English'

<translate>

To get the corresponding language code you can use use:

</translate>

locale = FreeCADGui.supportedLocales()[Gui.getLocale()]

<translate>

If the current language is English the result will be:

</translate>

'en'

<translate>

To set the current interface language use the setLocale method of the same module. You can specify the language or the language code:

</translate>

FreeCADGui.setLocale('Russian')
FreeCADGui.setLocale('ru')

<translate>


</translate>

<translate>

</translate>

<translate>

Overview

This page lists several additional Python modules or other pieces of software that can be downloaded freely from the internet, and add functionality to your FreeCAD installation.

PySide (previously PyQt)

PySide (previously PyQt) is required by several modules of FreeCAD to access FreeCAD's Qt interface. It is already bundled in the windows verison of FreeCAD, and is usually installed automatically by FreeCAD on Linux, when installing from official repositories. If those modules (Draft, Arch, etc) are enabled after FreeCAD is installed, it means PySide (previously PyQt) is already there, and you don't need to do anything more.

Note: FreeCAD progressively moved away from PyQt after version 0.13, in favour of PySide, which does exactly the same job but has a license (LGPL) more compatible with FreeCAD.

Installation

Linux

The simplest way to install PySide is through your distribution's package manager. On Debian/Ubuntu systems, the package name is generally python-PySide, while on RPM-based systems it is named pyside. The necessary dependencies (Qt and SIP) will be taken care of automatically.

Windows

The program can be downloaded from http://qt-project.org/wiki/Category:LanguageBindings::PySide::Downloads . You'll need to install the Qt and SIP libraries before installing PySide (to be documented).

MacOS

PySide on Mac can be installed via homebrew or port. See Install dependencies for more information.

Usage

Once it is installed, you can check that everything is working by typing in FreeCAD Python console:

</translate>

import PySide

<translate>

To access the FreeCAD interface, type:

</translate>

from PySide import QtCore,QtGui
FreeCADWindow = FreeCADGui.getMainWindow()

<translate>

Now you can start to explore the interface with the dir() command. You can add new elements, like a custom widget, with commands like:

</translate>

FreeCADWindow.addDockWidget(QtCore.Qt.RghtDockWidgetArea,my_custom_widget)

<translate>

Working with Unicode:

</translate>

text = text.encode('utf-8')

<translate>

Working with QFileDialog and OpenFileName:

</translate>

path = FreeCAD.ConfigGet("AppHomePath")
#path = FreeCAD.ConfigGet("UserAppData")
OpenName, Filter = PySide.QtGui.QFileDialog.getOpenFileName(None, "Read a txt file", path, "*.txt")

<translate>

Working with QFileDialog and SaveFileName:

</translate>

path = FreeCAD.ConfigGet("AppHomePath")
#path = FreeCAD.ConfigGet("UserAppData")
SaveName, Filter = PySide.QtGui.QFileDialog.getSaveFileName(None, "Save a file txt", path, "*.txt")

<translate>

Example of transition from PyQt4 and PySide

PS: these examples of errors were found in the transition from PyQt4 to PySide and these corrections were made, other solutions are certainly available with the examples above

</translate>

try:
    import PyQt4                                        # PyQt4
    from PyQt4 import QtGui ,QtCore                     # PyQt4
    from PyQt4.QtGui import QComboBox                   # PyQt4
    from PyQt4.QtGui import QMessageBox                 # PyQt4
    from PyQt4.QtGui import QTableWidget, QApplication  # PyQt4
    from PyQt4.QtGui import *                           # PyQt4
    from PyQt4.QtCore import *                          # PyQt4
except Exception:
    import PySide                                       # PySide
    from PySide import QtGui ,QtCore                    # PySide
    from PySide.QtGui import QComboBox                  # PySide
    from PySide.QtGui import QMessageBox                # PySide
    from PySide.QtGui import QTableWidget, QApplication # PySide
    from PySide.QtGui import *                          # PySide
    from PySide.QtCore import *                         # PySide

<translate>

To access the FreeCAD interface, type: You can add new elements, like a custom widget, with commands like:

</translate>

myNewFreeCADWidget = QtGui.QDockWidget()          # create a new dockwidget
myNewFreeCADWidget.ui = Ui_MainWindow()           # myWidget_Ui()             # load the Ui script
myNewFreeCADWidget.ui.setupUi(myNewFreeCADWidget) # setup the ui
try:
    app = QtGui.qApp                              # PyQt4 # the active qt window, = the freecad window since we are inside it
    FCmw = app.activeWindow()                     # PyQt4 # the active qt window, = the freecad window since we are inside it
    FCmw.addDockWidget(QtCore.Qt.RightDockWidgetArea,myNewFreeCADWidget) # add the widget to the main window
except Exception:
    FCmw = FreeCADGui.getMainWindow()             # PySide # the active qt window, = the freecad window since we are inside it
    FCmw.addDockWidget(QtCore.Qt.RightDockWidgetArea,myNewFreeCADWidget) # add the widget to the main window

<translate>

Working with Unicode:

</translate>

try:
    text = unicode(text, 'ISO-8859-1').encode('UTF-8')  # PyQt4
except Exception:
    text = text.encode('utf-8')                         # PySide

<translate>

Working with QFileDialog and OpenFileName:

</translate>

OpenName = ""
try:
    OpenName = QFileDialog.getOpenFileName(None,QString.fromLocal8Bit("Lire un fichier FCInfo ou txt"),path,"*.FCInfo *.txt") # PyQt4
except Exception:
    OpenName, Filter = PySide.QtGui.QFileDialog.getOpenFileName(None, "Lire un fichier FCInfo ou txt", path, "*.FCInfo *.txt")#PySide

<translate>

Working with QFileDialog and SaveFileName:

</translate>

SaveName = ""
try:
    SaveName = QFileDialog.getSaveFileName(None,QString.fromLocal8Bit("Sauver un fichier FCInfo"),path,"*.FCInfo") # PyQt4
except Exception:
    SaveName, Filter = PySide.QtGui.QFileDialog.getSaveFileName(None, "Sauver un fichier FCInfo", path, "*.FCInfo")# PySide

<translate>

The MessageBox:

</translate>

def errorDialog(msg):
    diag = QtGui.QMessageBox(QtGui.QMessageBox.Critical,u"Error Message",msg )
    try:
        diag.setWindowFlags(PyQt4.QtCore.Qt.WindowStaysOnTopHint) # PyQt4 # this function sets the window before
    except Exception:
        diag.setWindowFlags(PySide.QtCore.Qt.WindowStaysOnTopHint)# PySide # this function sets the window before
#    diag.setWindowModality(QtCore.Qt.ApplicationModal)       # function has been disabled to promote "WindowStaysOnTopHint"
    diag.exec_()

<translate>

Working with setProperty (PyQt4) and setValue (PySide)

</translate>

self.doubleSpinBox.setProperty("value", 10.0) # PyQt4

<translate>

replace with:

</translate>

self.doubleSpinBox.setValue(10.0) # PySide

<translate>

Working with setToolTip

</translate>

self.doubleSpinBox.setToolTip(_translate("MainWindow", "Coordinate placement Axis Y", None)) # PyQt4

<translate>

replace with:

</translate>

self.doubleSpinBox.setToolTip(_fromUtf8("Coordinate placement Axis Y")) # PySide

<translate>

or:

</translate>

self.doubleSpinBox.setToolTip(u"Coordinate placement Axis Y.")# PySide

<translate>

Additional documentation

Pivy

Pivy is a needed by several modules to access the 3D view of FreeCAD. On windows, Pivy is already bundled inside the FreeCAD installer, and on Linux it is usually automatically installed when you install FreeCAD from an official repository. On macOS, unfortunately, you will need to compile pivy yourself.

Installation

Prerequisites

I believe before compiling Pivy you will want to have Coin and SoQt installed.

I found for building on Mac it was sufficient to install the Coin3 binary package. Attempting to install coin from MacPorts was problematic: tried to add a lot of X Windows packages and ultimately crashed with a script error.

For Fedora I found an RPM with Coin3.

SoQt compiled from source fine on Mac and Linux.

Debian & Ubuntu

Starting with Debian Squeeze and Ubuntu Lucid, pivy will be available directly from the official repositories, saving us a lot of hassle. In the meantime, you can either download one of the packages we made (for debian and ubuntu karmic) availables on the Download pages, or compile it yourself.

The best way to compile pivy easily is to grab the debian source package for pivy and make a package with debuild. It is the same source code from the official pivy site, but the debian people made several bug-fixing additions. It also compiles fine on ubuntu karmic: http://packages.debian.org/squeeze/python-pivy download the .orig.gz and the .diff.gz file, then unzip both, then apply the .diff to the source: go to the unzipped pivy source folder, and apply the .diff patch:

</translate>

patch -p1 < ../pivy_0.5.0~svn765-2.diff

<translate>

then

</translate>

debuild

<translate>

to have pivy properly built into an official installable package. Then, just install the package with gdebi.

Other linux distributions

First get the latest sources from the project's repository:

</translate>

hg clone http://hg.sim.no/Pivy/default Pivy

<translate>

As of March 2012, the latest version is Pivy-0.5.

Then you need a tool called SWIG to generate the C++ code for the Python bindings. Pivy-0.5 reports that it has only been tested with SWIG 1.3.31, 1.3.33, 1.3.35, and 1.3.40. So you can download a source tarball for one of these old versions from http://www.swig.org. Then unpack it and from a command line do (as root):

</translate>

./configure
make
make install (or checkinstall if you use it)

<translate>

It takes just a few seconds to build.

Alternatively, you can try building with a more recent SWIG. As of March 2012, a typical repository version is 2.0.4. Pivy has a minor compile problem with SWIG 2.0.4 on macOS (see below) but seems to build fine on Fedora Core 15.

After that go to the pivy sources and call

</translate>

python setup.py build

<translate>

which creates the source files. Note that build can produce thousands of warnings, but hopefully there will be no errors.

This is probably obsolete, but you may run into a compiler error where a 'const char*' cannot be converted in a 'char*'. To fix that you just need to write a 'const' before in the appropriate lines. There are six lines to fix.

After that, install by issuing (as root):

</translate>

python setup.py install (or checkinstall python setup.py install)

<translate>

That's it, pivy is installed.

MacOS

These instructions may not be complete. Something close to this worked for OS 10.7 as of March 2012. I use MacPorts for repositories, but other options should also work.

As for linux, get the latest source:

</translate>

hg clone http://hg.sim.no/Pivy/default Pivy

<translate>

If you don't have hg, you can get it from MacPorts:

</translate>

port install mercurial

<translate>

Then, as above you need SWIG. It should be a matter of:

</translate>

port install swig

<translate>

I found I needed also:

</translate>

port install swig-python

<translate>

As of March 2012, MacPorts SWIG is version 2.0.4. As noted above for linux, you might be better off downloading an older version. SWIG 2.0.4 seems to have a bug that stops Pivy building. See first message in this digest

This can be corrected by editing the 2 source locations to add dereferences: *arg4, *arg5 in place of arg4, arg5. Now Pivy should build:

</translate>

python setup.py build
sudo python setup.py install

<translate>

Windows

Assuming you are using Visual Studio 2005 or later you should open a command prompt with 'Visual Studio 2005 Command prompt' from the Tools menu. If the Python interpreter is not yet in the system path do

</translate>

set PATH=path_to_python_2.5;%PATH%

<translate>

To get pivy working you should get the latest sources from the project's repository:

</translate>

svn co https://svn.coin3d.org/repos/Pivy/trunk Pivy

<translate>

Then you need a tool called SWIG to generate the C++ code for the Python bindings. It is recommended to use version 1.3.25 of SWIG, not the latest version, because at the moment pivy will only function correctly with 1.3.25. Download the binaries for 1.3.25 from http://www.swig.org. Then unpack it and from the command line add it to the system path

</translate>

set PATH=path_to_swig_1.3.25;%PATH%

<translate>

and set COINDIR to the appropriate path

</translate>

set COINDIR=path_to_coin

<translate>

On Windows the pivy config file expects SoWin instead of SoQt as default. I didn't find an obvious way to build with SoQt, so I modified the file setup.py directly. In line 200 just remove the part 'sowin': ('gui._sowin', 'sowin-config', 'pivy.gui.') (do not remove the closing parenthesis).

After that go to the pivy sources and call

</translate>

python setup.py build

<translate>

which creates the source files. You may run into a compiler error several header files couldn't be found. In this case adjust the INCLUDE variable

</translate>

set INCLUDE=%INCLUDE%;path_to_coin_include_dir

<translate>

and if the SoQt headers are not in the same place as the Coin headers also

</translate>

set INCLUDE=%INCLUDE%;path_to_soqt_include_dir

<translate>

and finally the Qt headers

</translate>

set INCLUDE=%INCLUDE%;path_to_qt4\include\Qt

<translate>

If you are using the Express Edition of Visual Studio you may get a Python keyerror exception. In this case you have to modify a few things in msvccompiler.py located in your Python installation.

Go to line 122 and replace the line

</translate>

vsbase = r"Software\Microsoft\VisualStudio\%0.1f" % version

<translate>

with

</translate>

vsbase = r"Software\Microsoft\VCExpress\%0.1f" % version

<translate>

Then retry again. If you get a second error like

</translate>

error: Python was built with Visual Studio 2003;...

<translate>

you must also replace line 128

</translate>

self.set_macro("FrameworkSDKDir", net, "sdkinstallrootv1.1")

<translate>

with

</translate>

self.set_macro("FrameworkSDKDir", net, "sdkinstallrootv2.0")

<translate>

Retry once again. If you get again an error like

</translate>

error: Python was built with Visual Studio version 8.0, and extensions need to be built with the same version of the compiler, but it isn't installed.

<translate>

then you should check the environment variables DISTUTILS_USE_SDK and MSSDK with

</translate>

echo %DISTUTILS_USE_SDK%
echo %MSSDK%

<translate>

If not yet set then just set it e.g. to 1

</translate>

set DISTUTILS_USE_SDK=1
set MSSDK=1

<translate>

Now, you may run into a compiler error where a 'const char*' cannot be converted in a 'char*'. To fix that you just need to write a 'const' before in the appropriate lines. There are six lines to fix. After that copy the generated pivy directory to a place where the Python interpreter in FreeCAD can find it.

Usage

To check if Pivy is correctly installed:

</translate>

import pivy

<translate>

To have Pivy access the FreeCAD scenegraph do the following:

</translate>

from pivy import coin
App.newDocument() # Open a document and a view
view = Gui.ActiveDocument.ActiveView
FCSceneGraph = view.getSceneGraph() # returns a pivy Python object that holds a SoSeparator, the main "container" of the Coin scenegraph
FCSceneGraph.addChild(coin.SoCube()) # add a box to scene

<translate>

You can now explore the FCSceneGraph with the dir() command.

Additonal Documentation

Unfortunately documentation about pivy is still almost nonexistant on the net. But you might find Coin documentation useful, since pivy simply translate Coin functions, nodes and methods in Python, everything keeps the same name and properties, keeping in mind the difference of syntax between C and Python:

You can also look at the Draft.py file in the FreeCAD Mod/Draft folder, since it makes big use of pivy.

pyCollada

pyCollada is a Python library that allow programs to read and write Collada (*.DAE) files. When pyCollada is installed on your system, FreeCAD will be able to handle importing and exporting in the Collada file format.

Installation

Linux

</translate>

sudo apt-get install python3-collada

<translate>

You can check if pycollada was correctly installed by issuing in a Python console:

</translate>

import collada

<translate>

If it returns nothing (no error message), then all is OK

Windows

On Windows since 0.15 pycollada is included in both the FreeCAD release and developer builds so no additional steps are necessary.

MacOS

If you are using the Homebrew build of FreeCAD you can install pycollada into your system Python using pip.

If you need to install pip:

</translate>

$ sudo easy_install pip

<translate>

Install pycollada:

</translate>

$ sudo pip install pycollada

<translate>

If you are using a binary version of FreeCAD, you can tell pip to install pycollada into the site-packages inside FreeCAD.app:

</translate>

$ pip install --target="/Applications/FreeCAD.app/Contents/lib/python2.7/site-packages" pycollada

<translate>

or after downloading the pycollada code

</translate>

$ export PYTHONPATH=/Applications/FreeCAD\ 0.16.6706.app/Contents/lib/python2.7/site-packages:$PYTHONPATH
$ python setup.py install --prefix=/Applications/FreeCAD\ 0.16.6706.app/Contents

<translate>

IfcOpenShell

IFCOpenShell is a library currently in development, that allows to import (and soon export) Industry foundation Classes (*.IFC) files. IFC is an extension to the STEP format, and is becoming the standard in BIM workflows. When ifcopenshell is correctly installed on your system, the FreeCAD Arch Workbench will detect it and use it to import IFC files, instead of its built-in rudimentary importer. Since ifcopenshell is based on OpenCasCade, like FreeCAD, the quality of the import is very high, producing high-quality solid geometry.

Installation

Since ifcopenshell is pretty new, you'll likely need to compile it yourself.

Linux

You will need a couple of development packages installed on your system in order to compile ifcopenshell:

</translate>

liboce-*-dev
python-dev
swig

<translate>

but since FreeCAD requires all of them too, if you can compile FreeCAD, you won't need any extra dependency to compile IfcOpenShell.

Grab the latest source code from here:

</translate>

git clone https://github.com/IfcOpenShell/IfcOpenShell.git

<translate>

The build process is very easy:

</translate>

mkdir ifcopenshell-build
cd ifcopenshell-build
cmake ../IfcOpenShell/cmake

<translate>

or, if you are using oce instead of opencascade:

</translate>

cmake -DOCC_INCLUDE_DIR=/usr/include/oce ../ifcopenshell/cmake

<translate>

Since ifcopenshell is made primarily for Blender, it uses Python3 by default. To use it inside FreeCAD, you need to compile it against the same version of Python that is used by FreeCAD. So you might need to force the Python version with additional cmake parameters (adjust the Python version to yours):

</translate>

cmake -DOCC_INCLUDE_DIR=/usr/include/oce -DPYTHON_INCLUDE_DIR=/usr/include/python2.7 -DPYTHON_LIBRARY=/usr/lib/python2.7.so ../ifcopenshell/cmake

<translate>

Then:

</translate>

make
sudo make install

<translate>

You can check that ifcopenshell was correctly installed by issuing in a Python console:

</translate>

import ifcopenshell

<translate>

If it returns nothing (no error message), then all is OK

Windows

Note: Official FreeCAD installers obtained from the FreeCAD website/github page now contain ifcopenshell already.

Copied from the IfcOpenShell README file

Users are advised to use the Visual Studio .sln file in the win/ folder. For Windows users a prebuilt Open CASCADE version is available from the opencascade website. Download and install this version and provide the paths to the Open CASCADE header and library files to MS Visual Studio C++.

For building the IfcPython wrapper, SWIG needs to be installed. Please download the latest swigwin version from swig website. After extracting the .zip file, please add the extracted folder to the PATH environment variable. Python needs to be installed, please provide the include and library paths to Visual Studio.

Links

Tutorial Import/Export IFC - compiling IfcOpenShell

LazyLoader

LazyLoader is a Python module that allows deferred loading, while still importing at the top of the script. This is useful if you are importing another module that is slow, and it is used several times throughout the script. Using LazyLoader can improve workbench startup times, but the module will still need to be loaded on first use.

Installation

LazyLoader is included with FreeCAD v0.19

Usage

You will need to import LazyLoader, then change the import of whatever module you want to be deferred.

from lazy_loader.lazy_loader import LazyLoader
Part = LazyLoader('Part', globals(), 'Part')

The variable Part is how the module is named in your script. You can replicate "import Part as P" by changing the variable.

P = LazyLoader('Part', globals(), 'Part')

You can also import a module from a package.

utils = LazyLoader('PathScripts', globals(), 'PathScripts.PathUtils')

You can't import individual functions, just entire modules.

Links


</translate>

Credits

<translate>

</translate>

<translate>

</translate> <translate>

FreeCAD would not be what it is without the generous contributions of many people. Here's an overview of the people and companies who contributed to FreeCAD over time. For credits for the third party libraries see the Third Party Libraries page.

Development

Project managers

Lead developers of the FreeCAD project:

</translate>

<translate>

Main developers

People who work regularly on the FreeCAD code (retrieved from https://github.com/FreeCAD/FreeCAD/graphs/contributors):

</translate>

<translate>

Other coders

Other people who contributed code to the FreeCAD project:

</translate>

  • Barleyman
  • Berthold Grupp
  • dbtayl
  • Dmitry Chigrin
  • ezzieyguywuf
  • fandaL
  • Georg Wiora
  • Graeme van der Vlugt
  • itain
  • j-dowsett
  • Jacques-Antoine Gaudin
  • jcc242
  • jmaustpc
  • Joachim Zettler
  • jobermayr
  • Johan3DV
  • jonnor
  • keithsloan52
  • Ken Cline
  • Mandeep Singh
  • marktaff
  • Martin Burbaum
  • maurerpe
  • ovginkel
  • peterl94
  • plaes
  • poutine70
  • TheMarkster
  • qingfengxia
  • Remigiusz Fiedler (DXF-parser)
  • SebKuzminsky
  • tomate44
  • triplus
  • usakhelo

<translate>

Companies

Companies which donated code, assets or developer time:

</translate>

<translate>

Forum moderators

People in charge of the FreeCAD forum (retrieved from http://forum.freecadweb.org/memberlist.php?mode=team):

</translate>

<translate>

Community

People from the community who put a lot of efforts in helping the FreeCAD project either by being active on the forum, keeping a blog about FreeCAD, making video tutorials, packaging FreeCAD for Windows/Linux/macOS, writing a FreeCAD book... (listed by alphabetical order) (retrieved from http://forum.freecadweb.org/memberlist.php?mode=&sk=d&sd=d#memberlist).

</translate>

<translate>

Documentation writers

People who wrote the documentation on this wiki:

</translate>

<translate>

Translators

People who helped to translate the FreeCAD application (retrieved from https://crowdin.com/project/freecad):

</translate>

<translate>

Addons developers

Developers of FreeCAD addons (retrieved from https://github.com/FreeCAD/FreeCAD-addons):

</translate>

<translate>


</translate>