Questo è il manuale FreeCAD. Comprende le parti essenziali del Wiki della documentazione di FreeCAD.
Questa versione è stata creata principalmente per essere stampata come un unico grande documento.
Se si sta leggendo questo online, si consiglia di andare direttamente alla Guida in linea, che è più facile da esplorare.
Questa documentazione è stata creata automaticamente a partire dai contenuti del wiki ufficiale di FreeCAD, raggiungibile anche attraverso l'indirizzo http://www.freecadweb.org/wiki/index.php?title=Main_Page. Poiché il wiki on-line è aggiornato e revisionato con continuità dalla community di FreeCAD, è possibile che la documentazione disponibile on-line sia più esaustiva e completa. In ogni caso crediamo che questa documentazione contenga tutte le informazioni che possono essere utili. Se così non fosse è possibile consultare il forum di FreeCAD, dove qualcuno sarà sicuramente in grado di aiutarvi.
Questo manuale è diviso in varie sezioni: Introduzione, utilizzo, scripting e sviluppo. Le ultime tre sezioni sono rivolte a diverse tipologie di utenti: utilizzatore, interessato al semplice utilizzo del programma; power-user, interessato allo sviluppo di script ed a personalizzazioni avanzate dell'ambiente; sviluppatore, che considera FreeCAD una base di partenza per la stesura di applicazioni personali per gli scopi più disparati. Se siete del tutto nuovi in FreeCAD vi consigliamo di partire dalla sezione: Introduzione.
Come sicuramente vi sarà capitato di constatare, i programmatori sono pessimi scrittori di guide e di help! Per loro, naturalmente, è tutto estremamente chiaro, avendo sviluppato personalmente tutte le caratteristiche del programma. E' quindi fondamentale, che gli utenti più esperti diano una mano nella stesura degli help e nella loro correzione. Già, ci riferiamo proprio a te! Ti stai chiedendo come? Semplice, accedi alla home del wiki dall'indirizzo http://www.freecadweb.org/wiki/index.php nella sezione User. Avrai bisogno di un account di sourceforge per loggarti, dopodiché puoi iniziare a dare il tuo contributo! Inoltre, guarda nella pagina http://www.freecadweb.org/wiki/index.php?title=Help_FreeCAD/it per vedere in quali altri modi si può aiutare FreeCAD.
FreeCAD è un software CAD di modellazione parametrica 3D. Lo sviluppo ed il codice sorgente vengono portati aventi tramite la filosofia Open Source (Licenza LGPL). FreeCAD è studiato per l'ingegneria meccanica e per il product design (progettazione del prodotto) ma è sfruttabile per un'ampia gamma di applicazioni, che vanno dall'architettura ad altre discipline ingegneristiche.
L'utilizzo e le funzioni di FreeCAD sono simili a quelle di Catia, SolidWorks o Solid Edge, e rientra anche nella categoria di MCAD, PLM, CAx e CAE. È un Modellatore parametrico di solidi con una architettura modulare che permette l'aggiunta e lo sviluppo di nuove funzioni con estrema facilità, senza modificare il "cuore" del software.
Come ogni moderno strumento di modellazione 3D CAD è provvisto di uno strumento di visualizzazione in 2D a partire dal modello spaziale, ma il disegno in 2D di tipo AutoCAD LT non è lo scopo del software, e non rientrano negli interessi principali neanche le animazioni come Maya, 3ds Max, Blender o Cinema 4D, anche se, grazie alla sua estrema flessibilità, FreeCAD può essere molto utile in numerosi altri campi che non fanno parte dei suoi interessi attuali.
FreeCAD fa abbondante uso delle eccellenti librerie open-source disponibili nel campo della computazione scientifica. Tra questi OpenCascade, un potente kernel CAD, Coin3D, che incarna gli intenti di Open Inventor, Qt, il framework per lo sviluppo di Interfacce Utente, e Python, uno dei migliori linguaggi di script attualmente disponibili. FreeCAD può anche essere utilizzato come libreria per altri software.
Inoltre, FreeCAD è totalmente multi-piattaforma, ed allo stato attuale è in grado di funzionare senza problemi su Windows, Linux/Unix e Mac OSX, conservando inalterate le caratteristiche e le funzionalità su ognuna di queste piattaforme.
Per ulteriori informazioni sulle funzionalità di FreeCAD, date un'occhiata alle caratteristiche, muovete i primi passi, oppure accedete direttamente al Centro utente, o vedere gli screenshot.
Il progetto FreeCAD è stato avviato fino al 2001, come descritto nella pagina Storia di FreeCAD.
FreeCAD è mantenuto e sviluppato da una comunità di sviluppatori appassionati e utenti (vedere la pagina credits). Essi lavorano su FreeCAD volontariamente, nel loro tempo libero. Non possono garantire che FreeCAD contenga o conterrà tutto ciò che si potrebbe desiderare, ma di solito fanno del loro meglio! La comunità si ritrova sul FreeCAD forum, dove sono discusse la maggior parte delle idee e delle decisioni. Sentitevi liberi di unirvi a noi!
Questa è una lista estesa, ma non completa, delle funzionalità (caratteristiche) già implementate in FreeCAD.
Se siete interessati a conoscere gli sviluppi futuri è possibile consultare il Piano di sviluppo.
Per un approccio sommario alle caratteristiche sono anche disponibili gli screenshot.
Alcuni utenti esperti hanno creato vari ambienti complementari personalizzati.
Il modo più semplice per installare FreeCAD su Windows è quello di scaricare il sottostante programma di installazione.
Windows 32 bits
Windows 64 bits
Dopo aver scaricato il file .msi (Microsoft Installer), è sufficiente fare doppio clic su di esso per avviare il processo di installazione automatica.
Più avanti sono riportate ulteriori informazioni sulle opzioni tecniche.
Se appaiono scoraggianti, nessuna preoccupazione, ignoratele! La maggior parte degli utenti Windows ha bisogno solo del file .msi per installare e iniziare ad usare FreeCAD!
Per scaricare una versione a 64 bit o una versione instabile di sviluppo, vedere la pagina Download (it) oppure la pagina originale Download (en).
Con l'utility a riga di comando msiexec.exe, sono disponibili funzioni aggiuntive, quali l'installazione non interattiva e l'installazione amministrativa.
L'installazione si avvia con il comando:
msiexec /i FreeCAD<version>.msi
Alla fine di questa riga di comando è possibile fornire i parametri aggiuntivi, come nel caso in cui si vuole specificare la directory di destinazione:
msiexec /i FreeCAD-2.5.msi TARGETDIR=r:\FreeCAD25
La dimensione dell'interfaccia utente che visualizza installazione può essere controllata con le opzioni /q, in particolare:
La proprietà TARGETDIR determina la directory principale di installazione di FreeCAD.
Ad esempio, si può specificare una diversa unità di installazione con
TARGETDIR=R:\FreeCAD25
La cartella di destinazione predefinita (TARGETDIR di default) è [WindowsVolume\Programm Files\]FreeCAD<version>.
Aggiungendo
ALLUSERS=1
si realizza una installazione per tutti gli utenti.
Come impostazioni predefinite, l'installazione non interattiva installa il pacchetto solo per l'utente corrente mentre l'installazione interattiva mostra una finestra di dialogo che ha come impostazione predefinita "Tutti gli utenti" se l'utente attuale ha, in Windows, i permessi necessari.
Varie proprietà permettono la selezione delle funzioni da installare, reinstallare, o rimuovere.
Il set di funzioni dell'installatore di FreeCAD è:
Inoltre, ALL specifica (installa) tutte le funzioni.
Tutte le funzioni dipendono da DefaultFeature, quindi installando qualsiasi funzione si installano automaticamente anche le funzione di default.
Le seguenti proprietà controllano le operazioni di installazione o di rimozione:
Ci sono alcune altre proprietà aggiuntive disponibili, vedere la documentazione MSDN per i dettagli.
Con queste opzioni, aggiungendo
ADDLOCAL=Extensions
installa l'interprete e registra le estensioni, ma non installa niente altro.
Si può disinstallare FreeCAD con:
msiexec /x FreeCAD<version>.msi
Per la disinstallazione, non è necessario disporre del file MSI; in alternativa, può anche essere specificato il codice del pacchetto o del prodotto.
Per trovare il codice del prodotto, esplorare le proprietà del collegamento per la disinstallazione che FreeCAD installa nel menu di Avvio.
Si può iniziare una installazione "amministrativa" (da rete) con:
msiexec /a FreeCAD<version>.msi
I file vengono decompressi nella directory di destinazione (che dovrebbe essere una directory in rete), ma non vengono apportate altre modifiche al sistema locale.
Inoltre, viene generato un altro file .msi (più piccolo) nella directory di destinazione, che i clienti possono utilizzare per eseguire un'installazione locale (le future versioni potrebbero anche offrire di mantenere alcune funzioni sull'unità di rete).
Attualmente non esiste alcuna interfaccia per le installazioni amministrative.
La directory di destinazione deve essere specificata nella riga di comando.
Non esiste una specifica procedura di disinstallazione, basta cancellare la directory di destinazione se non è più utilizzata da nessun client.
Con
msiexec /jm FreeCAD<version>.msi
è possibile, all'inizio, "annunciare" FreeCAD a una macchina (con /jm oppure ad un utente con /ju).
In questo modo, le icone appaiono nel menu Start e le estensioni vengono registrate senza che il software venga effettivamente installato.
Il primo uso di una funzione provoca l'installazione della funzione stessa.
L'installatore di FreeCAD attualmente supporta solo l'annuncio per le voci del menu di avvio, ma non supporta l'annuncio per i comandi di avvio veloce.
Utilizzando i criteri di gruppo di Windows, è possibile automatizzare l'installazione di FreeCAD su un gruppo di macchine.
Per effettuare questa operazione, attenersi alla seguente procedura:
La propagazione dei criteri di gruppo richiede in genere un po 'di tempo - per distribuire in modo affidabile il pacchetto, tutte le macchine dovrebbero essere riavviate.
È possibile installare la versione Windows di FreeCAD su un sistema Linux utilizzando CXOffice 5.0.1.
Eseguire msiexec dalla riga di comando di CXOffice.
Supponendo che il pacchetto di installazione si trovi nella directory "software", nell'unità "Y:":
msiexec /i Y:\\software\\FreeCAD<version>.msi
FreeCAD viene eseguito, ma è stato riferito che OpenGL non funziona, come succede con altri programmi che girano sotto [Wine], quali ad esempio [SketchUp].
L'installazione di FreeCAD sui sistemi Linux più noti ora è stata approvata dalla comunità e FreeCAD dovrebbe essere accessibile direttamente tramite il "Gestore dei pacchetti" disponibile nella propria distribuzione. Il team di FreeCAD fornisce inoltre i pacchetti "ufficiali" quando sono rilasciate le nuove versioni, e fornisce i repository PPA sperimentali per testare le ultime caratteristiche sviluppate.
Appena terminata l'installazione di FreeCAD, è ora di iniziare!
Molte distribuzioni Linux sono basate su Ubuntu e condividono i suoi repository. Per altre varianti ufficiali (Kubuntu, Xubuntu e Lubuntu), ci sono distro non ufficiali come per Linux Mint, Voyager e altri. Le opzioni di installazione riportate in seguito dovrebbero essere compatibili con tali sistemi.
FreeCAD è disponibile nei repository di Ubuntu e può essere installato tramite il Centro Software o tramite il terminale con:
sudo apt-get install freecad
ma è probabile che la versione installata in questo modo non sia aggiornata e non possieda le ultime caratteristiche. Per ottenere l'ultima versione rilasciata, si prega di utilizzare il PPA.
Per installare FreeCAD utilizzando il PPA dall'interfaccia grafica, si prega di seguire queste istruzioni. La comunità FreeCAD fornisce un PPA repository on Launchpad con l'ultima versione di FreeCAD stabile.
È necessario aggiungere alle Sorgenti software del sistema il seguente PPA. Per farlo aprire il Software Centre> Modifica Sorgenti> Software> Altro software. Fare clic su Aggiungi e copiare e incollare il codice sottostante:
ppa:freecad-maintainers/freecad-stable
Aggiornare le sorgenti del software, se richiesto. Ora, è possibile trovare ed installare l'ultima versione stabile di FreeCAD da Ubuntu Software Center.
Per avere ulteriori informazioni sui PPA, cliccare qui: Definition of PPA (Personal Package Archive) on help.ubuntu.com.
Digitare (o copia-incolla) questi comandi in una console per aggiungere il PPA e installare FreeCAD con la sua documentazione:
Per il PPA "stable"
sudo add-apt-repository ppa:freecad-maintainers/freecad-stable
Non dimenticare di recuperare l'elenco aggiornato dei pacchetti:
sudo apt-get update
Update sincronizza il proprio elenco dei pacchetti con quelli disponibili sul server.
Poi, installare FreeCAD con la sua documentazione:
sudo apt-get install freecad freecad-doc && sudo apt-get upgrade
Upgrade scarica e installa la versione più recente dei pacchetti dei programmi installati. Viene applicato a tutti i software installati sul computer.
Per avviare la versione stabile di FreeCAD eseguire questo comando:
freecad
Se si desidera installare l'ultima versione instabile di FreeCAD, utilizzare il PPA denominato "freecad-daily" repositorio PPA su Launchpad. In questo modo è possibile accedere alla versione più evoluta di FreeCAD. Questo PPA viene compilato automaticamente tutti i giorni dal ramo master del repositorio ufficiale di FreeCAD. Di solito contiene numerose correzioni di bug e gli ultimi aggiornamenti di funzionalità.
Per il PPA "daily"
sudo add-apt-repository ppa:freecad-maintainers/freecad-daily sudo apt-get update sudo apt-get install freecad-daily && sudo apt-get upgrade
Per avviare la versione daily build di FreeCAD eseguire questo comando :
freecad-daily
A partire da Debian Lenny, FreeCAD è disponibile direttamente nei repository di software Debian e può essere installato tramite Synaptic o semplicemente con:
sudo apt-get install freecad
FreeCAD si installa normalmente con:
zypper install FreeCAD
FreeCAD si può costruire/installare semplicemente eseguendo:
emerge freecad
Se scoprite che il vostro sistema è dotato di FreeCAD, ma in questa pagina non è documentato, per favore comunicatelo tramite il forum!
Sulla rete sono disponibili diversi pacchetti alternativi non ufficiali di FreeCAD, ad esempio per sistemi come Slackware o Fedora. Una ricerca in rete può dare rapidamente buoni risultati.
Se per qualche motivo non è possibile utilizzare uno dei metodi di cui sopra, si può sempre scaricare uno dei pacchetti .deb disponibili nella pagina Download.
Dopo aver scaricato la versione .deb corrispondente al proprio sistema, se è installato il pacchetto Gdebi (di solito lo è), basta spostarsi nella cartella del file scaricato e fare doppio clic su di esso. Le dipendenze necessarie sono installate automaticamente dal gestore del sistema. In alternativa è possibile installare il pacchetto dal terminale; spostarsi nella cartella che contiene il file e digitare:
sudo dpkg -i Name_of_your_FreeCAD_package.deb
sostituendo a Name_of_your_FreeCAD_package.deb il nome del file scaricato
Terminata l'installazione di FreeCAD, nella sezione "Grafica" del Menu Start viene aggiunta l'icona per avviarlo.
Purtroppo, al momento, nessun pacchetto precompilato è disponibile per altri sistemi Linux / Unix, quindi è necessario compilare FreeCAD da soli.
Vedere la pagina Installazione in Windows.
FreeCAD può essere installato su Mac OS X in una unica operazione usando l'installer seguente.
Mac 10.9 Mavericks 64-bit
Questa pagina descrive l'uso e le caratteristiche del programma di installazione di FreeCAD. Essa comprende anche le istruzioni di disinstallazione.
Terminata l'installazione, è possibile iniziare!
L'installatore di FreeCAD viene fornito come pacchetto di installazione (.app) incluso in un file di immagine disco.
È possibile scaricare l'ultima versione dell'installatore dalla pagina Download. Dopo aver scaricato il file, basta montare l'immagine, poi trascinarla nella cartella Applicazioni o in una cartella a scelta..
Questo è tutto. Basta cliccare sulla app per lanciare FreeCAD. Se si riceve il messaggio "FreeCAD non può essere aperto in quanto proviene da uno sviluppatore non identificato", aprire la cartella (Applicazione) e fare clic destro sulla App quindi fare clic su apri e accettare di aprire l'applicazione.
Attualmente non c'è un programma di disinstallazione per FreeCAD. Per rimuovere completamente FreeCAD e tutti i componenti installati, trascinare i seguenti file e cartelle nel cestino:
Tutto qui.
FreeCAD è una applicazione per la modellazione parametrica di tipo CAD/CAE. È fatto principalmente per la progettazione meccanica, ma serve anche in tutti casi in cui è necessario modellare degli oggetti 3D con precisione e avere il controllo dello storico della modellazione.
Nonostante FreeCAD sia ancora nella fase iniziale del suo sviluppo, offre già un lunga lista (che continua a aumentare) di funzionalità, ma ne mancano ancora molte altre, specialmente rispetto alle soluzioni commerciali, quindi potreste ritenerlo non ancora abbastanza sviluppato per essere usato in ambito produttivo. Ciò nonostante, c'è una comunità in rapida crescita di utenti entusiasti, e si possono già trovare molti esempi di progetti di qualità sviluppati con FreeCAD.
Come tutti i progetti open-source, il progetto FreeCAD non è un lavoro a senso unico che gli sviluppatori vi consegnano. La crescita del progetto, l'acquisizione di nuove funzionalità e la stabilità dell'applicazione (la correzione dei bug) dipendono molto dalla sua comunità. Quindi non dimenticate questo quando iniziate ad utilizzare FreeCAD, e se vi piace, potete contribuire e aiutare il progetto!
Per iniziare è necessario scaricare ed installare FreeCAD. Consultare la pagina (Download/en) Download/it per ottenere informazioni sulla versione corrente e sugli ultimi aggiornamenti. Sono disponibili i file di installazione per Windows (.msi), Ubuntu & Debian (.deb), openSUSE (.rpm) e Mac OSX. Dato che FreeCAD è open-source, se siete avventurosi e volete vedere le ultime funzionalità che in questo momento sono in fase di sviluppo, potete anche prelevare il codice sorgente e compilarlo (en).
Il concetto principale è che, dietro la sua interfaccia, FreeCAD è suddiviso in ambienti di lavoro. Ogni ambiente raggruppa gli strumenti idonei a svolgere un compito specifico, come ad esempio lavorare con gli oggetti mesh, oppure disegnare oggetti 2D o schizzi vincolati. È possibile cambiare l'ambiente corrente con il selettore (6). Si può personalizzare il set di strumenti inclusi in ogni ambiente, aggiungere degli strumenti da altri ambienti o anche aggiungere strumenti di propria creazione, che noi chiamiamo macro. Vi è anche un ambiente di lavoro generico denominato Completo che riunisce gli strumenti di uso più comune dagli altri ambienti.
Al primo avvio di FreeCAD viene visualizzato lo start center:
Lo Start Center permette di passare rapidamente a uno degli ambienti di lavoro più comuni, di aprire uno dei file recenti, oppure di vedere le ultime novità dal mondo di FreeCAD. Nelle preferenze è possibile modificare l'ambiente di lavoro predefinito.
FreeCAD permette di interagire con lo spazio 3D in diverse modalità di navigazione selezionabili nel dialogo delle preferenze oppure cliccando con il tasto destro nella vista 3D. Uno di essi è specifico per la Navigazione Touchpad, dove non si usa il tasto centrale del mouse.
Per la modalità di default, la "Navigazione CAD", i comandi sono i seguenti:
Selezione | Traslazione | Zoom | Rotazione | |
---|---|---|---|---|
![]() |
![]() |
![]() |
![]() | |
Premere il tasto sinistro del mouse sull'oggetto che si desidera selezionare. Tenere premuto il tasto Ctrl per selezionare più oggetti. | Fare clic sul pulsante centrale del mouse e muovere il mouse per spostare l'oggetto. Inoltre, per attivare la traslazione, si può tenere premuto Ctrl e cliccare con il tasto destro. In questo modo la funzione rimane attiva, senza impegnare la mano del mouse, e permette l'uso della rotellina per lo zoom, fino a quando il tasto Ctrl non viene rilasciato. |
Ruotare la rotellina del mouse per ingrandire e ridurre. | Premere e mantenere premuto il tasto centrale del mouse, fare clic con il pulsante sinistro, o destro, del mouse su qualsiasi parte visibile di un oggetto e trascinarlo nella direzione desiderata. La posizione del cursore nel momento in cui si preme il pulsante centrale del mouse determina il centro di rotazione. La rotazione funziona come nel caso di una palla che ruota attorno al suo centro. Se i tasti vengono rilasciati prima di arrestare il movimento e se l'opzione Abilita animazione è attivata, l'oggetto continua la rotazione automaticamente. Un doppio clic con il tasto centrale del mouse su qualsiasi parte di un oggetto imposta un nuovo centro di rotazione e di zoom in tale punto. Il secondo metodo può essere utile ai mancini. Inoltre, per attivare la rotazione, si può tenere premuto Maiusc (Shift) e cliccare con il tasto destro. In questo modo la funzione rimane attiva, senza impegnare la mano del mouse, e permette l'uso dello zoom, fino a quando il tasto Maiusc non viene rilasciato.
| |
Premere Ctrl, cliccare sul tasto destro, rilasciarlo e spostare il mouse per spostare la vista (rev 0.17) | Premere Ctrl, cliccare sul tasto destro, rilasciarlo, cliccare sul tasto sinistro, rilasciarlo e spostare il mouse per zoommare (rev 0.17) | Premere Maiusc, cliccare sul tasto destro, rilasciarlo e spostare il mouse per ruotare la vista (rev 0.17) |
Inoltre, sono disponibili alcune viste preconfigurate (dall'alto, laterale, frontale, ecc) accessibili dal menu Visualizza → Viste standard oppure tramite i pratici comandi veloci dei tasti numerici ( 1, 2, 3 etc...)
L'obiettivo di FreeCAD è quello di consentire di creare dei modelli 3D di alta precisione mantenendo uno stretto controllo sui modelli per essere in grado di tornare indietro nello storico della modellazione e di variare i parametri, e alla fine di costruire quei modelli (attraverso la stampa 3D, CNC o anche la costruzione in cantiere). È quindi molto diverso da alcune applicazioni 3D realizzate per altri scopi, come ad esempio per i film di animazione o per i giochi. La sua curva di apprendimento può essere ripida, specialmente se questo è il primo contatto con la modellazione 3D. Quando si rimane bloccati in un certo punto, ricordarsi che nel FreeCAD forum c'è una comunità amichevole di utenti può essere in grado di fornire un aiuto in breve tempo.
L'ambiente di lavoro con cui iniziare a lavorare in FreeCAD dipende dal tipo di lavoro si intende realizzare. Quando si ha intenzione di lavorare su modelli meccanici, o più in generale su qualsiasi oggetto di piccole dimensioni, probabilmente si vuole provare Part Design. Se si lavora in 2D, allora conviene passare all'ambiente Draft, o all'ambiente Sketcher quando servono i vincoli. Se si vuole fare BIM, avviare l'ambiente Architettura. Se si lavora con il disegno navale, è disponibile uno speciale ambiente Ship. Se si proviene dal mondo di OpenSCAD, si può provare l'ambiente OpenSCAD.
È possibile commutare gli ambienti di lavoro in qualsiasi momento, e anche personalizzare il proprio ambiente preferito aggiungendovi degli strumenti di altri ambienti.
PartDesign è fatto appositamente per costruire oggetti complessi, partendo da forme semplici a cui aggiungere o rimuovere dei pezzi (che noi chiamiamo "caratteristiche"), fino a ottenere l'oggetto finale. Tutte le caratteristiche applicate durante il processo di modellazione vengono memorizzate in una vista separata denominata vista a albero, che contiene anche gli altri oggetti del documento. Si può pensare ad un oggetto di PartDesign come a una successione di operazioni, ciascuna applicata al risultato di quella precedente, formando una grande catena. Nella vista ad albero, si vede l'oggetto finale, ma è possibile espanderla e recuperare tutti gli stati precedenti, e modificare i loro parametri, questo aggiorna automaticamente l'oggetto finale.
L'ambiente PartDesign fa uso importante di un altro ambiente, l'ambiente Sketcher. Sketcher permette di disegnare forme 2D vincolate, il che significa che alcune parti della forma 2D possono avere dei vincoli. Ad esempio, è possibile disegnare un rettangolo e impostare un vincolo di lunghezza per uno dei suoi lati. Quel lato quindi non può più essere ridimensionato, fino a quando il vincolo non viene modificato.
Queste forme 2D realizzate con lo sketcher sono molto utilizzate in PartDesign, ad esempio per creare i volumi 3D o per disegnare le aree sulle facce dell'oggetto che devono essere scavate dal volume principale. Ecco un tipico flusso di lavoro PartDesign:
Si ottiene un oggetto simile a questo:
In qualsiasi momento è possibile selezionare gli schizzi originali e modificarli oppure modificare i parametri delle operazioni di estrusione o di scavo, l'oggetto finale viene automaticamente aggiornato.
Gli ambienti Draft e Arch si comportano in modo un po' diverso dagli altri ambienti di lavoro di cui sopra, anche se seguono le regole comuni di FreeCAD. In breve, Sketcher e PartDesign sono utilizzati principalmente per la progettazione di singoli pezzi, invece Draft e Arch sono concepiti per facilitare il lavoro quando si opera con diversi oggetti semplici.
L'ambiente Draft offre degli strumenti 2D in parte simili a quelli che si possono trovare nelle applicazioni tradizionali di CAD 2D quali AutoCAD. Però, il disegno 2D è lontano dagli scopi di FreeCAD, quindi non aspettatevi di trovare in esso la gamma completa di strumenti offerta da queste applicazioni dedicate. La maggior parte degli strumenti di Draft lavorano, non solo in un piano 2D, ma anche nello spazio 3D, e beneficiano degli speciali sistemi di supporto come il Piano di lavoro e lo Snapping.
L'ambiente Arch aggiunge a FreeCAD gli strumenti BIM che consentono di costruire i modelli architettonici con degli oggetti parametrici. L'ambiente Arch si basa molto sugli altri moduli come Draft e Sketcher. Tutti gli strumenti di Draft sono presenti anche nell'ambiente Arch e molti strumenti di Arch usano i sistemi di supporto di Draft.
Un tipico flusso di lavoro con gli ambienti Arch e Draft potrebbe essere:
Si ottiene un oggetto simile a questo:
Maggiori informazioni si trovano nella sezione Tutorial.
Infine, una delle più potenti caratteristiche di FreeCAD che è l'ambiente di script. Dalla console Python integrata (o tramite qualsiasi altro script Python esterno), è possibile accedere a quasi tutte le parti di FreeCAD, creare o modificare le geometrie, modificare la rappresentazione degli oggetti nella vista 3D, oppure accedere e modificare l'interfaccia di FreeCAD. Gli script Python possono essere utilizzati anche all'interno delle macro che forniscono un metodo facile e veloce per creare combinazioni di comandi personalizzati.
La funzione Navigazione 3D - Tipo di mouse di FreeCAD comprende i comandi utilizzati per navigare visivamente lo spazio 3D e per interagire con gli oggetti visualizzati. Attualmente FreeCAD offre diversi stili di navigazione con il mouse. Lo stile di navigazione predefinito, denominato "Navigazione CAD", è molto semplice e pratico, ma si può anche usare uno stile alternativo, secondo le proprie preferenze.
Lo stile di navigazione impostato viene utilizzato in tutti gli ambienti di lavoro.
Ci sono due modi per modificare lo stile di navigazione:
Per controllare la posizione dell'oggetto e la vista si possono utilizzare i seguenti movimenti del mouse secondo lo stile di navigazione selezionato.
Questo è lo stile di navigazione predefinito e permette all'utente un semplice controllo della vista. Richiede l'uso della tastiera solo per eseguire multi-selezioni.
Selezione | Traslazione | Zoom | Rotazione | |
---|---|---|---|---|
![]() |
![]() |
![]() |
![]() | |
Premere il tasto sinistro del mouse sull'oggetto che si desidera selezionare. Tenere premuto il tasto Ctrl per selezionare più oggetti. | Fare clic sul pulsante centrale del mouse e muovere il mouse per spostare l'oggetto. Inoltre, per attivare la traslazione, si può tenere premuto Ctrl e cliccare con il tasto destro. In questo modo la funzione rimane attiva, senza impegnare la mano del mouse, e permette l'uso della rotellina per lo zoom, fino a quando il tasto Ctrl non viene rilasciato. |
Ruotare la rotellina del mouse per ingrandire e ridurre. | Premere e mantenere premuto il tasto centrale del mouse, fare clic con il pulsante sinistro, o destro, del mouse su qualsiasi parte visibile di un oggetto e trascinarlo nella direzione desiderata. La posizione del cursore nel momento in cui si preme il pulsante centrale del mouse determina il centro di rotazione. La rotazione funziona come nel caso di una palla che ruota attorno al suo centro. Se i tasti vengono rilasciati prima di arrestare il movimento e se l'opzione Abilita animazione è attivata, l'oggetto continua la rotazione automaticamente. Un doppio clic con il tasto centrale del mouse su qualsiasi parte di un oggetto imposta un nuovo centro di rotazione e di zoom in tale punto. Il secondo metodo può essere utile ai mancini. Inoltre, per attivare la rotazione, si può tenere premuto Maiusc (Shift) e cliccare con il tasto destro. In questo modo la funzione rimane attiva, senza impegnare la mano del mouse, e permette l'uso dello zoom, fino a quando il tasto Maiusc non viene rilasciato.
| |
Premere Ctrl, cliccare sul tasto destro, rilasciarlo e spostare il mouse per spostare la vista (rev 0.17) | Premere Ctrl, cliccare sul tasto destro, rilasciarlo, cliccare sul tasto sinistro, rilasciarlo e spostare il mouse per zoommare (rev 0.17) | Premere Maiusc, cliccare sul tasto destro, rilasciarlo e spostare il mouse per ruotare la vista (rev 0.17) |
Nella Navigazione OpenInventor (formalmente Inventor), secondo il modello Open Inventor, da non confondere con Autodesk Inventor, non è possibile selezionare gli oggetti utilizzando solo il mouse. Per selezionare gli oggetti, è necessario tenere premuto il tasto CTRL.
Nella Navigazione secondo il modello Blender non è possibile spostare gli oggetti utilizzando solo il mouse. Per spostare la vista, è necessario tenere premuto il tasto SHIFT.
Con la Navigazione Touchpad non è possibile effettuare le operazioni di traslazione, rotazione o ingrandimento utilizzando solo il mouse (oppure solo il touchpad). Per spostare la vista si deve premere il tasto SHIFT. Per ingrandire o ridurre premere PgUp oppure PgDn (senza usare il mouse o il touchpad). Per ruotare la vista tenere premuto il tasto ALT.
Questo stile di navigazione è fatto su misura per essere usato con il touchscreen o con la penna, ma è usabile anche con il mouse.
Note sullo stile di Navigazione Gesture:
Nella navigazione Maya-Gesture tutti i movimenti vista sono ottenuti premendo ALT e un pulsante del mouse, quindi per utilizzare correttamente questa modalità di navigazione è necessario disporre di un mouse con 3 pulsanti. In alternativa, dato che questo modo è stato sviluppato per essere normalmente usato come modalità di navigazione gestuale, è possibile utilizzare i gesti.
Gli oggetti si possono selezionare con un click del tasto sinistro del mouse o facendo clic sull'oggetto nella vista 3D o selezionandoli nella vista ad albero.
Passando con il mouse sugli oggetti, una funzione di Preselezione li evidenzia e visualizza le relative informazioni prima della loro selezione. Se questo comportamento non è gradito o si dispone di una macchina lenta, è possibile disattivare la funzione nel dialogo delle preferenze.
FreeCAD offre strumenti Manipolatori utilizzabili per modificare un oggetto o il suo aspetto visivo.
Un esempio semplice è dato dal Piano di taglio attivabile con il menu Visualizza → Piano di taglio.
FreeCAD supporta anche i dispositivi di input 3D.
Recentemente abbiamo ricevuto segnalazioni nel forum da utenti Mac che questi pulsanti del mouse e le combinazioni di tasti non funzionano come previsto. Purtroppo, nessuno degli sviluppatori possiede un Mac e neppure gli altri collaboratori regolari. Abbiamo bisogno del vostro aiuto per determinare quali pulsanti del mouse e quali combinazioni di tasti funzionano e poter aggiornare questo wiki.
Un documento FreeCAD contiene tutti gli oggetti della scena. Può contenere i gruppi e gli oggetti realizzati con qualsiasi ambiente di lavoro. Si possono quindi alternare gli ambienti pur continuando a lavorare sullo stesso documento. Il documento è ciò che viene salvato sul disco quando si salva il proprio lavoro. Inoltre, in FreeCAD è possibile aprire più documenti contemporaneamente, e aprire diverse viste dello stesso documento.
All'interno del documento, gli oggetti possono essere raggruppati, e avere un unico nome. La gestione dei gruppi, degli oggetti e dei nomi degli oggetti avviene prevalentemente nella vista a albero. Naturalmente, queste operazioni, come tutto in FreeCAD, si possono eseguire anche tramite interprete Python.
Nella vista ad albero, è possibile creare gruppi, spostare gruppi di oggetti, eliminare oggetti o gruppi, facendo clic destro nella vista ad albero o su un oggetto, oppure rinominare gli oggetti facendo doppio clic sui loro nomi, o eventualmente eseguire altre operazioni, attinenti l'ambiente di lavoro attivo.
Un documento FreeCAD può contenere oggetti di diversi tipi. Ogni ambiente di lavoro crea oggetti di tipo specifico, per esempio Ambiente Mesh crea oggetti Mesh , Ambiente Parte crea oggetti Parte, Ambiente Draft crea disegni e anche oggetti Parte, ecc.
In FreeCAD può essere attivo un solo documento alla volta. Il documento attivo è quello che viene visualizzato nella vista 3D corrente ed è il documento in lavorazione.
Come per quasi tutto il resto, in FreeCAD, la parte interfaccia utente (GUI) è separata dalla parte applicazione (App). Questo vale anche per i documenti.
I documenti sono composti da due parti: il documento Applicazione, che contiene gli oggetti, e il documento Visualizzazione, che contiene la rappresentazione degli oggetti sullo schermo.
Pensate a due spazi in cui sono definiti gli oggetti. I loro parametri costruttivi (si tratta di un cubo? di un cono? quanto misura?) sono memorizzati nel documento Applicazione, mentre la loro rappresentazione grafica (è disegnata con linee nere? con le facce blu?) sono memorizzati nel documento Visualizzazione. Questo permette di utilizzare FreeCAD anche senza interfaccia grafica, ad esempio all'interno di altri programmi, e di manipolare gli oggetti, anche senza disegnare nulla sullo schermo.
Il documento Visualizzazione contiene anche le viste 3D. Un documento può avere contemporaneamente diverse viste aperte, in modo da poterlo controllare da diversi punti di vista. Ad esempio, si può visualizzare allo stesso tempo una vista dall'alto e una vista frontale. Tutte le viste dello stesso progetto vengono memorizzate nel documento Visualizzazione. La produzione di nuove viste o la chiusura di viste attive si può fare dal menu Visualizza o facendo clic destro su una scheda di visualizzazione.
Tramite l'interprete Python, si può facilmente accedere, creare o modificare i documenti. Ad esempio:
FreeCAD.ActiveDocument
Restituisce il documento corrente (attivo)
FreeCAD.ActiveDocument.Blob
Accede ad un oggetto chiamato "Blob" all'interno del documento
FreeCADGui.ActiveDocument
Restituisce il documento associato al documento corrente
FreeCADGui.ActiveDocument.Blob
Accede alla rappresentazione grafica (visualizza) l'oggetto "Blob"
FreeCADGui.ActiveDocument.ActiveView
Restituisce la vista corrente
Il sistema delle preferenze di FreeCAD si trova nel menu Modifica → Preferenze.
Le funzionalità di FreeCAD sono suddivise in moduli separati, ciascun modulo si occupa della lavorazione in uno specifico Ambiente. FreeCAD utilizza il caricamento tardivo (late loading), questo significa che i componenti vengono caricati solo quando sono necessari. Come si può notare, un ambiente di lavoro con tutti i suoi componenti viene caricato solo al momento in cui l'ambiente viene selezionato nella barra degli strumenti di FreeCAD. Questo vale anche per le impostazioni delle preferenze (ndt le preferenze sono trattate come un componente dell'ambiente).
Senza alcun modulo caricato, si ha accesso a due sezioni di configurazione, responsabili delle impostazioni generali dell'applicazione e delle impostazioni della visualizzazione.
Quando si avvia FreeCAD senza nessun Ambiente caricato, si visualizza una finestra delle preferenze minimale. Man mano che si caricano i moduli aggiuntivi, nella finestra delle preferenze appaiono delle nuove sezioni che consentono di configurare i dettagli di ogni ambiente di lavoro.
FreeCAD è sempre in costante evoluzione, quindi il contenuto di tali schermate potrebbe differire dagli screenshot precedenti. Le impostazioni sono di solito auto-esplicative, quindi non dovresti avere alcuna difficoltà a configurare FreeCAD in base alle tue esigenze.
Il modulo Draft ha una propria finestra di dialogo per le preferenze
Dato che l'interfaccia di FreeCAD è basata sul moderno toolkit Qt, essa dispone di una organizzazione ottimale. Si possono modificare, spostare, condividere tra i vari ambienti di lavoro widget, menu, barre e altri strumenti. Si possono creare e modificare le scorciatoie da tastiera. Si possono registrare e riprodurre le macro.
La finestra di personalizzazione è accessibile dal menu Strumenti → Personalizza:
La scheda Comandi consente di esplorare tutti i comandi disponibili in FreeCAD, organizzati per categorie.
In Tastiera, è possibile vedere le scorciatoie da tastiera associate a ogni comando di FreeCAD, e volendo, si può modificare o assegnare un nuovo collegamento a qualsiasi comando. Quando si usa sovente uno specifico ambiente di lavoro, questo permette di velocizzare il suo utilizzo tramite la tastiera.
La scheda Barre degli strumenti consente di modificare le barre degli strumenti esistenti, o di creare nuove barre degli strumenti personalizzate.
La scheda Macro consente di gestire le Macro salvate in precedenza.
Le schede successive permettono di impostare le azioni di Spaceball (se installato)
Vedere anche il tutorial per creare la Barra personalizzata degli strumenti macro
Nella versione 0.16 è disponibile un nuovo strumento che permette di gestire gli ambienti di lavoro.
Come esempio del flusso di lavoro, supponiamo di voler avere la funzione "Misura Lineare" mostrata anche in una barra degli strumenti personalizzata nell'ambiente Draft.
Osservazioni:
Una Proprietà è una parte di informazione sotto forma di numero o di stringa di testo che viene allegata a un documento FreeCAD oppure a un oggetto in un documento. Le proprietà possono essere visualizzate e, se consentito, modificate con l'Editor delle proprietà.
In FreeCAD le proprietà svolgono un ruolo molto importante in quanto esso è concepito per lavorare con oggetti parametrici, ovvero oggetti definiti solo dalle loro proprietà.
In FreeCAD gli oggetti script personalizzati possono avere proprietà dei seguenti tipi:
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
FreeCAD, come molte altre applicazioni di grafica moderne quali Revit o Catia, è strutturato in Ambienti di lavoro definiti Workbench.
Ogni ambiente offre gli strumenti necessari, opportunamente riuniti, per svolgere un compito specifico.
Si pensi, come esempio, ad un laboratorio di mobili dove c'è un banco di lavoro per chi lavora il legno, un altro per chi lavora i pezzi di metallo, e forse un terzo per chi assembla tutti i componenti.
In FreeCAD, viene applicato lo stesso concetto. Gli strumenti sono raggruppati per ambienti in base alle funzioni correlate.
Quando si passa da un ambiente di lavoro ad un altro, cambiano anche gli strumenti disponibili visualizzati sull'interfaccia. Le barre degli strumenti, le barre dei comandi e eventualmente altre parti dell'interfaccia si adattano al nuovo ambiente, ma il contenuto della scena visualizzata non cambia. Si può, ad esempio, iniziare a disegnare forme 2D utilizzando l'ambiente Draft e poi continuare a lavorare su di esse con l'ambiente Parte.
Notare che a volte un Ambiente viene indicato come un Modulo. Gli Ambienti e i Moduli sono però entità diverse. Un modulo è una estensione di FreeCAD, mentre un ambiente di lavoro è una speciale configurazione dell'interfaccia grafica che raggruppa alcune barre degli strumenti e dei menu specifici. Di solito, ogni modulo contiene anche il proprio ambiente di lavoro, e viceversa, ogni ambiente dipende da un modulo, per questo motivo succede di fare un uso incrociato del nome.
Attualmente in tutte le installazioni di FreeCAD sono disponibili i seguenti ambienti:
Questi sono gli ambienti base forniti con ogni installazione di FreeCAD:
Gli ambienti di lavoro per FreeCAD sono facilmente programmabili in Python, quindi ci sono molte persone che stanno sviluppando degli ambienti aggiuntivi al di fuori del codice di base di FreeCAD. La pagina Ambienti complementari contiene alcune informazioni e tutorial su alcuni di loro, e il progetto FreeCAD Addons mira a raccoglierli e renderli facilmente installabili dall'interno di FreeCAD.
Sono in fase di sviluppo ulteriori nuovi ambienti.
L'ambiente Mesh gestisce i reticoli triangolari degli oggetti mesh.
Gli oggetti mesh sono un tipo speciale di oggetti 3D, composti da triangoli (le maglie della griglia) connessi lungo i loro bordi e nei loro vertici. Oggetti tassellati.
Un esempio di un oggetto mesh
Molte applicazioni 3D utilizzano i mesh come tipo principale di oggetti 3D, ad esempio: sketchup, blender, maya o3d studio max. Dato che i mesh sono oggetti molto semplici, contenenti solo vertici (punti), bordi e facce (triangoli), sono molto facili da creare, modificare, suddividere, allungare, e altrettanto facili da trasferire da un'applicazione all'altra senza alcuna perdita di informazioni. Inoltre, dal momento che contengono dati molto semplici, le applicazioni 3D ne possono gestire grandi quantità senza alcun problema. Per queste ragioni, gli oggetti mesh sono spesso il tipo di oggetto 3D utilizzato dalle applicazioni che si occupano di cinema, animazione e creazione di immagini.
Nel campo dell'ingegneria, tuttavia, i mesh presentano una grossa limitazione: Sono oggetti estremamente elementari, composti solo da punti, linee e facce; sono composti solo da superfici, e non contengono alcuna informazione sulla massa, di conseguenza non si comportano come solidi. In un mesh non c'è, ad esempio, un modo automatico per sapere se un punto è all'interno o all'esterno dell'oggetto. Tutte le operazioni sui volumi di questi oggetti, come l'addizione o la sottrazione, sono sempre complicate da eseguire e spesso si verificano errori.
In FreeCAD, poiché si tratta di un'applicazione di ingegneria, si preferisce lavorare con tipi di oggetti 3D più intelligenti, che possano contenere più informazioni, quali la massa, il comportamento solido o anche altri parametri personalizzati.
Il modulo mesh è stato creato come ambiente di prova, ma è comunque importante che FreeCAD sia in grado di leggere, modificare e convertire le mesh . Spesso, nel processo di lavoro, si ricevono i dati 3D in formato mesh. Di conseguenza è necessario poter gestire questi dati, analizzarli per individuare errori o altri problemi che impediscono di convertirli in oggetti più intelligenti e, infine, poterli convertire in oggetti più intelligenti per gestirli con l'Ambiente Parte.
Attualmente, il modulo Mesh ha una interfaccia molto semplice, tutte le sue funzioni sono raggruppate nelle voci del menu Mesh. Per il momento, le più importanti operazioni possibili sono:
Queste sono solo alcune delle operazioni di base, quelle che sono attualmente presenti nell'interfaccia del modulo Mesh.
Altri strumenti mesh sono disponibili nell'ambiente OpenSCAD.
FreeCAD può gestire gli oggetti grigliati in molti altri modi tramite gli script.
Le funzionalità CAD di FreeCAD sono basate sul kernel OpenCasCade. Il modulo Parte di FreeCAD permette di accedere e utilizzare gli oggetti e le funzioni di OpenCascade. OpenCascade è un kernel CAD di livello professionale, che contiene funzioni avanzate per la manipolazione degli oggetti e della geometria 3D.
Gli oggetti Parte sono molto più complessi degli oggetti Mesh e consentono quindi delle operazioni più avanzate, quali ad esempio le operazioni logiche booleane, la cronologia delle modifiche e un comportamento parametrico.
Esempio di forma realizzata con il modulo Parte di FreeCAD
Gli strumenti del modulo Parte sono tutti situati nel menu Parte che viene visualizzato quando si carica questo modulo.
Questi sono strumenti per creare oggetti primitivi.
Questi sono gli strumenti per modificare gli oggetti esistenti. Essi permettono di scegliere l'oggetto da modificare.
Un esempio di unione (Somma), intersezione (Comune) e differenza (Sottrazione)
Nella terminologia OpenCascade, si distingue tra primitive geometriche e forme (topologiche). Una primitiva geometrica può essere un punto, una linea, un cerchio, un piano, ecc o essere anche di tipo più complesso come una curva B-Spline o una superficie. Una forma può essere un vertice, un bordo, un profilo, una faccia, un solido o un insieme di più forme. Le primitive geometriche non sono fatte per essere visualizzate direttamente sulla scena 3D, ma piuttosto per essere utilizzate come geometrie per la costruzione di forme. Ad esempio, un bordo può essere costruito usando una linea o una porzione di un cerchio.
Potremmo dire, per riassumere, che le primitive geometriche sono blocchi di costruzione "informi", e le forme sono la reale geometria spaziale costruita su questi blocchi.
Per ottenere un elenco completo di tutti questi elementi fare riferimento alla documentazione OCC e cercare Geom_Geometry e TopoDS_Shape. Nella documentazione sono anche contenute ulteriori informazioni sulle differenze tra gli oggetti geometrici e le forme. La documentazione OCC non è disponibile online (è necessario scaricare un archivio) e si rivolge principalmente ai programmatori e non agli utenti finali. Si spera che le informazioni fornite in seguito siano sufficienti per iniziare.
I tipi di oggetti geometrici possono essere suddivisi in due gruppi principali: le curve e le superfici. Sulle curve (linea, cerchio, ...), è possibile creare direttamente un bordo, mentre sulle superfici (piano, cilindro, ...) è possibile costruire una faccia. Ad esempio, la linea primitiva geometrica è illimitata, ossia è definita da un vettore di base e da un vettore di direzione, mentre la sua forma (e rappresentazione) deve essere qualcosa di limitato da un punto iniziale e da un punto finale. E un cubo - solido - può essere creato da sei piani limitati.
Da un bordo o una faccia (forme) si può sempre risalire alla sua primitiva geometrica.
Utilizzando le forme, è possibile costruire parti molto complesse, oppure viceversa, si possono estrarre tutte le sotto-forme che compongono una forma complessa.
La struttura principale dei dati utilizzati nel modulo Parte di OpenCascade è il tipo di dati BRep . Quasi tutti i contenuti e i tipi di oggetti del modulo Parte sono ora disponibili per gli script Python. Questo include le primitive geometriche, come Linee e Cerchi (o Archi), e tutta la gamma di TopoShapes, come Vertici, Bordi, Contorni, Facce, Solidi e Compositi. Per ognuno di questi oggetti, esistono diversi metodi di creazione, e per alcuni di loro, soprattutto le TopoShapes, sono inoltre disponibili operazioni booleane avanzate come unione, differenza e intersezione. Per maggiori informazioni, esplorare il contenuto del modulo Parte, come descritto nella pagina Script.
Per creare un elemento linea, passare alla console Python e digitare:
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()
Descrizione passo per passo della procedura del precedente esempio Python:
import Part,PartGui doc=App.newDocument()
carica il modulo Parte e crea un nuovo documento
l=Part.LineSegment() l.StartPoint=(0.0,0.0,0.0) l.EndPoint=(1.0,1.0,1.0)
La funzione Line descrive in realtà un segmento di linea, quindi serve il punto iniziale e quello finale.
doc.addObject("Part::Feature","Line").Shape=l.toShape()
Questo comando aggiunge un oggetto di tipo Parte al documento e assegna la forma di rappresentazione del segmento di linea alla proprietà 'forma' (Shape) dell'oggetto aggiunto. È importante comprendere che abbiamo usato una primitiva geometrica (la Part.line) per creare un TopoShape su di essa (il metodo toShape()). Al documento possono essere aggiunte solo delle forme . In FreeCAD, le primitive geometriche vengono utilizzate come "strutture di base" per le forme.
doc.recompute()
Aggiorna il documento. Questo prepara anche la rappresentazione visiva del nuovo oggetto Parte.
Notare che una linea può essere creata specificando il suo punto iniziale e il suo punto finale direttamente nel costruttore, per es. Part.Line (point1, point2) oppure possiamo creare una linea predefinita e impostarne le proprietà in seguito, come in questo caso.
In modo analogo è possibile creare un cerchio:
import Part doc = App.activeDocument() c = Part.Circle() c.Radius=10.0 f = doc.addObject("Part::Feature", "Circle") f.Shape = c.toShape() doc.recompute()
Si noti ancora una volta che il cerchio (geometria primitiva) viene usato per costruire una forma su di esso. Ovviamente, in seguito, si può ancora accedere alla geometria di costruzione con:
s = f.Shape e = s.Edges[0] c = e.Curve
Qui si acquisisce la forma dell'oggetto f, poi si acquisisce la lista dei bordi, (in questo caso il bordo è uno solo perché si crea l'intera forma con un unico cerchio, quindi si definisce solo il primo elemento della lista Edges) e infine, si recupera la curva. Ogni bordo ha una curva, che è la geometria primitiva sulla quale è basato.
Per maggiori informazioni consultare la pagina Script di dati topologici
L'ambiente Disegno (Drawing) consente di trasferire su carta il lavoro realizzato in 3D.
Permette di produrre delle viste (proiezioni sul piano) del modello, di posizionarle in una finestra 2D e di inserire la finestra in una tavola, ad esempio, in un foglio con il bordo, il titolo e il logo e, infine, di stampare la tavola.
Questi strumenti permettono di creare, configurare e esportare le proiezioni dei solidi come disegni 2D.
Nota. Lo strumento Disegno è utilizzato principalmente per posizionare gli oggetti Draft sulla carta. Possiede alcune funzionalità aggiuntive rispetto agli strumenti standard di Drawing, e supporta degli oggetti specifici come le dimensioni di Draft.
Nella schermata precedente si vedono i componenti principali del modulo Drawing. Il documento contiene l'oggetto (Schenkel) da cui si vuole estrarre un disegno (una proiezione). Viene perciò creata una Pagina. La pagina viene creata tramite un modello, in questo caso il modello è A3_Landscape.
Il modello della pagina è un documento SVG che può contenere la consueta cornice e un logo oppure conformarsi a una presentazione standard personalizzata.
I modelli, di default, nei sistemi Windows si trovano in C:/Program Files/FreeCAD0.13/data/Mod/Drawing/Templates/A3_Landscape.svg, e nei sistemi Linux in /usr/share/freecad/Mod/Drawing/Templates/A3_Landscape.svg.
Nella pagina si possono inserire una o più viste.
Ogni vista ha una posizione nella pagina (Proprietà X, Y), un fattore di scala (proprietà di scala) e delle proprietà aggiuntive.
Ogni volta che la pagina, la vista o l'oggetto a cui si fa riferimento subiscono delle modifiche, la pagina viene rigenerata e viene anche aggiornata la sua visualizzazione.
Per ora le funzioni offerte dall'interfaccia grafica (GUI) sono molto limitate, quindi gli script API sono più interessanti. Ecco alcuni esempi su come utilizzare gli script API del modulo Disegno.
Lo script Macro_CartoucheFC permette di compilare agevolmente la tabella del modello di tavola FreeCAD A3_Landscape.
Prima di tutto è necessario caricare i moduli Part e Disegno:
import FreeCAD, Part, Drawing
Creare una Parte campione
Part.show(Part.makeBox(100,100,100).cut(Part.makeCylinder(80,100)).cut(Part.makeBox(90,40,100)).cut(Part.makeBox(20,85,100)))
Proiezione diretta. G0 significa bordo rigido, G1 è una tangente continua.
Shape = App.ActiveDocument.Shape.Shape [visibleG0,visibleG1,hiddenG0,hiddenG1] = Drawing.project(Shape) print "visible edges:", len(visibleG0.Edges) print "hidden edges:", len(hiddenG0.Edges)
Tutto viene proiettato sul piano Z:
print "Bnd Box shape: X=",Shape.BoundBox.XLength," Y=",Shape.BoundBox.YLength," Z=",Shape.BoundBox.ZLength print "Bnd Box project: X=",visibleG0.BoundBox.XLength," Y=",visibleG0.BoundBox.YLength," Z=",visibleG0.BoundBox.ZLength
Proiezione con un vettore diverso
[visibleG0,visibleG1,hiddenG0,hiddenG1] = Drawing.project(Shape,App.Vector(1,1,1))
Proiezione in SVG
resultSVG = Drawing.projectToSVG(Shape,App.Vector(1,1,1)) print resultSVG
Creare il corpo
import FreeCAD import Part import Drawing # Create three boxes and a cylinder App.ActiveDocument.addObject("Part::Box","Box") App.ActiveDocument.Box.Length=100.00 App.ActiveDocument.Box.Width=100.00 App.ActiveDocument.Box.Height=100.00 App.ActiveDocument.addObject("Part::Box","Box1") App.ActiveDocument.Box1.Length=90.00 App.ActiveDocument.Box1.Width=40.00 App.ActiveDocument.Box1.Height=100.00 App.ActiveDocument.addObject("Part::Box","Box2") App.ActiveDocument.Box2.Length=20.00 App.ActiveDocument.Box2.Width=85.00 App.ActiveDocument.Box2.Height=100.00 App.ActiveDocument.addObject("Part::Cylinder","Cylinder") App.ActiveDocument.Cylinder.Radius=80.00 App.ActiveDocument.Cylinder.Height=100.00 App.ActiveDocument.Cylinder.Angle=360.00 # Fuse two boxes and the cylinder App.ActiveDocument.addObject("Part::Fuse","Fusion") App.ActiveDocument.Fusion.Base = App.ActiveDocument.Cylinder App.ActiveDocument.Fusion.Tool = App.ActiveDocument.Box1 App.ActiveDocument.addObject("Part::Fuse","Fusion1") App.ActiveDocument.Fusion1.Base = App.ActiveDocument.Box2 App.ActiveDocument.Fusion1.Tool = App.ActiveDocument.Fusion # Cut the fused shapes from the first box App.ActiveDocument.addObject("Part::Cut","Shape") App.ActiveDocument.Shape.Base = App.ActiveDocument.Box App.ActiveDocument.Shape.Tool = App.ActiveDocument.Fusion1 # Hide all the intermediate shapes Gui.ActiveDocument.Box.Visibility=False Gui.ActiveDocument.Box1.Visibility=False Gui.ActiveDocument.Box2.Visibility=False Gui.ActiveDocument.Cylinder.Visibility=False Gui.ActiveDocument.Fusion.Visibility=False Gui.ActiveDocument.Fusion1.Visibility=False
Inserire un oggetto Page e assegnargli un modello
App.ActiveDocument.addObject('Drawing::FeaturePage','Page') App.ActiveDocument.Page.Template = App.getResourceDir()+'Mod/Drawing/Templates/A3_Landscape.svg'
Creare una vista dell'oggetto "Shape", definirne la posizione e la scala e assegnare la vista a una pagina
App.ActiveDocument.addObject('Drawing::FeatureViewPart','View') App.ActiveDocument.View.Source = App.ActiveDocument.Shape App.ActiveDocument.View.Direction = (0.0,0.0,1.0) App.ActiveDocument.View.X = 10.0 App.ActiveDocument.View.Y = 10.0 App.ActiveDocument.Page.addObject(App.ActiveDocument.View)
Creare una seconda vista, ruotata di 90 gradi, dello stesso oggetto.
App.ActiveDocument.addObject('Drawing::FeatureViewPart','ViewRot') App.ActiveDocument.ViewRot.Source = App.ActiveDocument.Shape App.ActiveDocument.ViewRot.Direction = (0.0,0.0,1.0) App.ActiveDocument.ViewRot.X = 290.0 App.ActiveDocument.ViewRot.Y = 30.0 App.ActiveDocument.ViewRot.Scale = 1.0 App.ActiveDocument.ViewRot.Rotation = 90.0 App.ActiveDocument.Page.addObject(App.ActiveDocument.ViewRot)
Creare una terza vista, con direzione isometrica, dello stesso oggetto. Anche le linee nascoste sono attivate.
App.ActiveDocument.addObject('Drawing::FeatureViewPart','ViewIso') App.ActiveDocument.ViewIso.Source = App.ActiveDocument.Shape App.ActiveDocument.ViewIso.Direction = (1.0,1.0,1.0) App.ActiveDocument.ViewIso.X = 335.0 App.ActiveDocument.ViewIso.Y = 140.0 App.ActiveDocument.ViewIso.ShowHiddenLines = True App.ActiveDocument.Page.addObject(App.ActiveDocument.ViewIso)
Modificare qualche parametro e aggiornare. Il processo di aggiornamento modifica la visualizzazione e aggiorna la pagina.
App.ActiveDocument.View.X = 30.0 App.ActiveDocument.View.Y = 30.0 App.ActiveDocument.View.Scale = 1.5 App.ActiveDocument.recompute()
Ottenere il frammento SVG di una singola vista
ViewSVG = App.ActiveDocument.View.ViewResult print ViewSVG
Ottenere l'intera pagina risultante (contenuta in un file nella directory temporanea del documento, con il permesso di sola lettura)
print "Resulting SVG document: ",App.ActiveDocument.Page.PageResult file = open(App.ActiveDocument.Page.PageResult,"r") print "Result page is ",len(file.readlines())," lines long"
Importante: liberare il file!
del file
Inserire una vista con un contenuto personalizzato:
App.ActiveDocument.addObject('Drawing::FeatureView','ViewSelf') App.ActiveDocument.ViewSelf.ViewResult = """<g id="ViewSelf" stroke="rgb(0, 0, 0)" stroke-width="0.35" stroke-linecap="butt" stroke-linejoin="miter" transform="translate(30,30)" fill="#00cc00" > <ellipse cx="40" cy="40" rx="30" ry="15"/> </g>""" App.ActiveDocument.Page.addObject(App.ActiveDocument.ViewSelf) App.ActiveDocument.recompute() del ViewSVG
Si ottiene il seguente risultato:
Il disegno delle dimensioni e delle tolleranze sono ancora in fase di sviluppo, ma, con un po' di lavoro, è già possibile ottenere alcune funzionalità di base.
Prima di tutto bisogna scaricare il modulo gdtsvg python da
https://github.com/jcc242/FreeCAD (ATTENZIONE: Questo link potrebbe essere interrotto in qualsiasi momento)
Per ottenere un riquadro per l'indicazione delle caratteristiche (una griglia in cui inserire i parametri), provare quanto segue:
import gdtsvg as g # Import the module, I like to give it an easy handle ourFrame = g.ControlFrame("0","0", g.Perpendicularity(), ".5", g.Diameter(), g.ModifyingSymbols("M"), "A", g.ModifyingSymbols("F"), "B", g.ModifyingSymbols("L"), "C", g.ModifyingSymbols("I"))
Ecco un esempio di buona ripartizione del contenuto di una griglia di controllo della geometria: [1]
I parametri da passare a ControlFrame sono:
La funzione ControlFrame restituisce un testo che contiene (stringa svg, larghezza totale del riquadro, altezza complessiva del riquadro)
Per ottenere una dimensione, provare quanto segue:
import gdtsvg ourDimension = linearDimension(point1, point2, textpoint, dimensiontext, linestyle=getStyle("visible"), arrowstyle=getStyle("filled"), textstyle=getStyle("text")
Gli input per ottenere una dimensione lineare sono:
Con la quotatura e l'indicazione delle tolleranze, si può procedere come sopra per visualizzarle nella pagina di disegno.
Questo modulo è provvisorio e può essere interrotto in qualsiasi momento, segnalazioni di bug per ora sono benvenute nella pagina github, oppure contattare jcc242 sul forum se si registra un bug da qualche altra parte.
FreeCAD viene fornito con una serie di modelli di pagina predefiniti, ma si possono trovare altri modelli in Modelli di squadrature.
Alcune ulteriori note sulla programmazione del Modulo Disegno sono contenute nella pagina Drawing Documentation (en) Drawing Documentation (it). Dette note aiutano a capire rapidamente come lavora questo modulo e permettono ai programmatori di avviare rapidamente la programmazione per esso.
Il modulo Raytracing ha la funzione di inviare il contenuto della scena presente sul monitor a un motore di rendering esterno, per produrre immagini foto-realistiche del progetto. Il modulo Raytracing lavora con dei modelli, nello stesso modo del modulo Drawing, e consente di creare un progetto di raytracing, in cui inserire una vista degli oggetti. Il progetto può essere esportato in un file ready-to-render, o essere trattato direttamente.
Attualmente sono supportati due renderizzatori: povray e luxrender. Per poter eseguire il rendering direttamente da FreeCAD, sul sistema deve essere installato almeno uno di questi renderer, e deve essere configurato il suo percorso nelle preferenze di FreeCAD per Raytracing. Senza alcun renderer installato, si può comunque esportare un file della scena e utilizzarlo successivamente in uno di questi renderer, o su una macchina diversa.
Il modulo Raytracing lavora con dei modelli, che sono dei file della scena completati per un dato renderer esterno, comprese le luci e eventuali geometrie aggiuntive, come i piani di appoggio. Questi file di scena contengono dei segnaposto, dove FreeCAD inserisce le informazioni per la posizione della fotocamera, la geometria e il materiale di ogni oggetto del progetto. Questo file di scena modificato è il file che viene poi esportato verso il renderer esterno.
Questi sono i principali strumenti per esportare il vostro lavoro 3D verso i software di renderizzazione (rendering) esterni.
Sono degli strumenti di supporto per eseguire manualmente compiti specifici
Gli strumenti di utilità descritti prima consentono di esportare la corrente vista 3D e tutto il suo contenuto in un file Povray. In primo luogo, è necessario caricare un documento o crearne uno e poi orientare la vista 3D come si desidera. Dopo, scegliere Esporta la vista ... nel menu di Raytracing.
Nella finestra di dialogo Esporta pagina, selezionare la destinazione per salvare il file *.pov. Successivamente aprire il file in Povray e generare la renderizzazione:
Come è noto, le applicazioni di renderizzazione possono produrre immagini di grandi dimensioni e ottima qualità:
I moduli Raytracing e RaytracingGui forniscono diversi metodi per scrivere i contenuti della scena come dati povray o luxrender. I più utili sono Raytracing.getPartAsPovray() e Raytracing.getPartAsLux() per il rendering di un oggetto Part di FreeCAD in una definizione povray o luxrender, e RaytracingGui.povViewCamera() e RaytracinGui.luxViewCamera() per ottenere il corrente punto di vista della finestra 3D di FreeCAD in formato luxrender o povray.
Ecco come utilizzare le funzionalità tramite Python, supponendo che il documento contenga un oggetto "Box":
import Raytracing,RaytracingGui OutFile = open('C:/Documents and Settings/jriegel/Desktop/test.pov','w') OutFile.write(open(App.getResourceDir()+'Mod/Raytracing/Templates/ProjectStd.pov').read()) OutFile.write(RaytracingGui.povViewCamera()) OutFile.write(Raytracing.getPartAsPovray('Box',App.activeDocument().Box.Shape,0.800000,0.800000,0.800000)) OutFile.close() del OutFile
E la stessa cosa per luxrender:
import Raytracing,RaytracingGui OutFile = open('C:/Documents and Settings/jriegel/Desktop/test.lxs','w') OutFile.write(open(App.getResourceDir()+'Mod/Raytracing/Templates/LuxClassic.lxs').read()) OutFile.write(RaytracingGui.luxViewCamera()) OutFile.write(Raytracing.getPartAsLux('Box',App.activeDocument().Box.Shape,0.800000,0.800000,0.800000)) OutFile.close() del OutFile
Oltre agli oggetti viste standard di Povray e di luxrender che offrono una visione di un oggetto Part esistente, e che possono essere inseriti rispettivamente in progetti Povray e luxrender, esiste un terzo oggetto, chiamato RaySegment, che può essere inserito sia in progetti Povray che luxrender. Questo oggetto RaySegment non è legato a nessuno degli oggetti di FreeCAD, e può contenere del codice povray o luxrender personalizzato che è possibile inserire in un progetto raytracing. È inoltre possibile utilizzarlo, ad esempio, per produrre il proprio oggetto FreeCAD in un modo particolare, se il modo standard non soddisfa. È possibile crearlo e utilizzarlo dalla console python in questo modo:
myRaytracingProject = FreeCAD.ActiveDocument.PovProject myCustomRenderObject = FreeCAD.ActiveDocument.addObject("Raytracing::RaySegment","myRenderObject") myRaytracingProject.addObject(myCustomRenderObject) myCustomRenderObject.Result = "// Hello from python!"
Attualmente vi è un nuovo Ambiente Renderer in fase di sviluppo per supportare diversi back-end, come Lux Renderer e YafaRay. Le informazioni per l'utilizzo della versione di sviluppo possono essere visionate nel progetto Render.
Per conoscere lo stato di sviluppo del Modulo Render consultare il progetto Raytracing
FreeCAD viene fornito con un paio di modelli predefiniti per Povray e LuxRender, ma si può facilmente crearne uno proprio. Basta creare un file di scena per un dato renderer, quindi modificarlo manualmente con un editor di testo per inserire i tag speciali che FreeCAD riconosce e dove inserisce il suo contenuto (i dati della fotocamera e degli oggetti).
I file di scena Povray (con estensione .pov) possono essere creati manualmente con un editor di testo (povray è fatto principalmente per essere utilizzato come un linguaggio di scripting), ma anche con una vasta gamma di applicazioni 3D, come ad esempio blender. Nel sito web di povray è possibile trovare ulteriori informazioni e un elenco di applicazioni in grado di produrre file .pov.
Quando si dispone di un file .pov pronto, è necessario aprirlo con un editor di testo e eseguire due operazioni:
Notare che FreeCAD aggiunge, dopo il tag //RaytracingContent, anche alcune dichiarazioni che è possibile utilizzare nel modello. Queste sono:
Ad esempio, per posizionare una lampada sopra la fotocamera, è possibile utilizzare:
light_source { cam_location + cam_angle * 100 color rgb <10, 10, 10> }
I file di una scena LuxRender (con estensione .lxs) possono essere dei singoli file o un file master .lxs che include i file per la definizione dell'insieme (.lxw), la definizione del materiale (.lxm) e la definizione della geometria (.lxo). È possibile lavorare con entrambi gli stili, ma è anche facile trasformare un gruppo di 4 file in un singolo file .lxs, copiando il contenuto di ogni file .lxw, .lxm e .lxo e incollandolo nel punto in cui quel file è inserito nel file master .lxs.
I file di scena LuxRender sono difficili da produrre a mano, ma sono facili da produrre con molte applicazioni 3D, come blender. Nel sito LuxRender, troverete maggiori informazioni e i plugin per le principali applicazioni 3D.
Se si lavora con i file .lxw, .lxm e .lxo separati, fare attenzione perchè i file .lxs finali esportati da FreeCAD possono essere in una posizione diversa rispetto al file del modello, e quindi non possono essere trovati da LuxRender in fase di rendering. In questo caso si deve copiare questi file nella posizione del file finale, o modificare i loro percorsi nel file .lxs esportato.
Se si esporta un file di scena da blender, e si vuole unire tutto in un unico file, è necessario eseguire un passaggio prima dell'esportazione: per impostazione predefinita, l'esportatore per LuxRender di blender esporta tutta la geometria delle mesh in file .ply separati, invece di inserire la geometria mesh direttamente all'interno del file .lxo. Per modificare questo comportamento, è necessario selezionare ciascuna delle mesh in blender, passare alla scheda "mesh" e impostare per ognuna l'opzione "Esporta come" "LuxRender mesh".
Quando il file di scena è pronto, per trasformarlo in un modello di FreeCAD, è necessario eseguire le seguenti operazioni:
Notare che in LuxRender, gli oggetti memorizzati in un file di scena possono definire matrici di trasformazione, che eseguono operazioni di posizionamento, rotazione o ridimensionamento. Queste matrici possono influenzare tutto quello che viene dopo di loro, quindi, ponendo il tag #RaytracingContent alla fine del file, è possibile vedere gli oggetti di FreeCAD colpiti da una matrice di trasformazione collocata all'interno del modello. Per assicurarsi che questo non accada, inserire il tag #RaytracingContent prima di qualsiasi altro oggetto di geometria presente nel modello. FreeCAD non definisce nessuna di queste matrici di trasformazione.
Sebbene l'esportazione diretta nel formato XML di Kerkythea non sia ancora supportata, è possibile esportare gli oggetti come file Mesh (.obj) e poi importarli in Kerkythea.
Il modulo Immagine gestisce diversi tipi di immagini bitmap, e permette di aprirle in FreeCAD.
Attualmente, il modulo consente di aprire file di formato .bmp, .jpg, .png e .xpm in una finestra di visualizzazione separata.
Il modulo Immagine consente inoltre di aprire una immagine su un piano nello spazio 3D di FreeCAD. Questa funzione è disponibile tramite il secondo pulsante dell'ambiente immagine.
L'immagine importata può essere unita come schizzo a uno dei tre piani principali (XY/XZ/YZ) con offset positivo o negativo.
Questa funzione è disponibile solo se è stato aperto un documento di FreeCAD.
L'immagine può essere spostata nello spazio 3D modificando il suo posizionamento nell'editor delle Proprietà.
Principalmente serve per costruire il tracciato di una nuova parte usando l'immagine come modello.
L'immagine viene importata con 1 pixel = 1mm. Pertanto si raccomanda di importare una immagine che abbia una risoluzione ragionevole. L'immagine può essere scalata modificando i valori "XSize" e "YSize" nella scheda delle Proprietà. L'immagine può essere spostata anche modificando i valori di Y/Z/X nella scheda Placement. L'immagine può essere ruotata attorno ad un asse utilizzando il dialogo di posizionamento.
Suggerimento:
La tracciatura di elementi di sketch su un'immagine funziona meglio se l'immagine ha un piccolo offset negativo rispetto al piano dello schizzo, ovvero se l'immagine è posizionata leggermente dietro al piano dello schizzo .
È possibile impostare un offset di -0,1 mm in fase di importazione oppure successivamente, modificando la posizione dell'immagine.
Strumenti
L'ambiente Draft permette di disegnare in modo rapido e semplice degli oggetti 2D nel documento corrente, e offre diversi strumenti per manipolarli.
Alcuni di questi strumenti funzionano su tutti gli oggetti di FreeCAD, non solo su quelli creati con l'ambiente Draft.
Fornisce inoltre un sistema completo di ancoraggio, e diverse utility per gestire gli oggetti e le impostazioni.
Questi sono gli strumenti per creare gli oggetti
Si tratta degli strumenti per la modifica di oggetti esistenti. Lavorano su oggetti selezionati precedentemente, quando nessun oggetto è selezionato, si viene invitati a scegliere uno.
Ulteriori strumenti disponibili tramite il menu contestuale del tasto destro, a seconda degli oggetti selezionati.
Il modulo Draft fornisce a FreeCAD gli importatori e gli esportatori per i seguenti formati di file:
Il modulo Draft incorpora una Draft API completa perciò si può utilizzare le sue funzioni negli script e nelle macro
Le macro sono un modo pratico per creare delle azioni complesse. In FreeCAD è sufficiente registrare le azioni così come vengono eseguite, quindi salvarle con un nome, per poterle ripetere quando si vuole. Dato che le macro sono in realtà un elenco di comandi python, è anche possibile modificarle e creare degli script molto complessi.
Quando dal menu Modifica -> Preferenze -> Generale -> Macro -> Mostra comandi script nella console python, si attiva l'output su console si vede che ogni azione che si compie, come ad esempio la pressione di un pulsante, invia un comando python. Questi comandi sono ciò che è possibile registrare in una macro. Lo strumento principale per creare una macro è la barra degli strumenti macro: . Su di essa si trovano 4 tasti: Registrare, Interrompere la registrazione, Modificare e Riprodurre la macro corrente.
È molto semplice da usare: Premere il pulsante di registrazione, dare un nome alla macro, quindi eseguire alcune azioni. Al termine, fare clic sul pulsante Interrompi registrazione, e le azioni compiute vengono salvate. Ora è possibile accedere alla finestra di dialogo delle macro utilizzando il pulsante Modifica:
Quì è possibile gestire le macro, eliminarle, modificarle o crearne di nuove partendo da zero. Quando si modifica una macro, essa viene aperta in una finestra dell'editor in cui è possibile apportare le proprie modifiche al codice.
Premere il pulsante di registrazione, fornire un nome, ad esempio, "cilindro 10x10", poi, nell'Ambiente Parte, creare un cilindro con raggio = 10 e altezza = 10. Quindi, premere il pulsante "Interrompi registrazione". Nella finestra di dialogo Modifica macro, è possibile vedere il codice python che è stato registrato, e, volendo, apportarvi delle modifiche. Per eseguire la macro, è sufficiente premere sul pulsante Esegui della barra degli strumenti, mentre la macro è nell'editor. La macro viene sempre salvata su disco, in modo che tutte le modifiche apportate, o ogni nuova macro creata, sono sempre disponibili al successivo avvio di FreeCAD.
Naturalmente non è pratico dover caricare una macro nell'editor per poterla utilizzare. FreeCAD fornisce modi migliori per usarle, come ad esempio l'assegnazione ad essa di una scorciatoia da tastiera o l'inserimento di una voce nel menu. Dopo aver creato la macro, tutto questo può essere fatto tramite il menu Strumenti -> Personalizza:
Personalizzare la barra degli strumenti. In questo modo si può trasformare la macro in un vero e proprio strumento, proprio come qualsiasi strumento standard di FreeCAD. Questo, sommato alla potenza degli script Python all'interno di FreeCAD, permette di aggiungere facilmente all'interfaccia dei propri strumenti. Per maggiori informazioni sugli script Python, continuare la lettura alle pagine del Centro utenti esperti o degli Script ...
Come installare le macro. È anche possibile inserire direttamente con copia/incolla del codice python in un macro, senza registrare le azioni della GUI (dell'interfaccia grafica). È sufficiente creare una nuova macro, modificarla, e incollare il codice. È quindi possibile salvare la macro nello stesso modo in cui si salva un documento di FreeCAD. Al prossima avvio di FreeCAD, la macro viene visualizzata in "Macro installate" nel menu Macro.
Visitare la pagina degli esempi di macro per trovare alcune utili macro da aggiungere alla propria installazione di FreeCAD.
Come installare ambienti di lavoro aggiuntivi
Questo è una breve guida realizzata per chi si avvicina per la prima volta a Python. Python è un linguaggio di programmazione multi-piattaforma open-source. Python dispone di numerose funzionalità che lo rendono molto diverso dagli altri comuni linguaggi di programmazione, ed è facilmente accessibile ai nuovi utenti:
Ora, mettiamoci al lavoro! Ricordare che ciò che verrà dopo è solamente una semplice introduzione e non un tutorial completo. Ma la speranza è che dopo si avranno basi sufficienti per esplorare più in profondità i meccanismi di FreeCAD.
Di solito, per scrivere programmi per computer, basta aprire un editor di testo (o l'ambiente di programmazione preferito che, in genere, è un editor di testo con strumenti aggiuntivi), scrivere il programma, quindi compilarlo ed eseguirlo. Il più delle volte si fanno degli errori di scrittura, per cui il programma non funziona, e si ottiene un messaggio di errore che dà informazioni su cosa è andato storto. Quindi si ritorna all'editor di testo, si correggono gli errori, si esegue di nuovo, e così via fino a quando il programma funziona bene.
In Python, l'intero processo, può essere eseguito in modo trasparente all'interno del suo interprete. L'interprete Python è una finestra con un prompt dei comandi, dove si può digitare direttamente il codice Python. Se si installa Python sul proprio computer (scaricarlo dal sito web di Python se lavorate su Windows o Mac, installarlo dal repository dei pacchetti se utilizzate GNU/Linux), si avrà un interprete Python nel menu di avvio. FreeCAD dispone di un proprio interprete Python visualizzato nella sua finestra inferiore:
Se non è visibile, cliccare su Visualizza → Viste → Console Python.
L'interprete mostra la versione di Python, quindi il simbolo >>>, che è il suo prompt dei comandi, cioè, dove si deve inserire il codice Python. Scrivere il codice nell'interprete è semplice: ogni riga è una istruzione. Quando si preme Invio, la riga di codice viene eseguita (dopo essere stata istantaneamente e invisibilmente compilata). Ad esempio, provare a scrivere questo:
print "hello"
per Python print
è una speciale parola chiave che, ovviamente, serve per stampare qualcosa sullo schermo. Quando si preme Invio, l'operazione viene eseguita, e viene stampato il messaggio "ciao". Se si commette un errore, provare, per esempio, a scrivere:
print hello
Python dice che non conosce ciao. I caratteri " " specificano che il contenuto è una stringa. In gergo tecnico, una stringa è semplicemente un pezzo di testo. Senza i segni ", la parola ciao viene vista come una specificazione del comando di stampa, cioè come una speciale parola chiave di Python, e non come un testo. Il fatto importante è che l'errore viene immediatamente notificato. Premendo la freccia verso l'alto (o, nell'interprete di FreeCAD, CTRL + freccia su), si può tornare all'ultimo comando scritto e correggerlo.
L'interprete Python possiede anche un sistema di aiuto incorporato. Provare a digitare:
help
oppure, ad esempio, se non si riesce a capire cosa è andato storto con il precedente comando print ciao, e si desiderano delle informazioni specifiche sul comando "print" digitare:
help("print")
Si ottiene una lunga e completa descrizione di tutto quello che può fare il comando print.
Ora che si ha il controllo totale dell'interprete, si può cominciare con le cose significative.
Naturalmente, stampare "ciao" non è molto interessante. Più interessante è stampare cose che non si conoscono prima, o lasciare che Python le trovi per noi. Qui entra in gioco il concetto di variabile. Una variabile è semplicemente un valore che viene memorizzato con un nome specifico. Ad esempio, digitare questo:
a = "hello" print a
Sicuramente si capisce quello che succede, la stringa "ciao" viene "salvata" sotto il nome "a". Ora, "a" non è più un nome sconosciuto! Si può usare ovunque, per esempio nel comando print. È possibile utilizzare qualsiasi nome che si desideri, basta rispettare alcune semplici regole, tipo non usare spazi o segni di punteggiatura. Ad esempio, si potrebbe tranquillamente scrivere:
hello = "my own version of hello" print hello
Visto? ciao ora non è più una parola indefinita. E se, per sfortuna, si sceglie un nome che in Python esiste già? Supponiamo di voler conservare una stringa con il nome "print":
print = "hello"
Python è molto intelligente e ci dice che questo non è possibile. Possiede alcune parole chiave "riservate" che non possono essere modificate. Invece le nostre variabili possono essere modificate in qualsiasi momento, il che è esattamente il motivo per cui sono chiamate variabili, ovvero il contenuto può variare. Ad esempio:
myVariable = "hello" print myVariable myVariable = "good bye" print myVariable
Il valore di myVariable è stato cambiato. Le variabili possono anche essere copiate:
var1 = "hello" var2 = var1 print var2
Notare che è importante dare alle variabili dei nomi descrittivi. Quando si scrivono programmi lunghi, dopo un po' probabilmente non si ricorda più cosa rappresenta la variabile denominata "a". Se invece viene chiamata, ad esempio, MioMessaggioDiBenvenuto, quando la si vede, si capisce facilmente a cosa serve. In più è un passo avanti verso l'autodocumentazione del proprio codice.
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.
È noto che la programmazione serve per trattare ogni tipo di dati, non solo le stringhe di testo, ma soprattutto i numeri. È molto importante che Python sappia che tipo di dati deve trattare. Nell'esempio precedente, con print ciao, si è visto che il comando print ha riconosciuto la nostra stringa "ciao". Questo perché utilizzando il segno ", abbiamo specificato al comando print che ciò che seguiva era una stringa di testo.
Per controllare in qualsiasi momento di quale tipo sono i dati contenuti in una variabile si utilizza la speciale parola chiave di Python type():
myVar = "hello" type(myVar)
In questo caso ci dice che il contenuto di myVar è 'str', ovvero una stringa in gergo Python. Ci sono anche altri tipi di dati, ad esempio i numeri interi (integer) e i numeri in virgola mobile (float numbers):
firstNumber = 10 secondNumber = 20 print firstNumber + secondNumber type(firstNumber)
Questo è già molto più interessante, vero? Ora si dispone di una potente calcolatrice! Notare bene come funziona. Python capisce che 10 e 20 sono numeri interi, quindi vengono memorizzati come "int", e con essi Python può fare tutte le operazioni consentite con numeri interi. Osservare i risultati di questo codice:
firstNumber = "10" secondNumber = "20" print firstNumber + secondNumber
Visto? Python è stato indotto a considerare le due variabili non più come numeri, ma come semplici parti di testo. Python può unire insieme due parti di testo, ma con esse non cerca di produrre una somma. Torniamo ai numeri. Oltre ai numeri interi (int) ci sono anche i numeri in virgola mobile (float). I numeri interi non hanno una parte decimale, mentre i numeri float possono avere una parte decimale:
var1 = 13 var2 = 15.65 print "var1 is of type ", type(var1) print "var2 is of type ", type(var2)
I numeri Int e Float possono essere mescolati tra di loro senza problemi:
total = var1 + var2 print total print type(total)
Naturalmente il totale ha dei decimali, vero? Quindi Python ha deciso automaticamente che il risultato è un float. In molti casi, come in questo, Python decide automaticamente il tipo da usare. In altri casi no. Ad esempio con:
varA = "hello 123" varB = 456 print varA + varB
Si produce un errore, varA è una stringa e varB è un int, quindi Python non sa cosa fare. Ma possiamo indurre Python a convertire i tipi:
varA = "hello" varB = 123 print varA + str(varB)
Ora entrambi sono stringhe, e l'operazione funziona! Notare che, con questi comandi, varB è convertita in "stringa" solo al momento della stampa, però varB originale non viene modificata. Per trasformare varB permanentemente in una stringa, si deve fare:
varB = str(varB)
Inoltre è possibile usare int() e float() per convertire in int e in float:
varA = "123" print int(varA) print float(varA)
Note sui comandi Python
Sicuramente avete notato che in questa sezione il comando di stampa (print) è stato utilizzato in diversi modi. Abbiamo stampato variabili, somme, parti separati da virgole, e anche il risultato di altri comandi Python, ad esempio type(). Forse avete anche notato che questi due comandi,
type(varA) print type(varA)
producono esattamente lo stesso risultato. Questo succede perché siamo nell'interprete, dove ogni cosa viene sempre automaticamente stampata sullo schermo. Per velocizzare, d'ora in avanti si può fare a meno di usarlo e quindi scrivere semplicemente:
myVar = "hello friends" myVar
Inoltre avrete notato che con la maggior parte dei comandi (o parole chiave) di Python si usano le parentesi per dire loro su quale contenuto devono operare: type(), int(), str(), ecc. Unica eccezione è il comando print, ma in realtà non si tratta di un'eccezione, anche lui funziona normalmente in questo modo:
print ("ciao")
però, siccome viene utilizzato frequentemente, i programmatori di Python ne hanno creato una versione semplificata.
Un altro tipo di dati interessante è una list (lista). Una lista è semplicemente un elenco di altri dati. In modo analogo a come si definisce una stringa di testo usando " ", una lista si definisce usando []:
myList = [1,2,3] type(myList) myOtherList = ["Bart", "Frank", "Bob"] myMixedList = ["hello", 345, 34.567]
Come si vede, una lista può contenere dati di qualsiasi tipo. Le liste sono molto utili perché permettono di raggruppare le variabili. Con il gruppo, successivamente, è possibile fare diverse cose, ad esempio contare i suoi componenti:
len(myOtherList)
o recuperare un elemento da una lista:
myName = myOtherList[0] myFriendsName = myOtherList[1]
Come si vede, mentre il comando len() restituisce il numero totale di elementi in una lista, la loro "posizione" nella lista inizia con 0. Il primo elemento in una lista si trova sempre in posizione 0, quindi nella lista myOtherList, "Bob" è nella posizione 2. Con le liste è possibile eseguire molte altre operazioni, descritte in modo più completo qui, ad esempio, ordinare i suoi contenuti, rimuovere o aggiungere elementi.
Una cosa curiosa: una stringa di testo è molto simile a una lista di caratteri! Provate a fare questo:
myvar = "hello" len(myvar) myvar[2]
In genere, tutto quello che si può fare con le liste si può fare anche con le stringhe. In effetti le liste e le stringhe sono entrambe delle sequenze.
Oltre a stringhe, int, float e liste, in Python sono disponibili molti altri tipi di dati built-in (incorporati), quali ad esempio i dictionaries (collezione di oggetti), oppure si possono creare dei propri tipi di dati utilizzando le classi.
Un tipico uso della lista consiste nel navigare al suo interno e di operare con i suoi elementi. Per esempio osservare questo:
alldaltons = ["Joe", "William", "Jack", "Averell"] for dalton in alldaltons: print dalton + " Dalton"
In questo esempio, la lista viene iterata (nuovo gergo di programmazione!) con il comando "for ... in ..." e con ognuno dei suoi elementi viene eseguito qualcosa.
Notare la speciale sintassi. Il comando "for" termina con un ":" questo indica a Python che ciò che segue è un blocco di uno o più comandi. Subito dopo che viene inserita la riga con il comando che termina con :, il prompt dei comandi cambia in ... il che significa che Python ha riconosciuto un comando terminato con un (:) e quello che segue è parte del comando stesso.
Come fa Python a sapere quante delle prossime righe sono da eseguire all'interno dell'operazione for ... in ? Per sapere questo, Python utilizza l'indentazione. Cioè, le righe successive non iniziano immediatamente, ma iniziano con uno o più spazi vuoti, oppure con uno o più spazi di tabulazione. Altri linguaggi di programmazione utilizzano vari metodi, tipo inserire tutto dentro parentesi, ecc. Finché le righe successive sono scritte con la stessa indentazione, esse sono considerate come parte del blocco for-in. Quando si inizia una riga con 2 spazi vuoti e quella successiva con 4, si produce un errore. Per terminare e uscire dal blocco for-in, basta scrivere una nuova riga senza rientro, o semplicemente premere Invio.
L'indentazione è molto utile perché conferisce leggibilità al promma. Se è ampia (usando, ad esempio, tab che crea più spazi invece di un solo), quando si scrive un programma lungo si ha una visione chiara di ciò che viene eseguito all'interno di ogni blocco. Vedremo che anche molti altri comandi diversi da for-in richiedono blocchi indentati.
Il comando for-in può essere utilizzato per varie operazioni che devono essere eseguite più volte. Ad esempio, può essere combinato con il comando range():
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
O per operazioni più complesse tipo questa:
alldaltons = ["Joe", "William", "Jack", "Averell"] for n in range(4): print alldaltons[n], " is Dalton number ", n
Come si vede, anche il comando range() ha la strana particolarità di iniziare con 0 (quando non si specifica il numero di partenza) e che il suo ultimo numero è uno in meno del numero finale specificato. Ciò, naturalmente, perché questo modo funziona bene con gli altri comandi di Python. Ad esempio:
alldaltons = ["Joe", "William", "Jack", "Averell"] total = len(alldaltons) for n in range(total): print alldaltons[n]
Un altro uso interessante dei blocchi indentati si ha con il comando if. Il comando if esegue un blocco di codice solo se una certa condizione è soddisfatta, ad esempio:
alldaltons = ["Joe", "William", "Jack", "Averell"] if "Joe" in alldaltons: print "We found that Dalton!!!"
Naturalmente, questo esempio stampa sempre la prima frase, ma provare a sostituire la seconda riga con:
if "Lucky" in alldaltons:
Ora non viene più stampato nulla. Si può anche specificare una dichiarazione: else:
alldaltons = ["Joe", "William", "Jack", "Averell"] if "Lucky" in alldaltons: print "We found that Dalton!!!" else: print "Such Dalton doesn't exist!"
I comandi standard di Python non sono molti. Nella versione corrente di Python ce ne sono circa 30, e ne conosciamo già alcuni di loro. Ma immaginate se potessimo inventare dei nostri propri comandi? Beh, possiamo, ed è estremamente facile. In effetti, la maggior parte dei moduli aggiuntivi che si possono aggiungere nella propria installazione di Python fanno esattamente questo, essi aggiungono dei comandi utilizzabili. In Python un comando personalizzato si chiama funzione e si crea in questo modo:
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.
Il nome "myValue" può contenere qualsiasi oggetto, e viene utilizzato solo all'interno della funzione. È solo un nome assegnato all'argomento in modo da poter operare con esso, però serve anche a fare in modo che la funzione sappia quanti argomenti aspettarsi. Se, ad esempio, si esegue:
printsqm(45,34)
Si ottiene un errore. La funzione è stata programmata per ricevere un solo argomento, ma ne ha ricevuto due, 45 e 34. In sostituzione, si può eseguire qualcosa di simile a:
def sum(val1,val2): total = val1 + val2 return total sum(45,34) myTotal = sum(45,34)
Dove si crea una funzione che riceve due argomenti, li somma, e restituisce il valore. Ottenere qualcosa è molto utile, perché permette di utilizzare il risultato ottenuto e, ad esempio, memorizzarlo nella variabile myTotal. Naturalmente, visto che siamo nell'interprete e tutto quello che facciamo viene stampato, digitando:
sum(45,34)
il risultato viene stampato sullo schermo, ma al di fuori dell'interprete, e, siccome non vi è alcun comando di stampa all'interno della funzione, sullo schermo non appare nulla. Per ottenere la stampa, si deve digitare:
print sum(45,34)
Per ulteriori informazioni sulle funzioni leggere qui.
Ora che si ha un'idea di come funziona Python, serve una ultima cosa: Come lavorare con i file e i moduli.
Fino ad ora, abbiamo scritto le istruzioni nell'interprete di Python riga per riga, vero?
Quando si intende fare delle cose più complesse, è certamente più comodo scrivere prima diverse righe di codice, e poi eseguirle tutte insieme in una unica volta. Bene, anche questo, è estremamente facile da farsi, e inoltre permette anche salvare il proprio lavoro.
È sufficiente aprire un editor di testo (ad es. il Blocco Note di Windows, o gedit, emacs, o vi per Linux), e scrivere tutte le proprie righe di Python, nello stesso modo in cui si scrivono nell'interprete, con indentazioni, ecc. Quindi, salvare il file da qualche parte, preferibilmente con estensione .py. Tutto qui, ora si dispone di un programma Python completo. Naturalmente, ci sono editor migliori di notepad, citato solo per dimostrare che un programma Python non è altro che un file di testo.
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"
e di salvarlo con il nome MioTest.py nella nostra directory /bin di FreeCAD (o on Linux to /home/<username>/.FreeCAD/Mod/scripts). Ora, avviamo FreeCAD e nella finestra interprete scriviamo:
import myTest
senza l'estensione. py. Questo comando esegue semplicemente il contenuto del file, riga per riga, esattamente come quando viene scritto nell'interprete. Viene creata la funzione somma, poi viene stampato il messaggio. Però c'è una grande differenza: il comando di importazione (import) serve non solo per eseguire i programmi contenuti in un file, come il nostro, ma anche per caricare le funzioni interne, in modo da renderle disponibili nell'interprete. I file, come il nostro, contenenti funzioni sono chiamati moduli.
Di solito, come si è fatto in precedenza, quando si scrive la funzione sum() nell'interprete, si digita semplicemente:
sum(14,45)
Invece, quando si importa un modulo contenente una funzione sum(), la sintassi è un po' diversa. Si scrive:
myTest.sum(14,45)
Cioè, il modulo viene importato come un "contenitore", e tutte le sue funzioni sono all'interno. Dato che è possibile importare più moduli, ciò è estremamente utile per tenere il tutto ben organizzato. In sostanza, quando si vede "qualcosa.qualcosaAltro", con un punto in mezzo, significa che "qualcosaAltro" è contenuto in "qualcosa".
Si può anche estrarre da test una sua parte, e importare la funzione sum() direttamente nello spazio principale dell'interprete, in questo modo:
from myTest import * sum(12,54)
In pratica tutti i moduli si comportano in questo modo. È possibile importare un modulo, e poi utilizzare le sue funzioni tramite l'istruzione: module.function (argomento). Quasi tutti i moduli eseguono le seguenti operazioni: definiscono le funzioni, i nuovi tipi di dati e le classi che è possibile utilizzare nell'interprete o nei moduli Python, perché nulla impedisce di importare altri moduli all'interno di un proprio modulo!
Un'ultima cosa estremamente utile. Come si fa per sapere quali moduli sono disponibili, quali funzioni sono al loro interno e come usarli (cioè, di che tipo di argomenti hanno bisogno)? Si è già visto che Python ha una funzione help(). Digitare:
help() modules
Viene restituito un elenco di tutti i moduli disponibili. Digitare q per uscire dall'aiuto interattivo e importare qualsiasi di essi.
Si può anche sfogliare il contenuto del modulo tramite il comando dir():
import math dir(math)
In questo caso, si vedono tutte le funzioni contenute nel modulo di matematica (il modulo math), come, ad esempio, cose con strani nomi __ doc__, __ FILE__, __ name__. L'oggetto doc__ __ è estremamente utile, è un testo di documentazione. Ogni funzione dei moduli (se fatti bene) ha un proprio __doc__ che spiega come usarla. Se, per esempio, si vuole sapere come usare la funzione sin (seno) contenuta all'interno del modulo math, basta digitare:
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()
Ma cosa succede se il modulo myTestFunction() non funziona correttamente? Si torna al proprio editor per modificarlo. Dopo, invece di chiudere e riaprire l'interprete python, è possibile aggiornare semplicemente il modulo in questo modo:
reload(myModule)
Questo perché Python non conosce l'estensione FCMacro.
Però, si può fare in due modi: 1. Utilizzare una funzione exec o execfile di Python all'interno della macro.
f = open("myModule","r") d = f.read() exec d
oppure
execfile "myModule"
Per condividere il codice tra le macro, è possibile ad esempio accedere al modulo FreeCAD o FreeCADGui (o qualsiasi altro modulo Python) e impostare qualsiasi attributo ad esso. Questo dovrebbe sopravvivere alla esecuzione della 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
Ora che si ha un'idea di come funziona Python si può iniziare ad esplorare quello che FreeCAD ha da offrire. Le funzioni Python di FreeCAD sono tutte ben organizzate in moduli diversi. Alcuni di loro vengono caricati (importati) all'avvio di FreeCAD. Quindi, basta solo, digitare:
dir()
e continuate a leggere in Script base in FreeCAD...
Naturalmente, quì si è visto solo una parte molto piccola del mondo di Python. Ci sono ancora molti altri concetti importanti che non sono stati menzionati qui.
In rete sono disponibili tre documenti molto importanti che referenziano Python:
Accertarsi di averli nel segnalibri!
FreeCAD è stato costruito fin dall'inizio per essere totalmente controllato tramite gli script Python.
Quasi tutte le parti di FreeCAD, come ad esempio l'interfaccia oppure i contenuti della scena, compresa la rappresentazione di quanto contenuto nelle viste 3D, sono accessibili tramite l'interprete Python incorporato o tramite script personali.
Per questo, FreeCAD risulta probabilmente una delle applicazioni ingegneristiche più profondamente personalizzabili oggi disponibili.
Allo stato attuale, FreeCAD ha però pochissimi comandi "nativi" per interagire con gli oggetti 3D, soprattutto perché è ancora all'inizio dello sviluppo, ma anche perché i suoi programmatori intendono fornire una piattaforma base per lo sviluppo del CAD piuttosto che un'applicazione per un uso specifico.
La facilità d'uso degli script Python all'interno di FreeCAD permette di conoscere velocemente le nuove funzionalità in fase di sviluppo come "utenti esperti", cioè come utenti che conoscono un po' di programmazione Python.
Python è uno dei più popolari linguaggi interpretati, e poiché è generalmente considerato facile da imparare, anche voi potrete produrre presto vostri script all'interno di FreeCAD come "utenti esperti".
Se non conoscete ancora Python, vi consigliamo di cercare qualche tutorial su internet e di dare un rapido sguardo alla sua struttura.
Python è un linguaggio molto facile da imparare, soprattutto perché può essere eseguito all'interno di un interprete, dove sia i comandi semplici come i programmi completi, possono essere eseguiti "al volo", cioè senza bisogno di compilare nulla.
FreeCAD incorpora un interprete Python. Se non vedete la finestra denominata "Console Python" della figura successiva, potete attivarla con Visualizza → Pannelli → Console Python e mostrare l'interprete.
Tramite l'interprete, è possibile accedere a tutti i moduli Python installati nel sistema, come pure ai moduli incorporati in FreeCAD e a tutti i moduli aggiuntivi di FreeCAD installati successivamente.
La schermata seguente mostra l'interprete Python di FreeCAD:
Tramite l'interprete è possibile eseguire del codice Python e sfogliare le classi e le funzioni disponibili.
FreeCAD fornisce un browser delle classi molto utile per esplorare il nuovo mondo di FreeCAD.
Quando si digita il nome di una classe nota seguita da un punto (.) (il che significa che si intende completare aggiungendo qualcos'altro alla classe), si apre la finestra del browser delle classi, dove si può navigare tra le sottoclassi e i metodi disponibili.
Quando si seleziona una voce, viene visualizzato il testo di aiuto associato (se esiste):
Per verificare questo, iniziate a digitare App. oppure Gui. e osservate cosa succede.
Generalmente, in Python, per esplorare il contenuto dei moduli e delle classi si utilizza il comando print dir().
Ad esempio, digitando print dir() si ottiene l'elenco di tutti i moduli attualmente caricati in FreeCAD e con print dir(App) si mostra tutto ciò che è contenuto all'interno del modulo App, ecc..
Inoltre l'interprete ricorda i codici che vengono digitati. Questa altra utile caratteristica dell'interprete permette di esplorare all'indietro i comandi digitati e di recuperare, attraverso la cronologia, una riga di codice scritta in precedenza.
Per navigare nella cronologia dei comandi, basta usare la combinazione di tasti CTRL+UP oppure CTRL+DOWN.
Cliccando col tasto destro nella finestra dell'interprete, si rendono disponibili diverse altre opzioni, quali, ad esempio, copiare lo storico (l'intera cronologia, cosa utile quando si desidera sperimentare qualcosa prima di utilizzarla in uno script) oppure inserire un nome di un file con il suo percorso completo.
Nel menu Aiuto di FreeCAD, trovate una voce denominata Moduli Python, essa apre una finestra del browser contenente una documentazione completa, generata in tempo reale, di tutti i moduli Python a disposizione dell'interprete di FreeCAD, compreso Python e i moduli interni di FreeCAD, i moduli installati dal sistema e i moduli aggiuntivi di FreeCAD.
La documentazione disponibile dipende dalla fatica che lo sviluppatore del modulo ha fatto per documentare il proprio codice. I moduli Python hanno la reputazione di essere in genere abbastanza ben documentati. La finestra di FreeCAD deve rimanere aperta perché questo sistema di documentazione funzioni.
Dato che FreeCAD è stato progettato per essere eseguito senza una interfaccia grafica (GUI), quasi tutte le sue funzionalità sono divise in due parti: la funzionalità di base, denominata App, e la funzionalità grafica, denominata Gui. Per questo motivo i due principali moduli incorporati nel nostro FreeCAD sono chiamati App e Gui. Questi due moduli sono accessibili, rispettivamente con il nome "FreeCAD" e "FreeCADGui", anche tramite script eseguiti al di fuori dell'interprete.
Elencare tutto il contenuto di tali moduli è un lavoro un po' controproducente, in quanto essi crescono molto velocemente seguendo lo sviluppo di FreeCAD.
I due strumenti di esplorazione disponibili (il browser delle classi e l'aiuto di Python) dovrebbero dare, in qualsiasi momento, una completa e aggiornata documentazione di questi moduli.
Come abbiamo detto, in FreeCAD, tutto viene separato tra nucleo e rappresentazione. Ciò vale anche per gli oggetti 3D.
È possibile accedere alla definizione delle proprietà degli oggetti (chiamate funzioni in FreeCAD) tramite il modulo App, e cambiare il modo in cui gli oggetti vengono riprodotti sullo schermo tramite il modulo Gui.
Ad esempio, un parallelepipedo ha delle proprietà che lo definiscono, (cioè larghezza, lunghezza e altezza) che vengono memorizzate in un oggetto App e delle proprietà di rappresentazione, (come il colore delle facce, la modalità di disegno) che sono memorizzate in un corrispondente oggetto Gui.
Questo modo di fare le cose consente una vasta gamma di operazioni, come gli algoritmi che funzionano solo sulla parte di definizione delle caratteristiche, senza la necessità di prendersi cura di nessuna parte visiva, e consente anche di reindirizzare il contenuto del documento a applicazioni non-grafiche, quali, ad esempio, elenchi, fogli di calcolo, o analisi degli elementi.
Nel documento, per ogni oggetto App, esiste un corrispondente oggetto Gui. Infatti lo stesso documento possiede sia oggetti App che oggetti Gui.
Questo, naturalmente, è valido solo quando si esegue FreeCAD completo di interfaccia grafica. Nella versione riga di comando, senza interfaccia grafica, sono quindi disponibili solo gli oggetti App.
Ricordare che la parte Gui degli oggetti viene rigenerata ogni volta che un oggetto App viene indicato "da ricalcolare" (ad esempio quando cambia uno dei suoi parametri), in quanto le modifiche fatte direttamente all'oggetto Gui potrebbero perdersi.
Per accedere alla parte App di qualcosa, si digita:
myObject = App.ActiveDocument.getObject("ObjectName")
dove "ObjectName" è il nome del vostro oggetto.
Inoltre è possibile digitare:
myObject = App.ActiveDocument.ObjectName
Per accedere alla parte Gui dello stesso oggetto, si digita:
myViewObject = Gui.ActiveDocument.getObject("ObjectName")
dove "ObjectName" è il nome del vostro oggetto.
Inoltre è possibile digitare:
myViewObject = App.ActiveDocument.ObjectName.ViewObject
Se non abbiamo GUI (ad esempio, siamo in modalità riga di comando), l'ultima riga non restituirà nulla.
In FreeCAD tutto il vostro lavoro si trova all'interno dei documenti.
Un documento contiene la geometria e può essere salvato in un file. Si possono avere simultaneamente più documenti aperti.
Il documento, come la geometria contenuta all'interno, ha oggetti App e oggetti Gui. L'oggetto App contiene le definizioni della geometria reale, mentre l'oggetto Gui contiene i diversi punti di vista del documento.
È possibile aprire più finestre, ognuna delle quali visualizza il lavoro con un fattore di zoom o un punto di vista diverso. Questi punti di vista fanno tutti parte dell'oggetto Gui del documento.
Per accedere alla parte App del documento attualmente aperto (attivo), si digita:
myDocument = App.ActiveDocument
Per creare un nuovo documento, si digita:
myDocument = App.newDocument("Document Name")
Per accedere alla parte Gui del documento attualmente aperto (attivo), si digita:
myGuiDocument = Gui.ActiveDocument
Per accedere alla vista corrente, si digita:
myView = Gui.ActiveDocument.ActiveView
I moduli FreeCAD e FreeCADGui sono responsabili esclusivamente della creazione e della gestione degli oggetti nel documento di FreeCAD.
Essi in realtà non fanno nulla che riguardi la creazione o la modifica della geometria.
Ciò è dovuto al fatto che la geometria può essere di diversi tipi, e quindi la sua gestione è affidata ai moduli aggiuntivi, ognuno di essi ha il compito di gestire uno specifico tipo di geometria.
Il modulo Parte utilizza il kernel OpenCascade, e quindi è in grado di creare e manipolare geometrie di tipo B-rep, che è appunto il tipo di geometria costruito da OpenCascade.
Il modulo Mesh è in grado di costruire e modificare gli oggetti mesh.
In questo modo, FreeCAD è in grado di gestire un'ampia gamma di tipi di oggetti che possono coesistere nello stesso documento, e nuovi tipi potrebbero essere aggiunti facilmente in futuro.
Ogni modulo tratta la propria geometria in un modo specifico, però in genere tutti i moduli possono creare degli oggetti nel documento.
Il documento FreeCAD è anche a conoscenza dei tipi di oggetti fornibili dai moduli e il seguente comando:
FreeCAD.ActiveDocument.supportedTypes()
mostra tutti gli oggetti che si possono creare.
Come esempio, proviamo a creare un oggetto mesh (trattato dal modulo Mesh) e un oggetto parte (trattato dal modulo Part):
myMesh = FreeCAD.ActiveDocument.addObject("Mesh::Feature","myMeshName") myPart = FreeCAD.ActiveDocument.addObject("Part::Feature","myPartName")
Il primo parametro è il tipo di oggetto, il secondo il nome dell'oggetto. I nostri due oggetti appaiono quasi come la stessa cosa.
Al momento, essi non contengono ancora la geometria, e se li ispezioniamo con dir(myMesh) e con dir(myPart) la maggior parte delle loro proprietà sono le stesse. L'unica differenza è che myMesh ha una proprietà "Mesh" e "Part" ha una proprietà "Shape". È qui che i dati Mesh e Parte vengono memorizzati.
Come esempio, creiamo un cubo di tipo Parte e poi lo archiviamo nel nostro oggetto myPart:
import Part cube = Part.makeBox(2,2,2) myPart.Shape = cube
Se provate a memorizzare il cubo all'interno della proprietà Mesh dell'oggetto myMesh, vi verrà restituito un messaggio di "errore di tipo". Questo perché le proprietà sono fatte in modo da memorizzare solo uno specifico tipo. Nelle proprietà Mesh di myMesh, è possibile salvare solo elementi creati con il modulo Mesh.
Notare che la maggior parte dei moduli hanno anche un collegamento per aggiungere la loro geometria al documento:
import Part cube = Part.makeBox(2,2,2) Part.show(cube)
La modifica di un oggetto si esegue nello stesso modo:
import Part cube = Part.makeBox(2,2,2) myPart.Shape = cube
Ora cambiamo la sua forma in una più grande:
biggercube = Part.makeBox(5,5,5) myPart.Shape = biggercube
È sempre possibile sapere di che tipo è un oggetto con:
myObj = FreeCAD.ActiveDocument.getObject("myObjectName") print myObj.TypeId
o sapere se un oggetto è derivato da uno di quelli base (struttura di Parte, struttura di Mesh, etc) con:
print myObj.isDerivedFrom("Part::Feature")
Ora si può davvero iniziare a divertirsi con FreeCAD! Per vedere ciò che si può fare con il Modulo Parte, leggere la pagina Script per ambiente Parte, o la pagina Script per ambiente Mesh per lavorare con il Modulo Mesh.
Notare che, oltre ai moduli Parte e Mesh che sono i più completi e sono molto utilizzati, anche altri moduli come il Modulo Draft hanno script API che possono servirvi.
Per un elenco completo di tutti i moduli e gli strumenti disponibili, consultare la sezione Category:API/it.
Prima di tutto si deve importare il modulo Mesh:
import Mesh
Dopo questa operazione si ha accesso al modulo Mesh e alla classe Mesh che offrono le funzioni del Kernel C++ Mesh di FreeCAD.
Per creare un oggetto mesh vuoto basta usare il costruttore standard:
mesh = Mesh.Mesh()
Inoltre è possibile creare un oggetto da un file
mesh = Mesh.Mesh('D:/temp/Something.stl')
Un elenco di tipi di file compatibili è disponibile in questa pagina al paragrafo 'Mesh'.
Oppure crearlo tramite un gruppo di triangoli descritti dai loro vertici:
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)
Il Kernel Mesh si occupa di creare una corretta struttura topologica dei dati individuando i punti e i bordi coincidenti.
Più avanti si vedrà come è possibile verificare ed esaminare i dati mesh.
Per creare delle geometrie regolari è possibile utilizzare lo script Python BuildRegularGeoms.py.
import BuildRegularGeoms
Questo script fornisce i metodi per definire semplici corpi di rotazione, tipo le sfere, gli ellissoidi, i cilindri, i coni e i toroidi. Inoltre ha anche un metodo per creare un semplice cubo.
Ad esempio, per creare un toroide si può fare nel modo seguente:
t = BuildRegularGeoms.Toroid(8.0, 2.0, 50) # list with several thousands triangles
m = Mesh.Mesh(t)
I primi due parametri definiscono i raggi del toroide e il terzo parametro è un fattore di sub-campionamento che stabilisce quanti triangoli vengono creati. Maggiore è questo valore e più il corpo è liscio, più questo valore è piccolo e più il corpo è grossolano (sfaccettato).
La classe Mesh fornisce una serie di funzioni booleane che possono essere utilizzate per operazioni di modellazione. Essa fornisce l'unione, l'intersezione e la differenza tra due oggetti mesh.
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
Ecco infine, un esempio completo che calcola l'intersezione tra una sfera e un cilindro che interseca la sfera.
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()
Si può anche scrivere l'oggetto mesh in un modulo python:
m.write("D:/Develop/Projekte/FreeCAD/FreeCAD_0.7/Mod/Mesh/SavedMesh.py")
import SavedMesh
m2 = Mesh.Mesh(SavedMesh.faces)
Una nutrita (anche se difficile da usare) libreria di script riferiti a Mesh sono gli script dell'unita di test del Modulo Mesh. In questa unit test sono letteralmente chiamati tutti i metodi e sono ottimizzate tutte le proprietà e gli attributi. Quindi, se siete abbastanza coraggiosi, date un'occhiata al modulo unit test.
Vedere anche Mesh API
|
Argomento |
---|
Programmazione |
Livello di difficoltà |
Intermedio |
Tempo di esecuzione |
Autore |
Versione di FreeCAD |
File di esempio |
Questa pagina descrive i diversi metodi per creare e modificare gli oggetti di tipo Parte tramite Python.
Se non si conosce ancora Python, prima di leggere questa pagina, è meglio leggere la pagina di introduzione a Python e quella in cui si descrive come funzionano gli script in FreeCAD.
Qui si spiega come controllare il Modulo Parte direttamente tramite l'interprete Python di FreeCAD, o tramite degli script esterni.
Se avete bisogno di ulteriori informazioni su come funzionano gli script in FreeCAD, potete consultare la sezione Script e la sezione Concetti base sugli script in FreeCAD.
Questa è una panoramica delle classi Linguaggio di Modellazione Unificato (UML) più importanti del modulo Parte:
Gli oggetti geometrici sono le fondamenta per la costruzione di tutti gli oggetti topologici:
Sono disponibili i seguenti tipi di dati topologici:
Creeremo ora una topologia tramite la costruzione della semplice geometria. Come caso di studio, utilizzeremo una forma come quella che si vede nella figura, composta da quattro vertici, due cerchi e due linee.
Per prima cosa dobbiamo creare le singole parti geometriche di questo contorno (wire). È necessario che i vertici delle parti geometriche siano nella stessa posizione. In caso contrario, in seguito potremmo non essere in grado di collegare le parti geometriche in una topologia!
Quindi creiamo prima i punti:
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)
Per creare un arco di cerchio prima creiamo un punto di supporto poi creiamo l'arco di cerchio tramite tre punti:
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)
La linea può essere creata molto semplicemente tramite i punti:
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
L'ultimo passaggio consiste nell'unire tutti gli elementi geometrici di base e produrre una forma topologica:
S1 = Part.Shape([C1,L1,C2,L2])
Ora si può estrudere il contorno nella direzione voluta e creare una forma 3D reale:
W = Part.Wire(S1.Edges) P = W.extrude(Base.Vector(0,0,10))
Per visualizzare il prisma:
Part.show(P)
Con i metodi "make...()" del Modulo Parte è possibile creare facilmente oggetti topologici di base (chiamati anche forme primitive). Ad esempio, si può creare un cubo con:
b = Part.makeBox(100,100,100) Part.show(b)
Altri metodi make...() disponibili sono:
Per avere un elenco completo dei metodi disponibili con il modulo Parte consultare la pagina API di Parte (Part API in inglese).
In primo luogo è necessario importare il modulo Parte per poter utilizzare i suoi contenuti in Python. Inoltre, importiamo anche il modulo Base dall'interno del modulo FreeCAD:
import Part from FreeCAD import Base
Per la costruzione di forme, i Vettori sono una delle parti di informazione più importanti. Di solito, ma non necessariamente sempre, essi contengono 3 numeri che sono le coordinate cartesiane x, y e z. È possibile creare un vettore nel modo seguente:
myVector = Base.Vector(3,2,0)
Abbiamo appena creato un vettore nelle coordinate x=3, y=2, z=0. Nel modulo Parte, i vettori sono usati in tutte le parti. Le forme Parte usano anche un altro tipo di rappresentazione del punto, chiamato Vertex (Vertice), che in realtà non è altro che un contenitore per un vettore. Si accede al vettore di un vertice in questo modo:
myVertex = myShape.Vertexes[0] print myVertex.Point > Vector (3, 2, 0)
Un bordo non è altro che una linea con due vertici:
edge = Part.makeLine((0,0,0), (10,0,0)) edge.Vertexes > [<Vertex object at 01877430>, <Vertex object at 014888E0>]
Nota: È anche possibile creare un bordo passando due vettori:
vec1 = Base.Vector(0,0,0) vec2 = Base.Vector(10,0,0) line = Part.LineSegment(vec1,vec2) edge = line.toShape()
È possibile trovare la lunghezza e il centro di un bordo in questo modo:
edge.Length > 10.0 edge.CenterOfMass > Vector (5, 0, 0)
Con le operazioni precedenti abbiamo creato un oggetto bordo, ma esso non è visibile da nessuna parte sullo schermo. Questo perché fino a qui abbiamo manipolato solo oggetti Python. La scena 3D di FreeCAD mostra solo quello che gli si chiede di visualizzare. Per farlo, usiamo questo semplice metodo:
Part.show(edge)
Nel nostro documento FreeCAD viene creato un oggetto, e la nostra forma "edge" viene attribuita ad esso. Utilizzare questo metodo ogni volta che si vuole visulizzare il proprio prodotto sullo schermo.
Un contorno è una polilinea e può essere creato da una serie di bordi o anche da una serie di contorni:
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) serve per visualizzare i 4 bordi che compongono il nostro contorno. Si possono facilmente recuperare altre informazioni utili con:
wire3.Length > 40.0 wire3.CenterOfMass > Vector (5, 5, 0) wire3.isClosed() > True wire2.isClosed() > False
Sono valide solo le facce create da contorni chiusi. Nell'esempio, wire3 è un contorno chiuso, ma wire2 non è un contorno chiuso (vedi esempio precedente)
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
Solamente le facce hanno un'area, non i contorni né i bordi.
Un cerchio può essere creato in questo semplice modo:
circle = Part.makeCircle(10) circle.Curve > Circle (Radius : 10, Position : (0, 0, 0), Direction : (0, 0, 1))
Se si vuole crearlo in una determinata posizione e con una direzione prestabilita:
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))
ccircle verrà creato a distanza 10 dall'origine su x e sarà rivolto verso l'asse x. Nota: makeCircle accetta solo Base.Vector() per la posizione e le normali, ma non tuple. È inoltre possibile creare una parte di cerchio fornendo un angolo iniziale e un angolo finale come:
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)
Unendo arc1 con arc2 (sono due semicerchi) si ottiene un cerchio completo. Gli angoli devono essere forniti in gradi, se avete angoli in radianti convertirli usando semplicemente la formula: gradi = radianti * 180/PI o utilizzando il modulo matematico di Python (ovviamente, dopo aver importato il modulo math):
degrees = math.degrees(radians)
Purtroppo, per creare un arco lungo tre punti non esiste una funzione makeArc ma si deve usare la funzione Part.Arc. Fondamentalmente si può pensare come un arco che unisce il punto iniziale e finale passando per il punto medio. Part.Arc crea un oggetto arco nel quale deve essere chiamato .toShape() per ottenere un oggetto bordo, allo stesso modo di quando si usa Part.Line al posto di Part.makeLine.
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()
Arc accetta solo punti Base.Vector(), ma non tuple. arc_edge è ciò che vogliamo e che possiamo visualizzare con Part.show(arc_edge). Inoltre è possibile ottenere un arco utilizzando una porzione di un cerchio:
from math import pi circle = Part.Circle(Base.Vector(0,0,0),Base.Vector(0,0,1),10) arc = Part.Arc(c,0,pi)
Gli archi sono bordi validi, come le linee. Quindi possono essere usati anche nei contorni.
Un poligono è semplicemente un contorno composto da diversi bordi diritti. La funzione makePolygon prende una lista di punti e crea un contorno attraverso questi punti:
lshape_wire = Part.makePolygon([Base.Vector(0,5,0),Base.Vector(0,0,0),Base.Vector(5,0,0)])
Le curve di Bézier sono utilizzate per modellare delle curve morbide utilizzando una serie di Poles (punti) e weight (pesi) opzionali. La funzione sottostante crea una Part.BezierCurve da una serie di punti FreeCAD.Vector. (Notare che gli indici di pole e di weight partono da 1, non da 0.)
def makeBCurveEdge(Points): geomCurve = Part.BezierCurve() geomCurve.setPoles(Points) edge = Part.Edge(geomCurve) return(edge)
Un Piano è semplicemente una superficie piana rettangolare. Il metodo utilizzato per crearlo è questo: makePlane(lunghezza, larghezza, [start_pnt, dir_normal]). Per impostazione predefinita start_pnt=Vector (0,0,0) e dir_normal=Vector(0,0,1). Utilizzando dir_normal=Vector(0,0,1) creeremo il piano orientato come l'asse z, mentre con dir_normal=Vector(1,0,0) creeremo il piano orientato come l'asse x:
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 è il parallelepipedo che racchiude il piano e la cui diagonale parte da (3,0,0) e termina in (5,0,2). Qui lo spessore di BoundBox sull'asse y è zero, poiché la nostra forma è totalmente piatta.
Nota: makePlane accetta solo Base.Vector() per start_pnt e dir_normal e non tuple
Per creare un'ellisse ci sono diversi modi:
Part.Ellipse()
Crea un'ellisse con raggio maggiore 2 e raggio minore 1 con centro in (0,0,0)
Part.Ellipse(Ellipse)
Crea una copia dell'ellisse data
Part.Ellipse(S1,S2,Center)
Crea un'ellisse centrato sul punto Center, in cui il piano dell'ellisse è definito da Center, S1 e S2, il suo asse maggiore è definito da Center e S1, il suo raggio maggiore è la distanza tra Center e S1, e il suo raggio minore è la distanza tra S2 e l'asse maggiore.
Part.Ellipse(Center,MajorRadius,MinorRadius)
Crea un'ellisse con il raggio maggiore e il raggio minore MajorRadius e MinorRadius, e situata nel piano definito da Center e la normale (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())
Nel codice precedente abbiamo passato S1, S2 e il centro. Analogamente a Arco, Ellisse crea un oggetto ellisse ma non un bordo, quindi, per visualizzarlo è necessario di convertirlo in bordo utilizzando toShape().
Nota: Arc accetta solo Base.Vector() per i punti, ma non le tuple
eli = Part.Ellipse(Base.Vector(0,0,0),10,5) Part.show(eli.toShape())
per il costruttore Ellisse precedente abbiamo passato il centro, MajorRadius e MinorRadius
Utilizzando il metodo makeTorus(radius1,radius2,[pnt,dir,angle1,angle2,angle]). Per impostazione predefinita PNT=Vector(0,0,0), dir=Vector(0,0,1), angle1=0, angle2=360 e angolo=360. Si consideri un toro, come un cerchio piccolo che si muove lungo un cerchio grande. Radius1 è il raggio del cerchio grande, radius2 è il raggio del cerchio piccolo, pnt è il centro del toro e dir è la direzione normale. angle1 e angle2 sono angoli in radianti per il cerchio piccolo cerchio, l'ultimo parametro angolo serve per realizzare una porzione del toro:
torus = Part.makeTorus(10, 2)
Il codice precedente creerà un toro con diametro 20 (raggio 10) e spessore di 4 (raggio del cerchio piccolo 2)
tor=Part.makeTorus(10,5,Base.Vector(0,0,0),Base.Vector(0,0,1),0,180)
Il codice sopra creerà una fetta del toro
tor=Part.makeTorus(10,5,Base.Vector(0,0,0),Base.Vector(0,0,1),0,360,180)
Il codice precedente creerà un semi toro, solo l'ultimo parametro viene modificato vale a dire l'angolo e gli angoli rimanenti sono predefiniti. Impostare il valore dell'angolo a 180 creerà il toro da 0 a 180, cioè, un mezzo toro.
Utilizzando makeBox(lunghezza, larghezza, altezza,[pnt,dir]). Per impostazione predefinita pnt=Vector(0,0,0) e dir=Vector(0,0,1)
box = Part.makeBox(10,10,10) len(box.Vertexes) > 8
Utilizzando makeSphere(radius,[pnt, dir, angle1,angle2,angle3]). Per impostazione predefinita pnt=Vector(0,0,0), dir=Vector(0,0,1), angle1=-90, angle2=90 e angle3=360. angle1 e angle2 sono il minimo e il massimo in verticale della sfera, angle3 è il diametro della sfera stessa.
sphere = Part.makeSphere(10) hemisphere = Part.makeSphere(10,Base.Vector(0,0,0),Base.Vector(0,0,1),-90,90,180)
Utilizzando makeCylinder(radius,height,[pnt,dir,angle]). Per impostazione predefinita pnt=Vector(0,0,0),dir=Vector(0,0,1) e angle=360
cylinder = Part.makeCylinder(5,20)
partCylinder = Part.makeCylinder(5,20,Base.Vector(20,0,0),Base.Vector(0,0,1),180)
Utilizzando makeCone(radius1,radius2,height,[pnt,dir,angle]). Per impostazione predefinita pnt=Vector(0,0,0), dir=Vector(0,0,1) e 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)
Ci sono diversi modi per modificare le forme. Alcuni sono semplici operazioni di trasformazione come lo spostamento o la rotazione di forme, altri sono più complessi, come ad esempio unire e sottrarre una forma da un'altra. Tenere in considerazione questo.
Traslare è l'atto di spostare una forma da un luogo all'altro. Qualsiasi forma (bordo, faccia, cubo, ecc ..) può essere traslata in questo modo:
myShape = Part.makeBox(2,2,2)
myShape.translate(Base.Vector(2,0,0))
Questo sposterà la forma "myShape" di 2 unità nella direzione dell'asse x.
Per ruotare una forma, è necessario specificare il centro di rotazione, l'asse e l'angolo di rotazione:
myShape.rotate(Vector(0,0,0),Vector(0,0,1),180)
Il codice precedente ruota la forma di 180 gradi attorno all'asse z.
Una matrice è un modo molto conveniente per memorizzare le trasformazioni nel mondo 3D. In una matrice singola, è possibile impostare valori di traslazione, rotazione e scala da applicare ad un oggetto. Ad esempio:
myMat = Base.Matrix()
myMat.move(Base.Vector(2,0,0))
myMat.rotateZ(math.pi/2)
Nota. Le matrici di FreeCAD lavorano in radianti. Inoltre, quasi tutte le operazioni di matrici che accettano un vettore possono anche accettare 3 numeri, quindi le seguenti 2 linee fanno la stessa cosa:
myMat.move(2,0,0)
myMat.move(Base.Vector(2,0,0))
Quando la matrice è impostata, possiamo applicarla alla nostra forma. FreeCAD fornisce 2 metodi per farlo: transformShape() e transformGeometry(). La differenza è che con il primo, si è sicuri che non si verifichino deformazioni (vedi "scalare una forma" più avanti). Quindi possiamo applicare la nostra trasformazione in questo modo:
myShape.trasformShape(myMat)
oppure
myShape.transformGeometry(myMat)
Scalare (ridimensionare) una forma è una delle operazioni più pericolose perché, a differenza della traslazione o della rotazione, il ridimensionamento non uniforme (con valori diversi per gli assi x, y, z) può modificare la struttura della forma. Ad esempio, la scalatura di un cerchio con un valore in orizzontale diverso da quello in verticale lo trasformerà in un ellisse, forma che matematicamente si comporta in modo molto diverso. Per il ridimensionamento, non possiamo usare transformShape, ma dobbiamo usare transformGeometry():
myMat = Base.Matrix()
myMat.scale(2,1,1)
myShape=myShape.transformGeometry(myMat)
Nel gergo OCC/FreeCAD, la differenza (sottrazione) di una forma da un altra si chiama "cut" taglia e si esegue così:
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)
Allo stesso modo, l'intersezione tra le forme 2 è chiamato "common" intersezione e viene eseguita in questo modo:
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)
Unione è chiamata "fuse" fusione e funziona allo stesso modo:
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)
Una sezione è l'intersezione tra una forma solida e una forma piana. Restituisce una curva di intersezione, un composto con i bordi:
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>]
Estrusione è l'atto di "spingere" una forma piatta in una certa direzione per produrre un corpo solido. Ad esempio, pensate di "spingere" un cerchio e di produrre un tubo:
circle = Part.makeCircle(10)
tube = circle.extrude(Base.Vector(0,0,2))
Se il cerchio è vuoto (sola circonferenza), si ottiene un tubo (cavo). Se il cerchio è in realtà un disco, con una faccia piena, si ottiene un cilindro (pieno):
wire = Part.Wire(circle)
disc = Part.Face(wire)
cylinder = disc.extrude(Base.Vector(0,0,2))
Si può facilmente esplorare la struttura dei dati topologici:
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
Digitando le righe di cui sopra nell'interprete Python, si otterrà una buona descrizione della struttura degli oggetti Parte. Qui, il nostro comando makeBox() crea una forma solida. Questo solido, come tutti i solidi Parte, contiene delle facce. Le facce contengono sempre delle linee (polilinee), che sono liste di bordi che delimitano la faccia. Ciascuna faccia ha almeno un contorno chiuso (ne può avere più di uno se la faccia presenta dei fori). Nel contorno, possiamo guardare a ciascun bordo separatamente, e all'interno di ogni bordo, possiamo vedere i vertici. Ovviamente, i bordi diritti hanno solo due vertici.
Nel caso in cui il bordo è una curva arbitraria, è più probabile che si voglia fare una discretizzazione. In FreeCAD i bordi sono parametrizzati dalle loro lunghezze. Ciò significa che si può percorrere un bordo/curva con la sua lunghezza:
import Part
box = Part.makeBox(100,100,100)
anEdge = box.Edges[0]
print anEdge.Length
Ora è possibile accedere a un sacco di proprietà del bordo utilizzando la lunghezza come una posizione. Ciò significa che se il bordo è lungo 100 mm la posizione iniziale è 0 e la posizione finale è 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)
Qui ora vediamo come possiamo usare la selezione che l'utente ha nel visualizzatore. Prima di tutto creiamo una scatola e la mostriamo nel visualizzatore:
import Part
Part.show(Part.makeBox(100,100,100))
Gui.SendMsgToActiveView("ViewFit")
Selezionate ora alcune facce o bordi. Con questo script è possibile iterare tutti gli oggetti selezionati e i relativi elementi secondari:
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
Selezionate alcuni bordi e questo script calcolerà la lunghezza:
length = 0.0
for o in Gui.Selection.getSelectionEx():
for s in o.SubObjects:
length += s.Length
print "Length of the selected edges:" ,length
Un esempio tipico si trova nella pagina OpenCasCade Technology Tutorial che spiega come costruire una bottiglia. Questo è un buon esercizio anche per FreeCAD. In effetti, si può seguire il nostro esempio qui sotto e la pagina di OCC contemporaneamente, capirete bene come sono implementate le strutture di OCC in FreeCAD. Lo script completo è anche incluso nell'installazione di FreeCAD (all'interno della cartella Mod/Part) e può essere chiamato dall'interprete python digitando:
import Part
import MakeBottle
bottle = MakeBottle.makeBottle()
Part.show(bottle)
Questo è lo script completo MakeBottle:
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)
import Part, FreeCAD, math
from FreeCAD import Base
Avremo bisogno, naturalmente, del modulo Parte, ma anche del modulo FreeCAD.Base, che contiene le strutture base di FreeCAD come vettori e matrici.
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)
Qui definiamo la nostra funzione makeBottle. Questa funzione può essere chiamata senza argomenti, come abbiamo fatto in precedenza, nel qual caso si utilizzano i valori di default per la larghezza, l'altezza e lo spessore. Poi, si definisce un paio di punti che verranno utilizzati per costruire il nostro profilo base.
aArcOfCircle = Part.Arc(aPnt2,aPnt3,aPnt4)
aSegment1=Part.LineSegment(aPnt1,aPnt2)
aSegment2=Part.LineSegment(aPnt4,aPnt5)
Qui definiamo la geometria effettiva: un arco, creato da 3 punti, e due segmenti di linea, creati da 2 punti.
aEdge1=aSegment1.toShape()
aEdge2=aArcOfCircle.toShape()
aEdge3=aSegment2.toShape()
aWire=Part.Wire([aEdge1,aEdge2,aEdge3])
Ricordate la differenza tra geometria e forme? Qui costruiremo forme partendo dalla nostra geometria di costruzione. Prima costruiremo 3 bordi (i bordi possono essere dritti o curvi), poi costruiremo un contorno con quei tre bordi.
aTrsf=Base.Matrix()
aTrsf.rotateZ(math.pi) # rotate around the z-axis
aMirroredWire=aWire.transformGeometry(aTrsf)
myWireProfile=Part.Wire([aWire,aMirroredWire])
Prima abbiamo costruito solo metà profilo. È più facile che costruire tutto l'intero profilo nello stesso modo, successivamente possiamo semplicemente rispecchiare quello che abbiamo costruito, e poi unire le due parti. Quindi per prima cosa è necessario creare una matrice. Una matrice è un modo molto comune per applicare trasformazioni agli oggetti nel mondo 3D, in quanto essa può contenere in un'unica struttura tutte le trasformazioni di base che gli oggetti 3D possono subire (spostamento, rotazione e scalatura). Qui, dopo aver creato la matrice, la specchiamo e creiamo una copia del nostro contorno applicando ad esso quella matrice di trasformazione. Ora abbiamo due contorni, e con essi possiamo produrre un terzo profilo, dal momento che i contorni sono in realtà liste di bordi.
myFaceProfile=Part.Face(myWireProfile)
aPrismVec=Base.Vector(0,0,myHeight)
myBody=myFaceProfile.extrude(aPrismVec)
myBody=myBody.makeFillet(myThickness/12.0,myBody.Edges)
Ora che abbiamo un contorno chiuso, esso può essere trasformato in una faccia. Una volta che abbiamo una faccia, possiamo estruderla. In questo modo, abbiamo effettivamente creato un solido. Poi si applica un piccolo arrotondamento al nostro oggetto, perché vogliamo ottenere una forma graziosa, non è vero?
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)
A questo punto, il corpo della nostra bottiglia è creato, abbiamo ancora bisogno di creare un collo. Così facciamo un nuovo solido, con un cilindro.
myBody = myBody.fuse(myNeck)
L'operazione di fusione, che in altre applicazioni a volte è chiamata unione, è molto potente. Si prenderà cura di incollare ciò che deve essere incollato e di rimuovere le parti che devono essere rimosse.
return myBody
Poi, otteniamo il nostro solido Parte come risultato della nostra funzione. Questo solido Parte, come qualsiasi altra forma Parte, può essere attribuito a un oggetto in un documento FreeCAD, con:
el = makeBottle()
Part.show(el)
oppure, più semplicemente con:
Ecco un esempio completo della costruzione di una scatola forata.
La costruzione è fatta lato per lato e quando il cubo è finito, viene scavato un foro con cilindro che l'attraversa.
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)
Nel modulo Parte ci sono diversi modi per salvare il proprio lavoro. Naturalmente, è possibile salvare il documento in formato FreeCAD, ma è anche possibile salvare gli oggetti Parte direttamente nei comuni formati CAD, come ad esempio BREP, IGS, STEP e STL.
Salvare una forma in un file è facile. Per tutti gli oggetti di forma sono disponibili i metodi exportBrep(), exportIges(), exportStl() e exportStep(). Così, facendo:
import Part
s = Part.makeBox(0,0,0,10,10,10)
s.exportStep("test.stp")
salviamo il nostro box in un file STEP. Per caricare un file BREP, IGES o STEP, basta fare il contrario:
import Part
s = Part.Shape()
s.read("test.stp")
Per convertire un file .stp in .igs fare semplicemente :
import Part
s = Part.Shape()
s.read("file.stp") # incoming file igs, stp, stl, brep
s.exportIges("file.igs") # outbound file igs
Notare che l'importazione o l'apertura di file BREP, IGES o STEP può essere effettuata anche direttamente dal menu File -> Apri o File -> Importa, mentre l'esportazione si esegue con File -> Esporta.
La conversione di oggetti di alto livello come le forme di Parte in oggetti semplici come gli oggetti Mesh è una operazione piuttosto semplice, nella quale tutte le facce di un oggetto Parte vengono triangolate (suddivise in maglie di una rete). Il risultato di tale triangolazione (tassellatura) viene poi utilizzato per costruire un oggetto mesh: (supponiamo che il nostro documento contenga un oggetto Parte)
#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)
A volte la triangolazione di alcune facce offerta da OpenCascade è abbastanza brutta. Se la faccia ha una forma rettangolare e non contiene buchi o altre curve di taglio è possibile creare una tassellatura da soli:
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
La conversione di oggetti Mesh in oggetti Parte è un'operazione estremamente importante nel lavoro CAD perché molto spesso i dati 3D si ricevono da altri in formato mesh o sono generati da altre applicazioni. I mesh sono molto pratici per rappresentare le geometrie di forma libera e grandi scene visive in quanto sono molto leggeri, ma per lavori CAD si preferiscono generalmente oggetti di livello superiore, che contengono molte più informazioni, come il concetto di solido, o facce composte da curve invece che da triangoli.
Convertire gli oggetti mesh in oggetti di livello superiore, come sono gli oggetti gestiti dal Modulo Parte di FreeCAD non è un'operazione facile. L'oggetto Mesh può contenere migliaia di triangoli (per esempio quando è generato da uno scanner 3D), e manipolare solidi costituiti dallo stesso numero di facce sarebbe estremamente pesante. Quindi, in genere, si desidera ottimizzare l'oggetto durante la conversione.
FreeCAD attualmente offre due metodi per convertire Mesh in oggetti Parte. Il primo metodo è una semplice conversione, diretta, senza alcuna ottimizzazione:
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)
Il secondo metodo offre la possibilità di considerare complanari le sfaccettature delle maglie quando l'angolo tra di loro è inferiore a un certo valore. Questo permette di costruire delle forme molto più semplici: (supponiamo che il nostro documento contenga un oggetto Mesh)
# 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 lsit 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)
FreeCAD è sostanzialmente un collage di potenti librerie. OpenCascade è la più importante ed è utilizzata per la gestione e la costruzione della geometria, Coin3d serve per visualizzare questa geometria, e Qt per disporre il tutto in una gradevole interfaccia grafica (GUI).
Le geometrie che appaiono nelle viste 3D di FreeCAD sono visualizzate (renderizzate) dalla libreria Coin3D. Coin3D è un'implementazione delle funzionalità standard di OpenInventor. Anche il software openCascade fornisce queste funzionalità, ma, fin dagli inizi dello sviluppo di FreeCAD, è stato deciso di non utilizzare il visualizzatore di OpenCascade e di sostituirlo con il software Coin3D in quanto più performante. Un buon modo per conoscere questa libreria è quello di consultare il manuale Open Inventor Mentor.
OpenInventor è in realtà un linguaggio di descrizione della scena 3D. La scena descritta in OpenInventor viene renderizzata (visualizzata) sul vostro schermo con OpenGL. Coin3D si occupa di questo processo, quindi non è necessario che il programmatore tratti complesse chiamate a OpenGL, ma deve solo fornire un codice OpenInventor valido. Il principale vantaggio è che OpenInventor è uno standard molto conosciuto e ben documentato.
Sostanzialmente, uno dei lavori più importanti che FreeCAD esegue per noi consiste nel tradurre le informazioni sulla geometria OpenCascade in linguaggio OpenInventor.
OpenInventor descrive una scena 3D in forma di grafo di scena (Scenegraph), come quello seguente:
immagine da Inventor mentor
Un grafo di scena di OpenInventor è una struttura di tipo "grafico ad albero" e descrive tutto ciò che fa parte di una scena 3D, come ad esempio la geometria, i colori, i materiali, le luci, ecc, e organizza tutti i dati in una struttura gerarchica, pratica e chiara. Tutto può essere raggruppato in sotto-strutture (nodi-figlio), il che consente di organizzare i contenuti della scena più o meno nel modo desiderato. Ecco un esempio di un file di OpenInventor:
#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 { } } }
Come si vede, la struttura è molto semplice. Si utilizzano i nodi (separator) per organizzare i dati in blocchi, un po' come si fa per organizzare i file in cartelle e sottocartelle. Ogni dichiarazione riguarda ciò che viene in seguito, per esempio, i primi due elementi del nostro nodo radice (root separator) sono una rotazione e una traslazione e agiscono entrambi sull'elemento successivo, che è un nodo (separator). In tale nodo sono definiti un materiale e una ulteriore trasformazione. Pertanto, il nostro cilindro sarà influenzato da entrambe le trasformazioni, da quella che è stata applicata direttamente ad esso e da quella che è stata applicata al suo nodo (separator) genitore.
Per organizzare la una scena, sono disponibili molti altri tipi di elementi, come gruppi, commutatori o annotazioni. Per gli oggetti si possono definire dei materiali molto complessi, con colori, texture, modalità di ombreggiatura e trasparenza. Si possono anche definire luci, punti di vista (camera) e perfino il movimento. È anche possibile incorporare parti di script nei file di OpenInventor, per definire comportamenti più complessi.
Se siete interessati a saperne di più su OpenInventor, consultate direttamente il suo manuale più famoso: il libro Inventor mentor.
Normalmente, in FreeCAD, non è necessario interagire direttamente con il grafo della scena di OpenInventor. Ogni oggetto in un documento di FreeCAD, sia che si tratti di un Mesh, di una forma Parte o di qualsiasi altra cosa, viene automaticamente convertito in codice OpenInventor e inserito nel grafo della scena principale che appare in una vista 3D. Questo grafo di scena viene costantemente aggiornato tutte le volte che si apportano delle modifiche, oppure si aggiungono o si rimuovono degli oggetti nel documento. In realtà, ogni oggetto (nell'ambito App) ha un fornitore di vista (un corrispondente oggetto nell'ambito Gui), responsabile del rilascio del codice OpenInventor.
Potere accedere al direttamente al grafico di scena presenta comunque molti vantaggi. Ad esempio, si può modificare temporaneamente la visualizzazione di un oggetto, oppure si possono aggiungere alla scena oggetti che nel documento di FreeCAD non hanno esistenza reale, come la geometria di costruzione, i riferimenti, i suggerimenti grafici oppure strumenti quali i manipolatori oppure informazioni sullo schermo.
FreeCAD dispone di diversi strumenti per visualizzare o modificare il codice OpenInventor. Ad esempio, il seguente codice Python mostra la rappresentazione OpenInventor di un oggetto selezionato:
obj = FreeCAD.ActiveDocument.ActiveObject viewprovider = obj.ViewObject print viewprovider.toString()
Inoltre, c'è anche un modulo Python che consente l'accesso completo a tutto quello che è gestito da Coin3D, come il grafico di scena di FreeCAD. Continuate quindi la lettura in Pivy.
Pivy è una libreria che collega Python con Coin3d, ed è la libreria di renderizzazione-3D utilizzata in FreeCAD. Quando viene importata in un interprete Python in esecuzione, permette di dialogare direttamente con qualsiasi grafo di scena (scenegraph) di Coin3d in esecuzione, come ad esempio le viste 3D di FreeCAD, o addirittura di creare nuovi grafi di scena. Pivy è incluso nell'installazione standard di FreeCAD.
La libreria Coin è divisa in vari moduli, Coin stessa, per manipolare grafi di scene e associarli a diversi sistemi GUI, come a Windows oppure, come nel nostro caso, a Qt. Tali moduli sono disponibili anche per Pivy, se sono presenti nel sistema. Il modulo Coin è sempre presente, ed è quello che useremo in tutti gli esempi, e non sarà necessario preoccuparsi di associare la nostra visualizzazione 3D ad alcuna interfaccia, perchè questo viene già fatto da FreeCAD stesso. Tutto quello che dobbiamo fare è:
from pivy import coin
Abbiamo già visto nella pagina Grafo della scena (Scenegraph) come è organizzata una tipica scena di Coin. Tutto ciò che appare in una vista 3D di FreeCAD è un Scenegraph di Coin, organizzato allo stesso modo. Abbiamo un nodo radice (principale), e tutti gli oggetti sullo schermo sono suoi figli.
FreeCAD dispone di un modo semplice per accedere al nodo radice (root) di una scena grafica in vista 3D:
sg = FreeCADGui.ActiveDocument.ActiveView.getSceneGraph() print sg
Ciò restituisce il nodo principale (root):
<pivy.coin.SoSelection; proxy of <Swig Object of type 'SoSelection *' at 0x360cb60> >
Siamo in grado di ispezionare i figli immediati della nostra scena:
for node in sg.getChildren(): print node
Alcuni di questi nodi, ad esempio SoSeparators o SoGroups, possono avere dei propri figli. L'elenco completo degli oggetti Coin disponibili si può trovare nella documentazione ufficiale di Coin.
Ora proviamo ad aggiungere qualcosa al nostro Scenegraph. Aggiungiamo un bel cubo rosso:
col = coin.SoBaseColor() col.rgb=(1,0,0) cub = coin.SoCube() myCustomNode = coin.SoSeparator() myCustomNode.addChild(col) myCustomNode.addChild(cub) sg.addChild(myCustomNode)
e questo è il nostro (bel) cubo rosso. Ora, proviamo questo:
col.rgb=(1,1,0)
Visto? Tutto è sempre accessibile e modificabile al volo. Non c'è bisogno di ricalcolare o ridisegnare nulla, Coin si prende cura di tutto. È possibile aggiungere elementi al grafo di scena, modificare le proprietà, nascondere delle cose, mostrare oggetti temporanei, qualsiasi cosa. Naturalmente, questo riguarda solo la visualizzazione nella vista 3D. Questa visualizzazione viene determinata da FreeCAD all'apertura del file attivo e quando un oggetto ha bisogno di essere ricalcolato. Quindi, se si modifica l'aspetto di un oggetto di FreeCAD esistente, tali modifiche andranno perse se l'oggetto viene ricalcolato o quando si riapre il file.
Per lavorare con i grafi di scena nei nostri script è fondamentale saper accedere a specifiche proprietà dei nodi aggiunti quando questo è necessario. Per esempio, se avessimo voluto spostare il nostro cubo, avremmo aggiunto un nodo SoTranslation al nostro nodo personalizzato, e lo script apparirebbe così:
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)
Ricordate che, in un Scenegraph di OpenInventor, l'ordine è importante. Un nodo riguarda ciò che viene dopo, quindi permette di definire qualcosa come: colore rosso, cubo, colore giallo, sfera, e di ottenere un cubo rosso e una sfera gialla. Se aggiungiamo ora la traslazione al nostro nodo personalizzato esistente, essa viene dopo il cubo, e non lo condiziona. Se lo avessimo inserito durante la creazione, come qui sopra, ora si potrebbe fare:
trans.translation.setValue([2,0,0])
E il nostro cubo si sposterebbe di 2 unità a destra.
Infine, la rimozione di qualcosa si fà con:
sg.removeChild(myCustomNode)
Un callback mechanism (meccanismo di richiamo) è un sistema che permette a una libreria che si sta utilizzando, come la nostra libreria Coin, di richiamare, cioè, di chiamare una determinata funzione dell'oggetto Python attualmente in esecuzione. Ciò è estremamente utile, perché in questo modo Coin può avvisarci se nella scena si verifica qualche evento specifico. Coin può controllare cose molto diverse, come la posizione del mouse, i clic di un pulsante del mouse, i tasti della tastiera che vengono premuti e tante altre cose.
FreeCAD fornisce un modo semplice per utilizzare tali callback:
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()
Il richiamo deve essere iniziato da un oggetto, perché questo oggetto deve essere ancora in esecuzione quando il callback si verifica. Vedere anche la lista completa degli eventi possibili e dei loro parametri, o la documentazione ufficiale di Coin.
Purtroppo, Pivy non ha ancora una propria documentazione adeguata, ma dato che è una traduzione esatta di Coin, si può tranquillamente utilizzare la documentazione di Coin come riferimento, e utilizzare lo stile Python al posto dello stile C++; ad esempio SoFile::getClassTypeId() in Pivy si scrive SoFile.getClassId().
PySide è il legame tra Python e la multi-piattaforma GUI degli strumenti di Qt. FreeCAD usa PySide all'interno di Python per tutti gli effetti GUI (Interfaccia grafica per l'utente). PySide è una alternativa al pacchetto PyQt che è stato utilizzato in precedenza da FreeCAD per la sua GUI. PySide ha una licenza più permissiva. Per maggiori informazioni sulla differenza vedere Differences Between PySide and PyQt.
Spesso gli utenti di FreeCAD accedono a tutto tramite l'interfaccia integrata. Per gli utenti che desiderano personalizzare le loro operazioni esiste l'interfaccia Python, che è documentata nel Tutorial degli script Python. L'interfaccia Python di FreeCAD è molto flessibile e potente. Questa pagina documenta l'interazione di Python con FreeCAD tramite PySide.
Python offre la dichiarazione 'print', data dal codice:
print 'Hello World'
Con l'istruzione print di Python si ha solo un limitato controllo dell'aspetto e del comportamento. PySide fornisce il controllo mancante e gestisce anche gli ambienti dove le funzionalità incorporate in Python non sono sufficienti, come ad esempio i file dell'ambiente macro di FreeCAD.
Le funzionalità di PySide vanno da:
a:
PySide è descritto nelle 3 pagine seguenti che dovrebbero essere lette nell'ordine:
Esse suddividono l'argomento in 3 parti, e si differenziano per livello di esposizione per PySide, Python e le parti incorporate in FreeCAD. La prima pagina contiene una panoramica e le basi della materia, fornisce una descrizione di PySide e di come è organizzato, mentre la seconda e la terza pagina contengono soprattutto degli esempi di codice di diversi livelli.
Con le pagine allegate si intende fornire del semplice codice Python per eseguire PySide, in modo che l'utente possa facilmente copiarlo, incollarlo nel proprio lavoro, adattarlo se necessario, e risolvere i suoi problemi con FreeCAD. Sperando che non abbia bisogno di andare alla ricerca di risposte alle domande su PySide attraverso internet. Allo stesso tempo, queste pagine non vogliono sostituirsi ai vari tutorial completi e ai siti di riferimento a PySide presenti nel web.
Oltre ai tipi di oggetti standard, come le Annotazioni, gli oggetti Mesh e gli oggetti Parte, FreeCAD offre anche la straordinaria possibilità di costruire al 100% oggetti in script di Python, chiamati Python Feature (Caratteristiche Python). Questi oggetti si comportano esattamente come un qualsiasi altro oggetto di FreeCAD, e sono salvati e ripristinati automaticamente con salva/apri il file.
Deve essere conosciuta una loro particolarità: questi oggetti vengono salvati in un file FcStd di FreeCAD con il modulo json di Python. Tale modulo converte un oggetto Python in una stringa, permettendo di aggiungerlo al file salvato. Quando l'oggetto viene caricato, il modulo json utilizza questa stringa per ricreare l'oggetto originale, fornendo l'accesso al codice sorgente da cui ha creato l'oggetto. Questo significa che se si salva un oggetto personalizzato e lo si apre su una macchina in cui non è presente il codice Python che ha generato l'oggetto, l'oggetto non può essere ricreato. Quando si forniscono ad altri utenti questi oggetti, è necessario fornire anche gli script di Python che li hanno creati.
Le Python Features seguono le stesse regole di tutte le altre funzionalità di FreeCAD: sono divise in una parte App e una parte GUI. La parte App, cioè il Document Object (oggetto del documento), definisce la geometria dell'oggetto, mentre la sua parte grafica, cioè il View Provider Object (fornitore della vista dell'oggetto), definisce come l'oggetto viene disegnato sullo schermo. Il View Provider Object, come qualsiasi altro elemento di FreeCAD, è disponibile solo quando si esegue FreeCAD nella sua GUI (interfaccia grafica). Per costruire il proprio oggetto, sono disponibili diversi metodi e proprietà. La Proprietà deve essere una qualsiasi dei tipi di proprietà predefinite che FreeCAD mette a disposizione. Le proprietà disponibili sono quelle che appaiono nella finestra di visualizzazione delle proprietà per consentire all'utente di modificarle. Con questa procedura, gli oggetti FeaturePython sono realmente e totalmente parametrici. E' possibile definire separatamente le proprietà per l'oggetto e per la sua ViewObject (rappresentazione).
Nota. In versioni precedenti abbiamo usato il modulo cPickle di Python. Questo modulo, però, esegue un codice arbitrario e provoca quindi un problema di sicurezza. Per questo motivo ora utilizziamo il modulo json di Python.
L'esempio seguente si trova nel file src/Mod/TemplatePyMod/FeaturePython.py, con molti altri esempi:
'''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()
Le proprietà sono i veri e propri mattoni per la costruzione degli oggetti FeaturePython. Attraverso di esse, l'utente è in grado di interagire e modificare l'oggetto. Dopo aver creato un nuovo oggetto FeaturePython nel documento ( obj=FreeCAD.ActiveDocument.addObject("App::FeaturePython","Box") ), è possibile ottenere un elenco delle proprietà disponibili digitando:
obj.supportedProperties()
Si ottiene l'elenco delle proprietà disponibili:
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
Quando si aggiungono delle proprietà agli oggetti personalizzati, stare attenti a questo:
Di default, le proprietà possono essere aggiornate. È possibile creare delle proprietà di sola lettura, per esempio nel caso si vuole mostrare il risultato di un metodo. È anche possibile nascondere una proprietà. Il tipo di proprietà può essere impostata usando
obj.setEditorMode("MyPropertyName", mode)
dove mode è un indice che può essere impostato:
0 -- default mode, lettura e scrittura 1 -- solo lettura 2 -- nascosto
Gli EditorModes non sono fissati nel file reload di FreeCAD. Questo può essere fatto dalla funzione __setstate__ . Vedere http://forum.freecadweb.org/viewtopic.php?f=18&t=13460&start=10#p108072. Usando setEditorMode le proprietà sono in sola lettura soltanto in PropertyEditor. Esse possono ancora essere modificate da un comando Python. Per renderle davvero in sola lettura le impostazioni devono essere passate direttamente all'interno della funzione addProperty. Per un esempio, vedere http://forum.freecadweb.org/viewtopic.php?f=18&t=13460&start=20#p109709.
In questo esempio si utilizza il Modulo Parte per creare un ottaedro, quindi si crea la sua rappresentazione Coin con Pivy.
Prima si crea l'oggetto del documento:
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
In seguito si crea il fornitore della vista dell'oggetto (view provider object), responsabile di mostrare l'oggetto nella scena 3D:
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
Infine, dopo che l'oggetto e il suo visualizzatore sono definiti, basta solo chiamarli (La classe Octahedron e il codice della classe viewprovider possono essere copiati direttamente nella console Python di FreeCAD)::
FreeCAD.newDocument() a=FreeCAD.ActiveDocument.addObject("App::FeaturePython","Octahedron") Octahedron(a) ViewProviderOctahedron(a.ViewObject)
Se volete rendere il vostro oggetto selezionabile, o almeno una parte di esso, facendo clic su di esso nella finestra, è necessario includere la sua geometria Coin all'interno di un nodo SoFCSelection. Se l'oggetto ha una rappresentazione complessa, con widget, annotazioni, etc, si potrebbe voler includere solo una parte di esso in un SoFCSelection. Tutto quello che compone un SoFCSelection viene costantemente analizzato da FreeCAD per rilevare selezioni/preselezioni, quindi non ha senso sovraccaricarlo con delle scansioni non necessarie. Ecco ciò che si dovrebbe fare per includere un self.face nell'esempio precedente:
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)
Praticamente, si crea un nodo SoFCSelection, quindi si aggiungono ad esso i nodi della geometria, e poi lo si aggiunge al nodo principale, invece di aggiungere direttamente i nodi geometria.
Se l'oggetto parametrico produce semplicemente una forma, non è necessario utilizzare un fornitore di vista dell'oggetto (view provider object). La forma viene visualizzata utilizzando la rappresentazione della forma standard di FreeCAD:
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()
Lo stesso codice con l'uso di 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()
Ci sono alcune discussioni nel forum molto interessanti su script di oggetti:
- http://forum.freecadweb.org/viewtopic.php?f=22&t=13740
- http://forum.freecadweb.org/viewtopic.php?t=12139
- https://forum.freecadweb.org/viewtopic.php?f=18&t=13460&start=20#p109709
- https://forum.freecadweb.org/viewtopic.php?f=22&t=21330
Oltre agli esempi presentati qui dare un'occhiata al codice sorgente di FreeCAD src/Mod/TemplatePyMod/FeaturePython.py per ulteriori esempi.
FreeCAD ha la sorprendente capacità di essere importabile come modulo Python in altri programmi o in una console autonoma di Python, insieme con tutti i suoi moduli e componenti. E' anche possibile importare la GUI di FreeCAD come modulo Python, anche se con alcune restrizioni. Però con alcune restrizioni.
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|FreeCAD library not found. Please check the FREECADPATH variable in the import script is correct')
else:
scene = Blender.Scene.GetCurrent()
import Part
doc = FreeCAD.open(filename)
objects = doc.Objects
for ob in objects:
if ob.Type[:4] == 'Part':
shape = ob.Shape
if shape.Faces:
mesh = Blender.Mesh.New()
rawdata = shape.tessellate(1)
for v in rawdata[0]:
mesh.verts.append((v.x,v.y,v.z))
for f in rawdata[1]:
mesh.faces.append.append(f)
scene.objects.new(mesh,ob.Name)
Blender.Redraw()
def main():
Blender.Window.FileSelector(import_fcstd, 'IMPORT FCSTD',
Blender.sys.makename(ext='.fcstd'))
# This lets you import the script without running it
if __name__=='__main__':
main()
Quando siamo sicuri che la libreria viene caricata (la sequenza try/except), possiamo lavorare con FreeCAD, allo stesso modo come faremmo all'interno dell'interprete Python di FreeCAD. Apriamo il documento FreeCAD che è passato a noi dalla funzione main(), e facciamo una lista dei suoi oggetti. Poi, siccome abbiamo deciso di preoccuparci solo della geometria del pezzo, controlliamo se la proprietà Type di ogni oggetto contiene "Parte", e dopo la tasselliamo.
Il tassellamento produce una lista di vertici e un elenco di facce definite dai vertici indicizzati. Questo è perfetto, poiché è esattamente lo stesso modo in cui Blender definisce i Mesh. Quindi, il nostro compito è ridicolmente semplice, basta aggiungere il contenuto di entrambi gli elenchi ai vertici e alle facce di una mesh di Blender. Quando tutto è fatto, basta ridisegnare lo schermo, e questo è tutto!
Ovviamente questo script è molto semplice (in realtà ne ho fatto uno più avanzato qui), è probabile che si voglia estenderlo, per esempio per importare anche oggetti mesh, o importare la geometria di una parte che non ha facce, o importare altri formati di file che FreeCAD è in grado di leggere. Si potrebbe anche voler esportare la geometria in un documento di FreeCAD, cosa che può essere fatto allo stesso modo. Si potrebbe anche voler costruire un dialogo per permettere all'utente di scegliere cosa importare, ecc.. La bellezza di tutto questo risiede proprio nel fatto che lasciate lavorare FreeCAD in ombra, mentre i suoi risultati sono presentati nel programma di vostra scelta.
Dalla versione 4.2, Qt ha la capacità affascinante di incorporare i plug-in della GUI dipendenti da Qt in applicazioni ospite (host) non-Qt e condividere il ciclo di eventi dell'ospite.
In particolare, per FreeCAD questo significa che esso può essere importato (incorporato) all'interno di un'altra applicazione con tutta la sua interfaccia utente dentro un'altra applicazione ospite la quale ha, a questo punto, il pieno controllo di FreeCAD.
L'intero codice python per ottenere questo ha solo due linee:
import FreeCADGui
FreeCADGui.showMainWindow()
Se l'applicazione ospite è basata su Qt, allora questa soluzione dovrebbe funzionare su tutte le piattaforme che supportano Qt. Tuttavia, l'ospite deve basarsi sulla stessa versione Qt di FreeCAD perché altrimenti si potrebbe incorrere in errori di esecuzione inaspettati.
Per le applicazioni non-Qt, tuttavia, ci sono alcune limitazioni di cui è necessario essere a conoscenza. Questa soluzione probabilmente non funziona con tutti gli altri toolkit. Per Windows funziona fintanto che l'applicazione ospite è basata direttamente su Win32 o su qualsiasi altro toolkit che utilizza internamente l'API Win32, come wxWidgets, MFC o WinForms. Al fine di farla funzionare sotto X11 l'applicazione ospite deve linkare la libreria "glib".
Notare che, questa soluzione, naturalmente, non funziona per nessuna applicazione da console perché non c'è nessun ciclo di eventi in esecuzione.
Anche se è possibile importare FreeCAD con un interprete Python esterno, questo non è uno scenario di utilizzo comune e richiede una certa cura. In generale, è meglio usare il Python incluso con FreeCAD, eseguire FreeCAD da linea di comando, o come un sottoprocesso. Vedere Avvio e configurazione per maggiori informazioni sulle ultime due opzioni.
Dato che il modulo Python di FreeCAD viene compilato da C ++ (invece di essere un puro modulo Python), esso può essere importato solo da un interprete Python compatibile. Generalmente questo significa che l'interprete Python deve essere compilato con lo stesso compilatore C che è stato utilizzato per costruire FreeCAD. Le informazioni sul compilatore utilizzato per costruire un interprete Python (compreso quello costruito con FreeCAD) si possono trovare nel seguente modo:
>>> 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)]'
|
Argomento |
---|
Python |
Livello di difficoltà |
Base |
Tempo di esecuzione |
Autore |
Versione di FreeCAD |
File di esempio |
Questa pagina contiene degli esempi di codice Python utilizzabili in FreeCAD, raccolti dalle esperienze degli utenti e dalle discussioni nel forum. Dopo averli letti, è possibile usarli per iniziare a creare degli script personali ...
Ogni modulo deve contenere, oltre al file del modulo principale, un file InitGui.py che ha il compito di inserire il modulo nella finestra grafica principale (GUI).
Questo è un esempio semplice di un file InitGui.py:
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())
Il seguente è un esempio di un file del modulo principale. Esso contiene tutto ciò che il modulo deve seguire. È il file Scripts.py richiamato dall'esempio precedente. In esso è possibile inserire tutti i comandi personalizzati.
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())
In FreeCAD, è facile creare un importatore per un nuovo tipo di file. FreeCAD non considera che si importano dati in un documento aperto, ma piuttosto che si può semplicemente aprire direttamente il nuovo tipo di file. Quindi, quello che si deve fare è aggiungere la nuova estensione di file alla lista delle estensioni conosciute di FreeCAD, scrivere il codice che legge il file e creare gli oggetti di FreeCAD che si desidera:
Per aggiungere la nuova estensione di file all'elenco si deve aggiungere questa riga al file InitGui.py :
# 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")
Poi nel file 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()
L'esportazione di un proprio documento in un nuovo tipo di file funziona allo stesso modo, ma si utilizza:
FreeCAD.addExportType("Your new File Type (*.ext)","Export_Ext")
Una linea ha semplicemente 2 punti.
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()
Un poligono è semplicemente un insieme di segmenti di linea collegati tra di loro (una polilinea in AutoCAD). Non è necessario che sia chiuso.
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()
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
Nota: È anche possibile annidare dei gruppi in altri gruppi e creare dei sottogruppi...
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
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()
A ogni oggetto di un documento di FreeCAD è associato un oggetto di rappresentazione della sua vista in cui sono memorizzati tutti i parametri che definiscono il modo in cui l'oggetto deve apparire, come il colore, la larghezza di linea, ecc ..
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
La struttura di Inventor permette di aggiungere uno o più nodi di richiamo (callback) al grafo di scena (Scenegraph) della vista. In FreeCAD è installato di default un nodo callback per la vista che permette di aggiungere funzioni C++ globali o statiche. In appropriate associazioni Python vengono forniti alcuni metodi per utilizzare questa tecnica all'interno del codice Python.
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)
Ora, cliccate in qualche parte nella zona nella vista 3D e osservate i messaggi nella finestra di output. Per terminare l'osservazione basta chiamare:
v.removeEventCallback("SoMouseButtonEvent",c)
Sono supportati i seguenti tipi di eventi:
La funzione di Python che può essere registrata con addEventCallback() si aspetta una difinizione. Secondo l'evento controllato la definizione può contenere chiavi differenti.
Per tutti gli eventi esistono le seguenti chiavi:
Per tutti gli eventi dei pulsanti, ad esempio eventi di tastiera, mouse o spaceball:
Per gli eventi da tastiera:
Per gli eventi del pulsante del mouse
Per gli eventi di Spaceball:
E infine eventi di movimento:
Questa macro visualizza nel report i tasti premuti e tutti gli eventi dei comandi
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
È anche possibile ottenere il Scenegraph (grafo della scena) in Python e modificarlo, con il modulo 'Pivy '- una associazione di Python per 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()
L'API in Python di Pivy viene creato utilizzando lo strumento SWIG. In FreeCAD si usano alcuni nodi auto-scritti che non è possibile creare direttamente in Python. Tuttavia, è possibile creare un nodo dal suo nome interno. Si può creare una istanza di tipo 'SoFCSelection' con:
type = SoType.fromName("SoFCSelection") node = type.createInstance()
Questo è un modo per aggiungere dei nuovi nodi al Scenegraph. Accertarsi di aggiungere sempre un SoSeparator per contenere la geometria, le coordinate e le informazioni sui materiale di uno stesso oggetto. L'esempio seguente aggiunge una linea rossa da (0,0,0) a (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)
Per rimuoverla, è sufficiente scrivere:
sg.removeChild(no)
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)
È possibile creare widget personalizzati con Qt designer, trasformarli in uno script Python e poi caricarli nell'interfaccia di FreeCAD con PySide.
Il codice Python prodotto dal compilatore Ui di Python (lo strumento che converte i file .ui di Qt-designer nel codice Python) appare in genere come questo (è semplice, si può anche codificare direttamente in 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))
Dopo, basta creare un riferimento alla finestra Qt di FreeCAD, inserire un widget personalizzato in essa, e "trasformare" questo widget nel proprio con il codice Ui che abbiamo appena creato:
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
Il seguente codice consente di aggiungere una nuova scheda nel pannello ComboView (vista combinata) di FreeCAD, oltre le schede standard "Progetto" e "Attività" . Questo codice utilizza anche il modulo UIC per caricare un file ui direttamente nella nuova scheda.
# 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)
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
import WebGui WebGui.openBrowser("http://www.example.com")
from PyQt4 import QtGui,QtWebKit a = QtGui.qApp mw = a.activeWindow() v = mw.findChild(QtWebKit.QWebFrame) html = unicode(v.toHtml()) print html
# -*- 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")
# -*- 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
for edge in FreeCAD.ActiveDocument.MyObjectName.Shape.Edges: # replace "MyObjectName" for list
print edge.Length
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)
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)
Questa funzione elenca i componenti ed estrae le coordinate XYZ di un oggetto, i bordi (edge) e le loro lunghezze, le sue facce e la loro superficie.
# -*- 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()
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")
import Draft obj = FreeCADGui.Selection.getSelection()[0] obj.addProperty("App::PropertyString","GComment","Draft","Font name").GComment = "Comment here" App.activeDocument().recompute()
Esempi di ricerca e decodifica di informazioni su un oggetto.
Ogni sezione separata da "############" è indipendente e può essere copiata direttamente nella console Python, o in una macro o usata come macro a sè stante. La descrizione della macro si trova nel commento.
Le informazioni ricercate in questo modo sono visualizzate nella finestra dei rapporti attivabile con Visualizza -> Viste -> Report
# -*- 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 ################################################################################## 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") 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") 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") ################################################################################## sel = FreeCADGui.Selection.getSelection() # select object with getSelection() boundBox_= sel[0].Shape.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() Yaw = sel[0].Shape.Placement.Rotation.toEuler()[0] # decode angle Euler Yaw App.Console.PrintMessage("Yaw : "+str(Yaw)+"\n") Pitch = sel[0].Shape.Placement.Rotation.toEuler()[1] # decode angle Euler Pitch App.Console.PrintMessage("Pitch : "+str(Pitch)+"\n") Roll = sel[0].Shape.Placement.Rotation.toEuler()[2] # decode angle Euler Yaw App.Console.PrintMessage("Roll : "+str(Roll)+"\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 0 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") ##################################################################################
# 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") ##################################################################################
Note: Di solito gli angoli sono espressi in radianti da convertire con:
Questo codice visualizza le coordinate cartesiane dell'elemento selezionato.
Modificare il valore di "numberOfPoints" se si desidera un diverso numero di punti (modificare la precisione)
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
Altro metodo per visualizzare "Int" e "Float" (interi e valori in virgola mobile)
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"
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
# 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 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
stesso codice semplificato
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)
Questo esempio mostra come trovare vettore normale alla superficie trovando prima i parametri u, v di un punto sulla superficie e utilizzando poi i parametri u, v per trovare il vettore normale
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)
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]
Questa pagina mostra come si possono facilmente costruire delle funzionalità avanzate con Python.
In questo esercizio, costruiremo un nuovo strumento che disegna una linea partendo da due punti cliccati nella vista 3D.
Questo strumento può essere collegato a un comando di FreeCAD, e tale comando può essere chiamato da un qualsiasi elemento dell'interfaccia, ad esempio da una voce di menu o da un pulsante in una barra degli strumenti.
Per prima cosa scriviamo uno script che contenga tutta la nostra funzionalità.
Dopo, salviamo questo script in un file e lo importiamo in FreeCAD, in modo che tutte le classi e le funzioni che scriviamo diventino disponibili in FreeCAD.
Lanciamo perciò il nostro editor di testo preferito, e digitiamo le seguenti righe:
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)
import Part, FreeCADGui from pivy.coin import *
In Python, quando si desidera utilizzare le funzioni di un altro modulo è necessario importarlo.
Nel nostro caso, abbiamo bisogno delle funzioni del Modulo Parte per creare la linea, e del modulo Gui (FreeCADGui) per accedere alla visualizzazione 3D.
Inoltre, abbiamo anche bisogno del contenuto completo della libreria di Coin, in modo da poter utilizzare direttamente tutti gli oggetti Coin, come, ad esempio, SoMouseButtonEvent, ecc ..
class line:
Qui definiamo la nostra classe principale.
Perché utilizzare una classe e non una funzione? Il motivo è che abbiamo bisogno che il nostro strumento rimanga "vivo" mentre aspettiamo che l'utente clicchi sullo schermo.
Una funzione termina quando il suo compito è stato svolto, invece un oggetto (una classe definisce un oggetto) rimane attivo finché non viene distrutto.
"this class will create a line after the user clicked 2 points on the screen"
In Python, ogni classe o funzione può avere una stringa di descrizione.
In FreeCAD, questo è particolarmente utile perché quando chiameremo la classe nell'interprete, la stringa di descrizione verrà visualizzata come tooltip (nota di descrizione o aiuto).
def __init__(self):
Le classi di Python possono sempre contenere una funzione __init__, che viene eseguita quando la classe viene chiamata per creare un oggetto. Quindi, metteremo qui tutto quello che vogliamo che accada quando il nostro strumento line (linea) inizia.
self.view = FreeCADGui.ActiveDocument.ActiveView
In una classe, di solito si aggiunge self. prima di un nome di variabile, in modo che sia facilmente accessibile a tutte le funzioni dentro e fuori questa classe. In questo script, usiamo self.view per accedere e manipolare la vista 3D attiva.
self.stack = []
Qui creiamo una lista vuota per archiviare i punti 3D inviati dalla funzione getpoint.
self.callback = self.view.addEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(),self.getpoint)
Questa è la parte importante.
Dato che in realtà si tratta una scena Coin3d, FreeCAD utilizza il meccanismo di callback (richiamo) di Coin, il quale permette di chiamare una funzione ogni volta che nella scena accade un determinato evento.
Nel nostro caso, stiamo creando un callback per gli eventi SoMouseButtonEvent e li colleghiamo alla funzione getpoint. Adesso, ogni volta che un pulsante del mouse viene premuto o rilasciato, viene eseguita la funzione getpoint.
Notare che alla addEventCallbackPivy() esiste anche un'alternativa, chiamata addEventCallback() la quale dispensa dall'uso di pivy. Ma, dal momento che pivy è un modo molto efficace e naturale per accedere a ogni parte di una scena di Coin, è meglio utilizzarlo il più possibile!
def getpoint(self,event_cb):
Ora definiamo la funzione getpoint, che sarà eseguita quando un pulsante del mouse verrà premuto in una vista 3D. Questa funzione riceverà un argomento, che chiamiamo event_cb.
Da questo evento callback possiamo accedere all'oggetto event, che contiene diverse parti di informazioni
Per maggiori informazioni sugli eventi controllabili consultate questa pagina.
if event.getState() == SoMouseButtonEvent.DOWN:
La funzione getpoint viene chiamata ogni volta che un pulsante del mouse viene premuto o rilasciato. Invece, noi vogliamo definire un punto 3D solo quando viene premuto (altrimenti otteniamo due punti 3D molto vicini l'uno all'altro). Pertanto quì dobbiamo verificare e stabilire questo.
pos = event.getPosition()
Qui otteniamo le coordinate dello schermo nella posizione del cursore del mouse
point = self.view.getPoint(pos[0],pos[1])
Questa funzione ci fornisce un vettore di FreeCAD (x, y, z) contenente il punto 3D che giace sul piano focale, esattamente sotto il cursore del mouse. Se siamo in vista camera, immaginiamo un raggio proveniente dalla fotocamera, passante per il cursore del mouse, che colpisce il piano focale. Questo è il nostro punto 3D. Se siamo in vista ortogonale, il raggio è parallelo alla direzione di visualizzazione.
self.stack.append(point)
Aggiungiamo il nostro nuovo punto nella pila (stack)
if len(self.stack) == 2:
Abbiamo già abbastanza punti? Se sì, allora disegnamo la linea!
l = Part.Line(self.stack[0],self.stack[1])
Qui usiamo la funzione Line() del Modulo Parte che crea una linea da due vettori di FreeCAD.
Tutto quanto che si crea e si modifica all'interno del modulo Parte, rimane nel modulo Parte. Quindi, fino ad ora, abbiamo creato una linea Parte. Essa non è legata ad alcun oggetto del nostro documento attivo, perciò sullo schermo non viene ancora visualizzato nulla.
shape = l.toShape()
Il documento di FreeCAD può accettare solo shape (forme) dal modulo Parte. Le shape sono il tipo più generico di forme del modulo Part. Dobbiamo quindi convertire la nostra linea in una shape prima di poterla aggiunge al documento.
Part.show(shape)
Il modulo Parte ha una funzione molto utile, show(), che crea un nuovo oggetto nel documento e collega ad esso una shape (forma).
Possiamo anche creare prima un nuovo oggetto nel documento, poi associare manualmente ad esso la shape.
self.view.removeEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(),self.callback)
Siccome con la nostra linea abbiamo finito, terminiamo il meccanismo di callback, che consuma preziosi cicli di CPU.
Ora, salviamo il nostro script in qualche posizione in cui l'interprete Python di FreeCAD possa trovarlo.
Durante l'importazione dei moduli, l'interprete punta nei seguenti luoghi: i percorsi di installazione di Python, la directory bin di FreeCAD, e tutte le directory dei moduli FreeCAD. Quindi, la soluzione migliore è quella di creare una nuova directory in una delle FreeCAD Mod directories, e salvare in essa il nostro script. Per esempio, creiamo una directory "MyScripts", e salviamo il nostro script come "exercise.py".
Adesso che tutto è pronto, basta avviare FreeCAD, creare un nuovo documento, e, nell'interprete Python, eseguire:
import exercise
Se non viene visualizzato nessun messaggio di errore, significa che il nostro script "exercise" è stato caricato.
Ora possiamo controllare il suo contenuto con:
dir(exercise)
Il comando dir() è un comando integrato di Python che elenca il contenuto di un modulo. Possiamo vedere che la nostra classe line() è lì, in attesa.
Non rimane che provarla scrivendo:
exercise.line()
Poi, clicchiamo due volte nella vista 3D, e bingo, ecco la nostra linea! Per farne una nuova, basta riscrivere ancora exercise.line(), e ancora, e ancora ... Siete contenti, no?
Per essere davvero efficace il nostro nuovo strumento linea (line) dovrebbe avere un suo pulsante sull'interfaccia, in modo da non dover digitare ogni volta tutte queste cose.
Il modo più semplice è quello di trasformare la nostra nuova directory MyScripts in un ambiente di lavoro completo di FreeCAD.
È facile. Basta solo inserire un file chiamato InitGui.py nella directory MyScripts. Il file InitGui.py conterrà le istruzioni per creare un nuovo ambiente di lavoro (workbench), poi aggiungere ad esso il nostro nuovo strumento.
Oltre a questo dobbiamo anche modificare un po' il nostro codice di exercise, in modo che lo strumento line() sia riconosciuto come un comando ufficiale di FreeCAD.
Cominciamo creando un file InitGui.py, e scriviamo in esso il seguente codice:
class MyWorkbench (Workbench): MenuText = "MyScripts" def Initialize(self): import exercise commandslist = ["line"] self.appendToolbar("My Scripts",commandslist) Gui.addWorkbench(MyWorkbench())
A questo punto, penso che dovreste già capire da soli lo script precedente.
Creiamo una nuova classe che chiamiamo MyWorkbench, le diamo un titolo (MenuText), e definiamo una funzione Initialize() che verrà eseguita quando l'ambiente di lavoro verrà caricato in FreeCAD. In tale funzione, si carica il contenuto del nostro file exercise, e si aggiungono i comandi di FreeCAD contenuti in una lista di comandi.
Dopo, costruiamo una barra degli strumenti denominata "My Scripts" a cui assegniamo la nostra lista comandi. Al momento, ovviamente, disponiamo di un solo strumento, quindi la nostra lista dei comandi contiene un solo elemento.
Quando il nostro ambiente di lavoro è pronto, lo aggiungiamo all'interfaccia principale.
Questo non basta ancora perché un comando di FreeCAD deve essere formattato in un certo modo per poter funzionare. Quindi è necessario modificare un po' il nostro strumento line().
Ora il nostro nuovo script exercise.py deve essere come questo:
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())
Quì abbiamo trasformato la nostra funzione __init__() in una funzione Activated(), perchè, quando i comandi di FreeCAD vengono eseguiti, essi eseguono automaticamente la funzione Activated().
Inoltre, abbiamo aggiunto una funzione GetResources(), che fornisce a FreeCAD le informazioni per trovare l'icona dello strumento, il nome e la descrizione (tooltip) del nostro strumento.
Qualunque immagine jpg, png o svg può fungere da icona, essa può essere di qualsiasi dimensione, ma è meglio usare una dimensione vicina all'aspetto finale, come, ad esempio, 16x16, 24x24 o 32x32.
Poi, abbiamo aggiunto la classe line() come un comando ufficiale di FreeCAD con il metodo AddCommand().
Questo è tutto, ora basta riavviare FreeCAD e avremo un bell'ambiente di lavoro con il nostro nuovo strumento line()!
Se questo esercizio vi è piaciuto, perché non cercare di migliorare questo piccolo strumento? Si possono fare molte cose, come ad esempio:
Non esitate a scrivere le vostre domande o idee nel forum!
In questa pagina vi mostreremo come creare una semplice finestra di dialogo di Qt con Qt Designer, lo strumento ufficiale di Qt per la progettazione di interfacce, quindi come convertirla in codice Python e poi utilizzarla all'interno di FreeCAD.
Nell'esempio si assume che sappiate già come modificare ed eseguire gli script di Python, e sappiate anche fare delle cose semplici in una finestra di terminale, come navigare, ecc.
Naturalmente, è necessario che PyQt sia installato.
Nelle applicazioni CAD, il disegno di una buona UI (interfaccia utente) è molto importante. L'utente esegue quasi tutte le operazioni tramite qualche componente dell'interfaccia: legge le finestre di dialogo, preme i pulsanti, sceglie tra le icone, ecc. Quindi è molto importante pensare attentamente a ciò che si intende fare, a come si desidera che l'utente si comporti, e a quale sarà il flusso di lavoro delle proprie azioni.
Quando si progetta l'interfaccia, è bene tenere presenti alcune cose:
Ora che abbiamo definito con precisione quello che faremo, è il momento di aprire Qt Designer.
Disegneremo una finestra di dialogo molto semplice, simile a questa:
Dopo utilizzeremo questa finestra di dialogo all'interno di FreeCAD per produrre un bel piano rettangolare. Forse pensate che produrre dei bei piani rettangolari non è particolarmente utile, però, in un secondo tempo, sarà facile apportarvi delle modifiche e creare delle cose più complesse.
Quando viene aperto, Qt Designer ha questo aspetto:
È molto semplice da utilizzare.
Sulla barra di sinistra ci sono gli elementi che possono essere trascinati nel proprio widget (componente aggiuntivo).
Sul lato destro sono disposti i pannelli delle proprietà che mostrano tutti i tipi di proprietà modificabili degli elementi selezionati.
Per iniziare, creare un nuovo widget o complemento. Selezionare "Dialog without buttons", in quanto non vogliamo i pulsanti Ok e Annulla predefiniti. Quindi, trascinare nel proprio widget 3 labels (etichette), una per il titolo, una per inserire il testo "Altezza" e un'altra per inserire il testo "Larghezza". Le etichette sono semplici testi che appaiono nel widget, al solo scopo di informare l'utente. Quando si seleziona un'etichetta, sul lato destro appaiono diverse proprietà che volendo si possono modificare, come, ad esempio, lo stile del carattere, la sua altezza, ecc.
Poi, aggiungere 2 LineEdits, che sono campi di testo che l'utente può riempire, uno per l'altezza e uno per la larghezza. Anche di questi oggetti si possono modificare le proprietà. Ad esempio, perché non impostare un valore predefinito? Per esempio digitiamo 1,00 per ciascuno. In questo modo, quando l'utente vedrà la finestra di dialogo, entrambi i valori saranno già compilati e se gli vanno bene può premere direttamente il tasto, risparmiando tempo prezioso. Dopo, aggiungere un PushButton, che è il tasto che l'utente dovrà premere dopo aver compilato i 2 campi.
Notare che qui che ho scelto dei comandi molto semplici, ma Qt dispone di molte altre opzioni, ad esempio, è possibile utilizzare Spinboxes invece di LineEdits, ecc .. Date un'occhiata a ciò che è disponibile, vi verranno sicuramente altre idee.
Questo è tutto quello che si deve fare in Qt Designer.
Un'ultima cosa, però, rinominare tutti i propri elementi con nomi più adeguati, così negli script sarà più facile identificarli:
Ora, salviamo il nostro widget da qualche parte. Esso verrà salvato come un file .ui, che potremo facilmente convertire in script di Python tramite pyuic. Su Windows, il programma pyuic è incluso con PyQt (da verificare), su Linux probabilmente è necessario installarlo separatamente tramite il proprio gestore di pacchetti (su sistemi debian-based è parte del pacchetto di strumenti PyQt4-dev-tools). Per fare la conversione, è necessario aprire una finestra di terminale (o una finestra del prompt dei comandi in Windows), portarsi nella cartella in cui si è salvato il file .ui, e digitare:
pyuic mywidget.ui > mywidget.py
In Windows pyuic.py si trova in "C:\Python27\Lib\site-packages\PyQt4\uic\pyuic.py" Per creare il file batch "compQt4.bat:
@"C:\Python27\python" "C:\Python27\Lib\site-packages\PyQt4\uic\pyuic.py" -x %1.ui > %1.py
Nella console Dos digitare senza estensione
compQt4 myUiFile
In Linux : da fare
Dato che, dopo la versione 0.13, FreeCAD si è progressivamente allontanato da PyQt a favore di PySide (Choice your PySide install building PySide), per costruire il file basato su PySide ora è necessario utilizzare:
pyside-uic mywidget.ui -o mywidget.py
In Windows uic.py si trova in "C:\Python27\Lib\site-packages\PySide\scripts\uic.py" Per creare il file batch "compSide.bat":
@"C:\Python27\python" "C:\Python27\Lib\site-packages\PySide\scripts\uic.py" %1.ui > %1.py
Nella console Dos digitare senza estensione
compSide myUiFile
In Linux : da fare
Su alcuni sistemi il programma si chiama pyuic4 invece di pyuic. Questa operazione converte semplicemente il file .ui in uno script Python. Se apriamo il file mywidget.py, è molto facile capire il suo contenuto:
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))
...
Come potete vedere ha una struttura molto semplice: viene creata una classe denominata Ui_Dialog, che memorizza gli elementi dell'interfaccia del nostro widget. Questa classe ha due metodi, uno per la creazione del widget, e uno per la traduzione del suo contenuto, questo fa parte del meccanismo generale di Qt per tradurre gli elementi dell'interfaccia. Il metodo di installazione crea semplicemente, uno per uno, i widget come li abbiamo definiti in Qt Designer, e imposta le loro opzioni come abbiamo deciso in precedenza. Poi, viene tradotta l'intera interfaccia e, infine, vengono collegati gli slot (di cui parleremo più avanti).
Ora possiamo creare un nuovo widget, e utilizzare questa classe per creare la sua interfaccia. A questo punto, possiamo già vedere in azione il nostro widget e, per provarlo, mettiamo il nostro file mywidget.py in un luogo dove FreeCAD possa trovarlo (nella directory bin di FreeCAD, o in una qualsiasi delle sottodirectory Mod), e, nell'interprete Python di FreeCAD, digitiamo:
from PySide import QtGui
import mywidget
d = QtGui.QWidget()
d.ui = mywidget.Ui_Dialog()
d.ui.setupUi(d)
d.show()
Ecco apparire la nostra finestra di dialogo! Notare che il nostro interprete Python sta ancora funzionando in quanto stiamo usando un dialogo non-modale. Per chiudere la finestra, (ovviamente, oltre a cliccare sulla sua icona di chiusura) possiamo digitare:
d.hide()
Ora che siamo in grado di mostrare e nascondere la nostra finestra di dialogo, basta solo aggiungere una ultima parte: per fargli fare qualcosa!
Provando per un po' Qt Designer, scoprirete presto un'intera sezione chiamata "signals and slots" (segnali e porte di ingresso dei segnali).
In pratica, funziona così: i componenti dei widget (nella terminologia Qt, questi elementi sono a loro volta dei widget) sono in grado di inviare dei segnali. Tali segnali differiscono a seconda del tipo widget. Ad esempio, un pulsante può inviare un segnale quando viene premuto e quando viene rilasciato. Questi segnali possono essere collegati agli slot. Gli slot possono essere una funzionalità speciale di altri widget (ad esempio una finestra di dialogo ha uno slot "close" al quale è possibile collegare il segnale di un pulsante di chiusura), o possono essere funzioni personalizzate.
La Documentazione di riferimento di PyQt elenca tutti i widget Qt, che cosa possono fare, quali segnali possono inviare, ecc..
Qui, come esempio, creiamo una nuova funzione che genera un piano basato su altezza e larghezza, e colleghiamo tale funzione al segnale "pressed" (premuto) emesso dal pulsante "Create!".
Allora, cominciamo con l'importazione dei nostri moduli FreeCAD, inserendo la seguente riga all'inizio dello script, dove importiamo già QtCore e QtGui:
import FreeCAD, Part
Dopo, aggiungiamo una nuova funzione alla nostra classe Ui_Dialog:
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()
Poi, bisogna dire a Qt di collegare il pulsante alla funzione, inserendo la seguente riga appena prima di QtCore.QMetaObject.connectSlotsByName (Dialog):
QtCore.QObject.connect(self.create,QtCore.SIGNAL("pressed()"),self.createPlane)
Questo, come vedete, collega il segnale "pressed()" del nostro oggetto create (il pulsante "Create!"), allo slot chiamato createPlane, che abbiamo appena definito. Questo è tutto!
Ora, come tocco finale, possiamo aggiungere una piccola funzione per creare il dialogo, così sarà più facile chiamarlo.
Fuori dalla classe Ui_Dialog, aggiungiamo questo codice:
class plane():
def __init__(self):
self.d = QtGui.QWidget()
self.ui = Ui_Dialog()
self.ui.setupUi(self.d)
self.d.show()
(Promemoria di Python: ogni volta che viene creato un nuovo oggetto il metodo __init__ di una classe viene eseguito automaticamente!)
Poi, da FreeCAD, basta solo fare:
import mywidget
myDialog = mywidget.plane()
Questo è tutto amici ... Ora è possibile provare diverse cose, come ad esempio inserire il widget nell'interfaccia di FreeCAD (vedere la pagina Esempi di codici), oppure creare strumenti personalizzati molto più avanzati, utilizzando altri elementi nel proprio widget.
Questo è lo script completo di riferimento:
# -*- 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()
Esempio di una finestra di dialogo completa con le sue connessioni.
# -*- 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()
Ecco la stessa finestra, ma con una icona per ogni pulsante.
Scaricare le icone associate (Clic destro "Salva immagine con nome")
# -*- 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()
Ecco il codice per visualizzare l'icona sul pushButton, cambiare il nome di un altro pulsante, (radioButton, checkBox) e il percorso per l'icona.
# 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
Il comando UserAppData dà il percorso dell'utente AppHomePath dà il percorso di installazione di FreeCAD
# path = FreeCAD.ConfigGet("UserAppData")
path = FreeCAD.ConfigGet("AppHomePath")
Questo comando inverte il pulsante orizzontale, da destra a sinistra.
self.pushButton.setLayoutDirection(QtCore.Qt.RightToLeft) # This command reverses the direction of the button
Un altro metodo per visualizzare una finestra. In questo caso creando un file QtForm.py che contiene il programma di intestazione (modulo chiamato con import QtForm), e un secondo modulo che contiene il codice della finestra di tutti questi accessori e il vostro codice (il modulo di chiamata).
Questo metodo richiede due file separati, ma permette di accorciare il programma utilizzando il file QtForm.py con import. Poi distribuire insieme i due file, essi sono inseparabili.
Il 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))
L'appellante, il file che contiene la finestra e il tuo codice
Il file my_file.py
I collegamenti sono da fare, sono un buon esercizio.
# -*- 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, "essai 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()
Altro esempio
Sono trattati:
La pagina del codice e delle icone: Qt_Example
Questo esempio crea oggetti con proprietà e icona personalizzate in ComboView
Scaricare l'icona di esempio e posizionarla nella stessa directory della macro
Vengono elaborati tre metodi per assegnare un'icona a un oggetto, un'icona in formato .png presente in un file sul disco, un'icona salvata in formato .xpm inclusa nella macro stessa e un'icona disponibile nelle risorse di FreeCAD.
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
Altro esempio completo di creazione di un cubo con l'icona nella macro
#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()
Codice completo:
# -*- 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)
Codice completo:
# -*- 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)
Codice completo:
# -*- 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
# 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))
Utilizzando i caratteri accentati, si ottiene l'errore :
Sono possibili diverse suluzioni
UnicodeDecodeError: 'utf8' codec can't decode bytes in position 0-2: invalid data
# 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')
o con la procedura
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")
o con la procedura
def iso8859(encoder):
return unicode(encoder).encode('iso-8859-1')
oppure
iso8859(unichr(176))
oppure
unichr(ord(176))
oppure
uniteSs = "mm"+iso8859(unichr(178))
print unicode(uniteSs, 'iso8859')
I know that the discussion on the "right" licence for open source occupied a significant portion of internet bandwidth and so is here the reason why, in my opinion, FreeCAD should have this one.
I chose the LGPL for the project and I know the pro and cons about the LGPL and will give you some reasons for that decision.
FreeCAD is a mixture of a library and an application, so the GPL would be a little bit strong for that. It would prevent writing commercial modules for FreeCAD because it would prevent linking with the FreeCAD base libs. You may ask why commercial modules at all? Therefore Linux is good example. Would Linux be so successful when the GNU C Library would be GPL and therefore prevent linking against non-GPL applications? And although I love the freedom of Linux, I also want to be able to use the very good NVIDIA 3D graphic driver. I understand and accept the reason NVIDIA does not wish to give away driver code. We all work for companies and need payment or at least food. So for me, a coexistence of open source and closed source software is not a bad thing, when it obeys the rules of the LGPL. I would like to see someone writing a Catia import/export processor for FreeCAD and distribute it for free or for some money. I don't like to force him to give away more than he wants to. That wouldn't be good neither for him nor for FreeCAD.
Nevertheless this decision is made only for the core system of FreeCAD. Every writer of an application module may make his own decision.
FreeCAD uses two different licenses, one for the application itself, and one for the documentation:
See FreeCAD's debian copyright file for more details about the licenses used by the different components found in FreeCAD
Private users can use FreeCAD free of charge and can do basically whatever they want to do with it: use it, copy it, modify it, redistribute it. They are always master of their data, they are not forced to update FreeCAD, change their usage of FreeCAD. Using FreeCAD doesn't bind them to any kind of contract or obligation.
Can use FreeCAD freely, for any kind of private or professional work. They can customize the application as they wish. They can write open or closed source extensions to FreeCAD. They are always master of their data, they are not forced to update FreeCAD, change their usage of FreeCAD. Using FreeCAD doesn't bind them to any kind of contract or obligation.
Can use FreeCAD as the groundwork for own extension modules for special purposes. They can choose either the GPL or the LGPL to allow the use of their work in proprietary software or not.
Commercial developers can use FreeCAD as the groundwork for their own extension modules for special purposes and are not forced to make their modules open source. They can use all modules which use the LGPL. They are allowed to distribute FreeCAD along with their proprietary software. They will get the support of the author(s) as long as it is not a one way street.
The following is no more applicable since version 0.14, since both FreeCAD and OpenCasCade are now fully LGPL.
Up to Version 0.13 FreeCAD is delivered as GPL2+, although the source itself is under LGPL2+. Thats because of linkage of Coin3D (GPL2) and PyQt(GPL). Starting with 0.14 we will be completely GPL free. PyQt will be replaced by PySide, and Coin3D was re-licensed under BSD. One problem, we still have to face, license-wise, the OCTPL (Open CASCADE Technology Public License). Its a License mostly LGPL similar, with certain changes. On of the originators, Roman Lygin, elaborated on the License on his Blog. The home-brew OCTPL license leads to all kind of side effects for FreeCAD, which where widely discussed on different forums and mailing lists, e.g. on OpenCasCade forum itself. I will link here some articles for the biggest problems.
We first discovered the problem by a discussion on the FSF high priority project discussion list. It was about a library we look at, which was licensed with GPL3. Since we linked back then with Coin3D, with GPL2 only, we was not able to adopt that lib. Also the OCTPL is considered GPL incompatible. This Libre Graphics World article "LibreDWG drama: the end or the new beginning?" shows up the drama of LibreDWG project not acceptably in FreeCAD or LibreCAD.
The incompatibility of the OCTPL was discussed on the debian legal list and lead to a bug report on the FreeCAD package which prevent (ignor-tag) the transition from debian-testing to the main distribution. But its also mentioned thats a FreeCAD, which is free of GPL code and libs, would be acceptably. With a re-licensed Coin3D V4 and a substituted PyQt we will hopefully reach GPL free with the 0.14 release.
In the Fedora project OpenCasCade is listed "non-free". This means basically it won't make it into Fedora or RedHat. This means also FreeCAD won't make it into Fedora/RedHat until OCC is changing its license. Here the links to the license evaluation:
The main problem they have AFIK is that the OCC license demand non discriminatory support fees if you want to do paid support. It has nothing to do with "free" or OpenSource, its all about RedHat's business model!
L'indirizzo del nostro bug tracker è:
https://www.freecadweb.org/tracker
Potete segnalare i bug, presentare le richieste di funzionalità, patch, o richiedere di fondere un proprio ramo, se avete sviluppato qualcosa usando git. Il tracker è suddiviso in moduli, quindi cercate di essere specifici e di presentare la richiesta nella sottosezione appropriata. In caso di dubbio, lasciare il messaggio nella sezione "FreeCAD".
Prima di creare istanze, si prega di discutere sempre prima il bug nel Help forum e le richieste di nuove funzionalità in Open discussion forum.
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.
Quando si pensa di aver trovato un bug, si è invitati a segnalarlo lì, se si è prima discusso la questione nelle sedi opportune.
Prima di segnalare un bug, si prega di verificare i seguenti punti:
Se desiderate qualcosa che in FreeCAD che non è ancora implementato, questo non è un bug, ma una richiesta di nuove funzionalità.
Se avete creato il programma di correzione a un bug, una estensione o altro che può essere di uso pubblico in FreeCAD, create una patch utilizzando lo strumento Git diff e presentatela utilizzando il medesimo tracker (file di 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.
NOTEː the FreeCAD community recommends to first discuss any large revision to the source code in advance to save everyone time.
Se avete creato un ramo git contenente delle modifiche che desiderate far confluire nel codice di FreeCAD, potete fare la richiesta di avere la recensione e la fusione del vostro ramo, se gli sviluppatori di FreeCAD sono d'accordo. È necessario pubblicare prima il ramo in un repository git pubblico (github, bitbucket, sourceforge ...) e poi fornire l'URL del vostro ramo nella richiesta di unione.
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 (Mantis Bug Tracker) has it's own unique markup.
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*
Below are special MantisBT Source-Integration plugin keywords which will link to the FreeCAD GitHub repo. See Tracker#GitHub_and_MantisBT.
cːFreeCADː709d2f325db0490016807b8fa6f49d1c867b6bd8ː
dːFreeCADː709d2f325db0490016807b8fa6f49d1c867b6bd8ː
pːFreeCADː498ː
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
The format MantisBT will recognize:
For the inquisitive here is the regex MantisBT uses for this operation:
/(?:bugs?|issues?|reports?)+\s*:?\s+(?:#(?:\d+)[,\.\s]*)+/i
The format MantisBT will recognize:
For the inquisitive here is the regex MantisBT uses for this operation:
/(?:fixe?d?s?|resolved?s?)+\s*:?\s+(?:#(?:\d+)[,\.\s]*)+/i
Questo articolo spiega passo dopo passo come compilare FreeCAD su Windows.
Per creare un ramo locale e scaricare il codice sorgente è necessario aprire un terminale (prompt dei comandi) e portarsi nella directory (cd) in cui si desidera creare il sorgente, quindi digitare:
git clone https://github.com/FreeCAD/FreeCAD.git free-cad-code
In Windows, il compilatore di default è MS Visual Studio, sia che si tratti della versione Express oppure Completa 2008, 2012, o 2013. Inoltre è necessario installare la piattaforma Windows SDK per disporre delle diverse librerie richieste (e.g. Windows.h), anche se esse possono non essere richieste con i compilatori MS (sia full che express).
Per chi vuole evitare l'installazione completa dell'ingombrante Visual Studio al solo scopo di avere un compilatore può vedere Compilare in Windows - Occupare meno spazio.
Though it may be possible to use Cygwin or MinGW gcc it's not tested or ported so far.
Per compilare correttamente FreeCAD, servono tutte le Librerie di terze parti . Se si usa i compilatori MS si raccomanda di installare FreeCAD LibPack,che fornisce tutte le librerie necessarie per costruire FreeCAD in Windows. Serve il Libpack adatto alla propria architettura e compilatore. Attualmente FreeCAD fornisce Libpack Version11 per x32 e x64, per VS9 2008, VS11 2012, e VS12 2013.
All'interno del percorso di sistema assicurarsi di impostare i percorsi corretti per i seguenti programmi:
Per aggiungere al percorso di sistema:
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.
The first step to build FreeCAD with CMake is to configure the environment. There are two ways to do it:
The following process will assume you are using the LipPack. The second option may be discussed
in Options for the Build Process.
This will begin configuration and should fail because the location of
FREECAD_LIBPACK_DIR is unset.
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.
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.
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
Make sure to specify Visual Studio 12 x64(or the alternate C-Compiler you are using) as the generator in CMake before you continue.
File -> Open -> Project/Solution
This may take a while depending on your sytem
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.
Since early 0.17 cycle Freecad uses c++11 features that are not supported by 2008 version
Now FreeCAD can be built
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.
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
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:
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.
Some search path of Visual Studio need to be set. To change them, use the menu Tools→Options→Directory
Add the following search path to the include path search list:
Add the following search path to the lib path search list:
Add the following search path to the executable path search list:
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.
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.
After you conform to all prerequisites the compilation is - hopefully - only a mouse click in VC
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:
When using a LibPack with a Python version older than 2.5 you have to copy two further files:
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.
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//.
Nelle distribuzioni Linux recenti FreeCAD si compila facilmente, dato che di solito tutte le dipendenze sono fornite dal gestore di pacchetti. Fondamentalmente si tratta di eseguire 3 passaggi:
Qui, di seguito, troverete le spiegazioni dettagliate di tutto il processo, delle particolarità che si possono incontrare e alcuni script di build,. Se trovate qualcosa di sbagliato o di non aggiornato nel testo successivo (le distribuzioni Linux cambiano spesso), o se utilizzate una distribuzione che non è elencata, per favore aiutateci a correggerlo.
Per poter compilare FreeCAD è necessario il codice sorgente. Ci sono 3 modi per ottenerlo:
Il modo migliore e più veloce per ottenere il codice è quello di clonare il repository git di sola lettura ora ospitato in GitHub (bisogna avere il pacchetto git installato):
git clone https://github.com/FreeCAD/FreeCAD.git free-cad-code
Questo crea una copia locale della versione più recente del codice sorgente di FreeCAD in una nuova directory chiamata "free-cad-code".
Il repository ufficiale di FreeCAD è su Github: github.com/FreeCAD/FreeCAD
In alternativa è possibile scaricare il pacchetto sorgente, ma potrebbe già essere abbastanza vecchio, e quindi è sempre meglio ottenere i sorgenti più recenti tramite git o github.
Per compilare FreeCAD sotto Linux è necessario installare prima tutte le librerie indicate nella pagina Librerie di terze parti. Notare che i nomi e la disponibilità delle librerie dipendono dalla vostra distribuzione. Notare che se non si utilizza la versione più recente della propria distribuzione, alcuni dei pacchetti indicati in seguito potrebbero mancare dal vostro repository. In questo caso, cercare nel paragrafo sottostante dedicato alle Distribuzioni vecchie e non convenzionali.
Passa al paragrafo Compilare FreeCAD
Su sistemi Debian-based (Debian, Ubuntu, Mint, etc...) è abbastanza facile ottenere tutte le dipendenze che devono essere installate. La maggior parte delle librerie sono disponibili tramite apt-get o il gestore dei pacchetti synaptic.
either:
or:
either:
or:
Istruzioni supplementari per libcoin80-dev Debian wheezy-backports, unstable, testing, Ubuntu 13.10 e successive
Notare che liboce*-dev include le seguenti librerie:
Potrebbe essere necessario installare singolarmente questi pacchetti tramite il loro nome.
Opzionalmente è anche possibile installare questi pacchetti extra:
sudo apt install build-essential cmake python python-matplotlib libtool libcoin80-dev libsoqt4-dev libxerces-c-dev libboost-dev libboost-filesystem-dev libboost-regex-dev libboost-program-options-dev libboost-signals-dev libboost-thread-dev libboost-python-dev libqt4-dev libqt4-opengl-dev qt4-dev-tools python-dev python-pyside pyside-tools libeigen3-dev libqtwebkit-dev libshiboken-dev libpyside-dev libode-dev swig libzipios++-dev libfreetype6-dev liboce-foundation-dev liboce-modeling-dev liboce-ocaf-dev liboce-visualization-dev liboce-ocaf-lite-dev libsimage-dev checkinstall python-pivy python-qt4 doxygen libspnav-dev oce-draw liboce-foundation-dev liboce-modeling-dev liboce-ocaf-dev liboce-ocaf-lite-dev liboce-visualization-dev libmedc-dev libvtk6-dev libproj-dev
Gli utenti di Ubuntu 16.04 vedano anche queste ulteriori instruzioni .
Sono necessari i seguenti pacchetti:
E opzionalmente:
You need the following packages :
(if coin2 is the latest available for your version of Fedora, use packages from http://www.zultron.com/rpm-repo/)
And optionally :
Il modo più semplice per controllare quali pacchetti sono necessari per compilare FreeCAD è quello di verificare tramite Portage:
emerge -pv freecad
Questo dovrebbe dare una bella lista di pacchetti extra che è necessario installare sul proprio sistema.
Sono necessari i seguenti pacchetti:
Per FreeCAD 0.14 stable e 0.15 unstable, se le librerie Eigen3 e swig non sono disponibili nei repositori standard, è possibile ottenerle e installarle da qui:
Notare inoltre che la libreria Eigen3 da Factory Education ha causato talvolta dei problemi, quindi utilizzare quella dei repo Extra di KDE 4.8
Starting with 0.17pre Opensuse 13.2 is too old to build due to too old boost.
You will need the following libraries from the official repositories:
Also, make sure to check the AUR for any missing packages that are not on the repositories, currently:
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
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 is not needed to build FreeCAD or to run it, but it is needed for the 2D Drafting 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 ort elsewhere, you can compile pivy yourself:
cMake è il sistema di build più recente, che ha il grande vantaggio di essere comune a differenti sistemi (Linux, Windows, MacOSX, etc). Atualmente FreeCAD usa il sistema cMake come suo principale sistema. Di solito la compilazione con cMake è molto semplice e avviene in 2 fasi. Nella prima fase, cMake verifica se tutti i programmi e le librerie necessarie sono presenti nel sistema e imposta tutto ciò che è necessario per la successiva compilazione. In seguito sono proposte e descritte un paio di alternative, ma FreeCAD viene fornito con valide impostazioni predefinite. La seconda fase è la compilazione stessa, che produce l'eseguibile di FreeCAD. Modificare le eventuali opzioni di cmake e renderle diverse dai loro valori di default, è molto più facile con cmake-gui o con altre applicazioni grafiche cmake che con cmake sulla riga di comando, dato che le applicazioni grafiche permettono un controllo interattivo.
Poiché FreeCAD è un'applicazione pesante, la compilazione può richiedere un po' di tempo (circa 10 minuti su una macchina veloce, 30 minuti, o più, su una lenta)
Se avete dei dubbi, a causa di suoi limiti, non fate una costruzione interna al sorgente, ma create una costruzione out-of-source, come spiegato nella sezione successiva. FreeCAD può essere costruito nel sorgente (in-source), il che significa che tutti i file risultanti dalla compilazione si trovano nella stessa cartella del codice sorgente. Questo va bene per "dare un'occhiata" a FreeCAD, e permette di rimuoverlo facilmente eliminando semplicemente la sua cartella. Quando si prevede di compilarlo spesso, si consiglia invece di fare una costruzione esterna al sorgente (out-of-source) perchè offre maggiori vantaggi. I seguenti comandi compilano FreeCAD:
$ cd freecad (the folder where you cloned the freecad source)
If you want to use your system's copy of Pivy, which you most commonly will, then if not on Linux, set the compiler flag to use the correct pivy (via FREECAD_USE_EXTERNAL_PIVY=1). Using external Pivy became the default for Linux, during development of FreeCAD 0.16, so it does not need to be manually set when compiling this version onwards, on Linux. Also, set the build type to Debug if you want a debug build or Release if not. 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. (NOTE: the space and "." after the cmake flags are CRITICAL!):
$ cmake -DFREECAD_USE_EXTERNAL_PIVY=1 -DCMAKE_BUILD_TYPE=Debug . # Note: to speed up build use all CPU cores: make -j$(nproc) $ make
$ cmake -DFREECAD_USE_EXTERNAL_PIVY=1 -DCMAKE_BUILD_TYPE=Release . # Note: to speed up build use all CPU cores: make -j$(nproc) $ make
L'eseguibile di FreeCAD risiede quindi nella cartella "bin", e può essere lanciato con:
$ ./bin/FreeCAD
This is a method, using Git, to repair your source code directory after accidentally running an in-source build.
1) delete everything in your source base directory EXCEPT the hidden .git folder 2) In terminal 'git reset --hard HEAD' //any remnants of an 'in source' build will be gone. 3) delete everything from your 'out of source' build directory and start over again with cmake and a full new clean build.
Se intendete seguire la rapida evoluzione di FreeCAD, convenie costruire in una cartella separata (Out-of-source build). Ogni volta che il codice sorgente viene aggiornato, cMake riconosce intelligentemente i file che sono stati modificati e ricompila solo ciò che è necessario. La costruzione Out-of-source è particolarmente utile quando si utilizza il sistema Git, perché si può facilmente provare altri rami senza confondere il sistema di compilazione. Per costruire out-of-source, è sufficiente creare una cartella di generazione, distinta dalla cartella di origine FreeCAD, e, dalla cartella di compilazione, indirizzare CMake (o se si usa cmake-gui sostituire nel codice seguente "cmake" con "cmake-gui") verso la cartella di origine :
mkdir freecad-build cd freecad-build cmake ../freecad (or whatever the path is to your FreeCAD source folder) # Note: to speed up build use all CPU cores: make -j$(nproc) make
L'eseguibile FreeCAD risiede quindi nella directory "bin" (all'interno della propria directory freecad-build).
Ci sono diversi moduli sperimentali o non finiti che devono essere costruiti, se si desidera lavorare su di essi. Per fare ciò, è necessario impostare le opzioni appropriate per la fase di configurazione. Fatelo dalla riga di comando, passando le opzioni -D <var>:<type>=<value> per cMake oppure utilizzando una delle interfaccie grafiche disponibili (gui-frontend) (ad es. i pacchetti cmake-qt-gui oppure cmake-curses-gui per Debian). Modificare le eventuali opzioni di cmake e renderle diverse dai loro valori di default, è molto più facile con cmake-gui o con altre applicazioni grafiche cmake che con cmake sulla riga di comando, dato che le applicazioni grafiche permettono un controllo interattivo.
A titolo di esempio, per configurare FreeCAD con la costruzione del modulo Assembly, basta selezionare la casella in un'applicazione CMake gui (ad esempio cmake-gui) o nella riga di comando digitare l'istruzione:
cmake -D FREECAD_BUILD_ASSEMBLY:BOOL=ON ''path-to-freecad-root''
Le opzioni possibili sono elencate nel file CmakeLists.txt della radice FreeCAD.
Se si desidera sviluppare del materiale Qt per FreeCAD, è necessario il plugin Qt Designer, che fornisce tutti i widget personalizzati di FreeCAD. Andare in
freecad/src/Tools/plugins/widget
Finora non forniamo un makefile -- ma chiamando
qmake plugin.pro
lo creiamo. Una volta fatto, chiamando
make
si crea la libreria libFreeCAD_widgets.so. Per rendere nota questa libreria a Qt Designer è necessario copiare il file in $QTDIR/plugin/designer
If you feel bold enough to dive in the code, you could take advantage to build and consult Doxygen generated FreeCAD's Source documentation
Se prevedete di costruire un pacchetto Debian indipendente dai sorgenti è necessario installare prima i seguenti pacchetti:
dh-make devscripts #optional, used for checking if packages are standard-compliant lintian
Per costruire un pacchetto, aprire una console, andare nella directory di FreeCAD e chiamare
debuild
Quando il pacchetto è costruito, è possibile utilizzare lintian per verificare se il pacchetto contiene errori
#replace by the name of the package you just created lintian your-fresh-new-freecad-package.deb
When building FreeCAD for 64-bit there is a known issue with the OpenCASCADE 64-bit package. To get FreeCAD running properly you might need to run the ./configure script with the additional define _OCC64 set:
./configure CXXFLAGS="-D_OCC64"
For Debian based systems this workaround is not needed when using the prebuilt package because there the OpenCASCADE package is built to set internally this define. Now you just need to compile FreeCAD the same way as described above.
Ecco tutto quello che vi serve per una compilazione completa di FreeCAD. Si tratta di uno script di approccio e funziona su una distro di recente installazione. I comandi richiedono la password di root (per l'installazione di pacchetti) e talvolta di riconoscere un'impronta digitale per il server di un repository esterno o un repository https-subversion. Questi script dovrebbero funzionare su versioni a 32 e 64 bit. Essi sono scritti per diverse versioni, e dovrebbero essere eseguibili anche su versioni successive, con o senza grandi cambiamenti.
Se disponete di uno script per la vostra distribuzione preferita, siete pregati di inviarlo! Noi lo incorporeremo in questo articolo.
These scripts provide a reliable way to install the correct set of dependencies required to build and run FreeCAD on Ubuntu. They make use of the FreeCAD Ubuntu PPA repositories, and should work on any version of Ubuntu targeted by the PPA. The 'daily' PPA targets recent versions of Ubuntu, and the 'stable' PPA targets all officially supported versions of Ubuntu.
This script installs dependencies for the daily development snapshot of FreeCAD.
#!/bin/sh sudo add-apt-repository --enable-source ppa:freecad-maintainers/freecad-daily && sudo apt-get update # Install the dependencies needed to build FreeCAD sudo apt-get build-dep freecad-daily # Install the dependencies needed to run FreeCAD (and a build of FreeCAD itself) sudo apt-get install freecad-daily
This script installs dependencies for the latest stable release of FreeCAD. (For Ubuntu 12.04, omit "--enable-source" from the add-apt-repository command.)
#!/bin/sh sudo add-apt-repository --enable-source ppa:freecad-maintainers/freecad-stable && sudo apt-get update # Install the dependencies needed to build FreeCAD sudo apt-get build-dep freecad # Install the dependencies needed to run FreeCAD (and a build of FreeCAD itself) sudo apt-get install freecad
(These scripts also install the PPA build of FreeCAD itself, as a side effect. You could then uninstall that while leaving the dependencies in place. However, leaving it installed will enable the package manager to keep the set of dependencies up to date, which is useful if you are following the development for a long time.)
After installing the dependencies, please see the generic instructions for getting the source code, running CMake, and compiling. The following script is an example of one way to do this.
#!/bin/sh # checkout the latest source git clone https://github.com/FreeCAD/FreeCAD.git freecad # go to source dir cd freecad # open cmake-gui window cmake-gui . # build configuration cmake . # build FreeCAD # Note: to speed up build use all CPU cores: make -j$(nproc) make
No external Repositories are needed to compile FreeCAD 0.13 with this release. However, there is an imcompatability with python3-devel which needs to be removed. FreeCAD can be compiled from GIT similar to in OpenSUSE 12.2
# install needed packages for development sudo zypper install gcc cmake OpenCASCADE-devel libXerces-c-devel \ python-devel libqt4-devel python-qt4 Coin-devel SoQt-devel boost-devel \ libode-devel libQtWebKit-devel libeigen3-devel gcc-fortran git swig # create new dir, and go into it mkdir FreeCAD-Compiled cd FreeCAD-Compiled # get the source git clone https://github.com/FreeCAD/FreeCAD.git free-cad # Now you will have subfolder in this location called free-cad. It contains the source # make another dir for compilation, and go into it mkdir FreeCAD-Build1 cd FreeCAD-Build1 # build configuration cmake ../free-cad # build FreeCAD make # test FreeCAD cd bin ./FreeCAD -t 0
Since you are using git, next time you wish to compile you do not have to clone everything, just pull from git and compile once more
# go into free-cad dir created earlier cd free-cad # pull git pull # get back to previous dir cd .. # Now repeat last few steps from before. # make another dir for compilation, and go into it mkdir FreeCAD-Build2 cd FreeCAD-Build2 # build configuration cmake ../free-cad # build FreeCAD # Note: to speed up build use all CPU cores: make -j$(nproc) make # test FreeCAD cd bin ./FreeCAD -t 0
# get the needed tools and libs sudo apt-get install build-essential python libcoin60-dev libsoqt4-dev \ libxerces-c2-dev libboost-dev libboost-date-time-dev libboost-filesystem-dev \ libboost-graph-dev libboost-iostreams-dev libboost-program-options-dev \ libboost-serialization-dev libboost-signals-dev libboost-regex-dev \ libqt4-dev qt4-dev-tools python2.5-dev \ libsimage-dev libopencascade-dev \ libsoqt4-dev libode-dev subversion cmake libeigen2-dev python-pivy \ libtool autotools-dev automake gfortran # checkout the latest source git clone https://github.com/FreeCAD/FreeCAD.git freecad # go to source dir cd freecad # build configuration cmake . # build FreeCAD # Note: to speed up build use all CPU cores: make -j$(nproc) make # test FreeCAD cd bin ./FreeCAD -t 0
Posted by user [PrzemoF] in the forum.
#!/bin/bash #ARCH=x86_64 #ARCH=i686 ARCH=$(arch) MAIN_DIR=FreeCAD BUILD_DIR=build #FEDORA_VERSION=22 FEDORA_VERSION=23 #FEDORA_VERSION=24 echo "Installing packages required to build FreeCAD" sudo dnf -y install gcc cmake gcc-c++ boost-devel zlib-devel swig eigen3 qt-devel \ shiboken shiboken-devel pyside-tools python-pyside python-pyside-devel xerces-c \ xerces-c-devel OCE-devel smesh graphviz python-pivy python-matplotlib tbb-devel \ freeimage-devel Coin3 Coin3-devel med-devel vtk-devel cd ~ mkdir $MAIN_DIR || { echo "~/$MAIN_DIR already exist. Quitting.."; exit; } cd $MAIN_DIR git clone https://github.com/FreeCAD/FreeCAD.git mkdir $BUILD_DIR || { echo "~/$BUILD_DIR already exist. Quitting.."; exit; } cd $BUILD_DIR cmake ../FreeCAD # Note: to speed up build use all CPU cores: make -j$(nproc) make
Lo sviluppo di FreeCAD è veloce, quasi ogni giorno ci sono correzioni di bug o nuove funzionalità. Il sistema cmake consente di aggiornare il codice sorgente in modo intelligente e di ricompilare solo ciò che è cambiato, con delle compilazioni successive molto veloci. Con git o subversion è molto semplice aggiornare il codice sorgente:
#Replace with the location where you cloned the source code the first time cd freecad #If you are using git git pull
Move into the appropriate build directory and run cmake again (as cmake updates the version number data for the Help menu, ...about FreeCAD), however you do not need to add the path to source code after "cmake", just a space and a dot:
#Replace with the location of the build directory cd ../freecad-build cmake . # to use all cpu cores change to: make -j$(nproc) make
Vedere anche Velocizzare la compilazione Come velocizzare la compilazione di FreeCAD
This page explains how to compile the latest FreeCAD source code on Mac OS X. It is meant as a starting point for developing on FreeCAD; if you instead want to try using the latest pre-release version of FreeCAD, downloads are available from our continuous integration system at https://github.com/FreeCAD/FreeCAD/releases .
Prima di tutto, è necessario installare il seguente software.
For FreeCAD, we usually use Homebrew, though MacPorts was used previously.
FreeCAD uses CMake to build the source. CMake comes in two versions, command-line and GUI. Use whichever you prefer.
The command-line version of CMake will be automatically installed by Homebrew in the prerequisites step, or the GUI version can be downloaded directly from https://www.cmake.org/download .
All of the needed libraries can be installed using Homebrew. We maintain a "tap" including a formula for FreeCAD, it can be used to get the relevant dependencies.
We are currently transitioning FreeCAD from Qt 4 to Qt 5; the Homebrew formula will default to installing Qt5.6 unless --with-qt4 is specified along with --only-dependencies.
Note that there is currently a bug where the dependencies aren't all installed on the first run of brew install... - the duplicate line below is intentional
brew tap homebrew/science brew tap freecad/freecad brew install --only-dependencies freecad brew install --only-dependencies freecad
In this guide, the source and build folders are created in /Users/username/FreeCAD, but you can of course use whatever folder you want.
mkdir ~/FreeCAD cd ~/FreeCAD
To get the FreeCAD source code, this command will create a "clone" of the FreeCAD git repository in to a new directory called FreeCAD-git:
git clone https://github.com/FreeCAD/FreeCAD FreeCAD-git
Create a new folder for the build:
mkdir ~/FreeCAD/build
Now you will need to run CMake to generate the build files. Several options will need to be given to CMake, which can be accomplished either with the CMake GUI application, or via the command line.
Name | Value | Notes |
---|---|---|
BUILD_QT5 | 1 (checked) | Set 0 (unchecked) if building with Qt4. |
FREECAD_USE_EXTERNAL_KDL | 1 (checked) | |
CMAKE_BUILD_TYPE | Debug | Can be Debug or Release. Debug is generally used for development |
BUILD_FEM_NETGEN | 1 (checked) | |
FREECAD_CREATE_MAC_APP | 1 (checked) | If you want to make a FreeCAD.app , this CMake option will cause "make install" to create a FreeCAD.app bundle in CMAKE_INSTALL_PREFIX . |
Open the CMake app, and fill in the source and build folder fields. In this case, it would be /Users/username/FreeCAD/FreeCAD-git for the source, and /Users/username/FreeCAD/build for the build folder.
Next, click the Configure button to populate the list of configuration options. This will display a dialog asking you to specify what generator to use. Leave it at the default Unix Makefiles. Configuring will fail the first time because there are some options that need to be changed. Note: You will need to check the Advanced checkbox to get all of the options.
Set options from the table above, then click Configure again and then Generate.
Open a terminal, cd in to the build directory that was created above. Run cmake with options from the table above, following the formula -D(Name)="(Value)", and the path to your FreeCAD source directory as the final argument.
$cd ~/FreeCAD/build $cmake -DFREECAD_USE_EXTERNAL_KDL="1" ...options continue... -DFREECAD_CREATE_MAC_APP ="1" ../FreeCAD-git
Finally, from a terminal run make to compile FreeCAD.
cd ~/FreeCAD/build make –j3
The -j option specifies how many make processes to run at once. One plus the number of CPU cores is usually a good number to use. However, if compiling fails for some reason, it is useful to rerun make without the -j option, so that you can see exactly where the error occurred.
See also Compiling - Speeding up.
If make finishes without any errors, you can now launch FreeCAD, either from Terminal with ./bin/FreeCAD, or by double clicking the executable in Finder.
FreeCAD development happens fast; every day or so there are bug fixes or new features. To get the latest changes, use git to update the source directory (see Source code management), then re-run the CMake and make steps above. It is not usually necessary to start with a clean build directory in this case, and subsequent compiles will generally go much faster than the first one.
"No CMAKE_Fortran_COMPILER could be found." during configuration - Older versions of FreeCAD will need a fortran compiler installed. With Homebrew, do "brew install gcc" and try configuring again, giving cmake the path to Fortran ie -DCMAKE_Fortran_COMPILER=/opt/local/bin/gfortran-mp-4.9 . Or, preferably use a more current version of FreeCAD source!
See OpenGL on MacOS for OpenGL issues when Qt 4.8 and earlier are used on MacOS.
When using CMake versions older than 3.1.0, it's necessary to set CMake variable FREETYPE_INCLUDE_DIR_freetype2 manually, eg /usr/local/include/freetype2
Si tratta di librerie che nel progetto di FreeCAD non vengono modificate. Sono utilizzate sostanzialmente senza modifiche come librerie a collegamento dinamico (*.so o *.dll). Se è necessario modificarle o è necessaria una classe wrapper (classe involucro), allora il codice della wrapper o il codice della libreria modificata deve essere spostato nel pacchetto base di FreeCAD.
Per l'ambiente Windows, considerare la possibilità di usare LibPack invece di scaricare e installare tutto da soli.
Le librerie utilizzate sono:
Lib name | Version needed | Link to get it |
---|---|---|
Python | >= 2.5.x | http://www.python.org/ |
OpenCasCade | >= 5.2 | http://www.opencascade.org |
Qt | >= 4.1.x | https://www.qt.io/ |
Coin3D | >= 2.x | http://www.coin3d.org |
SoQt | >= 1.2 | http://www.coin3d.org |
Xerces-C++ | >= 2.7.x < 3.0 | http://xml.apache.org/xerces-c/ |
Zlib | >= 1.x.x | http://www.zlib.net/ |
Boost | >= 1.33.x | http://www.boost.org/ |
Eigen3 | >= 3.0.1 | http://eigen.tuxfamily.org/index.php?title=Main_Page |
Shiboken | >= 1.1.2 | http://shiboken.readthedocs.org/en/latest/ |
libarea | N/A | https://github.com/danielfalck/libarea |
Versione: 2.5 o superiore
Licenza: licenza Python 2.5
È possibile utilizzare il codice sorgente o i binari forniti da http://www.python.org/ oppure, in alternativa, utilizzare ActiveState Python fornito da http://www.activestate.com/ anche se è un po' difficile ottenere le librerie di debug da ActiveState.
Python è il linguaggio di script primario ed è usato in tutta l'applicazione, ad esempio, per:
In particolare il "caricamento dinamico dei pacchetti" di Python viene utilizzato per caricare le funzionalità aggiuntive e gli ambienti di lavoro solo al momento in cui essi sono necessari per eseguire le operazioni in atto.
Per maggiori informazioni su Python vedere: www.python.org .
Qualcuno potrebbe chiedere: perché proprio Python? Ci sono diversi motivi. Finora, nella mia vita professionale ho usato diversi linguaggi di script:
Python è più OO (programmazione a oggetti; object-oriented: orientato a oggetti) di Perl e Tcl, il codice non è legato come in Perl e VB. Java innanzitutto non è un linguaggio di script ed è difficile (o impossibile) da incorporare. Python è ben documentato e facile da incorporare e da estendere. E' anche ben testato e ha un buon supporto nella comunità del software open source.
Un ringraziamento a Guido van Rossum e alle molte persone che hanno permesso tale successo a Python!
Versione: 5.2 o superiore
Licenza: v6.7.0 and later are governed by GNU Lesser General Public License (LGPL) version 2.1 with additional exception. https://www.opencascade.com/content/licensing Earlier versions use a slightly different license: https://www.opencascade.com/content/occt-public-license
OCC è un kernel di CAD completo. Originariamente, è stato sviluppato da Matra Datavision in Francia per le applicazioni Strim e Euclid Quantum e successivamente è stato reso Open Source. E' una enorme libreria e sopratutto rende possibile un programma di CAD gratuito, mettendo a disposizione alcuni pacchetti che sarebbero difficili o impossibili da realizzare in un progetto Open Source:
Per saperne di più su OpenCascade visitare la pagina di OpenCascade o consultare http://www.opencascade.org.
Versione: 4.1.x o superiore
Licenza: GPL v2.0/v3.0 o Commerciale (dalla versione 4.5 anche LPGL v2.1)
Non credo sia necessario dire molto su Qt. E' uno degli strumenti più utilizzati per i progetti di GUI (Interfacce grafiche) Open Source. Secondo me, i motivi principali per utilizzare Qt sono Qt Designer e la possibilità di caricare intere finestre di dialogo come risorse (XML) e di incorporarvi dei widget (componenti accessori) specializzati. In un'applicazione CAX l'interazione tra l'utente e le finestre di dialogo costituiscono sicuramente la maggior parte del codice e disporre un buon disegnatore di dialoghi è molto importante per poter estendere facilmente FreeCAD con nuove funzionalità. Ulteriori informazioni e una buona documentazione online si trova in http://www.qtsoftware.com.
Versione: 2.0 o superiore
Licenza: GPL v2.0 o Commerciale
Coin è una libreria di grafica 3D di alto livello con una interfaccia di programmazione delle applicazioni (Application Programming Interface) in C++. Per "renderizzare" i grafici in tempo reale Coin utilizza la struttura di dati scenegraph (grafo di scena) adatta alla maggior parte delle applicazioni di visualizzazione scientifica e ingegneristica.
Coin è portabile su un'ampia gamma di piattaforme: qualsiasi piattaforma UNIX / Linux / * BSD, tutti i sistemi operativi Microsoft Windows, e Mac OS X.
Coin è costruito secondo lo standard del settore OpenGL delle librerie di modalità di renderizzazione immediata, e aggiunge astrazioni per primitive di livello superiore, fornisce interattività 3D, aumenta enormemente la praticità e la produttività del programmatore, e contiene molte funzioni di ottimizzazione complesse per il rendering veloce che sono trasparenti per il programmatore di applicazioni.
Coin si basa sul SGI (sistema di gestione integrato) della API (interfaccia di programmazione di applicazioni) di Open Inventor. Open Inventor, per coloro che non hanno familiarità con essa, è da tempo diventata di fatto la libreria standard per la visualizzazione grafica 3D e per i software di simulazione visiva nella comunità scientifica e di ingegneria. È stata sperimentata per un periodo di oltre 10 anni, la sua maturità contribuisce al suo successo. È utilizzata quale blocco di costruzione principale per migliaia di applicazioni di ingegneria in larga scala in tutto il mondo.
In FreeCAD useremo OpenInventor come visualizzatore 3D perché il visualizzatore OpenCascade (AIS e Graphics3D) ha forti limitazione e costituisce una strozzatura delle prestazioni, soprattutto quando si tratta di grandi renderizzazioni di ingegneria. Altre cose quali texture o renderizzazione volumetrica non sono proprio supportate, ecc ....
Dalla versione 2.0 Coin utilizza un nuovo modello di licenza. Non è più LGPL. Usa GPL per l'open source e una licenza commerciale per le applicazioni closed source. Questo significa che per vendere un proprio lavoro basato su FreeCAD (moduli di estensione) è necessario acquistare una licenza Coin!
Versione: 1.2.0 o superiore
Licenza: GPL v2.0 o Commerciale
SoQt è il collante tra il toolkit dei componenti GUI Qt e Inventor. Purtroppo, non è più LGPL quindi dobbiamo rimuoverlo dal codice base di FreeCAD e collegarlo come una libreria. Ha lo stesso modello di licenza di Coin. Deve essere compilato con la propria versione di Qt.
Versione: 2.7.0 o superiore
Licenza: Apache Software License Versión 2.0
Xerces-C++ è un analizzatore (parser) di convalida XML scritto in un sottoinsieme portatile di C++. Xerces-C++ rende più facile fornire alla propria applicazione la capacità di leggere e scrivere dati XML. Per l'analisi, la generazione, la manipolazione, e la convalida di documenti XML è prevista una libreria condivisa.
Xerces-C++ è fedele alla raccomandazione XML 1.0 e ai molti standard associati (vedere Caratteristiche sotto).
L'analizzatore offre elevate prestazioni, modularità e scalabilità. Il codice sorgente, gli esempi e la documentazione API sono forniti con l'analizzatore stesso. Per permettere la portabilità, si è avuto cura di fare il minimo uso di modelli, non RTTI, e il minimo uso di #ifdefs.
In FreeCAD il parser è utilizzato per salvare e ripristinare i parametri.
Versione: 1.x.x
Licenza: zlib
zlib è una libreria di compressione usabile praticamente su qualsiasi hardware e sistema operativo senza perdita di dati. Di proposito generale, è progettata per essere libera, giuridicamente svincolata, cioè non coperta da alcun brevetto. Il formato dei dati zlib è di per sé portabile sulle varie piattaforme. A differenza del metodo di compressione LZW utilizzato nella compressione Unix e nel formato immagine GIF, il metodo di compressione attualmente utilizzato in zlib sostanzialmente non espande mai i dati. (LZW può raddoppiare o triplicare le dimensioni del file in casi estremi.) Inoltre, l'utilizzo di memoria di Zlib è indipendente dai dati di input e, se necessario, può essere ridotta, ma con una perdita di efficienza di compressione.
Versione: 1.33.x
Licenza: Boost Software License - Versione 1.0
Le librerie Boost C++ sono un insieme di librerie open source sottoposte a revisione paritaria, librerie che estendono le funzionalità di C++. Le librerie sono rilasciate sotto Licenza Boost Software, progettate per consentire a Boost di essere utilizzato sia con progetti aperti che chiusi. Molti dei fondatori di Boost fanno parte della commissione C++ standard e diverse librerie di Boost sono state accettate per l'incorporazione nel Technical Report 1 di C++0x.
Le librerie sono destinate a una vasta gamma di utenti e di campi di applicazioni C++. Si va dalle librerie di carattere generale come SmartPtr, alle applicazioni del sistema operativo come FileSystem, alle librerie rivolte principalmente a sviluppatori di altre librerie e a utenti avanzati di C++, come la libreria MPL.
Al fine di garantire efficienza e flessibilità, Boost fà ampio uso di modelli. Boost è stata una fonte di intenso lavoro e di ricerca nella programmazione generica e nella meta-programmazione in C++.
Vedere: http://www.boost.org/ per i dettagli.
Versione: N/A
Licenza: New BSD (BSD 3-Clause)
Area è una parte di software creato da Dan Heeks per HeeksCNC. Viene impiegato come una libreria per la generazione di operazioni CAM correlate all'ambiente Path.
LibPack è un utile pacchetto che comprende tutte le librerie di cui sopra. Attualmente è disponibile per la piattaforma Windows sulla pagina Download! Lavorando sotto Linux non si ha bisogno di LibPack, si deve invece fare uso dei repository di pacchetti della propria distribuzione Linux.
(lista dei cambiamenti)
Per sviluppare seriamente qualsiasi software servono degli strumenti. Ecco un elenco di quelli che usiamo per sviluppare FreeCAD:
Qt-toolkit è uno strumento avanzato per il disegno di interfacce utente indipendente dalla piattaforma. Esso è contenuto in LibPack di FreeCAD, ma può anche essere scaricato da Qt project.
Grande programma di disegno vettoriale. Aderisce allo standard SVG e viene utilizzato per disegnare icone e immagini. E' scaricabile da www.inkscape.org.
Uno strumento molto buono e stabile per generare la documentazione del codice partendo da file .h e .cpp.
Non c'è molto da dire su GNU Image Manipulation Program (Programma di manipolazione di immagini di GNU). Può anche gestire i file .xpm che sono un modo molto pratico per gestire le icone nei programmi di QT. XPM è sostanzialmente un codice C compilabile in un programma.
GIMP è scaricabile da: www.gimp.org
Anche se VC8 è per lo sviluppo in C++ non è migliorato molto da VisualStudio 6 (a mio parere è stato un bel passo indietro), è un sistema di sviluppo gratuito su Windows. Per le applicazioni native Win32 è necessario scaricare il PlatformSDK da M$.
L'edizione Express è difficile da trovare. Si può provare a questo link
È uno strumento Open Source per registrare Screencast (Webcast) (registrazione digitale dell'output dello schermo). È un ottimo strumento per creare tutorial registrandoli. Non è così noioso come scrivere la documentazione.
Vedere camstudio.org per avere maggiori informazioni.
Questo è uno strumento molto importante. Rende l'utilizzo di Subversion (il nostro sistema di controllo della versione in sf.net) un vero piacere. Tramite l'integrazione con l'esploratore, è possibile gestire facilmente le revisioni, controllare le differenze, risolvere conflitti, creare rami, ecc.... La finestra di dialogo commit è un capolavoro. Fornisce una panoramica sui propri file modificati e permette di metterli in commit o meno. Questo rende facile raggruppare le modifiche apportate alle unità logiche e commentarle con una efficace etichetta di commit.
Potete trovare TortoiseSVN in tortoisesvn.tigris.org.
Un programma UML open source completo di funzionalità. Ha un sacco di funzioni importanti, tra cui la generazione inversa del codice sorgente C++ codice .... (Permette, ad esempio, di generare codice C++ in automatico partendo da grafici).
Scaricarlo da: staruml.sourceforge.net
Da Fare
Questa pagina descrive i diversi modi per avviare FreeCAD e le principali caratteristiche di configurazione.
FreeCAD può essere avviato normalmente, facendo doppio clic sulla sua icona sul desktop o selezionandolo dal menu di avvio, ma può anche essere avviato direttamente dalla riga di comando. Ciò consente di modificare alcune delle opzioni di avvio di default.
Le opzioni della riga di comando sono soggette a frequenti cambiamenti, quindi è bene verificare le opzioni correnti digitando:
FreeCAD --help
Nella risposta sono elencati i parametri utilizzabili:
Usage: FreeCAD [options] File1 File2 ..... Allowed options: Generic options: -v [ --version ] print version string -h [ --help ] print help message -c [ --console ] start in console mode --response-file arg can be specified with '@name', too
Configuration: -l [ --write-log ] arg write a log file to default location(Run FreeCAD --h to see default location) --log-file arg Unlike to --write-log this allows to log to an arbitrary file -u [ --user-cfg] arg User config file to load/save user settings -s [ --system-cfg] arg System config file to load/save system settings -t [ --run-test ] arg test level -M [ --module-path ] arg additional module paths -P [ --python-path ] arg additional python paths
EX: (Windows)
"C:\Program Files\FreeCAD 0.14\bin\FreeCAD.exe" -M "N:\FreeCAD\Mod\Draft" -M "N:\FreeCAD\Mod\Part" -M "N:\FreeCAD\Mod\Drawing" -u "N:\FreeCAD\Config\user.cfg" -s "N:\FreeCAD\Config\system.cfg"
FreeCAD può leggere alcune di queste opzioni da un file di configurazione. Questo file deve essere nella directory bin e deve essere nominato FreeCAD.cfg. Tenere presente che le opzioni specificate nella riga di comando sovrascrivono il file di configurazione!
Alcuni sistemi operativi hanno una riga di comando estremamente corta. Il modo più comune per aggirare questa limitazione è quello di usare il file di risposta. Un file di risposta è semplicemente un file di configurazione che utilizza la stessa sintassi della riga di comando. Se la riga di comando specifica un nome di file di risposta da utilizzare, esso viene caricato e analizzato in aggiunta alla linea di comando:
FreeCAD @ResponseFile.txt
oppure:
FreeCAD --response-file=ResponseFile.txt
Per l'utente esistono alcune opzioni non visibili. Queste opzioni sono, per esempio, i parametri di X-Window analizzati dal sistema Windows:
FreeCAD si avvia normalmente in modalità GUI, ma si può anche forzare l'avvio in modalità console digitando:
FreeCAD -c
dalla riga di comando. In modalità console non viene visualizzata nessuna interfaccia utente, e appare un prompt dell'interprete di Python. Da questo prompt di Python, si ha le stesse funzionalità che si ha dall'interprete di Python che viene eseguito all'interno della GUI di FreeCAD e si ha normale accesso a tutti i moduli e plugin di FreeCAD, eccettuato il modulo FreeCADGui. Tenere presente che anche i moduli che dipendono da FreeCADGui potrebbero non essere disponibili.
Gli script Python e i file di macro di FreeCAD possono essere specificati come argomenti della riga di comando di uno dei file eseguibili di cui sopra.
A ogni avvio FreeCAD esamina i suoi ambienti ed i parametri della riga di comando. Si costruisce un set di configurazione che contiene l'essenza delle informazioni per l'esecuzione. Queste informazioni vengono poi utilizzate per determinare il luogo dove salvare i dati dell'utente o file di log (registro). E' anche molto importante per le analisi post-mortem. Pertanto viene salvato nel file di registro.
Nome var config | Descrizione | Esempio M$ | Esempio Posix (Linux) |
---|---|---|---|
UserAppData | Percorso dove FreeCAD archivia i dati dell'applicazione relativi all'utente. | C:\Documents and Settings\username\Application Data\FreeCAD | /home/username/.FreeCAD |
UserParameter | File in cui FreeCAD archivia i dati dell'applicazione relativi all'utente. | C:\Documents and Settings\username\Application Data\FreeCAD\user.cfg | /home/username/.FreeCAD/user.cfg |
SystemParameter | File in cui FreeCAD archivia i dati relativi all'applicazione. | C:\Documents and Settings\username\Application Data\FreeCAD\system.cfg | /home/username/.FreeCAD/system.cfg |
UserHomePath | Percorso home dell'utente corrente | C:\Documents and Settings\username\My Documents | /home/username |
Nome var config | Descrizione | Esempio |
---|---|---|
LoggingFile | 1 se il logging è attivato | 1 |
LoggingFileName | Nome del file dove si trova il log | C:\Documents and Settings\username\Application Data\FreeCAD\FreeCAD.log |
RunMode | Indica come funzionerà il ciclo principale. "Script" significa che richiama il file di script fornito e poi esce. "Cmd" esegue l'interprete della riga di comando. "Internal" esegue uno script interno. "Gui" entra nel ciclo di evento Gui. "Module" carica un dato modulo python. | "Cmd" |
FileName | Il suo significato dipende da RunMode | |
ScriptFileName | Il suo significato dipende da RunMode | |
Verbose | Livello di verbosità di FreeCAD | "" o "strict" |
OpenFileCount | Contiene il numero di file aperti attraverso gli argomenti della riga di comando | "12" |
AdditionalModulePaths | Contiene i percorsi di moduli aggiuntivi indicati nella linea di cmd | "extraModules/" |
Nome var config | Descrizione | Esempioo M$ | Esempio Posix (Linux) |
---|---|---|---|
AppHomePath | c:/Progam Files/FreeCAD_0.7 | /user/local/FreeCAD_0.7 | |
PythonSearchPath | Contiene un elenco di percorsi dove python cerca i moduli. Questo vale all'avvio e può cambiare durante l'esecuzione |
Alcune librerie hanno bisogno di chiamare le variabili di ambiente del sistema. A volte, quando c'è un problema con un'installazione FreeCAD, è perché qualche variabile d'ambiente è assente o è impostata in modo errato. Pertanto, alcune variabili importanti vengono duplicate in Config e salvate nel file di registro
Variabili d'ambiente relative a Python:
Variabili d'ambiente relative a OpenCascade:
Variabili d'ambiente relative al sistema:
La tabella seguente mostra le informazioni disponibili relative alla versione di costruzione. La maggior parte proviene dal repositorio di Subversion. Queste cose sono necessarie per ricostruire esattamente la versione!
Nome var config | Descrizione | Esempio |
---|---|---|
BuildVersionMajor | Numero di versione principale della costruzione. Definito in src/Build/Version.h.in | 0 |
BuildVersionMinor | Numero di versione secondario della costruzione. Definito in src/Build/Version.h.in | 7 |
BuildRevision | Numero di revisione del repositorio SVN del src nella costruzione. Generato da SVN | 356 |
BuildRevisionRange | Gamma di diversi cambiamenti | 123-356 |
BuildRepositoryURL | URL del repositorio | https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk/src |
BuildRevisionDate | Data della revisione precedente | 2007/02/03 22:21:18 |
BuildScrClean | Indica se il codice sorgente è stato modificato dopo il suo checkout | Src modified |
BuildScrMixed | Src not mixed |
Queste voci di configurazione sono legate al meccanismo di marchiatura di FreeCAD. Vedere Marchiatura per maggiori dettagli.
Nome var config | Descrizione | Esempio |
---|---|---|
ExeName | Nome del file di costruzione eseguibile. Può differire da quello di FreeCAD se è utilizzato un diverso main.cpp. | FreeCAD.exe |
ExeVersion | Versione globale mostrata all'inizio | V0.7 |
AppIcon | Icona che viene utilizzata per l'eseguibile, mostrata in Application MainWindow. | "FCIcon" |
ConsoleBanner | Banner che viene mostrato in modalità console | |
SplashPicture | Nome dell'icona utilizzata per la schermata iniziale | "FreeCADSplasher" |
SplashAlignment | Allineamento del testo nella finestra di dialogo iniziale | "Bottom o Left" |
SplashTextColor | Colore del testo iniziale | "#000000" |
StartWorkbench | Nome del Workbench che viene attivato automaticamente dopo l'avvio | "Part design" |
HiddenDockWindow | Elenco dei dockwindows (separati da un punto e virgola) che saranno disabilitati | "Property editor" |
Lo Strumento per la costruzione di FreeCAD (FreeCAD build tool o fcbt) è uno script in Python ubicato in
trunc/src/Tools/fcbt.py
Può essere usato per semplificare alcune frequenti operazioni nella costruzione, distribuzione e estensione di FreeCAD.
Con Python installato correttamente, fcbt può essere richiamato con il comando
python fbct.py
che visualizza un menu, in cui è possibile selezionare l'operazione che si desidera utilizzare per:
FreeCAD Build Tool Usage: fcbt <command name> [command parameter] possible commands are: - DistSrc (DS) Build a source Distr. of the current source tree - DistBin (DB) Build a binary Distr. of the current source tree - DistSetup (DI) Build a Setup Distr. of the current source tree - DistSetup (DUI) Build a User Setup Distr. of the current source tree - DistAll (DA) Run all three above modules - NextBuildNumber (NBN) Increase the Build Number of this Version - CreateModule (CM) Insert a new FreeCAD Module in the module directory For help on the modules type: fcbt <command name> ?
Al prompt inserire il comando abbreviato che si desidera utilizzare. Ad esempio digitare "CM" per creare un modulo.
Il comando "DS" crea una distribuzione di codice sorgente dell'albero di codice sorgente attuale.
Il comando "DB" crea una distribuzione binaria dell'albero di codice sorgente attuale.
Il comando "DI" crea una distribuzione di setup dell'albero di codice sorgente attuale.
Il comando "DUI" crea una distribuzione di setup dell'utente dell'albero di codice sorgente attuale.
Il comando "DA" esegue "DS", "DB" e "DI" in sequenza.
Il comando "NBN" incrementa il numero della costruzione per creare una nuova versione di FreeCAD.
Il comando "CM" crea un nuovo modulo dell'applicazione.
Aggiungere in FreeCAD dei nuovi moduli e dei nuovi ambienti di lavoro è molto facile.
Chiameremo modulo qualsiasi estensione di FreeCAD, invece un ambiente di lavoro (workbench) è una configurazione speciale della GUI che raggruppa alcune barre degli strumenti e dei menu.
Di solito si crea un nuovo modulo che contiene un proprio ambiente di lavoro.
I moduli possono essere programmati in C++ o in Python, o in una miscela di entrambi, ma i file di inizializzazione (init) del modulo devono essere in Python.
Impostare un nuovo modulo con questi file init è facile, e può essere fatto manualmente o con lo Strumento per la costruzione di FreeCAD.
Creare un nuovo modulo dell'applicazione in FreeCAD è piuttosto semplice. Nella struttura di sviluppo FreeCAD esiste lo Strumento per la costruzione di FreeCAD (fcbt) che fa per voi le cose più importanti. Si tratta di uno script Python e si trova in:
trunk/src/Tools/fcbt.py
Quando l'interprete Python è stato installato correttamente è possibile eseguire lo script da una riga di comando con:
python fcbt.py
Viene visualizzato il seguente menu:
FreeCAD Build Tool Usage: fcbt <command name> [command parameter] possible commands are: - DistSrc (DS) Build a source Distr. of the current source tree - DistBin (DB) Build a binary Distr. of the current source tree - DistSetup (DI) Build a Setup Distr. of the current source tree - DistSetup (DUI) Build a User Setup Distr. of the current source tree - DistAll (DA) Run all three above modules - NextBuildNumber (NBN) Increase the Build Number of this Version - CreateModule (CM) Insert a new FreeCAD Module in the module directory - CreatePyModule (CP) Insert a new FreeCAD Python Module in the module directory For help on the modules type: fcbt <command name> ?
Al prompt dei comandi digitare CM per avviare la creazione di un modulo:
Insert command: ''CM''
Ora viene chiesto di specificare un nome per il nuovo modulo. Supponiamo, ad esempio, di chiamarlo TestMod:
Please enter a name for your application: ''TestMod''
Dopo aver premuto Invio fcbt inizia a copiare tutti i file necessari per il nuovo modulo in una nuova cartella in
trunk/src/Mod/TestMod/
Dopo tutti i file vengono modificati con il nome del nuovo modulo. Ora l'unica cosa da fare è aggiungere i due nuovi progetti "appTestMod" e "appTestModGui" al proprio workspace (su Windows) o al proprio makefile targets (unix). Ecco fatto!
Per creare un nuovo modulo servono due cose:
In aggiunta, è anche possibile mettere un file Init.py. La differenza è che il file InitGui.py viene caricato solo quando FreeCAD viene eseguito in modalità GUI mentre il file Init.py viene sempre caricato. Dato che stiamo creando un ambiente di lavoro, lo metteremo in InitGui.py, perché gli ambienti di lavoro, ovviamente, vengono utilizzati solo in modalità GUI.
All'interno del file InitGui.py, una delle prima cosa da fare è quella di definire un ambiente di lavoro. Ecco il codice minimo che è possibile utilizzare:
class MyWorkbench ( Workbench ):
"My workbench object"
Icon = """
/* XPM */
static const char *test_icon[]={
"16 16 2 1",
"a c #000000",
". c None",
"................",
"................",
"..############..",
"..############..",
"..############..",
"......####......",
"......####......",
"......####......",
"......####......",
"......####......",
"......####......",
"......####......",
"......####......",
"......####......",
"................",
"................"};
"""
MenuText = "My Workbench"
ToolTip = "This is my extraordinary workbench"
def GetClassName(self):
return "Gui::PythonWorkbench"
def Initialize(self):
import myModule1, myModule2
self.appendToolbar("My Tools", ["MyCommand1","MyCommand2"])
self.appendMenu("My Tools", ["MyCommand1","MyCommand2"])
Log ("Loading MyModule... done\n")
def Activated(self):
# do something here if needed...
Msg ("MyWorkbench.Activated()\n")
def Deactivated(self):
# do something here if needed...
Msg ("MyWorkbench.Deactivated()\n")
FreeCADGui.addWorkbench(MyWorkbench)
L'ambiente di lavoro deve avere tutti questi attributi definiti:
Di solito si definiscono tutti gli strumenti (chiamati comandi in FreeCAD) in un altro modulo, quindi si importa quel modulo prima di creare le barre degli strumenti e i menu. Questo è il codice minimo che è possibile utilizzare per definire un comando:
import FreeCAD,FreeCADGui
class MyTool:
"My tool object"
def GetResources(self):
return {"MenuText": "My Command",
"Accel": "Ctrl+M",
"ToolTip": "My extraordinary command",
"Pixmap" : """
/* XPM */
static const char *test_icon[]={
"16 16 2 1",
"a c #000000",
". c None",
"................",
"................",
"..############..",
"..############..",
"..############..",
"......####......",
"......####......",
"......####......",
"......####......",
"......####......",
"......####......",
"......####......",
"......####......",
"......####......",
"................",
"................"};
"""}
def IsActive(self):
if FreeCAD.ActiveDocument == None:
return False
else:
return True
def Activated(self):
# do something here...
FreeCADGui.addCommand('MyCommand1',MyTool())
Ancora da documentare.
Prima di provare il debug usare la La struttura di Test (test framework - macro) per verificare se i test standard funzionano correttamente. Se non funzionano, è possibile che l'installazione sia danneggiata.
Il debug di FreeCAD è supportato da alcuni meccanismi interni. La versione a riga di comando di FreeCAD fornisce delle opzioni di supporto del debug:
Queste sono le opzioni attualmente riconosciute in FreeCAD 0.15:
Opzioni generiche:
-v [ --version ] Stampa una stringa della versione -h [ --help ] Stampa un messaggio di aiuto -c [ --console ] Avvia in modalità console --response-file arg Può anche essere specificato con '@name'
Configurazione:
-l [ --write-log ] Scrive un file di log file in: $HOME/.FreeCAD/FreeCAD.log --log-file arg A differenza di --write-log permette di scrivere il file di log in un file arbitrario -u [ --user-cfg ] arg File per caricare/salvare le impostazioni dell'utente -s [ --system-cfg ] arg File per caricare/salvare le impostazioni di sistema -t [ --run-test ] arg Livello di Test -M [ --module-path ] arg Percorsi di moduli aggiuntivi -P [ --python-path ] arg Percorsi aggiuntivi di python
Se si esegue una versione sperimentale di FreeCAD ancora in fase sviluppo, essa potrebbe "bloccarsi". Si può aiutare gli sviluppatori a risolvere questi problemi fornendo loro un "backtrace". Per fare questo, è necessario eseguire un "debug build" del software. "Debug build" è un parametro che viene impostato al momento della compilazione, perciò bisogna auto-compilare FreeCAD, oppure ottenere una versione "debug" precompilata.
Linux Debugging ---->
Prerequisiti:
Passaggi:
Immettere quanto segue nella finestra del terminale:
$ cd FreeCAD/bin $ gdb FreeCAD
GNUdebugger will output some initializing information. The (gdb) shows GNUDebugger is running in the terminal, now input:
(gdb) handle SIG33 noprint nostop (gdb) run
Ora FreeCAD viene avviato. Effettuare le operazioni che causano il crash o il blocco di FreeCAD, quindi immettere 'bt' nella finestra del terminale.
(gdb) bt
Questo genera una lunga lista che descrive esattamente ciò che il programma stava facendo quando è andato in crash o in blocco. Includere questa lista nel vostro rapporto sul problema.
MacOSX Debugging ---->
Prerequisiti:
Passaggi:
Immettere quanto segue nella finestra del terminale:
$ cd FreeCAD/bin $ lldb FreeCAD
LLDB produrrà alcune informazioni di inizializzazione. Il (lldb) mostra che il debugger è in esecuzione nel terminale, ora dare:
(lldb) run
Ora FreeCAD viene avviato. Effettuare le operazioni che causano il crash o il blocco di FreeCAD, quindi immettere 'bt' nella finestra del terminale.
(lldb) bt
Questo genera una lunga lista che descrive esattamente ciò che il programma stava facendo quando è andato in crash o in blocco. Includere questa lista nel vostro rapporto sul problema.
Ecco un esempio di utilizzo di winpdb all'interno di FreeCAD:
import rpdb2
rpdb2.start_embedded_debugger("test")
import FreeCAD
import Part
import Draft
print "hello"
print "hello"
import Draft
points=[FreeCAD.Vector(-3.0,-1.0,0.0),FreeCAD.Vector(-2.0,0.0,0.0)]
Draft.makeWire(points,closed=False,face=False,support=None)
FreeCAD possiede una sua struttura di estensione per le prove. Le prove si basano su un insieme di script Python che si trovano nel modulo test.
Questa è la lista delle applicazioni di test di 0.15 Git 4207:
Add test function
Add test function
Add test function
Add test function
Add test function
Add test function
Add test function
Add test function
Add test function
Add test function
Add test function
Add test function
Add test function
Questo articolo descrive la personalizzazione o Marchiatura di FreeCAD.
Marchiare (Branding) significa avviare la realizzazione di una propria applicazione basata su FreeCAD. La personalizzazione può riguardare solo il proprio eseguibile oppure andare dalla schermata iniziale fino alla rielaborazione completa del programma.
La maggior parte della marchiatura avviene in MainCmd.cpp oppure in MainGui.cpp. Questi Progetti generano i file eseguibili di FreeCAD. Per costruire il proprio marchio è sufficiente copiare i progetti Main o MainGui e dare all'eseguibile un nome diverso, ad esempio, FooApp.exe.
Le impostazioni più importanti per dare all'applicazione un nuovo aspetto possono essere fatte all'interno della funzione main().
Ecco la sezione di codice che controlla la marchiatura:
int main( int argc, char ** argv )
{
// Name and Version of the Application
App::Application::Config()["ExeName"] = "FooApp";
App::Application::Config()["ExeVersion"] = "0.7";
// set the banner (for loging and console)
App::Application::Config()["CopyrightInfo"] = sBanner;
App::Application::Config()["AppIcon"] = "FooAppIcon";
App::Application::Config()["SplashScreen"] = "FooAppSplasher";
App::Application::Config()["StartWorkbench"] = "Part design";
App::Application::Config()["HiddenDockWindow"] = "Property editor";
App::Application::Config()["SplashAlignment" ] = "Bottom|Left";
App::Application::Config()["SplashTextColor" ] = "#000000"; // black
// Inits the Application
App::Application::Config()["RunMode"] = "Gui";
App::Application::init(argc,argv);
Gui::BitmapFactory().addXPM("FooAppSplasher", ( const char** ) splash_screen);
Gui::Application::initApplication();
Gui::Application::runApplication();
App::Application::destruct();
return 0;
}
La prima voce Config definisce il nome del programma. Questo nome non è il nome del file eseguibile, il quale può essere modificato rinominandolo o tramite le impostazioni del compilatore, ma è il nome che viene visualizzato nella barra delle applicazioni di Windows o nell'elenco dei programmi sui sistemi Unix.
Le righe successive definiscono le voci di configurazione della vostra applicazione FooApp. Una descrizione di Config e delle sue voci si trova in Avvio e Configurazione.
In FreeCAD tutte le risorse immagine vengono compilate utilizzando Qt's resource system. Pertanto è necessario scrivere un file .qrc, un file basato sul formato XML, che elenca i file di immagine sul disco, ma anche qualsiasi altro tipo di file di risorse. Per caricare all'interno dell'applicazione le risorse compilate è necessario aggiungere una riga
Q_INIT_RESOURCE(FooApp);
nella funzione main(). In alternativa, se si dispone di un'immagine in formato XPM è possibile includerla direttamente nella propria main.cpp e aggiungere la seguente riga per registrarla:
Gui::BitmapFactory().addXPM("FooAppSplasher", ( const char** ) splash_screen);
In FreeCAD c'è anche un metodo supportato senza scrivere una funzione main() personalizzata. Per questo metodo basta scrivere un file chiamato branding.xml e metterlo nella directory di installazione di FreeCAD. Ecco un esempio con tutti i tag supportati:
<?xml version="1.0" encoding="utf-8"?>
<Branding>
<Application>FooApp</Application>
<WindowTitle>Foo App in title bar</WindowTitle>
<BuildVersionMajor>1</BuildVersionMajor>
<BuildVersionMinor>0</BuildVersionMinor>
<BuildRevision>1234</BuildRevision>
<BuildRevisionDate>2014/1/1</BuildRevisionDate>
<CopyrightInfo>(c) My copyright</CopyrightInfo>
<MaintainerUrl>Foo App URL</MaintainerUrl>
<ProgramLogo>Path to logo (appears in bottom right corner)</ProgramLogo>
<WindowIcon>Path to icon file</WindowIcon>
<ProgramIcons>Path to program icons</ProgramIcons>
<SplashScreen>splashscreen.png</SplashScreen>
<SplashAlignment>Bottom|Left</SplashAlignment>
<SplashTextColor>#ffffff</SplashTextColor>
<SplashInfoColor>#c8c8c8</SplashInfoColor>
<StartWorkbench>PartDesignWorkbench</StartWorkbench>
</Branding>
Tutti i tag elencati sono opzionali.
Localizzazione è in generale il processo che fornisce un software con una interfaccia utente (GUI) multilingua.
In FreeCAD è possibile impostare la lingua dell'interfaccia utente in Modifica → Preferenze → Applicazione.
FreeCAD utilizza Qt per abilitare il supporto di più lingue. Sui sistemi Unix / Linux, FreeCAD utilizza le impostazioni locali di default del sistema.
Una cosa importante che si può fare per FreeCAD, se non si è un programmatore, è quella di contribuire a tradurre il programma nella propria lingua.
Ora, con l'uso di Crowdin , un sistema collaborativo di traduzione on line, contribuire è più facile che mai.
Note: Se si partecipa alla traduzione di FreeCAD, e si desidera essere informati prima della pubblicazione di una prossima versione che è il momento di rivedere la propria traduzione, si prega di iscriversi a: http://www.freecadweb.org/tracker/view.php?id=137
Le seguenti informazioni non devono più essere utilizzate ed è probabile che diventino obsolete.
Sono mantenute qui in modo che i programmatori possano conoscere come funziona. |
Archivio dei file di traduzione disponibili
|
Per realizzare la traduzione del modulo dell'applicazione servono delle utility fornite con Qt. Esse si possono scaricare da Trolltech-Website, ma sono anche contenute in LibPack:
Per iniziare la localizzazione del proprio progetto andare alla GUI-Part del modulo e digitare sulla riga di comando:
qmake -project
Questo esegue la scansione della directory del progetto alla ricerca dei file contenenti stringhe di testo e crea un file di progetto come nel seguente esempio:
###################################################################### # Automatically generated by qmake (1.06c) Do 2. Nov 14:44:21 2006 ###################################################################### TEMPLATE = app DEPENDPATH += .\Icons INCLUDEPATH += . # Input HEADERS += ViewProvider.h Workbench.h SOURCES += AppMyModGui.cpp \ Command.cpp \ ViewProvider.cpp \ Workbench.cpp TRANSLATIONS += MyMod_de.ts
È possibile aggiungere manualmente i file qui. La sezione TRANSLATIONS contiene un elenco di file con la traduzione per ogni lingua. Nell'esempio precedente MyMod_de.ts è la traduzione in tedesco.
Ora è necessario eseguire lupdate per estrarre tutte le stringhe letterali nella propria GUI. Eseguire lupdate dopo le modifiche del codice sorgente è sempre una operazione sicura in quanto non cancella mai stringhe dai file di traduzione. Aggiunge solo le nuove stringhe.
Ora è necessario aggiungere i file .ts al proprio progetto VisualStudio. Specificare per essi il seguente metodo di costruzione personalizzato:
python ..\..\..\Tools\qembed.py "$(InputDir)\$(InputName).ts" "$(InputDir)\$(InputName).h" "$(InputName)"
Nota: Inserire questo comando in un'unica riga, l'interruzione di riga è finalizzata solo alla visualizzazione.
Compilando il file .ts dell'esempio precedente, si crea un file di di intestazione MyMod_de.h. La posizione migliore per memorizzare questo file è App<Modul>Gui.cpp. In questo esempio potrebbe essere AppMyModGui.cpp. Aggiungere lì la riga:
new Gui::LanguageProducer("Deutsch", <Modul>_de_h_data, <Modul>_de_h_len);
per pubblicare la traduzione nell'applicazione.
Per facilitare la localizzazione dei file .py è possibile utilizzare lo strumento pylupdate4 che accetta uno o più file .py. Con l'opzione -ts si può preparare / aggiornare uno o più file .ts. Ad esempio per preparare un file .ts per la traduzione in francese è sufficiente inserire nella riga di comando:
pylupdate4 *.py -ts YourModule_fr.ts
lo strumento pylupdate esegue la scansione dei file .py per le funzioni translate() o tr() e crea un file YourModule_fr.ts. Si può tradurre questo file con QLinguist e produrre il file YourModule_fr.qm con QLinguist o con il comando:
lrelease YourModule_fr.ts
Attenzione che lo strumento pylupdate4 non è molto efficace nel riconoscere le funzioni translate(), esse devono essere formattate in modo molto specifico (vedere come esempio i file del modulo Draft). All'interno del file, è possibile impostare un traduttore come questo (dopo il caricamento delle QApplication però PRIMA di creare qualsiasi widget Qt):
translator = QtCore.QTranslator() translator.load("YourModule_"+languages[ln]) QtGui.QApplication.installTranslator(translator)
Facoltativamente, è possibile anche creare il file XML Draft.qrc con questo contenuto:
<RCC> <qresource prefix="/translations" > <file>Draft_fr.qm</file> </qresource> </RCC>
e eseguire pyrcc4 Draft.qrc -o qrc_Draft.py che crea un grande file Python contenente tutte le risorse. Questo metodo funziona anche per inserire i file di icona in un file di risorse
Questo wiki ospita svariati contenuti. Il materiale più aggiornato e interessante viene raccolto nel manuale.
Quando il Wiki è stato spostato da SourceForge, Yorik ha installato un plugin di traduzione che facilita la traduzione delle pagine. Ad esempio, ora può essere tradotto anche il titolo della pagina. Altri vantaggi del plugin di traduzione sono che tiene traccia delle traduzioni, notifica se la pagina originale è stata aggiornata, e mantiene le traduzioni sincronizzate con la pagina originale inglese.
Lo strumento è documentato in Extension:Translate, ed è parte di Language Extension Bundle.
Per sapere come preparare rapidamente una pagina per la traduzione e attivare il plugin, si prega di leggere Page translation example.
Per vedere un esempio di come funziona lo strumento di traduzione quando il plugin di traduzione è attivo su una pagina, è possibile visitare la Main Page. Verrà visualizzata una nuova barra del menu lingua in basso. Esso viene generato automaticamente. Cliccando, per esempio, sul link tedesco, si apre la pagina Main Page/de. Immediatamente sotto al titolo, è possibile leggere "This page is a translated version of a page Main Page and the translation is xx% complete." "Questa pagina è una versione tradotta di Main Page e la traduzione è xx% completa." (xx è la percentuale attuale di traduzione). Cliccare sul link "Translate this page" per avviare la traduzione, o per aggiornare o correggere la traduzione esistente.
Noterete che quando la pagina è stata contrassegnata per la traduzione non è possibile modificarla direttamente, ma che si deve passare attraverso l'utility di traduzione.
Quando si aggiungono nuovi contenuti, prima deve essere creata la pagina inglese, e poi la pagina inglese può essere tradotta in un'altra lingua. Se qualcuno vuole cambiare o aggiungere dei contenuti in una pagina esistente, deve farlo nella pagina inglese, marcarla per la traduzione e poi tradurre i contenuti editati.
È necessario avere una conoscenza di base sulla formattazione dello stile wiki e sulle linee guida generali del wiki di FreeCAD, perché durante la traduzione bisogna sapere cosa fare con alcuni tag. Potete trovare queste informazioni in WikiPages.
Anche la barra laterale (il menu di navigazione a sinistra) è traducibile. Si prega di seguire le istruzioni dedicate a questo nella pagina Localisation Sidebar.
NOTA: La prima volta che una pagina viene passata al nuovo sistema di traduzione perde tutte le sue vecchie traduzioni "manuali". Per recuperare le traduzioni, è necessario aprire una versione precedente dalla cronologia (pulsante History), e fare manualmente il copia/incolla dei precedenti paragrafi nel nuovo sistema di traduzione.
Nota: ovviamente, per poter tradurre nel wiki, è necessario richiedere l'autorizzazione.
Se non siete sicuri su come procedere, non esitate a chiedere aiuto nel forum.
Queste istruzioni sono solo un background storico, mentre le pagine vengono passate al nuovo plugin di traduzione. |
Quindi il primo passo è controllare se è già stato avviata la traduzione del manuale per la propria lingua (cercare nella barra laterale sinistra, sotto "manual").
Convenzioni sui nomi delle pagine
#REDIRECT [[About FreeCAD/fr]]
{{docnav/fr|Bienvenue sur l'aide en ligne|Fonctionnalités}} La pagina "Bienvenue sur l'aide en ligne" reindirizza a Online Help Startpage/fr, e la pagina "Fonctionnalités" reindirizza a Feature list/fr. |
Questa pagina elenca alcuni moduli Python aggiuntivi o altre parti di software che possono essere scaricati gratuitamente da internet, e che aggiungono funzionalità alla vostra installazione FreeCAD.
PySide (precedentemente PyQt) è richiesto da diversi moduli di FreeCAD per accedere all'interfaccia Qt di FreeCAD. È già incluso nella versione per windows di FreeCAD, e di solito su Linux è installato automaticamente da FreeCAD quando l'installazione viene fatta dai repository ufficiali. Se i moduli Draft, Arch, ecc. sono abilitati, dopo che FreeCAD è installato, significa che PySide (precedentemente PyQt) è presente e non è più necessario fare nulla.
Note:
In FreeCAD, PyQt4 diventerà progressivamente obsoleto dopo la versione 0.13, a favore di PySide, che fa esattamente lo stesso lavoro, ma ha una licenza (LGPL) più compatibile con FreeCAD.
Il modo più semplice per installare PySide è attraverso il gestore dei pacchetti della propria distribuzione. Su sistemi Debian/Ubuntu, il nome del pacchetto è generalmente python-PySide, mentre per i sistemi basati su RPM viene chiamato pyside. Le dipendenze necessarie (Qt e SIP) si installano automaticamente.
Il programma può essere scaricato da http://qt-project.org/wiki/Category:LanguageBindings::PySide::Downloads. Prima di installare PyQt4 è necessario installare le librerie Qt e SIP (operazioni da documentare).
PyQt può essere installato su Mac tramite homebrew oppure port. Per maggiori informazioni, vedere CompileOnMac/it#Install_Dependencies.
Dopo l'installazione, è possibile verificare che tutto funzioni digitando nella console Python di FreeCAD:
import PySide
Per accedere all'interfaccia di FreeCAD, digitare:
from PySide import QtCore,QtGui FreeCADWindow = FreeCADGui.getMainWindow()
Quindi si può iniziare ad esplorare l'interfaccia con il comando dir(). È possibile aggiungere nuovi elementi, ad esempio un widget personalizzato, con comandi come:
FreeCADWindow.addDockWidget(QtCore.Qt.RghtDockWidgetArea,my_custom_widget)
Lavorare con Unicode
text = text.encode('utf-8')
Lavorare con QFileDialog e OpenFileName :
path = FreeCAD.ConfigGet("AppHomePath") #path = FreeCAD.ConfigGet("UserAppData") OpenName, Filter = PySide.QtGui.QFileDialog.getOpenFileName(None, "Read a txt file", path, "*.txt")
Lavorare con QFileDialog e SaveFileName :
path = FreeCAD.ConfigGet("AppHomePath") #path = FreeCAD.ConfigGet("UserAppData") SaveName, Filter = PySide.QtGui.QFileDialog.getSaveFileName(None, "Save a file txt", path, "*.txt")
Nota: questi sono esempi di errori riscontrati nella transizione da PyQt4 verso PySide con le correzioni che sono state fatte. Con gli esempi precedenti sono certamente possibili altre soluzioni
try: import PyQt4 # PyQt4 from PyQt4 import QtGui ,QtCore # PyQt4 from PyQt4.QtGui import QComboBox # PyQt4 from PyQt4.QtGui import QMessageBox # PyQt4 from PyQt4.QtGui import QTableWidget, QApplication # PyQt4 from PyQt4.QtGui import * # PyQt4 from PyQt4.QtCore import * # PyQt4 except Exception: import PySide # PySide from PySide import QtGui ,QtCore # PySide from PySide.QtGui import QComboBox # PySide from PySide.QtGui import QMessageBox # PySide from PySide.QtGui import QTableWidget, QApplication # PySide from PySide.QtGui import * # PySide from PySide.QtCore import * # PySide
Per accedere all'interfaccia di FreeCAD, digitare:
è possibile aggiungere nuovi elementi, come un widget personalizzato, con comandi come:
myNewFreeCADWidget = QtGui.QDockWidget() # create a new dockwidget myNewFreeCADWidget.ui = Ui_MainWindow() # myWidget_Ui() # load the Ui script myNewFreeCADWidget.ui.setupUi(myNewFreeCADWidget) # setup the ui try: app = QtGui.qApp # PyQt4 # the active qt window, = the freecad window since we are inside it FCmw = app.activeWindow() # PyQt4 # the active qt window, = the freecad window since we are inside it FCmw.addDockWidget(QtCore.Qt.RightDockWidgetArea,myNewFreeCADWidget) # add the widget to the main window except Exception: FCmw = FreeCADGui.getMainWindow() # PySide # the active qt window, = the freecad window since we are inside it FCmw.addDockWidget(QtCore.Qt.RightDockWidgetArea,myNewFreeCADWidget) # add the widget to the main window
Lavorare con Unicode
try: text = unicode(text, 'ISO-8859-1').encode('UTF-8') # PyQt4 except Exception: text = text.encode('utf-8') # PySide
Lavorare con QFileDialog e OpenFileName :
OpenName = "" try: OpenName = QFileDialog.getOpenFileName(None,QString.fromLocal8Bit("Lire un fichier FCInfo ou txt"),path,"*.FCInfo *.txt") # PyQt4 except Exception: OpenName, Filter = PySide.QtGui.QFileDialog.getOpenFileName(None, "Lire un fichier FCInfo ou txt", path, "*.FCInfo *.txt")#PySide
Lavorare con QFileDialog e SaveFileName :
SaveName = "" try: SaveName = QFileDialog.getSaveFileName(None,QString.fromLocal8Bit("Sauver un fichier FCInfo"),path,"*.FCInfo") # PyQt4 except Exception: SaveName, Filter = PySide.QtGui.QFileDialog.getSaveFileName(None, "Sauver un fichier FCInfo", path, "*.FCInfo")# PySide
Il MessageBox:
def errorDialog(msg): diag = QtGui.QMessageBox(QtGui.QMessageBox.Critical,u"Error Message",msg ) try: diag.setWindowFlags(PyQt4.QtCore.Qt.WindowStaysOnTopHint) # PyQt4 # this function sets the window before except Exception: diag.setWindowFlags(PySide.QtCore.Qt.WindowStaysOnTopHint)# PySide # this function sets the window before # diag.setWindowModality(QtCore.Qt.ApplicationModal) # function has been disabled to promote "WindowStaysOnTopHint" diag.exec_()
Lavorare con setProperty (PyQt4) e setValue (PySide)
self.doubleSpinBox.setProperty("value", 10.0) # PyQt4
sostituire con:
self.doubleSpinBox.setValue(10.0) # PySide
Lavorare con setToolTip
self.doubleSpinBox.setToolTip(_translate("MainWindow", "Coordinate placement Axis Y", None)) # PyQt4
sostituire con:
self.doubleSpinBox.setToolTip(_fromUtf8("Coordinate placement Axis Y")) # PySide
oppure:
self.doubleSpinBox.setToolTip(u"Coordinate placement Axis Y.")# PySide
Ecco alcuni tutorial di PyQt4 (che spiegano come costruire interfacce con Qt Designer da utilizzare con Python):
Pivy serve a alcuni moduli per accedere alla visualizzazione 3D di FreeCAD. Su Windows, Pivy è già in impacchettato nel programma di installazione FreeCAD, e su Linux solitamente è installato automaticamente quando si installa FreeCAD da un repository ufficiale. Su MacOSX, purtroppo, è necessario compilare pivy da soli.
Credo che prima di compilare Pivy si desideri avere Coin e SoQt installati.
Per compilarlo su Mac è sufficiente installare il pacchetto binario Coin3 . Il tentativo di installare Coin da MacPorts è stato problematico: ha cercato di aggiungere un sacco di pacchetti di X Windows e alla fine il tentativo è fallito con un errore di script.
Per Fedora ho trovato un RPM con Coin3
SoQt compilato da codice sorgente funziona bene su Mac e Linux.
A partire da Debian Squeeze e Ubuntu Lucid, Pivy sarà disponibile direttamente dai repository ufficiali e questo eviterà un sacco di problemi.
Nel frattempo, è possibile scaricare uno dei pacchetti che abbiamo creato (per Debian e Ubuntu Karmic) e disponibili nelle pagine Download, o compilarlo da soli.
Il modo migliore per compilare facilmente Pivy è quello di prendere il pacchetto sorgente di Debian per Pivy e creare un pacchetto con debuild.
È lo stesso codice sorgente dal sito ufficiale di Pivy, ma la comunità di Debian vi ha fatto diverse aggiunte bug-fixing.
Si compila bene anche su Ubuntu Karmic: http://packages.debian.org/squeeze/python-pivy . Scaricare i file .orig.gz e .diff.gz, poi decomprimerli entrambi, quindi applicare .diff al codice sorgente: andare nella cartella del codice sorgente decompresso di Pivy, e applicare la patch .diff:
patch -p1 < ../pivy_0.5.0~svn765-2.diff
poi
debuild
per avere Pivy correttamente costruito in un pacchetto ufficiale installabile. Dopo è sufficiente installare il pacchetto con gdebi.
Prima di tutto scaricare gli ultimi sorgenti dai repository del progetto:
hg clone http://hg.sim.no/Pivy/default Pivy
A partire dal marzo 2012, l'ultima versione è Pivy-0.5.
In seguito serve uno strumento chiamato SWIG per generare il codice C++ per i binding di Python. Pivy-0.5 segnala che è stato testato solo con SWIG 1.3.31, 1.3.33, 1.3.35 e 1.3.40. Perciò si può scaricare un tarball del codice sorgente di una di queste vecchie versioni da http://www.swig.org. Poi scompattarlo e da una riga di comando fare (come root):
./configure make make install (or checkinstall if you use it)
Impiega appena pochi secondi per costruirsi.
In alternativa, si può provare la costruzione con un SWIG più recente. A partire dal marzo 2012 la versione tipica del repository è la 2.0.4. Pivy presenta un piccolo problema di compilazione con SWIG 2.0.4 su Mac OS (vedere sotto), mentre pare si costruisca bene su Fedora Core 15.
Dopo le operazioni precedenti andare nel sorgente di Pivy e eseguire:
python setup.py build
per creare i file sorgente. Notare che la generazione può produrre migliaia di avvisi, ma fortunatamente non ci sono errori.
Questo è probabilmente obsoleto, ma si può incorrere in un errore di compilazione in cui una 'const char*' non può essere convertita in una 'char*'. Per risolvere il problema basta scrivere una 'const' prima nelle righe appropriate. Si devono correggere sei righe.
Dopo di che, installare digitando (come root):
python setup.py install (or checkinstall python setup.py install)
Questo è tutto. Pivy è installato.
Queste istruzioni potrebbero non essere complete. Qualcosa di simile a questo ha funzionato per OS 10,7 dopo marzo 2012. Io uso MacPorts come repository, ma dovrebbero funzionare anche le altre opzioni.
Per quanto riguarda Linux, scaricare l'ultimo codice sorgente:
hg clone http://hg.sim.no/Pivy/default Pivy
Se non si dispone di hg, è possibile ottenerlo da MacPorts:
port install mercurial
Poi, come prima, è necessario SWIG. Si tratta di fare:
port install swig
Ho scoperto che avevo bisogno anche di:
port install swig-python
Da marzo 2012, la versione di SWIG in MacPorts è la 2.0.4. Come detto in precedenza per Linux, potrebbe essere meglio scaricare una versione precedente. SWIG 2.0.4 sembra avere un bug che blocca la costruzione di Pivy. Vedere il primo messaggio in questa raccolta: https://sourceforge.net/mailarchive/message.php?msg_id=28114815
Questo problema può essere corretto modificando i 2 percorsi del codice sorgente per aggiungere dereferenziazioni: arg4 *, * arg5 al posto di arg4, arg5. Ora si può costruire Pivy:
python setup.py build sudo python setup.py install
Supponendo di utilizzare Visual Studio 2005 o versioni successive è necessario aprire un prompt dei comandi con 'Visual Studio 2005 Command prompt' dal menu Strumenti. Se l'interprete Python non è ancora nel percorso di sistema fare:
set PATH=path_to_python_2.5;%PATH%
Per avere pivy funzionante si devono scaricare gli ultimi sorgenti dal repository del progetto:
svn co https://svn.coin3d.org/repos/Pivy/trunk Pivy
Dopo serve lo strumento chiamato SWIG per generare il codice C++ per i binding con Python. Si raccomanda di utilizzare la versione 1.3.25 di SWIG, non l'ultima versione, perché al momento pivy funziona correttamente solo con la 1.3.25. Scaricare i file binari per 1.3.25 da http://www.swig.org. Poi scompattarli e dalla riga di comando aggiungerli al percorso di sistema
set PATH=path_to_swig_1.3.25;%PATH%
e impostare il percorso appropriato per COINDIR
set COINDIR=path_to_coin
Su Windows il file di configurazione di pivy si aspetta SoWin invece di SoQt come predefinito. Non ho trovato un modo valido per costruirlo con SoQt, così ho modificato direttamente il file setup.py. Nella riga 200 è sufficiente rimuovere la parte 'sowin': ('gui._sowin', 'sowin-config', 'Pivy.gui.') (non rimuovere le parentesi di chiusura).
Successivamente andare nel sorgente di pivy e eseguire:
python setup.py build
per creare i file sorgente. Si può incorrere nell'errore di compilazione 'header files couldn't be found' (file di intestazione non trovati). In questo caso, impostare la variabile INCLUDE
set INCLUDE=%INCLUDE%;path_to_coin_include_dir
e, se le intestazioni di SoQt non sono nella stessa posizione delle intestazioni di Coin, impostare anche
set INCLUDE=%INCLUDE%;path_to_soqt_include_dir
e infine impostare le intestazioni di Qt
set INCLUDE=%INCLUDE%;path_to_qt4\include\Qt
Se si utilizza la versione Express Edition di Visual Studio è possibile ottenere un'eccezione di errore di chiave di Python (KeyError). In questo caso è necessario modificare alcune cose in msvccompiler.py situato nella propria installazione di Python.
Andare alla riga 122 e sostituire la riga
vsbase = r"Software\Microsoft\VisualStudio\%0.1f" % version
con
vsbase = r"Software\Microsoft\VCExpress\%0.1f" % version
Riprovare di nuovo. Se si ottiene un secondo errore del tipo
error: Python was built with Visual Studio 2003;...
è necessario sostituire anche la riga 128
self.set_macro("FrameworkSDKDir", net, "sdkinstallrootv1.1")
con
self.set_macro("FrameworkSDKDir", net, "sdkinstallrootv2.0")
Riprovare ancora una volta. Se si ottiene di nuovo un errore quale
error: Python was built with Visual Studio version 8.0, and extensions need to be built with the same version of the compiler, but it isn't installed.
allora si deve controllare le variabili d'ambiente DISTUTILS_USE_SDK e MSSDK con
echo %DISTUTILS_USE_SDK% echo %MSSDK%
Se non sono ancora impostate basta impostarle, ad esempio, a 1
set DISTUTILS_USE_SDK=1 set MSSDK=1
Ora, si può incorrere in un errore di compilazione in cui una 'const char *' non può essere convertita in una 'char *'. Per risolvere il problema basta scrivere una 'const' prima nelle righe appropriate. Ci sono sei righe da correggere.
Infine, copiare la directory di pivy generata in un posto dove l'interprete di Python di FreeCAD possa trovarla.
Per verificare se Pivy è installato correttamente:
import pivy
Per consentire a Pivy di accedere al grafo di scena (Scenegraph) di FreeCAD effettuare le seguenti operazioni:
from pivy import coin App.newDocument() # Open a document and a view view = Gui.ActiveDocument.ActiveView FCSceneGraph = view.getSceneGraph() # returns a pivy Python object that holds a SoSeparator, the main "container" of the Coin scenegraph FCSceneGraph.addChild(coin.SoCube()) # add a box to scene
Ora è possibile esplorare FCSceneGraph con il comando dir().
Purtroppo in rete la documentazione su Pivy è ancora quasi inesistente. Ma può essere utile la documentazione di Coin, in quanto Pivy semplicemente traduce le funzioni di Coin, i nodi e i metodi in Python, tutto mantiene lo stesso nome e le stesse proprietà, tenendo presente la differenza di sintassi tra C e Python:
Potete anche esplorare il file Draft.py nella cartella Mod/Draft di FreeCAD, dato che che in esso si fa un grande uso di pivy.
pyCollada è una libreria di Python che permette ai programmi di leggere e di scrivere i file di Collada (*.DAE). Quando pyCollada è installato sul sistema, FreeCAD lo rileva e aggiunge le opzioni di importazione e di esportazione per gestire l'apertura e il salvataggio di file nel formato Collada.
Pycollada in genere non è ancora disponibile nei repository delle distribuzioni Linux, ma dato che è composto solo di file Python, non richiede la compilazione, ed è facile da installare. Si può installare in 2 modi, o direttamente dal repository git ufficiale di pycollada, o con lo strumento easy_install.
In entrambi i casi, è necessario che nel sistema siano già installati i seguenti pacchetti:
python-lxml python-numpy python-dateutil
git clone git://github.com/pycollada/pycollada.git pycollada cd pycollada sudo python setup.py install
Supponendo di avere già una installazione completa di Python, l'utilità easy_install dovrebbe essere già presente:
easy_install pycollada
Si può controllare se pycollada è stato installato correttamente digitando in una console python:
import collada
Se non viene restituito nulla (nessun messaggio di errore), allora tutto è OK
Su Windows, dalla versione 0.15, pycollada è incluso in FreeCAD sia nella versione di rilascio che in quella di sviluppo quindi non sono più necessari ulteriori passaggi.
Se si utilizza la build Homebrew di FreeCAD è possibile installare pycollada nel proprio sistema Python utilizzando pip.
Se è necessario installare pip:
$ sudo easy_install pip
Installare pycollada:
$ sudo pip install pycollada
Se si utilizza una versione binaria di FreeCAD, si può dire a pip di installare pycollada all'interno di FreeCAD.app:
$ pip install --target="/Applications/FreeCAD.app/Contents/lib/python2.7/site-packages" pycollada
or after downloading the pycollada code
$ export PYTHONPATH=/Applications/FreeCAD\ 0.16.6706.app/Contents/lib/python2.7/site-packages:$PYTHONPATH $ python setup.py install --prefix=/Applications/FreeCAD\ 0.16.6706.app/Contents
IFCOpenShell è una libreria attualmente in fase di sviluppo, che permette di importare (e presto di esportare) file Industry foundation Classes (*.IFC). IFC è una estensione per il formato STEP, e sta diventando lo standard nei processi di lavoro BIM. Quando ifcopenshell è installato correttamente nel vostro sistema, il modulo Arch di FreeCAD è grado di rilevarlo e usarlo per importare i file IFC. Poiché ifcopenshell si basa su OpenCascade, come FreeCAD, la qualità della importazione è molto buona, producendo geometria solida di alta qualità.
Dato che ifcopenshell è abbastanza recente, dovrete probabilmente compilarla da soli.
Per compilare ifcopenshell serve che sul sistema siano installati un paio di pacchetti di sviluppo:
liboce-*-dev python-dev swig
ma dato che anche FreeCAD richiede tutti questi pacchetti, se è possibile compilare FreeCAD, non serve alcun dipendenza in più per compilare IfcOpenShell.
Prelevare l'ultimo codice sorgente da:
git clone https://github.com/IfcOpenShell/IfcOpenShell.git
Il processo di costruzione è molto semplice:
mkdir ifcopenshell-build cd ifcopenshell-build cmake ../IfcOpenShell/cmake
o, se si utilizza Oce invece di OpenCascade:
cmake -DOCC_INCLUDE_DIR=/usr/include/oce ../ifcopenshell/cmake
Siccome ifcopenshell è fatto principalmente per Blender, utilizza python3 di impostazione predefinita. Per usarlo dentro FreeCAD, è necessario compilarlo contro la stessa versione di Python che viene utilizzata da FreeCAD. Quindi potrebbe essere necessario forzare la versione di Python con parametri aggiuntivi cmake (adattare per la vostra versione di Python):
cmake -DOCC_INCLUDE_DIR=/usr/include/oce -DPYTHON_INCLUDE_DIR=/usr/include/python2.7 -DPYTHON_LIBRARY=/usr/lib/python2.7.so ../ifcopenshell/cmake
Poi:
make sudo make install
Si può controllare se ifcopenshell è stato installato correttamente digitando in una console python:
import ifcopenshell
Se non viene restituito nulla (nessun messaggio di errore), allora tutto è OK
Copiato dal file README di IfcOpenShell
Users are advised to use the Visual Studio .sln file in the win/ folder. For Windows users a prebuilt Open CASCADE version is available from the http://opencascade.org website. Download and install this version and provide the paths to the Open CASCADE header and library files to MS Visual Studio C++.
For building the IfcPython wrapper, SWIG needs to be installed. Please download the latest swigwin version from http://www.swig.org/download.html . After extracting the .zip file, please add the extracted folder to the PATH environment variable. Python needs to be installed, please provide the include and library paths to Visual Studio.
Tutorial Importare e Esportare IFC - compilare IfcOpenShell
Il convertitore Teigha è una piccola utility liberamente disponibile che consente di convertire tra diverse versioni i file DWG e DXF. FreeCAD può usarlo per offrire l'importazione e l'esportazione dei file DWG, convertendo prima i formati DWG in DXF al suo interno, e poi importando il contenuto dei file tramite il suo importatore DXF standard. Si applicano le restrizioni di importazione di DXF.
Su tutte le piattaforme, basta installare il pacchetto appropriato da https://www.opendesign.com/guestfiles/teigha_file_converter . Se, dopo l'installazione, l'utility non viene trovata automaticamente da FreeCAD, può essere necessario impostare manualmente il percorso del file eseguibile del converter. Attivare l'ambiente Draft, poi nelle opzioni del menu Modifica -> Preferenze -> Draft -> Importa/Esporta ->DWG compilare il campo "Path to Teigha File Converter" con il corretto percorso.
<translate> FreeCAD would not be what it is without the generous contributions of many people. Here's an overview of the people and companies who contributed to FreeCAD over time. For credits for the third party libraries see the Third Party Libraries page.
Lead developers of the FreeCAD project: </translate>
<translate>
People who work regularly on the FreeCAD code (retrieved from https://github.com/FreeCAD/FreeCAD/graphs/contributors): </translate>
<translate>
Other people who contributed code to the FreeCAD project: </translate>
<translate>
Companies which donated code or developer time: </translate>
<translate>
People in charge of the FreeCAD forum (retrieved from http://forum.freecadweb.org/memberlist.php?mode=team): </translate>
<translate>
People from the community who put a lot of efforts in helping the FreeCAD project either by being active on the forum, keeping a blog about FreeCAD, making video tutorials, packaging FreeCAD for Windows/Linux/MacOS X, writing a FreeCAD book... (listed by alphabetical order) (retrieved from http://forum.freecadweb.org/memberlist.php?mode=&sk=d&sd=d#memberlist) </translate>
<translate>
People who wrote the documentation on this wiki: </translate>
<translate>
People who helped to translate the FreeCAD application (retrieved from https://crowdin.com/project/freecad): </translate>
<translate>
Developers of FreeCAD addons (retrieved from https://github.com/FreeCAD/FreeCAD-addons): </translate>
<translate> </translate>