culnuteurdebase Posté(e) le 16 août 2006 Posté(e) le 16 août 2006 Bonjour, Je cherche un moyen simple et rapide pour transformer une polyligne 3D plane vers une polyligne 2D orientée. je sais vous allez dire qu'il suffit de parcourir le forum pour repondre à ma question. Je cherche depuis quelques heures et la seule chose que j'ai trouvé c'est la commande flatten en EXPRESS. Cette solution ne convient pas à mon appli VBA La seule idée qui me vient actuellement c'est de recalculer le scu, de redefinir chaques points de ma poly3D par rapport à un plan 2D mais c'est assez fastidieus surtout que j'ai une dizaine de poly par plans :casstet: Quelqu'un a une autre idée à me proposer? ;) De base ...
Fraid Posté(e) le 17 août 2006 Posté(e) le 17 août 2006 Bonjour, j'ai sa qui traine dans ma biblotheque de lisp ;;; MAKE2D.lsp;;; Copyright © 1991, 1992 by Autodesk, Inc.;;;;;; Permission to use, copy, modify, and distribute this software and its;;; documentation for any purpose and without fee is hereby granted.;;;;;; THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.;;; ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF;;; MERCHANTABILITY ARE HEREBY DISCLAIMED.;;;;;; by Carl B. Bethea;;; 19 July 1991;;; Revised 1 May 92;;;;;;--------------------------------------------------------------------------;;;; DESCRIPTION;;;;;; This program converts 3Dpolines into 2D polylines with elevation.;;; It works by writing a DXF file containing the converted information.;;; The file is then imported, creating 2D plines on a layer named;;; "--2DPOLY--". Having new entities on this layer, rather than directly;;; modifying the exisitng entities, gives you the chance to compare the;;; new entities with the orginals. If the new entities need editing to;;; in order to more closely match the previous entities, you can change;;; the 2D plines before deleting the 3Dpolines.;;;;;; If you want to change the layer name for the 2D plines, then change the;;; name on line 172, below.;;;;;;;;;--- dxf ---------------------------------------------------;;; get the value of the dotted pair(defun dxf (x) (cdr(assoc x data)));;;;;;--- dxfmod ------------------------------------------------;;; modify association list data;;;(defun dxfmod (code new)(setq data (subst (cons code new) (assoc code data) data )));dxfmod;;;;;;;;;--- ifbit -------------------------------------------------;;; if bit is set, return true;;;(defun ifbit (x y) (= x (logand y x)));;;;;;--- putfile -----------------------------------------------;;; write association list to DXF file;;;(defun putfile (/ code) (foreach x (cdr data) ; take out ename (cond ((/= -1 (setq code (car x)) -2) (prin1 code fh) (write-char 10 fh) (setq x (cdr x)) (cond ((= 'STR (type x)) (write-line x fh) ) ((= 'LIST (type x)) (prin1 (car x) fh) (print (+ code 10) fh) (print (cadr x) fh) (print (+ code 20) fh) (print (caddr x) fh) (write-char 10 fh) ) (T (prin1 x fh) (write-char 10 fh) ) ) ) (T nil) ) ));;;;;;--- new_z -------------------------------------------------;;; replace Z in point list with the same as the header Z;;;(defun new_z (z) (dxfmod 10 (reverse (cons z (cdr (reverse (dxf 10))) ) ) ));;;--- make2d ------------------------------------------------;;; convert to 2D pline;;;(defun make2d (ent lyr / z) (if (ifbit 8 (dxf 70)) (progn ;; write the header (dxfmod 70 (- (dxf 70) 8)) ;change header group 70 (dxfmod 8 lyr) (setq z (cadddr (assoc 10 (entget (entnext ent))))) (grtext -1 (strcat "ELV: " (rtos z))) (new_z z) (putfile) ;; write the vertex and seqend (while (and (/= "SEQEND" (dxf 0)) (setq data (entget (setq ent (entnext ent)))) ) (dxfmod 8 lyr) (if (/= "SEQEND" (dxf 0)) (progn (dxfmod 70 (- (dxf 70) 32)) ;change vertex group 70 (new_z z) ) ) (putfile) );while );progn );if);;;make3d;;;;;;--- c:make2d ----------------------------------------------;;;;;; internal global contain ent assos list;;;(defun c:make2d (/ ss n i ent data fn fh) (prompt "\nConvert 3Dpoly to polylines ...") (setq ss (ssget) n (sslength ss) i 0 fn (if (= "" (setq fn (getstring "\nDXF filename : ")) ) "make2d" fn ) fh (if (setq fh (open (strcat fn ".dxf") "w")) fh (prompt (strcat "Cannot open " fn)) ) ) (if fh (progn (foreach x '( "0" "SECTION" "2" "ENTITIES") (write-line x fh) ) ) ) (while (and fh ss (< i n) (setq ent (ssname ss i)) ) (prompt (strcat "\rWorking, completed " (itoa i) " of " (itoa n )".")) (setq data (entget ent)) (if (= (dxf 0) "POLYLINE") (make2d ent "--2DPOLY--") ) (setq i (1+ i)) ) (if fh (progn (foreach x '( "0" "ENDSEC" "0" "EOF") (write-line x fh) ) (close fh) (command "dxfin" fn) ) );if (princ));;;--- end of file ----------------------------------------------- peut etre que cela vat t'aider bon courage https://github.com/Fraiddd
(gile) Posté(e) le 17 août 2006 Posté(e) le 17 août 2006 Salut, Je ne suis pas sûr de bien comprendre, veux-tu aligner ta poly sur un autre plan, ou la projeter sur ce plan ? Dans le premier cas, la commande _align ou, en VBA/Vlisp la méthode TransformBy (voir cesujet) devraient faire l'affaire. Dans le deuxième cas, il faut effectivement projeter chaque sommet sur le plan, ce qui, en programmation n'est "fastidieux" qu'une fois. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
culnuteurdebase Posté(e) le 17 août 2006 Auteur Posté(e) le 17 août 2006 En fait j'ai une polyligne 3D qui est plane dans l'espace. Je voudrais pouvoir la transformer en une polyligne 2D orienté de manière à ce que ma nouvelle poly2D soit à la meme place http://img225.imageshack.us/img225/2866/poly3dto2dwq8.jpg Ici j'i 4 polylignes 3D fermées et je voudrai obtenir des poly2D orientées avec élévation et tout ce qui suit mais exactement au meme endroit et sans déformation. Mais la j'en demande peut etre beaucoup juste après la fin des vacances debase...
(gile) Posté(e) le 17 août 2006 Posté(e) le 17 août 2006 Re, En LISP, je ne connais pas le VBA. La polyligne optimisée est créée dans le plan défini par les trois premiers points non colinéaires de la poly 3d et à l'élévation du premier point (au cas ou la poly 3D ne serait pas plane). ;;;**** SOUS-ROUTINES ****;;; ;;; 3d-coord->pt-lst Convertit une liste de coordonnées 3D en liste de points ;;; (3d-coord->pt-lst '(1.0 2.0 0.0 4.0 5.0 0.0)) -> ((1.0 2.0 0.0) (4.0 5.0 0.0)) (defun 3d-coord->pt-lst (lst) (cond ((atom lst) lst) ((cons (list (car lst) (cadr lst) (caddr lst)) (3d-coord->pt-lst (cdddr lst)) ) ) ) ) ;;; V^V Retourne le produit vectoriel de deux vecteurs (defun v^v (v1 v2) (if (inters '(0 0 0) v1 '(0 0 0) v2) (mapcar '(lambda (a b c d) (- (* a b) (* c d))) (reverse (cons (car v1) (reverse (cdr v1)))) (cons (last v2) (reverse (cdr (reverse v2)))) (reverse (cons (car v2) (reverse (cdr v2)))) (cons (last v1) (reverse (cdr (reverse v1)))) ) ) ) ;;; NORM_3PTS retourne le vecteur normal du plan défini par 3 points (defun norm_3pts (org xdir ydir / norm) (foreach v '(xdir ydir) (set v (mapcar '- (eval v) org)) ) (mapcar '(lambda (x) (/ x (distance '(0 0 0) norm))) (setq norm (v^v xdir ydir)) ) ) ;;; GETSPACE Retourne l'espace courant (Modèle ou Papier) (defun getspace () (if (= (getvar "CVPORT") 1) (vla-get-PaperSpace (vla-get-activedocument (vlax-get-acad-object)) ) (vla-get-ModelSpace (vla-get-activedocument (vlax-get-acad-object)) ) ) ) ;;;**** ROUTINE PRINCIPALE ****;;; ;;; 3D2LW Crée une lwpolyligne sur une poly 3D plane (defun c:3d2lw (/ ss ent p1 p2 p3 n pt_lst norm elev pt) ;; Sélection d'une polyligne 3D (while (not (setq ss (ssget "_:S:E" '((0 . "POLYLINE") (-4 . "&") (70 . 9) ) ) ) ) ) ;; ent : 3Dpolyline object (setq ent (vlax-ename->vla-object (ssname ss 0))) ;; pt_lst : liste des sommets de la polyligne 3D (setq pt_lst (3d-coord->pt-lst (vlax-get ent 'coordinates))) ;; p1 : premier sommet de la polyligne 3D (setq p1 (car pt_lst)) ;; p2 : second sommet de la polyligne 3D (setq p2 (cadr pt_lst)) ;; p3 = p2 -temporaire- (setq p3 p2) ;; n : compteur (setq n 1) ;; on cherche p3 tel qu'il ne soit pas colinéaire avec le segment p1 p2 (while (and ( (not (inters p1 p2 p1 p3)) ) (setq p3 (nth (setq n (1+ n)) pt_lst)) ) ;; norm : normale du plan -la sous routine norm_3pts est définie plus haut- (setq norm (norm_3pts p1 p2 p3)) ;; elev : la coordonnée z de la traduction de 0,0,0 du SCG vers le SCO de la poly ;; oté de la coordonnée z de la traduction de p1 du SCG vers le SCO de la poly (setq elev (- (caddr (trans p1 0 norm)) (caddr (trans '(0 0) 0 norm))) ) ;; transformation de la liste des sommets de la poly 3D en liste de coordonnées 2D ;; dans le SCO (argument pour addLightWeightPolyline) (setq pt_lst (apply 'append (mapcar '(lambda (pt) (list (car (trans pt 0 norm)) (cadr (trans pt 0 norm))) ) pt_lst ) ) ) ;; début du groupe d'annulation (vla-StartUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)) ) ;; création de la lwpolyligne (setq pline (vlax-invoke (getspace) 'addLightWeightPolyline pt_lst) ) ;; Changement de la Normale de la lwpolyligne (vla-put-Normal pline (vlax-3d-point norm)) ;; Changement de l'élévation (vla-put-Elevation pline elev) ;; fermeture de la polyligne (if (= (vla-get-closed ent) :vlax-true) (vla-put-closed pline :vlax-true) ) ;; Si on veut supprimer la poly 3D : oter les points virgule ;; (vl-delete ent) ;; fin du groupe d'annulation (vla-EndUndoMark (vla-get-ActiveDocument (vlax-get-acad-object)) ) (princ) ) (princ "\n3d2lw chargé. Taper 3d2lw pour lancer la commande." ) (princ) [Edité le 18/8/2006 par (gile)] Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
culnuteurdebase Posté(e) le 17 août 2006 Auteur Posté(e) le 17 août 2006 et moi j'y connais rien en lisp mais bon je pense que la méthode est bonneje vais m'en inspirer Un grand merci à toute la communauté CADXXX, merci. :P :P :P :P debase ...
didier Posté(e) le 17 août 2006 Posté(e) le 17 août 2006 coucou, je n'ai rien compris, c'est quoi une polyligne orientée ? avec élévation, mais laquelle ? sans déformation, par rapport à quoi ? on garde les X, les Y, quel Z ? ???? je veux bien voir en VBA, mais s'il me faut un dictionnaire de français, j'arrête. amicalement Éternel débutant... Mon site perso : Programmer dans AutoCAD
culnuteurdebase Posté(e) le 18 août 2006 Auteur Posté(e) le 18 août 2006 une polyligne orientée : ;) -> polyligne 2d suivant un plan orienté (repère utilisateur) en fait , dans la démarche il faut ( en théorie et en VBA ) : -> affecter un repère utilisateur à la polyligne 3D ( ici ma poly3D sera plane)-> retrouver la matrice de convertion avec "GetUCSMatrix"-> Convertir les points de ma poly3D grace à cette matrice-> Ne conserver que les éléments utiles pour passage en poly2D Moi en ce moment j'en suis encore à definir le repère utilisateur .... :P d'ailleur si quelqu'un sait comment on fait [surligneur] à partir de 3 points pour definir un repère en VBA je suis preneur[/surligneur] Merci .... :exclam: DEBASE ...
Fraid Posté(e) le 18 août 2006 Posté(e) le 18 août 2006 bonjour, j'aimerai bien savoir pourquoi tu tiens absolument a faire cela en vba? repere orienté? c'est du SCU dont tu parle? a tu essayé les lisp de Giles qui m'on l'aire efficace? https://github.com/Fraiddd
culnuteurdebase Posté(e) le 18 août 2006 Auteur Posté(e) le 18 août 2006 le problème c'est que dans mon appli c'est tout en vba et que malheureusement j'y connais rien en lisp... Le lisp et moi ca fait 2. Je sais meme pas comment on execute un programme :P alors pour la suite, le modifier pour le faire fonctionner dans mon prog c'est pas gagné Si une ame charitable veut bien me traduitre en francais ce que fait le programme je pourrai peut-etre m'en sortir sans trop avoir mal à la tête... debase...
Fraid Posté(e) le 18 août 2006 Posté(e) le 18 août 2006 tu n'a pas besoin de comprendre le lisp pour t'en serviril te suffit juste de le charger si tu veux essayer le lisp que je t'ai donner au debut du post tu le copie dans n'importe editeur de texte et tu enregistre sous make2d.lsp puis dans autocad tu vas dans outil/charger une applicationtu va cherher ton lisp une fois charger tu tappe make2d et voila https://github.com/Fraiddd
(gile) Posté(e) le 18 août 2006 Posté(e) le 18 août 2006 Salut, Je vais essayer d'expliquer comment, à partir de trois points définissant un plan (donc non-alignés), on peu définir un système de coordonnées, comme le fait l'option 3points de la commande SCU. Les trois points sont : - l'origine du système de coordonnées, p0 de coordonnées : x0, y0, z0- un point sur l'axe des X, p1 de coordonnées x1, y1, z1- un point dans la zone des Y positifs p2 de coordonnées x2, y2, z2 Les segments p0p1 et p0p2 ne sont pas nécessairement perpendiculaires, mais la position de p2 par rapport au segment p0p1 (zone des Y positifs) influe sur la direction de l'axe Z par rapport an plan (règle de la main droite) http://img155.imageshack.us/img155/2758/normalesl4.png Un peu de calcul vectoriel. Le vecteur normal du plan est le vecteur unitaire (de 1 unité) perpendiculaire à ces deux vecteurs. On le calcule en faisant le produit vectoriel de deux vecteurs non parallèles définissant le plan, puis en ramenant sa norme (grandeur) à une unité. Il s'agit, dans un premier de définir les vecteurs u et v, déplacements de p0 en, respectivement p1 et p2, en efectuant, sur les coordonnées, une somme vectorielle (ici une soustraction). Les coordonnées de u sont :ux = x1 - x0uy = y1 - y0uz = z1 - z0 Les coordonnées de v sont :vx = x2 - x0vy = y2 - y0vz = z2 - z0 Le produit vectoriel de u par v (noté u^v) est le vecteur w dont les coordonnées sont :wx = uy*vz - uz*vywy = uz*vx - ux*vzwz = ux*vy - uy*vx On peut procéder de même pour redéfinir le vecteur v, afin qu'il soit perpendiculaire à u et w, en faisant v = w^uvx = wy*uz - wz*uyvy = wz*ux - wx*uzvz = wx*uy - wy*ux Il faut maintenant transformer les trois vecteurs u, v et w en vecteurs unitaire en effectuant sur chacun le produit du vecteur par un scalaire le scalaire est ici un nombre réel représentant l'inverse de la norme du vecteur.Pour le vecteur u, par exemple, sa norme (nu) est égale à la distance du point 0,0,0 au point de coordonnées ux,uy,uz. nux = ux / nunuy = uy / nunuz = uz / nuOù nux, nuy, nuz correspond à la variable UCSXDIR du SCU défini par les points p0 p1 p2 nvx = vx / nvnvy = vy / nvnvz = vz / nvOù nvx, nvy, nvz correspond à la variable UCSYDIR nwx = wx / nwnwy = wy / nwnwz = wz / nwOù nwx, nwy, nwz correspond à la direction d'extrusion de ce SCU (que j'appelle souvent ucszdir) La matrice de transformation peut s'écrire ; nux nuy nuz x0nvx nvy nvz y0nwx nwy nwz z00 0 01 Voilà, j'espère avoir été clair (et ne pas m'être trompé).En LISP les fonctions permettant les opérations sur les listes facilitent beaucoup ce type de calculs, je ne sais pas ce qu'il en est en VBA, bon courage ... [Edité le 21/8/2006 par (gile)] Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Fraid Posté(e) le 18 août 2006 Posté(e) le 18 août 2006 t'a fait mathsup giles? :exclam: https://github.com/Fraiddd
(gile) Posté(e) le 18 août 2006 Posté(e) le 18 août 2006 t'a fait mathsup giles? Non, je suis menuisier, mais je me suis toujours intéressé à la géométrie, je pense que c'est un plus d'en connaître un peu quand on fait du dessin/traçage que ce soit sur une table à dessin, un ordinateur ou une pièce à usiner, et quand on joue à faire un peu de programmation en DAO, ça me paraît indispensable. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Fraid Posté(e) le 18 août 2006 Posté(e) le 18 août 2006 et ben bravoquand on voit le bouleau que ta fait sur les matrices on ne peut qu'etre admiratif https://github.com/Fraiddd
(gile) Posté(e) le 18 août 2006 Posté(e) le 18 août 2006 Merci :red: En fait, je m'entraine, je dois bientôt donner des cours de maths (géométrie) et de dessin technique/géométrie descriptive dans le cadre d'une formation de régisseurs de spectacle. Pour Culnuteurdebase, J'ai abondamment commenté le LISP que je donne plus haut, si ça peut t'aider... Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
didier Posté(e) le 18 août 2006 Posté(e) le 18 août 2006 hello, je n'ai pas suivi toute ton explication,car j'utilise plus souvent TRANS pour transformer mes coordonnées.en VBA, c'est ressemblant. toujours est il qu'on ne sait toujours pas ce qu'est une polyligne 2D orientée ???? amicalement Éternel débutant... Mon site perso : Programmer dans AutoCAD
(gile) Posté(e) le 18 août 2006 Posté(e) le 18 août 2006 J'utilise aussi trans, dans le LISP que je donne, je ne me sert pas de matrice de transformation, mais pour trans-former les coordonnées des sommets de la polyligne 2D, définies dans le SCG en coordonnées pour une lwpolyligne (ou polyligne 2d) définies dans son SCO, on est bien obligé de calculer ce "SCO" à partir de trois sommets de la polyligne 3D. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
didier Posté(e) le 18 août 2006 Posté(e) le 18 août 2006 hello, je viens de relire tous les messages de ce post,mea culpa maxima.je vais arrêter pour ce soir, j'ai les fils qui se touchent...si le courage me revient je m'y colle rassure moi si j'ai bien compris, par exemple la polyligne 3D est une tôle verticale,on veut obtenir la vue 2D ce cet objet donc une polyligne 2Dje ne vois pas l'utilité du SCU Objet, mais c'est autre chose. si je suis hors sujet, merci de me remettre dans le droit cheminpour une aide éventuelle,c'est quand même malheureux de ne rien comprendre... amicalement Éternel débutant... Mon site perso : Programmer dans AutoCAD
culnuteurdebase Posté(e) le 18 août 2006 Auteur Posté(e) le 18 août 2006 il y a de ca.. je crois qu'on commence à ce comprendre. Désolé de ne pas etre super clair mais lorsqu'on parle du plaquage d'une poly3D sur un plan 2D donné afin d'obtenir une poly2D forcément ca devient compliqué à expliquer. Bon j'arrète je veux pas te conduire au surmenage ... Debase ...
(gile) Posté(e) le 18 août 2006 Posté(e) le 18 août 2006 Si j'ai bien compris de mon côté, il s'agit de créer une polyligne 2D sur une polyligne 3D plane dans le plan de celle-ci (ce qui équivaudrait à transformer la polyl 3D en poly 2D si on supprimait la poly 3D).C'est ce que le LISP proposé fait. Pour se faire, je vois mal comment faire sans calculer la normale du plan de la polyligne 3D.S'il existe un autre moyen, je serais enchanté de le connaître... [Edité le 19/8/2006 par (gile)] Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
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