~~NOCACHE~~
====== Format DXF : expérimentations ======
Cette page regroupe des informations sur tout ce qui touche au format DXF dans QElectroTech. Pour le moment, cela se cantonne aux expérimentations en vue de l'implémentation de l'export DXF.
  * Comment lire un DXF sous GNU/Linux ? Le plus simple est d'utiliser QCad
  * Quelle bibliothèque sera utilisée pour manipuler ce format ?
    * Bien que la libqcad contienne sans doute déjà de quoi interfacer une QGraphicsScene et un fichier DXF, le projet QET ne souhaite pas dépendre de cette bibliothèque
    * 20/03/2011 : bemol : la dxflib va bientôt être packagée à part : http://ftp-master.debian.org/new/dxflib_2.2.0.0-1.html
    * la [[http://www.coin3d.org/lib/dime|libdime]], bibliothèque C++ portable centrée sur le DXF, paraît plus adaptée
    * GNU LibreDWG est une librairie logicielle écrite en C pour la lecture et l'écriture de fichiers au format DWG, avec l'objectif à terme de remplacer les bibliothèques du groupe Open Design Alliance. [[http://www.gnu.org/software/libredwg/]]
===== Bibliothèque dime : Programme de test =====
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
/**
	Ce programme de test genere un fichier test.dxf comportant un cercle sur un
	calque.
	Paquets necessaires : libdime, libdime-dev
	Compile avec :
	gcc testdxf0.cpp -o testdxf0 -lstdc++ -ldime
*/
using namespace std;
namespace TestDXF {
	void testColor(int);
}
int main(int /*argc*/, char **/*argv*/) {
	
	const string dxf_file = "dxftest.dxf";
	
	cout << "generation d'un fichier DXF" << endl;
	// modele
	dimeModel dxf_model;
	dxf_model.init();
	
	// section TABLES
	dimeLayerTable *circle_layer_table_entry = new dimeLayerTable();
	circle_layer_table_entry -> setLayerName("circle", NULL);
	circle_layer_table_entry -> setColorNumber(125);
	
	dimeTable *layer_tables = new dimeTable(NULL);
	layer_tables -> insertTableEntry(circle_layer_table_entry);
	
	dimeTablesSection *tables_section = new dimeTablesSection();
	tables_section -> insertTable(layer_tables);
	dxf_model.insertSection(tables_section);
	
	// cercle
	dimeCircle *dxf_circle = new dimeCircle();
	dxf_circle -> setCenter(dimeVec3f(0.0, 0.0, 0.0));
	dxf_circle -> setRadius(1.0);
	dxf_circle -> setThickness(0.1);
	
	const dimeLayer *circle_layer_ptr = dxf_model.addLayer("circle");
	if (circle_layer_ptr != NULL) {
		dxf_circle -> setLayer(circle_layer_ptr);
	} else {
		cout << "layer circle non cree" << endl;
	}
	
	// section ENTITIES
	dimeEntitiesSection *entities_section = new dimeEntitiesSection();
	dxf_model.insertSection(entities_section);
	entities_section -> insertEntity(dxf_circle);
	
	// objet dimeOutput pour l'export vers un fichier
	dimeOutput dxf_output;
	dxf_output.setFilename(dxf_file.c_str());
	
	// ecriture du fichier
	dxf_model.write(&dxf_output);
	
	//TestDXF::testColor(125);
	
	return(0);
}
void TestDXF::testColor(int test_color) {
	dxfdouble r = 0.0, g = 0.0, b = 0.0;
	dimeLayer::colorToRGB(test_color, r, g, b);
	r *= 255, g *= 255, b *= 255;
	cout << test_color << " => (" << (int)r << ", " <<  (int)g << ", " <<  (int)b << ")" << endl;
}
Questions et remarques :
  * Ce format semble utiliser des couleurs sur 16 bits ; la bibliothèque Dime fournit une fonction statique dimeLayer::colorToRGB pour passer d'un entier 16 bits à 3 flottants RVB ; la fonction TestDXF::testColor du programme ci-dessus utilise dimeLayer::colorToRGB pour afficher les valeurs RVB d'un entier. Comment obtenir cet entier à partir des trois valeurs RVB ?
  * La documentation de certaines classes de la bibliothèque Dime stipule qu'elles ne doivent jamais être allouées sur la pile, sous-entendant que d'autres classes les supprime après usage => bien étudier cette gestion des objets, le programme ci-dessus comporte peut-être des fuites mémoires.
  * Il faudra s'assurer que la libdime est packagée sous Mandriva et Slackware. Il s'agit très clairement d'une dépendance supplémentaire pour QET.
===== Bibliothèque Qt : rendre une QGraphicsScene en DXF =====
D'après la documentation Qt, pour ajouter la possibilité de faire un rendu DXF à l'instar du support SVG, il faut ajouter deux classes :
  * une classe dérivant de QPaintDevice dont il faudra implémenter au moins la méthode virtual QPaintEngine * paintEngine () const = 0
  * une classe dérivant de QPaintEngine, qui fera le rendu DXF à partir de primitives :
    * drawEllipse
    * drawImage
    * drawLines
    * drawPath
    * drawPixmap
    * drawPoints
    * drawPolygon
    * drawRects
    * drawTextItem
    * drawTiledPixmap
Avantage : très propre : les primitives utilisées pour les éléments sont dessinées exclusivement via QPainter, sans se soucier de la cible : écran (QGraphicsView), imprimante (physique/PDF/PS), image vectorielle (SVG/DXF), image bitmap (BMP/PNG/JPEG/...), ...
Inconvénient : assez compliqué car exhaustif. Il n'est toutefois pas exclu de n'implémenter que les primitives qui nous intéressent.
====import dxf to elmt====
inkscape -E intermediate.eps infile.svg
pstoedit -dt -f dxf:-polyaslines intermediate.eps outfile.dxf
./convert_dxf_elmt.py
====export dxf ====
 Il est possible de convertir des exports de Qet format svg en dxf sois avec
    * autotrace
    * inkscape
autotrace = le fichier est bien converti au format DXF mais le résultât n'est pas convaincant au vu des premiers essais 
autotrace fichier Qet.png -output-file output.dxf
{{:doc:export_dxf.png?200|}}{{:doc:export_dxf2.png?200|}}
inkscape s'en sort mieux et le resultat est presque exploitable 
{{:doc:export_dxf3_inkscape.png?200|}}{{:doc:export_dxf4_inkscape.png?200|}}