Aller au contenu

Dessiner un ressort en 3d


burinos

Messages recommandés

Salut,

 

Dessiner un ressort en 3d avec les version d'AutoCAD antérieures à 2007 est difficile et laborieux sans programmation.

 

J'avais fait un LISP avec boite de dialogue qui permet de faire une approche de ressort que je trouve acceptable : chaque spire est divisée en un nombre de segments qui sont en fait des arcs elliptiques (donc plans) servant de chemin à l'extrusion du boudin, les tronçons de boudins sont ensuite unis.

 

Il s'agit ici d'une version améliorée (Visual LISP) de ce LISP

 

Le LISP (commande TORS pour la boite de dialogue, -TORS pour entrer les données en ligne de commande).

 

;;; 17/06/05 Fonction TORS  - Gilles Chanteau -

;;; Crée un solide en forme de ressort hélicoïdal ou de pièce torse.
;;; Le chemin d'extrusion du boudin est constitué d'une succession d'arcs elliptiques jointifs.
;;; Le nombre de segments décrivant la longueur d'une spire est défini par l'utilisateur.
;;; Le départ du ressort se situe sur l'axe des X positifs par rapport au point de base.
;;; La fonction C:TORS commande la boite de dialogue "Ressort.dcl" pour la saisie des données.
;;; La fontion C:-TORS permet la saisie des données sur la ligne de commande.
;;; Ces deux fonctions lancent soit CREAT_RESSORT, soit CREAT_TORS en fonction des données.
;;;
;;; NOTA : Tors.lsp est une version "débridée" de Ressort.lsp qui autorise des dimensions
;;;        diamètre de boudin supérieure au rayon du solide ou au pas, ceci afin de modéliser des
;;;        formes torses (ex : pieds Louis XIII). Suivant les dimensions l'union des éléments peut
;;;        échouer.

(vl-load-com)

;;;****************************************************************************************************
;;; Fonctions principales : saisie des données
;;;****************************************************************************************************
;;; C:TORS Boite de dialogue

(defun c:tors (/ dcl_id what_next seg sp sens pas diam bdn axe)
 (setq dcl_id (load_dialog "tors.dcl"))
 (setq what_next 3)
 (while (>= what_next 3)				    ; Départ de la boucle d'affichage de la boite
   (if	(not (new_dialog "tors" dcl_id))
     (exit)
   )
   (if	(not (numberp *seg_trs*))			    ; Restauration des valeurs précedentes
     (setq *seg_trs* 12)				    ; si elles existent
   )
   (foreach n '("nb_seg" "sldr_seg")
     (set_tile n (itoa *seg_trs*))
   )
   (if	sp
     (set_tile "nb_sp" (itoa sp))
   )
   (if	pas
     (set_tile "val_pas" (rtos pas))
   )
   (if	diam
     (set_tile "dia_ext" (rtos diam))
   )
   (if	bdn
     (set_tile "dia_bdn" (rtos bdn))
   )
   (if	sens
     (if (equal sens "Droite")
(set_tile "drte" "1")
(set_tile "gche" "1")
     )
   )
   (if	(null axe)
     (setq axe '(0 0 0))
   )
   (set_tile "x_coord" (rtos (car axe)))
   (set_tile "y_coord" (rtos (cadr axe)))
   (set_tile "z_coord" (rtos (caddr axe)))
   (action_tile					    ; Interaction entre le curseur
     "sldr_seg"					    ; et la boite d'édition correspondante:
     (strcat						    ;
"(if (or (= $reason 1) (= $reason 3))"		    ; Mise à jour de la boite d'édition et de
"(progn (set_tile \"nb_seg\" $value)"		    ; la valeur de la variable (*seg_trs*) en
"(setq *seg_trs* (atoi $value))))"		    ; fonction des actions sur le curseur
     )							    ;
   )							    ;
   (action_tile					    ;
     "nb_seg"						    ;
     (strcat						    ;
"(if (or (= $reason 1) (= $reason 2))"		    ; Mise à jour du curseur et de la valeur
"(progn (set_tile \"sldr_seg\" $value)"		    ; de la variable (*seg_trs*) en fonction
"(setq *seg_trs* (atoi $value))))"		    ; des actions sur la boite d'édition
     )
   )
   (action_tile "nb_sp" "(setq sp (atoi $value))")	    ; Mise à jour des valeurs des variables
   (action_tile "val_pas" "(setq pas (atof $value))")
   (action_tile
     "drte"
     "(if (= (atoi $value) 1) (setq sens \"Droite\"))"
   )
   (action_tile
     "gche"
     "(if (= (atoi $value) 1) (setq sens \"Gauche\"))"
   )
   (action_tile "dia_ext" "(setq diam (atof $value))")
   (action_tile "dia_bdn" "(setq bdn (atof $value))")
   (action_tile
     "x_coord"
     "(setq axe (list (atof $value) (cadr axe) (caddr axe)))"
   )
   (action_tile
     "y_coord"
     "(setq axe (list (car axe) (atof $value) (caddr axe)))"
   )
   (action_tile
     "z_coord"
     "(setq axe (list (car axe)  (cadr axe) (atof $value)))"
   )
   (action_tile "b_axe" "(done_dialog 4)")		    ; Sélection à l'écran et réouverture
   (action_tile
     "accept"
     (strcat
"(setq seg *seg_trs*)"
"(cond"						    ; Tests de faisabilité
"((	"(alert \"Le nombre de segments ne peut être inférieur à 2.\")"
"(mode_tile \"nb_seg\" 2))"
"((	"(alert \"Le nombre de spires doit être positif et non nul.\")"
"(mode_tile \"nb_sp\" 2))"
"((	"(alert \"La valeur du pas doit être positive et non nulle.\")"
"(mode_tile \"val_pas\" 2))"
"((	"(alert \"Le diamètre du solide doit être positif et non nul.\")"
"(mode_tile \"dia_ext\" 2))"
"((	"(alert\"Le diamètre du boudin doit être positif et non nul.\")"
"(mode_tile \"dia_bdn\" 2))"
"((or (	"(done_dialog (ALERT_TORS)))"
"(T (done_dialog 1)))"				    ; Création du solide et fermeture
      )
   )
   (setq what_next (start_dialog))
   (cond
     ((= what_next 4)
      (initget 1)
      (setq axe
      (getpoint
	"\nSélectionnez le point à la base du solide: "
      )
      )
     )
     ((= what_next 1)
      (VL_CREAT_TORS seg sp sens pas diam bdn axe)
     )
   )
 )
 (unload_dialog dcl_id)
 (princ)
)

;;;****************************************************************************************************
;;; C:-TORS Ligne de commande

(defun c:-tors (/ seg sp sens pas diam bdn axe resp)
 (if (not (numberp *seg_trs*))
   (setq *seg_trs* 12)					    ; Nombre de segments par défaut
 )
 (princ (strcat "\nEntrez le nombre de segments par spire 		 (itoa *seg_trs*)
	 ">: "
 )
 )
 (if (setq seg (getint))
   (setq *seg_trs* seg)				    ; Nouvelle valeur du nombre de segments
   (setq seg *seg_trs*)				    ; Valeur précédente (ou défaut)
 )
 (while (    (alert
     "Le nombre de segments ne peut être inférieur à 2."
   )
   (setq seg	    (getint "\nEntrez un nouveau nombre de segments: ")
  *seg_trs* seg
   )
 )
 (initget 7)
 (setq sp (getint "\nEntrez le nombre de spires: "))
 (initget "Droite Gauche")
 (if (not
(setq sens (getkword "\nIndiquez le sens du pas [Droite/Gauche] : "))
     )
   (setq sens "Droite")				    ; Pas à droite par défaut
 )
 (initget 7)
 (setq pas (getdist "\nSpécifiez la valeur du pas: "))
 (initget 7)
 (setq diam (getdist "\nSpécifiez le diamètre extérieur du solide: "))
 (initget 7)
 (setq bdn (getdist "\nSpécifiez le diamètre du boudin: "))
 (initget 1)
 (setq axe (getpoint "\nSpécifiez le point à la base l'axe: "))
 (if (or (    (progn (setq resp (ALERT_TORS))
   (cond
     ((= resp 0) (exit))
     ((= resp 1) (VL_CREAT_TORS seg sp sens pas diam bdn axe))
     ((= resp 3) (C:-TORS))
   )
   )
   (VL_CREAT_TORS seg sp sens pas diam bdn axe)
 )
 (princ)
)

;;;****************************************************************************************************
;;; VL_CREAT_TORS Création d'un solide tors. Si le diamètre du boudin est supérieur au rayon extérieur du
;;; solide et/ou à la valeur du pas -> risque d'echec de modélisation.

(defun VL_CREAT_TORS (seg    sp	    sens   pas	  diam	 bdn	axe    /      r	     dist   ang
	      ang2   dist2  pt1	   pt2	  pt3	 Norm	N_axe  N_pt1  N_pt2  MajAx  arc
	      cercle region seg_lst	  spire	 sp_lst
	     )
 ;; Initialisaton de l'environnement et des données
 (setq	AcDoc (vla-get-activedocument (vlax-get-acad-object))
ModSp (vla-get-ModelSpace AcDoc)
 )
 (vla-startundomark AcDoc)
 (setq	m:err	*error*
*error*	VL_TORS_ERR
 )
 (if (= sens "Gauche")
   (setq pas (- pas)
  seg (- seg)
   )
 )
 (setq	r     (- (/ diam 2) (/ bdn 2))
pt1   (polar axe 0 r)
pt2   (polar axe (/ (* 2 pi) seg) r)
dist  (distance pt1 pt2)
ang   (atan dist (/ pas seg))			    ; Angle du plan de l'ellipse
dist2 (* r (cos (/ pi seg)))
ang2  (atan (/ dist (* 2 (sin ang))) dist2)	    ; Angle décrit par l'arc
axe   (ADD_Z axe (- (/ pas (* seg 2))))
Norm  (trans '(0 0 1) 1 0 T)				    ; Vecteur normal du plan XY du SCU
 )
 ;; Création du solide
 (repeat (abs seg)
   (setq axe	(ADD_Z axe (/ pas seg))
  pt2	(polar axe (+ (angle axe pt1) (/ pi seg)) r)
  N_axe	(trans axe 1 0)
  N_pt1	(trans pt1 Norm 0)
  N_pt2	(trans pt2 Norm 0)
  MajAx	(trans
	  (mapcar '-
		  (polar axe
			 (+ (angle axe pt2) (/ pi 2))
			 (/ r (sin ang))
		  )
		  axe
	  )
	  Norm
	  0
	)
  pt1	(ADD_Z (polar axe (+ (angle axe pt1) (/ (* 2 pi) seg)) r)
	       (/ pas (* seg 2))
	)
   )
   (foreach pt	'(N_pt1 N_pt2)
     (set pt
   (mapcar '+ (eval pt) (mapcar '- N_axe (trans axe Norm 0)))
     )
   )
   (setq arc (vla-addEllipse
	ModSp
	(vlax-3d-point N_axe)
	(vlax-3d-point MajAx)
	(sin ang)
      )
   )
   (vla-put-StartAngle arc (- (/ pi -2) ang2))
   (vla-put-EndAngle arc (+ (/ pi -2) ang2))
   (vla-Rotate3d
     arc
     (vlax-3d-point N_axe)
     (vlax-3d-point N_pt2)
     (if (= sens "Gauche")
(+ (/ pi 2) ang)
(- (/ pi 2) ang)
     )
   )
   (setq cercle (vla-addCircle ModSp (vlax-3d-point N_pt1) (/ bdn 2)))
   (vla-Rotate3d
     cercle
     (vlax-3d-point N_axe)
     (vlax-3d-point N_pt1)
     (- pi ang)
   )
   (setq region (car (vlax-safearray->list
		(vlax-variant-value
		  (vla-addRegion
		    ModSp
		    (vlax-SafeArray-fill
		      (vlax-make-safearray vlax-vbObject '(0 . 0))
		      (list cercle)
		    )
		  )
		)
	      )
	 )
   )
   (setq seg_lst (cons	(vla-addExtrudedSolidAlongPath ModSp region arc)
		seg_lst
	  )
   )
   (mapcar 'vla-erase (list cercle arc region))
 )
 (grtext -2 "Union des segments.")
 (mapcar '(lambda (x) (vla-Boolean (car seg_lst) acUnion x))
  (cdr seg_lst)
 )
 (setq spire (vlax-ename->vla-object (entlast)))
 ;; Création des spires suivantes
 (setq	sp_lst (vlax-SafeArray->list
	 (vlax-variant-value
	   (vla-ArrayRectangular spire 1 1 sp 0.0 0.0 (abs pas))
	 )
       )
 )
 (grtext -2 "Union des spires.")
 (mapcar '(lambda (x) (vla-Boolean spire acUnion x)) sp_lst)
 ;; Restauration de l'environnement
 (vla-endundomark AcDoc)
 (setq	*error*	m:err
m:err nil
 )
)


;;;****************************************************************************************************
;;; ALERT_TORS Ouvre une boite de dialogue prévenant des risques d'erreur de modélisation et permettant
;;; de choisir entre modifier les données, continuer la modélisation ou tout annuler.

(defun ALERT_TORS (/ dcl_id resp)
 (setq dcl_id (load_dialog "tors.dcl"))
 (if (not (new_dialog "alert_tors" dcl_id))
   (exit)
 )
 (foreach n '("0" "1" "3")
   (action_tile n "(setq resp (atoi $key))(done_dialog)")
 )
 (start_dialog)
 (unload_dialog dcl_id)
 resp
)

;;; ADD_Z Ajoute "val" à la coordonnée Z du point "pt" -accepte les points type (x y)-

(defun ADD_Z (pt val)
 (setq pt (trans pt 0 0))
 (list (car pt) (cadr pt) (+ (caddr pt) val))
)

;;; Redéfinition de *error*
(defun VL_TORS_ERR (msg)
 (if (or
(= msg "Fonction annulée")
(= msg "quitter / sortir abandon")
     )
   (princ)
   (princ (strcat "\nErreur: " msg))
 )
 (vla-endundomark AcDoc)
 (setq	*error*	m:err
m:err nil
 )
 (princ)
) 

 

 

Le fichier DCL des boites de dialogue à enregistrer sous Tors.dcl dans un dossier du chemin de recherche.

 

//Tors.dcl -Gilles Chanteau- 26/11/04
//Boite de dialogue de la fonction Tors

tors:dialog{
 label="Tors";
 initial_focus="nb_sp";
 :column{
   :boxed_column{
     label="Spires";
     :row{
       :edit_box{
         label="Segments par spire :";
         key="nb_seg";
         edit_width=4;
         allow_accept=true;
       }
       :slider{
         key="sldr_seg";
         min_value=2;
         max_value=24;
         big_increment=1;
         small_increment=1;
         width=16;
         is_tab_stop=false;
       } 
     }
     :edit_box{
       label="Nombre de spires (nombre entier) :";
       key="nb_sp";
       edit_width=4;
       allow_accept=true;
     }
   }
   :boxed_row{
     label="Pas de l'hélice";
     :radio_column{
       :radio_button{
         label="Pas à droite";
         key="drte";
         value="1";
       }
       :radio_button{
         label="Pas à gauche";
         key="gche";
       }
     }
     :edit_box{
       label="Valeur du pas:";
       key="val_pas";
       edit_width=8;
       fixed_width=true;
       allow_accept=true;
     }
   }
   :boxed_column{
     label="Dimensions";
     :edit_box{
       label="Diamètre extérieur du solide:";
       key="dia_ext";
       edit_width=8;
       allow_accept=true;
     }
     :edit_box{
       label="Diamètre du boudin:";
       key="dia_bdn";
       edit_width=8;
       allow_accept=true;
     }
   }
   :boxed_row{
     label="Base de l'axe";
       :row{
         :retirement_button{
           label="Choisir le point             key="b_axe";
           fixed_width=true;
           alignment=centered;
         }
       }
       :column{
         :edit_box{
           label="X:";
           key="x_coord";
           edit_width=10;
           allow_accept=true;
         }
         :edit_box{
           label="Y:";
           key="y_coord";
           edit_width=10;
           allow_accept=true;
         }
         :edit_box{
           label="Z:";
           key="z_coord";
           edit_width=10;
           allow_accept=true;
         }
       }
     }
   }
   ok_cancel;
 }

//alert_tors -Gilles Chanteau- 26/11/04
//Boite d'alerte de la fonction Tors

alert_tors:dialog{
 label="Message Tors";
 :column{
   :text{
     label="RISQUE D'ERREUR";
   }
   :paragraph{
     :text_part{
       label="Un diamètre de boudin supérieur au rayon du solide ou";
     }
     :text_part{
       label="à la valeur du pas peut faire échouer la modélisation.";
     }
   }
   spacer;
   :boxed_row{
     label="Souhaitez vous continuer ?";
     spacer;
     :button{
       fixed_width=true;
       label="Modifier";
       mnemonic="M";
       key="3";
     }
     :button{
       fixed_width=true;
       label="Continuer";
       mnemonic="C";
       key="1";
     }
     :button{
       fixed_width=true;
       label="Annuler";
       mnemonic="A";
       key="0";
       is_cancel=true;
     }
     spacer;
   }
 }
}

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

Créer un compte ou se connecter pour commenter

Vous devez être membre afin de pouvoir déposer un commentaire

Créer un compte

Créez un compte sur notre communauté. C’est facile !

Créer un nouveau compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant
×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer. Politique de confidentialité