azerty9 Posté(e) le 15 septembre 2013 Posté(e) le 15 septembre 2013 Bonjour à tous, Je voudrais savoir s'il était possible de définir des points particuliers sur un bloc enregistré dans un fichier à part. Je détaille : par un programme Lisp, un bloc est inséré, grâce son point d'insertion, à un point déjà connu. Je veux ensuite pouvoir récupérer les coordonnées d'un autre point spécifique de ce bloc, pour pouvoir insérer un autre bloc à partir de ce point. Les points pourraient être au préalable définis dans le bloc (ils sont spécifiques à chaque bloc et fixes). Il faudrait sinon un moyen de récupérer des valeurs en même temps que le bloc est inséré, ce qui permettrait alors de calculer les coordonnées du nouveau point. Si quelqu'un a des idées ! Merci.
lecrabe Posté(e) le 16 septembre 2013 Posté(e) le 16 septembre 2013 Hello J'imagine une routine qui recupererait apres insertion du bloc primaire : le nom de bloc secondaire , les coordonnees XY RELATIVES de deplacement par rapport au bloc primaire , la rotation eventuelle (si ce n'est pas la meme que celle du bloc primaire , etc depuis des attributs invisibles du bloc primaire ! Ainsi la routine serait "generaliste" ... Si j'ai bien compris la demande, lecrabe Autodesk Expert Elite Team
azerty9 Posté(e) le 16 septembre 2013 Auteur Posté(e) le 16 septembre 2013 Salut, Le principe est intéressant.. Il faut donc que j'arrive à récupérer les valeurs des attributs invisibles... J'ai trouvé un code sur internet qui rend visible les attributs invisibles, mais tout en Visual Lisp ! :( Pas simple à modifier ! Merci !
(gile) Posté(e) le 16 septembre 2013 Posté(e) le 16 septembre 2013 Salut, Pour rendre les attributs invisibles visibles, il suffit de jouer avec la variable système ATTMODE.Mais dans ton code AutoLISP ou Visual LISP, tu obtiendras tous les attributs sans distinction de visibilité, c'est par l'étiquette (tag) que tus les distingueras. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
azerty9 Posté(e) le 16 septembre 2013 Auteur Posté(e) le 16 septembre 2013 Salut, Pour rendre les attributs invisibles visibles, il suffit de jouer avec la variable système ATTMODE.Mais dans ton code AutoLISP ou Visual LISP, tu obtiendras tous les attributs sans distinction de visibilité, c'est par l'étiquette (tag) que tus les distingueras. Salut, Ok. Par contre, est-ce qu'il est possible de récupérer les attributs en AutoLisp (sans fonctions VL). Après avoir mis un attribut dans un bloc, j'ai essayé un (entnext (car (entsel))) en sélectionnant le bloc, mais ce ne fonctionne pas (retourne nil) (ça semble fonctionner dans l'éditeur de bloc uniquement). Du coup, comment faire ? Le passage par le VL est obligatoire ?J'ai trouvé des méthodes avec vla-get-tagstring et (vlax-invoke bloc 'getattributes), mais on trouve difficilement de la doc sur ces fonctions... Merci.
VDH-Bruno Posté(e) le 16 septembre 2013 Posté(e) le 16 septembre 2013 Bonsoir, Ok. Par contre, est-ce qu'il est possible de récupérer les attributs en AutoLisp (sans fonctions VL). Oui bien sur, d’ailleurs sur le forum (gile) a publié une routine GetAttribs très pratique pour récupérer les attributs sous forme d’une liste de paires pointés.Tu trouvera le code à cette adresse :http://cadxp.com/topic/32894-recuperer-la-valeur-dun-attribut/page__view__findpost__p__176345Ainsi que des explications et des lignes de codes commentés dans la suite de la discussion. A+ Apprendre => Prendre => Rendre
Bred Posté(e) le 17 septembre 2013 Posté(e) le 17 septembre 2013 Salut,J'ai l'impression que vous vous compliquez beaucoup la chose... Si c'es ten programation, il faudrait savoir à quel moment vous en êtres du programme pour déterminer le niveau de récupération des infos... et de quelle manière vous rentrez ces infos. Par contre, si vous voulez insérer un bloc sur un autre bloc "à la main" (mais pas à son point d'insert), vous n'avez qu'à créer dans le premier bloc un point, une marque (cercle, nodal, intersection...) qui vous serve de réference pour inserer le second... et si vous ne voulez pas que cette "marque" s'imprime, vous la mettez dans un calque spécifique. Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...
lecrabe Posté(e) le 17 septembre 2013 Posté(e) le 17 septembre 2013 Hello +1 avec Bred Par exemple un point graphique sur le calque "DefPoints" ainsi il ne s'imprimera jamais ! lecrabe Autodesk Expert Elite Team
VDH-Bruno Posté(e) le 17 septembre 2013 Posté(e) le 17 septembre 2013 Bonjour, vous n'avez qu'à créer dans le premier bloc un point, une marque (cercle, nodal, intersection...) qui vous serve de réference pour inserer le second... C’est l’illustration de ce que souhaitait azerty9 Les points pourraient être au préalable définis dans le bloc (ils sont spécifiques à chaque bloc et fixes). Le souci dans ce cas c’est qu’il te faudra tenir compte du point d’insertion de ta référence ainsi que de son l’échelle d’insertion, pour modifié les coordonnées de ton point que tu auras récupéré en parcourant la définition de ton bloc.Et dans l’hypothèse ou l’on voudrait définir plusieurs points comment les distinguer? Dans ma suggestion précédente, au développement succinct l’idée implicite n’était pas de récupérer la fonction GetAttribs tel quel, l’astuce dans mon esprit consistait à modifier légèrement le code de façon à récupérer la position des attributs en fonction de leurs étiquettes, à condition de positionner la définition de l’attribut au point désiré dans la définition de bloc. Pour ainsi obtenir directement les coordonnés pour la prochaine insertion en fonction de l’étiquette du bloc (Ce qui permettrait même de pouvoir en définir aisément plusieurs) La fonction s’écrivant par exemple comme ceci.;; GetPosAttribs ;; Retourne une liste de paire pointées (TAG . Position) par attribut contenus dans le bloc ;; Position -> code DXF 10 ;; Argument ;; ent : le nom d'entité (ENAME) de la référence de bloc (defun GetPosAttribs (ent / elst lst) (setq ent (entnext ent)) (while (= "ATTRIB" (cdr (assoc 0 (setq elst (entget ent))))) (setq lst (cons (cons (cdr (assoc 2 elst)) (cdr (assoc 10 elst))) lst) ent (entnext ent) ) ) (reverse lst) ) Pour finir de s'en convaincre il suffit de tester cette ligne de code(entmake (list '(0 . "LINE") (assoc 10 (entget(car(nentsel)))) '(11 0.0 0.0 0.0))) Sur un bloc ayant subit des transformations, puis de cliquer une fois sur un attributs puis une seconde fois sur une entité quelconque du bloc (ayant un code dxf 10), dans le premier cas une ligne est dessiné du point 0,0,0 au point d’insertion de l’attribut dans la référence de bloc, dans l’autre cas une ligne du point 0,0,0 au point dxf 10 tel qu’il est spécifié dans les coordonnées du SCO de la définition du bloc. En espérant avoir était suffisamment clair, même si sur ce dernier point j’ai un gros doute… A+ Bruno(Ps : Après rien n’empêche de définir les attributs sur un calque non imprimable ou même gelé) Apprendre => Prendre => Rendre
Bred Posté(e) le 17 septembre 2013 Posté(e) le 17 septembre 2013 ... Je pense que vous vous compliquez bien les choses, les attributs n'ont aucun interet dans ce cas.Créez un tableau dans le code avec le nom du bloc est par association une coordonnée secondaire correspondant.(Mais je reste dubitatif sur l'utilité d'un code pour cela, d'où ma question quel est le niveau dans la manip de ce besoin ?) Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...
azerty9 Posté(e) le 17 septembre 2013 Auteur Posté(e) le 17 septembre 2013 Hello tout le monde, et merci pour les réponses. L'astuce de récupérer la position de l'attribut est intéressante. Elle permettrait également de filtrer facilement les points, dans les cas ou il y en aurait plusieurs... A savoir que les points à obtenir pourraient être obtenus assez facilement avec 2-3 attributs qui contiendraient des infos sur la géométrie du bloc inséré. J'avais déjà pensé à utiliser un point, qui serait masqué. Mais, si le plan est censé contenir des points, l'utilisateur de la routine changera la variable PMODE afin d'afficher les points, et là, ce serait pas très beau à voir ! :P Mettre les points sur des calques spécifiques, masqués, fonctionnerait mais l'idée d'avoir un calque, au milieu des autres, qui ne contient que des données permettant l’exécution du programme, m’embête un petit peu, même si c'est peut-être au final pas grand chose... Les attributs sont intéressants dans le sens où ils ne créent pas d'objet graphique, et peuvent être totalement invisibles aux yeux de celui utilisera la routine. Si c'es ten programation, il faudrait savoir à quel moment vous en êtres du programme pour déterminer le niveau de récupération des infos... et de quelle manière vous rentrez ces infos. Sur ce programme, qui sera au final l'extension d'un déjà existant, rien n'est fait. J'attends justement de voir comment passer ce problème avant de commencer. J'ai aussi la liberté de pouvoir saisir les infos à peu près de la manière souhaitée. Dans ma suggestion précédente, au développement succinct l’idée implicite n’était pas de récupérer la fonction GetAttribs tel quel, l’astuce dans mon esprit consistait à modifier légèrement le code de façon à récupérer la position des attributs en fonction de leurs étiquettes, à condition de positionner la définition de l’attribut au point désiré dans la définition de bloc. Pour ainsi obtenir directement les coordonnés pour la prochaine insertion en fonction de l’étiquette du bloc (Ce qui permettrait même de pouvoir en définir aisément plusieurs) La fonction s’écrivant par exemple comme ceci.;; GetPosAttribs ;; Retourne une liste de paire pointées (TAG . Position) par attribut contenus dans le bloc ;; Position -> code DXF 10 ;; Argument ;; ent : le nom d'entité (ENAME) de la référence de bloc (defun GetPosAttribs (ent / elst lst) (setq ent (entnext ent)) (while (= "ATTRIB" (cdr (assoc 0 (setq elst (entget ent))))) (setq lst (cons (cons (cdr (assoc 2 elst)) (cdr (assoc 10 elst))) lst) ent (entnext ent) ) ) (reverse lst) ) J'ai fait un rapide essai, mais ça n'a pas fonctionné... Il semblerait que le entnext renvoie nil. A savoir que j'ai mis comme propriété à l'attribut invisible et constant, pour ne pas que l'utilisateur ait à saisir une valeur lors de l'insertion par la routine...
azerty9 Posté(e) le 17 septembre 2013 Auteur Posté(e) le 17 septembre 2013 Ah par contre, gros problème des attributs auxquels je n''avais pas pensé, c'est que les blocs pourront être amenés à être décomposés... Du coup le nom de l'attribut apparaît... Sur ce point là, le point masqué sur un calque a un avantage...
VDH-Bruno Posté(e) le 17 septembre 2013 Posté(e) le 17 septembre 2013 Bonsoir, J'ai fait un rapide essai, mais ça n'a pas fonctionné... Il semblerait que le entnext renvoie nil. A savoir que j'ai mis comme propriété à l'attribut invisible et constant, pour ne pas que l'utilisateur ait à saisir une valeur lors de l'insertion par la routine... Effectivement je n'avais jamais fait attention qu'avec constant on avait pas accès à la définition de l'attribut. Personnellement je ne me suis jamais servi de cette option ou alors très rarement et il y a très longtemps. Pour éviter de saisir une valeur lors de l'insertion je me sers de la propriété Prédéfini. Après un test rapide avec l'option prédéfini aucun soucis:_$ (GetPosAttribs (car (entsel))) (("POS3" 2606.56 1609.58 0.0) ("POS2" 2606.96 1604.11 0.0)) _$ Je récupère bien le point d'insertion de mes deux étiquette d'attributs Pos3 et Pos2 définie dans ma référence de bloc. Cordialement, Apprendre => Prendre => Rendre
VDH-Bruno Posté(e) le 17 septembre 2013 Posté(e) le 17 septembre 2013 Ah par contre, gros problème des attributs auxquels je n''avais pas pensé, c'est que les blocs pourront être amenés à être décomposés... Du coup le nom de l'attribut apparaît... Sur ce point là, le point masqué sur un calque a un avantage... Le même qu'une définition d'attribut sur un calque gelé ;) A+ Apprendre => Prendre => Rendre
azerty9 Posté(e) le 17 septembre 2013 Auteur Posté(e) le 17 septembre 2013 Merci bien VDH-Vruno ! ;) Du coup, il me reste à faire mon choix entre les deux solutions ! C'est possible de récupérer les attributs (ou points) sur un calque gelé ?Je pensais qu'il aurait été uniquement possible de le masquer. Merci
VDH-Bruno Posté(e) le 17 septembre 2013 Posté(e) le 17 septembre 2013 Du coup, il me reste à faire mon choix entre les deux solutions !Je pense qu’il y a également d’autres pistes de réflexion comme par exemple utiliser un ou plusieurs paramètres points lors de la création du bloc, il me semble avoir aperçu des codes utilisant les propriétés dynamique des bloc mais n’ayant jamais rien codé de tel, je ne peux à mon niveau garantir un résultat concluant, à voir.. A+ Apprendre => Prendre => Rendre
Bred Posté(e) le 18 septembre 2013 Posté(e) le 18 septembre 2013 Re,Pouquoi vouloir vous embéter avec les attributs ?... vous devez les modifier ? Il faudrait être plus clair sur le but final, car ce que vous vouez faire me semble simple.... sauf quand vous dites que vous devez décomposer des blocs, c'est votre prog qui fait ça ? J'ai déjà fait un gros developement permettant à partir d'une boite de dialogue de construire automatiquement une structure entièrement réalisé avec des dixaines de blocs différents positionné chacun à des points précis par rapport aux autres (constrution type métallique en 3D).Si c'est ce genre de chose que vous voulez faire, je ne vois pas en quoi des attributs peuvent vous aider, et encore moins la raison de vouloir décomposer un bloc. Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...
VDH-Bruno Posté(e) le 18 septembre 2013 Posté(e) le 18 septembre 2013 Bonjour, Pouquoi vouloir vous embéter avec les attributs ?... vous devez les modifier ?Pour mon cas personnel c’était plus tenter de répondre à l’intitulé du sujet «Définir des points particuliers sur un bloc», et je trouvais intéressant de passer par les attribut pour montrer que l’on peut exploiter autre chose que leurs valeurs, comme par exemple leurs coordonnées d’insertions en fonction de leurs libellés et ainsi s’affranchir du calcul des transformations de rotations, d’échelles et de translations. De plus la recherche de solution me permet sur un plan personnel d’approfondir certaines notions et dans le cas présent je n’avais jamais songé à la propriétés constant des attributs. Sinon pour moi c’est une solution comme tant d’autres, il est sûr que je n’ai pas ton recul et ton expérience sur le sujet. Je pense qu’il y a également d’autres pistes de réflexion comme par exemple utiliser un ou plusieurs paramètres points lors de la création du bloc, il me semble avoir aperçu des codes utilisant les propriétés dynamique des bloc mais n’ayant jamais rien codé de tel, je ne peux à mon niveau garantir un résultat concluant, à voir..Sinon pour me répondre et explorer des pistes qui me sont encore inconnue, l’idée d’exploiter les propriétés dynamique des blocs semble également fonctionner. D’autant plus que (gile) ayant été une fois de plus très généreux sur le sujet, c’est trés confortable pour le lispeur amateur que je suis de passer après, donc en repartant des codes publier ici :http://cadxp.com/topic/30066-modifier-un-bloc-dynamique-en-fonction-de-son-attribut/ ;; gc:GetDynProps ;; Retourne la liste des propriétés dynamiques de la référence de bloc ;; sous forme d'une liste de paires pointées : (nom_propriété . propriété) ;; ;; Argument ;; blk : le bloc (ename ou vla-object) (defun gc:GetDynProps (blk / lst) (vl-load-com) (and (= (type blk) 'ENAME) (setq blk (vlax-ename->vla-object blk))) (if (and (= (vla-get-ObjectName blk) "AcDbBlockReference") (= (vla-get-IsDynamicBlock blk) :vlax-true)) (foreach p (vlax-safearray->list (vlax-variant-value (vla-GetDynamicBlockProperties blk))) (setq lst (cons (cons (vla-get-PropertyName p) p) lst)) ) ) (reverse lst) ) ;; gc:GetDynPropValue ;; Retourne la valeur d'une propriété dynamique ;; ;; Arguments ;; blk : la référence de bloc (ename ou vla-object) ;; name : le nom de la propriété (sensible à la casse) (defun gc:GetDynPropValue (blk name / val) (vl-load-com) (if (setq prop (assoc name (gc:GetDynProps blk))) (vlax-variant-value (vla-get-Value (cdr prop))) ) ) Pour tester je me suis créer un bloc simple un carré de 10x10 auquel j’ai ajouté quatre paramètre point nommé Pos1, Pos2, Pos3, Pos4 à chaque sommet. Pour voir les paramètres de la référence de bloc :_$ (gc:GetDynProps (car (entsel)))(("Pos1 X" . #<VLA-OBJECT IAcadDynamicBlockReferenceProperty 2e450704>) ("Pos1 Y" . #<VLA-OBJECT IAcadDynamicBlockReferenceProperty 2e450f54>) ("Pos2 X" . #<VLA-OBJECT IAcadDynamicBlockReferenceProperty 2e450f34>) ("Pos2 Y" . #<VLA-OBJECT IAcadDynamicBlockReferenceProperty 2e450f14>) ("Pos3 X" . #<VLA-OBJECT IAcadDynamicBlockReferenceProperty 2e452f84>) ("Pos3 Y" . #<VLA-OBJECT IAcadDynamicBlockReferenceProperty 2e452f04>) ("Pos4 X" . #<VLA-OBJECT IAcadDynamicBlockReferenceProperty 2e452e84>) ("Pos4 Y" . #<VLA-OBJECT IAcadDynamicBlockReferenceProperty 2e452e04>) ) Pour récupérer par exemple les coordonnées (SCO) du paramètre point Pos1:((lambda (eName pName) (list (gc:GetDynPropValue eName (strcat pName " X")) (gc:GetDynPropValue eName (strcat pName " Y"))) ) (car (entsel)) "Pos1" )Retourne (-5.0 5.0) Le point retourné portant déjà des éventuelles transformations d’échelle, il ne reste plus qu’une rotation et un déplacement pour traduire les coordonnées dans le SCG (à condition que le SCO // SCG)((lambda (eName pName / eDxf ang pins pt) (setq eDxf (entget eName) ang (cdr (assoc 50 eDxf)) pins (cdr (assoc 10 eDxf)) pt (list (gc:GetDynPropValue eName (strcat pName " X")) (gc:GetDynPropValue eName (strcat pName " Y")) 0.0 ) ) (mapcar '+ (polar '(0. 0. 0.) (+ (angle '(0. 0. 0.) pt) ang) (distance '(0. 0. 0.) pt)) pins) ) (car (entsel)) "Pos1" ) Retourne (285.702 395.764 0.0) Remarque: L’inconvénient de la méthode c‘est que sur 2007, les blocs dynamiques ne supportent que les échelles homogènes en X, Y et Z. A+ Apprendre => Prendre => Rendre
azerty9 Posté(e) le 18 septembre 2013 Auteur Posté(e) le 18 septembre 2013 Bonjour a tous, En fait, une des utilisations de ce programme serait, un peu comme pour ton programme, Bred. c'est à dite un programme de dessin semi automatisé pour de la mécanique / tuyauterie. L'utilisation de blocs dynamiques, dans mon cas, me semble pas la plus adaptée, dans le sens où les blocs font partie d'une bibliothèque commune, où d'autres programmes font référence. Quand au besoin de décomposer des blocs, cela arrive assez fréquemment. Tout simple si un élément passe devant un autre (dessin en 2D). Alors parfois, il s'agit d'un élément un peu particulier, qui va être dessiné à partir d'un bloc "proche".
VDH-Bruno Posté(e) le 18 septembre 2013 Posté(e) le 18 septembre 2013 Re, L'utilisation de blocs dynamiques, dans mon cas, me semble pas la plus adaptée, dans le sens où les blocs font partie d'une bibliothèque commune, où d'autres programmes font référence. Le bloc n’est pas obligé d’être dynamique, pour avoir un paramètre point tu n’es pas obligé de lui associé un paramètre d’action. Voir ce sujet :http://cadxp.com/topic/36132-multi-points-de-base-dans-bloc-dynamique/page__view__findpost__p__196351L’information ainsi créé étant non graphique pas de soucis lors de la décomposition, et sur ta bibliothèque de bloc a part offrir des possibilités étendue de points d’insertions , je ne vois pas d’inconvénient particulier. Quand au besoin de décomposer des blocs, cela arrive assez fréquemment. Tout simple si un élément passe devant un autre (dessin en 2D Pour ce besoin je sais que certains utilise un masque, ou une hachure solide en jouant après sur l’ordre de tracé pour avoir l’effet souhaité. A+ Apprendre => Prendre => Rendre
azerty9 Posté(e) le 18 septembre 2013 Auteur Posté(e) le 18 septembre 2013 Très intéressant ce système dynamique. Je vais me renseigner et faire des essais... Par contre, pas de "conflit" avec le point de base initial ? Je pose la question par rapport aux autres routines déjà existantes qui utilisent le point de base...
VDH-Bruno Posté(e) le 18 septembre 2013 Posté(e) le 18 septembre 2013 Très intéressant ce système dynamique. Je vais me renseigner et faire des essais... Par contre, pas de "conflit" avec le point de base initial ? Je pose la question par rapport aux autres routines déjà existantes qui utilisent le point de base...Non pas à ma connaissance, car il ne peut y avoir qu’un seul point de base dans un bloc, pour tes essais il faut bien ajouter le paramètre point et pas point de base dans la conception de ton bloc via l’éditeur de bloc. A+ Apprendre => Prendre => Rendre
azerty9 Posté(e) le 18 septembre 2013 Auteur Posté(e) le 18 septembre 2013 En effet, pas de soucis de ce côté là, ni lors de la décomposition. Reste à trouver un Lisp pour récupérer ces points là ! Je me lance dans quelques recherches !
VDH-Bruno Posté(e) le 18 septembre 2013 Posté(e) le 18 septembre 2013 En effet, pas de soucis de ce côté là, ni lors de la décomposition. Reste à trouver un Lisp pour récupérer ces points là ! Je me lance dans quelques recherches ! Teste les codes de la réponse n°18, je pense que tu as la une bonne base de départ il suffit de spécifier le nom de ton paramètre pour récupérer ton point, après il ne reste plus qu'a adapter suivant ton besoin. A+ Apprendre => Prendre => Rendre
azerty9 Posté(e) le 20 septembre 2013 Auteur Posté(e) le 20 septembre 2013 En effet, après quelques essais, j'ai implémenté le code dans le programme, et ca fonctionne impeccablement ! Merci pour tout !
Messages recommandés
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 compteSe connecter
Vous avez déjà un compte ? Connectez-vous ici.
Connectez-vous maintenant