Aller au contenu

Messages recommandés

Posté(e)

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 ...

Posté(e)

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

Posté(e)

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

Posté(e)

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...

Posté(e)

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

Posté(e)

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

 

Posté(e)

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 ...

Posté(e)

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...

 

 

Posté(e)

tu n'a pas besoin de comprendre le lisp pour t'en servir

il 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 application

tu va cherher ton lisp

 

une fois charger tu tappe make2d

 

et voila

 

 

Posté(e)

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 - x0

uy = y1 - y0

uz = z1 - z0

 

Les coordonnées de v sont :

vx = x2 - x0

vy = y2 - y0

vz = 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*vy

wy = uz*vx - ux*vz

wz = 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^u

vx = wy*uz - wz*uy

vy = wz*ux - wx*uz

vz = 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 / nu

nuy = uy / nu

nuz = uz / nu

Où nux, nuy, nuz correspond à la variable UCSXDIR du SCU défini par les points p0 p1 p2

 

nvx = vx / nv

nvy = vy / nv

nvz = vz / nv

Où nvx, nvy, nvz correspond à la variable UCSYDIR

 

nwx = wx / nw

nwy = wy / nw

nwz = wz / nw

Où 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 x0

nvx nvy nvz y0

nwx nwy nwz z0

0 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

Posté(e)
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

Posté(e)

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

Posté(e)

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

Posté(e)

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 2D

je 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 chemin

pour une aide éventuelle,

c'est quand même malheureux de ne rien comprendre...

 

amicalement

 

Posté(e)

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 ...

Posté(e)

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

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é