Openscad

De Les Fabriques du Ponant
Aller à : navigation, rechercher

Préambule :

Openscad est un logiciel de modélisation libre (license GPL), qui est simple d'utilisation pour des formes relativements basiques, tout en permettant une utilisation avancée à l'aides des fonctions mathématiques (+,-,/,*,exp,log, cos,sin,...), des boucles, des conditions, etc. Il est conseillé pour ceux préférant ne pas trop utiliser la souris, ou ne pas perdre de temps avec des surcontraintes (car les contraintes n'existent pas, les pièces étant en un seul morceau après compilation), pour ceux voulant modéliser un objet simple ou plus complexe très rapidement avec des cotes précises,... Bref, il est conseillé pour tout le monde connaissant 5 mots d'anglais ressemblant à des mots francais (cube, cylinder, sphere, translate, rotate). Si, si, je le jure ;)


Principes du logiciel :

Openscad assemble des formes simples en créant un script, grace à différentes commandes ; l'utilisation des sommes, produits et fonctions trigonométriques est possibles pour les déplacements ainsi que les tailles des éléments.


Installation d'Openscad :

  • Debian (6.0 et supérieurs), Ubuntu (12.04 et supérieurs) : aptitude install openscad ou sudo apt-get install openscad
  • Mac, Windows, BSD : [[1]]
  • Code Source : [[2]]


Utilisation du logiciel

Règles élementaires :

  • Mettre un point-virgule ";" après chaque ligne d'instruction.
  • Les commentaires sont à signalés par deux slashs "//"


Formes de base :

  • pavé : cube([longueur,largeur,hauteur]);

(exemple : cube([1,2,3]); : x=1, y=2, z=3)

  • cylindre : cylinder(r=rayon, h=hauteur);

(exemple : cylinder(r=1,h=2); : rayon de 1, hauteur de 2) Notes :

  1. le rayon est la moitié du diamètre ; la visserie est répertoriée selon son diamètre, en mm : une vis m2 a un diamètre de 2mm)
  2. la hauteur est le z : un cylindre va toujours vers les z croissant. Pour changer d'orientation, il faut utiliser rotate.
  • sphère : sphere(r=rayon);

(exemple : sphere(r=1); : rayon de 1)


Déplacements :

  • translation : translate([selon x, selon y, selon z]);
  • rotation : rotate([autour de x, autour de y, autour de z]);


Remarque :

* les déplacements s'écrivent avant la forme : translate([...]) cylinder();
* on peut combiner rotations et translations
* les déplacements se notent avant la commande, selon l'ordre d'execution :

translate([...]) rotate([...]) cube([...]); =/= rotate([...]) translate([...]) cube([...]);

Formes plus complexes :

  • Cube avec l'origine au centre : cube([longueur,largeur,hauteur],center=true);
  • Cone : cylinder(r1 = rayon mini, r2 = rayon maxi, h= hauteur);
  • Pentagones, octogones,... d'extrusion : cylinder(r=rayon centre angle , $fn= nombre de cotés);
  • Polyèdres réguliers : sphère(r=rayon,$fn=nombre de faces par perimètre);

Fonctions :

Une fonction est toujours écrite sous la forme

fonction(){
 Argument1;
 Argument2;
 Argument3;
 ...
}
  • Relier deux volumes : hull() (en particulier deux cylindres, un cylindre et un pavé,...) :
  • Soustraire un volume à un autre : difference() Le premier argument sera la forme positive, et les suivants, seront les formes qui vont se soustrairent à la première. Pour visualiser les formes à enlever, on peut mettre un croisillon devant leurs arguments ; au rendu final, seul le final apparaitra, c'est à dire la forme avec les soustractions dans celle-ci, et meme si les soustractions dépassent.
  • Ajouter deux volumes : union() (Cette commande est automatique sauf à l'interieur d'une soustraction de matière, cf ci-dessus)
  • Créer sa propre fonction (que l'on pourra rappeler autant de fois qu'on le désire en faisant varier éventuellement des paramètres) :

module nom_du_module(var1,var2){ arg1; arg2; }

nom_du_module(var1,var2);

Fonctions mathématiques :

  • Opérations élémentaires : somme (+ et -), produit (* et /)
  • Fonctions trigonométriques : cosinus (cos), sinus (sin), tangente (tan)
  • Fonctions trigonométriques réciproques : Arccosinus (acos), Arcsinus (asin), Arctangente (atan)
  • Fonction exponentielle (exp)
  • Racine carrée (sqrt)
  • Rem une puissance ne s'écrit que par le poduit de termes : par exemple, a^3 = a*a*a

Tutorial : créer une voiture

Partie 1 : creer une base

La voiture est basee sur 3 cubes de differentes tailles.

Le capot est un cube de 30x20x10 (x,y,z) et on le deplace de -7 en y (c est a dire que son coin bas droit sera en 0,-7,0) (c est comme ca que j ai fait la premiere fois, en adaptant sa taille par rapport au reste de la voiture) La commande pour creer ce cube est donc simplement cube([30,20,10]);

L habitacle est un cube de 30x30x20 et on le deplace de 10 en y La commande pour creer ce cube est translate([0,10,0]) cube([30,30,20]) ;

A vous de creer le coffre ; c est un cube de 30x5x10 et on le place a 37 en y

Partie 2 : enlever de la matiere

Il suffit de creer une fonction du type (l ordre d ennonciation ne change rien pour la matiere a enlever : on peut faire forme2 forme1 )

difference(){
 base //(une seule);
 #forme1 ;//a enlever //peut depasser a l exterieur;
 #forme2 ;//a enlever 
//etc
}

Par exemple, enlever les parebrises de la voiture : ce sont des cubes de 30x3x8

difference(){
 translate([0,10,0]) cube([30,30,20]) ;//le cube de l habitacle
  //et oui, on peut faire des retours a la ligne rien que pour a-airer ou pour des commentaires plutot long comme celui ci
 #translate([0,9,10.5]) cube([30,3,8]); //parebriseav
 #translate([0,39,10.5]) cube([30,3,8]);//parbrisear
}

A vous de completer en placant les 4 vitres (de 3x10x9) de facon a peu pres convenable (je ne dit pas que ma correction est la meilleure : a vous de voir ; perso, je les met au coordonnes 28,13,10.5 28,28,10.5 -1,28,10.5 et -1,13,10.5)

difference(){
 translate([0,10,0]) cube([30,30,20]) ;
 #translate([0,9,10.5]) cube([30,3,8]); //parebriseav
 #translate([0,39,10.5]) cube([30,3,8]);//parbrisear
 #translate([28,13,10.5]) cube([3,10,9]);//fenetre
 //etc
}

Partie 3 : le module

Je ne vous ais pas montre a quel point un code peut etre vite surcharge si une difference est entre 2 formes de base, je vous laisse l imagine. Pour cela, il a ete cree des fonctions appele module qui permet de re-appeler un morceau de code a differents endroits

Il y a plusieurs facons de s en servir : -on met toutes les formes de bases sous un module et on fait les differences sur ce module -on met les pieces a enlever sous forme de modules et on fait la difference des formes de bases -on fait les formes de bases sous formes de module, les differences aussi on a alors module nom_du_module_sans_espace(variable1, variable2,...){ piece 1 ; piece 2 ; etc ; }

nom_du_module_sans_espace(valeur de variable1, valeur de variable2,...);


Pour l espace des roues, on va utiliser dans le module (de difference) une difference de difference : ca peut faire un peu peur, mais j expliquerais bien le code

module espace_roues(){
  //on introduit le module : ce qui est a l interieur est le negatif de ce qui sera enleve car on fera plus tard la difference de ce module
 difference(){ //on lui dit de faire une difference : comme c est le negatif, ca sera de la matiere non-enlevee au final
  translate([-5,36,0]) rotate([90,0,90]) cylinder (h=44,r=5); //on commence par creer un cylindre qui est plus grand que la voiture
  #difference(){ //on va faire la difference de ce cylindre par une difference
   translate([5,36,0]) rotate([90,0,90]) cylinder (h=20,r=5); //on lui enlever l entre-roues
   #translate([-10,36,0]) rotate([90,0,90]) cylinder (h=50,r=1.2); //mais on lui ajoute l axe des roues
  }
 
 }
 difference(){//de meme pour les roues avant
  translate([-5,0,0])rotate([90,0,90]) cylinder (h=44,r=5);//place des roues
  #difference(){
   translate([5,0,0]) rotate([90,0,90]) cylinder (h=20,r=5);//entreroues
   #translate([-10,0,0]) rotate([90,0,90]) cylinder (h=50,r=1.2);//axe des roues
  }
 }
}

On va faire une module de la base (ce n est pas tres utile dans ce cas, car ca fait juste gagner 2 lignes, mais dans des formes plus compliquees, ca peut rendre service).

module base(){
 //capot
  translate([0,-7,0]) cube([30,20,10]);
 //habitacle
  difference(){
   translate([0,10,0]) cube([30,30,20]) ;
 
   #translate([0,9,10.5]) cube([30,3,8]); //parebriseav
   #translate([0,39,10.5]) cube([30,3,8]);//parbrisear
 
   #translate([28,13,10.5]) cube([3,10,9]);//fenetre
   #translate([28,28,10.5]) cube([3,10,9]);//fenetre
   #translate([-1,28,10.5]) cube([3,10,9]);//fenetre
   #translate([-1,13,10.5]) cube([3,10,9]);//fenetre
  }
 //coffre
  translate([0,37,0]) cube([30,5,10]);
}

Maintenant, a vous de faire le module des phares arrieres : -les phares arriere ont une hauteur de 3, un rayon de 2 : la commande pour creer le cylindre est cylinder(h=3,r=2); -on le fait pivoter de 90° selon x (rappel : tout tourne autour de l axe x dans ce cas) dans le sens trigonometrique (=anti-horaire) : rotate([90,0,0]) -on les mets respectivement a 27.5,43,7.3 et 2.5,43,7.3

De meme pour les phares avant sauf qu ils sont a 4,-2,5 et 26,-2,5 et qu ils ont un rayon de 3 pour une hauteur de 3


On va maintenant faire la difference du bati et des negatifs que vous avez fait

difference(){
 bati();
 #phares_avant();
 #phares_arriere();
 #espace_roues();
}

Partie 4 : Solution de tout ce que vous avez fait jusqu a present :

module base(){
 //capot
  translate([0,0,0]) cube([30,20,10]);
 //habitacle
  difference(){
   translate([0,10,0]) cube([30,30,20]) ;
  
   #translate([0,9,10.5]) cube([30,3,8]); //parebriseav
   #translate([0,39,10.5]) cube([30,3,8]);//parbrisear
  
   #translate([28,13,10.5]) cube([3,10,9]);//fenetre
   #translate([28,28,10.5]) cube([3,10,9]);//fenetre
   #translate([-1,28,10.5]) cube([3,10,9]);//fenetre
   #translate([-1,13,10.5]) cube([3,10,9]);//fenetre
  }
 //coffre
  translate([0,37,0]) cube([30,5,10]);
}
module espace_roues(){
 difference(){
  translate([-5,36,0]) rotate([90,0,90]) cylinder (h=44,r=5);
  #difference(){
   translate([5,36,0]) rotate([90,0,90]) cylinder (h=20,r=5);
   #translate([-10,36,0]) rotate([90,0,90]) cylinder (h=50,r=1.2);
  }
 }
 difference(){
  translate([-5,0,0])rotate([90,0,90]) cylinder (h=44,r=5);
  #difference(){
   translate([5,0,0]) rotate([90,0,90]) cylinder (h=20,r=5);
   #translate([-10,0,0]) rotate([90,0,90]) cylinder (h=50,r=1.2);
  }
 }
}
module phares_arriere(){
 translate([27.5,43,7.3]) rotate([90,0,0]) cylinder(h=3,r=2);
 translate([2.5,43,7.3]) rotate([90,0,0]) cylinder(h=3,r=2);
}
module phares_avant(){
 translate([4,-5,5]) rotate([90,0,0]) cylinder(h=3,r=3);//phareav
 translate([26,-5,5]) rotate([90,0,0]) cylinder(h=3,r=3);
}
difference(){
 bati();
 #espace_roues(); //on nappelle pas forcement dans l ordre des modules, mais c est plus simple pour retrouver
 #phares_avant(); //les negatifs sont maintenant developpes et deviennent deviennent des differences
 #phares_arriere();
}

Partie 5 : creer les roues

La fonction for permet de repeter plusieurs fois une operation notation : for(variable=[valeur1,valeur2,valeur3,etc]){ commande1 commande2 }

Le rayon des roues est de 4.5, on deplace chaque nouvelle roue de 12 suivant y, et sont en -15,y,0 L axe des roues fait 1 de rayon pour 9 de hauteur, on les place au meme endroit que les roues sauf a 4 de hauteur

for (y=[0,1,2,3]){ //pour z prenant les valeurs de 0 a 3
 translate([-15,12*y,0]) cylinder (h=4.3,r=4.5);//on cree les roues ; le parametre y sert ici aussi a deplacer chaque nouvelle roue pour eviter que 2 roues se confondent
 translate([-15,12*y,4]) cylinder (h=9.5,r=1);//on cree les axes des roues
}

Partie 6 : creer les plaques d immatriculation

Ici, on utilise deux cylindres d une hauteur de 1 et de rayon 1, et toute l aire entre les 2 est remplie par la fonction hull. Les 2 cylindres extremites ont pour cotes 12 et 18 , 0.7,2 N oubliez pas d effectuer une rotation de 90 suivant x

hull(){ commande1; commande2; }


hull(){ //plaque avant
 translate([12,-6.3,2]) rotate([90,0,0]) cylinder(h=1,r=1);
 translate([18,-6.3,2]) rotate([90,0,0]) cylinder(h=1,r=1);
}


Faites la meme chose pour la plaque arriere (coordonnes 12 et 18, 42.3,2, meme taille)

CODE FINAL :

module base(){
 //capot
  translate([0,-7,0]) cube([30,20,10]);
 //habitacle
  difference(){
   translate([0,10,0]) cube([30,30,20]) ;
  
   #translate([0,9,10.5]) cube([30,3,8]); //parebriseav
   #translate([0,39,10.5]) cube([30,3,8]);//parbrisear
 
   #translate([28,13,10.5]) cube([3,10,9]);//fenetre
   #translate([28,28,10.5]) cube([3,10,9]);//fenetre
   #translate([-1,28,10.5]) cube([3,10,9]);//fenetre
   #translate([-1,13,10.5]) cube([3,10,9]);//fenetre
  }
 //coffre
  translate([0,37,0]) cube([30,5,10]);
}
module espace_roues(){
 difference(){
  translate([-5,36,0]) rotate([90,0,90]) cylinder (h=44,r=5);
  #difference(){
   translate([5,36,0]) rotate([90,0,90]) cylinder (h=20,r=5);
   #translate([-10,36,0]) rotate([90,0,90]) cylinder (h=50,r=1.2);
  }
 }
 difference(){
  translate([-5,0,0])rotate([90,0,90]) cylinder (h=44,r=5);
  #difference(){
   translate([5,0,0]) rotate([90,0,90]) cylinder (h=20,r=5);
   #translate([-10,0,0]) rotate([90,0,90]) cylinder (h=50,r=1.2);
  }
 }
}
module phares_arriere(){
 translate([27.5,43,7.3]) rotate([90,0,0]) cylinder(h=3,r=2);
 translate([2.5,43,7.3]) rotate([90,0,0]) cylinder(h=3,r=2);
}
module phares_avant(){
 translate([4,-5,5]) rotate([90,0,0]) cylinder(h=3,r=3);//phareav
  translate([26,-5,5]) rotate([90,0,0]) cylinder(h=3,r=3);
}
difference(){
 base();
 #espace_roues(); //on nappelle pas forcement dans l ordre des modules, mais c est plus simple pour retrouver
 #phares_avant(); //les negatifs sont maintenant developpes et deviennent deviennent des differences
 #phares_arriere();
}
//on cree maintenant les roues
for (y=[0,1,2,3]){ //pour z prenant les valeurs de 0 a 3
 translate([-15,12*y,0]) cylinder (h=4.3,r=4.5);//on cree les roues ; le parametre y sert ici aussi a deplacer chaque nouvelle roue pour eviter que 2  roues se confondent
 translate([-15,12*y,4]) cylinder (h=9.5,r=1);//on cree les axes des roues
}
//on fait les 2 plaques
hull(){ //plaque avant
 translate([12,-6.3,2]) rotate([90,0,0]) cylinder(h=1,r=1);
 translate([18,-6.3,2]) rotate([90,0,0]) cylinder(h=1,r=1);
}
hull(){ //plaque arriere
 translate([12,42.3,2]) rotate([90,0,0]) cylinder(h=1,r=1);
 translate([18,42.3,2]) rotate([90,0,0]) cylinder(h=1,r=1);
}

Remarques :

J aurais pu beaucoup plus utiliser la fonction for, mais le but n etait ici que de l introduire pour faire une chose de facile a comprendre J aurais pu ne pas mettre la fonction hull, mais je pense n introduire que for n aurait pas fait beaucoup

Manuel d'utilisation :

Vous y trouverz toutes les commandes avec des exemples et des images : (en anglais) [[3]]