/* Programme qui génère du OpenScad. L'idée est d'écrire du OpenScad en C++ En OpenScad, on crée un module qui génère un objet. En C++, on génère une classe qui décrit un objet. La classe non seulement peut générer le code OpenScad pour créer a forme 3D de l'objet, mais peut aussi fournir d'autres informations sur l'objet par exemple, certaines coordonnées dans l'objet (position de certains connecteurs). */ #include #include #include #include #include #include #include using namespace std; #include "openscadcpp.h" // Objets class ECHANGEUR: public COOROBJ, public SCAD_COMMON{ public: static const int width=100; static const int len=300; const int height=50; const int conray=15; const int conheight=20; enum class ID{in1,in2,out1,out2}; void print() const; void showconnect() const; COOR getcoor(ID id) const; }; void ECHANGEUR::print() const { tab(); cube(width,len,height); tab(); translate(getcoor(ID::in1)); translate(0,0,-conheight); cylinder(conray,conheight,40); tab(); translate(getcoor(ID::in2)); translate(0,0,-conheight); cylinder(conray,conheight,40); tab(); translate(getcoor(ID::out1)); translate(0,0,-conheight); cylinder(conray,conheight,40); tab(); translate(getcoor(ID::out2)); translate(0,0,-conheight); cylinder(conray,conheight,40); } void ECHANGEUR::showconnect() const { color("green"); printconnect(getcoor(ID::in1)); printconnect(getcoor(ID::in2)); color("blue"); printconnect(getcoor(ID::out1)); printconnect(getcoor(ID::out2)); } ECHANGEUR::COOR ECHANGEUR::getcoor(ID id) const { COOR ret; ret.z = height+conheight; switch(id){ case ID::in1: ret.x = width/4; ret.y = len/6; break; case ID::in2: ret.x = 3*width/4; ret.y = 5*len/6; break; case ID::out1: ret.x = width/4; ret.y = 5*len/6; break; case ID::out2: ret.x = 3*width/4; ret.y = len/6; break; } return ret; } class POMPE: public COOROBJ, public SCAD_COMMON{ public: using COOR = COOROBJ::COORSUBCUR; const int depth=100; const int ray=50; static const int outray=25; const int outlen = 25; const int width = 2*ray+2*outlen; enum class ID{in,out}; void print() const; void showconnect() const; COOR getcoor(ID id) const; }; void POMPE::print() const { tab(); color("red"); openbrace(); // Moteur tab(2); translate(outray,0,ray+outray); printf ("rotate([0,90,0]) "); cylinder(ray,depth,200); // Pompe tab(2); translate(-outray,0,ray+outray); printf ("rotate([0,90,0]) "); cylinder(ray+10,2*outray,200); // Tube in out tab(2); translate(0,width/2,outray); printf ("rotate([90,0,0]) "); cylinder(outray,width,80); tab();closebrace(); } void POMPE::showconnect() const { color("red"); printconnect(getcoor(ID::in)); color("blue"); printconnect(getcoor(ID::out)); } POMPE::COOR POMPE::getcoor(ID id) const { COOR ret; ret.cur.z = outray; switch(id){ case ID::out: ret.sub.angle_x = -90; ret.cur.y = width/2; break; case ID::in: ret.sub.angle_x = 90; ret.cur.y = -width/2; break; } return ret; } // Connecteur en T class TCON: public COOROBJ, public SCAD_COMMON{ public: using COOR = COOROBJ::COORSUBCUR; const int len=50; static const int ray=(3*25/4)/2; // 3/4 pouces const int width = 2*len; enum class ID{in,out,top}; void print() const; void showconnect() const; COOR getcoor(ID id) const; }; void TCON::print() const { tab(); color("lightgray"); openbrace(); // Tube horizontal tab(2); translate(0,-width/2,ray); printf ("rotate([-90,0,0]) "); cylinder(ray,width,80); // Tube vertical tab(2); translate(0,0,2*ray); cylinder(ray,len,80); tab();closebrace(); } void TCON::showconnect() const { printconnect(getcoor(ID::in)); printconnect(getcoor(ID::out)); printconnect(getcoor(ID::top)); } TCON::COOR TCON::getcoor(ID id) const { COOR ret; ret.cur.z = ray; switch(id){ case ID::in: ret.sub.angle_x = -90; ret.cur.y = width/2; break; case ID::out: ret.sub.angle_x = 90; ret.cur.y = -width/2; break; case ID::top: ret.cur.z = 2*ray+len; break; } return ret; } constexpr double ray_3_4 = (3.0*25/4)/2; constexpr double ray_1_5 = (3.0*25/2)/2; // Coude 1.5 pouces class COUDE: public COOROBJ, public SCAD_COMMON{ public: using COOR = COOROBJ::COORSUBCUR; const int len=4*25; static constexpr double ray=ray_1_5+4; // 1.5 pouces + 4mm const int width = 2*len; enum class ID{in,out}; void print() const; void showconnect() const; COOR getcoor(ID id) const; }; void COUDE::print() const { tab(); color("white"); openbrace(); // Tube horizontal tab(2); translate(0,0,ray+10); printf ("rotate([-90,0,0]) "); cylinder(ray,len,80); // Tube vertical tab(2); translate(0,0,0); cylinder(ray,len,80); tab();closebrace(); } void COUDE::showconnect() const { printconnect(getcoor(ID::in)); printconnect(getcoor(ID::out)); } COUDE::COOR COUDE::getcoor(ID id) const { COOR ret; switch(id){ case ID::in: ret.cur.z = len; break; case ID::out: ret.sub.angle_x = -90; ret.cur.z = ray+10; ret.cur.y = len; break; } return ret; } // CUVE class CUVE: public COOROBJ, public SCAD_COMMON{ public: using COOR = COOROBJ::COORSUBCUR; static const int len=24*25; static const int depth = 280; static const int height = 370; enum class ID{in,out}; void print() const; void showconnect() const; COOR getcoor(ID id) const; }; void CUVE::print() const { tab(); color("silver"); openbrace(); tab(2); difference(); tab(3); cube(depth,len,height); tab(3); scad_union(); tab(4); translate(2,2,2); cube(depth-4,len-4,height); tab(4); translate(depth/4,len-10,height-30); cube(depth/2,20,height); tab(3); closebrace(); tab(2);closebrace(); tab();closebrace(); } void CUVE::showconnect() const { printconnect(getcoor(ID::in)); printconnect(getcoor(ID::out)); } CUVE::COOR CUVE::getcoor(ID id) const { COOR ret; switch(id){ case ID::in: ret.sub.angle_x = 90; ret.cur.x = depth/2; ret.cur.y = 0; ret.cur.z = 20; break; case ID::out: ret.sub.angle_x = -90; ret.cur.x = depth/2; ret.cur.y = len; ret.cur.z = height-20; break; } return ret; } // COLLECTEUR class COLLECTEUR: public COOROBJ, public SCAD_COMMON{ public: using COOR = COOROBJ::COORSUBCUR; static const int len=6*25; static const int depth = 8*25; static const int height = 4*25; enum class ID{out}; void print() const; void showconnect() const; COOR getcoor(ID id) const; }; void COLLECTEUR::print() const { tab(); color("silver"); openbrace(); tab(2); difference(); tab(3); cube(depth,len,height); tab(3); translate(2,2,2); cube(depth-4,len-4,height); tab(2);closebrace(); tab();closebrace(); } void COLLECTEUR::showconnect() const { printconnect(getcoor(ID::out)); } COLLECTEUR::COOR COLLECTEUR::getcoor(ID id) const { COOR ret; switch(id){ case ID::out: ret.sub.angle_x = -180; ret.cur.x = depth/2; ret.cur.y = len/2; ret.cur.z = 0; break; } return ret; } // Table class TABLE: public COOROBJ, public SCAD_COMMON{ public: using COOR = COOROBJ::COORSUBCUR; const int width=40*25; const int height=40*25; const int heightbas=2*25; const int depth = 24*25; const int thick = 12; enum class ID{cuve,pompe,echangeur,coude,collecteur,tee,retour}; void print() const; void showconnect() const; COOR getcoor(ID id) const; }; void TABLE::print() const { tab(); color("lightgray"); openbrace(); // dessus tab(2); difference(); tab(3); translate(0,-width/2,height-thick); cube(depth,width,thick); tab(3); scad_union(); tab(4); translate(getcoor(ID::retour)); translate(0,0,-(thick+1)); cylinder(20,thick+2,80); tab(4); translate(getcoor(ID::collecteur)); translate(0,0,-(thick+1)); cylinder(ray_1_5+10,thick+2,80); tab(3); closebrace(); tab(2); closebrace(); // bas tab(2); translate(0,-width/2,heightbas-thick); cube(depth,width,thick); // Pattes const int thick1 = 2*25; const int thick2 = 3*25; tab(2); translate(0,-width/2,0); cube(thick2,thick1,height); tab(2); translate(0,width/2-thick1,0); cube(thick2,thick1,height); tab(2); translate(depth-thick2,-width/2,0); cube(thick2,thick1,height); tab(2); translate(depth-thick2,width/2-thick1,0); cube(thick2,thick1,height); tab(2); translate(0,-thick1/2,0); cube(thick2,thick1,height); tab(2); translate(depth-thick2,-thick1/2,0); cube(thick2,thick1,height); tab();closebrace(); } void TABLE::showconnect() const { printconnect(getcoor(ID::cuve)); printconnect(getcoor(ID::pompe)); printconnect(getcoor(ID::echangeur)); printconnect(getcoor(ID::collecteur)); printconnect(getcoor(ID::coude)); printconnect(getcoor(ID::tee)); printconnect(getcoor(ID::retour)); } TABLE::COOR TABLE::getcoor(ID id) const { COOR ret; switch(id){ case ID::cuve: ret.cur.z = height; ret.cur.x = depth/2; break; case ID::pompe: ret.cur.z = heightbas; ret.cur.x = depth/2; break; case ID::echangeur: ret.cur.z = heightbas+20*25; ret.cur.y = -width/2+100; ret.cur.x = depth/2; ret.sub.angle_x = 90; break; case ID::coude: ret.cur.z = heightbas; ret.cur.y = width/2-100; ret.cur.x = depth/2; break; case ID::collecteur: ret.cur.z = height; ret.cur.y = width/2-100; ret.cur.x = depth/2; break; case ID::tee: ret.cur.z = heightbas; ret.cur.y = -width/2+100; ret.cur.x = depth/2; break; case ID::retour: ret.cur.z = height; ret.cur.y = -width/2+100; ret.cur.x = depth/2; break; } return ret; } class HANGAR: public COOROBJ, public SCAD_COMMON{ public: using COOR = COOROBJ::COOR; enum class ID{in,out}; void print() const; void showconnect() const; COOR getcoor(ID id) const; private: auto make_echangeur(TABLE &table) const{ TRANSLATE echangeur(TRANSLATEC(ECHANGEUR(),table.getcoor(TABLE::ID::echangeur)),-ECHANGEUR::width/2+20,100,-ECHANGEUR::len/2); return echangeur; } }; void HANGAR::print() const { TABLE table; TRANSLATE pompe(TRANSLATEC(ROTATE(POMPE(),0,0,180),table.getcoor(TABLE::ID::pompe)),0,0,10); TRANSLATE tcon(TRANSLATEC(TCON(),table.getcoor(TABLE::ID::tee)),0,0,POMPE::outray-TCON::ray+10); auto echangeur = make_echangeur(table); TRANSLATE cuve(TRANSLATEC(CUVE(),table.getcoor(TABLE::ID::cuve)),-CUVE::depth/2,-CUVE::len/2,0); TRANSLATEC coude(ROTATE(COUDE(),0,0,180),table.getcoor(TABLE::ID::coude)); TRANSLATE collecteur(TRANSLATEC(COLLECTEUR(),table.getcoor(TABLE::ID::collecteur)),-COLLECTEUR::depth/2,-COLLECTEUR::len/2,200); table.print(); pompe.print(); tcon.print(); echangeur.print(); cuve.print(); coude.print(); collecteur.print(); // Connexions tube(pompe.getcoor(POMPE::ID::out),tcon.getcoor(TCON::ID::in),ray_3_4,80); auto ech_in1 = echangeur.getcoor(ECHANGEUR::ID::in1); tube(tcon.getcoor(TCON::ID::top),ech_in1,ray_3_4,80,makecoor(ech_in1,SECTION(0,0,0,30))); auto cuve_in = cuve.getcoor(CUVE::ID::in); tube(echangeur.getcoor(ECHANGEUR::ID::out1),cuve_in,ray_3_4,80,SECTION(0,0,0,30),makecoor(cuve_in,SECTION(0,0,0,100))); tube(collecteur.getcoor(COLLECTEUR::ID::out),coude.getcoor(COUDE::ID::in),ray_1_5,80); tube(coude.getcoor(COUDE::ID::out),pompe.getcoor(POMPE::ID::in),ray_1_5,80); } HANGAR::COOR HANGAR::getcoor(ID id) const { COOR ret; TABLE table; auto echangeur = make_echangeur(table); switch(id){ case ID::out: ret = echangeur.getfcoor(ECHANGEUR::ID::out2); break; case ID::in: ret = echangeur.getfcoor(ECHANGEUR::ID::in2); break; } return ret; } void HANGAR::showconnect() const { TABLE table; auto echangeur = make_echangeur(table); printconnect(echangeur.getcoor(ECHANGEUR::ID::in2)); printconnect(echangeur.getcoor(ECHANGEUR::ID::out2)); } int main (int argc, char *argv[]) { glocal int ret = -1; glocal int rotationx = 0; glocal int rotationy = 0; glocal int rotationz = 0; glocal int test=0; glocal int angle1 = 0; glocal int angle2 = 45; glocal int angle3 = 45; glocal const char *objet = "tout"; glocal bool showconnect = false; glocal.ret = (argc,argv); setproginfo ("plomberie","0.0" ,"Produit des schemas openscad pour le projet de serre\n" "\n" "Valeurs pour l'option --objet\n" "\tcollecteur\n" "\tcoude\n" "\tcuve\n" "\thangar\n" "\techangeur\n" "\tpompe\n" "\ttable\n" "\ttcon\n" "\n" "\thangar-asm\n" "\ttout-asm\n" ); setarg ('r',"rotationx","Rotation en X sur l'échangeur",glocal.rotationx,false); setarg (' ',"rotationy","Rotation en Y sur l'échangeur",glocal.rotationy,false); setarg (' ',"rotationz","Rotation en Z sur l'échangeur",glocal.rotationz,false); setarg ('t',"test","Différents cas de test",glocal.test,false); setarg (' ',"angle1","Premier angle du tube",glocal.angle1,false); setarg (' ',"angle2","Second angle du tube",glocal.angle2,false); setarg (' ',"angle3","Troisième angle du tube",glocal.angle3,false); setarg ('o',"objet","Objet a présenter seul",glocal.objet,false); setarg ('c',"showconnect","Montre les connections sur un objet",glocal.showconnect,false); if (is_eq(glocal.objet,"pompe")){ show(); }else if (is_eq(glocal.objet,"echangeur")){ show(); }else if (is_eq(glocal.objet,"tcon")){ show(); }else if (is_eq(glocal.objet,"table")){ show
(); }else if (is_eq(glocal.objet,"cuve")){ show(); }else if (is_eq(glocal.objet,"collecteur")){ show(); }else if (is_eq(glocal.objet,"coude")){ show(); }else if (is_eq(glocal.objet,"hangar")){ show(); }else if (is_eq(glocal.objet,"test-croise")){ ECHANGEUR e; ROTATE r(ECHANGEUR(),glocal.rotationx,glocal.rotationy,glocal.rotationz); module_composante(); r.print(); if (1){ auto out1 = r.getcoor(ECHANGEUR::ID::out1); auto in1 = r.getcoor(ECHANGEUR::ID::in1); auto out2 = r.getcoor(ECHANGEUR::ID::out2); auto in2 = r.getcoor(ECHANGEUR::ID::in2); tube(out1,out2,10,40,SECTION(glocal.angle1,0,0,180),SECTION(glocal.angle2,0,0,80),SECTION(glocal.angle3,0,0,60)); tube(in2,in1,10,40,SECTION(glocal.angle1,0,0,180),SECTION(glocal.angle2,0,0,80)); //tube(out1,in1,10,40,SECTION(glocal.angle1,0,0,180)); } closebrace(); }else if (is_eq(glocal.objet,"hangar-asm")){ module_composante(); HANGAR hangar; hangar.print(); #if 0 TABLE table; table.print(); TRANSLATE pompe(TRANSLATEC(ROTATE(POMPE(),0,0,180),table.getcoor(TABLE::ID::pompe)),0,0,10); pompe.print(); TRANSLATE tcon(TRANSLATEC(TCON(),table.getcoor(TABLE::ID::tee)),0,0,POMPE::outray-TCON::ray+10); tcon.print(); TRANSLATE echangeur(TRANSLATEC(ECHANGEUR(),table.getcoor(TABLE::ID::echangeur)),-ECHANGEUR::width/2+20,100,-ECHANGEUR::len/2); echangeur.print(); TRANSLATE cuve(TRANSLATEC(CUVE(),table.getcoor(TABLE::ID::cuve)),-CUVE::depth/2,-CUVE::len/2,0); cuve.print(); TRANSLATEC coude(ROTATE(COUDE(),0,0,180),table.getcoor(TABLE::ID::coude)); coude.print(); TRANSLATE collecteur(TRANSLATEC(COLLECTEUR(),table.getcoor(TABLE::ID::collecteur)),-COLLECTEUR::depth/2,-COLLECTEUR::len/2,200); collecteur.print(); // Connexions tube(pompe.getcoor(POMPE::ID::out),tcon.getcoor(TCON::ID::in),ray_3_4,80); auto ech_in1 = echangeur.getcoor(ECHANGEUR::ID::in1); tube(tcon.getcoor(TCON::ID::top),ech_in1,ray_3_4,80,makecoor(ech_in1,SECTION(0,0,0,30))); auto cuve_in = cuve.getcoor(CUVE::ID::in); tube(echangeur.getcoor(ECHANGEUR::ID::out1),cuve_in,ray_3_4,80,SECTION(0,0,0,50),makecoor(cuve_in,SECTION(0,0,0,120))); tube(collecteur.getcoor(COLLECTEUR::ID::out),coude.getcoor(COUDE::ID::in),ray_1_5,80); tube(coude.getcoor(COUDE::ID::out),pompe.getcoor(POMPE::ID::in),ray_1_5,80); #endif #if 0 // test tube(echangeur.getcoor(ECHANGEUR::ID::out2),tcon.getcoor(TCON::ID::out),12,80); tube(echangeur.getcoor(ECHANGEUR::ID::out1),cuve.getcoor(CUVE::ID::in),12,80); #endif closebrace(); if (0){ TRANSLATE ech(ECHANGEUR(),10,10,10); auto c = ech.getfcoor(ECHANGEUR::ID::out1); fprintf (stderr,"c=%lf,%lf,%lf X=%lf,%lf,%lf\n",c.x,c.y,c.z ,ech.getx(ECHANGEUR::ID::out1) ,ech.gety(ECHANGEUR::ID::out1) ,ech.getz(ECHANGEUR::ID::out1) ); } }else if (is_eq(glocal.objet,"tout-asm")){ module_composante(); TRANSLATE hangar(HANGAR(),50,50,0); hangar.print(); closebrace(); }else{ tlmp_error ("Aucun objet sélectionné\n"); } return 0; return 0; }