rrobert Posté(e) le 2 juin 2021 Posté(e) le 2 juin 2021 Bonjour, Ca y est, j'ai aussi passé la barre du VBA ! Vraiment simple en réalité, connaissant déjà VBA sur Excel, le passage sur Autocad se fait en effet sans encombres 🙂 J'aimerai créer une macro qui détecte le croisement d'objets sur Autocad. J'ai plein d'idées en têtes mais je suis sûr que vos idées et conseils sauront m'orienter dans la méthode de détection. Je m'explique, ce que je veux : - Sélectionner des objets sur mon plan Autocad (deux objets pour commencer) - Détecter tous les points de croisement entre ces objets - Créer un cercle autour du point de croisement détecté. Ainsi si deux objets ont au moins un point dont les coordonnées X, Y correspondent, alors il y a détection de croisement. Sachant que les objets seront principalement des blocs, avec plusieurs polylignes et cercles. Des exemples pour mieux comprendre : Attention, je ne cherche pas une macro toute faite, je suis simplement à la recherche de conseils pour établir une méthode de détection ! J'avais pensé à créer deux points dynamiques appelés Conn1 et Conn2 pour chaque bloc et faire correspondre les points de chaque bloc. Ainsi la macro pourrait vérifier s'ils y a une correspondance entre les "Connecteurs" des blocs sélectionnés. Sauf que cela m'oblige à déplacer tous les connecteurs des blocs en fonction de chaque paramètre dynamique, et m'aimerai éviter cela 😉 Dans l'attente de vos idées je vous souhaite une bonne journée ! Rémi
(gile) Posté(e) le 2 juin 2021 Posté(e) le 2 juin 2021 Salut, IntersectWith. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Curlygoth Posté(e) le 2 juin 2021 Posté(e) le 2 juin 2021 Quote le passage sur Autocad se fait en effet sans encombres Oui, j'arrete pas le dire ! cool que tu passe le pas ! Quote Ainsi si deux objets ont au moins un point dont les coordonnées X, Y correspondent, Yes, tu peux ça mais tu verras (avec expérience que calcule la fonction affine des polyligne entre 2 points pour calculer la distance des points les commparer etc etc etc.. c'est bien **** J'avais pensé à créer deux points dynamiques appelés Conn1 et Conn2 pour chaque bloc et faire correspondre les points de chaque bloc. Oui dans ce cas tu peux le faire, je l'ai fait pour creer un carroyage dans mes blocs folios sinon tu peux essayer cette méthodes : Points = OBJ1.IntersectWith(OBJ2, acExtendNone) ca va te donner les points d'intersection (attention Points est une liste de point 3D ! Mon site Web (en cours de construction) : Site DA-CODE de @didier
rrobert Posté(e) le 2 juin 2021 Auteur Posté(e) le 2 juin 2021 Mais c'est magique ça ! Je regarde ce midi, merci. Rémi
rrobert Posté(e) le 2 juin 2021 Auteur Posté(e) le 2 juin 2021 Alors ca marche très bien sur des objets de base (cercle, polyligne), mais sur les blocs j'ai du mal à comprendre 😕 On dirait que si les blocs sont proches, même s'ils ne se touchent pas, il renvoie un ou deux points, et ce même s'il y a plus de deux points de croisement. Et si les blocs sont suffisamment éloignés, il ne détecte pas de croisement. Voici le code test utilisé (repris en partie de la page Autocad) : Sub Example_IntersectWith() Dim selection1 As AcadEntity Dim selection2 As AcadEntity Dim point_selection As Variant 'Si la sélection comporte une erreur on recommence la phase de sélection On Error Resume Next RETRY: 'Code de sélection ThisDrawing.Utility.GetEntity selection1, point_selection, vbCr & "Sélectionnez l'objet 1" 'verification des erreurs de selection If Err <> 0 Then Err.Clear MsgBox "La sélection est vide ou non valide." GoTo RETRY End If 'Si la sélection comporte une erreur on recommence la phase de sélection On Error Resume Next RETRY2: 'Code de sélection ThisDrawing.Utility.GetEntity selection2, point_selection, vbCr & "Sélectionnez l'objet 2" 'verification des erreurs de selection If Err <> 0 Then Err.Clear MsgBox "La sélection est vide ou non valide." GoTo RETRY2 End If ' Find the intersection points between the line and the circle Dim intPoints As Variant intPoints = selection1.IntersectWith(selection2, acExtendNone) Dim str As String str = "" ' Print all the intersection points Dim I As Integer, j As Integer, k As Integer If VarType(intPoints) <> vbEmpty Then For I = LBound(intPoints) To UBound(intPoints) str = str & Chr(13) & "Intersection Point[" & k & "] is: " & intPoints(j) & " , " & intPoints(j + 1) & " , " & intPoints(j + 2) I = I + 2 j = j + 3 k = k + 1 Next MsgBox str, , "IntersectWith Example" End If End Sub J'ai également joint le fichier de test utilisé (une polyligne et un bloc simple). EDIT 1 : je suis pourtant bien en option acExtendNone, n'est-il pas censé ne pas étendre les objets? EDIT 2 : lorsque deux blocs se croisent et ont plus de 2 points de croisement, il ne me sort que 2 points d'intersection (ca parait logique car c'est un bloc composé de plusieurs objets élémentaires, mais peut-on trouver tous les points d'intersection de tous les objets des deux blocs?) Dessin2.dwg
Curlygoth Posté(e) le 2 juin 2021 Posté(e) le 2 juin 2021 C'est normal non? Mais... Rien ne t'empêche de construire des objets de constructions (comme mon programme qui gère une longueur dans mes bloc dynamique) Quote je suis pourtant bien en option acExtendNone, n'est-il pas censé ne pas étendre les objets? Tes objets "genre" polyligne, cercle, etc " oui Tes blocs dynamiques non 😉 Quote lorsque deux blocs se croisent et ont plus de 2 points de croisement, il ne me sort que 2 points d'intersection (ca parait logique car c'est un bloc composé de plusieurs objets élémentaires, mais peut-on trouver tous les points d'intersection de tous les objets des deux blocs?) Non car un bloc est un objet 😉 Si tu veux un "bloc" composé d'objets c'est un groupe qu'il faut faire 😉 Mon site Web (en cours de construction) : Site DA-CODE de @didier
rrobert Posté(e) le 2 juin 2021 Auteur Posté(e) le 2 juin 2021 1 hour ago, Curlygoth said: Mais... Rien ne t'empêche de construire des objets de constructions (comme mon programme qui gère une longueur dans mes bloc dynamique) Des objets de construction, c'est à dire? 1 hour ago, Curlygoth said: Non car un bloc est un objet 😉 Mais du coup, que prend-t-il en compte pour déterminer les points de croisement?
Curlygoth Posté(e) le 2 juin 2021 Posté(e) le 2 juin 2021 Quote Des objets de construction, c'est à dire? et bien dans mon programme, je dessine une droite qui part d'un point sur mon bloc (Point de base car moins compliqué pour la suite) je l’oriente d'un angle (angle qu'a en faite le bloc) puis je trace une droite ensuite je checks mes points d'intersections Je calcule la distance entre le point de base et le point d'intersection et paf je rentre la valeur dans mon bloc dynamique ! une orientation et une distance et voila mon bloc et parfait ^^ demo en gif : Mon site Web (en cours de construction) : Site DA-CODE de @didier
rrobert Posté(e) le 2 juin 2021 Auteur Posté(e) le 2 juin 2021 J'ai rajouté quelques lignes afin de créer un cercle dont le centre se trouve sur les points d'intersection trouvés. Et bien pour les blocs, tout cela parait bien chaotique...
rrobert Posté(e) le 2 juin 2021 Auteur Posté(e) le 2 juin 2021 3 minutes ago, Curlygoth said: et bien dans mon programme, je dessine une droite qui part d'un point sur mon bloc (Point de base car moins compliqué pour la suite) je l’oriente d'un angle (angle qu'a en faite le bloc) puis je trace une droite ensuite je checks mes points d'intersections Je calcule la distance entre le point de base et le point d'intersection et paf je rentre la valeur dans mon bloc dynamique ! une orientation et une distance et voila mon bloc et parfait ^^ demo en gif : Intéressant ! Je vais creuser ce sujet 🙂
Curlygoth Posté(e) le 2 juin 2021 Posté(e) le 2 juin 2021 si tu as besoin 😉 regarde mon site, je vais devoir le mettre à jour mais ça te donnera des idées ^^ (onglet réalisation) Mon site Web (en cours de construction) : Site DA-CODE de @didier
(gile) Posté(e) le 2 juin 2021 Posté(e) le 2 juin 2021 Pour les blocs, IntersectWith considère l'emprise (BoundingBox). À mon avis, le plus simple pour chercher les intersections entre les composants de deux blocs est de décomposer les blocs. La méthode Explode renvoie un tableau d'objets, on cherche les intersections entre les composants d'un bloc et ceux de l'autre puis on supprime ces objets (Delete). Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
rrobert Posté(e) le 2 juin 2021 Auteur Posté(e) le 2 juin 2021 @gile j'avais en effet pensé à cette solution. Ducoup sélectionner les blocs, en faire une copie, exploser les originaux, déterminer les intersections puis supprimer les originaux? Est-ce que IntersectWith peut gérer plus de deux objets?
Curlygoth Posté(e) le 2 juin 2021 Posté(e) le 2 juin 2021 Quote Ducoup sélectionner les blocs, en faire une copie, exploser les originaux, déterminer les intersections puis supprimer les originaux? tu peux tout faire ! a partir du moment ou tu "enregistre" ou sauvegarde tes blocs avec leurs propriétés pour les ressortir plus tard 😉 tu peux aussi les déplacer et les remettre ensuite.... il n'y a pas de limites aux idées !! Par contre, fixe toi en une. Ttravail-la et regarde ça convient ou non et au pire tu changes d'idées. tu vas vite prendre de l'expérience en faisant cette méthode 😉 et tu verras que tu cibleras plus vite comment résoudre tes problèmes futurs ! Quote Est-ce que IntersectWith peut gérer plus de deux objets? a ma connaissance non... mais donne nous un exemple je suis sur qu'on pourra t'aider dans ta problématique 😉 Mon site Web (en cours de construction) : Site DA-CODE de @didier
rrobert Posté(e) le 2 juin 2021 Auteur Posté(e) le 2 juin 2021 Autre question @gile, peut-on contrôler l'emprise du bloc ou bien est-elle définie automatiquement en fonction des objets qui sont dessus? 😁
Curlygoth Posté(e) le 2 juin 2021 Posté(e) le 2 juin 2021 je m'appelle pas (gile) mais je me permets de repondre quand même XD elle est définie automatiquement en fonction des objets qui compose le bloc voici la box de mon blocs en exemple dessiné en traité pointillé bleu gras Mon site Web (en cours de construction) : Site DA-CODE de @didier
rrobert Posté(e) le 2 juin 2021 Auteur Posté(e) le 2 juin 2021 @Curlygoth je m'en doute, mais ça atteint la limite de mes connaissances de VBA sur Autocad 😉 Existe-t-il des cours VBA Autocad pour débutants? Concernant la question du nombre de sélections : Voici un exemple type de ce que je souhaite faire : J'ai 6 blocs disposés ainsi : (la disposition change évidemment pour chaque projet) Je souhaite contrôler que tous mes blocs sont bien reliés entre eux. Ou plutôt, que chaque bloc a sa ou ses extrémités reliées à un autre bloc. Idéalement, j'aimerai sélectionner tous mes blocs d'un coup et que la macro vérifie tous les blocs en un passe (avec par exemple un attribut interne possédant le nombre de connections à vérifier pour chaque type de bloc).
rrobert Posté(e) le 2 juin 2021 Auteur Posté(e) le 2 juin 2021 1 minute ago, Curlygoth said: je m'appelle pas (gile) mais je me permets de repondre quand même XD elle est définie automatiquement en fonction des objets qui compose le bloc voici la box de mon blocs en exemple dessiné en traité pointillé bleu gras Comment as-tu fait pour visualiser l'emprise de ton bloc? Est-ce que IntersectWith peut contrôler autre chose que l'emprise (par exemple considérer le point d'insertion du bloc)?
Curlygoth Posté(e) le 2 juin 2021 Posté(e) le 2 juin 2021 Quote Existe-t-il des cours VBA Autocad pour débutants? Tu as pleins de bouquins en anglais... souvent payant (sinon je fais pas de pub ici) mais va sur mon site 😉 (gile) fait aussi des programmes (et il peut surement faire des formations aussi je pense faut lui demander) tu as son site dans ma signature Rebcao fait des programmes aussi (mais je sais pas s'il fait du VBA...) Tout ça pour dire qu'on est plusieurs à proposer ce genre des services, et que je ne veut pas faire d'ombre à ces personne qui vivent de ça contrairement à moi qui est un travail à coté (jusqu'au 18 juin 2021). Quote Je souhaite contrôler que tous mes blocs sont bien reliés entre eux. Facile ! si c'est des blocs dynamiques et si tu as des blocs "simple" comme ton TE, Iil faudra peut etre dessiner son contour via vba ^^ opu manuel pour récupérer sa geométrie et donc une fois fait. Analyser son emprise réel Quote Idéalement, j'aimerai sélectionner tous mes blocs d'un coup et que la macro vérifie tous les blocs en un passe (avec par exemple un attribut interne possédant le nombre de connections à vérifier pour chaque type de bloc). Et pourquoi pas l'inverse ? En dessinant l'axe de toutes tes "conduites" dans un calque, tu pourrais peut-etre dessiner tous en une fois ? mais sinon oui c'est faisable ! Quote Comment as-tu fait pour visualiser l'emprise de ton bloc? je suis pas magicien mais dans un objet tu as la variable .GetBoundingBox Ca te permet d'avoir les 2 points de box de ton objet (point bas gauche et haut droit si je dit pas de bêtises) (D'ailleurs j'utilise cette méthode pour nettoyer des plans dwg issu d'un pdf (je regarde le rapport "surface de la box" avec la "longueur des polylignes" qui est à l'intérieur) Mon site Web (en cours de construction) : Site DA-CODE de @didier
(gile) Posté(e) le 2 juin 2021 Posté(e) le 2 juin 2021 Essayez la méthode Explode avec un bloc, elle ajoute les composant à l'espace propriétaire du bloc et renvoie les liste de ces objets, mais elle ne supprime pas la référence de bloc source, donc pas besoin de copie. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
(gile) Posté(e) le 2 juin 2021 Posté(e) le 2 juin 2021 Un exemple vite fait en VisualLISP (mêmes fonctions qu'en VBA) qui dessine des cercles de 1 unité de rayon sur les intersections entre les deux blocs sélectionnés. (vl-load-com) (or *acad* (setq *acad* (vlax-get-acad-object))) (or *acdoc* (setq *acdoc* (vla-get-ActiveDocument *acad*))) (defun c:test (/ f e1 e2 l1 l2) (defun f (l) (if l (cons (list (car l) (cadr l) (caddr l)) (f (cdddr l))) ) ) (if (and (setq e1 (car (entsel "\nSélectionnez le premier bloc: "))) (setq e1 (vlax-ename->vla-object e1)) (= (vla-get-ObjectName e1) "AcDbBlockReference") (setq e2 (car (entsel "\nSélectionnez le second bloc: "))) (setq e2 (vlax-ename->vla-object e2)) (= (vla-get-ObjectName e2) "AcDbBlockReference") (setq l1 (vlax-invoke e1 'Explode)) (setq l2 (vlax-invoke e2 'Explode)) ) (progn (vl-catch-all-apply '(lambda (/ pts ms) (setq ms (vla-get-ModelSpace *acdoc*)) (foreach o1 l1 (foreach o2 l2 (foreach p (f (vlax-invoke o1 'IntersectWith o2 acExtendNone)) (vla-put-Color (vla-AddCircle ms (vlax-3d-Point p) 1.0) 1) ) ) ) ) ) (foreach o l1 (vla-Delete o)) (foreach o l2 (vla-Delete o)) ) ) (princ) ) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Curlygoth Posté(e) le 2 juin 2021 Posté(e) le 2 juin 2021 Quote Essayez la méthode Explode avec un bloc, elle ajoute les composant à l'espace propriétaire du bloc et renvoie les liste de ces objets, mais elle ne supprime pas la référence de bloc source, donc pas besoin de copie. J'avoue ! et tu supprimes ensuite tes entités du bloc "explode" ! comme quoi il existe une multitude de solutions pour un problème Mon site Web (en cours de construction) : Site DA-CODE de @didier
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