Aller au contenu

VDH-Bruno

Membres
  • Compteur de contenus

    1 146
  • Inscription

  • Dernière visite

  • Jours gagnés

    20

Tout ce qui a été posté par VDH-Bruno

  1. Bonjour, Je m’en étais aperçu en testant la fonction acet-attsync, je pense qu’une solution avec ATTSYNC ne peut être que un "truc à savoir", mais pas une "vraie solution". Pour moi le problème ne se pose plus, en repartant et en testant les lignes de Patrick_35 je pense que c’est plus complet et direct que mes précédentes propositions. Par contre le fait de redessiner la réference la replace en avant plan (un moindre mal qui doit peut être trouver sa solution …) A+
  2. Re, Non pas forcément il faut juste « forcer » le code dxf 70 à 2 dans la définition du bloc, pour pouvoir exécuter ATTSYNC sur les références de bloc. Pour le principe les quelques lignes de codes utilisés sur ton fichier pour venir à bout de la définition du bloc "PanneauSensInterdit"… ((lambda () (setq blk (entget (tblobjname "BLOCK" (cdr (assoc 2 (entget (car (entsel))))))) e (cdr (assoc -2 blk)) lstent nil ) (while e (setq lstent (cons (entget e) lstent)) (setq e (entnext e))) (entmake (subst '(70 . 2) (assoc 70 blk) blk)) (mapcar 'entmake (reverse lstent)) (entmake '((0 . "ENDBLK"))) ) ) Ci-joint ton fichier avec le code 66 supprimé après usage de la commande ATTSYNC: Commande: attsync Entrez une option [?/Nom/Sélectionner] <Sélectionner>: Sélectionnez un bloc: ATTSYNC le bloc PanneauSensInterdit? [Oui/Non] <Oui>: ATTSYNC terminé. A+ retour2-TEST_EE_200-1000-2.zip
  3. Non mais oui ;) Tel que décrit cela fonctionne (si si j'ai testé :D) car lorsque j’insère mon bloc dans mon nouveau dessin, j’insère également la définition correspondant dans la table des blocs et j'écrase la définition antérieure dans ce cas je "blouse" toujours ATTSYNC Je pense que dans ton dessin tu as fait tout le contraire tu as écrasé ta définition de bloc par une définition plus récente qui n’a jamais contenu d’attribut (la blague était bonne, car je n'avais rien compris à ce bloc merci pour l'explication :(rires forts): ) A+
  4. Re, Change de bloc, plus sérieusement même message avec "PanneauSensInterdit"... Je te retourne tout de même ton dessin car j'ai fait le même test avec COVAPOINT, tu verras qu'il n'y as plus de code 66. Je t'ai retourné en second dessin avec un de mes blocs avec attribut supprimé en référence et définition + code 66 à 1. Il n'y a plus qu'a lancer ATTSYNC dessus pour supprimer le code 66 A+ retour-TEST_EE_200-1000-2.zip Dessin6.zip
  5. Bonjour Olivier, Tu as sans doute raison pour les raisons évoqués, néanmoins dans mes tests, sans le faire exprès, j’ai réussi lever cette affirmation sous AutoCAD 2007: Donc pour le retour, je livre le mode opératoire (conscient que cela ne peut être qu’un « truc » plus qu’autre chose). En 1 : Supprimer les attributs des définitions de bloc (ex : routine de (gile)) En 2 : Pour pouvoir lancer ATTSYNC, avoir ou charger dans le dessin au moins une définition de bloc avec attribut. En 3 : Enregistrer fermer puis rouvrir le dessin. En 4 : Lancer la commande ATTSYNC. Contrôle du code 66 sur une référence de bloc : _$ (assoc 66 (entget (car (entsel)))) nil Toutes les références du bloc synchronisé sont à jour du code 66 dans de dessin ;-) Voilà à tester A+ (Ps: Je n'ai pas testé avec la fonction acet-attsync, je suppose que c'est le même comportement).
  6. Bonjour, Un test rapide me fait dire que la piste évoqué est bonne pour les références déjà inséré. A+
  7. Bonjour, Une veille astuce qui doit encore fonctionné sur vos versions récentes, avec les textes multi-lignes des cotations, on peut passer par le caractère d’empilement ^, Par exemple tu édites ta cotation et tu inscris en suffixe l’expression +0.2^-0.1, puis tu sélectionne et empile l’expression. Tu devrais obtenir le résultat souhaité, qu’il ne te reste plus qu’à copier-coller sur les autres cotations à appliquer Une discussion ou est déjà expliqué le procédé: Code ASCII http://cadxp.com/topic/36371-code-ascii/page__view__findpost__p__197999 Un code lisp proche (à adapter) qui peut donner une base de départ pour automatiser la tache: cotation avec exposant http://cadxp.com/topic/37002-cotation/page__view__findpost__p__202500 A+
  8. Bonjour, Pour le retour sous AutoCAD 2007, il n’y a pas de variable GROUPDISPLAYMODE, les poignées s’affichent donc sur tous les objets du groupe donc l’astuce fonctionne plutôt bien au niveau du dessin. Un petit bémol tout de même, les groupes étant géré dans des dictionnaires, ils sont spécifiques au dessin et non persistant d’un dessin à l’autre. Donc en l’état sans un petit développement. Il faudra recréer son groupe pour chaque dessin (contrairement à un bloc dont la définition peut être exportée). A+
  9. Bonjour à tous, Dans la série on en découvre tous les jours, bien que je n’ai que trop rarement le loisir de «lisper» en ce moment.. Au hasard d’une tentative de style dans l’écriture d’un code, je me suis aperçu chez moi (AutoCAD 2007) que les fonctions + et – étaient limité dans le nombre d’arguments. Après test la limite semblant être fixé à 255 éléments: _$ (repeat 255 (setq L255 (cons 1 L255))) 255 _$ (eval (cons '+ L255)) 255 _$ (eval (cons '+ (cons 1 L255))) ; erreur: limite interne: nombre d'arguments trop important dans l'appel de la fonction: + Je rassure la communauté, apply permet heureusement et toujours de s’affranchir de la limitation ;) _$ (apply '+ (repeat 8000 (setq L8000 (cons 1 L8000)))) 8000 Pour info, et à cette occasion j’en profite pour vous passer un petit bonjour à tous. A+ Bruno
  10. Bonjour, Pour mettre déjà bien creusé la tête sur ces questions, je ferai la même réponse que bonuscad, sauf pour les fonctions entmod et entmake. Car ces fonctions supportent le mode transparent, d’ailleurs c’est un moyens de substitution aux appels à la fonctions command dans le cas de la prise en compte du mode transparent. Un petit exemple dessine un objet, puis déplace-le en exécutant les fonctions suivantes en transparence : (defun c:rouge () (entmod (append (entget (entlast)) '((62 . 1)))) (princ)) (defun c:duplique () (entmake (entget (entlast))) (princ)) Te peux également recommencer en redessinant un autre objet puis déplace le et en cours de commande exécute la fonction suivante en transparence : (defun c:les2 () (c:rouge) (c:duplique) (princ)) Là tu constateras que le mode transparent s’exécute également sur toute les fonctions appelé du moment que ces dernières le peuvent. A+
  11. VDH-Bruno

    Intersection de ligne

    Bonjour, Sinon sur ce forum, je m’étais également essayé à un problème similaire.. http://cadxp.com/topic/33361-lister-les-intersections-d%E2%80%99objets-dun-jeu-de-selection/ http://cadxp.com/index.php?/topic/33341-lisp-pour-extraire-les-coordonnees-de-lintersection-des-axes/Lisp Dans ton cas je te propose de symboliser l’intersection par une entité point, dont tu pourras faire varier l’aspect (PDMODE) et la taille (PDSIZE) au moyen des variables AutoCAD Le code principal : (defun c:fiesta () (mapcar '(lambda (pt) (entmake (list '(0 . "POINT") (cons 10 pt)))) (bv:ListInters (ssget))) ) Les routines associées : ;; ----------------------------------------------------------------------------- ;; Liste toutes les intersections présentent dans le jeu de sélection ;; (Avec suppression des points en doublons) ;; ----------------------------------------------------------------------------- ;; Argument: Un jeu de sélection du type <Selection set: 2a> ;; Retourne: Une liste de point du type ((x1 y1 z1) (x2 y2 z2) (x3 y3 z3) ...) (defun bv:ListInters (ss / lst sel) (cond (ss (vlax-for obj (setq sel (vla-get-activeselectionset (vla-get-activedocument (vlax-get-acad-object)) ) ) (setq lst (cons obj lst)) ) (vla-delete sel) (remove_doubles (apply 'append (mapcar '(lambda (x) (bv:xyz->Pt (vlax-invoke (car x) 'IntersectWith (cadr x) 0) ) ) (bv:matches lst) ) ) ) ) ) ) ;; Transforme une liste de coordonnées en liste de point ;; Argument: Une liste du type (x1 y1 z1 x2 y2 z2 x3 y3 z3 ...) ;; Retourne: Une liste du type ((x1 y1 z1) (x2 y2 z2) (x3 y3 z3) ...) ;; soit (p1 p2 p3 ...) ;; Exemples : ;; (bv:xyz->Pt '(x1 y1 z1 x2 y2 z2)) -> ((X1 Y1 Z1) (X2 Y2 Z2)) ;; (bv:xyz->Pt '(x1 y1 z1)) -> ((X1 Y1 Z1)) (defun bv:xyz->Pt (L) (if L (cons (list (car L) (cadr L) (caddr L)) (bv:xyz->Pt (cdddr L)) ) ) ) ;; matches (renvoie les combinaisons 2 à 2 sans répétition). ;; Argument: Une liste du type (A B C D) ;; Retourne: Une liste du type ((A B) (A C) (A D) (B C) (B D) (C D)) (defun bv:matches (L) (if (cdr L) (append (mapcar '(lambda (x) (list (car L) x)) (cdr L)) (bv:matches (cdr L)) ) ) ) ;; Extrait du fichier Listes.lsp ;; REMOVE_DOUBLES - Auteur (gile) ;; Suprime tous les doublons d'une liste (defun remove_doubles (lst) (if lst (cons (car lst) (remove_doubles (vl-remove (car lst) lst))) ) ) Voilà maintenant tu n'as plus que l'embarras du choix ;) A+
  12. Bonjour, Bien que je me sois arrêté à la version 2007, et que je n’ai pas et ne verrai sans doute pas cette fameuse version 2015. Pour la petite histoire, il faut savoir qu’initialement dans AutoCAD le préfixe DD était par convention utilisé pour les commandes AutoCAD, qui appelaient une boite de Dialogue écrit en DCL. Donc j’ose croire que l’interface de ces commandes a été réécrite dans un langage plus actuel [/humour] et que par soucis de cohérence dans les appellations, ils ont pensé à renommer ces commandes… [humour] A+ Bruno
  13. VDH-Bruno

    pluie

    Salut, Histoire de parler de la pluie et du beau temps, je voulais juste rappeler la maxime suivante : "Un mauvais temps est un même temps qui dure trop longtemps..." A+
  14. Bonjour, Tu vas dans l’éditeur de bloc pour modifier la définition, puis dans la palette des propriétés supprime la mise à l’échelle uniformément. A+
  15. Re, A y repenser, je pense que la fonction de comparaison pour être juste doit s’inspirer de ta réflexion suivante : C’est-à-dire dans le cas de 2 fuzz différent, il faudrait garder le plus grand des 2 fuzz puis arrondir le nombre qui à le plus petit fuzz au fuzz retenu. A+
  16. Bonjour (gile) Je ne suis pas un grand spécialiste de la question, et je n’ai jamais réfléchi plus que cela au problème. Je suis totalement d’accord avec l’idée suivante: Là où je me perds c’est que les fonctions proposées ne permettent pas cela, si tu teste dans la console, tu obtiens: _$ (setq dist 1000) 1000 _$ (gc:EqualPoints (polar '(0. 0. 0.) pi dist) (list (- dist) 0. 0.)) nil Le résultat est nil, tel que sont codé les fonctions cela me semble juste car la fonction gc:EqualNumbers garde le fuzz maxi soit 1.0e-015 pour la coordonné Y,je souligne seulement qu’à cette précision les chiffres significatifs sont toujours différents… Au risque de dire une énormité et de simplifier abusivement, instinctivement je serai tenté de dire que devant un fuzz supérieur à 1.0e-015, il faut garder la différence des deux exposant du fuzz dans notre exemple (27 - 15)=12, pour faire une comparaison à 1.0e-012 pour pouvoir considérer les deux coordonnées en Y égal, et par conséquence les points aussi. En espérant avoir été un peu plus clair, je ne pense pas avoir proposé la solution mais seulement une piste de réflexion, ou alors j’ai rien compris ce qui est également possible… A+ Bruno
  17. Bonjour et merci (gile), Le sujet est excellent et bienvenu, j’avoue ne pas toujours être très à l’aise avec ces notions, j’ai donc pris les 5 mn nécessaire à la bonne compréhension des fonctions proposés. Certains points anecdotique me chagrine (mais rien de bien méchant, je pense qu’il faut les laisser mûrir), par contre dans la rédaction du sujet il y a comme un semblant de contradiction. Cette affirmation laisse penser que les fonctions de comparaison proposée amèneront automatiquement cette tolérance de comparaison (une comparaison à 1e-12 par exemple pour ce cas précis). Mais tel qu'elles sont écrite ce n’est pas le cas: Cela n’est pas possible car _$ (gc:Fuzz (cadr (polar '(0.0 0.0 0.0) pi 1000.0))) 1.0e-027 Et _$ (gc:Fuzz 0.0) 1.0e-015 De plus la fonction de comparaison gardant le plus grand Fuzz la fonction equal ne peut que retourner nil Donc pour moi _$ (gc:EqualPoints (polar '(0.0 0.0 0.0) pi 1000.0) '(-1000.0 0.0 0.0)) nil A+ Bruno
  18. Tu as été un peu rapide, il fallait substituer le second bloc d'instruction comme ceci: (defun c:subtitutexte (/ new_text old_text dxf1 dxf2) (initget "Echanger Copier _Swap Copy") (if (eq (getkword "\nChaine de texte [Echanger/Copier]? : ") "Swap") (progn (setq new_text (extract_txt nil (setq dxf1 (sel_obj "à ECHANGER")) nil)) (setq old_text (extract_txt nil (setq dxf2 (sel_obj "où ECHANGER")) nil)) (extract_txt T dxf1 old_text) (extract_txt T dxf2 new_text) ) (progn (setq new_text (extract_txt nil (setq dxf1 (sel_obj "à COPIER")) nil)) (while ; modif (setq old_text (extract_txt nil (setq dxf2 (sel_obj "où COLLER")) nil)) (extract_txt T dxf2 new_text) ) ;modif ) ) (prin1) ) A+
  19. Re, J’y pense, on arrive à le faire très facilement, en détournant légèrement le fonctionnement de l’excellente routine d’incrémentation INCSEL (gile): Pour cela il te suffit de copier dans la valeur de départ de la boite de dialogue le texte à coller, puis de régler la valeur de l’incrément à 0. C'est simple efficace et sans codage supplémentaire ;) A+
  20. Re, En attendant mieux, dans le code remplace cette séquence : (progn (setq new_text (extract_txt nil (setq dxf1 (sel_obj "à COPIER")) nil)) (setq old_text (extract_txt nil (setq dxf2 (sel_obj "où COLLER")) nil)) (extract_txt T dxf2 new_text) ) Par la suivante : (progn (setq new_text (extract_txt nil (setq dxf1 (sel_obj "à COPIER")) nil)) (while (setq old_text (extract_txt nil (setq dxf2 (sel_obj "où COLLER")) nil)); modif (extract_txt T dxf2 new_text) ) ; modif ) C’est pas un modèle d’élégance (faire échappe pour sortir de la boucle) mais cela devrait faire le travail, mes obligations personnelles et professionnelles ne me permettant pas de faire plus en ce moment.. A+
  21. Bonjour, Sur Cadxp après une rapide recherche, je pense que ce code de BonusCAD fera l’affaire.. http://cadxp.com/topic/7656-copier-la-valeur-de-lattribu/page__view__findpost__p__38070 Je ne l’ai pas testé en profondeur mais une lecture rapide du code me dit qu’il devrait plutôt bien fonctionner. A+
  22. Bonjour, Il me semble que tu as supprimé la version en téléchargement du fichier, ce n’est pas grave, j’ai compris l’erreur sur mes tests, ils étaient erronés car j’ai bêtement généré des lignes avec la commande réseau (donc avec une trop grande quantité de lignes de longueurs identiques ce qui pénalisait ton algorithme au détriment du mien). Merci pour cette échange qui m’aura permis d’avoir de meilleurs repères en tête pour le traitement de cas similaire. Merci également pour la version de ta dll EraseDuplicatedLines_17. Pour ce qui est des versions Lisp, il n’y a aucune difficulté majeure bien au contraire, pour adapter l’algorithme précédent proposé par (gile). On peut directement trier sur la valeur du rayon, puis comparer les centres, les angles de départ et les angles de fin des arcs de cercle de même rayon. En repartant du code de (gile) cela devrait donner quelque chose comme ceci : (defun c:comparearc (/ ss n ent elst cen ray angdep angfin lst sub dup toErase t0 t1) (setq t0 (* 84600 (getvar 'tdusrtimer))) (if (setq ss (ssget "_X" '((0 . "ARC")))) (progn ;; constitue une liste de sous liste de sous-liste pour chaque ligne ;; (rayon ename (startAng endAng Centre)) (repeat (setq n (sslength ss)) (setq ent (ssname ss (setq n (1- n))) elst (entget ent) cen (cdr (assoc 10 elst)) ray (cdr (assoc 40 elst)) angdep (cdr (assoc 50 elst)) angfin (cdr (assoc 51 elst)) lst (cons (list ray ent (cons angdep (cons angfin cen))) lst) ) ) ;; trie la liste par rayon (setq lst (vl-sort lst (function (lambda (l1 l2) (< (car l1) (car l2)))))) ;; boucle principale (while lst (setq ray (caar lst)) ;; constitue une liste de ligne de longueurs égales (while (= ray (caar lst)) (setq sub (cons (cdar lst) sub) lst (cdr lst) ) ) ;; boucle sur la liste d'arc de même rayons pour chercher les arc superposées (while sub (foreach l (cdr sub) ;; évalue si deux arc sont superposées (if (equal (cadar sub) (cadr l)); (setq toErase (cons (car l) toErase) sub (vl-remove l sub) dup T ) ) ) (if dup (setq toErase (cons (caar sub) toErase)) ) (setq sub (cdr sub) dup nil ) ) ) ;; supprime toutes les lignes superposées (foreach l toErase (entdel l)) ) ) (setq t1 (* 84600 (getvar 'tdusrtimer))) (princ (strcat "\nTemps d'exécution : " (rtos (- t1 t0)) " secondes")) (princ) ) Et dans la foulé la variante sur mon code précèdent, qui consistait à sous-traiter l’ensemble du trie à la fonction vl-sort : (defun c:compararc2 (/ ss i lst e elst cen ray angdep angfin flag t0 t1 l1<l2-p) ;; prédicat d'inférieurité de deux listes numériques (defun l1<l2-p (l1 l2) (if (and l1 (equal (car l1) (car l2))) (l1<l2-p (cdr l1) (cdr l2)) (< (car l1) (car l2)) ) ) (setq t0 (* 84600 (getvar 'tdusrtimer))) (and ;; sélection (setq ss (ssget "_X" '((0 . "ARC")))) ;; boucle (repeat (setq i (sslength ss)) ;; extraction des données (setq e (ssname ss (setq i (1- i))) elst (entget e) cen (cdr (assoc 10 elst)) ray (cdr (assoc 40 elst)) angdep (cdr (assoc 50 elst)) angfin (cdr (assoc 51 elst)) ;; definie une liste de sous liste de coordonnées orienté ;; format (((xcen ycen zcen ray angdep angfin) . <ename>) ...) lst (cons (cons (append cen (list ray angdep angfin)) e) lst) ) ) ) ;; trie en fonction des sous listes de cordonnées (setq lst (vl-sort lst '(lambda (a B) (l1<l2-p (car a) (car B))))) ;; suppression des lignes supperposées (coordonnées identique) (while (setq flag nil elst (car lst) lst (cdr lst) ) (while (equal (car elst) (caar lst)) (entdel (cdar lst)) (setq flag T lst (cdr lst) ) ) (if flag (entdel (cdr elst)) ) ) (setq t1 (* 84600 (getvar 'tdusrtimer))) (princ (strcat "\nTemps d'exécution : " (rtos (- t1 t0)) " secondes")) (princ) ) Par contre si c’est pour adapter les codes en .net, je me vois dans l’obligation de passer mon tour… ;) A+ Bruno (Ps : J’espère que (gile) ne m’en voudra pas d’avoir répondu à sa place)
  23. Bonjour, Pour faire suite à ce qu’il a été dit précédemment sur les algorithmes et pour satisfaire ma curiosité personnel, une meilleur version (même dans le cas extrême ou il n’y aurait que des lignes superposées) (Edit: Une autre version). L’idée de base étant d’orienter toutes les lignes dans le même sens, puis de les trier suivants l’ensemble de leurs coordonnées de façon à sous-traiter l’intégralité de l’optimisation du traitement à la fonction lisp vl-sort. (defun c:compare2 (/ ss i lst e elst pt1 pt2 flag) ;; prédicat d'infériorité de deux listes numériques (defun l1<l2-p (l1 l2) (if (and l1 (equal (car l1) (car l2))) (l1<l2-p (cdr l1) (cdr l2)) (< (car l1) (car l2)) ) ) (setq t0 (* 84600 (getvar 'tdusrtimer))) (and ;; sélection (setq ss (ssget "_X" '((0 . "LINE")))) ;; boucle (repeat (setq i (sslength ss)) ;; extraction des données (setq e (ssname ss (setq i (1- i))) elst (entget e) pt1 (cdr (assoc 10 elst)) pt2 (cdr (assoc 11 elst)) ) ;; définie une liste de sous liste de coordonnées orientés ;; format (((xa ya za xb yb zb) . <ename>) ...) (if (l1<l2-p pt1 pt2) (setq lst (cons (cons (append pt1 pt2) e) lst)) (setq lst (cons (cons (append pt2 pt1) e) lst)) ) ) ) ;; trie en fonction des sous listes de cordonnées (setq lst (vl-sort lst '(lambda (a B) (l1<l2-p (car a) (car B))))) ;; suppression des lignes supperposées (coordonnées identique) (while (setq flag nil elst (car lst) lst (cdr lst) ) (while (equal (car elst) (caar lst)) (entdel (cdar lst)) (setq flag T lst (cdr lst) ) ) (if flag (entdel (cdr elst)) ) ) (setq t1 (* 84600 (getvar 'tdusrtimer))) (princ (strcat "\nTemps d'exécution : " (rtos (- t1 t0)) " secondes")) (princ) ) (Ps : (gile) Le fichier test que tu as posté n’étant pas compatible avec ma version d’AutoCAD, je n’ai pas su faire de comparaison avec ta version en .NET mais si ce dernier ne comportait qu’un faible pourcentage de lignes superposées, j’espère ne pas être trop loin derrière… ) A+
  24. Je suis personnellement heureux que comme (gile) vous partagiez votre approche de la programmation lisp sur les forums, pour la plus grande joie du codeur amateur que je suis, merci à vous. A+
  25. VDH-Bruno

    filtre dans SSGET "X"

    Re, Dans ce cas pour développer ;) , le filtre de sélection utilisé par la fonction lisp ssget supporte: Dans le cas des codes de groupes utilisant des chaînes de caractères (tel que les codes de groupes 0, 2, 8 etc..), il est possible d’utiliser les caractères générique ainsi que la virgule, comme on le ferai dans l’utilisation d’un filtre pour la fonction wcmath. Wild-Card Patterns in Filter Lists Pour les codes de groupe utilisant des caractères numériques (tel que les codes de groupes 10, 11, 40 etc..), on utilise les tests relationnels suivant * = != <= < >= < & &= au moyen du code -4. Relational Tests Pour grouper les différents type de codes dxf entre eux et créer ainsi des groupes logiques autres que le "<and", "and>" implicite du groupe de filtre. Cela ce réalise au moyen des opérateurs relationnel que sont le: "<and", "and>", "<or", "or>", "<xor", "xor>", "<not" et "not>" Logical Grouping of Filter Tests Pour des explications illustrées d’exemples en français, je conseille (si ce n'est déjà fait) la lecture du support rédigé par (gile) : http://gilecad.azurewebsites.net/Tutorials/Introduction_a_AutoLISP.pdf (page 39) A+ Bruno
×
×
  • 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é