Aller au contenu

[Résolu]Fonction "measure" en Vlisp


alala

Messages recommandés

Bonjour,

 

continuant mon apprntissage du Lisp et Vlisp grâce à ce forum je tombe auojourd'hui sur un soucis de lenteur (voir de blocage).

 

En effet, tentant de reproduite la commande measure (dans le but d'accélerer celle-ci et de ne plus avoir les messages d'erreurs des objet "trop cours" et de ne paire que ce dont j'ai besoin) j'ai tenter de remplacer ceci :

(defun PPPoly ( / ss nb i NumEnt) ;Points sur les objets linéaires

(setq ss (ssget "_C" (getvar "extmin") (getvar "extmax") '((0 . "2DPOLYLINE,3DPOLYLINE,ARC,LINE,LWPOLYLINE,MLINE,SPLINE,XLINE")(410 . "MODEL")))) ;on filtre
;(command "-calque" "g" "*" "")
(setq nb (sslength ss)) ;on compte le nombre d'ojets sélectionnés
(setq i 0)
(while (< i nb) ; tan que l'on a pas fait tous les objets
	(command "_.measure" (ssname ss i) 1)
	;(command "_.erase" (ssname ss i) "")
	(setq i (1+ i))
)
(princ)
)

 

par ceci :

 

(defun PPPoly ( / Adoc ss1 pl par pointpar distpar mspace) ;Points sur les objets linéaires
(vl-load-com)
   (setq Adoc (vla-get-ActiveDocument (vlax-get-acad-object))) ;le document actif
(setq mspace (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object)))) ;l'espace papier
(setq ss1 (ssget "_C" (getvar "extmin") (getvar "extmax") '((0 . "2DPOLYLINE,3DPOLYLINE,ARC,LINE,LWPOLYLINE,MLINE,SPLINE,XLINE")(410 . "MODEL")))) ;on filtre
(vlax-for pl (setq ss1 (vla-get-ActiveSelectionSet Adoc)) ;pour tous les objets dans la sélection
	(progn
		(setq par (vlax-curve-getEndParam pl)) ;fin de l'objet
		(setq distpar(vlax-curve-getDistAtParam pl par)) ;distance du param sur la ligne
		(while (<= 0 par) ; tan qu'on est sur l'objet
			(setq pointpar (vlax-curve-getPointAtParam pl par)) ;point du param de la ligne
			(if pointpar
				(progn
					(if pointpar
						(progn
							(setq pointpar (list (car pointpar) (cadr pointpar) 10.0)) ;def du point à x,y,10
							(vla-addPoint mspace (vlax-3d-point pointpar)) ;on met un point à la distance
						)
					)
				)
			)
				(setq distpar (- distpar 1)) ;distance moins 1m
				(setq par (vlax-curve-getParamAtDist pl distpar)) ;parametre de la nouvelle distance
		)
		(if (vlax-curve-getPointAtParam pl 0)
			(progn
				(setq pointpar (vlax-curve-getPointAtParam pl 0))
				(setq pointpar (list (car pointpar) (cadr pointpar) 10.0));def du point à x,y,10
				(vla-addPoint mspace (vlax-3d-point pointpar)) ;point au debut de la courbe
			)
		)
		
	)
)
(vla-delete ss1)
)

 

Et je tombe donc sur certains fichier sur une grande lenteur, voir un blocage de l'execution (qui laisse penser à une boucle infini) dont je n'arrive pas à comprendre la source.

 

Je pensait le Vlisp plus rapide, surtout pour sa capacité à éviter de passer des commandes à Autocad, je m'étonne donc de ce résultat.

 

Constatez vous des problèmes dans mon code, et avez vous des solutions?

 

Merci d'avance.

C'est en forgeant que l'on devient forgerons.

Et c'est en sciant que Léonard DeVinci!

Lien vers le commentaire
Partager sur d’autres sites

Bonjour,

 

Je n'ai pas regardé le code en détail, mais n'oublie pas que les XLINE ont une longueur infinie.

Utiliser des fonctions comme (vlax-curve-getEndParam) sur ce type d'objet n'est probablement pas une bonne idée... ;)

Lien vers le commentaire
Partager sur d’autres sites

Salut,

 

Je vois une "erreur" dans ton filtre de sélection les types 2DPOLYLINE et 3DPOLYLINE n'existent pas en DXF, Les polylignes 2d et 3d sont des objets de type POLYLINE tout comme les maillages, donc pour sélectionner les polylignes 2d et 3d il faut sélectionner les objets POLYLINE et écarter les maillages à l'aide du code 70 et d'opérateurs logiques.

Sinon, ton code utilise beaucoup d'expressions inutiles.

 

(defun PPPoly (/ Adoc mspace ss1 dist pt);Points sur les objets linéaires
 (vl-load-com)
 (setq Adoc (vla-get-ActiveDocument (vlax-get-acad-object)));le document actif
 (setq	mspace (vla-get-modelspace Adoc));l'espace objet
 (setq	ss1
 (ssget
   "_C"
   (getvar "extmin")
   (getvar "extmax")
   '((-4 . "<OR")
      (0 . "POLYLINE,POLYLINE,ARC,LINE,LWPOLYLINE,MLINE,SPLINE,XLINE")
      (-4 . "<AND")
      (0 . "POLYLINE")
      (-4 . "<NOT")
      (-4 . "&")
      (70 . 112)
      (-4 . "NOT>")
      (-4 . "AND>")
      (-4 . "OR>")
      (410 . "MODEL")
    );on filtre
 )
 )					
 (vlax-for pl (setq ss1 (vla-get-ActiveSelectionSet Adoc));pour tous les objets dans la sélection
   (progn
     (setq dist (vlax-curve-getDistAtParam pl (vlax-curve-getEndParam pl)));longueur de la courbe
     (while (< 0. dist)			; tant qu'on est sur l'objet
(setq pt (vlax-curve-getPointAtDist pl dist))
(vla-addPoint mspace (vlax-3d-point (list (car pt) (cadr pt) 10.)));on met un point à la distance
(setq dist (1- dist));distance moins 1m
     )
     (setq pt (vlax-curve-getStartPoint pl))
     (vla-addPoint mspace (vlax-3d-point (list (car pt) (cadr pt) 10.)));point au debut de la courbe
   )
 )
 (vla-delete ss1)
)

Gilles Chanteau - gileCAD -
Développements sur mesure pour AutoCAD
ADSK_Expert_Elite_Icon_S_Color_Blk_125.png

Lien vers le commentaire
Partager sur d’autres sites

Merci pour les infos.

 

Je vais déjà corriger les erreurs de type (recup d'une requette Map pour me simplifier la vie, au final c'est surrement la mon soucis).

 

Pour le reste j'utilise beaucoup de verifications pour éviter les retours nil que j'avais sur certains objets.

Et j'utilise beaucoup de variables pour me simplifier la lecture du code (étant grand débutant).

 

lecrabe > le code s'utilise tel que même si il fait partis d'un plus gros morceau pour moi (point sur les cercles, sur les blocs, tracé d'une emprise covadis, ...).

C'est en forgeant que l'on devient forgerons.

Et c'est en sciant que Léonard DeVinci!

Lien vers le commentaire
Partager sur d’autres sites

Salut,

 

Juste une remarque en passant, dans le filtre de (gile) il y a une petite coquille, pour sélectionner les objets POLYLINE et écarter les maillages à l'aide du code 70 et d'opérateurs logiques. Il faut remplacer cette ligne

(0 . "POLYLINE,POLYLINE,ARC,LINE,LWPOLYLINE,MLINE,SPLINE,XLINE")

par la suivante :

(0 . "ARC,LINE,LWPOLYLINE,MLINE,SPLINE,XLINE")

 

 

Sinon en l’état, il serait préférable de supprimer XLINE du filtre comme suggéré par bryce pour éviter une erreur du type :

Commande: (pppoly)

; erreur: type d'argument incorrect: numberp: nil

 

Cordialement

Apprendre => Prendre => Rendre

Lien vers le commentaire
Partager sur d’autres sites

Effectivement j'ai supprimé le XLINE et un des deux POLYLINE (et j'aurais dut supprimer le second aussi, je corrige cela).

 

Il semble que les maillages polyface posent problème. (POLYLIGNE avec un argument 70 à 64 et non 112 comme indiqué au dessus, ou alors j'ai raté un truc dans l'aide)

Je vais donc m'attacher à les convertir avant traitement.

 

Merci pour toute cette aide!

C'est en forgeant que l'on devient forgerons.

Et c'est en sciant que Léonard DeVinci!

Lien vers le commentaire
Partager sur d’autres sites

Merci VDH-Bruno pour la correction.

 

Il semble que les maillages polyface posent problème. (POLYLIGNE avec un argument 70 à 64 et non 112 comme indiqué au dessus, ou alors j'ai raté un truc dans l'aide)

 

112 = 64 + 32 + 16

soit:

16 = Surface maillée 3D.

32 = Surface maillée fermée dans la direction N.

64 = La polyligne est une maille polyface.

Gilles Chanteau - gileCAD -
Développements sur mesure pour AutoCAD
ADSK_Expert_Elite_Icon_S_Color_Blk_125.png

Lien vers le commentaire
Partager sur d’autres sites

Etrangement si je fait une recherche sur un 112 je n'ai rien par contre sur un 64 oui.

Ne faudrait il pas faire une recherche sur chacun des cas possibles (lourd?)

C'est en forgeant que l'on devient forgerons.

Et c'est en sciant que Léonard DeVinci!

Lien vers le commentaire
Partager sur d’autres sites

Re,

Il semble que les maillages polyface posent problème. (POLYLIGNE avec un argument 70 à 64 et non 112 comme indiqué au dessus, ou alors j'ai raté un truc dans l'aide)

 

Pour compléter la réponse de (gile), je pense qu’une petite explication de l’opérateur relationnel "&" du filtre de sélection (-4 . "&") serai peut-être la bienvenu...

 

 

Etrangement si je fait une recherche sur un 112 je n'ai rien par contre sur un 64 oui.

Ne faudrait il pas faire une recherche sur chacun des cas possibles (lourd?)

 

C'est ce que fait le filtre.

 

 

 

Dans les filtres de sélection, comme pour les groupages logiques ("<and", "and>", "<or", "or>", "<xor", "xor>", "<not" et"not>"). Il est possible d’utiliser des tests relationnels classiques (">", ">", "*", "=", "<>" et "!=" ) ainsi que des tests relationnels plus spécifique que sont "&" et "&=" dit opérateurs binaires (permettant de tester la présence ou non de code binaire).

 

 

Dans notre cas l'opérateur binaire AND, "&" est vérifié si un des bits spécifiés (+ 16 32 64) soit 112 dans le code 70 et présent. Puis le groupage logique NOT permet d’exclure l’entité correspondant de la sélection.

(-4 . "<NOT")
  (-4 . "&")
  (70 . 112)
(-4 . "NOT>")

 

En espérant avoir été suffisament explicite.

A+

Apprendre => Prendre => Rendre

Lien vers le commentaire
Partager sur d’autres sites

Re,

 

C'est beaucoup plus clair pour moi maintenant.

Sans vouloir ajouter de confusion, juste pour compléter encore un peu, il possible d’assimiler l'opérateur binaire "&" (AND) dans les filtres de sélections, au fonctionnement de la fonction lisp logand (qui retourne le résultat d'une opération logique AND).

 

 

Pour t’en convaincre test l’expression suivante sur différent type de "POLYLINE" puis regarde les valeurs en retour.

(logand (cdr (assoc 70 (entget (car (entsel))))) (+ 16 32 64))

 

 

Et tu verras que l’on pourra écrire à titre d’illustration, un équivalent lisp à la sélection suivante:

;; Renvoie une sélection dans le cas de polylignes 2d et 3d
;;        et nil dans le cas maillage, ou autre..
(ssget "_+.:E:S"
      (list '(0 . "POLYLINE") '(-4 . "<NOT") '(-4 . "&") (cons 70 (+ 16 32 64)) '(-4 . "NOT>"))
)

 

 

Comme ceci :

;; Renvoie T dans le cas de polylignes 2d et 3d
;;        et nil dans le cas maillage, ou autre..
(and (setq ent (car (entsel)))
    (= (cdr (assoc 0 (setq ent (entget ent)))) "POLYLINE")
    (zerop (logand (cdr (assoc 70 ent)) (+ 16 32 64)))
)

 

 

En espérant avoir été complet sur le sujet.

A+

Apprendre => Prendre => Rendre

Lien vers le commentaire
Partager sur d’autres sites

J'avoue que la la fonction logand me dépasse un peu pour le moment!

 

 

Mais tout ceci est très instructif!

 

Pour en revenir a mon soucis j'en suis rendu à celle-ci:

 

(defun PPPoly ( / Adoc ss1 pl par pointpar distpar mspace) ;Points sur les objets linéaires
(vl-load-com)
   (setq Adoc (vla-get-ActiveDocument (vlax-get-acad-object))) ;le document actif
(setq mspace (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object)))) ;l'espace papier
(setq ss1
	(ssget
		"_C"
		(getvar "extmin")
		(getvar "extmax")
		'(
			(-4 . "<OR")
			(0 . "ARC,LINE,LWPOLYLINE,SPLINE")
			(-4 . "<AND")
			(0 . "POLYLINE")
			(-4 . "<NOT")
			(-4 . "&")
			(70 . 112)
			(-4 . "NOT>")
			(-4 . "AND>")
			(-4 . "OR>")
			(410 . "MODEL")
		);on filtre
	)
)     
(vlax-for pl (setq ss1 (vla-get-ActiveSelectionSet Adoc)) ;pour tous les objets dans la sélection
	(progn
		(setq par (vlax-curve-getEndParam pl)) ;fin de l'objet
		(setq distpar(vlax-curve-getDistAtParam pl par)) ;distance du param sur la ligne
		(while (<= 0 par) ; tan qu'on est sur l'objet
			(setq pointpar (vlax-curve-getPointAtParam pl par)) ;point du param de la ligne
			(if pointpar
				(progn
					(setq par (vlax-curve-getParamAtDist pl (setq distpar (- distpar 1)))) ;parametre de la nouvelle distance
					(vla-addPoint mspace (vlax-3d-point (list (car pointpar) (cadr pointpar) 10.0))) ;on met un point à la distance
				)
				(setq par 0)
			)
		)
		(setq pointpar (vlax-curve-getStartPoint pl))
		(vla-addPoint mspace (vlax-3d-point (list (car pointpar) (cadr pointpar) 10.0))) ;point au debut de la courbe
	)
)
(vla-delete ss1)
)

 

 

Avec ce code si je filtre comme tel ça ne fonctionne pas (sorte de boucle infinie).

Si je fitre LINE,LWPOLYLINE ça fonctionne vite.

Si je filtre avec ARC ou SPLINE en plus ça entre dans une sorte de boucle infinie.

 

Avez vous une info ou une "astuce" la dessus?

C'est en forgeant que l'on devient forgerons.

Et c'est en sciant que Léonard DeVinci!

Lien vers le commentaire
Partager sur d’autres sites

Bonsoir,

 

Avec ce code si je filtre comme tel ça ne fonctionne pas (sorte de boucle infinie).

Si je fitre LINE,LWPOLYLINE ça fonctionne vite.

Si je filtre avec ARC ou SPLINE en plus ça entre dans une sorte de boucle infinie.

 

L’erreur est ici dans le code

(while  (<= 0 par)

 

Remplace par

(while (< 0 par)

 

Cela devrait fonctionner beaucoup mieux, car plus en cohérence avec cette ligne

(setq par 0)

qui doit permettre ta sortie de boucle.

 

 

(Ps : Il aurait était plus logique d’utiliser dist ou distpar dans ton cas comme valeur de sortie de boucle comme l’avais écrit (gile). La tu test la non existance de pointpar pour savoir qu’il faut mettre par à 0, par atteindre la condition de sortie de boucle du while, c’est un peu moins lisible. )

 

Cordialement

Apprendre => Prendre => Rendre

Lien vers le commentaire
Partager sur d’autres sites

Effectivement vos deux observations sont pertinantes, j'ai fait ça un peu trop "à l'arrache" et a force de modifications et de bidouillages j'en arrive à un code vraiment mauvais.

 

La proposition de (gile) du second post est effectivement au plus juste, mon choix de passer par un parametre est antérieur à tout ce sujet, quand je me posais la question de mettre un point sur chaque sommet puis diviser les sections en nombre de points, ce que je n'ais pas fait et qui a plombé mon code ensuite.

 

je confirme donc qu'avec ce code chez moi cela fonctionne à la perfection :

 

(defun PPPoly ( / Adoc ss1 pl par pointpar distpar mspace) ;Points sur les objets linéaires
(vl-load-com)
   (setq Adoc (vla-get-ActiveDocument (vlax-get-acad-object))) ;le document actif
(setq mspace (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object)))) ;l'espace papier
(setq ss1
	(ssget
		"_C"
		(getvar "extmin")
		(getvar "extmax")
		'(
			(-4 . "<OR")
			(0 . "LWPOLYLINE,LINE,SPLINE,ARC")
			(-4 . "<AND")
			(0 . "POLYLINE")
			(-4 . "<NOT")
			(-4 . "&")
			(70 . 112)
			(-4 . "NOT>")
			(-4 . "AND>")
			(-4 . "OR>")
			(410 . "MODEL")
		);on filtre
	)
)     
(vlax-for pl (setq ss1 (vla-get-ActiveSelectionSet Adoc));pour tous les objets dans la sélection
	(progn
		(setq distpar (vlax-curve-getDistAtParam pl (vlax-curve-getEndParam pl)));longueur de la courbe
		(while (< 0. distpar)                        ; tant qu'on est sur l'objet
			(setq pointpar (vlax-curve-getPointAtDist pl distpar))
			(vla-addPoint mspace (vlax-3d-point (list (car pointpar) (cadr pointpar) 10.)));on met un point à la distance
			(setq distpar (1- distpar));distance moins 1m
		)
		(setq pointpar (vlax-curve-getStartPoint pl))
		(vla-addPoint mspace (vlax-3d-point (list (car pointpar) (cadr pointpar) 10.)));point au debut de la courbe
	)
)
(vla-delete ss1)
)

Et qu'en plus de cela c'est bien plus rapide que le code de la boucle sur "_.measure".

 

Me reste a retranscrire les maillages polyface et tout sera parfait!

 

Merci beaucoup à vous tous.

C'est en forgeant que l'on devient forgerons.

Et c'est en sciant que Léonard DeVinci!

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é