lundi 4 octobre 2021

OpenScad : modélisation 3D

OpenScad est un logiciel de modélisation 3D paramétrique sans interface graphique mais utilisant un langage fonctionnel. Je m'en sers, quand je fais de la menuiserie pour voir en volume. Dans cet article je vais explorer certaines de ces fonctionnalités sous l'angle de la menuiserie.

Introduction

La fenêtre d'Openscad se compose de trois volets :

La syntaxe du langage rappelle celle du C.

On peut utiliser son éditeur de texte habituel (un fichier openscad.vim existe).

Les objets 3D de base sont : cube, cylinder (cylindre), sphere, polyhedron (polyèdre) et les objets obtenus par extrusion. À ces objets on applique des transformations : translation, rotation, symétrie miroir, intersection, réunion, différence.

Dans cet article je vais modéliser un chevet (table de nuit) ci-dessous. C'est de la menuiserie. Je suppose que le lecteur a déjà lu une initiation à OpenScad.

Un fichier librecad chevet.dxf et une planche chevet.pdf sont joints en téléchargement.

Pour retrouver rapidement la syntaxe des fonctions d'OpenScad, ouvrez la page de l'aide mémoire et cliquez sur la fonction désirée.

Le code complet de la table de nuit est en deux fichiers chevet.scad et pieces.scad

Extrusion d'un polygone

Commençons par les pieds de la table de nuit. Chaque pied est composé de deux trapèzes rectangles de hauteur 60, de petite base 40 et de grande base 80, assemblés à angle droit.

Dans le plan xOy le code de ce trapèze est

polygon([[0, 0], [40, 0], [80, 60], [0, 60]]);

Pour obtenir le volume, on lui applique une extrusion de l'épaisseur du bois (ici 22 mm).

e = 22; // épaisseur du bois
linear_extrude(e) 
	polygon([[0, 0], [40, 0], [80, 60], [0, 60]]);

On obtient ainsi un cylindre (au sens large) de base le trapèze situé dans le plan xOy et dont les arêtes sont parallèles à Oz.

Il reste à le mettre debout par une rotation d'axe Ox et d'angle 90°.

e = 22; // épaisseur du bois
rotate([90, 0, 0]) 
	linear_extrude(e) 
		polygon([[0, 0], [40, 0], [80, 60], [0, 60]]);

Comme nous utiliserons cette pièce huit fois, on crée un module, entendez par là une pièce de bois.

e = 22; // épaisseur du bois
module pied() {
	rotate([90, 0, 0]) 
		linear_extrude(e) 
			polygon([[0, 0], [40, 0], [80, 60], [0, 60]]);
}

Remarques

Dans OpenScad les figures planes sont toujours dessinées dans le repère (Ox, Oy), d'origine O(0, 0),

Une extrusion se fait toujours suivant l'axe Oz.

On doit par la suite leur appliquer les transformations géométriques : translate, rotate, ou mirror.

L'image ci-contre est le rendu de ce module qu'on obtient par le code complet :

e = 22; // épaisseur du bois
module pied() {
	rotate([90, 0, 0]) 
		linear_extrude(e) 
			polygon([[0, 0], [40, 0], [80, 60], [0, 60]]);
}
pied();

Le calcul du rendu (compilation du code et affichage) s'obtient par la touche F5.

Je fais mes tatonnements dans l'éditeur intégré, mais pour des codes plus conséquents j'emploie mon éditeur habituel : Vim.

Extrusion à partir d'un fichier LibreCad xdf

Il s'agit ici de la partie en saillie à l'arrière du plateau, en forme de chapeau de Napoléon, que j'ai appelée chapeau. J'ai dessiné la section dans LibreCad et que j'ai enregistrée dans chapeau.dxf. Pour modéliser ce chapeau le code est :

e = 22;
module chapeau() {
	rotate([90, 0, 0])
    	linear_extrude(e) import("chapeau.dxf");
}

Rainures et autres entailles

Nous allons ici réaliser une rainure dans une planche, qui deviendra un montant du chevet. La fonction utilisée sera difference.

module montant() {
    difference() 
	    cube([22, 315, 486]); // planche
	    translate([15, 300, 0]) cube([7, 5, 508]); // rainure
}

Bord arrondi

Dans le paragraphe de l'extrusion j'ai importé un fichier dxf. Ici je vais calculer les ordonnées de l'arc de cercle du bord du plateau. Pour ça j'ai écrit un mini programme en C :

// calculs.c
#include <stdio.h>
#include <math.h>
/*                
   A'           ABA' est un arc de cercle de centre C et de rayon r
  ▞│			   la longueur de la corde AA'= 2×a 
B▐-│------ C   la distance de B à la corde est b
  ▚│            c = r - b est l'ordonnée de C dans le repère dont les
   A           les axes sont portés par (A'A) et (BC) dans ces sens 
*/
int a = 205, b = 35; // demi-corde, flêche
int r, c; // rayon, abscisse de C
int y(int x) { // Ordonnée d'un point de l'arc d'abscisse x
    return -(int)round(r*cos(asin((double)(x - a)/r)) - c);
}
int main()
{
	r = (int)round(((double)a*a + b*b)/2/b);
	c = r - b; // (int)round(((double)a*a - b*b)/2/b);
	printf("a = %d, b = %d\nr = %d, c = %d\n", a, b, r, c);
	printf("polygon([[0, 0], ");
	for(int x = 55; x < 400; x += 50)
		printf("[%d, %d], ", x, y(x));
	printf("[410, 0]]);\n");
}

Remarque : Dans mon crobard il faut tourner les axes de π/2 pour retrouver la représentation habituelle. La raison est que le dessin ascii est plus facile comme je l'ai fait.

Le résultat de ce programme est :

a = 205, b = 35
r = 618, c = 583
polygon([[0, 0], [55, -17], [105, -27], [155, -33], 
	[205, -35], [255, -33], [305, -27], [355, -17], [410, 0]]);

La première ligne affiche les données, la seconde affiche le rayon et l'ordonnée du centre du cercle, et la dernière je vais la copier dans le module ci-dessous :

e = 22;
module plateau () {
    cube([410, 315, e]);
    linear_extrude(e)
		polygon([[0, 0], [55, -17], [105, -27], [155, -33], 
		[205, -35], [255, -33], [305, -27], [355, -17], [410, 0]]);
}
plateau();

Une autre solution utilisant intersection aurait été :

e = 22;
module plateau() {
	intersection() {
		cube([410, 350, e]);
		translate([210, 618, 0]) cylinder(e, 618, 618);
	};
plateau();

Travail à la toupie

Conclusion

Pour qui préfère taper du code que remplir des formulaires interminables ou perdre sa patience avec la souris, openscad est une merveille.





Réalisé avec Qlam - LGPL