-
Compteur de contenus
12 247 -
Inscription
-
Dernière visite
-
Jours gagnés
209
Type de contenu
Profils
Forums
Calendrier
Blogs
Tout ce qui a été posté par (gile)
-
LISP pour récupérer dans un texte la surface d'une polyligne
(gile) a répondu à un(e) sujet de brunomu dans Routines LISP
Je me permet un petit rappel avec ce screencast à propos de la procédure pour trouver d'où vient l'erreur avec les fonctions de débogage de l'éditeur VLIDE. -
[RESOLU] Numérotation automatique des sommets d'une polyligne
(gile) a répondu à un(e) sujet de Hydro8 dans Débuter en LISP
Je ne vois pas quelle variable pourrait. Cette version crée le bloc s'il n'existe pas dans le dessin. (defun c:toto (/ massoc mkBlock mkInsert leftPad ss n i pls pts) (defun massoc (key alst) (if (setq alst (member (assoc key alst) alst)) (cons (cdar alst) (massoc key (cdr alst))) ) ) (defun mkBlock () (if (null (tblsearch "style" "Adam")) (entmake '((0 . "STYLE") (100 . "AcDbSymbolTableRecord") (100 . "AcDbTextStyleTableRecord") (2 . "Adam") (70 . 0) (40 . 0.0) (41 . 1.0) (50 . 0.0) (71 . 0) (42 . 0.2) (3 . "tahoma.ttf") (4 . "") ) ) ) (entmake '((0 . "BLOCK") (8 . "0") (2 . "DV-point") (70 . 2) (10 0.0 0.0 0.0) ) ) (entmake '((0 . "POINT") (8 . "0") (62 . 0) (10 0.0 0.0 0.0) ) ) (entmake '((0 . "ATTDEF") (8 . "!ADAM-POINTS") (10 0.0 0.0 0.0) (40 . 0.3) (1 . "") (7 . "Adam") (71 . 0) (72 . 1) (11 0.0 0.0 0.0) (3 . "Matricule") (2 . "MAT") (70 . 0) (74 . 1) ) ) (entmake '((0 . "ENDBLK"))) ) (defun mkInsert (pt n) (entmake (list (cons 0 "INSERT") (cons 2 "DV-point") (cons 8 "POINTS") (cons 10 pt) (cons 66 1) ) ) (entmake (list (cons 0 "ATTRIB") (cons 1 (itoa n)) (cons 2 "MAT") (cons 7 "Adam") (cons 8 "!ADAM-POINTS") (cons 10 '(0.0 0.0 0.0)) (cons 11 pt) (cons 40 0.3) (cons 70 0) (cons 71 0) (cons 72 1) (cons 74 1) ) ) (entmake '((0 . "SEQEND"))) (1+ n) ) (defun leftPad (str char num) (repeat (max (- num (strlen str)) 0) (setq str (strcat char str)) ) str ) (if (null (tblsearch "block" "DV-point")) (mkBlock) ) (if (and (setq ss (ssget '((0 . "LWPOLYLINE") (-4 . "&") (70 . 1)))) (setq n (getint "\nPremier numéro: ")) ) (progn (repeat (setq i (sslength ss)) (setq pls (cons (entget (ssname ss (setq i (1- i)))) pls)) ) (foreach pl (vl-sort pls '(lambda (l1 l2) '(< (leftPad (cdr (assoc 5 l1)) "0" 16) (leftPad (cdr (assoc 5 l2)) "0" 16) ) ) ) (foreach p (massoc 10 pl) (if (null (vl-some '(lambda (x) (equal x p 1e-8)) pts)) (setq pts (cons p pts) n (mkInsert p n) ) ) ) ) ) ) (princ) ) -
[RESOLU] Numérotation automatique des sommets d'une polyligne
(gile) a répondu à un(e) sujet de Hydro8 dans Débuter en LISP
Non je ne suis pas pourquoi et ça ne le fait pas chez moi. -
[RESOLU] Numérotation automatique des sommets d'une polyligne
(gile) a répondu à un(e) sujet de Hydro8 dans Débuter en LISP
Cette version devrait devrait répondre à ce cahier des charges : (defun c:toto (/ massoc entmakeInsert entmakeText leftPad f ss i n pts) (defun massoc (key alst) (if (setq alst (member (assoc key alst) alst)) (cons (cdar alst) (massoc key (cdr alst))) ) ) (defun entmakeInsert (pt n) (entmake (list (cons 0 "INSERT") (cons 2 "DV-point") (cons 8 "POINTS") (cons 10 pt) (cons 66 1) ) ) (entmake (list (cons 0 "ATTRIB") (cons 1 (itoa n)) (cons 2 "MAT") (cons 7 "Adam") (cons 8 "!ADAM-POINTS") (cons 10 '(0. 0. 0.)) (cons 11 pt) (cons 40 0.3) (cons 70 0) (cons 71 0) (cons 72 1) (cons 74 1) ) ) (entmake (list (cons 0 "SEQEND") ) ) (1+ n) ) (defun entmakeText (pt n) (entmake (list (cons 0 "TEXT") (cons 8 "POINTS") (cons 10 pt) (cons 1 (itoa n)) (cons 10 '(0. 0. 0.)) (cons 11 pt) (cons 40 0.3) (cons 72 1) (cons 73 1) ) ) (1+ n) ) (defun leftPad (str char num) (repeat (max (- num (strlen str)) 0) (setq str (strcat char str)) ) str ) (setq f (if (null (tblsearch "block" "DV-point")) entmakeText entmakeInsert ) ) (if (and (setq ss (ssget '((0 . "LWPOLYLINE") (-4 . "&") (70 . 1)))) (setq n (getint "\nPremier numéro: ")) ) (progn (repeat (setq i (sslength ss)) (setq plines (cons (entget (ssname ss (setq i (1- i)))) plines)) ) (foreach pl (vl-sort plines '(lambda (l1 l2) '(< (leftPad (cdr (assoc 5 l1)) "0" 16) (leftPad (cdr (assoc 5 l2)) "0" 16) ) ) ) (foreach p (massoc 10 pl) (if (null (vl-some '(lambda (x) (equal x p 1e-8)) pts)) (setq pts (cons p pts) n (f p n) ) ) ) ) ) ) (princ) ) -
LISP pour récupérer dans un texte la surface d'une polyligne
(gile) a répondu à un(e) sujet de brunomu dans Routines LISP
Rien, si tu fais la même chose à la ligne de commande ? (dans tous les cas, j'ai toujours recommandé d'utiliser l'éditeur pour développer en LISP). -
LISP pour récupérer dans un texte la surface d'une polyligne
(gile) a répondu à un(e) sujet de brunomu dans Routines LISP
Ça marche alors... Je ne comprends pas où est le problème. -
LISP pour récupérer dans un texte la surface d'une polyligne
(gile) a répondu à un(e) sujet de brunomu dans Routines LISP
Et si ensuite, toujours dans la console, tu fais : (getpropertyvalue ename "Area") ? Ou (setq vla-obj (vlax-ename->vla-object ename)) ? puis (vla-get-Area vla-obj) ? -
LISP pour récupérer dans un texte la surface d'une polyligne
(gile) a répondu à un(e) sujet de brunomu dans Routines LISP
J'ai dit une bêtise, les noms des propriétés ne sont pas sensibles à la casse. Comment fais-tu tes essais, en ligne commande ou dans la console de l'éditeur Visual LISP ? Que vois-tu quand tu fais : (setq ename (car (entsel "\nSélectionner un coutour : "))) ? -
LISP pour récupérer dans un texte la surface d'une polyligne
(gile) a répondu à un(e) sujet de brunomu dans Routines LISP
L'argument pour les fonctions vla ou vlax doit-être de type vla-object et pas de type ename. Les noms des propriétés sont sensibles à la casse "area" est différent de "Area". -
[RESOLU] Numérotation automatique des sommets d'une polyligne
(gile) a répondu à un(e) sujet de Hydro8 dans Débuter en LISP
Si l'ordre des numéros peut être aléatoire la routine ci-dessous devrait convenir. Si le bloc "DV-point" n'existe pas dans le dessin un simple texte est inséré à la place. (defun c:toto (/ massoc entmakeInsert entmakeText f ss i n pts) (defun massoc (key alst) (if (setq alst (member (assoc key alst) alst)) (cons (cdar alst) (massoc key (cdr alst))) ) ) (defun entmakeInsert (pt n) (entmake (list (cons 0 "INSERT") (cons 2 "DV-point") (cons 8 "POINTS") (cons 10 pt) (cons 66 1) ) ) (entmake (list (cons 0 "ATTRIB") (cons 1 (itoa n)) (cons 2 "MAT") (cons 7 "Adam") (cons 8 "!ADAM-POINTS") (cons 10 '(0. 0. 0.)) (cons 11 pt) (cons 40 0.3) (cons 70 0) (cons 71 0) (cons 72 1) (cons 74 1) ) ) (entmake (list (cons 0 "SEQEND") ) ) (1+ n) ) (defun entmakeText (pt n) (entmake (list (cons 0 "TEXT") (cons 8 "POINTS") (cons 10 pt) (cons 1 (itoa n)) (cons 10 '(0. 0. 0.)) (cons 11 pt) (cons 40 0.3) (cons 72 1) (cons 73 1) ) ) (1+ n) ) (setq f (if (null (tblsearch "block" "DV-point")) entmakeText entmakeInsert ) n 1 ) (if (setq ss (ssget '((0 . "LWPOLYLINE") (-4 . "&") (70 . 1)))) (repeat (setq i (sslength ss)) (foreach p (massoc 10 (entget (ssname ss (setq i (1- i))))) (if (null (vl-some '(lambda (x) (equal x p 1e-8)) pts)) (setq pts (cons p pts) n (f p n)) ) ) ) ) (princ) ) -
[RESOLU] Numérotation automatique des sommets d'une polyligne
(gile) a répondu à un(e) sujet de Hydro8 dans Débuter en LISP
Salut, Au vu de ton dessin le problème est bien plus complexe que ce que tu décris. Les points 3, 4, 5 et 6 ne sont pas incrémentés par polyligne*, mais suivant au moins un autre critère qu'à l'heure actuelle toi seul connais. En programmation toutes les décisions sont prises sur le même schéma : si condition alors ... sinon ... Il faut donc qu'absolument toutes les conditions qui on mené à la décision finale soient envisagées de cette façon binaire. Notre cerveau fait ça sans qu'on en ait toujours vraiment conscience mais pour le transcrire dans un langage de programmation il faut d'abord le décrire précisément de manière logique (on peut s'aider pour ça d'un logigramme ou organigramme de programmation). * les points 3 et 5 ne sont pas des sommets de la première polyligne dont les sommets sont numérotés 1, 2, 4 et 6. -
LISP pour récupérer dans un texte la surface d'une polyligne
(gile) a répondu à un(e) sujet de brunomu dans Routines LISP
Salut, En vla, tu fais un vlax-dump-object et tu regardes si une des propriétés correspond à ce que tu cherches, tu utilises ensuite cette propriété avec : (vlax-get vla-obj "NomDeLaPropriete") ou (vla-get-NomDeLaPropriete vla-obj). En "our AutoLISP", tu fais un dumpallproperties et tu regardes si une des propriétés correspond à ce que tu cherches, tu utilises ensuite cette propriété avec : (getpropertyvalue ename "NomDeLaPropriete"). -
AutoLISP, Leçon N°1 Avec le code ci-dessus : tu supprimes la première parenthèse ouvrante et, bien sûr la dernière parenthèse fermante tu remplaces lambda par : c:LeNomDeComandeQuiTeConviens tu supprimes le "_X" dans l'expression : (ssget "_X" '((0 . "HATCH"))) et ça devrait marcher.
-
@Fraid, la méthode de @Luna est plus simple et plus directe : (defun getHatch (ent / hatch) (cdr (assoc 330 (member '(102 . "{ACAD_REACTORS") (entget ent)))) ) Parfois, la bonne vielle méthode du DXF est plus simple...
-
Salut, ((lambda (/ ss i aci) (if (setq ss (ssget "_X" '((0 . "HATCH")))) (repeat (setq i (sslength ss)) (setq h (ssname ss (setq i (1- i))) aci (getpropertyvalue h "Color") ) (cond ((= aci "131") (setpropertyvalue h "Color" "221")) ((= aci "221") (setpropertyvalue h "Color" "131")) ((= aci "31") (setpropertyvalue h "Color" "91")) ((= aci "91") (setpropertyvalue h "Color" "31")) ((= aci "181") (setpropertyvalue h "Color" "11")) ((= aci "11") (setpropertyvalue h "Color" "181")) ) ) ) ) )
-
Ajout automatique de point sur tous les sommets de toutes les polylignes 3D
(gile) a répondu à un(e) sujet de yubari dans AutoCAD Civil
Salut, Je ne connais pas Civil, mais s'il existe une commande "sommets de polyligne automatique" qui demande à sélectionner une polyligne, on devrait pouvoir appeler cette commande en LISP pour chaque polyligne d'un jeu de sélection. -
Non, une polyligne fermée est une polyligne qui a sa propriété Closed égale à true ou le code binaire 1 dans son code de groupe DXF 70. C'est ce qui la différencie d'une polyligne qui a le dernier sommet confondu avec le premier . Je voulais juste dire qu'avant de couper les cheveux en quatre avec de histoires de quelques millisecondes de différence entre telle et telle routine, il faut d'abord qu'elle renvoient des résultats similaires si ce n'est identiques. Toutes les autres routines qui utilisent la liste DXF ou la propriété Coordinates renvoient les sommets de la polyligne sans en ajouter un si elle est fermée. On peut préférer récupérer des segments comme le fait zebulon_ mais ce n'est plus la même chose et ce n'est pas comparable en terme de rapidité d'exécution (idem pour la routine bonuscad qui effectue une opération de plus pour chaque sommet en le convertissant du SCO vers le SCG).
-
@Luna ta routine 'get-pt-list-curve' comme celle de @VDH-Bruno renvoie un sommet de trop en cas polyligne fermée (le premier sommet ajouté à la fin de la liste). 'vlax-curve-getPolylineCoordinates' traite correctement les polylignes fermées, ceci explique pourquoi il est légèrement moins rapide dans les benchmark.
-
J'ai modifié la commande TEST pour qu'elle renvoie un résultat similaire au Benchmark de Mickael Puckket. [CommandMethod("TEST")] public static void Test() { var ed = AcAp.DocumentManager.MdiActiveDocument.Editor; var entOpts = new PromptEntityOptions("\nSélectionnez une polyligne: "); entOpts.SetRejectMessage("\nL'objet séléctionné n'est pas une polyligne."); entOpts.AddAllowedClass(typeof(Polyline), true); var entRes = ed.GetEntity(entOpts); if (entRes.Status != PromptStatus.OK) return; var id = entRes.ObjectId; long elapsedMilliseconds = 0; int iterations = 1; while (elapsedMilliseconds < 1000) { var sw = new System.Diagnostics.Stopwatch(); sw.Start(); for (int i = 0; i < iterations; i++) { GetPlinePoints(id); } sw.Stop(); elapsedMilliseconds += sw.ElapsedMilliseconds; iterations *= 2; } ed.WriteMessage($"\nElapsed milliseconds {elapsedMilliseconds} for {iterations} iterations"); } Un exemple de résultats avec la polyligne 10000 points : TEST Sélectionnez une polyligne: Elapsed milliseconds 1794 for 4096 iterations Commande: TEST Sélectionnez une polyligne: Elapsed milliseconds 1806 for 4096 iterations Commande: TEST Sélectionnez une polyligne: Elapsed milliseconds 1795 for 4096 iterations Commande: TEST Sélectionnez une polyligne: Elapsed milliseconds 1805 for 4096 iterations GetPointListChallenge.zip
-
Il faut bien penser à prendre un peu de recul avec ces benchmarks (et en faire plusieurs pour faire une moyenne). Le benchmark double le nombre d'itérations jusqu'à ce que, pour la plus rapide des routine, on dépasse les 1000 millisecondes. Donc, si on considère les résultats avec la polyligne de 10 000 sommets, par exemple, on a 32 itérations. Autrement dit les résultats doivent être divisé par 32 pour avoir le temps moyen pour une exécution, soit, pour les 3 premiers 43, 44 et 50 (la différence entre le premier et le troisième est de moins de 10 millisecondes). D'après les résultats en .NET que donne Olivier, pour la même polyligne de 10000 sommets, on est autour 0.4 millisecondes, soit 100 fois plus rapide que les meilleurs LISP... @Curlygoth On parle de millisecondes, et pour avoir un chiffre conséquent, on répète le traitement plusieurs fois. Pour une polyligne de 10000 points il faut au moins 32 ou 64 itérations.
-
La routine de @zebulon_ avec massoc (peut-être pas très efficient) : (defun getPolySegs (pl / elst pts) (setq elst (entget pl) pts (massoc 10 elst) ) (mapcar 'list pts (massoc 42 elst) (if (= 1 (logand 1 (cdr (assoc 70 elst)))) (append (cdr pts) (list (car pts))) (cdr pts) ) ) )
-
Pour essayer de revenir au challenge (et avant de digresser moi aussi) je dévoile différentes implémentations de la routine générique massoc (pour multiple assoc) qui permet de récupérer toutes les entrées d'un même groupe de code dans une liste DXF. Ma réponse en "pur AutoLISP" utiliserait l'implémentation que je préfère : (defun massoc (key alst) (if (setq alst (member (assoc key alst) alst)) (cons (cdar alst) (massoc key (cdr alst))) ) ) (defun polyPoints (pl) (massoc 10 (entget pl)) ) Pour récupérer les sommets de la polyligne en coordonnées SCG (fonctionne aussi avec le polylignes 2d et 3d) : (defun vlax-curve-getPolylineCoordinates (pl / i pts) (repeat (setq i (if (vlax-curve-isClosed pl) (fix (vlax-curve-getEndParam pl)) (1+ (fix (vlax-curve-getEndParam pl))) ) ) (setq pts (cons (vlax-curve-getPointAtParam pl (setq i (1- i))) pts)) ) )
-
La DLL que j'ai postée a été compilée avec VS2019 en mode Release (Any CPU) en ciblant le Framework 4.6. Je ne vois pas d'où viennent ces différences. Dans tous les cas, ces chronométrages sont à prendre à titre indicatif avec des pincettes (ils sont influencé par ce qui se passe en même temps sur la machine) et la différence n'est que d'environ 0.15 millisecondes pour le traitement d'une polyligne de 10000 sommets. La routine écrite en F# (mêmes performances qu le C# puis que les deux sont compilées dans le même IL). let getPlinePoints (id: ObjectId) = use pl = id.Open(OpenMode.ForRead) :?> Polyline Array.init pl.NumberOfVertices (fun i -> pl.GetPoint2dAt(i))
-
Il y a 10 types de personnes dans le monde : celles qui comptent en binaire et les autres
(gile) a répondu à un(e) sujet de (gile) dans Débuter en LISP
Essaye : (dec->Transparency 16777216) et (dec->Transparency 33554432) tous les 2 renvoient 100 mais dans le premier cas, c'est DuBloc et dans le second 100% de transparence. -
Il y a 10 types de personnes dans le monde : celles qui comptent en binaire et les autres
(gile) a répondu à un(e) sujet de (gile) dans Débuter en LISP
Attention, par programmation on peut mettre 100% de transparence (440 . 33554432) ce qui est différent de ByBlock (440 . 16777216). Dans les deux cas l'octet de droite est à 0.
