Aller au contenu

Détection croisement d'objets


rrobert

Messages recommandés

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 :

 

image.thumb.png.a33a05591753c789f9e5e9ff72b98209.png

 

image.png.3066f191734d65da01d45d705a2cecb3.png

image.png.ae2ac2ed97009a53091d1f7cd10d8268.png

image.png.ef5780a01d221b3b85b6a951ad1c2d4a.png

 

 

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

Lien vers le commentaire
Partager sur d’autres sites

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 !

 

Lien vers le commentaire
Partager sur d’autres sites

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

Lien vers le commentaire
Partager sur d’autres sites

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 😉

Lien vers le commentaire
Partager sur d’autres sites

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?

Lien vers le commentaire
Partager sur d’autres sites

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 :

test.thumb.gif.f39bc8000fe6f2af7d5a4017e12396c3.gif

Lien vers le commentaire
Partager sur d’autres sites

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 :

test.thumb.gif.f39bc8000fe6f2af7d5a4017e12396c3.gif

 

 

Intéressant !

 

Je vais creuser ce sujet 🙂

Lien vers le commentaire
Partager sur d’autres sites

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

Lien vers le commentaire
Partager sur d’autres sites

@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?

Lien vers le commentaire
Partager sur d’autres sites

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 😉

Lien vers le commentaire
Partager sur d’autres sites

@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)

 

image.png.e6a4eae88f5d6cc0bd2c18195db56688.png

 

 

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).

 

 

 

Lien vers le commentaire
Partager sur d’autres sites

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

image.png.983e2e52165b8f30699b9630c7ee3c45.png

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)?

Lien vers le commentaire
Partager sur d’autres sites

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)

Lien vers le commentaire
Partager sur d’autres sites

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

Lien vers le commentaire
Partager sur d’autres sites

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

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é