(gile) Posté(e) le 29 avril 2007 Partager Posté(e) le 29 avril 2007 Ça avait commencé ici. J'ai essayé d'aboutir un peu mieux une routine qui permet de dessiner des polylignes 3D avec des arcs. Les arcs sont en fait une successions de segments droits dont le nombre par arc est défini par l'utilisateur au lancement de la routine. Le nombre d'arc par défaut est mémorisé dans le dessin. Les coordonnées des sommets sont calculées en fonction de l'arc plan projeté sur le plan XY du SCU courant, cet arc est déterminé par ses points de départ et de fin et sa tangente au départ. Par défaut l'arc est tangent au segment précédent (comme pour une polyligne) l'utilisateur peut spécifier une autre direction (comme l'option direction des polylignes). L'altitude de chaque sommet est calculé par interpolation linéaire en fonction de l'altitude des polints de départ et de fin (les sommets s'inscrivent sur un arc hécoïdal). La polyligne n'est créée qu'après validation (Entrée, Espace ou clic droit), pendant sa construction elle est affichée en "surbrillance", il est possible d'annUler une ou plusieurs opérations. Taper 3dpolyarc pour lancer la commande et suivre les indications de la ligne de commande. En images :en gris une polyligne 2D sélectionnée figure la projection de la polyligne 3D qui va passer par les extrémités des lignes verticales. http://img479.imageshack.us/img479/2445/poly3d1fq9.png http://img19.imageshack.us/img19/4493/poly3d2cc5.png http://img265.imageshack.us/img265/8070/poly3d3lg5.png le code : ;;; 3dPolyArc -Gilles Chanteau- 29/04/07 ;;; Crée une polyligne 3D. ;;; En option "Arc" les sommets s'inscrivent sur une hélicoïde, ;;; - leur altitude est calculée par interpolation linéaire en fonction ;;; de l'altitude des points de départ et de fin. ;;; - la courbure est celle de l'arc défini par la projection de ces points ;;; sur le plan XY du SCU courant et la tangente au départ de l'arc ;;; (tangent au dernier segment ou à la direction spécifiée). (defun c:3dPolyArc (/ 3dPolyArc_err drawvecs segmentundo AcDoc ModSp prec p1 p2 tg opt plst tglst cnt ) (vl-load-com) ;;***********************************************************;; (defun 3dPolyArc_err (msg) (if (= msg "Fonction annulée") (princ) (princ (strcat "\nErreur: " msg)) ) (redraw) (vla-EndUndoMark AcDoc) (setq *error* m:err m:err nil ) (princ) ) ;;***********************************************************;; (defun drawvecs (lst) (setq p1 (last lst)) (redraw) (if ( (grvecs (apply 'append (mapcar '(lambda (x1 x2) (list -255 x1 x2) ) (reverse (cdr (reverse lst))) (cdr lst) ) ) ) ) ) ;;***********************************************************;; (defun segmentundo () (if ( (prompt "\nTous les segments ont déjà été annulés.") (setq plst (sublst plst 1 (- (length plst) (car cnt))) tglst (cdr tglst) cnt (cdr cnt) ) ) ) (setq AcDoc (vla-get-ActiveDocument (vlax-get-acad-object)) ModSp (vla-get-ModelSpace AcDoc) m:err *error* *error* 3dPolyArc_err ) (vla-StartUndoMark AcDoc) (if (not (vlax-ldata-get "interpoly3d" "prec")) (vlax-ldata-put "interpoly3d" "prec" 20) ) (prompt (strcat "\nParamètre courant - Nombre de segments par arc: " (itoa (vlax-ldata-get "interpoly3d" "prec")) ) ) (while (not (vl-consp p1)) (initget 1 "Segments") (setq p1 (getpoint "\nSpécifiez le point de départ de la polyligne ou [segments]: " ) ) (if (= p1 "Segments") (progn (initget 6) (if (setq prec (getint (strcat "\nSpécifiez le nombre de segments pour les arcs (itoa (vlax-ldata-get "interpoly3d" "prec")) ">: " ) ) ) (vlax-ldata-put "interpoly3d" "prec" prec) ) ) ) ) (setq prec (vlax-ldata-get "interpoly3d" "prec") plst (cons p1 plst) cnt (cons 1 cnt) loop1 T ) (while loop1 (initget "Arc annUler") (setq p1 (last plst) p2 (getpoint p1 "\nSpécifiez l'extrémité de la ligne ou [Arc/annUler]: " ) ) (if p2 (progn (if (= p2 "annUler") (segmentundo) (if (= p2 "Arc") (progn (if (null tglst) (progn (initget 1) (setq tglst (cons (getorient p1 "\nSpécifiez la direction de la tangente pour le point de départ de l'arc: " ) tglst ) ) ) ) (setq loop2 T) (while loop2 (setq p2 p1) (while (equal p1 p2 1e-9) (initget "Direction Ligne annUler") (setq p2 (getpoint p1 "\nSpécifiez l'extrémité de l'arc ou [Direction/Ligne/annUler]: " ) ) ) (if p2 (if (= p2 "Ligne") (setq loop2 nil) (if (= p2 "annUler") (progn (segmentundo) (drawvecs plst) ) (if (= p2 "Direction") (progn (initget 1) (setq tglst (cons (getorient p1 "\nSpécifiez la direction de la tangente pour le point de départ de l'arc: " ) tglst ) ) ) (progn (setq new (interpol (last plst) p2 (car tglst) prec ) plst (append plst new) cnt (cons (length new) cnt) ) (drawvecs plst) ) ) ) ) (setq loop2 nil loop1 nil ) ) ) ) (setq plst (append plst (list p2)) tglst (cons (angle p1 p2) tglst) cnt (cons 1 cnt) ) ) ) (drawvecs plst) ) (setq loop1 nil) ) ) (if ( (vlax-invoke ModSp 'add3dPoly (apply 'append (mapcar '(lambda (p) (trans p 1 0)) plst)) ) ) (redraw) (vla-EndUndoMark AcDoc) (setq *error* m:err m:err nil ) (princ) ) (defun interpol (pt1 pt2 tg prec / alt1 alt2 p1 p2 mid cen rad ang i_ang i_alt n p_int ptlst ) (setq alt1 (caddr pt1) alt2 (caddr pt2) ) (mapcar '(lambda (p pt) (set p (list (car pt) (cadr pt) 0.0))) '(p1 p2) (list pt1 pt2) ) (setq mid (mapcar '(lambda (x1 x2) (/ (+ x1 x2) 2)) p1 p2)) (if (setq cen (inters p1 (polar p1 (+ tg (/ pi 2)) 1.0) mid (polar mid (+ (angle p1 p2) (/ pi 2)) 1.0) nil ) ) (progn (setq rad (distance cen p1) ang (ang ) (if ( (setq ang (- ang (* 2 pi))) ) (setq i_ang (/ ang prec) i_alt (/ (- alt1 alt2) prec) n 0 ) (repeat prec (setq p_int (polar cen (- (angle cen p2) (* i_ang n)) rad) p_int (list (car p_int) (cadr p_int) (+ alt2 (* i_alt n))) ptlst (cons p_int ptlst) n (1+ n) ) ) (setq tglst (cons (+ tg ang) tglst)) ) (setq ptlst (list pt2) tglst (cons (+ tg (angle p1 p2)) tglst) ) ) ptlst ) ;;; Ang (defun ang (if (and ( ang (ang ) ) ;;; SUBLST Retourne une sous-liste ;;; Premier élément : 1 ;;; (sublst '(1 2 3 4 5 6) 3 2) -> (3 4) ;;; (sublst '(1 2 3 4 5 6) 3 nil) -> (3 4 5 6) (defun sublst (lst start leng / rslt) (if (not ( (setq leng (- (length lst) (1- start))) ) (repeat leng (setq rslt (cons (nth (1- start) lst) rslt) start (1+ start) ) ) (reverse rslt) ) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD Lien vers le commentaire Partager sur d’autres sites More sharing options...
cdi Posté(e) le 30 avril 2007 Partager Posté(e) le 30 avril 2007 salut gile Personnellement comme d'autres j'ai révé d'un tel outil merci gile ...................je vais le tester dans la journée Lien vers le commentaire Partager sur d’autres sites More sharing options...
lecrabe Posté(e) le 30 avril 2007 Partager Posté(e) le 30 avril 2007 Hello (gile) Un seul mot : BRAVO :) :D :cool: Il y a un truc qui m'énerve ENORMEMENT chez Autodesk :Ils conçoivent des améliorations en 2D et 2D dans le noyau d'AutoCAD, et donc - Pourquoi n'ont ils jamais prévu de faire des ARCs en 3D ? - Pouquoi les objets 3D ont toujours le type de ligne CONTINUOUS ? Je ne sais plus quand les 3DPOLY sont apparues ?!Vu de loin je pense que c'est avec AutoCAD R11 ... :exclam: Le Decapode [Edité le 30/4/2007 par lecrabe] Autodesk Expert Elite Team Lien vers le commentaire Partager sur d’autres sites More sharing options...
Bred Posté(e) le 30 avril 2007 Partager Posté(e) le 30 avril 2007 Salut,Personnellement, pour réaliser des polignes 3D avec arc, j'utilisais le lissage (mais les courbes sont réalisées tangeantes au sommets...donc on les perdait (les sommets) !.. et il fallait les "retravailler" ensuite....)encore merci (gile) !http://xs114.xs.to/xs114/07181/poly3d1.JPG http://xs114.xs.to/xs114/07181/poly3d2.JPG Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose... Lien vers le commentaire Partager sur d’autres sites More sharing options...
nazemrap Posté(e) le 30 avril 2007 Partager Posté(e) le 30 avril 2007 Bonjour, En fait, ce n'est pas une réponse, mais une question.Le fait d'obtenir une polyligne 3d est-il plus intéressant qu 'un spline.C' est en fait ce que j' utilise (la spline) pour récupérer en vba la ligne de chant supérieur des limons courbe balancées.. Cordialement Lien vers le commentaire Partager sur d’autres sites More sharing options...
(gile) Posté(e) le 30 avril 2007 Auteur Partager Posté(e) le 30 avril 2007 D'abord merci pour les compliments, mais n'allez pas trop vite, essayez la fonction qui est loin d'être parfaite. Faire l'équivalent des "arcs" avec les poly 3d est une gageure et oblige à quelques choix arbitraires concernant la figure résultante. J'avais fait ici une version assez proche dont les parties en "arcs" s'inscrivent sur un arc de cercle plan défini par 3 points (3 points sur l'arc ou les extrémités et le centre). Le choix ici, est d'avoir des arcs de cercles en projection sur plan XY en s'appuyant sur la tangente à l'extémité du point suivant, il est tout aussi arbitraire que le précédent et les deux sont autant "valables". En l'état, le calcul de l'altitudes des sommets des segments figurant les arcs se faisant par interpolation linéaire entre les deux extrémités il peut y avoir des "ruptures de pente" entre les arcs. nazemrap, ni le LISP donné ici, ni celui donné dans le lien ne font des polylignes 3D semblables à une spline, ils essayent juste d'imiter les polylignes 2D. Les splines sont des courbes issus de calculs beaucoup plus complexes. Un des intérêts des polylignes 3D était surtout évident avant la version 2007 où c'était le seul objet non-plan pouvant servir de chemin d'extrusion. Si on veut faie des poly 3d comme des splines on peut utiliser : 3dPolySpline, qui par un habile artifice crée une poly 3d de la même façon qu'on fait une spline. (defun c:3dpolyspline (/ pt nb spl fpts len1 len2 lseg cnt plst n cl poly) (vl-load-com) (or (vlax-ldata-get "3dPolySpline" "n") (vlax-ldata-put "3dPolySpline" "n" 20) ) (setvar "cmdecho" 0) (prompt (strcat "\nParamètre courant - Nombre de segments entre chaque point de lissage: " (itoa (vlax-ldata-get "3dPolySpline" "n")) ) ) (while (not (and (setq pt (getpoint "\nSpécifiez le premier point ou : ") ) (listp pt) ) ) (initget 7) (setq nb (getint (strcat "\nSpécifiez le nombre de segments entre chaque point de lissage: " ) ) ) (vlax-ldata-put "3dPolySpline" "n" nb) ) (setq nb (vlax-ldata-get "3dPolySpline" "n")) (command "_.spline" pt) (setvar "cmdecho" 1) (while (/= 0 (getvar "CMDACTIVE")) (command pause) ) (setq spl (vlax-ename->vla-object (entlast))) (setq fpts (3d-coord->pt-lst (vlax-get spl 'Fitpoints))) (setq len1 (vlax-curve-getDistAtParam spl (vlax-curve-getEndParam spl)) ) (repeat (setq n (1- (length fpts))) (setq len2 (vlax-curve-getDistAtPoint spl (nth (1- n) fpts)) lseg (/ (- len1 len2) nb) cnt 0 ) (repeat nb (setq plst (cons (vlax-curve-getPointAtDist spl (- len1 (* cnt lseg))) plst ) cnt (1+ cnt) ) ) (setq n (1- n) len1 len2 ) ) (setq plst (cons (car fpts) plst)) (if (= (vla-get-Closed spl) :vlax-true) (setq plst (reverse (cdr (reverse plst))) cl T ) ) (setq poly (vlax-invoke (vla-get-modelSpace (vla-get-ActiveDocument (vlax-get-acad-object)) ) 'add3dPoly (apply 'append plst) ) ) (and cl (vla-put-Closed poly :vlax-true)) (vla-delete spl) (princ) ) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD Lien vers le commentaire Partager sur d’autres sites More sharing options...
(gile) Posté(e) le 30 avril 2007 Auteur Partager Posté(e) le 30 avril 2007 Un exemple en images sera sûrment plus parlant que mes confuses explications. 4 vues,Droite et Face en haut ; Isometrie SE et Dessus en bas : avec 3dPolyArc, en partant du niveau 0, un premier segment droit et deux autres en arc comme la poly 2d (en gris) http://img409.imageshack.us/img409/2982/3dpolyarcab0.png avec 3dPolySpline http://img296.imageshack.us/img296/6577/3dpolysplinerv6.png Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD Lien vers le commentaire Partager sur d’autres sites More sharing options...
Messages recommandés
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 compteSe connecter
Vous avez déjà un compte ? Connectez-vous ici.
Connectez-vous maintenant