Aller au contenu

Messages recommandés

Posté(e)

Bonjour,

 

Cela fait quelques temps que je consultes les forum cadxp et que grâce à ses membres j'ai pus créer quelques routines utiles à mon travail.

Je suis débutant en LISP et VLISP et bien que je réussisse quelques routines j'admet assez rapidement mes limites, mais grâce à ce forum elle sont chaque jour repoussés.

 

Cependant que sèche sur un soucis qui m'apparais dans l'une de mes routines de vérification de blocs.

 

En effet je cherche à trouver toutes les polylignes qui sont présentes sous une insertion de bloc.

 

Pour cela je récupère mon point d'insertion via :

(setq pt(cdr (assoc 10(entget(car(entsel))))))

 

puis je fait un ssget pour trouver les entités polylignes qui sont en dessous du point:

(setq ss (ssget "_C" pt pt (list '(0 . "LWPOLYLINE"))))

 

Mon soucis est que si celle polyligne dispose d'un type de ligne discontinue et que malheureusement cette discontinuité est présente à l'endroit ou le bloc se trouve, la fonction ne me renvoie rien (nil).

 

Avez vous une solution qui serais peu consommatrice en ressources pour résoudre ce souci.

 

Le reste de ma routine fonctionne parfaitement, pour dire vrais j'ai déjà une solution qui consiste à appliquer une vérification de toutes les polylignes du plan (filtré par calques) à chaque bloc testé, mais c'est très lourd en ressources si j'ai beaucoup de bloc et beaucoup de polylignes.

 

Merci d'avance pour vôtre aide.

C'est en forgeant que l'on devient forgerons.

Et c'est en sciant que Léonard DeVinci!

Posté(e)

Salut

 

Tu parles de sélectionner ce qui est sous le bloc mais je vois que tu utilises le point d'insertion du bloc, c'est différent car le point de base peut se trouver à Pétaouchnok du bloc.

 

Si tu pouvais préciser.

 

@+

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)

Bonjour,

 

Outre la réponse de Patrick_35 sur la définition du point d'insertion du bloc, il est vrai que les modes de sélection avec ssget autre qu'avec l'option "X" (pour tout) peut poser des problèmes suivant si les points de sélection sont hors écran, ou hors des limites de régénération actuel du dessin.

Tu poses aussi le problème des type de ligne discontinu employé qui peuvent aussi être un frein pour la sélection.

 

Donc pour ces modes de sélection avec points définis, il faut s'assurer en premier lieu que ces points soit dans l'espace graphique nécessaire, (en raccourci, je dirais aucune régénération de celui soit nécessaire pour afficher l'espace à exploiter).

Pour les type de ligne, c'est plus délicat. Comme tu utilises le mode "Capture" ("_Crossing"), tu pourrais calculer des points de façon à faire une fenêtre élargie et non une capture sur un point unique comme tu l'as fait. Ou encore plus simplement tu pourrais faire ta sélection sur ton point point unique pt; ssget sans aucune option de sélection, juste fournir les coordonnée de ton point de sélection ex: (ssget pt '((0 . "LWPOLYLINE"))), mais en réglant la variable "PICKBOX" (valeur de 0 à 50) à une valeur élevée. Plus la valeur sera grande, plus les chances de sélectionner les type de ligne discontinu seront élevé aussi, (au risque de sélectionner aussi d'autre objets proches, à moins de faire un filtre plus sélectif : calque, type de ligne, couleur...).

 

Voilà pour les piste que tu peux explorer.

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

Posté(e)

Pour le point, ce n'est pas un soucis, prenons le même exemple avec un cercle si il le faut!

Dans mon cas, je m'assure que le point d'insertion du bloc est bien sur la polyligne (passage de SCO en SCG si necessaire).

 

Merci pour le ssget sans option, de base (avec mon peu d'expérience de la chose) j'avais bêtement pensé que l'option était impérative.

 

Je vais effectivement explorer la piste de la sélection proche qui filtrera les polylignes alentours, mais le risque d'erreur en fonction de l'echelle de type de ligne me géne un peu.

 

Je me demandais si 'il n'y avais pas (peu être en Vlisp) une prise en charge de la polyligne compléte même si son type de ligne est dicontinu?

 

Merci pour cette aide.

C'est en forgeant que l'on devient forgerons.

Et c'est en sciant que Léonard DeVinci!

Posté(e)

Bonjour,

 

C’est non testé mais cela devrait fonctionner une fois que tu auras fait ta sélection proche ou par tout autre type de moyen sur tes polylignes, parcours ta sélection en la soumettant à la fonction vlax-curve-getDistAtPoint

 

Pour rappel la fonction Retourne la longueur du segment de la courbe entre le point de départ de la courbe et le point spécifié.

 

Dans ton cas le nom de ta polyligne et le point d’insertion de ton bloc, si la valeur de retour est nil, ta polyligne ne passe pas sous le point d’insertion de ton bloc.

 

A+

Apprendre => Prendre => Rendre

Posté(e)

Merci de ta réponse.

 

Mon soucis c'est qu'avec cette méthode j'en reviens encore à tester toutes les polylignes (proche ou non suivant le filtre) pour chaque point que je veu tester!

 

Je partais plus dans l'idée d'intéroger uniquement les objets qui se trouvent sous le point en question, histoire de limiter fortement les intérogations d'objets.

C'est en forgeant que l'on devient forgerons.

Et c'est en sciant que Léonard DeVinci!

Posté(e)
Je me demandais si 'il n'y avais pas (peu être en Vlisp) une prise en charge de la polyligne compléte même si son type de ligne est dicontinu?

 

Et non...

D'ailleurs même manuellement, tu remarquera qu'il est impossible de faire une sélection (pour effacement par exemple) en cliquant dans la discontinuité de la ligne.

 

Par programmation, le seul moyen fiable (à mon avis) pour que la sélection réussisse est de faire une sélection globale de tes polylignes (ssget "_X" '((0 . "LWPOLYLINE"))), de traiter cette sélection pour lui affecter le style de ligne continu, en sauvegardant pour chaque entité de la sélection son type de ligne original. D'appliquer alors ta routine et en fin de celle-ci restorer les type de ligne de départ.

Cela va compliquer beaucoup le code mais cela sera fiable.

 

Dans un premier temps essayes quand même d'augmenter la variable "PICKBOX" dans ton programme avant de faire la sélection, autant bien cela peu suffire à résoudre ton problème.

Si tu trouve la valeur pour PICKBOX qui te convient, assure toi d'avoir le même facteur de zoom sur ton dessin pendant l'éxecution car cela va influencer sur la zone de recherche de Pickbox. Avec cette variable cela restera quand même aléatoire pour la réussite de la sélection.

 

AutoDesk aurait du faire une variable similaire à QTEXTMODE pour les type de ligne afin de d'établir un affichage de travail et un affichage de rendu. Peut être sont-ils à l'écoute?

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

Posté(e)

Bonsoir alala,

 

Tout d’abord je te souhaite la bienvenu sur ce forum, je profite d’être à mon domicile pour développer un peu plus ma réponse précédente, en apportant quelques précision à ce qui a été dit, notamment sur le mode de sélection...

Car j’ai cru comprendre que tu recherchais à sélectionner toutes les polylignes qui sont présentes sous un point de sélection (ou plutôt point d’ insertion de bloc).

 

 

La sélection par capture comme tu nous la proposé me semble plus adapté

(setq ss (ssget "_C" pt pt (list '(0 . "LWPOLYLINE"))))

Que la sélection par point bien que cette dernière bénéficie de l'apport de la variable "PICKBOX"

(ssget pt '((0 . "LWPOLYLINE")))

Car chez moi cela ne sélectionne qu’un élément même si il y a plusieurs entités sous le point.

 

 

Maintenant la sélection par capture sur un point, ne permet pas de sélectionner une ligne si il y a discontinuité au point de capture, c’est pour cela que le conseil de Bonuscad d’élargir la zone de capture autour du point et une possibilité d’optimisation, au risque bien sur de sélectionner plus d’entité que nécessaire. C’est pour cela que tu es obligé si tu veux un code fiable de parcourir ta sélection pour éliminer les entités non valide.

 

 

Pour résumer je te propose une fonction qui devrait répondre à ton besoin basé sur ma proposition précédente avec l’emploie de vlax-curve-getDistAtPoint :

;; Sélection par point des polylignes optimisées..
;; Argument: un point de sélection 3D
;; Retourne: un jeu de sélection
(defun SeLwPt (pt / i e ss)
 (repeat (setq i (sslength (setq ss (ssget "_X" '((0 . "LWPOLYLINE"))))))
   (if	(vlax-curve-getDistAtPoint
  (vlax-ename->vla-object (setq e (ssname ss (setq i (1- i)))))
  pt
)
     ss
     (ssdel e ss)
   )
 )
)

 

 

Pour tester copie/colle ce qui suit dans ta console Vlisp

(sssetfirst nil (SeLwPt (cdr (assoc 10 (entget(car(entsel)))))))

 

 

Ps : Tu remarqueras que j’ai fait une sélection globale, si tu le souhaite tu peux toujours en fonction de ton environnement de travail affiner la sélection.

 

Cordialement

VDH-Bruno

Apprendre => Prendre => Rendre

Posté(e)

Merci beaucoup pour le temps que vous passez sur mon problème et vos réponses toutes les deux très intéressantes.

 

Effectivement il est un peu décevant qu'autocad ne propose pas une "vision" des objet linéaires non dépendant du type de ligne.

 

La solution pickbox ne me plais pas des masses pour l'aléatoirité quelle engendre.

 

Je fait une routine qui sera utilisable par d'autres et je souhaite qu'ils n'aient pas de possibilité de critiquer le résultat obtenu (ce serais pour moi je m'embéterais pas plus que ça et la soltion avec un zoom a l'echelle qui me plait et ça roule).

 

VDH-Bruno, ta solution m'interresse, mais elle oblige encore une fois a sélectioner toutes les polylignes. par contre elle apporte le fait de pouvoir vérifier plus que les sommets de polylignes correspondant aux blocs (point sur lequel je m'atais concentré sur ma routine, mais dont je n'ai pas parlé ici).

C'est même très intéressant pour moi car combiner à ce que je fait déjà je pourrais controler la présence sur une polyligne et/ou un sommet de celle-ci.

 

Encore merci à vous tous pour l'aide que vous m'apportez.

C'est en forgeant que l'on devient forgerons.

Et c'est en sciant que Léonard DeVinci!

Posté(e)

Hello

 

Rappel : je ne suis pas du tout developpeur !

 

Parfois quand je n'ai pas trop de types de lignes differents,

je force dans une certaine couleur pour un type de ligne "non continu"

et je met en CONTINUOUS tous les objets concernes ...

 

A ce moment, je n'ai presque pas de probleme de selection (surtout en Lambert)

a certains endroits critiques, et donc je tripatouille comme je veux !

 

Apres mes tripatouillages, je repasse les objets avec les couleurs "speciales" en type de ligne "non continu" !

 

C pas tres orthodoxe, mais en general ca marche bien !

 

lecrabe

Autodesk Expert Elite Team

Posté(e)

efectivement c'est une solution qui conviendrait.

A voir quel est le traitement le plus long (contrôle de toutes les polylignes pour chaque bloc sans rien changer ou un changement de chaque polyligne mais un contrôle beaucoup plus restreint pour chaque bloc.

 

Je vais tenter les deux méthode et analyser les résultat (que je ne manquerais pas de transmettre ici).

 

Encore merci pour toute vôtre aide.

 

ps: je ne suis pas (très loins de la) programmeur non plus, mais j'aime a apprendre le LISP pour AUtocad, je trouve le fait que le langage soit interprété est un vrais gain de temps pour l'apprentissage de celui-ci, même si il est surrement plus lent à l'execussion qu'un langage compilé.

De plus le Lisp me semble le meilleur moyen d'appliquer des routines logiques répétitive tel qu'un utilisateur le ferait, donc effectivement même si c'est pas toujours la meilleur métode, choisir de transposer une méthode logique de travail classique en routine lisp est une méthode qui porte ses fruits selon mon expérience (faible) de ce langage.

C'est en forgeant que l'on devient forgerons.

Et c'est en sciant que Léonard DeVinci!

Posté(e)

Bonjour,

 

VDH-Bruno, ta solution m'interresse, mais elle oblige encore une fois a sélectioner toutes les polylignes.

La sélection global était à titre d’exemple, car comme précisé elle peut être affiné, par exemple pour capturer les polylignes par une sélection de 100 unité de côté autour d’un point.

 

Remplace dans le code précédent l’expression:

(setq ss (ssget "_X" '((0 . "LWPOLYLINE"))))

 

Par

(setq ss (ssget "_C"
               (mapcar '+ '(-50.0 -50.0 0.0) (trans pt 0 1))
               (mapcar '+ '(50.0 50.0 0.0) (trans pt 0 1))
               '((0 . "LWPOLYLINE"))
        )
)

 

 

 

Effectivement il est un peu décevant qu'autocad ne propose pas une "vision" des objet linéaires non dépendant du type de ligne.

Rien n’empêche de jouer avec la variable LTSCALE ou la commande ECHLTP (qui provoque la régénération de l’affichage). En affectant une valeur suffisamment grande pour qu’AutoCAD ne puisse pas afficher la discontinuité des lignes.

 

 

Un exemple de ce que tu cherches à faire en utilisant ce principe… ce qui oblige à recalcule tous ce que tu as à l’affichage, en plus d’avoir à l’affichage la zone à analyser (ceci est valable également pour les sélections par mode graphique Trajet Capture Fenêtre ect…), bref un zoom étendu est préalablement recommandé.

 

Pour tester :

(progn (setq var-LTSCALE (getvar 'LTSCALE))
      (command "echltp" 1.0e+99)
      (setq ss (ssget "_C" (trans pt 0 1) (trans pt 0 1) '((0 . "LWPOLYLINE"))))
      (command "echltp" var-LTSCALE)
      (sssetfirst nil ss)  
)

 

Cordialement

Apprendre => Prendre => Rendre

Posté(e)

L'astuce de modifier l'échelle du type de ligne en valeur extrême (à la façon de _move pour mettre les Z à zéro) est peut être la méthode la plus simple.

En tout cas elle fonctionnera bien si les types de ligne sont affectés aux calques, cependant si le type de ligne est affecté à l'objet seul et en plus avec sa propre échelle, cela ne sera pas suffisant pour résoudre le problème de sélection.

 

J'ai rencontré des difficultés avec les fonctions lisp simulant une sélection manuelle par points (ssget), (nentselp) et aussi la fonction (osnap pt "mode d'accroche"), bien qu'elle simplifient la création d'un programme, elles ne sont pas toujours d'un comportement fiable d'une exécution à l'autre suivant le contexte.

 

J'ai observé récemment aussi des retours aléatoire nul non justifié avec (vlax-curve-getClosestPoint) ou (vlax-curve-getClosestPointToProjection); ceci dans des systèmes de coordonnées générales avec des mantisse élevées (Lambert93 par exemple). Il y a certainement des solutions, mais ces cas extrêmes peuvent devenir un vrai cas-tête, difficile d'allier alors concision du code et efficacité avec fiabilité d'exécution de celui-ci...

Quand on tombe sur les limites de calcul, soit c'est la bidouille, soit on laisse tomber ou dernière solution: on devient un génie de l'algorithme!

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

Posté(e)

Bonsoir bonuscad

 

J'ai observé récemment aussi des retours aléatoire nul non justifié avec (vlax-curve-getClosestPoint) ou (vlax-curve-getClosestPointToProjection); ceci dans des systèmes de coordonnées générales avec des mantisse élevées (Lambert93 par exemple).

 

Merci pour le retour, car c’est tout à fait le type d’expérience aux quelles je ne suis jamais confronté dans mon environnement de travail n’étant pas cartographe, ni géomètre, sur mes projets la structure béton d’une base logistique ou d’un centre commercial n’excède que rarement les 300 ml donc même si je cotais en millimètre, il reste encore suffisamment de chiffre significatif avant que la mantisse (ou significande) des nombres à virgules flottantes fasse des erreurs d’arrondie dans les calculs. D’ailleurs c’est grâce à tes interventions sur ce forum que je me suis sensibilisé au problème, même si je n’y pense pas toujours..

 

 

…cependant si le type de ligne est affecté à l'objet seul et en plus avec sa propre échelle, cela ne sera pas suffisant pour résoudre le problème de sélection.

 

??? Là j’avoue ne plus trop te suivre, car peu importe que le type de ligne ou que l’échelle du type de ligne soit forcé, sauf peut être si le type de ligne est forcé avec une valeur très proche des 1.0e-99 mais en vingt ans de dessin j’ai encore jamais vu..

 

 

Pour l’anecdote c’est le type d’astuce que j’utilisais en manuel sur version LT (au facteur d’échelle près), lorsque je n’arrivais pas à m’accrocher à l’intersection de lignes discontinues ou autres blagues du même genre, et c’est l’une des premières fonctions que je me suis empressé de programmer quand j’en ai eu la capacité, ci-joint le code internationalisé pour l’occasion.

 

;; VDH-Bruno
;; Transforme à l'affichage les lignes discontinues en continue
;; (Fonction réversible au 2nd appels)
(defun c:ldis ()
 (cond
   (*LD-LTSCALE* (command "'_.ltscale" *LD-LTSCALE*) (setq *LD-LTSCALE* nil))
   ((setq *LD-LTSCALE* (getvar 'LTSCALE)) (command "'_.ltscale" 1.0e+99))
 )
 (princ)
)

 

Le seul bémol, c’est que même si dans les faits rien n’empêche la transparence de la fonction pour que la régénération de l’affichage prenne effet, il faut hélas mais logiquement que ce soit en dehors de tout appel à la fonction commande. Sinon j’aurais fait de l’appel du pied à (gile) pour qu’il transpose l’idée en .net afin de l’intègrer à son Osnap Palette.

 

Ps: Faute d'une variable similaire à QTEXTMODE pour les type de ligne, c’est le type de code qui rend bien service au quotidien.. ;)

 

A+

Apprendre => Prendre => Rendre

Posté(e)
??? Là j’avoue ne plus trop te suivre, car peu importe que le type de ligne ou que l’échelle du type de ligne soit forcé, sauf peut être si le type de ligne est forcé avec une valeur très proche des 1.0e-99

 

Effectivement, moi aussi je ne me suis plus...

Quand j'ai écrit la réponse, je pensais à la variable "CELTSCALE", mais en fait cela n'aurait aucune incidence vu le facteur appliqué à LTSCALE.

 

Désolé de ce paragraphe de ma réponse complétement inapproprié et confus.

Il faut dire qu'entre LTSCALE, CELTSCALE et PSLTSCALE j'ai moi même du mal à régler parfois mes type de ligne quand ces variables ont des valeurs folkloriques.

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

Posté(e)

J'ai observé récemment aussi des retours aléatoire nul non justifié avec (vlax-curve-getClosestPoint) ou (vlax-curve-getClosestPointToProjection); ceci dans des systèmes de coordonnées générales avec des mantisse élevées (Lambert93 par exemple). Il y a certainement des solutions, mais ces cas extrêmes peuvent devenir un vrai cas-tête, difficile d'allier alors concision du code et efficacité avec fiabilité d'exécution de celui-ci...

J'ai eu le même soucis dans le cadre de la même routine que j'essais de créer ici!

A un moment j'ai pris le test de faire une sélection de toutes les polylignes sur les calques que je voulais controler puis d'entrer leurs coordonnées dans un liste.

Ensuite pour chaque bloc je controlais que les coordonnées été présentes dans la liste et si oui le bloc était déclaré valide, si non il était identifié et compté.

 

Soucis, en RGF93 les coordonnées tournents vite à des valeurs arondis (en plus d'appliquer un affichage scientifique) et sont incomparables car répondent toujours commes identiques alors qu'en réalité elle sont très lointaines.

Etonnament en choisisant de ne pas passer par une liste je n'ai aucun probléme et que des résultats corrects.

J'ai peu être (pas souvenir et je suis en congées) repassé mes coordonnées en liste avec un rtos quelque part, mais je ne pourrais pas l'assurer!

C'est le genre de truc qui font tourner en rond un bon moment pour contourner le problème.

 

Pour en revenir au sujet principal, je tiens une fois de plus à tous vous remercier pour votre aide.

J'avoue que la modification de l'echelle de type de ligne globale est une option que je n'envisageait pas dans un lisp, pensant que le rafraichissement ne se ferais qu'après l'execution du lisp, donc trop tard (quand je trace des objets en Vlisp il n'apparaissent qu'après la fin du Lisp).

 

Reste une solution "simple" de copier toutes les polylignes dans un calque avec un type de ligne continu et d'applier un type de ligne "du calque" à toutes. Puis de faire la routine ensuite et de tout supprimer à la fin. C'est barbare (et je voulais l'éviter), mais ça fonctionnerais.

 

Je vais me pencher sur l'echelle de type de ligne en rentrant de congées, je pense que c'est la solution la plus rapide pour arriver à ce que je souhaite , et au pire la sélection "proche" ou globale mais avec un temps d'execution plus long sur les gros fichiers.

C'est en forgeant que l'on devient forgerons.

Et c'est en sciant que Léonard DeVinci!

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é