Aller au contenu

Lisp de bordures


Vincent P.

Messages recommandés

Bien le bonjour nobles Lispeurs!

 

Je viens à vous en ce jour car je me confronte a un blocage.

Je ne suis pas un grand pacha d'AutoLisp, mais en venant ici, j'avais dans l'espoir que vous pourriez solutionner mon problème.

 

Je vous mets dans la situation.

Je travaille sur des plans de VRD, et souhaite dessiner des bordures le long de mes voiries.

En plan de support, j'ai un plan de revêtement dans lequel j'ai toutes mes surfaces de projet qui sont modélisées par des hachures (un type pour les voiries, un autre pour les trottoir, les espaces vert ....), chaque hachures est bordé d'une polyligne, et entre mes contours, j'ai un espace de 15-20cm prévu pour accueillir mes bordures.

 

Je souhaite donc me faciliter la vie avec un lisp qui me permettras de suivre mes polylignes de contour, et qui me créeras automatiquement une polyligne décalé et de la bonne épaisseur.

 

Voici mon premier jet :

;;;Créer une bordure
(defun c:Bordure (/ ep ent p1 p2)
 (initget 1 "0.15 0.20")
 (setq ep (getreal "\nSpécifiez l'épaisseur de la dordure : [0.15/0.20]"))
 (setq p1 (getpoint "\nSpécifiez le premier point à suivre : "))
 (command "_PLINE" p1 "la" ep ep )
 (command " ")
 (setq ent (entlast) 
p2 (getpoint "\nSpécifiez le coté où décaler : "))
 (command "_offset" (/ ep 2) ent p2 ; décaler la polyligne
   " ")
 (entdel ent) ; supprimer la 1er polyligne
 )

 

Sauf que ça ne prend pas.

 

Je dessin bien ma première polyligne (qui se superpose avec mes contours de hachures), elle est de la bonne épaisseur, mais pas de décalage.

 

Merci par avance pour votre aide et vos conseils.

Lispeur débutant!
Autocad Map3D 2023
Covadis-Autopist 18.0C

Lien vers le commentaire
Partager sur d’autres sites

  • 2 mois après...

Salut, j'aurai peut- être une réponse à ton sujet, en tripatouillant dans MLSTYLE tu peut créer un style de ligne multiple, dedans tu crée un style avec l'écart que tu souhaite, cela fais, tu coche dans les cases de gauche Ligne: départ et fin, normalement cela te créera une entité que tu pourra hachurée.

 

Par contre je ne sais pas comment y donner une épaisseur désolé voir peut être avec la largeur de ligne de ton calque ?

 

Je te prépare aussi un lisp que j'utilise pour faire des bordure je t'inviterai à l'ouvrir en lisp et à le regarder ;)

“L'environnement est important, pour sauver un arbre, mangez un castor !”

Lien vers le commentaire
Partager sur d’autres sites

(defun c:bora ( / REP DC)
       (setvar "OSMODE" 3) ;accrochage milieu et extremité
       (initget "A1 A2") ;choix des bordure
       (setq REP (getkword "\nType de bordure [A1/A2] <A1> : ")) ;type de bordure et A1 par defaut
       (if (not rep)
               (setq rep "A1") ;si ok ou défaut faire A1
       )
       (if (not (tblsearch "LAYER" "Bordure_A1_AVANT")) ;cherche ton calque 
               (command "_.layer" "_new" "Bordure_A1_AVANT" "") ;si il n'y est pas, le crée
       )
       (if (not (tblsearch "LAYER" "Bordure_A1_ARRIERE"))
               (command "_.layer" "_new" "Bordure_A1_ARRIERE" "")
       )
       (if (not (tblsearch "LAYER" "Bordure_A2_AVANT"))
               (command "_.layer" "_new" "Bordure_A2_AVANT" "")
       )
       (if (not (tblsearch "LAYER" "Bordure_A2_ARRIERE"))
               (command "_.layer" "_new" "Bordure_A2_ARRIERE" "")
       )
 
       (prin1 "\nCliquer le parcour de votre réseau <Taper (Return) pour FIN>")
       (command "_.pline" pause "_width" 0.02 0.02) ;largeur de base de la polyligne ici 0.02 0.02
       (while (not (zerop (getvar "CMDACTIVE")))
               (command pause)
       )
       (cond
               ((= REP "A1")(command "_.chprop" (entlast) "" "_layer" "Bordure_A1_AVANT" "") ;met la première polyligne dans un calque avant
                       (setq DC 0.2) ;distance de décallage
       (command "_.offset" DC (entlast) pause "")
       (command "_.chprop" (entlast) "" "_layer" "Bordure_A1_ARRIERE" "") ;celle décalée dans le calque derriere
       (prin1)

	 )
               ((= REP "A2")(command "_.chprop" (entlast) "" "_layer" "Bordure_A2_AVANT" "")
                       (setq DC 0.15)
       (command "_.offset" DC (entlast) pause "")
       (command "_.chprop" (entlast) "" "_layer" "Bordure_A2_ARRIERE" "")
       (prin1)

	 )
       )
 (setvar "PLINEWID" 0)

)

;pour les autres remplacer A1 par P1 A2 par P2 ajouter P3 en copiant collant une séquence et en le rajoutant à coté des précedent dans type de bordure iniget etc

“L'environnement est important, pour sauver un arbre, mangez un castor !”

Lien vers le commentaire
Partager sur d’autres sites

Bien le bonjour nobles Lispeurs!

 

Bien le bonjour également. Je ne suis pas noble et si d'aventure on me colle une particule à mon nom de famille, cela deviendrait particulièrement ridicule. Mais ce n'est pas la question.

 

Concernant ton problème de lisp, il serait intéressant d'exposer le but de la manœuvre à l'aide d'un croquis ou d'un fichier joint, ce serait beaucoup plus parlant. Quant au premier jet que tu nous soumets et qui a le mérite d'exister, je ne vois pas comment on peut arriver à dessiner une polyligne en ne donnant qu'un seul point

(command "_PLINE" p1 "la" ep ep )

et, conséquemment, cela m'étonnerait que (entlast) récupère bien l'entité voulue.

 

Les multilignes qui sont évoquées par Red ont certainement beaucoup d'atouts, mais aussi un problème de fond : on ne peut pas faire de segment courbe. A moins que les versions récentes n'aient changé la donne.

 

Amicalement

Vincent

C'est au pied du mur que l'on reconnaît le maçon ! (Anonyme)

C’est en restant au pied du mur qu’on ne voit que le mur (Anonyme aussi)

Lien vers le commentaire
Partager sur d’autres sites

Bonjour,

 

Alors j'ai un peu travaillé dessus (en m'inspirant de ce que je trouvais ce ci de là) et j'en suis sorti avec un lisp qui me plais plutôt bien :

 

;;; Créer une bordure
(DEFUN c:Bordure (/ ep ent osm)
 (setq osm (getvar "OSMODE")) ; Mémoriser l'accroche Objet
 (setvar "OSMODE" 0) ; désactiver l'accroche Objet
 (initget "T1 T2 T3 T4 T5 P1 G30")
 (setq
   Ep (cdr
 (assoc	(getkword
	  "\nType de bordure [T1/T2/T3/T4/T5/P1/G30] <T2> : "
	)
	'((nil . 0.15)
	  ("T1" . 0.12)
	  ("T2" . 0.15)
	  ("T3" . 0.17)
	  ("T4" . 0.20)
	  ("T5" . 0.24)
	  ("P1" . 0.08)
	  ("G30" . 0.30)
	 )
 )
      )
 )
 (command "_POLY2D" "G" pause pause "" "") ; créer une polyligne en suivant un contour
 (SETQ ent (entlast))		; Sélectionne la polyligne créée
 (COMMAND "_PEDIT" ent "_width" ep "")	; Modifie la largeur de la polyligne
 (COMMAND "_offset" (/ ep 2) ent pause "") ; copier-décaler la polyligne
 (ENTDEL ent)				; supprimer la 1er polyligne
 (setvar "OSMODE" osm) ; Rétablir l'accroche Objet
)

 

Donc tous marches bien, je peux faire des longueurs de bordures en suivant une polyligne.

Tout fonctionne bien si j'exécute entièrement la commande.

Mais, si j’interromps avant la fin (parce que j'ai sélectionné le mauvais contour à suivre, ou autre), mon accroche objet ne se rétabli pas. C'est normale puisque je le désactive en début de commande et que je le rétablie à la toute fin.

 

Ma question du moment est donc : Est-il possible de rétablir mon accroche objet (osmode) lorsque j’interromps la commande en cour?

Lispeur débutant!
Autocad Map3D 2023
Covadis-Autopist 18.0C

Lien vers le commentaire
Partager sur d’autres sites

Bonjour,

Ma question du moment est donc : Est-il possible de rétablir mon accroche objet (osmode) lorsque j’interromps la commande en cour?

 

par une gestion des erreurs.

 

Mais avant cela, on peut se demander pourquoi tu désactives l'accroche aux objets. A mon avis il n'y en a pas besoin, puisque tu ne calcules aucun point et il n'y a aucune commande qui place un point qui pourrait être sensible à un accrochage aux objets.

 

Au pire, je préfère mettre un "_non" avant le point à placer pour désactiver localement l'accrochage aux objets plutôt que de bricoler "OSMODE"

 

Amicalement

Vincent

C'est au pied du mur que l'on reconnaît le maçon ! (Anonyme)

C’est en restant au pied du mur qu’on ne voit que le mur (Anonyme aussi)

Lien vers le commentaire
Partager sur d’autres sites

par une gestion des erreurs.

 

qui pourrait ressembler à cela, pour répondre à la question, quand même !

(defun c:test ( / *error* oldos )
 
   (defun *error* ( msg )
     ;; ici on peut mettre tout ce qui permet de sortir proprement d'une fonction après erreur
     (princ (strcat "\nvaleur OSMODE active avant gestion erreur : " (itoa (getvar 'osmode))))
     (princ (strcat "\nvaleur OSMODE sauvegardée : " (itoa oldos)))
     (setvar 'osmode oldos)  ;; on remet osmode comme à l'origine malgré l'erreur
     (princ (strcat "\nErreur: " msg))
     (princ (strcat "\nvaleur OSMODE active après gestion erreur : " (itoa (getvar 'osmode))))
     (princ)
   )

   (setq oldos (getvar 'osmode))
   (setvar 'osmode 0)

   (rtos (getreal "\nEchap ou entrée pour provoquer une erreur ! "))

   (setvar 'osmode oldos)
   (princ)
)

 

à noter qu'ici *error* est local à la fonction test (donc à déclarer impérativement dans les variables locales de la fonction test) et n'écrase pas la définition de la fonction *error* standard. Cela me semble être la façon de faire la plus orthodoxe. Bien sûr, il y a sans doute d'autres avis qui ne manqueront pas de s'exprimer.

 

Amicalement

Vincent

C'est au pied du mur que l'on reconnaît le maçon ! (Anonyme)

C’est en restant au pied du mur qu’on ne voit que le mur (Anonyme aussi)

Lien vers le commentaire
Partager sur d’autres sites

  • 2 mois après...

Salut!

 

Déjà, merci zebulon_ pour ton aide!

 

Je souhaitais désactiver l'accroche objet car ca me perturbe lorsque j'utilise la commande :wacko:

 

Du coup, mon code ressemble désormais à ça :

DEFUN c:Bordure (/ ep ent osm )
 (initget "Autre T1 T2 T3 T4 T5 P1 G30")
 (setq
   ep (cdr
 (assoc	(getkword
	  "\nType de bordure [Autre/T1/T2/T3/T4/T5/P1/G30] <T2> : "
	)
	'((nil . 0.15)
	  ("T1" . 0.12)
	  ("T2" . 0.15)
	  ("T3" . 0.17)
	  ("T4" . 0.20)
	  ("T5" . 0.24)
	  ("P1" . 0.08)
	  ("G30" . 0.30)
	  ("Autre" . nil)
	 )
 )
      )
 )
 (If (= ep nil)
   (setq ep (getreal "\nLargeur de la Bordure? : "))
   (princ ep))
 (command "_POLY2D" "G" "_non" pause "_non" pause "" "") ; Créer une polyligne en suivant un contour
 (SETQ ent (entlast))		; Selectionne la polyligne créée
 (COMMAND "_PEDIT" ent "_width" ep "")	; Modifie la largeur de la polyligne
 (COMMAND "_offset" (/ ep 2) ent pause "") ; Copier-décaler la polyligne
 (ENTDEL ent)				; Supprimer la 1er polyligne
)

 

Bien!

 

Ma prochaine problématique :

temps que je dessine de la bordure T2, tous vas bien, mais si je me met à dessiner autre chose (par exemple de la P1), à chaque lancement de la commande je doit lui repréciser le type de bordure.

 

Mon idée est donc de mémoriser la dernière entrée et ne plus imposer <T2> par défaut.

Autrement dit, je souhaite retrouver le fonctionnement de commandes comme par exemple Décaler (offset) qui mémorise la dernière valeur de décalage et la propose par défaut lors de la prochaine utilisation.

 

En cherchant, je suis tombé sur les variable environnementales (getenv setenv), et je voudrais savoir si elle sont une solution à ma question. Et si oui, y a t'il une méthode plus simple? (je me complique peut-être la vie)

Lispeur débutant!
Autocad Map3D 2023
Covadis-Autopist 18.0C

Lien vers le commentaire
Partager sur d’autres sites

Salut

Peut-être que...

Tu te crées un "Précédent" dans ton getkword.

Lors de ton choix du type de bordure, tu attribues ta valeur "ep" à une variable que "Précédent" ira chercher.

exple : (setq valeur_precedent ep)

et

("Précédent" . ep)

avec valeur_precedent que tu ne déclares pas en variables locale, sinon lorsque tu relancera ton lisp tu n'auras plus la valeur.

 

Le premier choix lors de ton lancement de programme donnera une valeur à "ep", exple "0.12", et ensuite "Précédent" ira chercher directement ep.

 

C'est un peu comme le fonctionnement de certaines commandes. Enfin, je ferais ça comme ça...

Lien vers le commentaire
Partager sur d’autres sites

Ma prochaine problématique :

temps que je dessine de la bordure T2, tous vas bien, mais si je me met à dessiner autre chose (par exemple de la P1), à chaque lancement de la commande je doit lui repréciser le type de bordure.

 

Mon idée est donc de mémoriser la dernière entrée et ne plus imposer <T2> par défaut.

Autrement dit, je souhaite retrouver le fonctionnement de commandes comme par exemple Décaler (offset) qui mémorise la dernière valeur de décalage et la propose par défaut lors de la prochaine utilisation.

 

En cherchant, je suis tombé sur les variable environnementales (getenv setenv), et je voudrais savoir si elle sont une solution à ma question. Et si oui, y a t'il une méthode plus simple? (je me complique peut-être la vie)

 

Il faudrait garder le résultat du getkword. Le plus simple, c'est d'utiliser une variable générale (donc non déclarée dans le (/ ...) du defun). Cette variable, dont on essaiera de choisir un nom suffisament spécifique pour ne pas risquer qu'il soit utilisé par un autre lisp, conservera sa valeur tant que le fichier est ouvert. Au début du lisp, on vérifie si cette variable est nil. Si oui, on définit une valeur par défaut, sinon on prend la valeur qu'elle contient.

On peut aussi enregistrer des données dans le fichier dwg, pour retrouver la valeur d'une variable même après fermeture/ouverture d'une fichier, avec les vlax-ldata-put et vlax-ldata-get.

 

Amicalement

Vincent

C'est au pied du mur que l'on reconnaît le maçon ! (Anonyme)

C’est en restant au pied du mur qu’on ne voit que le mur (Anonyme aussi)

Lien vers le commentaire
Partager sur d’autres sites

  • 1 mois après...

Bonjour,

 

J'ai laissé de coté mon lisp de bordure, car d'autres projet, et m'y suis remis cette semaine.

 

J'ai donc un peut remanié, et appliqué ton conseil, et voila :

(DEFUN c:Bordure (/ ep ent)
 (if (= oldbord nil)
   (setq oldbord 0.15)
   (princ oldbord))
 (setq ep (getdist (strcat "\nLargeur de la Bordure? <" (rtos oldbord) ">: ")))
 (If (= ep nil)
   (setq ep oldbord)
   (princ ep))
 (setq oldbord ep)
 (princ ep)
 (command "_POLY2D" "G" "_non" pause "_non" pause "" "") ; Créer une polyligne en suivant un contour
 (SETQ ent (entlast))		; Selectionne la polyligne créée
 (COMMAND "_PEDIT" ent "_width" ep "")	; Modifie la largeur de la polyligne
 (COMMAND "_offset" (/ ep 2) ent pause "") ; Copier-décaler la polyligne
 (ENTDEL ent)				; Supprimer la 1er polyligne
)

 

J'utilise donc une nouvelle variable nommée oldbord qui n'est pas déclarée, et donc garderas sa valeur après fermeture du programme. Ainsi, au lancement suivant, je peut retrouver sa valeur. La valeur se réinitialise que lorsque je ferme mon DWG.

J'ai aussi retiré quelque fioriture (comme la sélection manuelle du type de bordure) pour me concentré sur l’essentielle!

 

Merci zebulon_ pour ta précieuse aide.

Lispeur débutant!
Autocad Map3D 2023
Covadis-Autopist 18.0C

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é