Aller au contenu

[RESOLU] Numérotation automatique des sommets d'une polyligne


Hydro8

Messages recommandés

Bonjour à tous,

Je me demandais s'il était possible en lisp de numéroter "automatiquement" les sommets d'une polyligne, sauf quand il existe déjà un point à ce sommet ?

J'ai des dossiers avec pas mal de polyligne qui se touchent et je dois numéroter chaque sommet. Pour le moment, j'ai un lisp qui insère un block avec une numérotation automatique.

L'idée serait de sélectionner toutes les polylignes et qu'il insère un numéro incrémenté automatiquement, sauf quand un sommet a déjà été inséré pour une polyligne précédente.

J'en demande surement trop :rolleyes: Surtout pour récupérer l'information comme quoi il existe déjà un point.

Je mets un exemple du résultat actuel.

Merci pour vos informations.

Points.dwg

Lien vers le commentaire
Partager sur d’autres sites

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.

  • Like 1

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

Bonjour,

j'avais travaillé sur un sujet comme cela et je passais à chaque sommet un test d'existence de point par proximité, je ne sais pas comment référencer une discussion dans une autre, si tu cherches mes messages, tu trouveras une routine de test qui devrait te convenir.

  • Like 1

Geometre - Autocad 2016 - Covadis v17.0

Lien vers le commentaire
Partager sur d’autres sites

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

 

  • Like 1

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

1 hour ago, jujugeometre said:

Bonjour,

j'avais travaillé sur un sujet comme cela et je passais à chaque sommet un test d'existence de point par proximité, je ne sais pas comment référencer une discussion dans une autre, si tu cherches mes messages, tu trouveras une routine de test qui devrait te convenir.

Bonjour, très intéressant il faut que je regarde comment ca fonctionne !

1 hour ago, (gile) said:

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.

 

Bonjour et merci pour ce lisp que je pourrais tester demain :)

Pour répondre au premier post, j'imagine la logique suivante :

- indiquer le numéro de point de depart.

- sélectionner les polylignes.

- les sommets sont numérotés par ordre de création de la polyligne et par ordre de création du sommet.

Concernant les points intermédiaires, peut-être que cela serait plus simple de dire aux utilisateurs de créer des sommets pour chaque points qu'ils veulent numéroter. 

merci encore.

Lien vers le commentaire
Partager sur d’autres sites

1 hour ago, Hydro8 said:

- indiquer le numéro de point de depart.

- sélectionner les polylignes.

- les sommets sont numérotés par ordre de création de la polyligne et par ordre de création du sommet.

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

 

  • Like 1

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

Bonjour (gile),

Je viens d'essayer ton code et il fonctionne parfaitement ! Super un grand merci !

Est-il possible d'aller chercher le bloc "dv-point" s'il n'est pas présent dans le dessin ? C'est un bloc dans les fichiers support d'autocad.

Encore merci.

Lien vers le commentaire
Partager sur d’autres sites

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

 

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

Bonjour

J'ai testé ton lisp, elle fonctionne super bien ! Un grand merci !

Petite question, parfois lorsque je copie les contours et les points dans un autre dessin, il me remet des points où il y en a déjà. Comment regarde-t-il si il existe déjà un point pour ce sommet ?

Lien vers le commentaire
Partager sur d’autres sites

Ok il faut que je vois comme avait fait @jujugeometreje suppose, avec une distance par rapport au sommet.

C'est vrai que c'est quelque chose que je n'ai pas expliqué dans mon post initial.

Une fois que j'ai fais mes contours sur un plan n°1, je copie ces contours et les points sur un plan n°2.

Sur le plan n°2 je peux être amené à modifier certains contours, et je dois mettre des nouveaux points uniquement sur ces nouveaux sommets.

Lien vers le commentaire
Partager sur d’autres sites

Ça devrait le faire comme ça :

(defun c:toto (/ massoc mkBlock mkInsert leftPad getDVpoints 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
  )

  (defun getDVpoints (/ s i l)
    (if	(setq s	(ssget "_X"
		       (list (cons 0 "INSERT")
			     (cons 2 "DV-point")
			     (cons 410 (getvar 'ctab))
		       )
		)
	)
      (repeat (setq i (sslength s))
	(setq
	  l (cons (cdr (assoc 10 (entget (ssname s (setq i (1- i))))))
		  l
	    )
	)
      )
    )
  )
  
  (if
    (and
      (setq ss (ssget '((0 . "LWPOLYLINE") (-4 . "&") (70 . 1))))
      (setq n (getint "\nPremier numéro: "))
    )
     (progn
       (if (null (tblsearch "block" "DV-point"))
	 (mkBlock)
	 (setq pts (getDVpoints))
       )
       (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) (< (distance p x) 1e-8)) pts))
	     (setq pts (cons p pts)
		   n   (mkInsert p n)
	     )
	   )
	 )
       )
     )
  )
  (princ)
)

 

  • Like 1

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

  • 1 mois après...

Bonjour Bonjour,

 

Pour les utilisateurs de Covadis, la commande "_CovaImmatric" (Covadis 2D/Point Topographiques/Immatriculation d'entités) répond à la demande de base.

 

Amicalement!

VincentP.

 

Lispeur éternel débutant!
Autocad Map3D 2023
Covadis-Autopist 18.2

Lien vers le commentaire
Partager sur d’autres sites

Le 14/06/2021 à 14:53, Vincent P. a dit :

Bonjour Bonjour,

 

Pour les utilisateurs de Covadis, la commande "_CovaImmatric" (Covadis 2D/Point Topographiques/Immatriculation d'entités) répond à la demande de base.

 

Amicalement!

VincentP.

 

Bonjour

Merci pour l'astuce mais je n'ai malheureusement pas covadis.

 

Le 02/05/2021 à 08:39, (gile) a dit :

Ça devrait le faire comme ça :

 

(gile) quand je réalise la fonction sur une première polyligne cela fonctionne. Je copie ensuite les points sur un ensemble de polylignes et relance la fonction.

J'obtiens des points en double au même endroit. Je te joints un dwg avec le résultat brut.

Merci pour ton aide.

Dessin2.dwg

Lien vers le commentaire
Partager sur d’autres sites

il y a une heure, Hydro8 a dit :

gile) quand je réalise la fonction sur une première polyligne cela fonctionne. Je copie ensuite les points sur un ensemble de polylignes et relance la fonction.

J'obtiens des points en double au même endroit. Je te joints un dwg avec le résultat brut.

Merci pour ton aide.

Même question posée le 2 mai, même réponse.

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

  • 2 ans après...

Bonjour, voila quelques jours que je cherche créer des points 3D sur tous les sommets de mes polylignes 3D via autocad j'en ai des centaines sur plusieurs kilomètres.
Puisque chaque polylignes 3D à chacun de ses sommets connus en XYZ , je suis persuadé qu'il existe une possibilité via lisp pour récupérer la donnée.

J'ai essayé votre lisp sans succès, même une simple numérotation ne fonctionne pas...

J'ai essayé de créer mon lisp via la documentation que vous avez mis en ligne @(gile)  (merci infiniment d'ailleurs ) mais la encore, pas le moindre résultat...

 

 

Lien vers le commentaire
Partager sur d’autres sites

Bonjour @Lucas

Un petit truc simple en considérant que le bloc tcpoint existe dans le dessin, car les gens qui demandent ce genre de truc ont Covadis donc le tcpoint.
Si tu ne l'as pas, c'est un bloc point avec deux attributs, num et Z.

Le nom de la commande à lancer est Lucas01.

Amicalement

(defun c:Lucas01  (/ ent entlst lst num)
    (setq ent (car (entsel "\nChoix de la poly 3D à immatriculer ...\n")))
    (while (and
               (setq ent (entnext ent))
               (/= "SEQEND" (cdr (assoc 0 (setq entlst (entget ent)))))
               )
        (setq lst (cons (cdr (assoc 10 entlst)) lst))
        )
    (setq lst (reverse lst))
    (setq num 1)
    (foreach item  lst
        (command "_insert"
                 "tcpoint"
                 item ;        (nth 0 lst)
                 "1"
                 "1"
                 "1"
                 (itoa num)
                 (rtos (caddr item))
                 2
                 3)
        (setq num (1+ num))
        )
    )
;|«Visual LISP© Format Options»
(150 4 10 0 nil "Fin de " 80 10 0 0 0 nil T nil T)
;*** NE PAS AJOUTER de texte au-dessous du commentaire! ***|;

 

Lien vers le commentaire
Partager sur d’autres sites

il y a 55 minutes, didier a dit :

Bonjour @Lucas

Un petit truc simple en considérant que le bloc tcpoint existe dans le dessin, car les gens qui demandent ce genre de truc ont Covadis donc le tcpoint.
Si tu ne l'as pas, c'est un bloc point avec deux attributs, num et Z.

Le nom de la commande à lancer est Lucas01.

Amicalement

Bonjour @didier et merci !
Avec ta formule je suis a 60% de mon objectif:
-Créer des points 3D ou 2D sur des milliers de sommets de polylignes 3D différentes d'un seul coup, afin de créer un seul CSV.

J'avais covadis, mais désormais je ne l'aurais plus, et autocad parait bien inutile sans covadis !
Me voila donc sur ce forum, et ton site, ou je tente de bidouiller sans avoir le temps de comprendre comment tout ca se rédige.

J'ai l'impression qu'on ne peut pas sélectionner plusieurs polylignes3D en même temps pour ne déclencher qu'une seule action de création de points ?
J'ai pu retrouver un TCPOINT, mais il me faut renseigner manuellement les infos (MAT,ALT,COD) DANS mon Bloc:TCPOINT (affreusement long). Je vais essayer de les supprimer complètement, les coordonnées XYZ (d'insertion) du bloc me suffiront largement.
 

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é