Manual/sv

From FreeCAD Documentation
Jump to: navigation, search

Detta är FreeCAD manualen. Den innehåller de viktiga delarna ur FreeCADs dokumentationswiki. Den är avsedd att skrivas ut som ett enda stort dokument, så om du läser detta online, så kanske du föredrar att hoppa direkt tillOnline hjälp versionen, vilken är lättare att använda.



150

Välkommen till FreeCAD on-line hjälp

Detta dokument har skapats automatiskt av innehållet i den officiella FreeCAD wiki dokumentationen, vilken kan läsas online på http://www.freecadweb.org/wiki/index.php?title=Main_Page. Eftersom wikin underhålls och utvecklas kontinuerligt av FreeCAD communityn av utvecklare och användare, så kan du finna att online-versionen innehåller mer eller nyare information än detta dokument. Men vi hoppas i alla fall att du kommer hitta all den information du behöver här. Om du har frågor som du inte kan hitta svaren på i detta dokument, ta en titt på FreeCAD forumet, där din fråga kanske finns besvarad, eller du finner någon som kan hjälpa dig.

Hur man använder detta dokument

Detta dokument är uppdelat i flera avsnitt: introduktion, användande, skriptning och utveckling, de sista tre är specifikt tillägnade de tre breda FreeCAD användarkategorierna: slutanvändare, som helt enkelt vill använda programmet, experter, som är intresserade av FreeCAD's skriptmöjligheter och vill förändra några av dess egenskaper, och utvecklare, som vill använda FreeCAD som en bas för att utveckla sina egna applikationer. Om du aldrig har använt FreeCAD innan, så föreslår vi att du startar med introduktionen.

Bidra

Som du kanske märkt tidigare, så är programmerare riktigt dåliga manualskrivare! För dem är allting självklart, eftersom de skrev programmet på det sättet. Därför är det viktigt att användare med god erfarenhet hjälper oss att skriva och revidera dokumentationen. Ja, vi menar dig! Hur, frågar du dig? Gå bara till wikin http://www.freecadweb.org/wiki/index.php i användarsektionen. Du kommer att behöva ett sourceforge konto för att logga in, sedan kan du börja att redigera!


Introduktion

Freecad default.jpg

FreeCAD är en allmän 3D CAD modellerare. Utvecklingen är helt baserad på öppen källkod (GPL & LGPL Licens). FreeCAD riktar sig direkt till mekanisk konstruktion och produkt design men passar även i ett bredare område inom konstruktion, som arkitektur eller andra konstruktions specialiteter.


FreeCAD erbjuder verktyg liknande Catia, SolidWorks eller Solid Edge, och hamnar därför i samma kategorier som MCAD, PLM, CAx och CAE. Det kommer att bli en parametrisk solidmodellerare med en modulär mjukvaruarkitektur vilket gör det lätt att erbjuda extre funktionalitet utan att behöva ändra kärnsystemet.


Som med många moderna 3D CAD modellerare så kommer den att ha en 2D komponent för att kunna skapa ritningar av 3D modellen, men direkt 2D ritare (som AutoCAD LT) är inte avsikten, inte heller animeringar eller organiska former (som Maya, 3ds Max eller Cinema 4D), fast tack vare sin stora anpassningsbarhet, så kan FreeCAD bli användbart inom ett mycket större område än vad som avses för tillfället.


En annan viktig sak för FreeCAD är ett flitigt användande av alla de fantastiska öppen-källkodsbibliotek som finns därute inom området Vetenskaplig databehandling. Bland dem är OpenCascade, en kraftfull CAD kärna, Coin3D, en inkarnation av OpenInventor, Qt, det världsberömda användargränssnittsverktyget, och Python, en av de bästa skriptspråken som finns. Själva FreeCAD kan även användas som ett bibliotek av andra program.


FreeCAD är också helt multiplattform, och fungerar för närvarande perfekt på Windows och Linux/Unix och Mac OSX systems, med exakt samma utseende och funktionalitet på alla plattformarna.


Blev du nyfiken? Ta en titt på Egenskaper eller Introduktion artiklarna, eller hoppa direkt till Användarhubben!

FreeCAD features tools similar to Catia, SolidWorks or Solid Edge, and therefore also falls into the category of MCAD, PLM, CAx and CAE. It is a feature based parametric modeler with a modular software architecture which makes it possible to provide additional functionality without modifying the core system.

As with many CAD modelers it has many 2D components in order to sketch planar shapes or create production drawings. However, direct 2D drawing (like Inkscape or AutoCAD LT) is not the focus, neither are animation or mesh edition (like Blender, Maya, 3ds Max, or Cinema 4D). Nevertheless, thanks to its wide adaptability, FreeCAD might become useful in a much broader area than its current focus.

FreeCAD makes heavy use of open-source libraries that exist in the field of scientific computing. Among them are Open Cascade Technology (OCCT), a powerful CAD kernel; Coin3D, a toolkit for 3D graphics development compatible with Open Inventor; Qt, the world-famous user interface framework; and Python, a modern scripting language. FreeCAD itself can also be used as a library by other programs.

FreeCAD is also multi-platform, and currently runs on Linux/Unix, Windows, and Mac OSX systems with the same look and functionality on all platforms.

For more information about FreeCAD's capabilities, take a look at the feature list, the latest release notes, and the getting started articles, or see more screenshots.

About the FreeCAD project

The FreeCAD project was started as far back as 2001, as described in its history page.

FreeCAD is maintained and developed by a community of enthusiastic developers and users (see the contributors page). They work on FreeCAD voluntarily, in their free time. They cannot guarantee that FreeCAD contains everything you might wish, but they will do their best! The community gathers on the FreeCAD forum, where most of the ideas and decisions are discussed. Feel free to join us there!


Detta är en extensiv, fast inte komplett, lista på de funktioner som FreeCAD har. Om du vill se in i framtiden, se utvecklingskartan för en snabb överblick så är Skärmdumpar en bra plats att gå till.

Release notes

Allmäna funktioner

  • Feature1.jpg
    En komplett OpenCasCade-baserad geometrikärna som tillåter komplexa 3D operationer på komplexa formtyper, och stöder nativt koncept som brep, nurbs, booleska operationer eller fasningar
  • Feature7.jpg
    En Skissare med begränsningslösare, som låter dig skissa geometri-begränsade 2D former. Skissare tillåter dig för tillfället att bygga flera typer av begränsad geometri, och sedan använda dem som en bas att bygga andra objekt i FreeCAD.
  • Feature9.jpg
    En Robot simulerings modul som tillåter dig att studera robotrörelser. Robotmodulen har redan ett utökat grafiskt gränssnitt, vilket kan användas för ett smidigt arbetsflöde.
  • Feature8.jpg
    En Ritningsark modul som låter dig skapa 2D vyer på dina 3D modeler på ett ritningsark. Denna modul producerar sedan färdiga SVG eller PDF dokument. Modulen är ännu funktionsfattig, men har redan en kraftfull python-funktionalitet.
  • Feature-raytracing.jpg
    En Renderingsmodul som kan exportera 3D objekt för rendering med externa rendererare. Stödjer för närvarande endast povray, men förväntas stödja andra renderare i framtiden.
  • Feature-arch.jpg
    En Arkitektur modul som tillåter BIM-likt arbetsflöde, med IFC kompatibilitet. Skapandet av arkitekturmodulen diskuteras mycket av communityn här.
BIM-like workflow, with IFC compatibility. The making of the Arch module is heavily discussed by the community here.

Allmänna funktioner

  • FreeCAD är multi-plattform. Det kan köras och beter sig på exakt samma sätt på Windows Linux och Mac OSX plattformarna.
  • FreeCAD är en helgrafisk applikation. FreeCAD har ett komplett grafiskt användargränssnitt baserat på det berömda Qt strukturen, med en 3D visare baserad på Open Inventor, vilket tillåter snabb rendering av 3D scener och en mycket lättåtkomlig scenrepresentation.
  • FreeCAD kan också köras som en kommandolinje applikation, med litet minnesbehov. I kommandolinje läge, så körs FreeCAD utan ett gränssnitt, men med alla geometriverktyg. Det kan till exempel användas som en server för att producera data för andra applikationer.
  • FreeCAD kan importeras som en Python modul, inuti andra applikationer som kan köra python skript, eller i en python konsol. Som i konsol läge, så är FreeCAD's gränssnitt otillgängligt, men alla geometriverktyg finns tillgängliga.
  • Arbetsbänk koncept: I FreeCAD gränssnittet, så är verktygen grupperade i arbetsbänkar. Detta innebär att endast de verktyg som behövs för att utföra en viss uppgift visas, vilket håller arbetsytan ren och responsiv, och snabb laddning av applikationen.
  • Plugin/Modul struktur för sen laddnig av funktioner/data-typer. FreeCAD är uppdelat i en kärnapplikation och moduler, som endast laddas när de behövs. Nästan alla verktyg och geometrityper är lagrade i moduler. Moduler beter sig som plugins, och kan adderas eller tas bort från en existerande installation av FreeCAD.
  • Parametriska associativa dokumentobjekt: Alla objekt i ett FreeCAD dokument kan definierass av parametrar. Dessa parametrar kan ändras direkt, och omberäknas när som helst. Förhållandet mellan objekt lagras också, så om ett objekt ändras, så ändras även de objekt som är beroende av det.
  • Parametriska primitiver som låda, sfär, cylinder, kon eller torus.
  • Grafiska ändringsoperationer som förflyttning, rotation, skalning, spegling, offset (trivial or after Jung/Shin/Choi) eller formförändring, i valfritt plan i 3D rymden
  • Grafiskt skapande avenkel plangeometri som linjer, trådar, rektanglar, cirkelbågar eller cirklar i valfritt plan i 3D rymden
  • Modellering med raka eller rotering extrusioner, sektioneringar och avrundningar.
  • Topologiska komponenter som hörn, kanter, trådar och plan (via pythonskript).
  • Testing and repairing tools for meshes: solid test, non-two-manifolds test, self-intersection test, hole filling and uniform orientation.
  • Anteckningar som texter eller dimensioner
  • Ångra/Gör om struktur: Allt kan ångras eller göras om, med åtkomst till ångra minnet, så multipla steg kan ångras åt gången.
  • Transaktionshantering: Ångra/Gör om minnet lagrar dokumenttransaktioner och inte enstaka aktioner, vilket tillåter varje verktyg att exakt definiera vad som ska ångras eller göras om.
  • Inbyggd skript struktur: FreeCAD tillhandahåller en inbyggd Python tolk, och ett API som täcker nästan alla delar av applikationen, gränssnittet, geometrin och representationen av denna geometri i 3D visaren. Tolken kan köra från enstaka kommandon upp till komplexa skript, faktum är att hela moduler kan programmeras helt och hållet i Python.
  • Inbyggd Python konsol med syntaxmarkering, autokomplettering och klassvisare: Python kommandon kan utföras direk i FreeCAD och ge resultat omedelbart, vilket tillåter skriptskrivare att testa funktionaliteten direkt, utforska modulernas innehåll och lätt lära sig FreeCAD's innanmäte.
  • Användarinteraktion speglas i konsolen: Allt som användaren gör i FreeCAD's gränssnitt, kör pythonkod, vilken kan skrivas ut i konsolen och spelas in i makron.
  • Full makro inspelning & redigering: De pythonkommandon som körs när användaren manipulerar gränssnittet kan spelas in, om nödvändigt redigeras, och sparas för att reproduceras senare.
  • Sammansatt (ZIP baserat) dokumentformat: FreeCAD dokument som är sparade med filtypen .fcstd kan innehålla många olika informationstyper, som geometri, skript eller tumnagelikoner.
  • Fullt anpassningsbart/skriptbart grafiskt användargränssnitt. Det Qt-baserade gränssnittet i FreeCAD är helt åtkomligt via python tolken. Förutom de enkla funktioner som FreeCAD själv ger till arbetsbänkarna, så är hela Qt strukturen också tillgänglig, vilket tillåter vilken operation som helst på gränssnittet, som till exempel skapa, lägga till, docka, ändra eller ta bort widgets och verktygslådor.
  • Tumnaglare (endast Linux system för närvarande): FreeCAD's dokumentikoner visar filens innehåll i de flesta filhanterarapplikationer som till exempel gnome's nautilus.
  • en modulär MSI installerare tillåter flexibel installation på Windowssystem. Paket för Ubuntusystem är också underhållna.

I utveckling

  • Feature-assembly.jpg
    An Församling modul som gör det möjligt för att arbeta med flera projekt, flera former, flera dokument, flera filer, flera relationer...
  • Feature-CAM.jpg
    CAM modulen är tillägnad mekanisk bearbetning som till exempel fräsning. Denna modul har just påbörjats och är för tillfället mest tillägnad Inkrementell plåtformning. Fastän det finns en del algoritmer för verktygsväg planering, så är de inte användbara för slutanvändaren för tillfället.

Extra Workbenches

Power users have created various custom external workbenches.



Installation

Installera på Windows


The easiest way to install FreeCAD on Windows is to download the installer below. Windows.png Windows 32 bit (sha256)

Windows.png Windows 64 bit (sha256)

Det lättaste sättet att installera FreeCAD på Windows är genom att använda installeraren. Denna sida beskriver hur man använder den och egenskaperna av Microsoft Installeraren för mer installationsalternativ.

Enkel Installation

FreeCAD installeraren levereras i .msi (Windows Installer) format.

Du kan ladda ned den senaste .msi filen från den officiella FreeCAD nedladdningssidan.

Efter att du har laddat ned filen, dubbelklicka på den för att starta installationsprocessen.

Windows.png Windows 32 bit (sha256)

Windows.png Windows 64 bit (sha256)


After downloading the .msi (Microsoft Installer) file, double-click on it to start the installation process.

Below is more information about technical options. If it looks daunting, don't worry! Most Windows users will not need anything more than the above .msi to install FreeCAD and Get started!


Simple Microsoft Installer Installation

The easiest way to install FreeCAD on Windows is by using the downloadable installer bundle above. This page describes the usage and features of the Microsoft Installer for more installation options.

If you would like to download either a 64 bit or unstable development version, see the Download page. Download/sv

Kommandolinje Installation

Med msiexec.exe kommandolinje programmet, så finns ytterligare funktioner tillgängliga, som o-interaktiv installation och administrativ installation.

O-interaktiv Installation

Med kommandoraden

 msiexec /i FreeCAD<version>.msi

installation kan startas via ett program. Extra parametrar kan läggas till i slutet på denna kommandorad, som

msiexec /i FreeCAD-2.5.msi TARGETDIR=R:\FreeCAD25

Begränsat användargränssnitt

Det användargränssnitt som installeraren visar kan kontrolleras med /q alternativ, som:

  • /qn - Inget gränssnitt
  • /qb - Grundläggande gränssnitt - endast en liten förloppsdialog
  • /qb! - Som /qb, men göm Avbryt knappen
  • /qr - Reducerat gränssnitt - visar alla dialoger som inte kräver svar från användaren (skippa alla modala dialoger)
  • /qn+ - Like /qn, men visa "Färdig" dialogen vid slutet
  • /qb+ - Like /qb, men visa "Färdig" dialogen vid slutet

Målkatalog

Egenskapen TARGETDIR avgör FreeCAD installationens rotkatalog. Till exempel, en annan installationsenhet kan specificeras med

TARGETDIR=R:\FreeCAD25

Standard TARGETDIR är [WindowsVolume\Program\]FreeCAD<version>.

Installation för Alla användare

Genom att lägga till

ALLUSERS=1

så installeras programmet för alla användare. Som standard, så installerar den o-interaktiva installeraren paketet endast för den nuvarande användaren, och den interaktiva installeraren visar en dialog som har "alla användare" som standard, om användaren har tillräckliga rättigheter.

Val av funktioner

Ett antal egenskaper tillåter val av vilka funktioner som ska installeras, ominstalleras, eller tas bort. Funktionerna för FreeCAD installeraren är

  • DefaultFeature - installera mjukvaran korrekt, plus kärnbiblioteken
  • Documentation - installera dokumentationen
  • Source code - installera källkoden
  • ... ToDo

I tillägg, så specificerar ALL alla funktioner. Alla funktioner beror på DefaultFeature, så när en funktion installeras, så installeras även standardfunktionen automatiskt. Följande egenskaper kontrollerar vilka funktioner som ska installeras eller tas bort

  • ADDLOCAL - lista på funktioner som ska installeras på den lokala maskinen
  • REMOVE - lista på funktioner som ska tas bort
  • ADDDEFAULT - lista på funktioner som ska läggas till i dess standardkonfiguration (vilket är lokal för alla FreeCAD funktioner)
  • REINSTALL - lista på funktioner som ska ominstalleras/repareras
  • ADVERTISE - lista på funktioner som ska annonsera en installation

Det finns en del ytterligare alternativ tillgängliga; se MSDN dokumentationen för detaljer.

Med dessa alternativ, genom att lägga till

ADDLOCAL=Extensions

installerar själva tolken och registrerar extensionerna, men installerar inget annat.

Avinstallering

Med

msiexec /x FreeCAD<version>.msi

så kan FreeCAD avinstalleras. Det är inte nödvändigt att ha MSI filen tillgänglig för avinstalleringar; alternativt så kan även paketet eller produktkoden specificeras. Du kan hitta produktkoden genom att titta på avinstalleringsgenvägens egenskaper som FreeCAD installerar i startmenyn.

Administrativ installation

Med

msiexec /a FreeCAD<version>.msi

så kan en "administrativ" (nätverks) installation startas. Filerna packas upp till målkatalogen (vilken ska vara en nätverkskatalog), men inga andra ändringar görs på det lokala systemet. Dessutom genereras en annan (mindre) msi fil i målkatalogen, vilken klienter sedan kan använda för att utföra en lokal installation (framtida versioner kan också erbjuda att behålla vissa funktioner på nätverksenheten).

För närvarande finns det inget användargränssnitt för administrativa installationer, så målkatalogen måste specificeras på kommandolinjen.

Det finns ingen specifik avinstallationsprocedur för en administrativ installation - radera bara målkatalogen om inga klienter använder den längre.

Annonsering

Med

msiexec /jm FreeCAD<version>.msi

så är det i princip möjligt att "annonsera" FreeCAD till en maskin (med /ju till en användare). Detta gör att ikonerna syns i startmenyn, och extensionerna registreras, utan att någon mjukvara installeras. Det första användandet av en funktion orsakar en installation av densamma.

FreeCAD installeraren stödjer för närvarande endast annonsering till startmenyn, men inga annonseringar av genvägar.

Automatisk Installation på en maskingrupp

Med Windows Group Policy, så är det möjlig att automatiskt installera FreeCAD på en grupp av maskiner. För att göra det, utför följande steg:

  1. Logga in på domän controllern
  2. Kopiera MSI filen till en delad mapp som alla målmaskiner har åtkomst till.
  3. Öppna MMC snapin "Active Directory users and computers"
  4. Navigera till den datorgrupp som behöver FreeCAD
  5. Öppna egenskaper
  6. Öppna Group Policy
  7. Lägg till en ny policy, och redigera den
  8. I datorkonfiguration/Mjukvaruinstallation, välj Ny/Paket
  9. Välj MSI filen i nätverkssökvägen
  10. Välj alternativt att du vill att FreeCAD ska avinstalleras om datorn lämnar policyns område.

Grupp policy propagering brukar ta lite tid - för att distribuera paketet pålitligt, starta om samtliga maskiner.

Installation på Linux om du använder Crossover Office

Du kan installera windows versionen av FreeCAD på ett Linux system genom att använda CXOffice 5.0.1. Kör msiexec frånCXOffice's kommandolinje, det antas att installationspaketet finns i "software" katalogen som är mappad till enhetsbokstaven "Y:":

FreeCAD is running, but it has been reported that the OpenGL display does not work, like with other programs running under Wine i.e. Google SketchUp.


Installera på Unix/Linux

För tillfället, så erbjuder FreeCAD teamet endast installerare för 32bit Debian och Ubuntu system, men en del medlemmar av FreeCADs användargrupp erbjuder även anpassade installerare för andra Linuxvarianter. Ta en titt på Nedladdningssidan sidan för att se vad som för tillfället finns tillgängligt.

Once you've got FreeCAD installed, it's time to get started!

Installation på Debian/Ubuntu system

När du har laddat ned den .deb som motsvarar din systemversion, och om du har Gdebi paketet installerat (det är det vanligtvis), så behöver du bara navigera till där du laddade ned filen, och dubbelklicka på den. Nödvändiga beroenden kommer att tas hand om automatiskt av din pakethanterare. Alternativt, så kan du även installera den från terminalen, genom att navigera till där du laddade ned filen, och skriva:

sudo dpkg -i Name_of_your_FreeCAD_package.deb

byt Name_of_your_FreeCAD_package.deb till namnet på den fil som du laddade ned.

Efter att du har installerat FreeCAD, så kommer en startikon läggas till i "Grafik" sektionen i din startmeny.

Many Linux distributions are based on Ubuntu and share its repositories. Besides official variants (Kubuntu, Lubuntu and Xubuntu), there are non official distros such as Linux Mint, Voyager and others. The installation options below should be compatible to these systems.

Official Ubuntu repository

FreeCAD is available from Ubuntu repositories and can be installed via the Software Center or with this command in a terminal:

sudo apt-get install freecad

Important Note: Chances are this stable version will be outdated, and not have the latest features. To get the last release version, please use the Personal Package Archive (PPA) options below.

Stable PPA with GUI

To install FreeCAD using the PPA, from the graphical interface, please follow those instructions. The FreeCAD community provides a PPA repository on Launchpad with the latest stable FreeCAD version.

You need to add to your system's Software Sources the following PPA. To do that navigate to Ubuntu Software Centre → Edit → Software Sources → Other Software. Click on add and copy and past the code below:

ppa:freecad-maintainers/freecad-stable

Refresh your software sources, if asked. Now, you can find and install the last stable FreeCAD version on the Ubuntu Software Center.

Stable PPA with console

Type, or copy-paste, these commands in a console to add the PPA:

For the "stable" PPA

sudo add-apt-repository ppa:freecad-maintainers/freecad-stable

Don't forget to retrieve the updated the package lists:

sudo apt-get update

Update synchronizes your list of available packages with the servers.

Then, install FreeCAD along with the documentation:

sudo apt-get install freecad freecad-doc && sudo apt-get upgrade

Upgrade downloads and installs the newest packages version of the installed programs. It will be applied to all the softwares installed on your computer.

Execute this command to open the stable version of FreeCAD:

freecad

Daily PPA with console

To install the last unstable version of FreeCAD, use the "freecad-daily" PPA repository on Launchpad. This way you can access the bleeding edge of FreeCAD development. This PPA is automatically compiled daily from the official FreeCAD's master branch repository. It will usually contain numerous bug fixes and feature updates.

To install the daily PPA:

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

You can then update to the latest daily at any time with:

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

Run this command to open the daily build of FreeCAD:

freecad-daily

Debian and other debian-based systems

Since Debian Lenny, FreeCAD is available directly from the Debian software repositories and can be installed via synaptic or simply with:

sudo apt-get install freecad

OpenSUSE

FreeCAD is typically installed with:

zypper install FreeCAD

Gentoo

FreeCAD can be built/installed simply by issuing:

emerge freecad

Fedora

FreeCAD has been included in the official Fedora packages since Fedora 20. It can be installed from the command line with:

sudo dnf install freecad

On older Fedora releases, that was:

sudo yum install freecad

The gui packages managers can also be used. Search for "freecad". The official release package version tends to be well behind the FreeCAD releases. Package: freecad shows the versions included in the Fedora repositories over time and versions.

More current versions can be obtained by downloading one of the .AppImage releases from the github repository. These work fine on Fedora.

If you want to keep up with the absolute latest daily builds, FreeCAD is also available on copr. To install the build from there, in a terminal session, enter:

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

That leaves the copr repository active, so

sudo dnf upgrade

or equivalent, will update to the latest FreeCAD build, along with updates from any of the other active repos. If you want something a bit more stable, you can disable @freecad/nightly again after the initial install. The copr repository only keeps builds from the past 2 weeks. This is not a solution if you want to pick a specific older version.

Instructions are also available on compile FreeCAD yourself, including a script specifically for Fedora. With a minor change, to checkout the specific commit from git, any version since about FreeCAD 0.15 can be built on any distribution since Fedora 21.

Arch

Installing FreeCAD on Arch Linux and derivatives (ex. Manjaro):

pacman -S freecad

Other

If you find out that your system features FreeCAD but is not documented in this page, please tell us on the forum!

Many alternative, non-official FreeCAD packages are available on the net, for example for systems like slackware or fedora. A search on the net can quickly give you some results.

Manual install on .deb based systems

If for some reason you cannot use one of the above methods, you can always download one of the .deb packages available on the Download page.
Linux.png Ubuntu 32/64bit AppImage-logo.png AppImage 64bit


Once you downloaded the .deb corresponding to your system version, if you have the Gdebi package installed (usually it is), you just need to navigate to where you downloaded the file, and double-click on it. The necessary dependencies will be taken care of automatically by your system package manager. Alternatively you can also install it from the terminal, navigating to where you downloaded the file, and type:

sudo dpkg -i Name_of_your_FreeCAD_package.deb

changing Name_of_your_FreeCAD_package.deb by the name of the file you downloaded.

After you installed FreeCAD, a startup icon will be added in the "Graphic" section of your Start Menu.

Installera på andra Linux/Unix system

Olyckligtvis finns det för tillfället inga förkompilerade paket för andra Linux/Unix system, så du får kompilera FreeCAD själv.

Many common Linux distros now include a precompiled FreeCAD as part of the standard packages. This is often out of date, but is a place to start. Check the standard package managers for your system. One of the following (partial) list of commands could install the official version of FreeCAD for your distro from the terminal. These probably need administrator privileges.

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

The package name is case sensitive, so try `FreeCAD` as well as `freecad`. If that does not work for you, either because your package manager does not have a precompiled FreeCAD version available, or because the available version is too old for your needs, you can try downloading one of the .AppImage releases from the github repository. These tend to work on most 64 bit Linux distributions, without any special installation. Just make sure the downloaded file is marked as executable, then run it.

If that still is not good enough, and you can not locate another source of a precompiled package for your situation, you will need to compile FreeCAD yourself.

Installing Windows Version on Linux

See the Install on Windows page.


Installera på Mac

FreeCAD kan installeras på Mac OS X i ett steg genom att använda Installeraren. Denna sida beskriver användandet och funktionerna i FreeCAD installeraren. Den inkluderar också avinstallations instruktioner.

Mac.png MacOS 10.11 El Capitan 64-bit (sha256)


This page describes the usage and features of the FreeCAD installer. It also includes uninstallation instructions. Once installed, you can get started!

Enkel Installation

FreeCAD installeraren erbjuds som ett Installationspaket(.mpkg) bifogad i en diskavbildningsfil.

Du kan ladda ned den senaste installeraren från Nedladdningssidan. Efter att du laddat ned filen, montera diskavbildningen, kör sedan Install FreeCAD paketet.

Mac installer 1.png

Installeraren kommer att presentera en Customize Installation skärm som listar de paket som kommer att installeras. Om du vet att du redan har något av dessa paket, så kan du välja bort dem genom att använda kryssrutorna. Om du inte är säker, lämna alla rutor markerade.


Avinstallation

Det finns för närvarande ingen avinstallerare för FreeCAD. För att helt ta bort FreeCAD och alla installerade komponenter, dra följande filer och mappar till papperskorgen:

  • I /Applications:
    • FreeCAD

Det är allt. Eventuellt så kommer FreeCAD att finnas tillgängligt som ett applikationspaket så att allt detta trubbel kommer att försvinna.


Upptäcka FreeCAD

Förord

FreeCAD är en CAD/CAE parametrisk modelleringsapplikation. Den är fortfarande i ett tidigt utvecklingsstadium, så förvänta dig inte att du ska kunna använda den till professionellt arbete än.

Men, om du är nyfiken på hur FreeCAD ser ut och vilka funktioner som håller på att utvecklas, så är du välkommen att ladda ned den och testa den. För tillfället finns det redan många funktioner, men gränssnittet för många av dem har ännu inte skapats. detta innebär att om du kan lite om python, så kommer du redan att kunna producera och förändra komplex geometri relativt enkelt. Om inte, så kommer du förmodligen att upptäcka att FreeCAD fortfarande har en del att erbjuda dig. Men, ha tålamod, detta kommer att förändras snart.

Och om du efter att ha testat den har kommentarer, ideer eller åsikter, var vänlig att dela dem med oss på FreeCAD diskussionsforum!

Installation

Först av allt (om det inte redan är gjort), ladda ned och installera FreeCAD. Se Nedladdningssidan för information om nuvarande versioner och updateringar. Det finns färdiga installationspaket för Windows (.msi), Ubuntu & Debian (.deb) openSUSE (.rpm) och Mac OSX.

Utforska FreeCAD

FreeCAD gränssnittet när du startar den första gången. Se fler skärmdumpar här.

FreeCAD är en allmän, allt-i-allo 3D modelleringsapplikation, fokuserad på mekanisk konstruktion och relaterade områden, som andra konstruktionsspecialiteter eller arkitektur. Den är utformad som en plattform för utveckling av vilken 3D applikation som helst, men även för att göra väldigt specifika uppgifter. För det ändamålet så är dess gränssnitt uppdelat i en serie med Arbetsbänkar. Arbetsbänkar gör att du ändrar gränssnittsinnehållet till att endast visa de verktyg som är nödvändiga för en specifik uppgift, uppgiftsgrupper.

FreeCAD gränssnittet kan därför beskrivas som en mycket enkel behållare, med en menyrad, en 3D visningsområde, och några sidopaneler för att visa sceninnehållet eller objektegenskaper. Allt innehåll i dessa paneler kan förändras beroende på arbetsbänken.

När du startar FreeCAD för den första gången, så kommer en "generell" arbetsbänk att presenteras för dig, som vi kallar "komplett arbetsbänk". Denna arbetsbänk samlar de mognaste verktygen från andra arbetsbänkar. Eftersom FreeCAD är ganska ungt och inte har använts för något specialiserat arbete ännu, så är denna arbetsbänk väldigt smidig för att utforska FreeCAD lättare. Alla verktyg som är tillräckligt bra för att producera geometri finns här.

  1. The 3D view, showing the contents of your document
  2. The tree view showing the hierarchy and construction history of all the objects in your document
  3. The property editor, which allows you to view and modify properties of the selected objects
  4. The report view (or output window), where FreeCAD prints messages, warnings and errors
  5. The Python console, where all the commands executed by FreeCAD are printed, and where you can enter python code
  6. The workbench selector, where you select the active workbench

The main concept behind the FreeCAD interface is that it is separated into workbenches. A workbench is a collection of tools suited for a specific task, such as working with meshes, or drawing 2D objects, or constrained sketches. You can switch the current workbench with the workbench selector (6). You can customize the tools included in each workbench, add tools from other workbenches or even self-created tools, that we call macros. Widely used starting points are the PartDesign Workbench and Part Workbench.

When you start FreeCAD for the first time, you are presented with the start center. Here is what it looks like for version 0.16:

Startcenter.jpg

For FreeCAD 0.17 see this start center screenshot.


The Start Center allows you to quickly jump to one of the most common workbenches, open one of the recent files, or see the latest news from the FreeCAD world. You can change the default workbench in the preferences.

Navigera i 3D rymden

FreeCAD har två olika navigationslägen tillgängliga, som kan ställas in i inställningsdialogen. I standardläget, så utförs zoomning med Mushjulet, panorering med Mittre musknappen, och rotation med vänster musknapp och Mittre musknappen samtidigt. Val av ett objekt görs genom att klicka på det med vänster musknapp, med CTRL nedtryckt om du vill välja flera objekt.

Du har också flera förinställda vyer (Toppvy, Frontvy, etc) tillgängliga i Visa menyn och på verktygslådan Visa, och via numeriska genvägar (1, 2, etc...)

Skript

Och slutligen, en av de kraftfullaste funktionerna i FreeCAD är skript miljön. Från den integrerade pythonkonsolen (eller från något externt pythonskript), så får du åtkomst till nästan vilken del som helst av FreeCAD, skapa eller ändra geometri, ändra representationen av dessa objekt i 3D scenen eller förändra FreeCAD's gränssnitt. Python skript kan även användas i makron, vilket erbjuder en lätt metod att skapa anpassade kommandon.

FreeCAD has several different navigation modes available, that change the way you use your mouse to interact with the objects in the 3D view and the view itself. One of them is specifically made for touchpads, where the middle mouse button is not used. The following table describes the default mode, called CAD Navigation (You can quickly change the current navigation mode by right-clicking on an empty area of the 3D view):

Select Pan Zoom Rotate view
First method
Rotate view
Alternate method
Hand cursor.png Pan cursor.png Zoom cursor.png Rotate cursor.png Rotate cursor.png
Mouse LMB.svg Mouse MMB hold.svg Mouse MMB rotate.svg Mouse MMB+LMB hold.svg Mouse MMB+RMB hold.svg
Press the left mouse button over an object you want to select.

Holding down Ctrl allows the selection of multiple objects.

Hold the middle mouse button, then move the pointer. Use the mouse wheel to zoom in and out.

Clicking the middle mouse button re-centers the view on the location of the cursor.

Hold the middle mouse button, then press and hold the left mouse button, then move the pointer.

The cursor location when the middle mouse button is pressed determines the center of rotation. Rotation works like spinning a ball which rotates around its center. If the buttons are released before you stop the mouse motion, the view continues spinning, if this is enabled.

A double click with the middle mouse button sets a new center of rotation.

Hold the middle mouse button, then press and hold the right mouse button, then move the pointer.

With this method the middle mouse button may be released after the right mouse button is held pressed.

Users who use the mouse with their right hand may find this method easier than the first method.

Ctrl+Mouse RMB.svg Ctrl+Shift+Mouse RMB.svg Shift+Mouse RMB.svg
Pan mode: hold the Ctrl key, press the right mouse button once, then move the pointer. introduced in version 0.17 Zoom mode: hold the Ctrl and Shift keys, press the right mouse button once, then move the pointer. introduced in version 0.17 Rotate mode: hold the Shift key, press the right mouse button once, then move the pointer. introduced in version 0.17

Holding down Ctrl allows the selection of multiple objects. |Pan_text=Hold the middle mouse button, then move the pointer. |Pan_mode_text=Pan mode: hold the Ctrl key, press the right mouse button once, then move the pointer. introduced in version 0.17 |Zoom_text=Use the mouse wheel to zoom in and out.

Clicking the middle mouse button re-centers the view on the location of the cursor. |Zoom_mode_text=Zoom mode: hold the Ctrl and Shift keys, press the right mouse button once, then move the pointer. introduced in version 0.17 |Rotate_view_text=Hold the middle mouse button, then press and hold the left mouse button, then move the pointer.

The cursor location when the middle mouse button is pressed determines the center of rotation. Rotation works like spinning a ball which rotates around its center. If the buttons are released before you stop the mouse motion, the view continues spinning, if this is enabled.

A double click with the middle mouse button sets a new center of rotation. |Rotate_view_mode_text=Rotate mode: hold the Shift key, press the right mouse button once, then move the pointer. introduced in version 0.17 |Rotate_view_alt_text=Hold the middle mouse button, then press and hold the right mouse button, then move the pointer.

With this method the middle mouse button may be released after the right mouse button is held pressed.

Users who use the mouse with their right hand may find this method easier than the first method. }}

You also have several view presets (top view, front view, etc) available in the View menu, on the View toolbar, and by numeric shortcuts (1, 2, etc...). By right-clicking on an object or on an empty area of the 3D view, you have quick access to some common operations, such as setting a particular view, or locating an object in the Tree view.

First steps with FreeCAD

FreeCAD's focus is to allow you to make high-precision 3D models, to keep tight control over those models (being able to go back into modelling history and change parameters), and eventually to build those models (via 3D printing, CNC machining or even construction worksite). It is therefore very different from some other 3D applications made for other purposes, such as animation film or gaming. Its learning curve can be steep, especially if this is your first contact with 3D modeling. If you are struck at some point, don't forget that the friendly community of users on the FreeCAD forum might be able to get you out in no time.

The workbench you will start using in FreeCAD depends on the type of job you need to do: If you are going to work on mechanical models, or more generally any small-scale objects, you'll probably want to try the PartDesign Workbench. If you will work in 2D, then switch to the Draft Workbench, or the Sketcher Workbench if you need constraints. If you want to do BIM, launch the Arch Workbench. If you are working with ship design, there is a special Ship Workbench for you. And if you come from the OpenSCAD world, try the OpenSCAD Workbench.

You can switch workbenches at any time, and also customize your favorite workbench to add tools from other workbenches.

Working with the PartDesign and Sketcher workbenches

The PartDesign Workbench is made to build complex objects, starting from simple shapes, and adding or removing pieces (called "features"), until you get to your final object. All the features you applied during the modelling process are stored in a separate view called the tree view, which also contains the other objects in your document. You can think of a PartDesign object as a succession of operations, each one applied to the result of the preceding one, forming one big chain. In the tree view, you see your final object, but you can expand it and retrieve all preceding states, and change any of their parameter, which automatically updates the final object.

The PartDesign workbench makes heavy use of another workbench, the Sketcher Workbench. The sketcher allows you to draw 2D shapes, which are defined by applying Constraints to the 2D shape. For example, you might draw a rectangle and set the size of a side by applying a length constraint to one of the sides. That side then cannot be resized anymore (unless the constraint is changed).

Those 2D shapes made with the sketcher are used a lot in the PartDesign workbench, for example to create 3D volumes, or to draw areas on the faces of your object that will then be hollowed from its main volume. This is a typical PartDesign workflow:

  1. Create a new sketch
  2. Draw a closed shape (make sure all points are joined)
  3. Close the sketch
  4. Expand the sketch into a 3D solid by using the pad tool
  5. Select one face of the solid
  6. Create a second sketch (this time it will be drawn on the selected face)
  7. Draw a closed shape
  8. Close the sketch
  9. Create a pocket from the second sketch, on the first object

Which gives you an object like this:

Partdesign example.jpg

At any moment, you can select the original sketches and modify them, or change the extrusion parameters of the pad or pocket operations, which will update the final object.

Working with the Draft and Arch workbenches

The Draft Workbench and Arch Workbench behave a bit differently than the other workbenches above, although they follow the same rules, which are common to all of FreeCAD. In short, while the Sketcher and PartDesign are made primarily to design single pieces, Draft and Arch are made to ease your work when working with several, simpler objects.

The Draft Workbench offers you 2D tools somewhat similar to what you can find in traditional 2D CAD applications such as AutoCAD. However, 2D drafting being far away from the scope of FreeCAD, don't expect to find there the full array of tools that these dedicated applications offer. Most of the Draft tools work not only in a 2D plane but also in the full 3D space, and benefit from special helper systems such as Work planes and object snapping.

The Arch Workbench adds BIM tools to FreeCAD, allowing you to build architectural models with parametric objects. The Arch workbench relies extensively on other modules such as Draft and Sketcher. All the Draft tools are also present in the Arch workbench, and most Arch tools make use of the Draft helper systems.

A typical workflow with Arch and Draft workbenches might be:

  1. Draw a couple of lines with the Draft Line tool
  2. Select each line and press the Wall tool to build a wall on each of them
  3. Join the walls by selecting them and pressing the Arch Add tool
  4. Create a floor object, and move your walls in it from the Tree view
  5. Create a building object, and move your floor in it from the Tree view
  6. Create a window by clicking the Window tool, select a preset in its panel, then click on a face of a wall
  7. Add dimensions by first setting the working plane if necessary, then using the Draft Dimension tool

Which will give you this:

Arch workflow example.jpg

More on the Tutorials page.

Scripting

And finally, one of the most powerful features of FreeCAD is the scripting environment. From the integrated python console (or from any other external Python script), you can gain access to almost any part of FreeCAD, create or modify geometry, modify the representation of those objects in the 3D scene or access and modify the FreeCAD interface. Python scripting can also be used in macros, which provide an easy method to create custom commands.

What's new


Arbeta med FreeCAD

3D navigering

FreeCAD's musmodell är mycket flexibel och intuitiv och med några tips så kan du använda den redan efter någon minuts träning.

Mouse-model.png

FreeCAD's musmodell är mycket flexibel och intuitiv och med några tips så kan du använda den redan efter någon minuts träning.

Mouse-model.png

Välja objekt

Objekt kan väljas med ett klick med den vänstra musknappen antingen genom att klicka på objektet i 3D-vyn eller genom att välja den i trädvyn. Det finns även en Förvals mekanism som markerar objekt och visar information om dem bara genom att hålla markören över den. Om du inte gillar det beteendet eller om du har en långsam maskin, så kan du stänga av förval i inställningarna.

Hantera Objekt

Objekthanteringen är gemensam för alla arbetsbänkar. Följande musgester kan användas till att kontrollera objektposition och vy.

Välj
Klicka med den vänstra musknappen över det objekt som du vill välja.
Zoom
Använd + eller - tangenterna eller mushjulet för att zooma in och ut.
Panorera
Klicka med den mittre musknappen och flytta runt objektet .
Rotera
Klicka först med den mittre musknappen, håll den nedtryckt och klicka sedan med den vänstra musknappen på en synlig del av ett objekt och dra den i den önskade riktningen. Detta fungerar som en boll som snurrar runt dess centrum. Om du släpper knapparna innan du stoppar rörelsen, så kommer objektet fortsätta att rotera, om detta är aktiverat.
Ställa in rotationscentrum
Ett dubbelklick med den mittre musknappen på valfri del av objektet ställer in ett nytt roationscentrum och zoomar in på denna punkt.

Manipulera Objekt

FreeCAD har manipulatorer som kan användas till att ändra ett objekt eller dess visuella utseende. Ett enkelt exempel är klippningsplan som kan aktiveras med Visa?Klippningsplan menyn. Efter aktivering så kommer klippningsplan objektet fram och visar sju självklara manipulatorer som små lådor: En på varje ände på dess tre koordinataxlar och en på dentrum på den axel som är normal till planet. Det finns fyra till som inte är så självklara: Själva planet och den tunna delen på de tre axelobjekten.

Skalning
För att skala objektet klicka med den vänstra musknappen på lådmanipulatorerna vid slutet på axlarna och dra dem bakåt och framåt. Beroende på objektet så arbetar manipulatorerna oberoende eller synkront.
Flytta ut ur planet
För att flytta objektet längs dess normalvektor, dra i den långa lådan vid axelns centrum med den vänstra musknappen. För klippningsplanet finns det endast en manipulator längs normalvektorn.
Flytta i planet
För att flytta klippningsplanets centrum, klicka på planobjektet och dra den till den önskade positionen.
Rotation
Klicka på den tunna delen av axlarna sätter manipulatorn i rotationsläge.

The FreeCAD mouse model consists of the commands used to visually navigate the 3D space and interact with the objects displayed. FreeCAD supports multiple mouse model navigation styles. The default navigation style is referred to as "CAD Navigation," and is very simple and practical, but FreeCAD also provides alternative navigation styles, that you can choose according to your preferences.

Hantera Objekt

Objekthanteringen är gemensam för alla arbetsbänkar. Följande musgester kan användas till att kontrollera objektposition och vy.

Välj
Klicka med den vänstra musknappen över det objekt som du vill välja.
Zoom
Använd + eller - tangenterna eller mushjulet för att zooma in och ut.
Panorera
Klicka med den mittre musknappen och flytta runt objektet .
Rotera
Klicka först med den mittre musknappen, håll den nedtryckt och klicka sedan med den vänstra musknappen på en synlig del av ett objekt och dra den i den önskade riktningen. Detta fungerar som en boll som snurrar runt dess centrum. Om du släpper knapparna innan du stoppar rörelsen, så kommer objektet fortsätta att rotera, om detta är aktiverat.
Ställa in rotationscentrum
Ett dubbelklick med den mittre musknappen på valfri del av objektet ställer in ett nytt roationscentrum och zoomar in på denna punkt.

Manipulera Objekt

FreeCAD har manipulatorer som kan användas till att ändra ett objekt eller dess visuella utseende. Ett enkelt exempel är klippningsplan som kan aktiveras med Visa?Klippningsplan menyn. Efter aktivering så kommer klippningsplan objektet fram och visar sju självklara manipulatorer som små lådor: En på varje ände på dess tre koordinataxlar och en på dentrum på den axel som är normal till planet. Det finns fyra till som inte är så självklara: Själva planet och den tunna delen på de tre axelobjekten.

Skalning
För att skala objektet klicka med den vänstra musknappen på lådmanipulatorerna vid slutet på axlarna och dra dem bakåt och framåt. Beroende på objektet så arbetar manipulatorerna oberoende eller synkront.
Flytta ut ur planet
För att flytta objektet längs dess normalvektor, dra i den långa lådan vid axelns centrum med den vänstra musknappen. För klippningsplanet finns det endast en manipulator längs normalvektorn.
Flytta i planet
För att flytta klippningsplanets centrum, klicka på planobjektet och dra den till den önskade positionen.
Rotation
Klicka på den tunna delen av axlarna sätter manipulatorn i rotationsläge.

The FreeCAD mouse model consists of the commands used to visually navigate the 3D space and interact with the objects displayed. FreeCAD supports multiple mouse model navigation styles. The default navigation style is referred to as "CAD Navigation," and is very simple and practical, but FreeCAD also provides alternative navigation styles, that you can choose according to your preferences.

Navigation

The mouse gestures used for object manipulation vary depending on the Navigation style selected; the currently selected style is used for all workbenches.

There are two ways to change the navigation style:

  • In the Preferences Editor, Edit → Preferences → Display → 3D View → 3D Navigation.
  • By right-clicking in empty space in the 3D view, then selecting Navigation style →... in the contextual menu.

CAD Navigation (default)

This is the default navigation style and allows the user a simple control of the view, and does not require the use of keyboard keys except to make multi-selections.

Select Pan Zoom Rotate view
First method
Rotate view
Alternate method
Hand cursor.png Pan cursor.png Zoom cursor.png Rotate cursor.png Rotate cursor.png
Mouse LMB.svg Mouse MMB hold.svg Mouse MMB rotate.svg Mouse MMB+LMB hold.svg Mouse MMB+RMB hold.svg
Press the left mouse button over an object you want to select.

Holding down Ctrl allows the selection of multiple objects.

Hold the middle mouse button, then move the pointer. Use the mouse wheel to zoom in and out.

Clicking the middle mouse button re-centers the view on the location of the cursor.

Hold the middle mouse button, then press and hold the left mouse button, then move the pointer.

The cursor location when the middle mouse button is pressed determines the center of rotation. Rotation works like spinning a ball which rotates around its center. If the buttons are released before you stop the mouse motion, the view continues spinning, if this is enabled.

A double click with the middle mouse button sets a new center of rotation.

Hold the middle mouse button, then press and hold the right mouse button, then move the pointer.

With this method the middle mouse button may be released after the right mouse button is held pressed.

Users who use the mouse with their right hand may find this method easier than the first method.

Ctrl+Mouse RMB.svg Ctrl+Shift+Mouse RMB.svg Shift+Mouse RMB.svg
Pan mode: hold the Ctrl key, press the right mouse button once, then move the pointer. introduced in version 0.17 Zoom mode: hold the Ctrl and Shift keys, press the right mouse button once, then move the pointer. introduced in version 0.17 Rotate mode: hold the Shift key, press the right mouse button once, then move the pointer. introduced in version 0.17
Select Pan Zoom Rotate view
First method
Rotate view
Alternate method
Hand cursor.png Pan cursor.png Zoom cursor.png Rotate cursor.png Rotate cursor.png
Mouse LMB.svg Mouse MMB hold.svg Mouse MMB rotate.svg Mouse MMB+LMB hold.svg Mouse MMB+RMB hold.svg
Press the left mouse button over an object you want to select.

Holding down Ctrl allows the selection of multiple objects.

Hold the middle mouse button, then move the pointer. Use the mouse wheel to zoom in and out.

Clicking the middle mouse button re-centers the view on the location of the cursor.

Hold the middle mouse button, then press and hold the left mouse button, then move the pointer.

The cursor location when the middle mouse button is pressed determines the center of rotation. Rotation works like spinning a ball which rotates around its center. If the buttons are released before you stop the mouse motion, the view continues spinning, if this is enabled.

A double click with the middle mouse button sets a new center of rotation.

Hold the middle mouse button, then press and hold the right mouse button, then move the pointer.

With this method the middle mouse button may be released after the right mouse button is held pressed.

Users who use the mouse with their right hand may find this method easier than the first method.

Ctrl+Mouse RMB.svg Ctrl+Shift+Mouse RMB.svg Shift+Mouse RMB.svg
Pan mode: hold the Ctrl key, press the right mouse button once, then move the pointer. introduced in version 0.17 Zoom mode: hold the Ctrl and Shift keys, press the right mouse button once, then move the pointer. introduced in version 0.17 Rotate mode: hold the Shift key, press the right mouse button once, then move the pointer. introduced in version 0.17


OpenInventor Navigation

In OpenInventor (formerly Inventor) Navigation, modeled after Open Inventor (not to be confused with Autodesk Inventor), there is no mouse-only selection. In order to select objects, you must hold down the CTRL key.

Select Pan Zoom Rotate view
Hand cursor.png Pan cursor.png Zoom cursor.png Rotate cursor.png
Ctrl+Mouse LMB.svg Mouse MMB hold.svg Mouse MMB rotate.svg Mouse MMB+LMB hold.svg Mouse LMB hold.svg
Hold Ctrl, then press the left mouse button over an object you want to select. Hold the middle mouse button, then move the pointer. Use the mouse wheel to zoom in and out.

Alternatively, hold the middle mouse button, then press and hold the left mouse button, then move the pointer.

Hold the left mouse button, then move the pointer.

This mode is not based on Autodesk Inventor.

Select Pan Zoom Rotate view
Hand cursor.png Pan cursor.png Zoom cursor.png Rotate cursor.png
Ctrl+Mouse LMB.svg Mouse MMB hold.svg Mouse MMB rotate.svg Mouse MMB+LMB hold.svg Mouse LMB hold.svg
Hold Ctrl, then press the left mouse button over an object you want to select. Hold the middle mouse button, then move the pointer. Use the mouse wheel to zoom in and out.

Alternatively, hold the middle mouse button, then press and hold the left mouse button, then move the pointer.

Hold the left mouse button, then move the pointer.


Blender Navigation

The Blender Navigation was modeled after Blender. Previously there was no mouse-only panning, and it required use of the SHIFT key to pan the view. This changed in 2016 with a feature-addition. In order to pan the view, you can now press both left and right mouse buttons and drag in the view.

Select Pan Zoom Rotate view
Hand cursor.png Pan cursor.png Zoom cursor.png Rotate cursor.png
Mouse LMB.svg Shift+Mouse MMB hold.svg Mouse LMB+RMB hold.svg Mouse MMB rotate.svg Mouse MMB hold.svg
Press the left mouse button over an object you want to select. Hold Shift and the middle mouse button, then move the pointer.

Alternatively, hold both left and right mouse buttons, and then move the pointer.

Use the mouse wheel to zoom in and out. Hold the middle mouse button, then move the pointer.

Alternatively, hold both left and right mouse buttons, and then move the pointer. |Zoom_text=Use the mouse wheel to zoom in and out. |Rotate_view_text=Hold the middle mouse button, then move the pointer. }}

Touchpad Navigation

In Touchpad Navigation, neither panning, nor zooming, nor rotating the view, are mouse-only (or touchpad-only) operations.

Select Pan Zoom Rotate view
Hand cursor.png Pan cursor.png Zoom cursor.png Rotate cursor.png
Touchpad LB.svg Shift+Touchpad.svg PageUp, PageDown Alt+Touchpad.svg
Press the left mouse button over an object you want to select. Hold Shift, then move the pointer. Use PageUp and PageDown to zoom in and out. Hold Alt, then move the pointer.
Shift+Ctrl+Touchpad.svg Shift+Touchpad LB hold.svg
Alternatively, hold Shift and Ctrl, then move the pointer. Alternatively, hold Shift and the left button, then move the pointer.

Gesture Navigation (v0.16)

This navigation style was tailored for usability with touchscreen and pen, but is very usable with mouse too.

Select Pan Zoom Rotate view Tilt view
Hand cursor.png Pan cursor.png Zoom cursor.png Rotate cursor.png Rotate cursor.png
Mouse LMB.svg Mouse RMB hold.svg Mouse MMB rotate.svg Mouse LMB hold.svg Mouse LMB+RMB hold.svg
Press the left mouse button over an object you want to select. Hold the right mouse button, then move the pointer. Use the mouse wheel to zoom in and out. Hold the left mouse button, then move the pointer.

In Sketcher and other edit modes, this behavior is disabled. Hold Alt when pressing the mouse button to enter rotation mode.

To set the camera's focus point for rotation, click a point with the middle mouse button. Alternatively, aim the cursor at a point and press H on the keyboard.

Hold both left and right mouse buttons, and then move the pointer sideways.
Touch Tap.svg Touch Two-Finger-Drag.svg Touch Tap-Hold-Drag.svg Touch Pinch.svg Touch One-Finger-Drag.svg Touch Rotate.svg
Tap to select. Drag with two fingers.

Alternatively, tap and hold, then drag. This simulates the pan with the right mouse button.

Drag two fingers (pinch) closer or farther apart. Drag with one finger to rotate.

Hold Alt when in the Sketcher.

Rotate the imaginary line formed by two touch points.

On v0.18 this method is disabled by default. To enable, go to Edit → Preferences → Display, and untick "Disable touchscreen tilt gesture" checkbox.

Alternatively, tap and hold, then drag. This simulates the pan with the right mouse button. |Zoom_text=Use the mouse wheel to zoom in and out. |Zoom_gesture_text=Drag two fingers (pinch) closer or farther apart. |Rotate_view_text=Hold the left mouse button, then move the pointer. In Sketcher and other edit modes, this behavior is disabled. Hold Alt when pressing the mouse button to enter rotation mode.

To set the camera's focus point for rotation, click a point with the middle mouse button. Alternatively, aim the cursor at a point and press H on the keyboard. |Rotate_view_gesture_text=Drag with one finger to rotate.

Hold Alt when in the Sketcher. |Tilt_view_text=Hold both left and right mouse buttons, then move the pointer sideways. |Tilt_view_gesture_text=Rotate the imaginary line formed by two touch points.

On v0.18 this method is disabled by default. To enable, go to Edit → Preferences → Display, and untick "Disable touchscreen tilt gesture" checkbox. }}

Maya-Gesture Navigation

In Maya-Gesture Navigation, all view movements are activated pressing ALT and a mouse button, so that it will be needed to have a 3 button mouse in order to correctly use this navigation mode. Alternately it's possible to use gestures as this mode was been developed over the normal Gesture Navigation mode.

Select Pan Zoom Rotate view
Hand cursor.png Pan cursor.png Zoom cursor.png Rotate cursor.png
Mouse LMB.svg Alt+Mouse MMB hold.svg Alt+Mouse RMB hold.svg Mouse MMB rotate.svg Alt+Mouse LMB hold.svg
Press the left mouse button over an object you want to select. Hold Alt and the middle mouse button, then move the pointer. Hold Alt and the right mouse button, then move the pointer.

Alternatively, use the mouse wheel to zoom in and out.

Hold Alt and the left mouse button, then move the pointer.

Alternatively, use the mouse wheel to zoom in and out. |Rotate_view_text=Hold Alt and the left mouse button, then move the pointer. }}


Revit Navigation

This style was introduced in version 0.18.

Select Pan Zoom Rotate view
Hand cursor.png Pan cursor.png Zoom cursor.png Rotate cursor.png
Mouse LMB.svg Mouse MMB hold.svg Mouse LMB+RMB hold.svg Mouse MMB rotate.svg Shift+Mouse MMB hold.svg Mouse MMB+RMB hold.svg


Press the left mouse button over an object you want to select. Hold the middle mouse button, then move the pointer.

Alternatively, hold both left and right mouse buttons, then move the pointer.

Use the mouse wheel to zoom in and out. Hold Shift and the middle mouse button, then move the pointer.

Alternatively, hold the middle mouse button, then press and hold the right mouse button, then move the pointer.


OpenCascade

This style was introduced in version 0.18.

Select Pan Zoom Rotate view
Hand cursor.png Pan cursor.png Zoom cursor.png Rotate cursor.png
Mouse LMB.svg Ctrl+Mouse MMB hold.svg Mouse MMB hold.svg Mouse MMB rotate.svg Ctrl+Mouse LMB hold.svg Ctrl+Mouse RMB hold.svg


Press the left mouse button over an object you want to select. Hold the middle mouse button, then move the pointer. Use the mouse wheel to zoom in and out.

Alternatively, hold Ctrl and the left mouse button, then move the pointer.

Hold Ctrl and the right mouse button, then move the pointer.


Selecting objects

Simple selection

Objects can be selected by a click with the left mouse button either by clicking on the object in the 3D-view or by selecting it in the tree view.

Preselection

There is also a Preselection mechanism that highlights objects and displays information before selection by just hovering the mouse over the objects. If you don't like this behaviour or you have a slow machine, you can switch preselection off in the preferences.

Manipulating Objects

FreeCAD offers manipulators that are handles that can be used to modify an object's appearance, shape, or other parameters.

The clipping plane is an example of an object with manipulators. A clipping plane can be activated with the menu View → Clipping Plane.

Hardware support

FreeCAD also supports some 3D input devices.

Mac OS X Issues

Recently we got reports on the forum from Mac users that those mouse button and key combination do not work as expected. Unfortunately, none of the developers owns a Mac, neither do the other regular contributors. We need your help to determine which mouse buttons and key combination work so we can update this wiki.


FreeCAD Dokumentet

Screenshot treeview.jpg

Ett FreeCAD document inehåller alla objekten i din scen. Det kan innehålla grupper, och objekt gjorda med valfri arbetsbänk. Du kan därför växla mellan arbetsbänkar, och ändå arbeta med samma dokument. Dokumentet är det som sparas till disk när du sparar ditt arbete. Du kan också äppna flera dokument samtidigt i FreeCAD, och öppna flera vyer av samma dokument.

Inuti dokumentet, så kan objekten flyttas in i grupper, och ha unika namn. Hantering av grupper, objekt och objektnamn görs huvudsakligen från Trädvyn. Det kan förstås också göras, som allt annat i FreeCAD, från pythontolken. I trädvyn, så kan du skapa grupper, flytta objekt till grupper, radera objekt eller grupper, genom att högerklicka i trädvyn eller på ett objekt, döpa om objekt genom att dubbelklicka på dess namn, eller möjligtvis andra operationer, beroende på vilken arbetsbänk som används.

Objekten inuti ett FreeCAD dokument kan vara av olika typer. Varje arbetsbänk kan skapa sina egna objekttyper, till exempel Nät arbetsbänken skapar nätobjekt, Del arbetsbänken skapar Del objekt, Rit arbetsbänken skapar också Del objekt, etc.

Om det finns åtminstone ett dokument öppet i FreeCAD, så finns det alltid ett och endast ett aktivt dokument. Det är det dokument som syns i den nuvarande 3D vyn, dokumentet som du för närvarande jobbar med.

Applikations och Användargränssnitt

Liksom nästan allt annat i FreeCAD, så är användargränssnittsdelen separerad från basapplikationsdelen. Detta gäller även för dokument. Dokumenten utgörs också av två delar: Applikationsdokumentet, vilket innehåller våra objekt, och Vydokumentet, vilket innehåller skärmrepresentationen av våra objekt.

Tänk på det som två rymder, där objekten är definierade. Dess konstruktiva parametrar (är det en kub? en kon? vilken storlek?) lagras i Applikationsdokumentet, emedan dess grafiska representation (Är den ritad med svarta linjer? med blå ytor?) lagras i Vydokumentet. Varför är det så? därför att FreeCAD kan även användas UTAN grafiskt gränssnitt, till exempel inuti andra program, och vi måste fortfarande kunna manipulera våra objekt, även om inget ritas på skärmen.

En annan sak som lagras i Vydokumentet är 3D vyer. Ett dokument kan ha flera vyer öppnade, så du kan inspektera ditt dokument från flera håll samtidigt. Du kanske vill se en toppvy och en frontvy av ditt arbete samtidigt? Då kommer du att ha två vyer av samma dokument, båda lagrade i Vydokumentet. Skapande av nya vyer eller stänga vyer kan göras från Visa menyn eller genom att högerklicka på en vytabb.

Skript

Dokument kan lätt skapas, kommas åt och ändras från tolken. Till exempel:

FreeCAD.ActiveDocument

Kommer att returnera det nuvarande (aktiva) dokumentet

FreeCAD.ActiveDocument.Blob

Kommer åt ett objekt kallat "Blob" inuti ditt dokument

FreeCADGui.ActiveDocument

Kommer att returnera det vydokument som är associerat med det nuvarande dokumentet

FreeCADGui.ActiveDocument.Blob

Kommer åt den grafiska representationen (vy) delen av vårt Blob objekt

FreeCADGui.ActiveDocument.ActiveView

Kommer att returnera nuvarande vy


Ställa in användarpreferenser

FreeCAD inställningssystem finns i Redigera menyn → Alternativ.

FreeCAD's funktionalitet är uppdelat i olika moduler, där varje modul är ansvarig för att en specifik arbetsbänk ska fungera. FreeCAD använder sig också av ett koncept kallat sen laddning, vilket innebär att komponenter endast laddas när de behövs. du kanske har märkt att när du väljer en arbetsbänk i FreeCAD's verktygslåda, så laddas den arbetsbänken och alla dess komponenter just då. Detta inkluderar dess inställningar.

Om inga moduler är laddade, så kommer du att ha två konfigurationssektioner, ansvariga för de allmäna applikationsinställningarna och för visningsinställningar.

Clicking the Reset button in the lower left corner of any preferences display will set all of the FreeCAD preferences to their default values.

De allmäna inställningarna

När du startar FreeCAD utan någon arbetsbänk laddad, så kommer du ha ett minimalt inställningsfönster. Alltefter som du laddar fler moduler, så kommer nya avsnitt fram i inställningsfönstret, vilket tillåter dig att konfigurera detaljer för varje arbetsbänk.

Allmän

Preference General Tab 01.png

In the General tab you can specify the following:

Name Description
Change language Select the language of FreeCAD's user interface
Size of recent file list Specification how many files should be listed in the recent files list
Enable tiled background If checked, the background of FreeCAD's main window will by default consist of tiles of this image: Background.png
This option only has an effect if in Style sheet/No style sheet is selected.
The image can be changed by adding the folders Gui/Images in the folder
%APPDATA%/FreeCAD (on Windows),
$HOME/.FreeCAD (on Linux) or
$HOME/Library/Preferences/FreeCAD (on MacOS).
Put there a file named background.png and uncheck/check this option to see the changed file.
Style sheet Selection of a style sheet. The style sheets define how the user interface of FreeCAD looks.
Size of toolbar icons Selection of the size for the toolbar icons
Auto load module after start up Selection what workbench will be used directly after starting FreeCAD
Enable splash screen at start up If checked, the splash screen of FreeCAD is shown when starting.
The splash screen image can be changed by adding the folders Gui/Images in the folder %APPDATA%/FreeCAD (where %APPDATA% is the the user-specific application folder of FreeCAD of your operating system). Put there a file named splash_image.png and restart FreeCAD to see the changed splash screen.
Enable word wrap Words will be wrapped when the exceed the available horizontal space in the Python console. This console is shown using the menu View → Panels → Python console.

Dokument

Preference General Tab 02.png

In the Document tab you can specify the following:

Name Description
Create new document at start up If checked, FreeCAD will create a new document when started
Document save compression level Specification of the compression level for FCStd files. FCStd files are ZIP-compressed files. Therefore you can rename their suffix .FCStd to .zip and open them with a ZIP archive program.
Using Undo/Redo on documents If checked, all changes in documents are stored so that they can be undone/redone
Maximum Undo/Redo steps Specification how many Undo/Redo steps should be recorded
Run AutoRecovery at startup If there is a recovery file available FreeCAD will automatically run a file recovery when it is started. This way files can be restored if a crash occurred.
Save AutoRecovery information every Specification how often a recovery file is written.
Save thumbnail into project file when saving document If checked, also a thumbnail will be stored when the document is saved. The thumbnail will for example be shown in the list of recent files in the Start workbench.
Add the program logo to the generated thumbnail If checked, the FreeCAD program logo FreeCAD-logo.svg will be added to the thumbnail. This option only has an effect if Save thumbnail into project file when saving document is used.
Maximum number of backup files to keep when resaving document If checked, backup files will be kept when saving the document. You can specify how many backup files will be kept. They contain the previously saved document version. The first backup file will have the file suffix .FCStd1, the second .FCStd2 and so on.
Allow duplicate object labels in one document If checked, objects can have the same label/name. For example different parts or features can then have the same name in the same document.
Author name All documents that will be created will get the specified author name. Keep the author field blank for an anonymous author. If the option Set on save is checked, the field Last modified by will be set to the specified author when saving the file. This field can be viewed using the menu File → Project information.
Company All documents that will be created will get the specified company name
Default license Selection of a default license for new documents. For predefined license the License URL will automatically be set accordingly. Select 'Other' for an own or special license.
License URL Specification of an URL describing the license selected in Default license

Redaktör

Preference General Tab 03.png

The editor preferences settings affect the behavior of the macro editor. This editor can be opened using the menu Macro → Macros... → Edit/Create.
Note: the color and font settings also affect the Python console. This console is shown using the menu View → Panels → Python console.

In the Editor tab you can specify the following:

Name Description
Display Items Selection of the code type. The color and font settings will be applied to the selected type. The result can be seen in the Preview field.
Family Specification of the font family that should be used for the selected code type
Size Specification of the font size that should be used for the selected code type
Enable line numbers If checked, the code lines will be numbered
Tab size Specification of the tabulator raster (how many spaces). If it is for example set to '6', pressing Tab will jump to character 7 or 13 or 19 etc., depending the current cursor position. This setting is only used if Keep tabs is selected.
Indent size Specification of how many spaces will be inserted when pressing Tab. This setting is only used if Insert spaces is selected.
Keep tabs If selected, pressing Tab will insert a tabulator with the raster defined by Tab size
Insert spaces If selected, pressing Tab will insert the amount of spaces defined by Indent size

Utmatningsfönster

Preference General Tab 04.png

In the Output tab you can specify the following:

Name Description
Record log messages If checked, also log messages will be recorded. They will be output in the Report view panel with the color set in Log messages. This panel is shown using the menu View → Panels → Report view.
Record warnings If checked, warnings will be recorded. They will be output in the Report view panel with the color set in Warnings.
Record error messages If checked, error messages will be recorded. They will be output in the Report view panel with the color set in Errors
Normal messages Specification of the font color for normal messages in the Report view panel.
Log messages Specification of the font color for log messages in the Report view panel.
Warnings Specification of the font color for warning messages in the Report view panel.
Errors Specification of the font color for error messages in the Report view panel.
Redirect internal Python output to report view If checked, internal Python output will be redirected from the Python console to the Report view panel. The Python console is shown using the menu View → Panels → Python console
Redirect internal Python errors to report view If checked, Python error messages will be redirected from the Python console to the Report view panel.

Makro

Preference General Tab 05.png

In the Macro tab you can specify the following:

Name Description
Run macros in local environment If checked, variables defined by macros are created as local variables, otherwise as global Python variable
Macro path Specification of a path to macro files
Recording GUI commands If checked, recorded macros will also contain user interface commands
Record as comment If checked, recorded macros will also contain user interface commands but as comments. This is useful if you don't want to execute visible actions when running the macro but to see what could be done visibly.
Show script commands in python console If checked, the commands executed by the macro scripts are shown in the Python console. This console is shown using the menu View → Panels → Python console.

Enheter

Preference General Tab 06.png

In the Units tab you can specify the following:

Name Description
User system Selection of a unit system that should be used for all parts of FreeCAD
Number of decimals The number of decimals that should be shown for numbers and dimensions in FreeCAD
Minimum fractional inch Minimum fractional inch that should be displayed. This setting is only available if the unit system Building US (ft-in/sqft/cuft) is used.


Skärmens inställningar

This preferences section has up to 3 tabs:

3D View

Preference Display Tab 01.png

In the 3D View tab you can specify the following:

Name Description
Show coordinate system in the corner If checked, the main coordinate system will always be shown at the lower right in opened files
Show counter of frames per second If checked, the time needed for the last operation and the resulting frame rate will always be shown at the lower left in opened files
Show navigation cube If checked, the navigation cube will always be shown at the selected Corner in opened files
Use OpenGL Vertex Buffer Object If checked, Vertex Buffer Objects (VBO) will be used. A VBO is an OpenGL feature that provides methods for uploading vertex data (position, normal vector, color, etc.) to the video device. VBOs offer substantial performance gains because the data resides in the video device memory rather than the system memory and so it can be rendered directly by the video device. For more background info see this webpage.
Enable animation 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 is 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.
3D Navigation Selection of a navigation settings set. To see what each set defines, select a set and press the button Mouse....
Orbit style Selection of the rotation orbit style. When viewing a part in the x-y plane an 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.
Anti-Aliasing Selection if and what kind of Multisample anti-aliasing is used
New Document Camera Orientation Selection of the camera orientation for new documents
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, the tilting gesture will be disabled for pinch-zooming (two-finger zooming). This only affects the 3D Navigation set Gesture.
Drag at cursor If checked, rotations in 3D will use the current cursor position as center for the rotation. Otherwise always the center of the screen will be used.
Marker size Selection of the size of vertices (points) in the Sketcher workbench
Eye to eye distance for stereo modes Specification of the eye-to-eye distance used for stereo projections. The specified value is a factor that will be multiplied with the bounding box size of the 3D object that is currently displayed.
Enable backlight color If checked, backlight is enabled with the defined color
Intensity of backlight Specification of the intensity of the backlight. This setting is only enabled if Enable backlight color is checked.
Camera type Selection of the camera projection type.
If Perspective rendering is selected, objects will appear in a perspective projection.
If Orthographic rendering is selected, objects will be projected in orthographic projection.

Färger

Preference Display Tab 02.png

In the Colors tab you can specify the following:

Name Description
Enable preselection highlighting If checked, preselection is turned on and will be highlighted by the specified color. Preselection means that for example edges in parts will be highlighted while hovering with the mouse over them to indicate that they can be selected.
Enable selection highlighting If checked, selection highlighting is turned on and the specified color will be used for it
Pick radius Sets the area of confusion for picking elements in 3D view. Larger value makes it easier to pick stuff, but will make some small features impossible to select.
Simple color If selected, the background for parts will have the selected color
Color gradient If selected, the background for parts will have the selected color gradient
Middle color Is only enabled if Color gradient is selected. If checked, the color gradient will get the selected color as middle color.
Object being edited Selection of the background color for objects in the tree view that are currently edited
Active container Selection of the background color for active containers in the tree view. For example if there are several parts in the tree view and one part is toggled as active body, it will get the selected background color in the tree view.

Delfärger

This tab is only shown if you are in the Part or PartDesign workbench or if you have been in these workbenches before.

Preference Display Tab 03.png

In the Part colors tab you can specify the following:

Name Description
Default shape color Selection of the default color for new shapes. If the option Random shape color is set, a random color is used instead.
Default line color Selection of the default line color for new shapes
Default line width Specification of the default line thickness for new shapes
Default vertex color Selection of the default color for new vertices
Default vertex size Specification of the default size for new vertices
Bounding box color Selection of the color of bounding boxes in the 3D view
Default text color Selection of the default text color for document annotations. There is currently no dialog to add annotations to documents. Annotations can only be added using the Python console with this command:
obj=App.ActiveDocument.addObject("App::Annotation","Label")
This console is shown using the menu View → Panels → Python console.

Import-Export settings

The Import-Export settings affect how files are imported and exported to and from FreeCAD. Note that the Import-Export preferences dialog offers file type settings for most workbenches but not every workbench is able to import/export all file types.

FreeCAD supports many file formats. For the following file formats it offers to apply special settings:

DAE

The Collada DAE (Digital Asset Exchange) format is a standard file format for exchange of Mesh data. The Arch workbench can import meshes from .dae files, and export Arch and other Shape-based objects to the .dae format. The Collada import functionality in the Arch module depends on pycollada. If it is not installed on your system, Collada import/export will be disabled.

For the DAE format you can specify the following:

Name Description
Scaling factor All dimensions in the file will be scaled with the specified factor
Mesher Sets the meshing program that should be used. If using Netgen, make sure that it is available. This can be checked by using the Mesh module and creating a mesh using Netgen. If it is not available another version of FreeCAD, compiled with Netgen, must be installed.
Tessellation The tessellation value to use with the Builtin and the Mefisto meshing program.
Grading The grading value to use for meshing using Netgen. This value describes how fast the mesh size decreases. The gradient of the local mesh size h(x) is bounded by |Δh(x)| ≤ 1/value.
Segments per edge The maximum number of segments per edge
Segments per radius The number of segments per radius
Second order Allow a second order mesh
Optimize Allows optimization
Allow quads Allow quadrilateral faces

DWG

DWG (from drawing) is a proprietary binary file format used for storing two- and three- dimensional design data and metadata. Since it is a closed source file format it cannot be directly supported by FreeCAD. Therefore the external file converter ODA is required.

For the DWG format you can only specify the path to ODA. note: All settings for DXF file format also apply to DWG.

Name Description
Path to ODA (formerly Teigha) File Converter Sets the path to the ODA file converter

DXF

AutoCAD DXF (Drawing eXchange Format) is a proprietary format to exchange CAD data between AutoCAD and other programs.

For the DXF format you can specify the following:

Name Description
Show this dialog when importing and exporting This preferences dialog will be shown when importing or exporting DXF files
Use legacy python importer If checked, the Python importer is used, otherwise the newer C++ one. The C++ importer is faster, but has not as many features yet.
Allow FreeCAD to automatically download and update the DXF libraries By checking this, you will allow FreeCAD to download the Python converter for DXF import and export. This converter cannot be bundled with FreeCAD because it has a different software license.
Import Select what will be imported.
If texts and dimensions is unchecked, texts and mtexts won't be imported.
If layouts is checked, paper space objects will be imported too.
Check *blocks if you want the non-named blocks (beginning with a *) to be imported too.
Create Select what will be created.
If simple Part shapes is selected, only standard Part objects will be created. This is the fastest.
If Draft objects is selected, parametric Draft objects will be created whenever possible.
If Sketches is selected, sketches will be created whenever possible.
Scale factor to apply to imported files Scale factor to apply to DXF files on import. The factor is the conversion between the unit of your DXF file and millimeters. Example: for files in millimeters: 1, in centimeters: 10, in meters: 1000, in inches: 25.4, in feet: 304.8
Get original colors from the DXF file If checked, colors will be retrieved from the DXF objects whenever possible. Otherwise default colors will be applied.
Join geometry If checked, FreeCAD will try to join coincident objects into wires. Note that this can take a while.
Group layers into blocks If checked, objects from the same layers will be joined into Draft Blocks, turning the display faster, but making them less easily editable ??The Draft Wiki pages don't mention Draft blocks??
Use standard font size for texts If checked, imported texts will get the standard Draft Text size, instead of the size they have in the DXF document
Use VisGroups If checked, DXF layers will be imported as Draft VisGroups
Import hatch boundaries as wires If checked, hatches will be converted into simple wires
Render polylines with width If checked, when polylines have a width defined, they will be rendered as closed wires with the correct width
Treat ellipses and splines as polylines The export of ellipses and splines is poorly supported. ??Still the case?? Use this option to export them as polylines instead.
The setting Max Spline Segment is then the maximum length of each of the polyline segments. If it is set to '0' the whole spline is treated as a straight segment.
Export 3D objects as polyface meshes If checked, all objects containing faces will be exported as 3D polyfaces
Export Drawing Views as blocks If this is checked, Drawing Views will be exported as blocks. This might fail for post DXF R12 templates.
Project exported objects along current view direction If checked, the exported objects will be projected to reflect the current view direction

IGES

The Initial Graphics Exchange Specification (IGES) file format is a file format that allows the digital exchange of information among CAD systems. Since the specification for the STEP file format was published, the development of IGES was stopped in 1996. It is nevertheless still supported by many CAD programs.

The tab IGES is only shown in the preferences if you are in the Part or PartDesign workbench or if you have been in these workbenches before.
For the IGES format you can specify the following:

Name Description
Units for export of IGES Selection what unit will be used when exporting IGES files
Write solids and shells as Selection how solids and shells should be output.
If Groups of Trimmed Surfaces (type 144) is selected, they will be exported as trimmed surface.
If Solids (type 186) and Shells (type 514) / B-REP mode is selected, solids will be exported as manifold solid B-Rep object, shells as shell.
Skip blank entities If checked, blank entities will not be imported
Company If not empty, the entered text will be used in the IGES file header for the company
Author If not empty, the entered text will be used in the IGES file header for the author
Product If not empty, the entered text will be used in the IGES file header for the product

IFC

Industry Foundation Classes (IFC) is a wide spread format to interchange data between BIM applications, used in architecture and engineering.

For the IFC format you can specify the following:

Name Description
Show debug messages Shows verbose debug messages during import and export of IFC files in the Report view panel
Create clones when objects have shared geometry IFC objects can share a same geometry definition between several objects, only their placement is different. So when this option is enabled, clones are used to achieve the same result in FreeCAD. One object is the base object, the others are clones.
Import arch IFC objects as What will be created in FreeCAD for arch IFC objects
Import struct IFC objects as What will be created in FreeCAD for struct IFC objects
Root element Only subtypes of the specified element will be imported. Keep the predefied element IfcProduct to import all building elements.
Separate openings If checked, openings will be imported as subtractions, otherwise wall shapes will already have their openings subtracted
Detect extrusions If checked, the importer will try to detect extrusions. Note that this might slow things down.
Split multilayer walls Split walls made of multiple layers
Prefix names with ID number If checked, object names will be prefixed with the IFC ID number
Merge materials with same name If several materials with the same name are found in the IFC file, they will be treated as one.
Import Ifc Properties in spreadsheet If checked, each object will have their IFC properties stored in a spreadsheet object.
Exclude list A comma-separated list of IFC entities to be excluded from imports
Fit view while importing Fit view during import on the imported objects. This will slow down the import, but one can watch the import.
Force export as Brep Some IFC viewers don't like objects exported as extrusions. Use this to force all objects to be exported as BREP geometry.
Use DAE triangulation options Use triangulation options set in the DAE options page
Join coplanar facets when triangulating Curved shapes that cannot be represented as curves in IFC are decomposed into flat facets. If this is checked, some additional calculation is done to join coplanar facets.
Store IFC universal ID in FreeCAD objects When exporting objects without universal ID (UID), the generated UID will be stored inside the FreeCAD object for reuse next time that object is exported. This leads to smaller differences between file versions.
Use IfcOpenShell serializer if available IFCOpenShell is a library that allows to import IFC files. Its serializer functionality allows to give it an OCC shape and it will produce an adequate IFC geometry: NURBS, faceted, or anything else. Note that the serializer this is still an experimental feature.
Export 2D objects as IfcAnnotations If checked, 2D objects will be exported as IfcAnnotation
Export full FreeCAD parametric model If checked, all FreeCAD object properties will be stored inside the exported objects, allowing to recreate a full parametric model on reimport.
Reuse similar entities If checked, similar entities will be used only once in the file if possible. This can reduce the file size a lot, but will make it less easily readable by humans.
Disable IfcRectangleProfileDef When possible, IFC objects that are extruded rectangles are exported as IfcRectangleProfileDef. However, some other applications have problems importing that entity. If this is your case, you can disable this and then all profiles will be exported as IfcArbitraryClosedProfileDef.

INP

INP is the input file format for the FEM software Abaqus. It is used for the solver CalculiX in the FEM workbench.

The tab Abaqus INP is only shown in the preferences if you are or if you have been in the FEM workbench before.
For the INP format you can specify the following:

Name Description
Which mesh elements to export Selection what mesh element parameters should be exported.
If All is selected, all elements will be exported.
If Highest is selected, only the highest elements will be exported. This means for means volumes for a volume mesh and faces for a shell mesh.
If FEM is selected, only FEM elements will be exported. This means only edges not belonging to faces and faces not belonging to volumes.
Export group data If checked, mesh groups are exported too. Every constraint and, if there are different materials, material consists of two mesh groups, faces and nodes where the constraint or material is applied.

Mesh formats

Meshes are a special type of 3D object, composed of triangular faces connected by their vertices and edges. They are widely used for additive manufacturing. The FreeCAD provides the Mesh workbench to create and handle meshes. FreeCAD supports the file formats AMF and its predecessor STL, OBJ, OFF, PLY and SMF.

The tab Mesh formats is only shown in the preferences if you are in the Mesh workbench or if you have been in this workbench before.
For the Mesh formats you can specify the following:

Name Description
Maximum mesh deviation Specification of the maximal deviation between the mesh and the object
Export AMF files using compression If checked, ZIP compression is used when writing a mesh file in AMF format

OCA

The OCA file format is a community project to create a free, simple and open CAD file format. OCA is largely based on the GCAD file format generated by gCAD3D. Both formats can be imported in FreeCAD and the OCA files exported by FreeCAD can be opened in gCAD3D.

For the OCA format you can specify the following:

Name Description
Import OCA areas If checked, the areas (3D faces) will be imported too

STEP

The standard for the exchange of product model data (STEP) file format is an ISO standard for the computer-interpretable representation and exchange of product manufacturing information. STEP is therefore commonly used to exchange 3D data between CAD software. STEP files have the suffix .step or sometimes .stp.

The tab STEP is only shown in the preferences if you are in the Part or PartDesign workbench or if you have been in these workbenches before.
For the STEP format you can specify the following:

Name Description
Units for export of STEP Selection what unit will be used when exporting STEP files
Write out curves in parametric space of surface If checked, parametric curves (curves in parametric space of surface) will be written into the STEP file. Unchecking the option can be helpful to minimize the size of the resulting STEP file.
Scheme Selection what STEP application protocol (AP) will be used for the export.
AP 203 is the protocol for configuration controlled 3D designs of mechanical parts and assemblies.
AP 204 is the protocol for core data for automotive mechanical design processes.
Enable STEP Compound merge If checked, a compound merge will be done during file reading. This is slower but results in higher details.
Company If not empty, the entered text will be used in the STEP file header for the company
Author If not empty, the entered text will be used in the STEP file header for the author
Product If not empty, the entered text will be used in the STEP file header for the product

SVG

Scalable Vector Graphics (SVG) is a vector image format for two-dimensional graphics. The vectors make SVG are very useful for technical drawing programs like FreeCAD's TechDraw because a vector image can be scaled to any size without losing its shape or amount of details. SVG can be scaled to any required resolution and converted to bitmap formats like PNG or JPEG for printing.

For the SVG format you can specify the following:

Name Description
Import style Selection how SVG object colors and line widths will be imported.
If None (fastest) is selected no color and line width settings will be imported.
If Use default color and linewidth is selected FreeCAD will use its default color and line width.
If Original color and linewidth is selected FreeCAD will use the color and linewidth from the SVG objects.
Disable units scaling If checked, no units conversion will occur. One unit in the SVG file will translate as one millimeter.
Export style Selection how Sketches are exported to SVG.
If Translated (for print & display) is selected, SVG objects are encapsulated in a group that is scaled and moved to the correct place in the SVG document to fit into a printable area.
If Raw (for CAM) is selected, SVG objects are placed as they are - at the same coordinates as in the FreeCAD model (1:1 export).
Translate white line color to black If checked, all white lines will appear in black in the SVG for better readability against white backgrounds
Max segment length for discretized arcs Older versions of Open CASCADE than version 6.8 don't support arc projection. In this case arcs will be discretized into small line segments. This value is the maximum segment length.

VTK

The Visualization Toolkit (VTK) is an open-source, freely available software system for 3D computer graphics, image processing and visualization. VTK files are used by the FEM workbench for the post processing of simulation results.

The tab VTK is only shown in the preferences if you are or if you have been in the FEM workbench before.
For the VTK format you can specify the following:

Name Description
Which object to import into Selection what objects should be imported.
If VTK result object is selected, a FreeCAD FEM VTK result object will be imported (equals to the object which was exported).
If FEM mesh object is selected, the results in the VTK file will be omitted, only the mesh data will be imported and a FreeCAD FEM mesh object will be created.
If FreeCAD result object is selected, the imported data will be converted into a FreeCAD FEM Result object. Note: this setting needs the exact result component names and thus it only works properly with VTK files exported from FreeCAD.


Workbench preferences

Preferences for the more common workbenches are linked below. Some workbenches have no preferences. Other optional workbenches may not be listed.


A2plus Preferences

Draft-modulen har sin Inställningar -skärm

Draft Preferences

Drawing Preferences (none)

Fem Preferences

Image Preferences (none)

Inspection Preferences (none)

Mesh Design Preferences (none)

OpenSCAD Preferences

Part Preferences (none)

Part Design Preferences (none)

Path Preferences

Plot Preferences (none)

Points Preferences (none)

Raytracing Préférences

Reverse Engineering Preferences (none)

Robot Preferences (none)

Ship Preferences (none)

Sketcher Preferences

Spreadsheet Preferences (none)

Surface Preferences (none)

TechDraw Preferences

Test Framework Preferences (none)


Web Preferences (none)


Anpassa gränssnittet

Eftersom FreeCAD gränssnittet är baserat på det moderna Qt verktygssetet, så har det en högklassig organisation. Widgetar, menyer, verktygslådor och andra verktyg kan ändras, flyttas, delas mellan arbetsbänkar, tangentbordsgenvägar kan ställas in, ändras, och makron kan spelas in och spelas upp. Anpassningsfönstret hittas i Verktyg -> Anpassa menyn:

Screenshot-customize.jpg

Kommandon tabben visar alla tillgängliga FreeCAD kommandon, organiserade i kategorier.

I Tangentbord, så kan du se de tangentbordsgenvägar som är associerade med varje FreeCAD kommando, och om du vill, ändra eller tilldela nya genvägar till valfritt kommando. Hit är var du vill komma om du använder en viss arbetsbänk ofta, och vill snabba upp dess användande genom att använda tangentbordet.

Verktygslådor tabben låter dig ändra existerande verktygslådor, eller skapa dina egna anpassade verktygslådor.

Makron tabben låter dig hantera dina sparade Makron.

Create your Toolbars for your macro Customize Toolbars

Since FreeCAD 0.16 a new tool is available that lets you manage your workbenches.

CustomizeWorkbenches.png

Example

For an example workflow lets suppose we want to have the "Measure Linear" tool also show up in a custom toolbar in the Draft Workbench.

  • in FreeCAD choose Tools → Customize from the top menu
  • select the "Toolbars" tab
  • on the left side choose "Part" in the pull down menu
  • on the left side in the lower window scroll down to the "Measure Linear" entry and select it
  • on the right side choose "Draft" in the pull down menu
  • click on New... to create a new toolbar and choose a name for it
  • now select your destination toolbar in the right lower window (only needed if you have more than one toolbar)
  • by clicking on the blue "Arrow right" (top icon in the middle row) you will add your selected entry to the selected toolbar

Remarks

When selecting "Global" in the pull down menu on the right side you will create a toolbar which will be visible in all workbenches.

For adding an installed macro to a toolbar you must

  • select "Macros" in the pull down menu on the left side
  • have assigned menu text, icon (Pixmap) and so on using the Tools → Customize → Macros menu



Objekt egenskaper

En egenskap är en informationsbit som till exempel ett nummer eller en textsträng som hör till ett FreeCAD dokument eller ett objekt i ett dokument. Egenskaper kan visas och - om det är tillåtet - ändras med egenskapsredigeraren.


Egenskaper spelar en mycket viktig roll i FreeCAD, eftersom det från början är gjort för att arbeta med parametriska objekt, vilket är objekt som endast definieras av deras egenskaper.


Anpassade skript objekt i FreeCAD kan ha egenskaper av följande typer:


Boolean
Float
FloatList
FloatConstraint
Angle
Distance
Integer
IntegerConstraint
Percent
Enumeration
IntegerList
String
StringList
Link
LinkList
Matrix
Vector
VectorList
Placement
PlacementLink
Color
ColorList
Material
Path
File
FileIncluded
PartShape
FilletContour
Circle

Properties play a very important part in FreeCAD, since it has been designed to work with parametric objects, which are objects defined only by their properties.

Custom scripted objects in FreeCAD can have properties of the following types:

Boolean
 Float
 FloatList
 FloatConstraint
 Angle
 Distance
 Integer
 IntegerConstraint
 Percent
 Enumeration
 IntegerList
 String
 StringList
 Link
 LinkList
 Matrix
 Vector
 VectorList
 Placement
 PlacementLink
 Color
 ColorList
 Material
 Path
 File
 FileIncluded
 PartShape
 FilletContour
 Circle



Arbeta med arbetsbänkar

FreeCAD, som många moderna design applikationer som Revit, är baserade på konceptet Arbetsbänk. En arbetsbänk kan anses vara ett set verktyg, grupperade för en viss uppgift. I en traditionell möbelverkstad, så skulle du ha ett arbetsbord för den person som arbetar med trä, ett annat bord för den som arbetar med metalldelar, och kanske ett tredje för den som monterar ihop allting.

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.

I FreeCAD, så används samma koncept . Verktyg är grupperade i arbetsbänkar i enlighet med de uppgifter de är relaterade till.

När du byter från en arbetsbänk till en annan, så byts de tillgängliga verktygen i gränssnittet ut. Verktygslådor, kommandolådor och eventuellt andra delar av gränssnittet byts till den nya arbetsbänken, men innehållet i din scen förändras inte. Du kan till exempel börja att rita 2D former med Rit arbetsbänken, sedan fortsätta arbetet på dem med Del arbetsbänken.

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 GUI configuration that groups some toolbars and menus. Usually every Module contains its own Workbench, hence the cross-use of the name.

Built-in workbenches

För närvarande har vi följande arbetsbänkar:

  • Workbench Arch.svg The Arch Workbench for working with architectural elements.
  • Workbench Complete.svg The Complete Workbench hold all commands and features from all the modules and workbenches which met certain quality criteria.
  • Workbench Draft.svg 2D skissning: En enkel arbetsbänk för 2D skissning
  • Workbench Drawing.svg Ritning: Hjälper dig att lägga dina 3D vyer på ett 2D pappersark
  • Workbench FEM.svg The FEM Workbench provides Finite Element Analysis (FEA) workflow.
  • Workbench Image.svg Bild: Hanterar Bitmappsbilder
  • Workbench Inspection.svg The Inspection Workbench is made to give you specific tools for examination of shapes. It is still in development.
  • Workbench Mesh.svg Nät: Hanterar triangulerade nät
  • Workbench OpenSCAD.svg The OpenSCAD Workbench for interoperability with OpenSCAD and repairing Constructive Solid Geometry (CSG) model history.
  • Workbench Part.svg Del: Hanterar BREP objekt
  • Workbench PartDesign.svg The Part Design Workbench for building Part shapes from sketches.
  • Workbench Path.svg The Path Workbench is used to produce G-Code instructions. It is still in a stage of development. Only basic functions in 0.16
  • Workbench Plot.svg The Plot Workbench is used to edit and save output plots created from other modules and tools.
  • Workbench Points.svg Punkter: Låter dig arbeta med punktmoln
  • Workbench Raytracing.svg Rendering: Tillåter att du använder extern renderingsmjukvara
  • Workbench Reverse Engineering.svg The Reverse Engineering Workbench is intended to give you specific tools to convert shapes/solids/meshes into parametric FreeCAD-compatible features. It is still in development.
  • Workbench Robot.svg Robot simulering: Simulera 6-Axliga industrirobotar som Kuka, ABB och andra.
  • Workbench Ship.svg The Ship Workbench FreeCAD-Ship works over Ship entities, that must be created on top of provided geometry.
  • Workbench Sketcher.svg The Sketcher Workbench for working with geometry-constrained sketches.
  • Workbench Spreadsheet.svg The Spreadsheet Workbench for creating and manipulating spreadsheet data.

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 → AddonManager.svg Addon manager.

Nya arbetsbänkar är under utveckling, håll utkik!


Nät arbetsbänken

Workbench Mesh.svg

Nät arbetsbänken hanterar triangelnät. Nät är en speciell typ av 3D objekt, sammansatt av trianglar som är ihopkopplade via deras kanter och hörn.

Många 3D applikationer använder nät som deras primära 3D objektstyp, som sketchup, blender, maya eller 3d studio max. Eftersom nät är mycket simpla objekt, som endast innehåller hörn (punkter), kanter och (triangulära) ytor, så är de mycket lätta att skapa, förändra, dela upp, sträcka ut, och kan lätt flyttas från en applikation till en annan utan några förluster. Eftersom de dessutom innehåller mycket simpel data, så kan 3D applikationer vanligtvis hantera mycket stora kvantiteter av dem utan några problem. Av dessa anledningar, så är nät ofta den valda 3D objekttypen i applikationer för filmer, animeringar, och bildbehandling.

Emellertid har nät en stor begränsning inom konstruktionsfältet: De är mycket 'dumma' objekt, som endast består av punkter, linjer och ytor. De består endast av ytor, och har ingen informationom dess massa, så de beter sig inte som solider. I ett nät så finns det inget automatiskt sätt att avgöra om en punkt är inuti eller utanför objektet. Detta innebär att alla solidbaserade operationer, som addition eller subtraktion, alltid är svåra att utföra på nät, och ofta orsakar fel.

Contents

Mesh example.jpg

Använda nätmodulen

Nätmodulen har för närvarande ett mycket enkelt gränssnitt, alla dess funktioner är grupperade i Nät menyn. De viktigaste operationerna som du för närvarande kan göra med nät är:

  • Importera nät i flera filformat
  • Exportera nät i flera filformat
  • Konvertera Del objekt till nät
  • Analysera kurvatur, ytor, och kontrollera om ett nät kan konverteras till en solid på ett säkert sätt
  • Vända nät normaler
  • Stänga hål i nät
  • Ta bort ytor i nät
  • Förena, subtrahera och skära nät
  • Skapa nätprimitiver, som kuber, sfärer, Koner eller cylindrar
  • Klippa nät längs en linje

General tools

Analyze

Analysis of curvature, faces, and check if a mesh can be safely converted into a solid

Regular solid

Mesh Regular Solid.png Regular solid... Create mesh primitives, like cubes, cylinders, cones, or spheres:

Boolean

  • Union: Does a union (fusion) on meshes
  • Intersection: Does an intersection (common) on meshes
  • Difference: Does a difference (cut) on meshes

Cutting

Other

Preferences

Detta är bara några av de grundläggande operationerna som för närvarande finns i Nätmodulens gränssnitt. Men FreeCAD nät kan också hanteras på många fler sätt med skript.

Meshes can also be handled by Mesh Scripting.

Links


Del arbetsbänken

Workbench Part.svg

FreeCAD's CAD kapabilitet är baserad på OpenCasCade kärnan. Del modulen tillåter FreeCAD att komma åt och använda OpenCasCade objekt och funktioner. OpenCascade är en professionell CAD kärna, som erbjuder avancerad 3D geometrimanipulation och objekt. Del objekten, till skillnad från Nätmodul objekten, är mycket komplexare, och tillåter därför mycket mer avancerade operationer, som koherenta booleska operationer, ändringshistorik och parametriskt beteende.

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 modelling 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.

Part example.jpg

Part Workbench relationships.svg

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


Verktygen

Alla Del modul verktygen finns i Del menyn som kommer fram när du laddar Del modulen.

Primitiver

Detta är verktyg för att skapa primitivobjekt.

  • Part Box.png Låda: Ritar en låda genom att ge dess dimensioner
  • Part Cylinder.png Cylinder: Ritar en cylinder genom att ge dess dimensioner
  • Part Sphere.png Sfär: Ritar en sfär genom att ge dess dimensioner
  • Part Cone.png Kon: Ritar en kon genom att ge dess dimensioner
  • Part Torus.png Torus: Ritar en torus (ring) genom att ge dess dimensioner
  • Part CreatePrimitives.png CreatePrimitives: Ett verktyg för att skapa olika parametriska geometriska primitiver
  • Part Shapebuilder.png Shapebuilder: Ett verktyg för att skapa mer komplexa former från olika parametriska geometriska primitiver

Förändra objekt

Detta är verktyg för att förändra existerande objekt. De kommer att låta dig välja vilka objekt som du vill förändra.

  • Part Extrude.png Extrudera: Extruderar plana ytor på ett objekt
  • Part Revolve.png Rotera: Skapar ett objekt genom att rotera ett annat objekt runt en axel
  • Part Mirror.png Spegling: Speglar de valda objekten runt en given axel
  • Part Fillet.png Fasning: Fasar (rundar) kanterna på ett objekt
  • Part Chamfer.png Fasning: Fasar (klipper) kanter på ett objekt
  • Part RuledSurface.png Ruled Surface:
  • Part Loft.png Loft: Lofts från en profil till en annan
  • Part Sweep.png Sweep: Sopa en eller flera profiler längs en bana
  • Part CompOffsetTools.png Offset tools:
    • Part Offset.png 3D Offset: Constructs a parallel shape at a certain distance from original.
    • Part Offset2D.png 2D Offset: Constructs a parallel wire at certain distance from original, or enlarges/shrinks a planar face. (v0.17)
  • Part Thickness.png Thickness: Hollows out a solid, leaving openings next to select faces.
  • Part Booleans.png Boolesk: Utför booleska operationer på objekt
  • Part Union.png Förena: Förenar två objekt
  • Part Common.png Gemensamt: Tar bort den gemensamma (skärningen) delen mellan två objekt
  • Part Cut.png Klipp: Klipper (tar bort) ett objekt från ett annat
  • Part CompJoinFeatures.png Join features: smart booleans for walled objects (e.g., pipes) (v0.16)
    • Part JoinConnect.png Connect: Connects interiors of objects (v0.16)
    • Part JoinEmbed.png Embed: Embeds a walled object into another walled object (v0.16)
    • Part JoinCutout.png Cutout: Creates a cutout in a wall of an object for another walled object (v0.16)
  • Part CompSplittingTools.png Splitting tools: (v0.17)
    • Part BooleanFragments.png Boolean fragments: makes all the pieces that can be obtained by Boolean operations between objects (v0.17)
    • Part SliceApart.svg Slice a part: tool to split shapes by intersection with other shapes
    • Part Slice.png Slice: Splits an object into pieces by intersections with another object (v0.17)
    • Part XOR.png XOR: removes space shared by even number of objects (symmetric version of Cut) (v0.17)

Other tools

  • Part ImportCAD.png Import CAD: This tool allows you to add a file *.IGES, *.STEP, *.BREP to the current document.
  • Part ExportCAD.png Export CAD: This tool allows you to export a part object in a *.IGES, *.STEP, *.BREP file.
  • Part ShapeFromMesh.png Shape from Mesh: Creates a shape object from a mesh object.
  • Convert to solid: Converts a shape object to a solid object.
  • Reverse shapes: Flips the normals of all faces of the selected object.
  • Part CreateSimpleCopy.svg Create simple copy: Creates a simple copy of the selected object.
  • Part RefineShape.png Refine shape: Cleans faces by removing unnecessary lines.
  • Part CheckGeometry.png Check geometry: Checks the geometry of selected objects for errors.
  • Measure: Allows linear and angular measurement between points/edges/faces.
  • Part Attachment.svg Attachment: Attachment is a utility to attach an object to another one.

Preferences

Förklaring av koncepten

I OpenCasCade terminologi, så skiljer vi mellan geometriska primitiver och (topologiska) former. En geometrisk primitiv kan vara en punkt, en linje, en cirkel, ett plan, etc. eller även mer komplexa typer som en B-Spline kurva eller yta. En form kan vara ett hörn, en kant, en tråd, en yta, en solid eller en sammansättning av andra former. De geometriska primitiverna är inte gjorda för att direkt visas i 3D scenen, utan snarare för att användas som bygggeometri för former. Till exempel så kan en kant skapas av en linje eller av en cirkeldel.

Vi skulle kunna säga att geometriprimitiver är "formlösa" byggblock, och former är den riktiga spatiala geometrin som är byggd på dem.

För att få en komplett lista på dem, se OCC documentation och leta efter Geom_Geometry och TopoDS_Shape. Där kan du också läsa mer om skillnaderna mellan geometriska objekt och former. Notera att OCC dokumentationen inte är tillgänglig online (du måste ladda ned ett arkiv) och är mest riktad till programmerare, inte till slutanvändare. Men förhoppningsvis hittar du tillräckligt med information här för att kunna börja.

De geometriska typeerna kan uppdelas i två huvudgrupper: kurvor och ytor. Från kurvor (linje, cirkel, ...) så kan du bygga en kant, från ytor (plan, cylinder, ...) så kan en yta byggas. Den geometriska primitiven linje är till exempel obegränsad, d.v.s. den är definierad av en basvektor och en riktningsvektor emedan dess formrepresentation måste vara något som begränsas av en start och en slutpunkt. Och en låda -- en solid -- kan skapas av sex begränsade plan.

Från en kant eller yta så kan du också gå tillbaka till dess motsvarande geometriska primitiv.

Så, av former så kan du bygga mycket komplexa delar eller, åt andra hållet, plocka ut alla delformer som en mer komplex form är gjord av.

Skript

See also: Part scripting

Den huvudsakliga data strukturen som används i Del modulen är BRep datatypen från OpenCascade.

Nästan alla Del modulens innehåll och objekttyper finns nu tillgängliga för python skript. Detta inkluderar geometriska primitiver, som Linje och Cirkel (eller Cirkelbåge), och alla topologiska former, som Hörn, Kanter, Trådar, Ytor, Solider och Sammansättningar. För vart och ett av dessa objekt, så finns flera metoder att skapa dem, och för en del av dem, speciellt de topologiska formerna, så finns avancerade operationer som booleska förening/skillnad/skärning . Utforska innehållet in Del modulen, som det är beskrivet i FreeCAD Skript Grunder sidan, för att lära dig mer.

Exempel

För att skapa en linje, växla till Python konsolen och skriv:

import Part,PartGui 
doc=App.newDocument()  
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()

Låt oss gå igenom ovanstående python exempel steg för steg:

import Part,PartGui
doc=App.newDocument()

laddar Del modulen och skapar ett nytt dokument

l=Part.LineSegment()
l.StartPoint=(0.0,0.0,0.0)
l.EndPoint=(1.0,1.0,1.0)

Linje är egentligen ett linjesegment, därför start och slutpunkten.

doc.addObject("Part::Feature","Line").Shape=l.toShape()

Detta lägger till en Del objekttyp till dokumentet och tilldelar linjesegmentets formrepresentation till 'Shape' egenskapen på det tillagda objektet. Det är viktigt att förstå att vi använde en geometrisk primitiv (Part.line) för att skapa en topologisk form av den ( toShape() metoden). Endast former kan adderass till dokumentet. I FreeCAD, så används geometriprimitiver som "byggstrukturer" för former.

doc.recompute()

Uppdaterar dokumentet. Detta förbereder också den visuella representationen av det nya del objektet.

Notera att en Linje kan skapas genom att du specificerar dess start och slutpunkt direkt i konstruktorn, till exempel Part.Line(point1,point2) eller vi kan skapa en standardlinje och ändra dess egenskaper efteråt, som vi gjorde här.

En cirkel kan skapas på ett liknanade sätt:

import Part
doc = App.activeDocument()
c = Part.Circle() 
c.Radius=10.0  
f = doc.addObject("Part::Feature", "Circle")
f.Shape = c.toShape()
doc.recompute()

Notera igen, att vi använde cirkel (geometriprimitiv) för att konstruera en form av den. Vi kan förstår fortfarande komma åt vår konstruktionsgeometri efteråt, genom att göra:

s = f.Shape
e = s.Edges[0]
c = e.Curve

Här tar vi formen av vårt objekt f, sedan tar vi dess lista av kanter, i detta fall kommer det endast att vara en, eftersom vi gjorde hela formen av en enda cirkel, så vi tar endast den första punkten i Kant listan, och vi tar dess kurva. Varje Kant har en Kurva, vilken är den geometriprimitiv den är baserad på.

Gå till Topologiska data skript sidan om du vill veta mer.

Tutorials


Ritnings arbetsbänken

Workbench Drawing.svg

Introduction

Development of the Drawing Workbench stopped in FreeCAD 0.16, and the new TechDraw Workbench aiming to replace it was introduced in v0.17. Both workbenches are still provided in v0.17, but the Drawing Workbench may be removed in future releases.


Ritnings modulen tillåter dig att lägga ut ditt 3D arbete på papper. Det är, att lägga vyer av dina modeller i ett 2D fönster osh att sätta in det fönstret i en ritning, till exempel ett ark med en ram, en titel och din logotyp och slutligen skriva ut det arket. Ritningsmodulen är för närvarande under konstruktion och är mer eller mindre en teknologisk förhandstitt!

Drawing extraction.png

Gränssnittsverktyg

Detta är verktyg för att skapa, konfigurera och exportera 2D ritningsark

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

Note The Draft Module has its own Draft_Drawing too to place Draft objects on paper. It has a couple of extra capabilities over the standard Drawing tools, and supports specific objects like Draft dimensions.

I bilden så ser du huvudkoncepten av Ritningsmodulen. Dokumentet innehåller ett formobjekt (Schenkel) som vi vill göra en ritning av. Därför så är en "Sida" skapad. Sidan fås genom en mall, i detta fall "A3_Landskap" mallen. Mallen är ett SVG dokument som kan innehålla din vanliga sidram, din logotyp eller så den överensstämmer med dina presentationsstandarder.

I denna sida så kan vi sätta in en eller fler vyer. Varje vy har en position på sidan (Egenskaper X,Y), en skalfaktor (Egenskap skala) och ytterligare egenskaper. Varje gång som sidan ,eller vyn, eller det refererade objektet ändras så regenereras sidan och visningen uppdateras.

Skript

För tillfället så är arbetsflödet för slutanvändaren väldigt begränsat, så skript API't är intressantare. Här följer exempel på hur man använder skript API't för ritningsmodulen.

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

Here a script that can easily fill the Macro_CartoucheFC leaf FreeCAD A3_Landscape.

Exempel

FreeCAD kommer med ett standardset med mallar, men du kan hitta fler på Ritningsmallar sidan.

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

External links


Raytracing arbetsbänken

Workbench Raytracing.svg

Denna modul är tänkt att skicka innehållet i din scen till en extern rendererare, för att generera fotorealistiska bilder på ditt arbete. Renderingsmodulen är fortfarande i ett mycket tidigt skede, så du har inte så många tillgängliga alternativ för tillfället. För närvarande finns endast ett grundläggande verktygsset för att exportera Del objekt som POV-ray filer. Dessa filer kan sedan laddas i POV-ray och renderas.

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: povray 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.

A new Render Workbench has been in development to support multiple back-ends such as Lux Renderer and Yafaray. Information for using the development version can be viewed at Render project. For development status of the Render Module look into the Raytracing project.

Raytracing example.jpg

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.


Raytracing Workbench workflow.svg


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.


Gränssnittsverktyg

Project tools

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

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

Utilities

These are helper tools to perform specific tasks manually.

Preferences

  • Preferences-raytracing.svg 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.

FreeCAD Raytracing.jpg

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

Povray.jpg

As usual in a renderer you can make big and nice pictures:

Scharniergreifer render.jpg

Skript

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

Länkar

POVRay

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


Bild arbetsbänken

Workbench Image.svg

Introduction

Bildmodulen hanterar olika typer av bitmapp bilder, och låter dig öppna dem i FreeCAD. För närvarande, så kan modulen öppna .bmp, .jpg, .png och .xpm filformat i ett separat visningsfönster. Det finns också ett verktyg som tillåter dig att fånga bilder från en webcam.

Currently, the module supports opening BMP, JPG, PNG, and XPM file formats.

Tools

  • Image-import.svg Open: open an image on a new viewport.
  • Image-import-to-plane.svg Import to plane: import an image to a plane in the 3D view.
  • Image-scale.svg Scaling: scale an image imported to a plane.

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.




Skiss arbetsbänken

Workbench Draft.svg

Rit modulen är ett pågående arbete och är en ganska experimentell modul som har gjorts för att lägga till grundläggande 2d ritfunktionalitet till FreeCAD. Den är helt och hållet skriven i python, och är även tänkt att fungera som en presentation om hur mycket du kan utöka FreeCAD endast med hjälp av python, utan att ens röra källkoden.

The created 2D objects can be used for general drafting in a way similar to Inkscape or Autocad. These 2D shapes can also be used as the base components of 3D objects created with other workbenches, for example, the Part and Arch Workbenches. Conversion of Draft objects to Sketches is also possible, which means that the shapes can also be used with the PartDesign Workbench for the creation of solid bodies.

FreeCAD is primarily a 3D modelling application, and thus its 2D tools aren't as advanced as in other drawing programs. If your primary goal is the production of complex 2D drawings and DXF files, and you don't need 3D modelling, you may wish to consider a dedicated software program for technical drafting such as LibreCAD, QCad, TurboCad, and others.

Draft Workbench Example.png

Rita objekt

Detta är verktyg för att rita objekt.

  • Draft Line.png 2-punkt Linje: Ritar ett linjesegment mellan 2 punkter
  • Draft Wire.png Tråd (multi-punkts linje): Ritar en linje som består av flera linjesegment
  • Draft Circle.png Cirkel: Ritar en cirkel med hjälp av centrum och radie
  • Draft Arc.png Cirkelbåge: Ritar en cirkelbåge med hjälp av centrum, radie, startvinkel och slutvinkel
  • Draft Ellipse.png Ellipse: Draws an ellipse from two corner points
  • Draft Polygon.png Polygon: Ritar en regelbunden polygon med center och en radie
  • Draft Rectangle.png Rektangel: Ritar en rektangel från 2 motsatta punkter (hörnen)
  • Draft Text.png Text: Ritar en text annotering med flera rader
  • Draft Dimension.png Dimension: Ritar en måttsättning
  • Draft BSpline.png BSpline: Ritar en B-Spline från en serie med punkter
  • Draft Point.png Point: Inserts a point object
  • Draft ShapeString.png ShapeString: The ShapeString tool inserts a compound shape representing a text string at a given point in the current document
  • Draft Facebinder.png Facebinder: Creates a new object from selected faces on existing objects
  • Draft BezCurve.png Bezier Curve: Draws a Bezier curve from a series of points
  • Draft Label.png Label: Places a label with an arrow pointing to a selected element available in version 0.17

Förändra objekt

Detta är verktyg för att förändra existerande objekt. De arbetar med valda objekt, men om inget objekt är valt, så ombes du att välja ett.

Many operation tools (move, rotate, array, etc.) also work on solid objects (Part, PartDesign, Arch, etc.).

Utility tools

Additional tools available from the menu Draft → Utilities, or via the right-click context menu, depending on the selected object.

Preferences

  • Preferences-draft.svg Preferences: general preferences for the working plane and the drawing tools.
  • Preferences-import-export.svg Import-Export Preferences: preferences available for importing from and exporting to different file formats.

Import & export


Detta är funktioner för att öppna, importera eller exportera andra filformat. Öppna kommet att öppna ett nytt dokument med filens innehåll, medan importera kommer att lägga till filinnehållet till det nuvarande dokumentet. Exportera kommer att spara de valda objekten till en fil. Om inget är valt, så kommer alla objekt att exporteras. Var uppmärksam på att eftersom tanken med Ritmodulen är att arbeta med 2d objekt, så fokuserar dessa importerare endast på 2d objekt, och, fastän DXF och OCA formaten stödjer objektdefinitioner i 3D rymden (objekt är inte nödvändigtvis platta), så kommer de inte att importera volymetriska objekt som nät, 3D ytor, etc, utan snarare linjer, cirklar, text eller flata former. För närvarande så stöds följande filformat:

  • Autodesk .DXF: Importerar och exporterar DXF filer som har skapats med andra CAD applikationer
  • SVG (som geometri): Importerar och exporterar SVG filer som har skapats med vektorbaserade ritapplikationer

Gemensamt beteende

  • Snäpp: tillåter dig att placera nya punkter på speciella platser på existerande objekt
  • Begränsning: Tillåter att nya punkter placeras horisontellt eller vertikalt i relation till tidigare punkter
  • Kopiering: Alla ändringsverktyg kan antingen ändra de valda objekten eller skapa en förändrad kopiaav dem. Genom att trycka på ALT tangenten medan verktyget används kommer att skapa en kopia
  • Konstruktionsläge: Tillåter dig att skilja viss geometri åt från resten, för att lätt kunna stänga på/av
  • Arbetsplan: Alla skisskommandon kan användas på valfritt plani i 3D rymden. Det gällande arbetsplanet kan konfigureras på ett lätt sätt

API

Se Skiss API sidan för en komplett beskrivning av Skissfunktionerna som du kan använda i skript och makron


Skript och Makron

Macros

Introduction

Makron är ett smidigt sätt att skapa komplexa aktioner i FreeCAD. Du behöver bara spela in aktioner samtidigt som du gör dem, och sedan spara det under ett namn, och senare spela upp det när du vill. Eftersom makron i realiteten är en lista av python kommandon, så kan du även redigera det, och skapa mycket komplexa skript.

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 Introduction to Python to learn about the Python programming language, and then Python scripting tutorial and FreeCAD Scripting Basics to learn about writing macros.

Hur det fungerar

Om du aktiverar konsolutmatning(Meny Redigera -> Alternativ -> Allmänt -> Makro -> Visa skriptkommandon i python konsolen), så kommer du se att varje aktion du gör i FreeCAD, , som att klicka på en knapp, genererar ett python kommando. Dessa kommandon är vad som kan spelas in i ett makro. Huvudverktyget för att göra makron är makroverktygslådan: Macros toolbar.jpg. På den finns det 4 knappar: Spela in, stoppa inspelning, redigera och spela upp det nuvarande makrot.

Det är mycket enkelt att använda: Klicka på inspelningsknappen, du kommer att efterfrågas om ett namn till ditt makro, utför sedan några aktioner. När du är klar, Klick på stoppa inspelning knappen, och dina aktioner kommer att spaaras. Du kan nu komma åt makrodialogen med redigeraknappen:

Macros.jpg

Där kan du hantera dina makron, radera, redigera eller skapa nya från scratch. Om du redigerar ett makro, så kommer det att öppnas i ett redigeringsfönster där du kan förändra dess kod.

Exempel

Klicka på inspelningsknappen, ge den ett namn, låt oss säga "cylinder 10x10", skapa skapa sedan med Del arbetsbänken en cylinder med radien= 10 och höjden = 10. Klicka sedan på "stoppa inspelning" knappen. I redigera makro dialogen, så kan du se den python kod som har spelats in, och om du vill, göra ändringar på den. För att köra ditt makro, klicka på uppspelningsknappen i verktygslåden medan ditt makro är i redigeraren. Ditt makro sparas alltid till disk, så alla ändringar du gör, eller alla nya makron du skapar, kommer alltid att finnas tillgängliga nästa gång som du startar FreeCAD.

Anpassning

Det är förstås inte så praktiskt att behöva ladda ett makro i redigeraren för att kunna använda det. FreeCAD erbjuder många bättre sätt att använda ditt makro, som att tilldela en tangentbordsgenväg till den eller lägga till en punkt i menyn. När ditt makro är sparat, så kan allt detta göras via Verktyg -> Anpassa menyn:

Macros config.jpg

Pä detta sätt så kan du göra ditt makro till ett riktigt verktyg, precis som ett standardverktyg i FreeCAD . Detta, i tilläg till kraften hos pythonskripten i FreeCAD, gör det möjligt att lätt lägga till dina egna verktyg till gränssnittet. Läs vidare på Skript sidan om du vill veta mer om python skript...

Skapa makron utan inspelning

Du kan också direkt kopiera/klistra in python kod till ett makro, utan att behöva spela in aktioner i gränssnittet. Skapa bara ett nytt makro, redigera det, och klistra in din kod. Ditt makro sparas automatiskt när du stänger makroredigerings fönstret.

Makroförråd

Besök Makrorecept sidan för att hämta några användbara makron att lägga till din FreeCAD installation.

Links

Installing more workbenches.

Tutorials

How to install additional workbenches.



Introduktion till Python

(November 2018) FreeCAD was originally designed to work with Python 2. Many features work with Python 3, but some do not. Making FreeCAD fully support Python 3 is a work in process. The information here describes Python 2, but most of the code should work the same with Python 3. In particular, the print() function is preferred over the old print statement.


This is a short tutorial for those new to Python. Python is an open-source, multiplatform programming language. Python has several features that make it very different than other common programming languages, and very accessible to new users like yourself:

  • It has been designed specially to be easy to read by human beings, and so it is very easy to learn and understand.
  • It is interpreted, that is, unlike compiled languages like C, your program doesn't need to be compiled before it is executed. The code you write can be immediately executed, line by line if you wish. Because you can go slowly, step-by-step, it is extremely easy to learn and to find errors in your code.
  • It can be embedded in other programs to be used as scripting language. FreeCAD has an embedded Python interpreter; you can write Python code in FreeCAD, that will manipulate parts of FreeCAD, for example to create geometry. This is extremely powerful, instead of just clicking a button labeled "create sphere", that some programmer has coded; you have the freedom to easily build your own tool, creating exactly the geometry you want, in a manner or shape that the programmer may not foresee.
  • It is extensible, you can easily plug new modules in your Python installation and extend its functionality. For example, you have modules that allow Python to read and write jpg images, to communicate with twitter, to schedule tasks to be performed by your operating system, etc.

We strongly encourage you to enter the code snippets below into a Python interpreter. For many of our discussions, the important point is the line after the snippet is run, the reveal. Not running the code would be all build up, without a punch line. So, hands on! The following is a very simple introduction, and by no means a complete tutorial. But our hope is that this will provide enough basics to explore deeper into the FreeCAD mechanisms.

The interpreter

Usually, when writing computer programs, you simply open a text editor or your special programming environment, (which is usually a text editor with several additional tools) write your program, then compile and execute. Usually, one or more errors were made during entry, so your program won't work. You may even get an error message telling you what went wrong. Then you go back to your text editor, correct the mistakes, run again, repeating until your program works as intended.

That whole process, in Python, can be done transparently inside the Python interpreter. The interpreter is a Python window with a command prompt, where you can simply type Python code. If you install Python on your computer (download it from the Python website if you are on Windows or Mac, install it from your package repository if you are on GNU/Linux), you will have a Python interpreter in your start menu. But FreeCAD also has a Python interpreter in its lower window:

Screenshot pythoninterpreter.jpg

(If you don't have it, click on View --> Panels --> Python console.)

The interpreter shows the Python version, then a >>> symbol, which is the command prompt, that is, where you enter Python code. Writing code in the interpreter is simple: one line is one instruction. When you press Enter, your line of code will be executed (after being instantly and invisibly compiled). For example, try writing this:

print "hello"

print is a special Python keyword that means, obviously, to print something on the screen. When you press Enter, the operation is executed, and the message "hello" is printed. If you make an error, for example let's write:

print hello

Python will tell us that it doesn't know what hello is. The " characters specify that the content is a string, which is simply, in programming jargon, a piece of text. Without the ", the print command believed hello was not a piece of text but a special Python keyword. The important thing is, you immediately get notified that you made an error. By pressing the up arrow (or, in the FreeCAD interpreter, CTRL+up arrow), you can go back to the last command you wrote and correct it.

The Python interpreter also has a built-in help system. Try typing:

help

or, for example, let's say we don't understand what went wrong with our print hello command above, we want specific information about the "print" command:

help("print")

You'll get a long and complete description of everything the print command can do.

Now that we totally dominate our interpreter, we can begin with the serious stuff.

Variables

Of course, printing "hello" is not very interesting. More interesting is printing stuff you didn't know before, or let Python find for you. That's where the concept of the variable comes in. A variable is simply a value that you store under a name. For example, type this:

a = "hello"
print a

I guess you understood what happened, we "saved" the string "hello" under the name "a." Now, "a" is not an unknown name any more! We can use it anywhere, for example in the print command. We can use any name we want, just follow some simple rules, like not using spaces or punctuation. For example, we could write:

hello = "my own version of hello"
print hello

See? now hello is not an undefined word any more. What if, by terrible bad luck, we choose a name that already exists in Python? Let's say we want to store our string under the name "print":

print = "hello"

Python is very intelligent and will tell us that this is not possible. It has some "reserved" keywords that cannot be modified. But our variables can be modified any time, that's why they are called variables, the contents can vary. For example:

myVariable = "hello"
print myVariable
myVariable = "good bye"
print myVariable

We changed the value of myVariable. We can also copy variables:

var1 = "hello"
var2 = var1
print var2

Note that it is important to give meaningful names to your variables. After a while you won't remember what your variable named "a" represents. But if you named it, for example myWelcomeMessage, you'll easily remember its purpose. Plus your code is a step closer to being self-documenting.

Case is very important. myVariable is not the same as myvariable, the difference in the upper/lower case v. If you were to enter print myvariable it would come back with an error as not defined.

Numbers

Of course you must know that programming is useful to treat all kinds of data, and especially numbers, not only text strings. One thing is important, Python must know what kind of data it is dealing with. We saw in our print hello example, that the print command recognized our "hello" string. That is because by using the ", we told specifically the print command what follows next is a text string.

We can always check the data type of a variable with the special Python keyword type:

myVar = "hello"
type(myVar)

It will tell us the contents of myVar is 'str', short for string in Python jargon. We have also other basic types of data, such as integer and float numbers:

firstNumber = 10
secondNumber = 20
print firstNumber + secondNumber
type(firstNumber)

This is much more interesting, isn't it? Now we have a powerful calculator! Look at how well it worked, Python knows that 10 and 20 are integer numbers. So they are stored as "int", and Python can do with them everything it can do with integers. Look at the results of this:

firstNumber = "10"
secondNumber = "20"
print firstNumber + secondNumber

See? We forced Python to consider that our two variables are not numbers but mere pieces of text. Python can add two pieces of text together, but it won't try to find out any sum. But we were talking about integer numbers. There are also float numbers. The difference is that integer numbers don't have decimal part, while float numbers can have a decimal part:

var1 = 13
var2 = 15.65
print "var1 is of type ", type(var1)
print "var2 is of type ", type(var2)

Int and Floats can be mixed together without problem:

total = var1 + var2
print total
print type(total)

Of course the total has decimals, right? Then Python automatically decided that the result is a float. In several cases such as this one, Python automatically decides what type to use. In other cases it doesn't. For example:

varA = "hello 123"
varB = 456
print varA + varB

This will give us an error, varA is a string and varB is an int, and Python doesn't know what to do. However, we can force Python to convert between types:

varA = "hello"
varB = 123
print varA + str(varB)

Now both are strings, the operation works! Note that we "stringified" varB at the time of printing, but we didn't change varB itself. If we wanted to turn varB permanently into a string, we would need to do this:

varB = str(varB)

We can also use int() and float() to convert to int and float if we want:

varA = "123"
print int(varA)
print float(varA)

Note on Python commands

You must have noticed that in this section we used the print command in several ways. We printed variables, sums, several things separated by commas, and even the result of other Python command such as type(). Maybe you also saw that doing those two commands,

type(varA)
print type(varA)

have exactly the same result. That is because we are in the interpreter, and everything is automatically printed. When we write more complex programs that run outside the interpreter, they won't print automatically, so we'll need to use the print command. From now on, let's stop using it here, it'll go faster. So we can simply write:

myVar = "hello friends"
myVar

You must have seen that most of the Python commands (or keywords) type(), int(), str(), etc. have parenthesis to limit the command contents. The only exception is the print command, which in fact is not really an exception, as it also works normally: print("hello"). However, since it is used often, the Python designers allowed a simpler version.

Lists

Another interesting data type is a list. A list is simply a collection of other data. The same way that we define a text string by using " ", we define a list by using [ ]:

myList = [1,2,3]
type(myList)
myOtherList = ["Bart", "Frank", "Bob"]
myMixedList = ["hello", 345, 34.567]

You see that it can contain any type of data. Lists are very useful because you can group variables together. You can then do all kinds of things within that group, for example counting them:

len(myOtherList)

or retrieving one item of a list:

myName = myOtherList[0]
myFriendsName = myOtherList[1]

You see that while the len() command returns the total number of items in a list, their "position" in the list begins with 0. The first item in a list is always at position 0, so in our myOtherList, "Bob" will be at position 2. We can do much more with lists, you can read here, such as sorting contents, removing or adding elements.

A funny and interesting thing: a text string is very similar to a list of characters! Try doing this:

myvar = "hello"
len(myvar)
myvar[2]

Usually, what you can do with lists can also be done with strings. In fact both lists and strings are sequences.

Outside strings, ints, floats and lists, there are more built-in data types, such as dictionaries, or you can even create your own data types with classes.

Indentation

One big cool use of lists is also browsing through them and do something with each item. For example look at this:

alldaltons = ["Joe", "William", "Jack", "Averell"]
for dalton in alldaltons:
   print dalton + " Dalton"

We iterated (programming jargon) through our list with the "for ... in ..." command and did something with each of the items. Note the special syntax: the for command terminates with : indicating the following will be a block of one of more commands. In the interpreter, immediately after you enter the command line ending with :, the command prompt will change to ... which means Python knows that a colon (:) ended line has happened and more is coming.

How will Python know how many of the next lines will be to be executed inside the for...in operation? For that, Python uses indentation. That is, your next lines won't begin immediately. You will begin them with a blank space, or several blank spaces, or a tab, or several tabs. Other programming languages use other methods, like putting everything inside parenthesis, etc. As long as you write your next lines with the same indentation, they will be considered part of the for-in block. If you begin one line with 2 spaces and the next one with 4, there will be an error. When you finished, just write another line without indentation, or simply press Enter to come back from the for-in block

Indentation is cool because it aids in program readability. If you use large indentations (for example use tabs instead of spaces because it's larger), when you write a big program you'll have a clear view of what is executed inside what. We'll see that commands other than for-in, can have indented blocks of code too.

For-in commands can be used for many things that must be done more than once. It can, for example, be combined with the range() command:

serie = range(1,11)
total = 0
print "sum"
for number in serie:
   print number
   total = total + number
print "----"
print total

(If you have been running the code examples in an interpreter by Copying and Pasting, you will find the previous block of text will throw an error. Instead, copy to the end of the indented block, i.e. the end of the line total = total + number and then paste to the interpreter. In the interpreter issue an <enter> until the three dot prompt disappears and the code runs. Then copy the final two lines into the interpreter followed by one or more <enter> The final answer should appear.)

If you would type into the interpreter help(range) you would see:

range(...)
    range(stop) -> list of integers
    range(start, stop[, step]) -> list of integers

Here the square brackets denote an optional parameter. However all are expected to be integers. Below we will force the range parameters to be an integer using int()

decimales = 1000                     # for 3 decimales 
#decimales = 10000                   # for 4 decimales ...
for i in range(int(0 * decimales),int(180 * decimales),int(0.5 * decimales)):
    print float(i) / decimales

Or more complex things like this:

alldaltons = ["Joe", "William", "Jack", "Averell"]
for n in range(4):
   print alldaltons[n], " is Dalton number ", n

You see that the range() command also has that strange particularity that it begins with 0 (if you don't specify the starting number) and that its last number will be one less than the ending number you specify. That is, of course, so it works well with other Python commands. For example:

alldaltons = ["Joe", "William", "Jack", "Averell"]
total = len(alldaltons)
for n in range(total):
   print alldaltons[n]

Another interesting use of indented blocks is with the if command. If executes a code block only if a certain condition is met, for example:

alldaltons = ["Joe", "William", "Jack", "Averell"]
if "Joe" in alldaltons:
   print "We found that Dalton!!!"

Of course this will always print the first sentence, but try replacing the second line by:

if "Lucky" in alldaltons:

Then nothing is printed. We can also specify an else: statement:

alldaltons = ["Joe", "William", "Jack", "Averell"]
if "Lucky" in alldaltons:
   print "We found that Dalton!!!"
else:
   print "Such Dalton doesn't exist!"

Functions

There are few standard Python commands. In the current version of Python, there are about 30, and we already know several of them. But imagine if we could invent our own commands? Well, we can, and it's extremely easy. In fact, most the additional modules that you can plug into your Python installation do just that, they add commands that you can use. A custom command in Python is called a function and is made like this:

def printsqm(myValue):
   print str(myValue)+" square meters"
 
printsqm(45)

(Another copy and paste error, only copy through the end of the indented section i.e. " square meters" Paste to the interpreter, and issue <enter> until the three dot prompt goes a way, then copy and paste the final line.)

Extremely simple: the def() command defines a new function. You give it a name, and inside the parenthesis you define arguments that we'll use in our function. Arguments are data that will be passed to the function. For example, look at the len() command. If you just write len() alone, Python will tell you it needs an argument. That is, you want len() of something, right? Then, for example, you'll write len(myList) and you'll get the length of myList. Well, myList is an argument that you pass to the len() function. The len() function is defined in such a way that it knows what to do with what is passed to it. Same as we did here.

The "myValue" name can be anything, and it will be used only inside the function. It is just a name you give to the argument so you can do something with it, but it also serves to tell the function how many arguments to expect. For example, if you do this:

printsqm(45,34)

There will be an error. Our function was programmed to receive just one argument, but it received two, 45 and 34. We could instead do something like this:

def sum(val1,val2):
   total = val1 + val2
   return total

sum(45,34)
myTotal = sum(45,34)

We made a function that receives two arguments, sums them, and returns that value. Returning something is very useful, because we can do something with the result, such as store it in the myTotal variable. Of course, since we are in the interpreter and everything is printed, doing:

sum(45,34)

will print the result on the screen, but outside the interpreter, since there is no print command inside the function, nothing would appear on the screen. You would need to:

print sum(45,34)

to have something printed. Read more about functions here.

Modules

Now that we have a good idea of how Python works, we'll need one last thing: How to work with files and modules.

Until now, we wrote Python instructions line by line in the interpreter, right? What if we could write several lines together, and have them executed all at once? It would certainly be handier for doing more complex things. And we could save our work too. Well, that too, is extremely easy. Simply open a text editor (such as the windows notepad, Linux gedit, emacs, or vi), and write all your Python lines, the same way as you write them in the interpreter, with indentations, etc. Then, save that file somewhere, preferably with a .py extension. That's it, you have a complete Python program. Of course, there are much better editors than notepad, but it is just to show you that a Python program is nothing else than a text file.

To make Python execute that program, there are hundreds of ways. In windows, simply right-click your file, open it with Python, and execute it. But you can also execute it from the Python interpreter itself. For this, the interpreter must know where your .py program is. In FreeCAD, the easiest way is to place your program in a place that FreeCAD's Python interpreter knows by default, such as FreeCAD's bin folder, or any of the Mod folders. (In Linux, you probably have a directory /home/<username>/.FreeCAD/Mod, let's add a subdirectory to that called scripts where we will put the text file.) Suppose we write a file like this:

def sum(a,b):
    return a + b

print "myTest.py succesfully loaded"

and we save it as myTest.py in our FreeCAD/bin directory (or on Linux to /home/<username>/.FreeCAD/Mod/scripts.) Now, let's start FreeCAD, and in the interpreter window, write:

import myTest

without the .py extension. This will simply execute the contents of the file, line by line, just as if we had written it in the interpreter. The sum function will be created, and the message will be printed. There is one big difference: the import command is made not only to execute programs written in files, like ours, but also to load the functions inside, so they become available in the interpreter. Files containing functions, like ours, are called modules.

Normally when we write a sum() function in the interpreter, we execute it simply like that:

sum(14,45)

Like we did earlier. When we import a module containing our sum() function, the syntax is a bit different. We do:

myTest.sum(14,45)

That is, the module is imported as a "container", and all its functions are inside. This is extremely useful, because we can import a lot of modules, and keep everything well organized. So, basically, everywhere you see something.somethingElse, with a dot in between, that means somethingElse is inside something.

We can also import our sum() function directly into the main interpreter space, like this:

from myTest import *
sum(12,54)

Basically all modules behave like that. You import a module, then you can use its functions: module.function(argument). Almost all modules do that: they define functions, new data types and classes that you can use in the interpreter or in your own Python modules, because nothing prevents you from importing other modules inside your module!

One last extremely useful thing. How do we know what modules we have, what functions are inside and how to use them (that is, what kind of arguments they need)? We saw already that Python has a help() function. Doing:

help()
modules

Will give us a list of all available modules. We can now type q to get out of the interactive help, and import any of them. We can even browse their content with the dir() command

import math
dir(math)

We'll see all the functions contained in the math module, as well as strange stuff named __doc__, __file__, __name__. The __doc__ is extremely useful, it is a documentation text. Every function of (well-made) modules has a __doc__ that explains how to use it. For example, we see that there is a sin function in side the math module. Want to know how to use it?

print math.sin.__doc__

(It may not be evident, but on either side of doc are two underscore characters.)

And finally one last little goodie: When we work on a new or existing module, it's best to replace the file extension with py such as: myModule.FCMacro => myModule.py. We often want to test it so we will load it as above.

import myModule
myModule.myTestFunction()

But what if we see that myTestFunction() doesn't work correctly? We go back to our editor and make changes. Then, instead of closing and reopening the python interpreter, we can simply update the module like this:

reload(myModule)

This file renaming is because Python doesn't know about the extension FCMacro.

However, there are two alternates: Inside the one macro use Python's exec or execfile functions.

f = open("myModule","r")
d = f.read()
exec d

or

execfile "myModule"

For Python 3.xxx replace this code with:

exec(open("C:/PathToMyMacro/myMacro.FCMacro").read())

To share code across macros, you can access the FreeCAD or FreeCADGui module (or any other Python module) and set any attribute to it. This should survive the execution of the macro.

import FreeCAD
if hasattr(FreeCAD,"macro2_executed"):
    ...
else:
    FreeCAD.macro2_executed = True # you can assign any value because we only check for the existence of the attribute
    ... execute macro2

Starting with FreeCAD

Well, I think you now have a good idea of how Python works, and you can start exploring what FreeCAD has to offer. FreeCAD's Python functions are all well organized in different modules. Some of them are already loaded (imported) when you start FreeCAD. So, just do

dir()

and read on to FreeCAD Scripting Basics.

Of course, we saw here only a very small part of the Python world. There are many important concepts that we didn't mention. There are three very important Python reference documents on the net:

Be sure to bookmark them!



Python skript i FreeCAD

FreeCAD är byggt från grunden att helt och hållet kunna kontrolleras av python skript. Nästan alla delar av FreeCAD som gränssnittet, sceninnehållet, och även representationen av detta innehåll i 3d vyerna kan kommas åt från den inbyggda pythontolken eller från dina egna skript. Resultatet av detta är att FreeCAD troligen är en av de mest anpassningsbara konstruktionsapplikationerna som finns idag.

I dess nuvarande läge, så har FreeCAD emellertid mycket få "nativa" kommandon för att interagera på dina 3D objekt, huvudsakligen därför att den fortfarande är i ett tidigt utvecklingsstadium, men också för att filosofin bakom den är mer att erbjuda en plattform för CAD utveckling än en skräddarsydd användarapplikation. Men lättheten med python skript inuti FreeCAD kommer troligen att hjälpa mycket för att snabbt se ny funktionalitet utvecklas av "expertanvändare", eller, typiskt, användare som kan lite pythonprogrammering, som, hoppas vi, du själv.

Om du inte kan något om python, så rekommenderar vi att du letar efter övningar på internet, och tar en snabbtitt på dess struktur. Python är ett mycket lättlärt språk, speciellt eftersom det kan köras inuti en tolk, där allt från enkla kommandon till kompletta program kan köras direkt, utan något bahov för kompilering. FreeCAD har en inbyggd tolk. Om du inte ser fönstret "Rapportvy", som visas nedan, så kan du få fram den genom att klicka på Vy -> Vyer -> Rapportvy.

Tolken

Från tolken så har du åtkomst till alla dina systeminstallerade pythonmoduler, såväl som FreeCAD's inbyggda moduler, och alla extra FreeCAD moduler som du installerat senare. Skärmdumpen nedan visar python tolken:

FreeCAD python tolken

Från tolken kan du köra pythonkod, lista igenom tillgängliga klasser och funktioner. FreeCAD erbjuder en väldigt smidig klasslistare för utforskning av din nya FreeCAD värld: När du skriver namnet på en känd klass följt av en punkt (vilket innebär att du vill addera något från den klassen), så öppnas en klasslistare, där du kan navigera mellan tillgängliga underklasser och metoder. När du väljer något, så visas en associerad hjälptext (om den finns):

FreeCAD klasslistare

Så, starta här genom att skriva App. eller Gui. och se vad som händer. Ett annat mer allmänt python-sätt att utforska modul- och klassinnehåll är att använda print dir() kommandot. Till exempel, genom att skriva print dir() så kommer alla moduler som för närvarande är laddade i FreeCAD att listas. print dir(App) kommer att visa dig allt inuti App modulen, etc.

En annan användbar egenskap hos tolken är möjligheten att backa i kommandohistorian och hämta en kod-rad som du skrivit tidigare. För att navigera i kommandohistorian, använd CTRL+UPP-PIL eller CTRL+NED-PIL.

Genom att högerklicka i tolkfönstret, så har du flera andra alternativ, som att kopiera hela historian (användbart för att göra en experimentskript, och sedan kunna spara det), eller att sätta in ett filnamn med full sökväg.

Python Hjälp

I FreeCAD Hjälpmenyn, så hittar du en menypunkt som heter "Python hjälp", vilken kommer att öppna ett webbfönster som innehåller en komplett, realtidsgenererad dokumentation över alla python moduler som finns tillgänglig för FreeCAD tolken, inklusive python inbyggda FreeCAD moduler, system-installerade moduler, och extra FreeCAD moduler. Den dokumentation som fills tillgänglig där beror på hur mycket arbete varje modulutvecklare lägger på att dokumentera sin kod, men vanligtvis her pythonmoduler ett rykte om sig att vara ganska väldokumenterade. Ditt FreeCAD fönster måste vara öppet för att detta dokumentationssystem ska fungera.

Inbyggda moduler

Eftersom FreeCAD är designat för att kunna köras utan ett grafiskt användargränssnitt, så är nästan all dess funktionalitet uppdelat i två grupper: Kärnfunktioner, benämnda App, och gränssnittsfunktioner, benämnda Gui. Så våra två inbyggda FreeCAD huvudmoduler kallas för App och Gui. Dessa två moduler kan även kommas åt av skript utanför tolken, genom de respektive namnen FreeCAD och FreeCADGui.

  • I App modulen, så hittar du allt som är relaterat till själva applikationen, som metoder för att öppna eller stänga filer, och till dokumenten, som att ställa in det aktiva dokumentet eller lista dess innehåll.
  • I Gui modulen, så hittar du verktyg för åtkomst och hantering av gränssnittselement, som arbetsbänkarna och dears verktygslådor, och mer intressant, den grafiska representationen av allt FreeCAD innehåll.

Att lista allt innehåll av dessa moduler är en lite improduktiv uppgift, eftersom de växer ganska snabbt tillsammans med FreeCAD's utveckling. Men de två erbjudna listverktygen (klasslistaren och python hjälpen) ska alltid ge dig en komplett och uppdaterad dokumentation av dessa moduler.

App och Gui objekten

Som vi sade, så är allt i FreeCAD uppdelat mellan kärna och representation. Detta inkluderar även 3D objekten. Du kan komma åt objektens definierande egenskaper (kallade features i FreeCAD) via App modulen, och ändra det sätt som de representeras på skärmen via Gui modulen. Till exempel, en kub har egenskaper som definierar den, som bredd, längd, höjd som sparas i ett App objekt, och representationsegenskaper, som ytfärg, ritläge, som lagras i ett motsvarande Gui objekt.

Detta sätt att göra det på tillåter ett mycket brett användningsområde, som att låta algoritmer endast arbeta på den definierande delen av objekten, utan att behöva bry sig om någon visuell del, eller även att skicka dokumentets innehåll till icke-grafiska applikationer, som listor, räkneark eller elementanalyser.

För varje App objekt i ditt dokument, så existerar det ett motsvarande Gui objekt. Själva dokumentet har faktiskt också ett App och ett Gui objekt. Detta är förstås endast giltigt när du kör FreeCAD med dess fulla gränssnitt. I kommando-linje versionen, så existerar inget gränssnitt, så endast App objekt är tillgängliga. Notera att Gui delen av objekt genereras igen varje gång som ett App objekt är markerat som "att omberäknas" (till exempel när en av dess parametrar har ändrats), så ändringar som du har gjort direkt på Gui objektet kan förloras.

För att komma åt App delen av något, så skriver du:

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

där "ObjektNamn är namnet på ditt objekt. Du kan också skriva:

myObject = App.ActiveDocument.ObjectName

För att komma åt Gui delen av samma objekt, skriv:

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

där "ObjektNamn är namnet på ditt objekt. Du kan också skriva:

myViewObject = App.ActiveDocument.ObjectName.ViewObject

Om vi inte har något gränssnitt (vi är till exempel i kommandoradsläge), så kommer den sista raden att returnera None.

Dokument objekten

I FreeCAD så finns allt ditt arbete i Dokument. Ett dokument innehåller din geometri och kan sparas till en fil. Flera dokument kan öppnas samtidigt. Dokumentet, som geometrin som finns i den, har App och Gui objekt. App objekt innehåller dina geometridefinitioner, medan Gui objekt innehåller ditt dokuments olika vyer Du kan öppna flera fönster, där varje fönster visar ditt arbete med en annan zoomfaktor eller synvinkel. Dessa vyer är en del av Gui objektet i ditt dokument.

För att komma åt App delen i det aktiva dokumentet, skriv:

myDocument = App.ActiveDocument

För att skapa ett nytt dokument, skriv:

myDocument = App.newDocument("Document Name")

För att komma åt Gui delen i det aktiva dokumentet, skriv:

myGuiDocument = Gui.ActiveDocument

För att komma åt nuvarande vy, skriv:

myView = Gui.ActiveDocument.ActiveView

Using additional modules

The FreeCAD and FreeCADGui modules are solely responsibles for creating and managing objects in the FreeCAD document. They don't actually do anything such as creating or modifying geometry. That is because that geometry can be of several types, and so it is managed by additional modules, each responsible for managing a certain geometry type. For example, the Part Module uses the OpenCascade kernel, and therefore is able to create and manipulate B-rep type geometry, which is what OpenCascade is built for. The Mesh Module is able to build and modify mesh objects. That way, FreeCAD is able to handle a wide variety of object types, that can all coexist in the same document, and new types could be added easily in the future.

Creating objects

Each module has its own way to treat its 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:

FreeCAD.ActiveDocument.supportedTypes()

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

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

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, myMesh has a "Mesh" property and "Part" 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:

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

You could try storing the cube inside the Mesh property of the myMesh object, it will return an error complaining of the wrong type. That is because those properties are made to store only a certain type. In the myMesh's 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:

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

Modifying objects

Modifying an object is done the same way:

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

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

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

Querying objects

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

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

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

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

Now you can really start playing with FreeCAD! To look at what you can do with the Part Module, read the Part scripting page, or the Mesh Scripting page for working with the Mesh Module. Note that, although the Part and Mesh modules are the most complete and widely used, other modules such as the Draft Module also have scripting APIs that can be useful to you. For a complete list of each modules and their available tools, visit the Category:API section.



Introduktion

Först av allt så måste du importera Nätmodulen:

import Mesh

Efter det så har du åtkomst till Nätmodulen och Nätklassen Mesh class som ger åtkomst till funktionerna i FreeCAD's C++ Mesh-Kernel.

Skapande och laddning

För att skapa ett tomt nätobjekt använd standardkonstruktören:

mesh = Mesh.Mesh()

Du kan också skapa ett objekt från en fil

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

Vilka filformat du kan använda för att bygga upp ett nät är här.

Eller skapa det från ett set av trianglar, beskrivna av dess hörnpunkter:

planarMesh = [
# 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],
]
planarMeshObject = Mesh.Mesh(planarMesh)
Mesh.show(planarMeshObject)

Mesh-Kernel tar hand om skapandet av en topologiskt korrekt datastruktur genom att sortera sammanfallande punkter och kanter tillsammans.

Senare kommer du att se hur du kan testa och undersöka nät data.

Modellering

För att skapa reguljärageometrier så kan du används Python skriptet BuildRegularGeoms.py.

import BuildRegularGeoms

Detta skript ger metoder att definiera enkla rotationskroppar som sfärer, ellipsoider, cylindrar, toroider och koner. Och det har även en metod för att skapa en enkel kub.

För att till exempel skapa en toroid, så kan du göra enligt följande:

t = BuildRegularGeoms.Toroid(8.0, 2.0, 50) # list with several thousands triangles
m = Mesh.Mesh(t)

De första två parametrarna definierar toroidens radier och den tredje parametern är en sub-sampling faktor för hur många trianglar som skapas. Ju högre värde på denna faktorn, desto jämnare blir kroppen.

Nät klassen har ett set med booleska funktioner som kan användas för modelleringsändamål. Den erbjuder förening, skärning och skillnad mellan två nätobjekt.

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

Slutligen, ett komplett exempel som beräknar skärningen mellan en sfär och en cylinder som skär sfären.

import Mesh, BuildRegularGeoms
sphere = Mesh.Mesh( BuildRegularGeoms.Sphere(5.0, 50) )
cylinder = Mesh.Mesh( BuildRegularGeoms.Cylinder(2.0, 10.0, True, 1.0, 50) )
diff = sphere
diff = diff.difference(cylinder)
d = FreeCAD.newDocument()
d.addObject("Mesh::Feature","Diff_Sphere_Cylinder").Mesh=diff
d.recompute()

Undersökning och testning

Skriv dina egna algoritmer

Exportera

Du kan även skriva nätet till en python modul:

m.write("D:/Develop/Projekte/FreeCAD/FreeCAD_0.7/Mod/Mesh/SavedMesh.py")
import SavedMesh
m2 = Mesh.Mesh(SavedMesh.faces)

Gränssnittsrelaterade saker

Special

En extensiv, fast svåranvänd, källa för Nätrelaterade skript är Nätmodulens enhetstestskript. I detta enhetstest så kallas samtliga metoder och samtliga egenskaper/attribut ändras. Så om du är tillräckligt modig, ta en titt på Unit Test module.

See also Mesh API


Base ExampleCommandModel.png Tutorial

Topic
Programming
Level
Intermediate
Time to complete
Author
FreeCAD version
Example File(s)



This page describes several methods for creating and modifying Part shapes from python. Before reading this page, if you are new to python, it is a good idea to read about python scripting and how python scripting works in FreeCAD.

Introduktion

Här kommer vi att förklara hur du kontrollerar Del Modulen direkt från FreeCADs python tolk, eller från ett externt skript. Titta igenom Skript avsnittet och FreeCAD Skript grunder sidorna om du behöver mer information om hur python skript fungerar i FreeCAD.


För att kunna använda Delmodulens funktioner så måste du ladda Del modulen i tolken:

import Part

Klass Diagram

Detta är en UML översikt över de viktigaste klasserna i Del modulen:

Python klasser i Del modulen

Geometri

De geomtriska objekten är byggblocken för alla topologiska objekt:

  • GEOM Basklass för geometriska objekt
  • LINE En rak linje i 3D, definierad av en start- och en slutpunkt
  • CIRCLE Cirkel eller cirkelsegment som definieras av en centrumpunkt, start- och en slutpunkt
  • ...... Och snart lite mer

Topologi

Följande topologiska datatyper finns tillgängliga:

  • COMPOUND En grupp av valfri typ av topologiska objekt.
  • COMPSOLID En kompositsolid är ett set av solider ihopkopplade genom dess ytor. Det expanderar begreppen WIRE och SHELL till solider.
  • SOLID En rymd som är begränsad av skal. Den är tredimensionell.
  • SHELL Ett set av ytor ihopkopplade genom dess kanter. Ett skal kan vara öppet eller slutet.
  • FACE I 2D så är det en del av ett plan; i 3D är det en del av en yta. Dess geometri är begränsad (trimmad) av konturer. Den är tvådimensionell.
  • WIRE Ett set av kanter som är ihopkopplade genom dess hörn. Det kan vara en öppen eller sluten kontur beroende på om kanterna är ihoplänkade eller inte.
  • EDGE Ett topologiskt element som motsvarar en begränsad kurva. En kant är vanligtvis begränsad av hörn. Det har en dimension.
  • VERTEX Ett topologiskt element som motsvarar en punkt. Dess dimension är noll.
  • SHAPE En allmän term som täcker allt ovan.

Exempel

Skapa simpel topologi

Wire


Vi ska nu skapa en topologi genom att konstruera den utifrån enklare geometri. Som ett studiefall så använder vi en del som syns i bilden vilken består av fyra hörn, två cirklar och två linjer.

Skapa Geometri

Först så måste vi skapa de distinkt geometriska delarna av denna tråd. Och vi måste ta hänsyn till att hörnen på de geometriska delarna är på samma position. Annars kanske vi inte kan koppla ihop de geometriska delarna till en topologi!

Så vi skapar punkterna först:

from FreeCAD import Base
V1 = Base.Vector(0,10,0)
V2 = Base.Vector(30,10,0)
V3 = Base.Vector(30,-10,0)
V4 = Base.Vector(0,-10,0)

Cirkelbåge

Circle


För att skapa en cirkelbåge så skapar vi en hjälppunkt och skapar cirkelbågen genom tre punkter:

VC1 = Base.Vector(-10,0,0)
C1 = Part.Arc(V1,VC1,V4)
# and the second one
VC2 = Base.Vector(40,0,0)
C2 = Part.Arc(V2,VC2,V3)

Linje

Line


Linjen kan skapas mycket lätt ur punkterna:

L1 = Part.LineSegment(V1,V2)
# and the second one
L2 = Part.LineSegment(V3,V4)

Note: in FreeCAD 0.16 Part.Line was used, for FreeCAD 0.17 Part.LineSegment has to be used

Sätta ihop allt

Det sista steget är att sätta ihop den geometriska grundelementen och baka en topologisk form:

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

Skapa ett prisma

Extrudera nu tråden i en riktning och skapa en äkta 3D form:

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

Show it all

Part.show(P)

Skapa grundtyper

Kort beskrivning

Du kan lätt skapa enkla topologiska objekt med "make...()" metoden från Del Modulen:

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

Några andra make...() metoder fom finns:

  • makeBox(l,w,h,[p,d]) -- Skapa en låda placerad i p och pekar i riktningen d med dimensionerna (l,w,h). Som standard är p Vektor(0,0,0) och d är Vektor(0,0,1)
  • makeCircle(radius,[p,d,angle1,angle2]) -- Skapa en cirkel med en given radie. Som standard är p Vektor(0,0,0), d är Vektor(0,0,1) angle1=0 och angle2=360
  • makeCompound(list) -- Skapar en compound från en lista med former (shapes)
  • makeCone(radius1,radius2,height,[p,d,angle]) -- Skapa en kon med given radie och höjd. Som standard är p Vektor(0,0,0), d är Vektor(0,0,1) och angle=360
  • makeCylinder(radius,height,[p,d,angle]) -- Skapa en cylinder med given radie och höjd. Som standard är p Vektor(0,0,0), d är Vektor(0,0,1) och angle=360
  • makeLine((x1,y1,z1),(x2,y2,z2)) -- Skapa en linje mellan två punkter
  • makePlane(length,width,[p,d]) -- Skapa ett plan med längd och bredd. med given radie och höjd. Som standard är p Vektor(0,0,0), och d är Vektor(0,0,1)
  • makePolygon(list) -- Skapa en polygon från en lista med punkter
  • makeSphere(radius,[p,d,angle1,angle2,angle3]) -- Skapa en sfär med given radie. Som standard är p Vektor(0,0,0), d Vektor(0,0,1), angle1=0, angle2=90 och angle3=360
  • makeTorus(radius1,radius2,[p,d,angle1,angle2,angle3]) -- Skapa en torus med given radie. Som standard är p Vektor(0,0,0), d Vektor(0,0,1), angle1=0, angle2=360 och angle3=360

See the Part API page for a complete list of available methods of the Part module.

Detaljerade förklaringar

Importera först följande:

import Part
from FreeCAD import Base

Creating 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:

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

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:

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

Hur skapar man en kant?

En kant är inget annat än en linje med två hörn:

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

Notera: Du kan inte skapa en kant som passerar två hörn.

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

Du kan hitta en kants längd och centrum så här:

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

Putting 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:

Part.show(edge)

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.

Hur skapar man en tråd?

en tråd kan skapas från en lista med kanter eller en lista med trådar:

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)

Part.show(wire3) kommer att visa fyra linjer som bildar en kvadrat:

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

Hur skapar man en yta?

Endast ytor som skapats av stängda trådar är giltiga.

I detta exempel, så är wire3 en stängd tråd men wire2 är inte det (se ovan)

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

Endast ytor har en area, inte trådar eller kanter.

Hur skapar man en cirkel?

circle = Part.makeCircle(radius,[center,dir_normal,angle1,angle2]) -- Skapa en cirkel med en given radie

Som standard är, center=Vektor(0,0,0), dir_normal=Vektor(0,0,1), angle1=0 och angle2=360.

En cirkel kan skapas så här:

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

Om du vill skapa den vid en viss position och med en viss riktning

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

cirkeln kommer att skapas med en distans 10 från nollpunkten i x och kommer att vara vänd mot x axeln.

Notera: makeCircle accepterar endast Base.Vector() men inte tupler.

Du kan också skapa en cirkelbåge genom att ge start- och slutvinkel:

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

Både arc1 och arc2 kommer tillsammans skapa en cirkel.

Vinklar ska anges i grader, om du har radianer, konvertera det genom att använda formeln:

Grader = radianer * 180/PI

eller genom att använda python's math modul (efter att du importerat math, förstås):

grader = math.degrees(radianer)

degrees = math.degrees(radians)

Hur skapar man en cirkelbåge längs punkter?

Olyckligtvis så finns det ingen makeArc funktion men vi har Part.Arc funktionen för att skapa en cirkelbåge längs tre punkter.

Det kan antas vara en cirkelbåge som förenar start- och slutpunkt genom mittenpunkten.

Part.Arc skapar ett arc objekt på vilken .toShape() måste kallas för att få kant objektet,

vilket i allmänhet skapas av makeLine eller makeCircle

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

Notera: Arc accepterar endast Base.Vector() för punkter men inte tupler.

arc_edge är vad vi vill ha, vilken vi kan visa med Part.show(arc_edge).

Om du vill ha en liten del av en cirkel som en cirkelbåge, så är det också möjligt:

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

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

Hur skapar man en polygon eller linje längs punkter?

En linje längs multipla punkter är inget annat än att skapa en tråd med multipla kanter.

makePolygon funktionen tar en lista med punkter och skapar en tråd längs dessa punkter:

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

Creating 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.)

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

Hur skapar man ett plan?

Ett plan är en platt yta, alltså en yta i 2D

makePlane(length,width,[start_pnt,dir_normal]) -- Skapa ett plan

Som standard start_pnt=Vector(0,0,0) och dir_normal=Vector(0,0,1).

dir_normal=Vector(0,0,1) kommer att skapa ett plan vinkelrätt mot z axeln.

dir_normal=Vector(1,0,0) kommer att skapa ett plan vinkelrätt mot x axeln:

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

BoundBox är en kub som omsluter planet med en diagonal som startar vid (3,0,0) och slutar vid (5,0,2).

Här ar BoundBox tjockleken i y axeln noll.

Notera: makePlane accepterar endast Base.Vector() för start_pnt och dir_normal men inte tupler

Hur skapar man en ellips?

För att skapa en ellips så finns det flera sätt:

Part.Ellipse()

Skapar en ellips med majorradie 2 och minorradie 1 med

centrum i (0,0,0)

Part.Ellipse(Ellipse)

skapa en kopia på den givna ellipsen

Part.Ellipse(S1,S2,Center)

Skapar en ellips centrerad på punkten Center, där ellipsens plan är definierad av Center, S1 och S2, dess majoraxel är definierad av Center och S1, dess majorradie är avståndet mellan Center och S1, och dess minorradie är avståndet mellan S2 och majoraxeln.

Part.Ellipse(Center,MajorRadius,MinorRadius)

Skapar en ellips med major och minor radierna MajorRadius och MinorRadius, och är placerad i det plan som definieras av Center och normalen (0,0,1)

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

I koden ovan så har vi gett S1, S2 och centrum. I likhet med Arc, så skapar Ellipse också ett ellipsobjekt men inte kant, så vi behöver konvertera den till en kant genom att använda toShape() för att visa den

Note: Arc accepterar endast Base.Vector() för punkter men inte tupler

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

För Ellipse konstruktören ovan så har vi gett center, MajorRadius och MinorRadius

Hur skapar man en Torus?

makeTorus(radius1,radius2,[pnt,dir,angle1,angle2,angle]) -- Skapa en torus med given radie och vinklar.

Som standard är pnt=Vector(0,0,0),dir=Vector(0,0,1),angle1=0,angle1=360 och angle=360

anse torus som en liten cirkel som sveper längs en stor cirkel:

radius1 den stora cirkelns radie, radius2 är den lilla cirkelns radie, pnt torusens centrum och dir är normalriktningen. angle1 och angle2 är vinklar i radianer för den lilla cirkeln, för att skapa en cirkelbåge den sista parametervinkeln är för att sektionera torusen:

torus = Part.makeTorus(10, 2)

Ovanstående kod kommer att skapa en torus med diametern 20(radie 10) och tjocklek 4(lilla cirkelradien 2)

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

Ovanstående kod kommer att skapa en bit av en torus

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

Ovanstående kod kommer att skapa en semi torus, endast den sista parametern är ändrad d.v.s. vinkeln och de kvarvarande vinklarna är standardvärden.


Genom att ge vinkeln 180 så kommer en halvtorus att skapas

Hur skapar man en låda eller en kub?

makeBox(length,width,height,[pnt,dir]) -- Skapar en låda placerad i pnt med dimensionerna (längd,bredd,höjd)

Som standard är pnt=Vektor(0,0,0) och dir=Vektor(0,0,1)

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

Hur skapar man en sfär?

makeSphere(radius,[pnt, dir, angle1,angle2,angle3]) -- Skapa en sför med given radie.

Som standard är pnt=Vektor(0,0,0), dir=Vektor(0,0,1), angle1=-90, angle2=90 och angle3=360.

angle1 och angle2 är sfärens vertikala minimum och maximum ,

angle3 sfärdiametern

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

Hur skapar men en Cylinder?

makeCylinder(radius,height,[pnt,dir,angle]) -- skapa en cylinder med given radie och höjd

Som standard är pnt=Vektor(0,0,0),dir=Vektor(0,0,1) och angle=360

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

Hur skapar man en Kon?

makeCone(radius1,radius2,height,[pnt,dir,angle]) -- skapa en kon med given radie och höjd

Som standard är pnt=Vector(0,0,0), dir=Vector(0,0,1) och angle=360

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

Modifying 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.

Transform operations

Translating 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:

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

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

Rotating a shape

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

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

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

Generic transformations with matrixes

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:

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

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:

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

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:

myShape.transformShape(myMat)

or

myShape.transformGeometry(myMat)

Scaling 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 can't use the transformShape, we must use transformGeometry():

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

Booleska Operationer

Hur klipper man ut en form från en annan?

cut(...)

Skillnaden mellan denna och en given topografisk form.

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

Hur får man det gemensamma mellan två former?

common(...)

Skärning mellan denna och en given topografisk form.

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

Hur förenar man två former?

fuse(...)

Förening av denna och en given topografisk form.

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

Hur man sektionerar en solid med given form?

section(...)

Sektionering av denna med en given topografisk form.


Kommer att returnera en skärningskurva, en compound med kanter

cylinder1 = Part.makeCylinder(3,10,Base.Vector(0,0,0),Base.Vector(1,0,0))
cylinder2 = Part.makeCylinder(3,10,Base.Vector(5,0,-5),Base.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>]

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":

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

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:

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

Utforska former

du kan lätt utforska den topologiska datastrukturen:

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

Genom att skriva in ovanstående rader i python tolken, kommer du att få en god förståelse av Del objektens struktur . Här skapade vårt makeBox() kommando en solid form. Denna solid, liksom alla Del solider, innehåller ytor. Ytor innehåller alltid trådar, vilka är listor på kanter som gränsar till ytan. Varje yta har exakt en stängd tråd. I tråden, så kan vi titta på varje kant separat, och inuti varje kant, så kan vi se hörnen. Raka kanter har förstås endast två hörn. Del Hörn är OCC former, men de har ett punktattribut vilket returnerar en snygg FreeCAD Vektor.

Utforska Kanter

I fallet Kanter, vilken är en godtycklig kurva, så är det mycket troligt att du vill göra en diskretisering. I FreeCAD så är kanterna parametriserade av dess längder. Det innebär att du kan gå en kant/kurva genom dess längd:

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

Nu kan du komma åt många av kantens egenskaper genom att använda längden som en position. Det betyder att om

kanten är 100mm lång så är startpositionen 0 och slutpositionen 100.

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)

Använda valet

Här ser vi nu hur vi kan använda det val som användaren gjorde i visaren.

Först av allt så skapar vi en låda och visar den i visaren

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

Välj nu några ytor eller kanter. Med detta skript kan du

iterera alla valda objekt och deras delelement:

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

Välj några kanter och detta skript kommer att beräkna längden:

length = 0.0
for o in Gui.Selection.getSelectionEx():
	for s in o.SubObjects:
		length += s.Length
print "Length of the selected edges:" ,length

OCC flaskan

Ett typiskt exempel som finns på OpenCasCade Startsida är hur man bygger en flaska.

Detta är en god övning även för FreeCAD. Du kan faktiskt följa vårt exempel nedan och OCC sidan samtidigt , du kommer att få en god förståelse om hur OCC strukturer är implementerade i FreeCAD.


Hela skriptet nedan är även inkluderat i FreeCAD installationen (i Mod/Part mappen) och kan anropas från python tolken genom att skriva:

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

Det kompletta skriptet

Här är det kompletta MakeBottle skriptet:

import Part, FreeCAD, math
from FreeCAD import Base

def makeBottle(myWidth=50.0, myHeight=70.0, myThickness=30.0):
   aPnt1=Base.Vector(-myWidth/2.,0,0)
   aPnt2=Base.Vector(-myWidth/2.,-myThickness/4.,0)
   aPnt3=Base.Vector(0,-myThickness/2.,0)
   aPnt4=Base.Vector(myWidth/2.,-myThickness/4.,0)
   aPnt5=Base.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=Base.Matrix()
   aTrsf.rotateZ(math.pi) # rotate around the z-axis
   
   aMirroredWire=aWire.transformGeometry(aTrsf)
   myWireProfile=Part.Wire([aWire,aMirroredWire])
   myFaceProfile=Part.Face(myWireProfile)
   aPrismVec=Base.Vector(0,0,myHeight)
   myBody=myFaceProfile.extrude(aPrismVec)
   myBody=myBody.makeFillet(myThickness/12.0,myBody.Edges)
   neckLocation=Base.Vector(0,0,myHeight)
   neckNormal=Base.Vector(0,0,1)
   myNeckRadius = myThickness / 4.
   myNeckHeight = myHeight / 10
   myNeck = Part.makeCylinder(myNeckRadius,myNeckHeight,neckLocation,neckNormal)	
   myBody = myBody.fuse(myNeck)
   
   faceToRemove = 0
   zMax = -1.0
   
   for xp in myBody.Faces:
       try:
           surf = xp.Surface
           if type(surf) == Part.Plane:
               z = surf.Position.z
               if z > zMax:
                   zMax = z
                   faceToRemove = xp
       except:
           continue
   
   myBody = myBody.makeFillet(myThickness/12.0,myBody.Edges)
   
   return myBody

el = makeBottle()
Part.show(el)

Detaljerad förklaring

import Part, FreeCAD, math
from FreeCAD import Base

Vi kommer förstås behöva Del modulen, men också FreeCAD.Base modulen, vilken innehåller grundläggande FreeCAD strukturer som vektorer och matriser.

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

Här definierar vi vår makeBottle funktion. Denna funktion kan anropas utan argument, som vi gjorde ovan, i vilket fall standardvärden för bredd, höjd, och tjocklek kommer att användas. Sedan så definierar vi ett par punkter som kommer att användas för att bygga vår grundprofil.

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

Här definierar vi själva geometrin: en cirkelbåge, gjord av 3 punkter, och två linjesegment, gjorda av 2 punkter.

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

Kommer du ihåg skillnaden mellan geometri och former? Här bygger vi former utifrån vår konstruktionsgeometri. 3 kanter (kanter kan vara raka eller krökta), sedan en tråd av dessa tre kanter.

aTrsf=Base.Matrix()
   aTrsf.rotateZ(math.pi) # rotate around the z-axis
   aMirroredWire=aWire.transformGeometry(aTrsf)
   myWireProfile=Part.Wire([aWire,aMirroredWire])

Tills nu så har vi bara byggt en halv profil. Lättare än att bygga hela profilen på samma sätt, så behöver vi bara spegla det vi har gjort, och limma ihop båda halvorna. Så vi skapar först en matris. En matris är ett mycket vanligt sätt att tillämpa omvandlingar på objekt i 3D världen, eftersom den i en struktur kan innehålla alla grundläggande omvandlingar som 3D objekt kan påtvingas (flytta, rotera och skala). Här, efter att vi skapat matrisen, så speglar vi den, och vi skapar en kopia av vår tråd med tillämpning av vår omvandlingsmatris. Vi har nu två trådar, och vi kan göra en tredje tråd från dem, eftersom trådar egentligen är listor med kanter.

myFaceProfile=Part.Face(myWireProfile)
   aPrismVec=Base.Vector(0,0,myHeight)
   myBody=myFaceProfile.extrude(aPrismVec)
   myBody=myBody.makeFillet(myThickness/12.0,myBody.Edges)

Nu när vi har en stängd tråd, så kan den omvandlas till en yta. När vi väl har en yta, så kan vi extrudera den. Genom att göra så, så skapar vi en solid. Sedan tillämpar vi en snygg liten fasning på vårt objekt för vi vill ha en bra design, eller hur?

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

När vår flaskas kropp är skapad, så behöver vi fortfarande skapa en hals. Så vi gör en ny solid, med en cylinder.

myBody = myBody.fuse(myNeck)

Ihopsmältningsoperationen, vilket i andra applikationer ibland kallas för förening, är mycket kraftfull. Den kommer att limma ihop det som behövs, och ta bort de delar som inte behövs.

return myBody

Sedan så får vi tillbaka vår Del solid som ett resultat av vår funktion. Denna Del solid, liksom andra Del former, kan tillskrivas ett objekt i ett FreeCAD dokument, med:

el = makeBottle()
Part.show(el)

eller, mer enkelt:

Box pierced

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.

import Draft, Part, FreeCAD, math, PartGui, FreeCADGui, PyQt4
from math import sqrt, pi, sin, cos, asin
from FreeCAD import Base

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 = FreeCAD.Matrix()
myMat.rotateZ(math.pi/2)
face2.transformShape(myMat)
face2.translate(FreeCAD.Vector(size, 0, 0))

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

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

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

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

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

mySolid = Part.makeSolid(myShell)
mySolidRev = mySolid.copy()
mySolidRev.reverse()

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

cut_part = mySolidRev.cut(myCyl)

Part.show(cut_part)

Ladda och spara

Det finns flera sätt att spara ditt arbetet i Del modulen. Du kan förstås spara ditt FreeCAD dokument, men du kan också spara Del objekt direkt till vanliga CAD format, som BREP, IGS, STEP och STL.

Att spara en form till en fil är lätt. det finns exportBrep(), exportIges(), exportStl() och exportStep() metoder tillgängliga för alla form objekt. Så genom att göra:

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

detta kommer att spara vår låda i en STEP fil. För att ladda en BREP, IGES eller STEP fil, gör bara motsatsen:

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

To convert an .stp file to an .igs file:

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

Notera att import eller öppning av BREP, IGES eller STEP filer även kan göras direkt via Fil -> Öppna eller Fil -> Importera menyn. För närvarande är export fortfarande inte möjligt den vägen, men ska vara det snart.



Konvertera Del objekt till Nät

Att konvertera högnivåobjekt som Del former till enklare objekt som nät är en ganska enkel operation, där alla ytor på ett Del objekt blir triangulerade. Resultatet av denna triangulering (tessellering) används sedan till att konstruera ett nät: (Låt oss anta att vårt dokument innehåller ett Del objekt)

#let's assume our document contains one part object
import Mesh
faces = []
shape = FreeCAD.ActiveDocument.ActiveObject.Shape
triangles = shape.tessellate(1) # the number represents the precision of the tessellation)
for tri in triangles[1]:
    face = []
    for i in range(3):
        vindex = tri[i]
        face.append(triangles[0][vindex])
    faces.append(face)
m = Mesh.Mesh(faces)
Mesh.show(m)

Ibland så är den triangulering av vissa ytor som erbjuds av OpenCascade ganska ful. Om ytan har en rektangulär parameterrymd och inte innehåller några hål eller andra trimkurvor så kan du också skapa ett eget Nät:

import Mesh
def makeMeshFromFace(u,v,face):
	(a,b,c,d)=face.ParameterRange
	pts=[]
	for j in range(v):
		for i in range(u):
			s=1.0/(u-1)*(i*b+(u-1-i)*a)
			t=1.0/(v-1)*(j*d+(v-1-j)*c)
			pts.append(face.valueAt(s,t))

	mesh=Mesh.Mesh()
	for j in range(v-1):
		for i in range(u-1):
			mesh.addFacet(pts[u*j+i],pts[u*j+i+1],pts[u*(j+1)+i])
			mesh.addFacet(pts[u*(j+1)+i],pts[u*j+i+1],pts[u*(j+1)+i+1])

	return mesh

Konvertera Nät till Del objekt

Konvertering av Nät till Del objekt är en mycket viktig operation i CAD arbete, eftersom du mycket ofta tar emot 3D data i nätformat från andra människor eller utmatade från andra applikationer. Nät är mycket praktiskt för att representera friformsgeometri och stora visuella scener, eftersom den är mycket kompakt, men för CAD föredrar vi i allmänhet mer högnivåobjekt som bär mycket mer information, som solider, eller ytor som är skapade av kurvor istället för trianglar.

Konvertering av nät till dessa högnivåobjekt (hanterat av Del Modulen i FreeCAD) är inte en lätt operation. Nät kan vara gjord av tusentals trianglar (till exempel när de är genererade av en 3D skanner), och att ha solider gjorda med samma antal ytor skulle bli väldigt tungrott att manipulera. Så generellt sett så vill du optimera objektet när du konverterar.

FreeCAD erbjuder för närvarande två metoder för att konvertera Nät till Del objekt. Den första metoden är en enkel, direkt konvertering, utan någon optimering:

import Mesh,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)

Den andra metoden erbjuder möjligheten att anse nätfasetter koplanära när vinkeln mellan dem är under ett visst värde. Detta tillåter uppbyggnad av mycket enklare former: (Låt oss anta att vårt dokument innehåller ett Nät objekt)

# let's assume our document contains one Mesh object
import Mesh,Part,MeshPart
faces = []
mesh = App.ActiveDocument.ActiveObject.Mesh
segments = mesh.getPlanes(0.00001) # use rather strict tolerance here
 
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))

shell=Part.Compound(faces)
Part.show(shell)
#solid = Part.Solid(Part.Shell(faces))
#Part.show(solid)


Arrow-left.svg Previous: Mesh to Part
Next: Pivy Arrow-right.svg

Den geometri som syns i FreeCAD's #D vyer är renderade av Coin3D biblioteket. Coin3D är en implementering av OpenInventor standarden. openCascade mjukvaran erbjuder också samma funktionalitet, men det beslöts när FreeCAD påbörjades att inte använda openCascade's inbyggda visare utan istället använda sig av den snabbare coin3D mjukvaran.

OpenInventor är egentligen ett 3D scen beskrivningsspråk. Den scen som beskrivs i renderas sedan av OpenGL på din skärm. Coin3D gör arbetet med detta, så programmeraren inte behöver bry sig om komplexa openGL anrop, programmeraren behöver bara förse den med giltig OpenInventor kod. Den stora fördelen är att openInventor är en mycket välkänd och väldokumenterad standard.

Ett av de stora jobben som FreeCAD gör för dig är att översätta openCascade geometriinformation till openInventor språket.

OpenInventor beskriver en 3D scen i formen av en scenegraph, som den nedan:

Scenegraph.gif image from Inventor mentor

En openInventor scengraf beskriver allt som utgör en 3D scen, som geometri, färger, material, ljus, etc, och organiserar all den data i smidig och klar struktur. Allting kan grupperas till sub-strukturer, vilket tillåter dig att organisera ditt sceninnehåll så som du vill. Här är ett exempel på en openInventor fil:

#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 {
       }
    }
}

Som du kan se, så är strukturen mycket simpel. Du använder separatorer för att organisera din data till block, lite som du skulle organisera dina filer i mappar. Varje uttryck påverkar vad som kommer härnäst, till exempel de första två punkterna i vår rot separator är en rotation och en förflyttning, båda kommer att påverka nästa punkt, vilken är en separator. I den separatorn, så är ett material definierat, och en annan förflyttning. Vår cylinder kommer därför att påverkas av båda förändringarna, den som vi lade direkt på den och den som vi lade på dess förälderseparator.

Vi har också många andra elementtyper för att organisera vår scen, som grupper, växlar eller annoteringar. Vi kan definiera mycket komplexa material för våra objekt, med färg, texturer, skugglägen och transparens. Vi kan också definiera ljus, kameror, och även rörelser. Det är även möjligt att bädda in skriptbitar i openInventor filer, för att definiera mer komplext beteende.

Om du är intresserad av att lära dig mer om openInventor, hoppa direkt till dess berömdaste referens, Inventor mentor.

I FreeCAD behöver vi normalt inte interagera direkt med scengrafen openInventor. Varje objekt i ett FreeCAD dokument, ett nät, en delform eller något annat, blir automatiskt konverterat till openInventor kod och insatt i huvudscengrafen som du ser i en 3D vy. Den scengrafen uppdateras kontinuerligt när du gör förändringar, lägger till eller tar bort objekt i dokumentet. Alla objekt (i App rymden) har en visare(ett motsvarande objekt i Gui rymden), som anvarar för att ge openInventor kod.

Men det finns många fördelar med att kunna komma åt scengrafen direkt. Vi kan till exempel temporärt ändra utseendet på ett objekt, eller vi kan lägga till objekt som inte har en reell existens i FreeCAD dokumentet, som till exempel konstruktionsgeometri, hjälpare, grafiska tips eller verktyg som manipulatorer eller information på skärmen.

Själva FreeCAD har flera verktyg för att se eller ändra openInventor kod. Till exempel, följande pythonkod kommer att visa openInventor representationen av ett valt objekt:

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

Men vi har också en python modul som tillåter komplett åtkomst till allt som hanterar av Coin3D, som vår FreeCAD scengraf. Så, läs vidare på Pivy.


Pivy är ett python bindnings bibliotek för Coin3d, det 3D-renderingsbibliotek som används av FreeCAD. när det importeras i en körande python tolk, så kan du föra en direkt dialog med alla körande scengrafer, som FreeCAD's 3D vyer, eller att även skapa nya. Pivy följer med i en standard FreeCAD installation.

Coin biblioteket är uppdelat i flera delar, själva coin, för manipulation av scengrafer och bindningar för flera GUI system, som windows, eller som i vårt fall, qt. Dessa moduler är även tillgängliga för pivy, beroende på om de finns i systemet. Coin modulen finns alltid, och det är vad vi kommer att använda i alla fall, eftersom vi inte behöver bry oss om att förankra vårt 3D fönster i något gränssnitt, det görs redan av FreeCAD själv. Allt vi behöver göra är detta:

from pivy import coin

Komma åt och ändra scengrafen

Vi såg i Scengraf sidan hur en typisk Coin scen är organiserad. Allt som syns i en FreeCAD 3D vy är en coin scengraf, organiserad på samma sätt. Vi har en rotnod, och alla objekt på skärmen är dess barn.

FreeCAD har ett lätt sätt att komma åt 3D vy scengrafens rotnod:

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

Detta kommer att returnera rotnoden:

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

Vi kan inspektera vår scen's närmaste barn:

for node in sg.getChildren():
    print node

En del av dessa noder, som SoSeparators eller SoGroups, kan själva ha barn. Den kompletta listan på de tillgängliga coin objekten kan återfinnas på official coin documentation.

Låt oss försöka lägga till något till vår scengraf nu. Vi lägger till en snygg röd kub:

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

och här är vår (snygga) röda kub. Låt os nu försöka detta:

col.rgb=(1,1,0)

Se? Allt är fortfarande åtkomligt och förändringsbart direkt. Inget behov av omberäkningar eller omritningar, coin tar hand om allt. Du kan lägga till saker till din scengraf, ändra egenskaper, gömma saker, visa temporära objekt, allting. Detta gäller förstås endast visningen i 3D vyn. Den visningen beräknas om av FreeCAD när filen öppnas, och när ett objekt behöver omberäknas. Så om du ändrar en aspekt på ett existerande FreeCAD objekt, så kommer dessa ändringar att förloras om objektet beräknas om eller när du öppnar filen igen.

En nyckel till arbete med scengrafer i dina skript är att kunna komma åt vissa egenskaper på de noder som du vid behov lägger till. Till exempel, om vi skulle vilja flytta vår kub, så skulle vil ha lagt till en SoTranslation nod till vår anpassade nod, och det skulle ha sett ut så här:

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

Kom ihåg att i en openInventor scengraf, så är ordningen viktig. en nod påverkar efterkommande saker, så du kan säga något som : färg röd, kub, färg gul, sfär, och du kommer att få en röd kub och en gul sfär. Om vi lade till förflyttning till vår existerande anpassade nod, så skulle den komma efter kuben, och inte påverka den. Om vi hade satt in den när vi skapade den, som här ovan, så skulle vi nu kunna göra:

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

Och vår kub skulle hoppa 2 enheter åt höger. Slutligen, att ta bort något görs med:

sg.removeChild(myCustomNode)

Använda återanropsmekanismer

En återanropsmekanism är ett system som tillåter ett bibliotek som du använder, som vårt coin bibliotek, att anropa tillbaka, vilket innebär att anropa en viss funktion från ditt för närvarande körande python objekt. Detta är väldigt användbart, därför att på det sättet så kan coin meddela python objektet om någon specifik händelse uppstår i scenen. Coin kan övervaka väldigt olika saker, som musposition, musklick, tangentbordsnedtryckningar, och många andra saker.

FreeCAD erbjuder ett lätt sätt att använda sådana återanrop:

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

Återanropet måste initieras från ett objekt, därför så måste det objektet fortfarande köras när återanropet uppstår.

Se även den kompletta listan för möjliga händelser och dess parametrar, eller i den officiella coin dokumentationen.

Dokumentation

Olyckligtvis har pivy själv ingen ordentlig dokumentation, men eftersom det är en riktig översättning av coin, så kan du med säkerhet använda coin dokumentationen som referens, och använda python stil istället för c++ stil (till exempel SoFile::getClassTypeId() skulle i pivy bli SoFile.getClassId())


PySide

PySide is a Python binding of the cross-platform GUI toolkit Qt. FreeCAD uses PySide for all GUI (Graphic User Interface) purposes inside of Python. PySide is an alternative to the PyQt package which was previously used by FreeCAD for its GUI. PySide has a more permissible licence. See Differences Between PySide and PyQt for more information on the differences.

Users of FreeCAD often achieve everything using the built-in interface. But for users who want to customise their operations then the Python interface exists which is documented in the Python Scripting Tutorial. The Python interface for FreeCAD had great flexibility and power. For its user interaction Python with FreeCAD uses PySide, which is what is documented on this page.

Python offers the 'print' statement which gives the code:

print 'Hello World'

With Python's print statement you have only limited control of the appearance and behaviour. PySide supplies the missing control and also handles environments (such as the FreeCAD macro file environment) where the built-in facilities of Python are not enough.

PySide's abilities range from:

PySideScreenSnapshot1.jpg

to:

PySideScreenSnapshot2.jpg

PySide is described in the following 3 pages which should follow on one from each other:

They divide the subject matter into 3 parts, differentiated by level of exposure to PySide, Python and the FreeCAD internals. The first page has overview and background material giving a description of PySide and how it is put together while the second and third pages are mostly code examples at different levels.

The intention is that the associated pages will provide simple Python code to run PySide so that the user working on a problem can easily copy the code, paste it into their own work, adapt it as necessary and return to their problem solving with FreeCAD. Hopefully they don't have to go chasing off across the internet looking for answers to PySide questions. At the same time this page is not intended to replace the various comprehensive PySide tutorials and reference sites available on the web.


Förutom standard objekttyper som annoteringar, nät och delobjekt, så erbjuder FreeCAD också den fantastiska möjligheten att bygga 100% python-skriptade objekt, som kallas för Python Funktioner. dessa objekt kommer att bete sig exakt som alla andra FreeCAD objekt, de kan sparas i ett dokument och öppnas av en annan FreeCAD installation, eftersom den python kod som definierar objektet även sparas i dokumentet.

One particularity must be understood, those objects are saved in FreeCAD FcStd files with python's json module. That module turns a python object as a string, allowing it to be added to the saved file. On load, the json module uses that string to recreate the original object, provided it has access to the source code that created the object. This means that if you save such a custom object and open it on a machine where the python code that generated the object is not present, the object won't be recreated. If you distribute such objects to others, you will need to distribute the python script that created it together.

Python Funktioner följer samma regler som alla FreeCAD funktioner: de är separerade i App och GUI delar. App delen, Dokumentobjektet, definierar vårt objekts geometri , medan dess gränssnittsdel, Visaobjektet, definierar hur objektet kommer att ritas på skärmen. VisaObjektet, är som alla andra FreeCAD funktioner, endast tillgängligt när du kör FreeCAD i dess eget gränssnitt. Det finns flera egenskaper och metoder tillgängliga för att bygga ditt objekt. Egenskaperna måste vara en av de fördefinierade egenskapstyperna som FreeCAD erbjuder, och kommer att visas i egenskapsfönstret, så de kan redigeras av användaren. på detta sätt så är Python Funktionsobjekt totalt parametrisk. Du kan definiera egenskaper för objektet och dess Visaobjekt separat.

Hint: In former versions we used Python's cPickle module. However, this module executes arbitrary code and thus causes a security problem. Thus, we moved to Python's json module.

Enkelt exempel

Följande exempel kan hittas i src/Mod/TemplatePyMod/FeaturePython.py filen, tillsammans med flera andra exempel:

'''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 __getstate__(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 __setstate__(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()

Tillgängliga egenskaper

Egenskaper är PythonFunktion objektens sanna byggstenar. Genom dem, så kan användaren interagera och ändra objektet. Efter att ett nytt PythonFunktion objekt har skapats i ditt dokument ( a=FreeCAD.ActiveDocument.addObject("App::FeaturePython","Box") ), så kan du få en lista på de tillgängliga egenskaperna genom att skriva:

obj.supportedProperties()

Du kommer att få en lista på tillgängliga egenskaper:

App::PropertyBool
App::PropertyBoolList
App::PropertyFloat
App::PropertyFloatList
App::PropertyFloatConstraint
App::PropertyQuantity
App::PropertyQuantityConstraint
App::PropertyAngle
App::PropertyDistance
App::PropertyLength
App::PropertySpeed
App::PropertyAcceleration
App::PropertyForce
App::PropertyPressure
App::PropertyInteger
App::PropertyIntegerConstraint
App::PropertyPercent
App::PropertyEnumeration
App::PropertyIntegerList
App::PropertyIntegerSet
App::PropertyMap
App::PropertyString
App::PropertyUUID
App::PropertyFont
App::PropertyStringList
App::PropertyLink
App::PropertyLinkSub
App::PropertyLinkList
App::PropertyLinkSubList
App::PropertyMatrix
App::PropertyVector
App::PropertyVectorList
App::PropertyPlacement
App::PropertyPlacementLink
App::PropertyColor
App::PropertyColorList
App::PropertyMaterial
App::PropertyPath
App::PropertyFile
App::PropertyFileIncluded
App::PropertyPythonObject
Part::PropertyPartShape
Part::PropertyGeometryList
Part::PropertyShapeHistory
Part::PropertyFilletEdges
Sketcher::PropertyConstraintList

När du adderar egenskaper till dina anpassade objekt, var uppmärksam på detta:

  • Använd inte tecknen "<" eller ">" i egenskapsbeskrivningen (det förstör xml delarna i .fcstd filen)
  • Egenskaper lagras i alfabetisk ordning i en .fcstd fil. Om du har en form i dina egenskaper, så kommer alla egenskaper vars namn kommer efter "Form" i alfabetisk ordning att laddas EFTER formen, vilket kan orsaka ett märkligt beteende.

Property Type

By default the properties can be updated. It is possible to make the properties read-only, for instance in the case one wants to show the result of a method. It is also possible to hide the property. The property type can be set using

obj.setEditorMode("MyPropertyName", mode)

where mode is a short int that can be set to:

 0 -- default mode, read and write
 1 -- read-only
 2 -- hidden

The EditorModes are not set at FreeCAD file reload. This could to be done by the __setstate__ 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 PropertyEditor. They could 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):

obj.addProperty("App::PropertyString","MyCustomProperty","","",8)

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


You can find these different property types defined in the source code C++ header for PropertyContainer

Andra mer komplexa exempel

Detta exempel använder sig av Del Modulen för att skapa en oktahedron, sedan skapas dess coin representation med pivy.

Det första är själva Dokument objektet:

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

Sedan så har vi visarobjektet, ansvarigt för att visa objektet i 3D scenen:

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

     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 __getstate__(self):
     return None

  def __setstate__(self,state):
     return None

Slutligen, när vårt objekt och dess visningsobjekt är definierade, så behöver vi bara anropa dem:

FreeCAD.newDocument()
a=FreeCAD.ActiveDocument.addObject("App::FeaturePython","Octahedron")
Octahedron(a)
ViewProviderOctahedron(a.ViewObject)

Göra objekt valbara

Om du vill göra ditt objekt valbart, eller åtminstone en del av den, genom att klicka på den i vyn, så måste du inkludera dess geometri inuti en SoFCSelection nod. Om ditt objekt har en komplex representation, med widgetar, annoteringar, etc, så kanske du bara vill inkludera en del av den i en SoFCSelection. Allt som är en SoFCSelection skannas konstant av FreeCAD för att detektera val/förval, så det är vettigt att inte försöka överbelasta den med onödig skanning. Detta är vad du skulle göra för att inkludera en self.face från det ovan visade exemplet:

selectionNode = coin.SoType.fromName("SoFCSelection").createInstance()
selectionNode.documentName.setValue(FreeCAD.ActiveDocument.Name)
selectionNode.objectName.setValue(obj.Object.Name) # here obj is the ViewObject, we need its associated App Object
selectionNode.subElementName.setValue("Face")
selectNode.addChild(self.face)
...
self.shaded.addChild(selectionNode)
self.wireframe.addChild(selectionNode)

Du skapar en SoFCSelection nod, sedan lägger du till dina geometrinoder till den, sedan lägger du till den till din huvudnod, istället för att lägga till dina geometrinoder direkt.

Arbeta med enkla former

Om ditt parametriska objektbara resulterar i en form, så behöver du inte använda ett visarobjekt. Formen kommer att visas med hjälp av FreeCAD's standard form representation:

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

Same code with use ViewProviderLine

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

- Python object attributes lost at load

- New FeaturePython is grey

- Eigenmode frequency always 0?

- how to implement python feature's setEdit properly?

In addition to the examples presented here have a look at FreeCAD source code src/Mod/TemplatePyMod/FeaturePython.py for more examples.



FreeCAD har den fantastiska förmågan att kunna importeras som en python modul i andra program eller i en python konsol, tilsammans med alla dess moduler och komponenter. Det är även möjligt att importera FreeCAD's gränssnitt som en python modul -- emellertid med några begränsningar.

Använda FreeCAD utan gränssnitt

En första, direkt, lätt och användbar sak du kan göra med detta är att importera FreeCAD dokument in till ditt program. I det följande exemplet, så kommer vi att importera Del geometrin i ett FreeCAD dokument till blender. Här är det kompletta skriptet. Jag hoppas att du kommer att bli imponerad av dess enkelhet:

FREECADPATH = '/opt/FreeCAD/lib' # path to your FreeCAD.so or FreeCAD.dll file
import Blender, sys
sys.path.append(FREECADPATH)
 
def import_fcstd(filename):
   try:
       import FreeCAD
   except ValueError:
       Blender.Draw.PupMenu('Error%t

Den första, viktiga delen är att försäkra sig om att python kan hitta vårt FreeCAD bibliotek. När den väl har hittats, så kommer alla FreeCAD moduler som Del, som vi kommer använda, automatiskat att vara tillgängliga. Så vi tar bara sys.path variabeln, vilket är var python söker efter moduler, och lägger till sökvägen till FreeCAD's bibliotek. Denna ändring är endast temporär, och kommer att förloras när vi stänger vår python tolk. Ett annat sätt kan vara att göra en länk till ditt FreeCAD bibliotek i en av python's sökvägar. Jag behöll sökvägen i en konstant (FREECADPATH) så att det blir lättare för en annan användare av skriptet att konfigurera den till sitt eget system.

När vi är säkra på att biblioteket är laddat(try/except sekvensen), så kan vi nu arbeta med FreeCAD, på samma sätt som vi skulle inuti FreeCAD's egen python tolk. Vi öppnar FreeCAD dokumentet som skickats till oss genom main() funktionen, och vi gör en lista på dess objekt. Sedan då vi valde att endast bry oss om Del geometri, så kontrollerar vi om varje objekts Typegenskap innehåller "Part", sedan tesselerar vi den.

Tesseleringen producerar en lista på hörn och en lista på ytor som definierats av hörnindexen. Detta är perfekt, eftersom det är på exakt samma sätt som blender definierar nät. Så vår uppgift är löjligt enkel, vi adderar bara båda listinnehållen till verts och faces av ett blender nät. När allting är gjort, så ritar vi bara om skärmen, och det är klart!

Detta skript är förstås mycket enkelt (det finns ett mer avancerat här), du kanske vill bygga ut det, för att till exempel importera nätobjekt också, eller importera Del geometri som inte har några ytor, eller importera andra filformat som FreeCAD kan läsa. Du kanske också vill exportera geometri till ett FreeCAD dokument, vilket kan göras på samma sätt. Du kanske också vill bygga en dialog, så att användaren kan välja vad som ska importeras, etc... Skönheten i allt detta ligger i det faktum att du låter FreeCAD göra grundarbetet medan du presenterar dess resultat i ett program som du väljer.

Använda FreeCAD med gränssnitt

Från och med version 4.2 så har Qt den fängslande förmågan att inbädda Qt-gränssnitt-beroende plugins till icke-Qt värdapplikationer och dela värdens händelseslinga.

Speciellt för FreeCAD så betyder detta att den kan importeras från en annan applikation med hela gränssnittet där värdapplikationen har full kontroll över FreeCAD.

Hela python koden för att uppnå detta har bara två rader

import FreeCADGui 
FreeCADGui.showMainWindow()

Om värdapplikationen är baserad på Qt så ska denna lösningen fungera på alla plattformar som Qt stöder. emellertid så ska värden länka samma Qt version som FreeCAD, annars såkan du få oväntade fel.

Men för icke-Qt applikationer så finns det en del begränsningar som du måste vara uppmärksam på. Denna lösning fungerar troligen inte tillsammans med alla andra verktygskiten.

I Windows så fungerar det så länge som värdapplikationen är direkt baserad på Win32 eller något annat verktygskit som internt använder Win32 API som wxWidgets, MFC eller WinForms. för att få det att fungera under X11 så måste värdapplikationen länka till "glib" biblioteket.

Notera att för konsolapplikationer fungerar inte denna lösning eftersom det inte finns någon händelseslinga som körs.

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:

>>> 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)]'



Base ExampleCommandModel.png Tutorial

Topic
Python
Level
Beginner
Time to complete
Author
FreeCAD version
Example File(s)


Denna sida innehåller exempel, delar, bitar av FreeCAD pythonkod som samlats ihop från användare och diskussioner på forumen. Läs och använd dem som en början för dina egna skript...

En typisk InitGui.py fil

Varje modul måste innehålla, förutom din huvudmodul fil, en InitGui.py fil, som ansvarar för insättningen av modulen i huvudgränssnittet. Detta är ett exempel på en enkel sådan.

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

En typisk modulfil

Detta är ett exempel på en huvudmodulfil, som innehåller allt som din modul gör. Det är Scripts.py filen startad i föregående exempel. Du kan ha alla dina anpassade kommandon här.

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

Importera en ny filtyp

Att skapa en importerare för en ny filtyp i FreeCAD är lätt. FreeCAD anser inte att du importerar data i ett öppnat dokument, utan snarare att du direkt kan öppna den nya filtypen. Så vad du behöver göra är att lägga till den nya filtypen till FreeCAD's lista på kända filtyper, och skriva koden som kommer att läsa filen och skapa de FreeCAD objekt som du vill:

Denna rad måste läggas till i InitGui.py filen för att lägga till den nya filtypen till listan:

# 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")

Sedan i filen Import_Ext.py :

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

För att exportera ditt dokument till någon ny filtyp fungerar på samma sätt, förutom att du använder:

FreeCAD.addExportType("Din nya FilTyp (*.ext)","Export_Ext") 

Lägga till en linje

En linje har 2 punkter.

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

Lägga till en polygon

En polygon ett set av ihopkopplade linjesegment (en polyline i AutoCAD). Den behöver inte vara stängd.

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

Lägga till och ta bort ett objekt till/från en grupp

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

Notera: Du kan även lägga till andra grupper till en grupp...

Lägga till ett nät

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

Lägga till en cirkelbåge eller en cirkel

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

Komma åt och ändra representationen av ett objekt

Varje objekt i ett FreeCAD dokument har ett associerat vy representationsobjekt som sparar alla parametrar som definierar hur objekten syns, som färg, linjebredd, etc...

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

Observation av mushändelser i 3D visaren via Python

Inventor ramverket tillåter att du lägger till en eller flera återanropsnoder vill visarens scengraf. som standard i FreeCAD är en återanropsnod installerad per visare vilket tillåter att du kan lägga till globala eller statiska C++ funktioner. I en lämplig Python bindning så erbjuds några metoder för att använda denna teknik inuti Python kod.

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)

Klicka nu någonstans i 3D visaren och observera meddelandena i utmatningsfönstret. För att avsluta observationen, anropa bara

v.removeEventCallback("SoMouseButtonEvent",c)

Följande händelsetyper stöds

  • SoEvent -- alla sorts händelser
  • SoButtonEvent -- alla musknapps och tangentbordshändelser
  • SoLocation2Event -- 2D rörelsehändelser (normalt musförflyttningar)
  • SoMotion3Event -- 3D rörelsehändelser (normalt spaceball)
  • SoKeyboardEvent -- tangentbordsknapp ned och upphändelser
  • SoMouseButtonEvent -- musknapp ned och upphändelser
  • SoSpaceballButtonEvent -- spaceballknapp ned och upphändelser

Python funktionen som kan registreras med addEventCallback() förväntar sig ett lexikon. Beroende på den övervakade händelsen så kan lexikonet innehålla olika nycklar.

För alla händelser så har den nycklarna:

  • Type -- händelsetypens namn d.v.s. SoMouseEvent, SoLocation2Event, ...
  • Time -- nuvarande tid som en sträng
  • Position -- en tupel med två heltal, musposition
  • ShiftDown -- en boolesk, sann om Skift var nedtryckt, annars falsk
  • CtrlDown -- en boolesk, sann om CTRL var nedtryckt, annars falsk
  • AltDown -- en boolesk, sann om Alt var nedtryckt, annars falsk


För alla knapphändelser, d.v.s. tangentbord, mus eller spaceball händelser

  • State -- En sträng 'UP' om knappen var uppe, 'DOWN' om den var nera eller 'UNKNOWN' för alla andra fall


För tangentbordshändelser:

  • Key -- tecknet för den nedtryckta tangenten


För musknappshändelser

  • Button -- den nedtryckta knappen, kan vara BUTTON1, ..., BUTTON5 eller ANY


För spaceballhändelser:

  • Button -- den nedtryckta knappen, kan vara BUTTON1, ..., BUTTON7 eller ANY


Och slutligen rörelsehändelser:

  • Förflyttning -- en tupel med tre flyttal
  • Rotation -- en kvaternion för rotationen, d.v.s. en tupel med fyra flyttal

Display keys pressed and Events command

This macro displays in the report view the keys pressed and all events command

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

Manipulera scengrafen i Python

Det är också möjligt att hämta och ändra scengrafen i Python, med 'pivy' modulen -- en Python bindning för Coin.

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

Pivy's Python API skapas med hjälp av verktyget SWIG. Då vi i FreeCAD använder några självskrivna noder så kan du inte skapa dem direkt i Python. Emellertid så är det möjligt att skapa en nod med dess interna namn. En instans av typen 'SoFCSelection' kan skapas med

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

Lägga till och ta bort objekt till/från scengrafen

Addering av nya noder till scengrafen kan görass på detta sätt. Var noga med att alltid lägga till en SoSeparator för att innehålla geometrin, koordinaterna och materialinformationen på samma objekt. Följande exempel lägger till en röd linje från (0,0,0) till (10,0,0):

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

För att ta bort den, skriv bara:

sg.removeChild(no)

Saves the sceneGraph with a rotation in a series of 36 files in the X Y Z axis

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)

Lägga till anpassade widgetar till gränssnittet

Du kan skapa anpassade widgetar med Qt designer, omvandla dem till ett python skript, och sedan ladda dem till FreeCAD gränssnittet med PyQt4.

Den pythonkod som producerats av Ui pythonkompilatorn (det verktyg som konverterar qt-designer .ui file till pythonkod) ser i allmänhet ut så här (det är enkelt, du kan även skriva det direkt i python):

class myWidget_Ui(object):
 def setupUi(self, myWidget):
   myWidget.setObjectName("my Nice New Widget")
   myWidget.resize(QtCore.QSize(QtCore.QRect(0,0,300,100).size()).expandedTo(myWidget.minimumSizeHint())) # 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))

Allt du sedan behöver göra är att skapa en referens till FreeCAD's Qt fönster, sätta in en anpassad widget i det, och "omvandla" denna widget till din med den Ui kod vi just gjorde:

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

Adding a Tab to the Combo View

The following code allows you to add a tab to the FreeCAD ComboView, besides the "Project" and "Tasks" tabs. It also uses the uic module to load an ui file directly in that tab.

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

Enable or disable a window

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

Opening a custom webpage

import WebGui
WebGui.openBrowser("http://www.example.com")

Getting the HTML contents of an opened webpage

from PySide import QtGui,QtWebKit
a = QtGui.qApp
mw = a.activeWindow()
v = mw.findChild(QtWebKit.QWebFrame)
html = unicode(v.toHtml())
print html

Retrieve and use the coordinates of 3 selected points or objects

# -*- 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")

List all objects

# -*- 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

List the dimensions of an object, given its name

for edge in FreeCAD.ActiveDocument.MyObjectName.Shape.Edges: # replace "MyObjectName" for list
    print edge.Length


Function resident with the mouse click action

Here with SelObserver on a object select

# -*- 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):                # Delete the selected object
        App.Console.PrintMessage("removeSelection"+ "\n")

    def setSelection(self,doc):                           # Selection in ComboView
        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

Other example with ViewObserver on a object select or view

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)

Finding-selecting all elements below cursor

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)

List the components of an object

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

List the PropertiesList

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

Adding one Property "Comment"

import Draft
obj = FreeCADGui.Selection.getSelection()[0]
obj.addProperty("App::PropertyString","GComment","Draft","Font name").GComment = "Comment here"
App.activeDocument().recompute()

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 "View Report" window (View > Views > View report)

# -*- coding: utf-8 -*-
# -*- 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 on Report view : Menu View > Views > report view
#
# rev:30/08/2014:29/09/2014:17/09/2015
 
from FreeCAD import Base
import DraftVecUtils, Draft, Part
 
mydoc = FreeCAD.activeDocument().Name                                     # Name of active Document
App.Console.PrintMessage("Active docu    : "+(mydoc)+"\n")
##################################################################################
 
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")
##################################################################################
 
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
App.Console.PrintMessage("sel            : "+str(sel[0])+"\n\n")          # sel[0] first 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")
##################################################################################
 
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")            
##################################################################################
 
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
App.Console.PrintMessage("sel            : "+str(sel[0])+"\n\n")          # sel[0] first object selected
##################################################################################
 
SubElement = FreeCADGui.Selection.getSelectionEx()                        # sub element name with getSelectionEx()
App.Console.PrintMessage("SubElement     : "+str(SubElement[0])+"\n\n")   # name of sub element
##################################################################################

SubElement = Gui.Selection.getSelectionEx()[0].SubObjects[0].Length       # sub element or element name with getSelectionEx()
App.Console.PrintMessage("SubElement length: "+str(length)+"\n")          # length
##################################################################################

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")    
##################################################################################
 
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")            
##################################################################################
 
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
surface = sel[0].Shape.Area                                               # Area object complete
App.Console.PrintMessage("surfaceObjet   : "+str(surface)+"\n\n")
##################################################################################
 
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")
App.Console.PrintMessage("CenterOfMassZ  : "+str(CenterOfMass[2])+"\n\n")
##################################################################################
 
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")
##################################################################################
 
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")
##################################################################################
 
objs = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()

if len(objs) >= 1:
    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

#sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
#boundBox_= sel[0].Shape.BoundBox                                          # BoundBox of the object
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
boundBoxDiag= boundBox_.DiagonalLength                                    # Diagonal Length boundBox rectangle

App.Console.PrintMessage("boundBoxLX     : "+str(boundBoxLX)+"\n")
App.Console.PrintMessage("boundBoxLY     : "+str(boundBoxLY)+"\n")
App.Console.PrintMessage("boundBoxLZ     : "+str(boundBoxLZ)+"\n")
App.Console.PrintMessage("boundBoxDiag   : "+str(boundBoxDiag)+"\n\n")

##################################################################################
 
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")
##################################################################################
 
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")
##################################################################################
 
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
 
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")
##################################################################################
 
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
rotation = sel[0].Placement.Rotation                                      # decode Placement Rotation
App.Console.PrintMessage("rotation              : "+str(rotation)+"\n\n")
##################################################################################
 
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")
##################################################################################
 
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")
##################################################################################
 
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
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")
 
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")
 
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")
 
Rot_3 = sel[0].Placement.Rotation.Q[3]                                    # decode Placement Rotation 3
App.Console.PrintMessage("Rot_3         : "+str(Rot_3)+"\n\n")
##################################################################################
 
sel = FreeCADGui.Selection.getSelection()                                 # select object with getSelection()
Yaw   = sel[0].Shape.Placement.Rotation.toEuler()[0]                      # decode angle Euler Yaw (Z)
App.Console.PrintMessage("Yaw            : "+str(Yaw)+"\n")
Pitch = sel[0].Shape.Placement.Rotation.toEuler()[1]                      # decode angle Euler Pitch (Y)
App.Console.PrintMessage("Pitch          : "+str(Pitch)+"\n")
Roll  = sel[0].Shape.Placement.Rotation.toEuler()[2]                      # decode angle Euler Roll (X)
App.Console.PrintMessage("Roll           : "+str(Roll)+"\n\n")
##################################################################################

import DraftGeomUtils
sel = FreeCADGui.Selection.getSelection()
vecteur = DraftGeomUtils.findMidpoint(sel[0].Shape.Edges[0])              # find Midpoint
App.Console.PrintMessage(vecteur)
Draft.makePoint(vecteur)
##################################################################################

Manual search of an element with label

# Extract the coordinate X,Y,Z and Angle giving the label 
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")
##################################################################################

PS: Usually the angles are given in Radian to convert :

  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)

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)

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

Other method display on "Int" and "Float"

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"

Select all objects in the document

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

Selecting a face of an object

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

Create one object to the position of the Camera

# 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

here same code simplified

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)

Find 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

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)

Read And write one Expression

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]


Get the normal vector of a suface from a STL file

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)

you are done then run for quit:

Gui.ActiveDocument.ActiveView.removeEventCallbackPivy(coin.SoMouseButtonEvent.getClassTypeId(), meth)


Denna sida visar hur lätt avancerad funktionalitet kan byggas i Python. I denna övning, så kommer vi att bygga ett nytt verktyg som ritar en linje. Detta verktyg kan sedan länkas till ett FreeCAD kommando, och det kommandot kan anropas av ett element i gränssnittet, som en menypunkt eller en knapp i en verktygslåda.

Huvudskriptet

Först kommer vi att skriva ett skript som innehåller all vår funktionalitet. Sedan kommer vi att spara detta i en fil, och importera den i FreeCAD, så att alla klasser och funktioner som vi skriver kommer att vara tillgängliga för FreeCAD. Så, starta din favorit textredigerare, , och skriv följande rader:

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.Line(self.stack[0],self.stack[1])
                shape = l.toShape()
                Part.show(shape)
                self.view.removeEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(),self.callback)

Detaljerad förklaring

import Part, FreeCADGui
from pivy.coin import *

När du vill använda funktioner från en annan modul I Python, så behöver du importera den. I vårt fall, så behöver vi funktioner från Del Modulen, för att skapa linjen, och från gränssnittsmodulen (FreeCADGui), för att komma åt 3D vyn. Vi behöver även innehållet i coin biblioteket, så vi kan använda alla coin objekt som SoMouseButtonEvent, etc...

class line:

Här definierar vi vår huvudklass. Varför använder vi en klass och inte en funktion? Skälet är att vårt verktyg behöver "stanna vid liv" medan vi väntar på att användaren ska klicka på skärmen. En funktion avslutas när dess uppgift är klar, men ett objekt (en klass definierar ett objekt) stannar vid liv ända tills den förstörs.

"this class will create a line after the user clicked 2 points on the screen"

I Python, så kan varje klass eller funktion ha en beskrivningssträng. Detta är speciellt användbart i FreeCAD, därför att när du anropar den klassen i tolken, så visas beskrivningssträngen som ett verktygstips.

def __init__(self):

Python klasser kan alltid innehålla en __init__ funktion, vilken utförs när klassen anropas för att skapa ett objekt. Så här lägger vi allt som vi vill ska hända när vårt linjeverktyg börjar.

self.view = FreeCADGui.ActiveDocument.ActiveView

I en klass, så vill du vanligtvis lägga till self. innan ett variabelnamn, så att den kan kommas åt lätt för alla funktioner inuti och utanför den klassen. Här kommer vi att använda self.view för att komma åt och manipulera den aktiva 3D vyn.

self.stack = []

Här skapar vi en tom lista som kommer att innehålla 3D punkterna som sänds av getpoint funktionen.

self.callback = self.view.addEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(),self.getpoint)

Detta är den viktiga delen: Eftersom det egentligen är en coin3D scen, så använder FreeCAD coin's återanropsmekanism, som tillåter en funktion att anropas varje gång en viss scenhändelse inträffar. I vårt fall, så skapar vi ett återanrop för SoMouseButtonEvent händelser, och vi binder den till getpoint funktionen. Nu, varje gång som en musknapp trycks ned eller släpps, så kommer getpoint funktionen att utföras.

Notera att det finns ett alternativ till addEventCallbackPivy() kallat addEventCallback() vilket dispenserar bruket av pivy. Men eftersom pivy är en mycket effektiv och naturlig väg att komma åt en del av coin scenen, så är det mycket bättre att använda den så mycket du kan!

def getpoint(self,event_cb):

Nu definierar vi getpoint funktionen, som kommer utföras när en musknapp trycks ned i en 3D vy. Denna funktion kommer att ta emot ett argument, som vi kommer kalla event_cb. Från denna händelses återanrop kan vi komma åt händelseobjektet, vilket innehåller flera informationsbitar (läge info här).

if event.getState() == SoMouseButtonEvent.DOWN:

Getpoint funktionen kommer att anropas när en musknapp trycks ned eller släpps. Men vi vill bara välja en 3D punkt när den trycks ned (annars skulle vi få två 3D punkter mycket nära varann). Så vi måste kontrollera det här.

pos = event.getPosition()

Här får vi musmarkörens skärmkoordinater

point = self.view.getPoint(pos[0],pos[1])

Denna funktion ger oss en FreeCAD vektor (x,y,z) som innehåller den 3D punkt som ligger på fokalplanet, precis under vår musmarkör. om du är i kameravy, tänk dig en stråle som kommer från kameran, och passerar genom musmarkören, och träffar fokalplanet. Där är vår 3D punkt. On vi är i ortogonal vy, så är strålen parallell med vyriktningen.

self.stack.append(point)

Vi lägger till vår nya punkt till stacken

if len(self.stack) == 2:

Har vi tillräckligt med punkter? Om ja, låt oss då rita linjen!

l = Part.Line(self.stack[0],self.stack[1])

Här använder vi funktionen Line() från Del Modulen som skapar en linje från två FreeCAD vektorer. Allt som vi skapar och ändrar inuti Del modulen, stannar i Del modulen. Så, tills nu, så har vi skapat en Linje Del. Den är inte bunden till något objekt i vårt aktiva dokument, så inget syns på skärmen.

shape = l.toShape()

FreeCAD dokumentet kan bara acceptera former från Del modulen. Former är Del modulens mest allmäna typ. Så vi behöver konvertera vår linje till en form innan vi lägger till den till dokumentet.

Part.show(shape)

Del modulen har en mycket smidig show() funktion som skapar ett nytt objekt i dokumentet och binder en form till den. Vi skulle också kunna ha skapat ett nytt objekt i dokumentet först, och sedan ha bundit formen till den manuellt.

self.view.removeEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(),self.callback)

Eftersom vi är klara med vår linje, låt oss ta bort vår återanropsmekanism, som använder värdefulla CPU cykler.

Testa & använda skriptet

Låt oss nu spara vårt skript på någon plats där FreeCAD's python tolk kommer att hitta den. När moduler importerass, så kommer tolken att leta på följande platser: python's installationssökväg, FreeCAD bin katalogen, och alla FreeCAD modulkataloger. Så, den bästa lösningen är att skapa en ny katalog i en av FreeCAD's Mod kataloger, och spara vårt skript i den. Låt oss till exempel skapa en "MinaSkript" katalog, och spara vårt skript som "ovning.py".

Nu är allt klart, låt oss starta FreeCAD, skapa ett nytt dokument, och i pythontolken skriva:

import exercise

Om inga felmeddelanden kommer fram, så innebär det att vårt övningsskript har laddats. Vi kan nu kontrollera dess innehåll med :

dir(exercise)

Kommandot dir() är ett inbyggt python kommando som listar modulens innehåll. Vi kan se att vår line() klass är där, som väntar på oss. Låt oss nu testa den:

exercise.line()

Klicka sedan på två olika ställen i 3D vyn, och bingo, där är vår linje! För att göra det igen, skriv bara ovning.line() igen, och igen, och igen... Känns det bra?

Registrera skriptet i FreeCAD's gränssnitt

För att vårt nya linjeverktyg ska bli ännu häftigare, så borde det ha en knapp i gränssnittet, så vi inte behöver skriva allt det varje gång. Den lättaste vägen är att omvandla vår nya MinaSkript katalog till en full FreeCAD arbetsbänk. Det är lätt, allt som behövs är att lägga in en fil som kallas InitGui.py inuti din MinaSkript katalog. InitGui.py kommer att innehålla instruktioner för att skapa en ny arbetsbänk, och addera vårt nya verktyg till den. Förutom det så behöver vi ändra vår övningskod lite, så att line() verktyget igenkänns som ett officiellt FreeCAD kommando. Låt oss starta genom att göra en InitGui.py fil, och skriva följande kod i den:

class MyWorkbench (Workbench): 
   MenuText = "MyScripts"
   def Initialize(self):
       import exercise
       commandslist = ["line"]
       self.appendToolbar("My Scripts",commandslist)
Gui.addWorkbench(MyWorkbench())

Jag tror att du redan nu förstår det ovanstående skriptet: Vi skapar en ny klass som vi kallar MinArbetsbänk, vi ger den en titel (MenuText), och vi definierar en Initialize() funktion som kommer att utföras när arbetsbänken laddas till FreeCAD. I den funktionen så laddar vi innehållet i vår övningsfil, och lägger till de FreeCAD kommandon som hittas i det i en kommandolista. Sedan gör vi en verktygslåda som kallas "Mina Skript" och vi tilldelar vår kommandolista till den. För närvarande har vi förstås endast ett verktyg, så vår kommandolista innehåller endast ett element. Sedan, när vår arbetsbänk är klar, så lägger vi till den till huvudgränssnittet.

Men det kommer fortfarande inte att fungera, därför att ett FreeCAD kommando måste formatteras på ett visst sätt för att fungera. så vi behöver ändra vårt line() verktyg lite. Vår nya ovning.py skript kommer nu att se ut så här:

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

Vad vi gjorde här var att omvandla vår __init__() funktion till en Activated() funktion, därför att när FreeCAD kommandon körs, så utför de automatiskt Activated() funktionen. Vi lade också till en GetResources() funktion, som informerar FreeCAD var den kan hitta en ikon för verktyget, och namnet och verktygstipset för vårt verktyg. en jpg, png eller svg bild kommer att fungera som en ikon, den kan vara av valfri storlek, men det är bäst att använda en storlek osm är nära den slutliga, som 16x16, 24x24 eller 32x32.

Sedan lägger vi till line() klassen som ett officiellt FreeCAD kommando med addCommand() metoden.

Klart, nu behöver vi bara starta om FreeCAD och vi kommer att ha en ny snygg arbetsbänk med vårt splitternya verktyg!

Så du vill ha mer?

Om du gillade denna övningen, varför inte försöka förbättra detta lilla verktyg? Det finns många saker som kan göras, som till exempel:

  • Lägga till feedback för användaren: nu är det ett mycket 'naket' verktyg, så användaren kan bli lite osäker när det används. Så vi skulle kunna lägga till lite feedback, tala om vad som ska göras. Du skulle till exempel kunna mata ur meddelanden till FreeCAD konsolen. Ta en titt i FreeCAD.Console modulen
  • Lägga till en möjlighet att skriva in 3D punkterna manuellt. Titta på python input() funktionen, till exempel
  • Lägga till möjligheten att lägga till mer än 2 punkter
  • Lägga till händelser för andra saker: Nu kontrollerar vi endast musknappshändelser, men om vi också kunde göra något när musen förflyttas, som att visa koordinater?
  • Ge ett namn till det skapade objektet

Tveka inte att skriva dina frågor eller ideer på forum!


På denna sida kommer vi att visa hur man bygger en simpel Qt Dialog med Qt Designer, Qt's officiella verktyg för att designa gränssnitt, och sedan konvertera den till pythonkod, och sedan använda den inuti FreeCAD. Jag antar i exemplet att du redan vet hur du ska redigera och köra python skript, och att du kan göra enkla saker i ett terminalfönster som att navigera, etc. Du måste förstås också ha pyqt installerat.

Designa dialogen

Att i CAD applikationer designa ett bra användargränssnitt är mycket viktigt. Nästan allt som användaren kommer att göra kommer att vara genom någon typ av gränssnitt: läsa dialogrutor, klicka på knappar, välja mellan ikoner, etc. Så det är mycket viktigt att noga tänka igenom vad du vill göra, hur du vill att användaren ska bete sig, och hur arbetsflödet i din aktion kommer att se ut.

Det finns några koncept man bör känna till när man designar ett gränssnitt:

  • Modal/non-modal dialogs: En modal dialog kommer fram längst fram på skärmen, stoppar aktionen i huvudfönstret, och tvingar användare att svara på dialogen, emedan en icke-modal dialog inte stoppar dig från att arbeta med huvudfönstret. I en del fall så är det första bättre, i andra fall inte.
  • Identifiera vad som krävs och vad som är valbart: Försäkra dig om att användaren vet vad den måste göra. Etikettera allting med en riktig beskrivning, använd verktygstips, etc.
  • Separera kommandon från parametrar: Detta görs vanligtvis med knappar och textinmatningsfält. Användaren vet att om en knapp klickas så produceras en aktion emedan ändring av ett värde inuti ett textfält kommer att ändra en parameter någonstans. Nuförtidan så vet de flesta användarna vad en kanpp är, vad ett inmatningsfält är, etc. Det gränssnitts verktygskit vi använder, Qt, är en av de bästa verktygskiten, och vi behöver inte bry oss om så mycket om hur man klargör saker, eftersom de redan är mycket tydliga.

Så, nu när vi har definierat vad vi ska göra, så är det dags att öppna qt designer. Låt oss designa en mycket enkel dialog, som den här:

Qttestdialog.jpg

Vi kommer sedan använda denna dialog i FreeCAD till att producera ett fint rektangulärt plan. Du kanske tycker att det inte är så användbart att producera fina rektangulära plan, men det kommer vara lätt att senare ändra den till att göra mer komplexa saker. När du öppnar det, så ser Qt Designer ut så här:

Qtdesigner-screenshot.jpg

Det är mycket enkelt att använda. I den vänstra lådan har du element som kan dras till din widget. på den högra sidan har du egenskapspanelerna som visar alla möjliga redigerbara egenskaper på de valda elementen. Så, börja med att skapa en ny widget. Välj "Dialog without buttons", eftersom vi inte vill ha standard Ok/Cancel knappar. Dra sedan3 labels, på din widget, en för titeln, en för att skriva "Höjd" och en för att skriva "Bredd". Labels är enkla texter som syns på din widget, bara för att informera användaren. Om du väljer en label, så kommer det fram flera egenskaper på den högra sidan som du kan ändra om du vill, som teckensnitt, höjd, etc.

Lägg sedan till 2 LineEdits, vilket är textfält som användaren kan fylla i, en för höjden och en för bredden. Här kan vi också redigera egenskaper. Till exempel, varför inte ställa in ett standardvärde? Till exempel 1.00 för varje. På detta sätt, när användaren ser dialogen, så kommer båda värdena redan vara ifyllda och om användaren är nöjd så kan den klicka på knappen direkt, och spara dyrbar tid. Lägg sedan till en PushButton, vilken är den knapp som användaren kommer att behöva klicka på efter att de 2 fälten är ifyllda.

Notera att jag här valde mycket enkla kontroller, men Qt har många fler alternativ, du kan till exempel använda Spinboxes istället för LineEdits, etc... Ta en titt på vad som finns tillgängligt, du kommer säkert att få andra ideer.

Det är ungefär allt vi behöver göra i Qt Designer. En sista sak bara, låt oss döpa om alla våra element till lättare namn, så blir det lättare att identifiera dem i våra skript:

Qtpropeditor.jpg

Konvertera vår dialog till python

Låt oss nu spara vår widget någonstans. Den kommar att sparas som en .ui fil, som vi smidigt kan omvandla till python skript med pyuic. på windows, så är pyuic programmet hoppackat med pyqt (ska verifieras), på linux behöver du troligen installera den separat från din pakethanterare (på debian-baserade system, så är det en del av pyqt4-dev-tools paketet). För att göra konverteringen, så behöver du öppna ett terminalfönster (eller ett kommandoprompt fönster på windows), navigera till där du sparade din .ui file, och skriva:

pyuic mywidget.ui > mywidget.py

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:

@"C:\Python27\python" "C:\Python27\Lib\site-packages\PyQt4\uic\pyuic.py" -x %1.ui > %1.py

In the DOS console type without extension

compQt4 myUiFile

Into Linux : to do

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:

pyside-uic mywidget.ui -o mywidget.py

In Windows uic.py are located in "C:\Python27\Lib\site-packages\PySide\scripts\uic.py" For create batch file "compSide.bat":

@"C:\Python27\python" "C:\Python27\Lib\site-packages\PySide\scripts\uic.py" %1.ui > %1.py

In the DOS console type without extension

compSide myUiFile

Into Linux : to do

På en del system så kallas programmet pyuic4 istället för pyuic. Detta kommer att konvertera .ui filen till ett python skript. Om vi öppnar mywidget.py filen, så är dess innehåll mycket lätt att förstå:

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

Som du ser så har det en mycket enkel struktur: En klass benämnd Ui_Dialog skapas, som sparar din widgets gränssnittselement. Den klassen har två metoder, en fär att ställa in widgeten, och en för att översätta dess innehåll, som är en del av de allmäna Qt mekanismerna för översättning av gränssnittselement. Inställningsmetoden skapar, en och en, widgetarna som vi har definierat dem i Qt Designer, och sätter deras alternativ som vi bestämt tidigare. Sedan blir hela gränssnittet översatt, och slutligen, blir sloten anslutna (vi pratar om det senare).

Vi kan nu skapa en ny widget, och använda denna klass till att skapa dess gränssnitt. Vi kan redan se vår widget i aktion, genom att sätta vår mywidget.py fil på en plats där FreeCAD kommer att hitta den (i FreeCAD's bin katalog, eller i någon av underkatalogerna till Mod ), och i FreeCAD pythontolken skriva:

from PySide import QtGui
import mywidget
d = QtGui.QWidget()
d.ui = mywidget.Ui_Dialog()
d.ui.setupUi(d)
d.show()

Och vår dialog kommer fram! Notera att din pythontolk fortfarande fungerar, vi har en icke-modal dialog. Så, för att stänga den, så kan vi (förutom att klicka på dess stängningsikon, förstås) skriva:

d.hide()

Ordna så att vår dialog gör något

Nu när vi kan visa och gömma vår dialog, så behöver vi bara lägga till en sista bit: Att låta den göra något! Om du leker lite med Qt designer, så kommer du snabbt upptäcka ett helt avsnitt som kallas "signals and slots". I grunden så fungerar det så här: element på dina widgetar (i Qt terminologi, så är dessa element widgetar själva) kan sända signaler. Dessa signaler skiljer sig beroende på widget typ. Till exempel, en knapp kan sända en signal när den är nedtryckt och när den släpps. Dessa signaler kan anslutas till slots, vilka kan vara en speciell funktionalitet i andra widgetar (till exempel en dialog har en "stäng" slot till vilken du kan ansluta signalen från en stäng knapp), eller kan vara anpassade funktioner. PyQt Referensdokumentation listar alla qt widgetar, vad de kan göra, vilka signaler de kan sända , etc...

Vad vi kommer att göra här, är att skapa en ny funktion som kommer att skapa ett plan, baserat på höjd och bredd, och ansluta denna funktion till nedtryckt signalen som sänds av vår "Skapa!" button. Så, låt os börja med att importera våra FreeCAD moduler, genom att sätta följande rader i toppen på skriptet, där vi redan har importerat QtCore och QtGui:

import FreeCAD, Part

Låt oss sedan lägga till en ny funktion till vår Ui_Dialog klass:

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

Sedan behöver vi informera Qt att ansluta knappen till funktionen, genom att placera följande rad precis innan QtCore.QMetaObject.connectSlotsByName(Dialog):

QtCore.QObject.connect(self.create,QtCore.SIGNAL("pressed()"),self.createPlane)

Detta ansluter, som du ser, pressed() signalen från vårt skapade objekt ("Skapa!" knappen), till en slot benämnd createPlane, som vi just definierade. Klart! Nu, som en slutlig justering, så kan vi lägga till lite funktion för att skapa dialogen, så kommer den bli lättare att anropa. Utanför Ui_Dialog klassan, så lägger vi till denna kod:

class plane():
   def __init__(self):
       self.d = QtGui.QWidget()
       self.ui = Ui_Dialog()
       self.ui.setupUi(self.d)
       self.d.show()

(Python reminder: the __init__ method of a class is automatically executed whenever a new object is created!)

Det enda vi sedan behöver göra från FreeCAD är:

import mywidget
myDialog = mywidget.plane()

Det var allt. Nu kan du försöka andra saker, som till exempel sätta in din widget i FreeCAD's gränssnitt (se kodbitar sidan), eller göra mycket mer avancerade verktyg, genom att använda andra element på din widget.

Det kompletta skriptet

För referens, så är det kompletta skriptet här:

# -*- coding: utf-8 -*-

# 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(QtGui.QApplication.translate("Dialog", "Dialog", None, QtGui.QApplication.UnicodeUTF8))
       self.title.setText(QtGui.QApplication.translate("Dialog", "Plane-O-Matic", None, QtGui.QApplication.UnicodeUTF8))
       self.label_width.setText(QtGui.QApplication.translate("Dialog", "Width", None, QtGui.QApplication.UnicodeUTF8))
       self.label_height.setText(QtGui.QApplication.translate("Dialog", "Height", None, QtGui.QApplication.UnicodeUTF8))
       self.create.setText(QtGui.QApplication.translate("Dialog", "Create!", None, QtGui.QApplication.UnicodeUTF8))

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

Creation of a dialog with buttons

Method 1

An example of a dialog box complete with its connections.

# -*- coding: utf-8 -*-
# Create by flachyjoe

from PySide import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)


class Ui_MainWindow(object):

     def __init__(self, MainWindow):
        self.window = MainWindow

        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(400, 300)
        self.centralWidget = QtGui.QWidget(MainWindow)
        self.centralWidget.setObjectName(_fromUtf8("centralWidget"))

        self.pushButton = QtGui.QPushButton(self.centralWidget)
        self.pushButton.setGeometry(QtCore.QRect(30, 170, 93, 28))
        self.pushButton.setObjectName(_fromUtf8("pushButton"))
        self.pushButton.clicked.connect(self.on_pushButton_clicked) #connection pushButton

        self.lineEdit = QtGui.QLineEdit(self.centralWidget)
        self.lineEdit.setGeometry(QtCore.QRect(30, 40, 211, 22))
        self.lineEdit.setObjectName(_fromUtf8("lineEdit"))
        self.lineEdit.returnPressed.connect(self.on_lineEdit_clicked) #connection lineEdit

        self.checkBox = QtGui.QCheckBox(self.centralWidget)
        self.checkBox.setGeometry(QtCore.QRect(30, 90, 81, 20))
        self.checkBox.setChecked(True)
        self.checkBox.setObjectName(_fromUtf8("checkBoxON"))
        self.checkBox.clicked.connect(self.on_checkBox_clicked) #connection checkBox

        self.radioButton = QtGui.QRadioButton(self.centralWidget)
        self.radioButton.setGeometry(QtCore.QRect(30, 130, 95, 20))
        self.radioButton.setObjectName(_fromUtf8("radioButton"))
        self.radioButton.clicked.connect(self.on_radioButton_clicked) #connection radioButton

        MainWindow.setCentralWidget(self.centralWidget)

        self.menuBar = QtGui.QMenuBar(MainWindow)
        self.menuBar.setGeometry(QtCore.QRect(0, 0, 400, 26))
        self.menuBar.setObjectName(_fromUtf8("menuBar"))
        MainWindow.setMenuBar(self.menuBar)

        self.mainToolBar = QtGui.QToolBar(MainWindow)
        self.mainToolBar.setObjectName(_fromUtf8("mainToolBar"))
        MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.mainToolBar)

        self.statusBar = QtGui.QStatusBar(MainWindow)
        self.statusBar.setObjectName(_fromUtf8("statusBar"))
        MainWindow.setStatusBar(self.statusBar)

        self.retranslateUi(MainWindow)

     def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
        self.pushButton.setText(_translate("MainWindow", "OK", None))
        self.lineEdit.setText(_translate("MainWindow", "tyty", None))
        self.checkBox.setText(_translate("MainWindow", "CheckBox", None))
        self.radioButton.setText(_translate("MainWindow", "RadioButton", None))

     def on_checkBox_clicked(self):
        if self.checkBox.checkState()==0:
            App.Console.PrintMessage(str(self.checkBox.checkState())+"  CheckBox KO\r\n")
        else:     
            App.Console.PrintMessage(str(self.checkBox.checkState())+" CheckBox OK\r\n")
#        App.Console.PrintMessage(str(self.lineEdit.setText("tititi"))+" LineEdit\r\n") #write text to the lineEdit window !
#        str(self.lineEdit.setText("tititi")) #écrit le texte dans la fenêtre lineEdit
        App.Console.PrintMessage(str(self.lineEdit.displayText())+" LineEdit\r\n")

     def on_radioButton_clicked(self):
        if self.radioButton.isChecked():
             App.Console.PrintMessage(str(self.radioButton.isChecked())+" Radio OK\r\n")
        else:
             App.Console.PrintMessage(str(self.radioButton.isChecked())+"  Radio KO\r\n")

     def on_lineEdit_clicked(self):
#        if self.lineEdit.textChanged():
             App.Console.PrintMessage(str(self.lineEdit.displayText())+" LineEdit Display\r\n")

     def on_pushButton_clicked(self):
        App.Console.PrintMessage("Terminé\r\n")
        self.window.hide()

MainWindow = QtGui.QMainWindow()
ui = Ui_MainWindow(MainWindow)
MainWindow.show()

Here the same window but with an icon on each button.

Download associated icons (click right "Copy the image below ...)"

Icone01.png Icone02.png Icone03.png

# -*- coding: utf-8 -*-

from PySide import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)


class Ui_MainWindow(object):

     def __init__(self, MainWindow):
        self.window = MainWindow
        path = FreeCAD.ConfigGet("UserAppData")
#        path = FreeCAD.ConfigGet("AppHomePath")

        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(400, 300)
        self.centralWidget = QtGui.QWidget(MainWindow)
        self.centralWidget.setObjectName(_fromUtf8("centralWidget"))

        self.pushButton = QtGui.QPushButton(self.centralWidget)
        self.pushButton.setGeometry(QtCore.QRect(30, 170, 93, 28))
        self.pushButton.setObjectName(_fromUtf8("pushButton"))
        self.pushButton.clicked.connect(self.on_pushButton_clicked) #connection pushButton

        self.lineEdit = QtGui.QLineEdit(self.centralWidget)
        self.lineEdit.setGeometry(QtCore.QRect(30, 40, 211, 22))
        self.lineEdit.setObjectName(_fromUtf8("lineEdit"))
        self.lineEdit.returnPressed.connect(self.on_lineEdit_clicked) #connection lineEdit

        self.checkBox = QtGui.QCheckBox(self.centralWidget)
        self.checkBox.setGeometry(QtCore.QRect(30, 90, 100, 20))
        self.checkBox.setChecked(True)
        self.checkBox.setObjectName(_fromUtf8("checkBoxON"))
        self.checkBox.clicked.connect(self.on_checkBox_clicked) #connection checkBox

        self.radioButton = QtGui.QRadioButton(self.centralWidget)
        self.radioButton.setGeometry(QtCore.QRect(30, 130, 95, 20))
        self.radioButton.setObjectName(_fromUtf8("radioButton"))
        self.radioButton.clicked.connect(self.on_radioButton_clicked) #connection radioButton

        MainWindow.setCentralWidget(self.centralWidget)

        self.menuBar = QtGui.QMenuBar(MainWindow)
        self.menuBar.setGeometry(QtCore.QRect(0, 0, 400, 26))
        self.menuBar.setObjectName(_fromUtf8("menuBar"))
        MainWindow.setMenuBar(self.menuBar)

        self.mainToolBar = QtGui.QToolBar(MainWindow)
        self.mainToolBar.setObjectName(_fromUtf8("mainToolBar"))
        MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.mainToolBar)

        self.statusBar = QtGui.QStatusBar(MainWindow)
        self.statusBar.setObjectName(_fromUtf8("statusBar"))
        MainWindow.setStatusBar(self.statusBar)

        self.retranslateUi(MainWindow)

        # Affiche un icone sur le bouton PushButton
        # self.image_01 = "C:\Program Files\FreeCAD0.13\Icone01.png" # adapt the icon name
        self.image_01 = path+"Icone01.png" # adapt the name of the icon
        icon01 = QtGui.QIcon() 
        icon01.addPixmap(QtGui.QPixmap(self.image_01),QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.pushButton.setIcon(icon01) 
        self.pushButton.setLayoutDirection(QtCore.Qt.RightToLeft) # This command reverses the direction of the button

        # Affiche un icone sur le bouton RadioButton 
        # self.image_02 = "C:\Program Files\FreeCAD0.13\Icone02.png" # adapt the name of the icon
        self.image_02 = path+"Icone02.png" # adapter le nom de l'icone
        icon02 = QtGui.QIcon() 
        icon02.addPixmap(QtGui.QPixmap(self.image_02),QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.radioButton.setIcon(icon02) 
        # self.radioButton.setLayoutDirection(QtCore.Qt.RightToLeft) #  This command reverses the direction of the button

        # Affiche un icone sur le bouton CheckBox 
        # self.image_03 = "C:\Program Files\FreeCAD0.13\Icone03.png" # the name of the icon
        self.image_03 = path+"Icone03.png" # adapter le nom de l'icone
        icon03 = QtGui.QIcon() 
        icon03.addPixmap(QtGui.QPixmap(self.image_03),QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.checkBox.setIcon(icon03) 
        # self.checkBox.setLayoutDirection(QtCore.Qt.RightToLeft) # This command reverses the direction of the button


     def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(_translate("MainWindow", "FreeCAD", None))
        self.pushButton.setText(_translate("MainWindow", "OK", None))
        self.lineEdit.setText(_translate("MainWindow", "tyty", None))
        self.checkBox.setText(_translate("MainWindow", "CheckBox", None))
        self.radioButton.setText(_translate("MainWindow", "RadioButton", None))

     def on_checkBox_clicked(self):
        if self.checkBox.checkState()==0:
            App.Console.PrintMessage(str(self.checkBox.checkState())+"  CheckBox KO\r\n")
        else:     
            App.Console.PrintMessage(str(self.checkBox.checkState())+" CheckBox OK\r\n")
           # App.Console.PrintMessage(str(self.lineEdit.setText("tititi"))+" LineEdit\r\n") # write text to the lineEdit window !
           # str(self.lineEdit.setText("tititi")) #écrit le texte dans la fenêtre lineEdit
        App.Console.PrintMessage(str(self.lineEdit.displayText())+" LineEdit\r\n")

     def on_radioButton_clicked(self):
        if self.radioButton.isChecked():
             App.Console.PrintMessage(str(self.radioButton.isChecked())+" Radio OK\r\n")
        else:
             App.Console.PrintMessage(str(self.radioButton.isChecked())+"  Radio KO\r\n")

     def on_lineEdit_clicked(self):
          # if self.lineEdit.textChanged():
          App.Console.PrintMessage(str(self.lineEdit.displayText())+" LineEdit Display\r\n")

     def on_pushButton_clicked(self):
        App.Console.PrintMessage("Terminé\r\n")
        self.window.hide()

MainWindow = QtGui.QMainWindow()
ui = Ui_MainWindow(MainWindow)
MainWindow.show()

Here the code to display the icon on the pushButton, change the name for another button, (radioButton, checkBox) and the path to the icon.

# Affiche un icône sur le bouton PushButton
        # self.image_01 = "C:\Program Files\FreeCAD0.13\icone01.png" # the name of the icon
        self.image_01 = path+"icone01.png" # the name of the icon
        icon01 = QtGui.QIcon() 
        icon01.addPixmap(QtGui.QPixmap(self.image_01),QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.pushButton.setIcon(icon01) 
        self.pushButton.setLayoutDirection(QtCore.Qt.RightToLeft) # This command reverses the direction of the button

The command UserAppData gives the user path AppHomePath gives the installation path of FreeCAD

#        path = FreeCAD.ConfigGet("UserAppData")
        path = FreeCAD.ConfigGet("AppHomePath")

This command reverses the horizontal button, right to left.

self.pushButton.setLayoutDirection(QtCore.Qt.RightToLeft) # This command reverses the direction of the button

Method 2

Another method to display a window, here by creating a file QtForm.py which contains the header program (module called with import QtForm), and a second module that contains the code window all these accessories, and your code (the calling module).

This method requires two separate files, but allows to shorten your program using the file ' ' QtForm.py ' ' import. Then distribute the two files together, they are inseparable.

The file QtForm.py

# -*- coding: utf-8 -*-
# Create by flachyjoe
from PySide import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
   def _fromUtf8(s):
      return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
      return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
   def _translate(context, text, disambig):
      return QtGui.QApplication.translate(context, text, disambig)

class Form(object):
   def __init__(self, title, width, height):
      self.window = QtGui.QMainWindow()
      self.title=title
      self.window.setObjectName(_fromUtf8(title))
      self.window.setWindowTitle(_translate(self.title, self.title, None))
      self.window.resize(width, height)

   def show(self):
      self.createUI()
      self.retranslateUI()
      self.window.show()
   
   def setText(self, control, text):
      control.setText(_translate(self.title, text, None))

The calling file that contains the window and your code.

The file my_file.py

The connections are to do, a good exercise.

# -*- coding: utf-8 -*-
# Create by flachyjoe
from PySide import QtCore, QtGui
import QtForm

class myForm(QtForm.Form):
   def createUI(self):
      self.centralWidget = QtGui.QWidget(self.window)
      self.window.setCentralWidget(self.centralWidget)
      
      self.pushButton = QtGui.QPushButton(self.centralWidget)
      self.pushButton.setGeometry(QtCore.QRect(30, 170, 93, 28))
      self.pushButton.clicked.connect(self.on_pushButton_clicked)
      
      self.lineEdit = QtGui.QLineEdit(self.centralWidget)
      self.lineEdit.setGeometry(QtCore.QRect(30, 40, 211, 22))
      
      self.checkBox = QtGui.QCheckBox(self.centralWidget)
      self.checkBox.setGeometry(QtCore.QRect(30, 90, 81, 20))
      self.checkBox.setChecked(True)
      
      self.radioButton = QtGui.QRadioButton(self.centralWidget)
      self.radioButton.setGeometry(QtCore.QRect(30, 130, 95, 20))
   
   def retranslateUI(self):
      self.setText(self.pushButton, "Fermer")
      self.setText(self.lineEdit, "essais de texte")
      self.setText(self.checkBox, "CheckBox")
      self.setText(self.radioButton, "RadioButton")
   
   def on_pushButton_clicked(self):
      self.window.hide()

myWindow=myForm("Fenetre de test",400,300)
myWindow.show()

Other example


Are treated :

  1. icon for window
  2. horizontalSlider
  3. progressBar horizontal
  4. verticalSlider
  5. progressBar vertical
  6. lineEdit
  7. lineEdit
  8. doubleSpinBox
  9. doubleSpinBox
  10. doubleSpinBox
  11. button
  12. button
  13. radioButton with icons
  14. checkBox with icon checked and unchecked
  15. textEdit
  16. graphicsView with 2 graphes

The code page and the icons Qt_Example

Icon personalised in ComboView

Here an example to create an object with properties and icon personalised in ComboView

Download the example icon to the same directory as the macro icon Example for the macro

Use of an icon for three different use cases: icon_in_file_disk (format .png), icon_XPM_in_macro (format .XPM) and icon_resource_FreeCAD

icon personalised


import PySide
import FreeCAD, FreeCADGui, Part
from pivy import coin
from PySide import QtGui ,QtCore
from PySide.QtGui import *
from PySide.QtCore import *
import Draft

global path
param = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macro")# macro path in FreeCAD preferences
path = param.GetString("MacroPath","") + "/"                        # macro path
path = path.replace("\\","/")                                       # convert the "\" to "/"


class IconViewProviderToFile:                                       # Class ViewProvider create Property view of object
    def __init__( self, obj, icon):
        self.icone = icon
        
    def getIcon(self):                                              # GetIcon
        return self.icone
        
    def attach(self, obj):                                          # Property view of object
        self.modes = []
        self.modes.append("Flat Lines")
        self.modes.append("Shaded")
        self.modes.append("Wireframe")
        self.modes.append("Points")
        obj.addDisplayMode( coin.SoGroup(),"Flat Lines" )           # Display Mode
        obj.addDisplayMode( coin.SoGroup(),"Shaded" )
        obj.addDisplayMode( coin.SoGroup(),"Wireframe" )
        obj.addDisplayMode( coin.SoGroup(),"Points" )
        return self.modes

    def getDisplayModes(self,obj):
        return self.modes

#####################################################
########## Example with icon to file # begin ########
#####################################################

object1 = FreeCAD.ActiveDocument.addObject("App::FeaturePython", "Icon_In_File_Disk")                                     # create your object
object1.addProperty("App::PropertyString","Identity", "ExampleTitle0", "Identity of object").Identity = "FCSpring"        # Identity of object
object1.addProperty("App::PropertyFloat" ,"Pitch",    "ExampleTitle0", "Pitch betwen 2 heads").Pitch  = 2.0               # other Property Data
object1.addProperty("App::PropertyBool"  ,"View",     "ExampleTitle1", "Hello world").View            = True              # ...
object1.addProperty("App::PropertyColor" ,"LineColor","ExampleTitle2", "Color to choice").LineColor   = (0.13,0.15,0.37)  # ...
#...other Property Data
#...other Property Data
#
object1.ViewObject.Proxy = IconViewProviderToFile( object1, path + "FreeCADIco.png")                                      # icon download to file
App.ActiveDocument.recompute()
#
#__Detail__:
# FreeCAD.ActiveDocument.addObject( = create now object personalized
# "App::FeaturePython",             = object as FeaturePython
# "Icon_In_File_Disk")              = internal name of your object
#
#
# "App::PropertyString",    = type of Property , availlable : PropertyString, PropertyFloat, PropertyBool, PropertyColor
# "Identity",               = name of the feature
# "ExampleTitle0",          = title of the "section"
# "Identity of object")     = tooltip displayed on mouse
# .Identity                 = variable (same of name of the feature)
# object1.ViewObject.Proxy  = create the view object and gives the icon
#
########## example with icon to file end



#####################################################
########## Example with icon in macro # begin #######
#####################################################

def setIconInMacro(self):        # def contener the icon in format .xpm
    # File format XPM created by Gimp "https://www.gimp.org/"
    # Choice palette Tango
    # Create your masterwork ...
    # For export the image in XPM format
    #     Menu File > Export as > .xpm
    # (For convert image true color in Tango color palette : 
    #     Menu Image > Mode > Indexed ... > Use custom palette > Tango Icon Theme > Convert)
    return """
            /* XPM */
            static char * XPM[] = {
            "22 24 5 1",
            " 	c None",
            ".	c #CE5C00",
            "+	c #EDD400",
            "@	c #F57900",
            "#	c #8F5902",
            "                      ",
            "                      ",
            "  ....                ",
            "  ..@@@@..            ",
            "  . ...@......        ",
            "  .+++++++++...       ",
            "  .      ....++...    ",
            "  .@..@@@@@@.+++++..  ",
            "  .@@@@@..#  ++++ ..  ",
            "  .       ++++  .@..  ",
            "  .++++++++  .@@@.+.  ",
            " .      ..@@@@@. ++.  ",
            " ..@@@@@@@@@.  +++ .  ",
            " ....@...# +++++ @..  ",
            " .    ++++++++ .@. .  ",
            " .++++++++  .@@@@ .   ",
            " .   #....@@@@. ++.   ",
            " .@@@@@@@@@.. +++ .   ",
            " ........  +++++...   ",
            " ...  ..+++++ ..@..   ",
            "    ......  .@@@ +.   ",
            "          ......++.   ",
            "                ...   ",
            "                      "};
        """

object2 = FreeCAD.ActiveDocument.addObject("App::FeaturePython", "Icon_XPM_In_Macro")                                    #
object2.addProperty("App::PropertyString","Identity","ExampleTitle","Identity of object").Identity = "FCSpring"
#...other Property Data
#...other Property Data
#
object2.ViewObject.Proxy = IconViewProviderToFile( object2, setIconInMacro(""))              # icon in macro (.XPM)
App.ActiveDocument.recompute()
########## example with icon in macro end



####################################################################
########## Example with icon to FreeCAD ressource # begin ##########
####################################################################

object3 = FreeCAD.ActiveDocument.addObject("App::FeaturePython", "Icon_Ressource_FreeCAD")                               #
object3.addProperty("App::PropertyString","Identity","ExampleTitle","Identity of object").Identity = "FCSpring"
#...other Property Data
#...other Property Data
#
object3.ViewObject.Proxy = IconViewProviderToFile( object3, ":/icons/Draft_Draft.svg")       # icon to FreeCAD ressource
App.ActiveDocument.recompute()
########## example with icon to FreeCAD ressource end

Complete example creating a cube and its icon

#https://forum.freecadweb.org/viewtopic.php?t=10255#p83319
import FreeCAD, Part, math
from FreeCAD import Base
from PySide import QtGui

global path
param = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macro")# macro path in FreeCAD preferences
path = param.GetString("MacroPath","") + "/"                        # macro path
path = path.replace("\\","/")                                       # convert the "\" to "/"

def setIconInMacro(self):
    return """
        /* XPM */
        static char * xpm[] = {
        "22 22 12 1",
        " 	c None",
        ".	c #A40000",
        "+	c #2E3436",
        "@	c #CE5C00",
        "#	c #F57900",
        "$	c #FCAF3E",
        "%	c #5C3566",
        "&	c #204A87",
        "*	c #555753",
        "=	c #3465A4",
        "-	c #4E9A06",
        ";	c #729FCF",
        "                      ",
        "                      ",
        "                      ",
        "        ..   ..       ",
        "       +@#+++.$$      ",
        "       +.#+%..$$      ",
        "       &*$  &*#*      ",
        "      &   =&=  =      ",
        "   ++&  +.==   %=     ",
        "  ++$@ ..$ %=   &     ",
        "  ..-&%.#$$ &## +=$   ",
        "   .#  ..$ ..#%%.#$$  ",
        "     ;    =+=## %-$#  ",
        "     &=   ;&   %=     ",
        "      ;+ &=;  %=      ",
        "      ++$- +*$-       ",
        "      .#&&+.@$$       ",
        "      ..$# ..$#       ",
        "       ..   ..        ",
        "                      ",
        "                      ",
        "                      "};
        """

class PartFeature:
    def __init__(self, obj):
        obj.Proxy = self

class Box(PartFeature):
    def __init__(self, obj):
        PartFeature.__init__(self, obj)
        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

    def onChanged(self, fp, prop):
        try:
            if prop == "Length" or prop == "Width" or prop == "Height":
                fp.Shape = Part.makeBox(fp.Length,fp.Width,fp.Height)
        except:
            pass

    def execute(self, fp):
        fp.Shape = Part.makeBox(fp.Length,fp.Width,fp.Height)

class ViewProviderBox:
    def __init__(self, obj, icon):
        obj.Proxy  = self
        self.icone = icon
        
    def getIcon(self):
        return self.icone

    def attach(self, obj):
        return

    def setupContextMenu(self, obj, menu):
        action = menu.addAction("Set default height")
        action.triggered.connect(lambda f=self.setDefaultHeight, arg=obj:f(arg))

        action = menu.addAction("Hello World")
        action.triggered.connect(self.showHelloWorld)

    def setDefaultHeight(self, view):
        view.Object.Height = 15.0

    def showHelloWorld(self):
        QtGui.QMessageBox.information(None, "Hi there", "Hello World")

def makeBox():
    FreeCAD.newDocument()
    a=FreeCAD.ActiveDocument.addObject("Part::FeaturePython","Box")
    Box(a)
#    ViewProviderBox(a.ViewObject, path + "FreeCADIco.png")    # icon download to file
#    ViewProviderBox(a.ViewObject,  ":/icons/Draft_Draft.svg") # icon to FreeCAD ressource
    ViewProviderBox(a.ViewObject,  setIconInMacro(""))        # icon in macro (.XPM)
    App.ActiveDocument.recompute()

makeBox()

Use QFileDialog for writing to a file

Complete code:

# -*- coding: utf-8 -*-
import PySide
from PySide import QtGui ,QtCore
from PySide.QtGui import *
from PySide.QtCore import *
path = FreeCAD.ConfigGet("UserAppData")

try:
    SaveName = QFileDialog.getSaveFileName(None,QString.fromLocal8Bit("Save a file txt"),path,             "*.txt") # PyQt4
#                                                                     "here the text displayed on windows" "here the filter (extension)"   
except Exception:
    SaveName, Filter = PySide.QtGui.QFileDialog.getSaveFileName(None, "Save a file txt", path,             "*.txt") # PySide
#                                                                     "here the text displayed on windows" "here the filter (extension)"   
if SaveName == "":                                                            # if the name file are not selected then Abord process
    App.Console.PrintMessage("Process aborted"+"\n")
else:                                                                         # if the name file are selected or created then 
    App.Console.PrintMessage("Registration of "+SaveName+"\n")                # text displayed to Report view (Menu > View > Report view checked)
    try:                                                                      # detect error ...
        file = open(SaveName, 'w')                                            # open the file selected to write (w)
        try:                                                                  # if error detected to write ...
            # here your code
            print("here your code")
            file.write(str(1)+"\n")                                           # write the number convert in text with (str())
            file.write("FreeCAD the best")                                    # write the the text with ("  ")
        except Exception:                                                     # if error detected to write
            App.Console.PrintError("Error write file "+"\n")                  # detect error ... display the text in red (PrintError)
        finally:                                                              # if error detected to write ... or not the file is closed
            file.close()                                                      # if error detected to write ... or not the file is closed
    except Exception:
        App.Console.PrintError("Error Open file "+SaveName+"\n")      # detect error ... display the text in red (PrintError)

Use QFileDialog to read a file

Complete code:

# -*- coding: utf-8 -*-
import PySide
from PySide import QtGui ,QtCore
from PySide.QtGui import *
from PySide.QtCore import *
path = FreeCAD.ConfigGet("UserAppData")

OpenName = ""
try:
    OpenName = QFileDialog.getOpenFileName(None,QString.fromLocal8Bit("Read a file txt"),path,             "*.txt") # PyQt4
#                                                                     "here the text displayed on windows" "here the filter (extension)"   
except Exception:
    OpenName, Filter = PySide.QtGui.QFileDialog.getOpenFileName(None, "Read a file txt", path,             "*.txt") #PySide
#                                                                     "here the text displayed on windows" "here the filter (extension)"   
if OpenName == "":                                                            # if the name file are not selected then Abord process
    App.Console.PrintMessage("Process aborted"+"\n")
else:
    App.Console.PrintMessage("Read "+OpenName+"\n")                           # text displayed to Report view (Menu > View > Report view checked)
    try:                                                                      # detect error to read file
        file = open(OpenName, "r")                                            # open the file selected to read (r)  # (rb is binary)
        try:                                                                  # detect error ...
            # here your code
            print("here your code")
            op = OpenName.split("/")                                          # decode the path
            op2 = op[-1].split(".")                                           # decode the file name 
            nomF = op2[0]                                                     # the file name are isolated

            App.Console.PrintMessage(str(nomF)+"\n")                          # the file name are displayed

            for ligne in file:                                                # read the file
                X  = ligne.rstrip('\n\r') #.split()                           # decode the line
                print(X)                                                      # print the line in report view other method 
                                                                              # (Menu > Edit > preferences... > Output window > Redirect internal Python output (and errors) to report view checked) 
        except Exception:                                                     # if error detected to read
            App.Console.PrintError("Error read file "+"\n")                   # detect error ... display the text in red (PrintError)
        finally:                                                              # if error detected to read ... or not error the file is closed
            file.close()                                                      # if error detected to read ... or not error the file is closed
    except Exception:                                                         # if one error detected to read file
        App.Console.PrintError("Error in Open the file "+OpenName+"\n")       # if one error detected ... display the text in red (PrintError)

Use QColorDialog to get the color

Complete code:

# -*- coding: utf-8 -*-
# https://deptinfo-ensip.univ-poitiers.fr/ENS/pyside-docs/PySide/QtGui/QColor.html
import PySide
from PySide import QtGui ,QtCore
from PySide.QtGui import *
from PySide.QtCore import *
path = FreeCAD.ConfigGet("UserAppData")

couleur = QtGui.QColorDialog.getColor()
if couleur.isValid():
    red   = int(str(couleur.name()[1:3]),16)    # decode hexadecimal to int()
    green = int(str(couleur.name()[3:5]),16)    # decode hexadecimal to int()
    blue  = int(str(couleur.name()[5:7]),16)    # decode hexadecimal to int()

    print(couleur)                              # 
    print("hexadecimal ",couleur.name())        # color format hexadecimal mode 16
    print("Red   color ",red)                   # color format decimal
    print("Green color ",green)                 # color format decimal
    print("Blue  color ",blue)                  # color format decimal

Use QColorDialog and create your palette colors (Standard and Customize)

This example modify the Standard color and the Customize color with the Tango FreeCAD guide.

The complete code


# -*- coding: utf-8 -*-
# https://deptinfo-ensip.univ-poitiers.fr/ENS/pyside-docs/PySide/QtGui/QColor.html
import PySide
from PySide import QtGui ,QtCore
from PySide.QtGui import *
from PySide.QtCore import *

###############################################
##        Window colors organisation         ##
##        __________________________         ##
## StandardColor:                            ##
##                                           ##
##           Colonnes:                       ##
##           1:  2:  3:  4:  5:  6:  7:  8:  ##
##          _______________________________  ##
## Line 1:   0   6   12  18  24  30  36  42  ##
## Line 2:   1   7   13  19  25  31  37  43  ##
## Line 3:   2   8   14  20  26  32  38  44  ##
## Line 4:   3   9   15  21  27  33  39  45  ##
## Line 5:   4   10  16  22  28  34  40  46  ##
## Line 6:   5   11  17  23  29  35  41  47  ##
##                                           ##
## CustomColor:                              ##
##                                           ##
##           Colonnes:                       ##
##           1:  2:  3:  4:  5:  6:  7:  8:  ##
##          _______________________________  ##
## Line 1:   0   2   4   6   8   10  12  14  ##
## Line 2:   1   3   5   7   9   11  13  15  ##
##                                           ##
###############################################

color_Dialog   = QtGui.QColorDialog()
# FreeCAD-Tango
# Customize the colors in the standard box (in numeric mode)
#
#### Dialog line 1
color_Dialog.setStandardColor( 0, QtGui.QColor(252, 233,  79 , 0).rgba())    # Butte 1
color_Dialog.setStandardColor( 6, QtGui.QColor(237, 212,   0 , 0).rgba())    # Butte 2
color_Dialog.setStandardColor(12, QtGui.QColor(196, 160,   0 , 0).rgba())    # Butte 3
color_Dialog.setStandardColor(18, QtGui.QColor( 48,  43,   0 , 0).rgba())    # Butte 4

color_Dialog.setStandardColor(24, QtGui.QColor(138, 226,  52 , 0).rgba())    # Chameleo 1
color_Dialog.setStandardColor(30, QtGui.QColor(115, 210,  22 , 0).rgba())    # Chameleo 2
color_Dialog.setStandardColor(36, QtGui.QColor( 78, 154,   6 , 0).rgba())    # Chameleo 3
color_Dialog.setStandardColor(42, QtGui.QColor( 23,  42,   4 , 0).rgba())    # Chameleo 4
#### Dialog line 2
color_Dialog.setStandardColor( 1, QtGui.QColor(252, 175,  62 , 0).rgba())    # Orang 1
color_Dialog.setStandardColor( 7, QtGui.QColor(245, 121,   0 , 0).rgba())    # Orang 2
color_Dialog.setStandardColor(13, QtGui.QColor(206,  92,   0 , 0).rgba())    # Orang 3
color_Dialog.setStandardColor(19, QtGui.QColor( 50,  25,   0 , 0).rgba())    # Orang 4

color_Dialog.setStandardColor(25, QtGui.QColor(114, 159, 207 , 0).rgba())    # Sky Blu 1
color_Dialog.setStandardColor(31, QtGui.QColor( 52, 101, 164 , 0).rgba())    # Sky Blu 2
color_Dialog.setStandardColor(37, QtGui.QColor( 32,  74, 135 , 0).rgba())    # Sky Blu 3
color_Dialog.setStandardColor(43, QtGui.QColor( 11,  21,  33 , 0).rgba())    # Sky Blu 4
#### Dialog line 3
color_Dialog.setStandardColor( 2, QtGui.QColor(173, 127, 168 , 0).rgba())    # Plu 1
color_Dialog.setStandardColor( 8, QtGui.QColor(117,  80, 123 , 0).rgba())    # Plu 2
color_Dialog.setStandardColor(14, QtGui.QColor( 92,  53, 102 , 0).rgba())    # Plu 3
color_Dialog.setStandardColor(20, QtGui.QColor( 23,  16,  24 , 0).rgba())    # Plu 4

color_Dialog.setStandardColor(26, QtGui.QColor(233, 185, 110 , 0).rgba())    # Chocolat 1
color_Dialog.setStandardColor(32, QtGui.QColor(193, 125,  17 , 0).rgba())    # Chocolat 2
color_Dialog.setStandardColor(38, QtGui.QColor(143,  89,   2 , 0).rgba())    # Chocolat 3
color_Dialog.setStandardColor(44, QtGui.QColor( 39,  25,   3 , 0).rgba())    # Chocolat 4
#### Dialog line 4
color_Dialog.setStandardColor( 3, QtGui.QColor(239,  41,  41 , 0).rgba())    # Scarle Re 1
color_Dialog.setStandardColor( 9, QtGui.QColor(204,   0,   0 , 0).rgba())    # Scarle Re 2
color_Dialog.setStandardColor(15, QtGui.QColor(164,   0,   0 , 0).rgba())    # Scarle Re 3
color_Dialog.setStandardColor(21, QtGui.QColor( 40,   0,   0 , 0).rgba())    # Scarle Re 4

color_Dialog.setStandardColor(27, QtGui.QColor( 52, 224, 226 , 0).rgba())    # FreeTea 1
color_Dialog.setStandardColor(33, QtGui.QColor( 22, 208, 210 , 0).rgba())    # FreeTea 2
color_Dialog.setStandardColor(39, QtGui.QColor(  6, 152, 154 , 0).rgba())    # FreeTea 3
color_Dialog.setStandardColor(45, QtGui.QColor(  4,  42,  42 , 0).rgba())    # FreeTea 4
#### Dialog line 5
color_Dialog.setStandardColor( 4, QtGui.QColor(255, 255, 255 , 0).rgba())    # Snow White

color_Dialog.setStandardColor(10, QtGui.QColor(238, 238, 236 , 0).rgba())    # Aluminiu 1
color_Dialog.setStandardColor(16, QtGui.QColor(211, 215, 207 , 0).rgba())    # Aluminiu 2
color_Dialog.setStandardColor(22, QtGui.QColor(186, 189, 182 , 0).rgba())    # Aluminiu 3

color_Dialog.setStandardColor(28, QtGui.QColor(136, 138, 133 , 0).rgba())    # Aluminiu 4
color_Dialog.setStandardColor(34, QtGui.QColor( 85,  87,  83 , 0).rgba())    # Aluminiu 5
color_Dialog.setStandardColor(40, QtGui.QColor( 46,  52,  54 , 0).rgba())    # Aluminiu 6

color_Dialog.setStandardColor(46, QtGui.QColor(  0,   0,   0 , 0).rgba())    # Je Black
#### Dialog line 6
color_Dialog.setStandardColor( 5, QtGui.QColor(255, 255, 255 , 0).rgba())    # Snow White
color_Dialog.setStandardColor(11, QtGui.QColor(255,   0,   0 , 0).rgba())    # Aluminiu 1
color_Dialog.setStandardColor(17, QtGui.QColor(  0, 255,   0 , 0).rgba())    # Aluminiu 2
color_Dialog.setStandardColor(23, QtGui.QColor(  0,   0, 255 , 0).rgba())    # Aluminiu 3

color_Dialog.setStandardColor(29, QtGui.QColor(255, 255,   0 , 0).rgba())    # Aluminiu 4
color_Dialog.setStandardColor(35, QtGui.QColor(255,   0, 255 , 0).rgba())    # Aluminiu 5
color_Dialog.setStandardColor(41, QtGui.QColor(  0, 255, 255 , 0).rgba())    # Aluminiu 6
color_Dialog.setStandardColor(47, QtGui.QColor(  0,   0,   0 , 0).rgba())    # Je Black
color_Dialog.setStandardColor(47, QtGui.QColor(  0,   0,   0 , 0).rgba())    # Je Black

#### Customize the colors to Dialog CustomColor (in hexadecimal converted in numeric mode)
# Use the Yellow tones for tools that create objects.
# Dialog line 1
color_Dialog.setCustomColor(0, QtGui.QColor( int("fc",16),int("e9",16),int("4f",16) , 0).rgba()) # hexadecimal converted in int
color_Dialog.setCustomColor(2, QtGui.QColor( int("ed",16),int("d4",16),int("00",16) , 0).rgba()) # hexadecimal converted in int
color_Dialog.setCustomColor(4, QtGui.QColor( int("c4",16),int("a0",16),int("00",16) , 0).rgba()) # hexadecimal converted in int
color_Dialog.setCustomColor(6, QtGui.QColor( int("30",16),int("2b",16),int("00",16) , 0).rgba()) # hexadecimal converted in int

# Use the Blue tones for tools that modify objects
color_Dialog.setCustomColor(8, QtGui.QColor( int("72",16),int("9f",16),int("cf",16) , 0).rgba()) # hexadecimal converted in int
color_Dialog.setCustomColor(10,QtGui.QColor( int("34",16),int("65",16),int("a4",16) , 0).rgba()) # hexadecimal converted in int
color_Dialog.setCustomColor(12,QtGui.QColor( int("20",16),int("4a",16),int("87",16) , 0).rgba()) # hexadecimal converted in int
color_Dialog.setCustomColor(14,QtGui.QColor( int("0b",16),int("15",16),int("21",16) , 0).rgba()) # hexadecimal converted in int

# Use the Teal tones for view-related tools
# Dialog line 2
color_Dialog.setCustomColor(1, QtGui.QColor( int("34",16),int("e0",16),int("e2",16) , 0).rgba()) # hexadecimal converted in int
color_Dialog.setCustomColor(3, QtGui.QColor( int("16",16),int("d0",16),int("d2",16) , 0).rgba()) # hexadecimal converted in int
color_Dialog.setCustomColor(5, QtGui.QColor( int("06",16),int("98",16),int("9a",16) , 0).rgba()) # hexadecimal converted in int
color_Dialog.setCustomColor(7, QtGui.QColor( int("04",16),int("2a",16),int("2a",16) , 0).rgba()) # hexadecimal converted in int

# Use the Red tones for Constraint related tools
color_Dialog.setCustomColor(9, QtGui.QColor( int("ef",16),int("29",16),int("29",16) , 0).rgba()) # hexadecimal converted in int
color_Dialog.setCustomColor(11,QtGui.QColor( int("cc",16),int("00",16),int("00",16) , 0).rgba()) # hexadecimal converted in int
color_Dialog.setCustomColor(13,QtGui.QColor( int("a4",16),int("00",16),int("00",16) , 0).rgba()) # hexadecimal converted in int
color_Dialog.setCustomColor(15,QtGui.QColor( int("28",16),int("00",16),int("00",16) , 0).rgba()) # hexadecimal converted in int

Color = color_Dialog.getColor()                                   # Color.name() extract the color in Hexadecimal mode (#ad7fa8)

if Color.isValid():

    print("__.name()___________")
    print("hexadecimal         ", Color.name())                   # color format hexadecimal mode 16
    red   = int(str( Color.name()[1:3]),16 )                      # decode hexadecimal to int()
    green = int(str( Color.name()[3:5]),16 )                      # decode hexadecimal to int()
    blue  = int(str( Color.name()[5:7]),16 )                      # decode hexadecimal to int()

    print("Red   color decimal ", str( Color.name()[1:3]), red )  # color format hex to decimal
    print("Green color decimal ", str( Color.name()[3:5]), green )# color format hex to decimal
    print("Blue  color decimal ", str( Color.name()[5:7]), blue ) # color format hex to decimal

    print("__.red()____________")
    print("Red   color decimal ", Color.red() )                   # extract the color RGBa with Qt (0 to 255)
    print("Green color decimal ", Color.green() )                 # extract the color RGBa with Qt (0 to 255)
    print("Blue  color decimal ", Color.blue() )                  # extract the color RGBa with Qt (0 to 255)
    print("Alpha       decimal ", Color.alpha() )                 # extract the color RGBa with Qt (0 to 255)

    print("__.redF()___________")
    print("Red   color float   ", Color.redF() )                  # extract the color RGBa with Qt (0.0 to 1.0) as FreeCAD
    print("Green color float   ", Color.greenF() )                # extract the color RGBa with Qt (0.0 to 1.0) as FreeCAD
    print("Blue  color float   ", Color.blueF() )                 # extract the color RGBa with Qt (0.0 to 1.0) as FreeCAD
    print("Alpha       float   ", Color.alphaF() )                # extract the color RGBa with Qt (0.0 to 1.0) as FreeCAD
    print("__enjoy_____________")

else:
    Color = ""


Display Image with QLabel and Gif animated with QMovie

import PySide
from PySide import QtGui ,QtCore
from PySide.QtGui import QPixmap, QMovie, QLabel
from PySide.QtCore import *
class MyLabelPatience():
    label = QtGui.QLabel()
    label.setText("<img src=" + path_Name_Image + "><b><center>Wait please</center> \n\n<center>i search the fonts !\n\n</center></b>")
    # center screen
    ecran = FreeCADGui.getMainWindow().frameGeometry()
    xF = 250; yF = 120
    xW = (ecran.width()/2) - (xF/2)
    yW = (ecran.height()/2)- (yF/2)
    label.setGeometry(xW, yW, xF, yF)
    ####
    label.setStyleSheet("QLabel {background-color : #F0C300;font: 12pt; }");
    label.setWindowFlags(Qt.WindowFlags(Qt.FramelessWindowHint))        # pas de bords (not border)
    ### un-comment for use ###############
    movie = QtGui.QMovie(path_Name_Image)    # anime le fichier Gif anime (decommenter)
    label.setMovie(movie)
    movie.start()
    ##################

patience = MyLabelPatience().label
patience.show()                    #show the image
#patience.close()                   #close the Qlabel
#MyLabelPatience().movie.start()    #start the animation (after patience.show())
#MyLabelPatience().movie.stop()     #stop animation
  • Example QLabel with image and text
Example QLabel with image


  • Example QLabel with image animated Gif
Example animated Gif

Some useful commands

# Here the code to display the icon on the '''pushButton''', 
# change the name to another button, ('''radioButton, checkBox''') as well as the path to the icon,

       # Displays an icon on the button PushButton
       # self.image_01 = "C:\Program Files\FreeCAD0.13\icone01.png" # he name of the icon
       self.image_01 = path+"icone01.png" # the name of the icon
       icon01 = QtGui.QIcon() 
       icon01.addPixmap(QtGui.QPixmap(self.image_01),QtGui.QIcon.Normal, QtGui.QIcon.Off)
       self.pushButton.setIcon(icon01) 
       self.pushButton.setLayoutDirection(QtCore.Qt.RightToLeft) # This command reverses the direction of the button


# path = FreeCAD.ConfigGet("UserAppData") # gives the user path
  path = FreeCAD.ConfigGet("AppHomePath") # gives the installation path of FreeCAD

# This command reverses the horizontal button, right to left
self.pushButton.setLayoutDirection(QtCore.Qt.RightToLeft) # This command reverses the horizontal button

# Displays an info button
self.pushButton.setToolTip(_translate("MainWindow", "Quitter la fonction", None)) # Displays an info button

# This function gives a color button
self.pushButton.setStyleSheet("background-color: red") # This function gives a color button

# This function gives a color to the text of the button
self.pushButton.setStyleSheet("color : #ff0000") # This function gives a color to the text of the button

# combinaison des deux, bouton et texte
self.pushButton.setStyleSheet("color : #ff0000; background-color : #0000ff;" ) #  combination of the two, button, and text

# replace the icon in the main window
MainWindow.setWindowIcon(QtGui.QIcon('C:\Program Files\FreeCAD0.13\View-C3P.png'))

# connects a lineEdit on execute
self.lineEdit.returnPressed.connect(self.execute) # connects a lineEdit on "def execute" after validation on enter
# self.lineEdit.textChanged.connect(self.execute) # connects a lineEdit on "def execute" with each keystroke on the keyboard

# display text in a lineEdit
self.lineEdit.setText(str(val_X)) # Displays the value in the lineEdit (convert to string)

# extract the string contained in a lineEdit
 val_X = self.lineEdit.text() # extract the (string) string contained in lineEdit
 val_X = float(val_X0)        # converted the string to an floating
 val_X = int(val_X0)          # convert the string to an integer

# This code allows you to change the font and its attributes
       font = QtGui.QFont()
       font.setFamily("Times New Roman")
       font.setPointSize(10)
       font.setWeight(10)
       font.setBold(True) # same result with tags "<b>your text</b>" (in quotes)
       self.label_6.setFont(font)
       self.label_6.setObjectName("label_6")
       self.label_6.setStyleSheet("color : #ff0000") # This function gives a color to the text
       self.label_6.setText(_translate("MainWindow", "Select a view", None))

By using the characters with accents, where you get the error :

UnicodeDecodeError: 'utf8' codec can't decode bytes in position 0-2: invalid data

Several solutions are possible.

# conversion from a lineEdit
App.activeDocument().CopyRight.Text = str(unicode(self.lineEdit_20.text() , 'ISO-8859-1').encode('UTF-8'))
DESIGNED_BY = unicode(self.lineEdit_01.text(), 'ISO-8859-1').encode('UTF-8')

or with the procedure

def utf8(unio):
    return unicode(unio).encode('UTF8')

UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 9: ordinal not in range(128)

# conversion
a = u"Nom de l'élément : "
f.write('''a.encode('iso-8859-1')'''+str(element_)+"\n")

or with the procedure

def iso8859(encoder):
    return unicode(encoder).encode('iso-8859-1')

or

iso8859(unichr(176))

or

unichr(ord(176))

or

uniteSs = "mm"+iso8859(unichr(178))
print(unicode(uniteSs, 'iso8859'))



Utveckla applikationer för FreeCAD

Använda licenser

Här är de tre licenserna under vilka FreeCAD är publicerad:

FreeCAD uses two different licenses, one for the application itself, and one for the documentation:

GPL
För Python sripten för att bygga binärfilerna som uttalat i .py filerna i src/Tools
LGPL
För kärnbiblioteken som uttalat i .h och .cpp filerna i src/App src/Gui src/Base och de flesta modulerna i src/Mod och för de körbara som uttalat i .h och .cpp filerna i src/main
Open Publication Licence
För dokumentationen på http://free-cad.sourceforge.net/ om inget annat markerats av författaren

Creative Commons Attribution 3.0 License (CC-BY-3.0) For the documentation on http://www.freecadweb.org

Se FreeCAD's debian copyright file för mer detaljer om de licenser som används i FreeCAD

Licensernas inverkan

Below is a friendlier explanation of what the LGPL license means for you:

Privata användare

Privata användare kan använda FreeCAD utan avgift och kan göra ungefär vad de vill med den....

Professionella användare

Kan använda FreeCAD fritt, för alla sorters privata eller professionella arbeten. De kan anpassa applikationen som de önskar. De kan skriva öppen eller sluten källkodsextensioner till FreeCAD. De är alltid herrar över deras data, de är inte tvingade att uppdatera FreeCAD, ändra deras bruk av FreeCAD. Att använda FreeCAD binder dem inte till några kontrakt eller krav.

Öppen källkodsutvecklare

Kan använda FreeCAD som grundplattform för egna extensionsmoduler för speciella ändamål. De kan välja antingen GPL eller LGPL för att tillåta bruk av deras arbete i proprietär mjukvara, eller inte.

Professionella utvecklare

Professionella utvecklare Kan använda FreeCAD som grundplattform för egna extensionsmoduler för speciella ändamål och är inte tvingade att göra sina moduler till öppen källkod. De kan använda alla moduler som använder LGPL. De är tillåtna att distribuera FreeCAD tillsammans med deras proprietära mjukvara. De kommer få support av författarna så länge som den inte är enkelriktad. Om du vill sälja din modul så behöver du en Coin3D licens, annars är du tvingad av detta bibliotek att göra den till öppen källkod.

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.

Uttalande från underhållaren

Jag vet att diskussionen om "rätt" licens för öppen källkod tar upp en signifikant del av internetbandbredden, så här är skälen till varför, enligt min åsikt, FreeCAD ska ha denna.

Jag valde LGPL och GPL för projektet och jag vet för- och nackdelarna med LGPL och vill ge dig några skäl till det beslutet.

FreeCAD är en blandning av bibliotek och en applikation, så GPL skulle vara lite för starkt för det. Det skulle förhindra skapande av kommersiella moduler för FreeCAD därför att det skulle förhindra länkning med FreeCAD's basbibliotek. Du kanske frågar dig: varför kommersiella moduler överhuvudtaget? Därför är Linux ett bra exempel. Skulle Linux vara så framgångsrikt om GNU C Biblioteket skulle vara GPL och därför förhindra länkning mot icke-GPL applikationer? Och fastän jag älskar friheten i Linux, så vill jag också kunna använda den mycket bra NVIDIA 3D grafikdrivrutinen. Jag förstår och accepterar anledningen till att NVIDIA inte vill ge bort drivrutinskod. Vi jobbar alla för företag och behöver lön eller åtninstone mat. Så för mig är en samexistens av öppen källkod och sluten källkodsmjukvara inte något dåligt, när det följer reglerna i LGPL. Jag skulle vilja se någon som skriver en Catia import/export processor för FreeCAD och distribuerar den gratis eller för lite pengar. Jag tycker inte om att tvinga honom att ge bort mer än han vill. Det skulle inte vara bra varken för honom eller FreeCAD.

Detta beslut är ändå bara gjort för FreeCAD's kärnsystem. Var och en som skriver en applikationsmodul kan ta sina egna beslut.

Jürgen Riegel
—15 October 2006


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

Bugreport-workflow.png

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.

Rapportera buggar

Om du tror att du funnit en bugg, så är du välkommen att rapportera den där. Men innan du rapporterar en bugg, kontrollera följande punkter:

  • Försäkra dig om att din bugg verkligen är en bugg, vilket är något som ska fungera men inte fungerar. Om du inte är säker, tveka inte att förklara ditt problem på forumet och fråga vad du ska göra.
  • Innan du skickar något, läs ofta ställda frågor, gör en sökning på forumet, och försäkra dig om att buggen inte har rapporterats innan , genom att söka i bug trackern.
  • Beskriv problemet så klart och noggrant som möjkligt, och hur det kan reproduceras. Om vi inte kan verifiera buggen, så kanske vi inte kan fixa den.
  • Skicka med följande information: Ditt operativsystem, om det är 32 eller 64 bitars, och vilken FreeCAD version du kör.
  • Var snäll och posta en separat rapport för varje bugg.
  • Om du är på ett linuxsystem och din bugg orsakar en krasch i FreeCAD, så kan du försöka köra en debug backtrace: Från en terminal så kör du gdb freecad (med antagandet att paketet gdb är installerat), sedan, inuti gdb, skriv run . FreeCAD kommer att starta. Efter att kraschen har uppstått , skriv bt , för att få hela backtracen. Inkludera denna backtrace i din buggrapport.

Begära funktioner

Om du vill ha något i FreeCAD som inte finns ännu, så är detta inte en bugg utan en funktionsbegäran. Du kan också skicka den på samma tracker (posta den som en funktionsbegäran istället för bugg), men tänk på att det finns inga garantier att din önskan blir uppfylld.

  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

Skicka patchar

Om du har programmerat en buggfix, en extension eller något annat som kan vara allmänt gångbart i FreeCAD, skapa en patch genom att använda Subversion's diff verktyg och posta den på samma tracker (posta den som en patch).

Addendumː FreeCAD development has switched to the GitHub development model so the workflow for submitting patches has been greatly enhanced/streamlined by submitting Pull Requests.

  • Open a forum thread in the Developer subforum to announce and discuss your patch.
  • Submit your PR to the FreeCAD GitHub repo. Be sure to link the forum thread in to the git commit summary.
  • Paste the PR link in to the forum thread for the devs/testers to test.
  • Be present for the discussion so that your code can potentially be merged more effectively.

NOTEː the FreeCAD community recommends to first discuss any large revision to the source code in advance to save everyone time.

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
Mantisbt-mention-example.jpg
  • #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.
Mantisbt-ticket-shortcut-example.jpg
  • ~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
Mantisbt-comment-shortcut-example.jpg
  • <del></del> - Using these tags will strikeout text.
Mantisbt-strikeout-text-example.jpg
  • <code></code> - To present a line or block of code, use this tag and it will colorize and differentiate it elegantly.
Mantisbt-colorized-code-example.jpg

MantisBT BBCode

In addition to the above Tracker/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 Tracker#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ː
Mantisbt-source-integration-markup.jpg


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

Related


This article explains step by step how to compile FreeCAD on Windows.

See also

Prerequisites

Required programs

  • Git There are a number of alternatives such as GitCola, Tortoise Git, and others.
  • CMake version 2.x.x or Cmake 3.x.x
  • Python >2.5 (This is only required if NOT using the Libpack. The Libpack comes with a minimal Python(2.7.x) suitable for compiling and running FreeCAD)

Source Code

Using Git (Preferred)

To create a local tracking branch and download the source code you need to open a terminal(command prompt) and cd to the directory you want the source, then type:

git clone https://github.com/FreeCAD/FreeCAD.git FreeCAD-code

Compiler

On Windows, the default compiler is MS Visual Studio. CI uses 2013 version.

For those who want to avoid installing the huge Visual Studio for the mere purpose of having a compiler, see CompileOnWindows - Reducing Disk Footprint.

Note

Though it may be possible to use Cygwin or MinGW gcc it's not tested or ported so far.


Third Party Libraries

You will need all of the Third Party Libraries to successfully compile FreeCAD. If you use the MS compilers it is recommended to install a FreeCAD LibPack, which provides all of the required libraries to build FreeCAD in Windows. You will need the Libpack for your architecture and compiler. FreeCAD currently supplies Libpack Version11 for x32 and x64, for VS9 2008, VS11 2012, and VS12 2013.

Optional programs

  • NSIS Windows installer (note: formerly, WiX installer was used - now under transition to NSIS) - if you want to make msi installer

System Path Configuration

Inside your system path be sure to set the correct paths to the following programs:

  • git (not tortoiseGit, but git.exe) This is necessary for Cmake to properly update the "About FreeCAD" information in the version.h file which allows FreeCAD to report the proper version in About FreeCAD from the help menu.
  • Optionally you can include the Libpack in your system path. This is useful if you plan to build multiple configurations/versions of FreeCAD, you will need to copy less files as explained later in the build process.

To add to your system path:

  • Start menu → Right click on Computer → Properties → Advanced system settings
  • Advanced tab → Environment Variables...
  • Add the PATH/TO/GIT to the PATH
  • It should be separated from the others with a semicolon `;`

Configuration with CMake

The switch to CMake

Warning

Since FreeCAD version 0.9 we have stopped providing .vcproj files.

Currently, FreeCAD uses the CMake build system to generate build and make files that can be used between different operating systems and compilers. If you want build former versions of FreeCAD (0.8 and older) see Building older versions later in this article.

We switched because it became more and more painful to maintain project files for 30+ build targets and x compilers. CMake gives us the possibility to support alternative IDEs, like Code::Blocks, Qt Creator and Eclipse CDT. The main compiler is still MS VC9 Express, though. But we plan for the future a build process on Windows without proprietary compiler software.

CMake

The first step to build FreeCAD with CMake is to configure the environment. There are two ways to do it:

  • Using the LibPack
  • Installing all the needed libraries and let CMake find them


The following process will assume you are using the LibPack. The second option may be discussed in Options for the Build Process.

Configure CMake using GUI

  • Open the CMake GUI
  • Specify the source folder
  • Specify the build folder
  • Click Configure
  • Specify the generator according to the IDE that you'll use.


This will begin configuration and should fail because the location of FREECAD_LIBPACK_DIR is unset.

  • Expand the FREECAD category and set FREECAD_LIBPACK_DIR to the correct location
  • Check FREECAD_USE_EXTERNAL_PIVY
  • Optionally Check FREECAD_USE_FREETYPE this is required to use the Draft WB's Shape String functionality
  • Click Configure again
  • There should be no errors
  • Click Generate
  • Close CMake
  • Copy libpack\bin folder into the new build folder CMake created

Options for the Build Process

The CMake build system gives us a lot more flexibility over the build process. That means we can switch on and off some features or modules. It's in a way like the Linux kernel build. You have a lot of switches to determine the build process.

Here is the description of some of these switches. They will most likely change a lot in the future because we want to increase the build flexibility a lot more.


Link table
Variable name Description Default
FREECAD_LIBPACK_USE Switch the usage of the FreeCAD LibPack on or off On Win32 on, otherwise off
FREECAD_LIBPACK_DIR Directory where the LibPack is FreeCAD SOURCE dir
FREECAD_BUILD_GUI Build FreeCAD with all Gui related modules ON
FREECAD_BUILD_CAM Build the CAM module, experimental! OFF
FREECAD_BUILD_INSTALLER Create the project files for the Windows installer. OFF
FREECAD_BUILD_DOXYGEN_DOCU Create the project files for source code documentation. OFF
FREECAD_MAINTAINERS_BUILD Switch on stuff needed only when you do a Release build. OFF

If you are building with Qt Creator, jump to Building with Qt Creator, otherwise proceed to Building with Visual Studio 9 2008.

Building FreeCAD

Depending on your current setup, the process for building FreeCAD will be slightly different. This is due to the differences in available software and software versions for each operating system.


The following procedure will work for compiling on Windows Vista/7/8, for XP an alternate VS tool set is required for VS 2012 and 2013, which has not been tested successfully with the current Libpacks. To target XP(both x32 and x64) it is recommended to use VS2008 and Libpack FreeCADLibs_11.0_x86_VC9.7z

Building with Visual Studio 12 2013

Make sure to specify Visual Studio 12 x64(or the alternate C-Compiler you are using) as the generator in CMake before you continue.

  • Start Visual Studio 12 2013 by clicking on the desktop icon created at installation.
  • Open the project by:

File → Open → Project/Solution

  • Open FreeCAD_Trunk.sln from the build folder CMake created
  • Switch the Solutions Configuration drop down at the top to Release X64

This may take a while depending on your sytem

  • Build → Build Solution
  • This will take a long time...

If you don't get any errors you are done. Exit Visual Studio and start FreeCAD by double clicking the FreeCAD icon in the bin folder of the build directory.


Building with Visual Studio 9 2008

Warning

Since early 0.17 cycle Freecad uses c++11 features that are not supported by 2008 version



Building with Qt Creator

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 Build

  • 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.


Command line build

Here an example how to build FreeCAD from the Command line:

rem @echo off
rem   Build script, uses vcbuild to completetly build FreeCAD
 
rem update trunc
d:
cd "D:\_Projekte\FreeCAD\FreeCAD_0.9"
"C:\Program Files (x86)\Subversion\bin\svn.exe" update 
 
rem  set the aprobiated Variables here or outside in the system
 
set PATH=C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem
set INCLUDE=
set LIB=
 
rem Register VS Build programms
call "C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat"
 
rem Set Standard include paths
set INCLUDE=%INCLUDE%;%FrameworkSDKDir%\include
set INCLUDE=%INCLUDE%;C:\Program Files\Microsoft SDKs\Windows\v6.0A\Include
 
rem Set lib Pathes
set LIB=%LIB%;C:\Program Files\Microsoft SDKs\Windows\v6.0A\Lib
set LIB=%LIB%;%PROGRAMFILES%\Microsoft Visual Studio\VC98\Lib
 
rem Start the Visuall Studio build process
"C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcpackages\vcbuild.exe" "D:\_Projekte\FreeCAD FreeCAD_0.9_build\FreeCAD_trunk.sln" /useenv

Building older versions

Using LibPack

To make it easier to get FreeCAD compiled, we provide a collection of all needed libraries. It's called the LibPack. You can find it on the download page on sourceforge.

You need to set the following environment variables:

FREECADLIB = "D:\Wherever\LIBPACK"
QTDIR = "%FREECADLIB%"

Add "%FREECADLIB%\bin" and "%FREECADLIB%\dll" to the system PATH variable. Keep in mind that you have to replace "%FREECADLIB%" with the path name, since Windows does not recursively replace environment variables.

Directory setup in Visual Studio

Some search path of Visual Studio need to be set. To change them, use the menu Tools→Options→Directory

Includes

Add the following search path to the include path search list:

  •  %FREECADLIB%\include
  •  %FREECADLIB%\include\Python
  •  %FREECADLIB%\include\boost
  •  %FREECADLIB%\include\xercesc
  •  %FREECADLIB%\include\OpenCascade
  •  %FREECADLIB%\include\OpenCV
  •  %FREECADLIB%\include\Coin
  •  %FREECADLIB%\include\SoQt
  •  %FREECADLIB%\include\QT
  •  %FREECADLIB%\include\QT\Qt3Support
  •  %FREECADLIB%\include\QT\QtCore
  •  %FREECADLIB%\include\QT\QtGui
  •  %FREECADLIB%\include\QT\QtNetwork
  •  %FREECADLIB%\include\QT\QtOpenGL
  •  %FREECADLIB%\include\QT\QtSvg
  •  %FREECADLIB%\include\QT\QtUiTools
  •  %FREECADLIB%\include\QT\QtXml
  •  %FREECADLIB%\include\Gts
  •  %FREECADLIB%\include\zlib
Libs

Add the following search path to the lib path search list:

  •  %FREECADLIB%\lib
Executables

Add the following search path to the executable path search list:

  •  %FREECADLIB%\bin
  • TortoiseSVN binary installation directory, usually "C:\Programm Files\TortoiseSVN\bin", this is needed for a distribution build when SubWVRev.exe is used to extract the version number from Subversion.

Python needed

During the compilation some Python scripts get executed. So the Python interpreter has to function on the OS. Use a command box to check it. If the Python library is not properly installed you will get an error message like Cannot find python.exe. If you use the LibPack you can also use the python.exe in the bin directory.

Special for VC8

When building the project with VC8, you have to change the link information for the WildMagic library, since you need a different version for VC6 and VC8. Both versions are supplied in LIBPACK/dll. In the project properties for AppMesh change the library name for the wm.dll to the VC8 version. Take care to change it in Debug and Release configuration.

Compile

After you conform to all prerequisites the compilation is - hopefully - only a mouse click in VC

After Compiling

To get FreeCAD up and running from the compiler environment you need to copy a few files from the LibPack to the bin folder where FreeCAD.exe is installed after a successful build:

  • python.exe and python_d.exe from LIBPACK/bin
  • python25.dll and python25_d.dll from LIBPACK/bin
  • python25.zip from LIBPACK/bin
  • make a copy of Python25.zip and rename it to Python25_d.zip
  • QtCore4.dll from LIBPACK/bin
  • QtGui4.dll from LIBPACK/bin
  • boost_signals-vc80-mt-1_34_1.dll from LIBPACK/bin
  • boost_program_options-vc80-mt-1_34_1.dll from LIBPACK/bin
  • xerces-c_2_8.dll from LIBPACK/bin
  • zlib1.dll from LIBPACK/bin
  • coin2.dll from LIBPACK/bin
  • soqt1.dll from LIBPACK/bin
  • QtOpenGL4.dll from LIBPACK/bin
  • QtNetwork4.dll from LIBPACK/bin
  • QtSvg4.dll from LIBPACK/bin
  • QtXml4.dll from LIBPACK/bin

When using a LibPack with a Python version older than 2.5 you have to copy two further files:

  • zlib.pyd and zlib_d.pyd from LIBPACK/bin/lib. This is needed by python to open the zipped python library.
  • _sre.pyd and _sre_d.pyd from LIBPACK/bin/lib. This is needed by python for the built in help system.

If you don't get it running due to a Python error it is very likely that one of the zlib*.pyd files is missing.

Alternatively, you can copy the whole bin folder of libpack into bin folder of the build. This is easier, but takes time and disk space. This can be substited by making links instead of copying files, see CompileOnWindows - Reducing Disk Footprint.

Additional stuff

If you whant to build the source code documentation you need DoxyGen.

To create an intstaller package you need WIX.

During the compilation some Python scripts get executed. So the Python interpreter has to work properly.

For more details have also a look to README.Linux in your sources.

First of all you should build the Qt plugin that provides all custom widgets of FreeCAD we need for the Qt Designer. The sources are located under

//src/Tools/plugins/widget//.

So far we don't provide a makefile -- but calling

qmake plugin.pro

creates it. Once that's done, calling make will create the library

//libFreeCAD_widgets.so//.

To make this library known to your Qt Designer you have to copy the file to

//$QTDIR/plugin/designer//.

References


On recent linux distributions, FreeCAD is generally easy to build, since all dependencies are usually provided by the package manager. It basically involves 3 steps:

  1. Getting the FreeCAD source code
  2. Getting the dependencies (packages FreeCAD depends upon)
  3. Configure with "cmake" and Compile with "make"

Below, you'll find detailed explanations of the whole process, some build scripts, and particularities you might encounter. If you find anything wrong or out-of-date in the text below (Linux distributions change often), or if you use a distribution which is not listed, please help us correcting it.

Getting the source

Before you can compile FreeCAD, you need the source code. You can clone it using git, or download it as an archive.

Git

The quickest and best way to get the code is to clone the read-only git repository now hosted on GitHub (you need the git package installed):

git clone https://github.com/FreeCAD/FreeCAD.git freecad-code

This will place a copy of the latest version of the FreeCAD source code in a new directory called "freecad-code".

Source archive

Alternatively you can download the source as an archive.

Getting the dependencies

To compile FreeCAD under Linux you have to install all libraries mentioned in Third Party Libraries first. Please note that the names and availability of the libraries will depend on your distribution. Note that if you don't use the most recent version of your distribution, some of the packages below might be missing from your repositories. In that case, look in the Older and non-conventional distributions section below.

Skip to Compile FreeCAD

Debian and Ubuntu

On Debian-based systems (Debian, Ubuntu, Mint, etc...) it is quite easy to get all needed dependencies installed. Most of the libraries are available via apt-get or synaptic package manager.

If you already installed FreeCAD from the official repositories, you can install its build dependencies with this single line of code in a terminal:

 sudo apt build-dep freecad
  • build-essential
  • cmake
  • python
  • python-matplotlib
  • libtool

either:

  • libcoin80-dev (Debian jessie, stretch, Ubuntu 16.04 to 18.10)

or:

  • libboost-dev
  • libboost-date-time-dev
  • libboost-filesystem-dev
  • libboost-graph-dev
  • libboost-iostreams-dev
  • libboost-program-options-dev
  • libboost-python-dev
  • libboost-regex-dev
  • libboost-signals-dev
  • libboost-serialization-dev
  • libboost-thread-dev
  • libeigen3-dev
  • libopencv-dev | libcv-dev
  • libgts-bin
  • libgts-dev
  • libkdtree++-dev
  • libmedc-dev
  • libproj-dev
  • libvtk6-dev | libvtk7-dev
  • libx11-dev
  • libxerces-c-dev
  • libzipios++-dev
  • lsb-release
  • swig

with Qt4 and Python 2 (for Debian jessie, stretch, Ubuntu 16.04):

  • libqt4-dev
  • libqt4-opengl-dev
  • libqtwebkit-dev
  • libshiboken-dev
  • libpyside-dev
  • python-dev
  • python-pivy
  • python-ply
  • python-pyside
  • pyside-tools
  • qt4-dev-tools

or with Qt5 and Python 3 (Debian buster, Ubuntu 19.04 and forward, as well as Ubuntu 18.04/18.10 with the freecad-stable/freecad-daily PPAs added to your software sources:

  • libqt5opengl5-dev
  • libqt5svg5-dev
  • libqt5webkit5-dev or qtwebengine5-dev
  • libqt5x11extras5-dev
  • libpyside2-dev
  • libshiboken2-dev
  • pyside2-tools
  • python3-dev
  • python3-pivy
  • python3-ply
  • python3-pyside2.qtcore
  • python3-pyside2.qtgui
  • python3-pyside2.qtsvg
  • python3-pyside2.qtwidgets
  • python3-pyside2uic
  • qtbase5-dev
  • qttools5-dev

either:

  • libocct*-dev (official opencascade version, up-to-date, available in Debian buster and Ubuntu 18.10 and forward, as well as Ubuntu 18.04 with the freecad-stable/freecad-daily PPAs added to your software sources)
  • occt-draw

or:

  • liboce*-dev (opencascade community edition, outdated, available in Debian jessie, stretch, Ubuntu 16.04 and forward)
  • oce-draw

Note that liboce*-dev/libocct*-dev include the following libraries (substitute oce for occt):

  • liboce-foundation-dev
  • liboce-modeling-dev
  • liboce-ocaf-dev
  • liboce-visualization-dev
  • liboce-ocaf-lite-dev

You may have to install these packages by individual name.

Optionally you can also install these extra packages:

  • libsimage-dev (to make Coin to support additional image file formats)
  • checkinstall (to register your installed files into your system's package manager, so you can easily uninstall later)
  • python-matplotlib
  • doxygen and libcoin80-doc (if you intend to generate source code documentation)
  • libspnav-dev (for 3Dconnexion devices support like the Space Navigator or Space Pilot)


Single command for Qt5 and Python 3 (requires Pyside2 available in Debian buster and the freecad-stable/freecad-daily PPAs)

sudo apt install cmake debhelper dh-exec dh-python libboost-date-time-dev libboost-dev libboost-filesystem-dev libboost-graph-dev libboost-iostreams-dev libboost-program-options-dev libboost-python-dev libboost-regex-dev libboost-serialization-dev libboost-signals-dev libboost-thread-dev libcoin-dev libcv-dev libeigen3-dev libgts-bin libgts-dev libkdtree++-dev libmedc-dev libocct-data-exchange-dev libocct-ocaf-dev libocct-visualization-dev libopencv-dev libproj-dev libpyside2-dev libqt5opengl5-dev libqt5svg5-dev libqt5x11extras5-dev libshiboken2-dev libspnav-dev libvtk7-dev libx11-dev libxerces-c-dev libzipios++-dev lsb-release occt-draw pyside2-tools python-matplotlib python3-dev python3-pivy python3-ply python3-pyside2.qtcore python3-pyside2.qtgui python3-pyside2.qtsvg python3-pyside2.qtwidgets python3-pyside2uic qtbase5-dev qttools5-dev libqt5webkit5-dev swig

Single command for Qt4 and Python 2

sudo apt install cmake debhelper dh-exec dh-python libboost-date-time-dev libboost-dev libboost-filesystem-dev libboost-graph-dev libboost-iostreams-dev libboost-program-options-dev libboost-python-dev libboost-regex-dev libboost-serialization-dev libboost-signals-dev libboost-thread-dev libcoin80-dev libopencv-dev libeigen3-dev libgts-bin libgts-dev libkdtree++-dev libmedc-dev libocct-data-exchange-dev libocct-ocaf-dev libocct-visualization-dev libproj-dev libpyside-dev libqt4-dev libqt4-opengl-dev libqtwebkit-dev libshiboken-dev libspnav-dev libvtk6-dev libx11-dev libxerces-c-dev libzipios++-dev lsb-release occt-draw pyside-tools python-dev python-matplotlib python-pivy python-ply swig

Ubuntu 16.04 users please see also these additional instructions.

Fedora

You need the following packages :

  • gcc-c++ (or possibly another C++ compiler?)
  • cmake
  • doxygen
  • swig
  • gettext
  • dos2unix
  • desktop-file-utils
  • libXmu-devel
  • freeimage-devel
  • mesa-libGLU-devel
  • OCE-devel
  • python
  • python-devel
  • python-pyside-devel
  • pyside-tools
  • boost-devel
  • tbb-devel
  • eigen3-devel
  • qt-devel
  • qt-webkit-devel
  • ode-devel
  • xerces-c
  • xerces-c-devel
  • opencv-devel
  • smesh-devel
  • coin3-devel

(if coin2 is the latest available for your version of Fedora, use packages from http://www.zultron.com/rpm-repo/)

  • soqt-devel
  • freetype
  • freetype-devel

And optionally :

Gentoo

Easiest way to check which packages are needed to compile FreeCAD is to check via portage:

emerge -pv freecad

This should give a nice list of extra packages that you need installed on your system.

If FreeCAD is not available on portage, it is available on the waebbl overlay. The issue tracker on the waebbl overlay Github may help guide through some issues you may come across. The overlay provides freecad-9999, which you can choose to compile, or simply use to get the dependencies.

layman -a waebbl

openSUSE

Tumbleweed

The following commands will install the packages required for building FreeCAD with Qt5 and Python 3.

zypper in --no-recommends -t pattern devel_C_C++ devel_qt5

zypper in libqt5-qtbase-devel libqt5-qtsvg-devel libqt5-qttools-devel boost-devel swig libboost_program_options-devel libboost_mpi_python3-devel libboost_system-devel libboost_program_options-devel libboost_regex-devel libboost_python3-devel libboost_thread-devel libboost_system-devel libboost_headers-devel libboost_graph-devel python3 python3-devel python3-matplotlib python3-matplotlib-qt5 python3-pyside2 python3-pyside2-devel python3-pivy gcc gcc-fortran cmake occt-devel libXi-devel opencv-devel libxerces-c-devel Coin-devel SoQt-devel freetype2-devel eigen3-devel libode6 vtk-devel libmed-devel hdf5-openmpi-devel openmpi2-devel netgen-devel freeglut-devel libspnav-devel f2c doxygen dos2unix glew-devel

The following command will install Qt Creator and the GNU Project Debugger.

zypper in libqt5-creator gdb

If any packages are missing, then you can check the Tumbleweed "FreeCAD.spec" file on the Open Build Service.

Also, check to see if there are any patches you need to apply (such as 0001-find-openmpi2-include-files.patch).

Leap

If there is a difference between the available packages on Tumbleweed and Leap, then you can read the Leap "FreeCAD.spec" file on the Open Build Service to determine the required packages.

Arch Linux

You will need the following libraries from the official repositories:

  • boost-libs
  • curl
  • hicolor-icon-theme
  • libspnav
  • opencascade
  • python2-matplotlib
  • shared-mime-info
  • xerces-c
  • boost
  • cmake
  • desktop-file-utils
  • eigen
  • gcc-fortran
  • swig

Also, make sure to check the AUR for any missing packages that are not on the repositories, currently:

  • coin
  • python2-pivy
  • python2-pyside
  • python2-pyside-tools
  • python2-shiboken
  • qtwebkit
  • med (Modelisation et Echanges de Donnees)
sudo pacman -S boost-libs curl hicolor-icon-theme libspnav opencascade python2-pivy python2-matplotlib python2-pyside python2-shiboken qtwebkit shared-mime-info xerces-c boost cmake coin desktop-file-utils eigen gcc-fortran med python2-pyside-tools

Older and non-conventional distributions

On other distributions, we have very few feedback from users, so it might be harder to find the required packages. Try first locating the required libraries mentioned in Third Party Libraries. Beware that some of them might have a slightly different package name in your distribution (such as name, libname, name-dev, name-devel, etc...).

You also need the GNU gcc compiler version equal or above 3.0.0. g++ is also needed because FreeCAD is completely written in C++. During the compilation some Python scripts get executed. So the Python interpreter has to work properly. To avoid any linker problems during the build process it is also a good idea to have the library paths either in your LD_LIBRARY_PATH variable or in your ld.so.conf file. This is normally already the case in recent distributions.

For more details have also a look to README.Linux in your sources.

Pivy

Pivy is not needed to build FreeCAD or to run it, but it is needed for the Draft module to work. If you are not going to use that module, you won't need pivy. By November 2015 the obsolete version of Pivy included with FreeCAD source code will no longer compile on many systems, due to its age. If you cannot find Pivy in your distribution's packages repository or elsewhere, you can compile pivy yourself:

Pivy compilation instructions

Compile FreeCAD

FreeCAD uses CMake as its main build system. CMake is a build system available on all major operating systems. Compiling with CMake is usually very simple and happens in two steps.

  1. CMake checks that every needed program and library is present on your system, and configures the build system for the second step. FreeCAD has several configuration options to choose from, but it comes with sensible defaults. Some alternatives are detailed below.
  2. The compilation itself, which produces the FreeCAD executable.

Since FreeCAD is a large application, compiling can take between 10-30 minutes, depending on the power of the hardware performing the compilation.

You can build the code either in or out of the source directory. Out-of-source building is generally the best option.

Out-of-source build

If you intend to follow the fast evolution of FreeCAD, building in a separate folder is much more convenient than an in-source build. Every time you update the source code, CMake can intelligently determine which files have changed, and recompile only what is needed. Out-of-source builds are specially handy when using the Git system, because you can easily try other branches without confusing the build system. To build out-of-source, simply create a build directory, distinct from your FreeCAD source folder, and, from the build folder, point CMake (or if using cmake-gui replace "cmake" in the code below with "cmake-gui") to the source folder:

$ mkdir freecad-build
$ cd freecad-build
$ cmake ../freecad-code (or whatever the path is to your FreeCAD source folder)
$ make -j$(nproc --ignore=2)

The FreeCAD executable will then reside in the freecad-build/bin directory.

In-source building

In-source builds are fine if you are just looking at FreeCAD, and want to be able to remove it easily by just deleting that folder.

The following commands will compile FreeCAD:

$ cd freecad-source
$ cmake .
$ make -j$(nproc --ignore=2)

The FreeCAD executable will then reside in the freecad-source/bin directory.

How to repair your source code directory after accidentally running an in-source build

This is a method, using Git, to repair your source code directory after accidentally running an in-source build. If you do not clear it, subsequent runs of cmake may not capture all of your new options.

$ > .gitignore
$ git clean -df
$ git reset --hard HEAD

The first line clears the .gitignore file. This ensures that the following clean and reset commands will affect everything in the directory and will not ignore items matching the expressions in .gitignore. The second line deletes all files and directories that are not tracked by the git repository, and then the reset will reset any changes to tracked files (including the first command which cleared the .gitignore file.

Configuration

By passing different options to CMake, you can change how FreeCAD is compiled. This can be useful for several purposes. For example, by calling CMake like this, you can instruct it to not build the FEM module:

cmake -D BUILD_FEM:BOOL=OFF ''path-to-freecad-root''

All possible options are listed in FreeCAD's root CMakeLists.txt file. Try searching for the string OPTION. Alternatively, use the command cmake -LH. Below, we've listed some of the more relevant options you may want to configure.

To pass a value for an option you find in the CMakeLists.txt file, use the following flag: -D <var>:<type>=<value>

For a Debug build

$ cmake -DCMAKE_BUILD_TYPE=Debug .

For a Release build

A Release build will run much faster than a Debug build. Sketcher becomes very slow with complex sketches if your FreeCAD is a Debug build.

$ cmake -DCMAKE_BUILD_TYPE=Release .

External, or internal Pivy

If you want to use your system's copy of Pivy, which you most commonly will, then if