Aller au contenu

Messages recommandés

Posté(e)

bonjour,

 

J'essai de me faire une routine me permetant de decaler une polyligne puis d'ajuster les polyligne se trouvant entre les deux premieres

 

voila

 

(defun C:083 (/)

 

(command (getcname "decaler") "0.83")

 

 

(command (getcname "ajuster") "")

(princ)

 

:P on ne rigole pas....

 

je pense que je suis mal partis

 

merci de me conseiller

Posté(e)

Salut

C'est bien de vouloir se lancer dans le lisp. Tous mes encouragements :thumbup:

Je vais juste apporter quelques précisions

Vouloir internationaliser ses commandes part d'un très bon principe mais un (command (getcname "decaler") "0.83") ne peut fonctionner que sur Autocad français. Une version anglaise ne connait pas "decaler" :casstet:

Donc un (getcname "decaler") me retourne "_offset", je fais donc un (command "_offset" "0.83").

Ca ne fonctionne pas ! :o

Voyons ce que j'ai raté. La sélection d'un objet bien sure :D

Donc en premier, je choisis une ligne --> (setq ent (entsel))

Je regarde la valeur qui m'est retournée et je trouve (< Nom d'entité: 7bb79110 > (46.4175 -50.7276 0.0))

Ce qui m'intéresse dans cette liste est la première valeur, donc un (setq ent (car (entsel))) devrait suffire ?

J'essai et oui, ça fonctionne, je trouve mon entité :cool:

C'est bien, mais si je clique à coté, ma sélection est vide !!!

Donc je fais un (if (setq ent (car (entsel)))

(progn

(command "_offset" "0.83" ent)

) ; fin progn

) ; fin if

Grrrr, ça plante encore :mad:

Ah oui, j'ai oublié de préciser de quel coté décaler mon entité !

donc

(if (setq ent (car (entsel)))

(progn

(command "_offset" "0.83" ent pause)

) ; fin progn

) ; fin if

Tiens je continue sur ma commande décaler ??? :exclam:

Normal, je n'ai pas fait entrée à la fin

Donc

 

(if (setq ent (car (entsel)))

(progn

(command "_offset" "0.83" ent pause "")

) ; fin progn

) ; fin if

Ouf, ça marche :cool:

Je te laisse faire la suite ;)

 

@+

Les Lisps de Patrick

Le but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.

Joseph Joubert, 1754-1824

Posté(e)

c'est vraiment une maniere de penser particuliere le lisp

 

sa "m'exite"

 

donc si je fais

(command "_trim" ent entlast)

 

cela devrait marché?

 

mais il manque la suite

comment dire toute les polyligne qui se trouve entre les deux?

Posté(e)
c'est vraiment une maniere de penser particuliere le lisp

Non, c'est de la logique et juste un langage de programmation

 

donc si je fais

(command "_trim" ent entlast)

cela devrait marché?

Non, (entlast) est une fonction, il manque deux parenthèses et de plus, un décaler veux dire que c'est des parallèles

 

mais il manque la suite

comment dire toute les polyligne qui se trouve entre les deux?

On complique les choses ;)

par un ssget fenêtre ou capture, cela dépend du besoin et en utilisant les extémités des poly comme points de cordonnées de la fenêtre/capture

 

@+

Les Lisps de Patrick

Le but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.

Joseph Joubert, 1754-1824

Posté(e)

(setq resultat(vlax-invoke-method (vlax-ename->vla-object(car(entsel))) "Offset" (- 30)))

 

renvoie une liste des objets créés par la commande (en Variant, pour quand tu seras plus grand en lisp).

 

Mais ce qui est intéressant dans cette façon de faire c'est que tu peux aussi "contrôler" le côté du décalage vers un objet plus petit ou plus grand (quand AutoCAD peut trouver des valeurs différentes). Donc pratique dans le cas de rectangles fermés, par exemple.

 

Il suffit d'invoquer "Offset", sans "_"( contrairement à l'usage de COMMAND, réservé aux débutants et à certaines fonctions, très similaire aux scripts).

 

Ainsi

(vlax-invoke-method (vlax-ename->vla-object ent) "Offset" (- 30)))
et
(vlax-invoke-method (vlax-ename->vla-object ent) "Offset" (+ 30)))

sont complémentaires car il permettent de décaler des 2 côtés sans spécifier de point.

Peut-être peux-tu t'aider de celà, sinon, avec COMMAND, c'est la même PROBLEMATIQUE que le SCRIPT.

Bureau d'études dessin.

Spécialiste Escaliers

Développement - Formation

 

./__\.
(.°=°.)
Posté(e)

Salut,

 

Je m'immisce dans la leçon.

 

Pour faire un jeu de sélection, on utilise la fonction ssget.

 

Cette fonction comporte beaucoup d'options, donc de possibilités pour faire la sélection et pour filtrer le type d'entités sélectionnées.

Dans ton cas, par exemple si tu veux sélectionner toute le polylignes (on va dire les poly optimisées seulement) strictement entre les deux poly.

 

Tu vas choisir l'option de sélection WP (window polygon), ça sera le premier argument pour la fonction ssget, qui sélectionne toutes les entités entièrement à l'intérieur du polygone défini par une liste de points.

 

La difficulté va être de constituer la liste de points (ça sera le second argument pour la fonction ssget) à partir des sommets des deux polylignes (ent et decal_ent on suppose que tu as fait un :

(setq decal_ent (entlast)) 

après le décalage pour stocker le nom d'entité -ename- de la poly créée dans la variable decal_ent).

 

La formule magique pour récupérer es sommets d'une lwpolyligne est :

(mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget lwpolyline)))

Elle est expliquée en détail ici

 

dans notre cas on sait maintenant faire la liste des sommets de chacune des polylignes mais pour "dessiner" notre polygone de sélection il ne faut qu'une liste et inverser l'ordre des sommets pour un des deux polyligne. La fonction append "assemble plusieurs liste en une seule et la fonction reverse inverse l'ordre des éléments d'une liste.

 

Pour constituer la liste des sommets du polygone on peut donc écrire :

(setq pt_lst
(append
(mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget ent)))
(reverse (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget decal_ent))))
)
)

 

Tu vas aussi filtrer les lwpolylines pour ne sélectionner que ce type d'entité.

C'est le troisième argument pour la fonction ssget. Ce doit être une liste dont les éléments sont aussi des liste (ou paires pointées) telle que ceux constituant les listes retournées par la fonction entget. chaque élément contient un "code de groupe dxf" et sa valeur. Ici :

 

(list '(0 . "LWPOLYLINE"))

 

pour ne sélectionner que les entités "polyligne".

 

On peut maintenant faire notre jeu de sélection :

 

(setq jeu_sel (ssget "_WP" pt_lst (list '(0 . "LWPOLYLINE"))))

 

Voilà, je pense que tu as de quoi cogiter ;)

 

 

N'hésite pas à consulter l'aide : si tu travailles avec l'éditeur VisualLISP, ce que je te recommande fortement il suffit de sélectionner une fonction -double-clic sur le nom de la fonction- puis de cliquer sur l'icône avec un point d'interrogation.

Tu peux aussi voir les fonctions décrites en français ici.

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

Posté(e)

Re,

 

J'ai oublié une chose, l'exemple précédent vaut si les polylignes qui servent à faire le polygone sont "ouvertes".

 

Si les polylignes sont fermées, il faudra utiliser une autre méthode de sélection.

Sélectionner toutes les polylignes strictement à l'intérieur de la poly la plus à l'extérieur (option WindowPolygon de ssget) et oter de ce jeu de sélection toutes les polylignes qui croisent la poly le plus à l'intérieur (option CrossingPolygon de ssget)

 

Il faut donc faire 2 jeux de sélection (on suppose que ent à été décalée vers l'intérieur, decal_ent est à l'intérieur de ent)

 

(setq ss1 (ssget "_WP"
	 (mapcar 'cdr
		 (vl-remove-if-not
		   '(lambda (x) (= (car x) 10))
		   (entget ent)
		 )
	 )
                (list '(0 . "LWPOLYLINE"))
  )
)
(setq ss2 (ssget "_CP"
	 (mapcar 'cdr
		 (vl-remove-if-not
		   '(lambda (x) (= (car x) 10))
		   (entget decal_ent)
		 )
	 )
                (list '(0 . "LWPOLYLINE"))
  )
)

 

Et oter de ss1 les entités contenues dans ss2, pour ce faire on parcours ss1 et on teste, pour chaque entité, si elle est présente dans ss2, si c'est le cas, on la supprime de ss1 :

 

(setq n (sslength ss1)) ; nombre d'entités dans ss1
(repeat	n ; Répète autant de fois
 (setq n (1- n)) ; Incrémentation de n pour l'index dans le jeu de sélection
 (setq e (ssname ss1 n)) ; Entité à l'index n dans ss1 (première entité : index 0)
 (if (ssmemb e ss2) ; Si e est membre de ss2 ...
   (ssdel e ss1) ; ... e est supprimé de ss1
 )
) 

 

 

Donc, avant tout, il faut interroger les propriétés de ent (ou decal_ent, c'est pareil) pour savoir si elle est ouverte ou fermée. On trouve ça dans la "liste entget" de l'entité (voir dans l'aide aux développeurs >> Référence DXF >> Section ENTITIES).

 

Elle est dans le code de groupe dxf 70, la valeur est un code binaire, c'est la somme de plusieurs entiers qui sont des puissances de 2 (1 2 4 8 16 ...).

Les fonction LISP boole, logang et logior permettent de tester la présence dans un entier quelconque d'un ou de plusieurs bits.

 

L'expression : (logand 1 (cdr (assoc 70 (entget ent)))) retourne 1 si 1 est présent dans la valeur du code 70 de la liste entget de ent ou 0 sinon.

 

On peut donc faire un test pour savoir si la polyligne (et celle créée par le décalage) est fermée ou non pour appliquer l'une ou l'autre méthode.

 

(if (= (logand 1 (cdr (assoc 70 (entget ent)))) 1)
(progn 
;; Appliquer la deuxième méthode
)
(progn
;; Appliquer la première méthode
)
) 

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

Posté(e)

Et on pourrait fixer la barre encore plus haut ! :exclam:

 

En effet je penses que, comme certains, on a tous voulu créer ce genre de fonction pour l'ajustement automatique.

 

On commmence par un truc tout simple, et au fur et à mesure, on voit les limites du code qu'on a créé et on essaye de modifier en conséquence (j'tdis pas l'histoire sans fin! ) ;)

 

Ici le plus gros "Hic" c'est quand on veut que cela soit valable avec les arcs.

Le code proposé fonctionnera dans ce cas ci avec les cordes des arcs, donc dans des cas complexes certain objets vont mal réagir, ou pas comme on veut.

 

On est alors confronté à la résolution de défintion des arcs. Certain on résonné avec les longueurs fixe d'arc pour créer les points suffisant pour créer la sélection. Pour ma part je pense qu'il vaut mieux le faire soit, par une division fixe de la longueur de l'arc concerné, ou par balayage angulaire, ceci pour avoir toujours le même nombre de points quelque soit la grandeur utilisé pour l'arc ou l'unité utilisé. (la définition de la partie fixe, ou d'ouverture d'angle fixera la présicion de la routine et sa fiabilité ET sa rapidité.)

 

A une époque "Miamar" avait voulu éplucher la fonction extrim des express tools par un sujet ou j'avais essayer de l'aider. On constate aussi que Extrim est confronté à ce problème de résolution des arc.

 

 

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Posté(e)

merci a vous tous pour cette leçon de lisp

 

c'est vrai que j'ai du bouleau sur la planche

 

mais pour l'instant je vais oublier les fonction VLA

pour me concentrer sur la manipulation des jeux de selections

qui déja est un gros morceau

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é