LISP : Aide et optimisation de commande.

LISP : Aide et optimisation de commande.

ftmanu777
Enthusiast Enthusiast
841 Visites
8 Réponses
Message 1 sur 9

LISP : Aide et optimisation de commande.

ftmanu777
Enthusiast
Enthusiast

Bonjour à tous,

Voila,
J'ai créé une commande pour tracer automatiquement des profils à partir d'un plan existant.

Pour se faire:

a-) sélection des lignes qui vont servir de repère pour dessiner les profils.

b-) sélection du plan (généralement en poly3D)

c-) la routine crée automatiquement les profils.

A priori la commande fonctionne très bien sauf dans le cas où il y a une superposition de sommet lors de la création de ces profils. Les dessins qui en résultent devient illogique.

Je vous invite à checker la commande (ci-dessous) que j'ai écrit avec un fichier .dwg (en PJ aussi) qui illustre ce que je veux faire, et me dire (voir apportez une modification) comment faire afin que même s'il y a une superposition de sommet, les dessins de profil se fassent d'une manière logique.

 

MERCI INFINIMENT,

 

(defun c:PROFIL3D	(/	 ssline	 sspoly3 cnt	 nbr
			 idx	 idx2	 name	 nameData
			 p1	 p2	 P3	 P4	 ent
			 EntLst	 lstsom	 revlstsom	 lstsom0
			 int	 dist1	 dist2	 distx	 rap1
			 rap2	 z	 zreel	 int2	 lstint2
			)
;;;dessin de polyligne 3D depuis une liste de point
;;;Source https://www.da-code.fr/
  (defun da:DessPoly3D (ptlist / pt)
    (entmake (list '(0 . "POLYLINE")
		   '(100 . "AcDbEntity")
		   '(100 . "AcDb3dPolyline")
		   '(70 . 8)
	     )
    )
    (repeat (length ptlist)
      (setq pt	   (car ptlist)
	    ptlist (cdr ptlist)
      )
      (entmake (list
		 '(0 . "VERTEX")
		 '(100 . "AcDb3dPolylineVertex")
		 (cons 10 pt)
		 '(70 . 32)
	       )
      )
    ) ;_ repeat
    (entmake '((0 . "SEQEND")))
  )
;;;Selection des lignes et des polylgnes 3D
  (setq
    ssline  (ssget '((0 . "LINE")))
    sspoly3 (ssget '((0 . "POLYLINE")))
  )
;;;Mise en place des conteurs pour les boucles
  (setq cnt 0)
  (setq nbr 0)
  (setq idx (sslength sspoly3))
;;;Première boucle pour les lignes
  (while (< cnt (sslength ssline))
    (setq
      name     (ssname ssline cnt)
      nameData (entget name)
      p1       (cdr (assoc 10 nameData))
      p2       (cdr (assoc 11 nameData))
    )
;;;Deuxième boucle pour les polys 3Ds
    (while (< nbr idx)
      (setq ent (ssname sspoly3 nbr))
;;;Troisième boucle pour enregistrer les sommets d'une poly3D
      (while
	(and
	  (setq ent (entnext ent))
	  (/= "SEQEND" (cdr (assoc 0 (setq EntLst (entget ent)))))
	)
	 (setq lstsom	 (cons (cdr (assoc 10 EntLst)) lstsom)
	       revlstsom (reverse lstsom)
	 )
;;;plaquage à Z = 0 des points contenues dans la liste "revlstsom"
	 (setq lstsom0
		(mapcar '(lambda (x) (mapcar '* '(1 1 0) x)) revlstsom)
	 )
      )
;;;Fin du troisième boucle
;;;Quatrième boucle qui évalue l'intersection entre la première ligne du premier boucle et les segments de la poly3D issue du troisième boucle
      (repeat (setq idx2 (length lstsom0))
	(setq idx2 (1- idx2))
	(setq
	  P3 (nth idx2 lstsom0)
	  P4 (nth (+ 1 idx2) lstsom0)
	)
	(if (= P4 nil)
	  (setq P4 (mapcar '+ '(0.1 0.1 0.0) P3))
	)
	(setq int (inters P1 P2 P3 P4 T))
;;;Calcul de l'atitude Z du point d'intersection
	(if (/= int nil)
	  (progn
	    (setq dist1	(distance (nth (+ 1 idx2) revlstsom)
				  (nth idx2 revlstsom)
			)
	    )
	    (setq dist2 (distance P4 P3))
	    (setq distx (distance P4 int))
	    (setq rap1 (/ distx dist2))
	    (setq rap2 (* dist1 rap1))
;;;propriété de Pythagore
	    (setq z (sqrt (- (* rap2 rap2) (* distx distx))))
;;;Z réel
	    (if	(< (last (nth (+ 1 idx2) revlstsom))
		   (last (nth idx2 revlstsom))
		)
	      (setq zreel (+ (last (nth (+ 1 idx2) revlstsom)) z))
	      (setq zreel (- (last (nth (+ 1 idx2) revlstsom)) z))
	    )
	    (setq int2 (subst zreel (last int) int))
	  )
;;;fin de progn
	)
;;;fin de if
      )
;;;fin du quatrième boucle "Repeat"
      (setq lstint2 (cons int2 lstint2))
;;;Trie des points contenues dans "lstint2" suivant X
      (setq lstint2
	     (vl-sort lstint2
		      (function	(lambda	(e1 e2)
				  (< (cadr e1) (cadr e2))
				) ;_ Fin de lambda
		      ) ;_ Fin de function
	     ) ;_ Fin de vl-sort
      ) ;_ Fin de setq
      (setq nbr (+ 1 nbr))
      (setq lstsom nil)
    )
;;;fin du deuxième boucle
    (da:desspoly3d lstint2)
    (setq lstint2 nil)
    (setq cnt (+ 1 cnt))
    (setq nbr 0)
  )
;;;fin de la première boucle
  (princ)
)
0 J'aime
Solutions acceptées (1)
842 Visites
8 Réponses
Replies (8)
Message 2 sur 9

Luna3
Advocate
Advocate

Coucou,

Je crois que tu as oublié le .dwg 😉 Cela sera plus simple de tester ce qui ne va pas avec le .dwg d'exemple. Et s'il y a moyen de montrer/pointer un endroit où cela ne fonctionne justement pas, chat serait top !

 

Bisous,
Luna

0 J'aime
Message 3 sur 9

ftmanu777
Enthusiast
Enthusiast

Mince alors… Où avais-je la tête ?

Le voici 🙂

0 J'aime
Message 4 sur 9

ftmanu777
Enthusiast
Enthusiast

J'ai oublié le fichier .dwg en question.

Le voici... 🙂 🙂 🙂

0 J'aime
Message 5 sur 9

CADaSchtroumpf
Advisor
Advisor

Bonjour,

Dans ton code tu tri tes points résultant selon l'ordre des X.

Si tu supprime les lignes suivantes de ton code, le résultat te semble probant?

;;;Trie des points contenues dans "lstint2" suivant X
      (setq lstint2
	     (vl-sort lstint2
		      (function	(lambda	(e1 e2)
				  (< (cadr e1) (cadr e2))
				) ;_ Fin de lambda
		      ) ;_ Fin de function
	     ) ;_ Fin de vl-sort
      ) ;_ Fin de setq
0 J'aime
Message 6 sur 9

ftmanu777
Enthusiast
Enthusiast

J'ai déjà songé à cette option mais il est possible que l'ordre auquel les éléments (les poly3Ds représentant le corps du dessin) dans le plan soient créés aléatoirement.

C'est pour ça que je les ai trié. Hélas! 😞

0 J'aime
Message 7 sur 9

CADaSchtroumpf
Advisor
Advisor

@ftmanu777  a écrit :

J'ai déjà songé à cette option mais il est possible que l'ordre auquel les éléments (les poly3Ds représentant le corps du dessin) dans le plan soient créés aléatoirement.

C'est pour ça que je les ai trié. Hélas! 😞


Alors il reste la solution de rajouter que lorsque les X sont égaux de trier selon le Y (ou le Z selon le SCU utilisé)

Mais il restera le problème que lorsqu'il y a un retour vers l'axe (cas de ta corniche) celui ne devrais pas être trié, mais cela est impossible il me semble à résoudre par programmation.

La solution qui me semblerait la plus pertinente, serait de sélectionner une à une et dans l'ordre tes polylignes 3D.

Il n'y aurait plus de tri à faire mais la sélection serait fastidieuse... mais le résultat serait correct!

Il faut faire un choix (impasse sur la corniche, ou sélection ordonnée)

0 J'aime
Message 8 sur 9

CADaSchtroumpf
Advisor
Advisor
Solution acceptée

Une possibilité pour avoir un résultat correct est d'utiliser les Xdatas

Dans ton fichier DWG j'ai rajouté l'application "ordre" au poly3D en ajoutant (dans l'ordre) un entier long:

0 à l'axe

n-1 vers la gauche

n+1 vers la droite

Ce qui me permet de re-classifier le jeu de sélection des poly3D afin que l'interpolation se fasse dans l'ordre.

L'attribution des Xdata aux poly3d est certes fastidieuse, mais elle sera définitive (elle peut, peut être, être faite automatiquement en amont de ta conception?  à voir!)

Utilise XDLIST des expresstool pour voir l'application appliqué aux 3dpoly.

 

Message 9 sur 9

ftmanu777
Enthusiast
Enthusiast
Hum... J'ai testé et ça fonctionne. Merci beaucoup...
Je vais exploiter ce que tu m'as proposé là. C'est très intéressant comme piste.
0 J'aime