-
Compteur de contenus
12 247 -
Inscription
-
Dernière visite
-
Jours gagnés
209
Type de contenu
Profils
Forums
Calendrier
Blogs
Tout ce qui a été posté par (gile)
-
Lancer AutoCAD depuis un exe
(gile) a répondu à un(e) sujet de kluna dans ObjectARX/DBX, C++, .NET, RealDWG
Salut, Il serait bon que tu précise dans quel but tu désires faire ceci, parce que si c'est pour pour accéder au dessin en lecture et/ou en écriture depuis l'exe, tu ne peux le faire que via ActiveX et, dans ce cas, tu dois référencer les bibliothèque Autodesk.AutoCAD.Interop et, éventuellement, Autodesk.AutoCAD.Interop.Common. Un exemple avec une simple application console : using Autodesk.AutoCAD.Interop; using System; using System.Runtime.InteropServices; namespace ConsoleAppAutoCAD { class Program { static void Main(string[] args) { AcadApplication acadApp = null; // progId concerne la denière version utilisée sur le poste (en fonction de la version majeure) const string progId = //"AutoCAD.Application"; // toutes versions //"AutoCAD.Application.19"; // AutoCAD 2013-2014 //"AutoCAD.Application.20"; // AutoCAD 2015-2016 //"AutoCAD.Application.21"; // AutoCAD 2017 //"AutoCAD.Application.22"; // AutoCAD 2018 //"AutoCAD.Application.23"; // AutoCAD 2019-2020 "AutoCAD.Application.24"; // AutoCAD 2021-2022 // Essaye d'obtenir une instance d'AutoCAD en cours try { acadApp = (AcadApplication)Marshal.GetActiveObject(progId); } catch // une exception est lancée si aucun processus n'est trouvé { try { // Crée une nouvelle instance d'AutoCAD acadApp = (AcadApplication)Activator.CreateInstance(Type.GetTypeFromProgID(progId), true); } catch { // Si aucune instance n'a pu être démarrée (aucun AutoCAD R24 n'est installé) System.Windows.Forms.MessageBox.Show("Aucune instance de 'AcadApplication' n'a pu être créée."); return; } } // Afficher AutoCAD acadApp.Visible = true; // Ouvrir le fichier acadApp.Documents.Open(@"D:\Dossier Plans\xxx.dwg"); // Manipuler le fichier avec l'API COM/ActiveX // par exemple, faire un zoom étendu acadApp.ZoomExtents(); } } } -
Salut, Si les deux polylignes ne sont composées que de segments droits et ont le même nombre de sommets, c'est assez facile de faire un LISP (je pense avoir déjà posté ce type de routine sur CADxp, mais où ?).
-
Je ne pourrais pas vraiment t'aider en ce qui concerne le code VBA. Mais il me semble que tu peux améliorer l'algorithme en commençant par récupérer toutes les étiquettes des attributs (dans la première référence de bloc de la sélection ou dans la définition même du bloc) pour définir les colonnes attribut et seulement après, remplir ces colonnes pour chaque attribut avec les valeurs.
-
Salut, Il faut que tu te penches sur les codes de groupe DXF des entités AutoCAD, et dans ton cas, spécifiquement sur celles des références de bloc (INSERT). Tu verras que pour le nom de bloc, le code de groupe est : 2.
-
C'est toi qui est censé connaître le VBA... Peut-être comme ça : Function HasLinetype (nomDuTypeDeLigne As String) As Boolean Dim result As Boolean = False For Each lType in ThisDrawing.LineTypes If lType.Name = nomDuTypeDeLigne Then result = True Exit For Next HasLinetype = result
-
Même "à distance" tu utilises une instance de AcadApplication et donc l'Object Model d'autoCAD.
-
Si tu veux faire du VBA AutoCAD, la base c'est l'Object Model.
-
Salut, Tu peux utiliser la méthode Item sur la table des types de ligne : ThisDrawing.Linetypes.Item(nomDuTypeDeLigne) mais, comme expliqué dans cette réponse, Item génère une erreur si l'entrée n'existe pas dans la table. Une autre façon, est de parcourir la table des types de ligne avec For Each pour comparer les noms de types de ligne. Function HasLinetype (nomDuTypeDeLigne As String) As Boolean For Each lType in ThisDrawing.LineTypes If lType.Name = nomDuTypeDeLigne Then Return True Next Return False
-
Salut, Cherche cette expression dans le code: (vla-SetBlockTableRecordId ; block symbol table row 2 (vla-get-ObjectId (vla-Item *blocks* (car item))) :vlax-true ) et remplace :vlax-true par :vlax-false.
-
@Curlygoth Le titre du sujet est : "Comment créer un filtre de propriété pour les calques.", ce que tu proposes ressemble à ce qui existe nativement dans AutoCAD et s'appelle : filtre de groupe.
-
Concernant les dictionnaires et xrecords, tu peux voir ce sujet. Les exemple de code sont en LISP mais la 'théorie' sur les dictionnaires et xrecords vaut quel que soit l'environnement de développement.
-
Salut, C'est quoi le problème avec le LISP ? Quoi qu'il en soit, c'est du vlisp, c'est 'presque' du VBA. 1. On récupère le dictionnaire d'extension de la table des calques : (setq xdic (vla-getextensiondictionary (vla-get-layers (vla-get-activedocument (vlax-get-acad-object))) ;_ Fin de vla-get-layers ) ;_ Fin de vla-getextensiondictionary ) ;_ Fin de setq En VBA, ça serait quelque chose comme : Dim xdict As AcadDictionary Set xdict = ThisDrawing.Layers.GetExtensionDictionary() 2. On cherche le dictionnaire "ACAD_LAYERFILTERS" comme entrée du dictionnaire d'extension mais si l'entrée n'existe pas, ça génère une erreur. on peut alors ajouter cette entrée au dictionnaire d'extension (il faut voir le (and ...) comme un (if ...) : (and (vl-catch-all-error-p (setq dict (vl-catch-all-apply 'vla-item (list xdic "ACAD_LAYERFILTERS")) ;_ Fin de vl-catch-all-apply ) ;_ Fin de setq ) ;_ Fin de vl-catch-all-error-p (setq dict (vla-addobject xdic "ACAD_LAYERFILTERS" "AcDbDictionary")) ;_ Fin de setq ) ;_ Fin de and en VBA, je ne suis pas très sûr de moi avec la célèbrement calamiteuse gestion des erreurs du VBA, mais ça devrait être quelque chose comme ça: Dim dict As AcadDictionary On Error GoTo ErrorHandler Set dict = xdict.Item("ACAD_LAYERFILTERS") ErrorHandler: Set dict = xdic.AddObject("ACAD_LAYERFILTERS", "AcDbDictionary") Resume Next 3. On refait la même chose pour le Xrecord, entrée du dictionnaire "ACAD_LAYERFILTERS" : Dim ndict As AcadXRecord On Error GoTo ErrorHandler Set ndict = dict.Item(nom) ErrorHandler: Set ndict = dic.AddXRecord(nom) Resume Next 4. On définit les données du Xrecord : (vlax-invoke ndic 'setxrecorddata '(1 1 1 1 70 1 1) (list nom filtre "*" "*" 0 "*" "*")) Ce qui devrait pouvoir s'écrire en VBA : Dim dataType As Variant Dim dataValue As Variant Set dataType = Array(1 1 1 1 70 1 1) Set dataValue = Array(nom filtre "*" "*" 0 "*" "*") ndic.SetXRecordData(dataType, dataValue)
-
La question paire pointée vs liste de 2 éléments est anecdotique*. Par contre faire des listes séparées en fonction du diamètre me semble inévitable (idem pour la couleur si les barres entières sont colorées). * c'est juste que construire une liste de deux éléments avec : (list a b) correspond à : (cons a (cons b nil)) quand construire une paire pointée c'est simplement faire : (cons a b). Idem pour : (cadr p) qui correspond à : (car (cdr p))
-
(defun miseEnBarre (listeDebit lgBarre / mettreEnBarre) (defun mettreEnBarre (listeDebit lgRestante barre debitRestant) (cond ((null listeDebit) (cons (reverse barre) (if debitRestant (mettreEnBarre (reverse debitRestant) lgBarre nil nil) ) ) ) ((<= (cadar listeDebit) lgRestante) (mettreEnBarre (cdr listeDebit) (- lgRestante (cadar listeDebit)) (cons (car listeDebit) barre) debitRestant ) ) (T (mettreEnBarre (cdr listeDebit) lgRestante barre (cons (car listeDebit) debitRestant) ) ) ) ) (mettreEnBarre (vl-sort listeDebit '(lambda (p1 p2) (< (cadr p2) (cadr p1)))) lgBarre nil nil) ) Avec ta liste, (setq resultat (miseEnBarre listebarre lgbarre)) renvoie: ((("r" 256.7) ("s" 233.5)) (("ag" 256.7) ("ah" 233.5)) (("af" 159.7) ("q" 159.7) ("d" 156.8)) (("w" 156.8) ("ab" 156.8) ("i" 156.8)) (("c" 148.5) ("v" 148.5) ("aa" 148.5) ("o" 50.5)) (("h" 148.5) ("e" 147.8) ("x" 147.8) ("ad" 50.5)) (("ac" 147.8) ("j" 147.8) ("a" 120.0) ("k" 50.5)) (("b" 120.0) ("f" 120.0) ("g" 120.0) ("t" 120.0)) (("u" 120.0) ("y" 120.0) ("z" 120.0) ("m" 50.5) ("n" 47.9)) (("p" 47.9) ("l" 47.9) ("ae" 47.9)) ) Si tu veux avoir les chutes pour chaque barre, (mapcar '(lambda (l) (- lgBarre (apply '+ (mapcar 'cadr l)))) resultat) renvoie : (9.8 9.8 23.8 29.6 4.0 5.4 33.9 20.0 41.6 356.3) Personnellement j'aurais utilisé des paires pointées plutôt que des paires, plus simples à construire avec (cons ...) et à lire avec (cdr ...) au lieu de (cadr ...).
-
Salut, Un algorithme simple de bin packing en une dimension (best-fit decreasing). (defun miseEnBarre (listeDebit lgBarre / mettreEnBarre) (defun mettreEnBarre (listeDebit lgRestante barre debitRestant) (cond ((null listeDebit) (cons (reverse barre) (if debitRestant (mettreEnBarre (reverse debitRestant) lgBarre nil nil) ) ) ) ((<= (car listeDebit) lgRestante) (mettreEnBarre (cdr listeDebit) (- lgRestante (car listeDebit)) (cons (car listeDebit) barre) debitRestant ) ) (T (mettreEnBarre (cdr listeDebit) lgRestante barre (cons (car listeDebit) debitRestant) ) ) ) ) (mettreEnBarre (vl-sort (mapcar 'float listeDebit) '>) lgBarre nil nil) )
-
coordonnée du point d'intersection de la perpendiculaire
(gile) a répondu à un(e) sujet de PHILPHIL dans Routines LISP
J'ai ajouté la méthode 3 dans ce petit exposé sur calcul vectoriel avec AutoLISP. -
coordonnée du point d'intersection de la perpendiculaire
(gile) a répondu à un(e) sujet de PHILPHIL dans Routines LISP
Salut, Si tu as une ligne AB, vlax-curveGetClosestPointTo est le plus simple : (vlax-curveGetClosestPointTo ligneAB pointC T) Sinon, on peut utiliser la fonction trans. En convertissant les points A et C dans un système de coordonnées dont le vecteur AB est la normale, le point rechercha a les coordonnées X et Y de A et la coordonnée Z de C. Il suffit ensuite de reconvertir ce point de ce système vers de SCG : (setq n (mapcar '- b a) a (trans a 0 n) c (trans c 0 n) ) (trans (list (car a) (cadr a) (caddr c)) n 0) Ou encore avec un peu de calcul vectoriel (avec des fonctions issues de MathGeom en bas de cette page) : (setq u (gc:GetUnitVector a b) v (gc:GetVector a c) ) (mapcar '+ a (gc:ScaleVector u (gc:DotProduct u v))) -
Programmation VB.net
(gile) a répondu à un(e) sujet de Netparty dans ObjectARX/DBX, C++, .NET, RealDWG
Salut, Tout d'abord, bienvenue dans l'aventure .NET AutoCAD. Le premier conseil que je te donnerais, puisque tu débutes avec .NET, c'est de choisir le langage C# plutôt que VB. Tu trouveras plus d'aide, plus d'exemples en C# qu"en VB. C# demande plus de rigueur dans le code et c'est une bonne chose dans des environnements aussi complexes que le Framework .NET et l'API .NET d'AutoCAD. Si tu viens du VBA, apprendre un nouveau langage devrait t'aider à aborder .NET comme quelque chose de nouveau et différent. Microsoft a annoncé que, contrairement au C# qui continue à évoluer régulièrement, le VB sera juste maintenu en l'état. Le second conseil, si tu te lances dans l'aventure .NET, c'est de commencer par apprendre .NET hors AutoCAD et de ne t'attaquer à la programmation d'AutoCAD qu'une fois que tu seras à l'aise avec la Programmation Orientée Objet, les bases du Framework .NET, l'IDE Visual Studio dans le langage que tu auras choisi. Il existe pleins de tutos, livres etc. pour débuter avec .NET. Ensuite, concernant ton projet, il faut déterminer si tu veux construire une application externe (un .exe lancé hors processus -standalone application) ou une extension (une .dll chargée depuis AutoCAD -plugin). Voir ce sujet de la documentation "officielle". Dans le premier cas, le programme (exe) démarre un processus AutoCAD (ou accède à un processus déjà lancé) et peut le lire et/ou le modifier mais uniquement avec l'API COM/ActiveX (comme en VBA) Dans le second cas, le programme (dll) est chargé depuis AutoCAD avec la commande NETLOAD (ou automatiquement) et il est généralement lancé par une commande personnalisée qui peut lire et/ou modifier le fichier en utilisant l'API .NET d'AutoCAD qui est beaucoup plus puissante que l'API COM (qu'on peut aussi utiliser). Tu peux commencer par lire la documentation Autodesk en anglais. Tu trouveras quelques tutos en français sur cette page. notamment celui concernant la construction d'un modèle de projet. -
@La Lozère @benoitlacroix Je n'ai pas l'intention de modifier Edit_Bloc (comme je l'ai dit précédemment). L'histoire de cette routine a commencé avant l'apparition de l'éditeur de bloc. il me semble que ce que vous demandez est relativement simple à faire via cet éditeur.
-
Salut, Les bibliothèques DCL fournissent des boutons ou groupes de boutons à utiliser pour fermer les boites de dialogue (ok_only, ok_cancel, ok_cancel_help, ok_cancel_help_info). On peut créer un groupe de boutons Oui / Non (yes_no) utilisable de la même façon que ok_cancel en ajoutant ces quelques lignes à son fichier DCL. yes_button : retirement_button { label = " Oui "; key = "accept"; is_default = true; } no_button : retirement_button { label = " Non "; key = "cancel"; is_cancel = true; } yes_no : column { : row { fixed_width = true; alignment = centered; yes_button; : spacer { width = 2; } no_button; } } On peut aussi utiliser ce même code pour écrire le fichier DCL "à la volée" depuis le fichier LISP. Un exemple avec une boite de dialogue "générique" qui permet d'afficher un message / question et des boutons Oui / Non. (defun YesNoBox (title msg / temp file dcl_id status) ;; Créer un fichier DCL temporaire (setq temp (vl-filename-mktemp "Tmp.dcl") file (open temp "w") ) ;; Ecrire le fichier ;; boutons Oui / Non (write-line "yes_button : retirement_button { label = \" Oui \"; key = \"accept\"; is_default = true; } no_button : retirement_button { label = \" Non \"; key = \"cancel\"; is_cancel = true; } yes_no : column { : row { fixed_width = true; alignment = centered; yes_button; : spacer { width = 2; } no_button; } }" file ) ;; boite de dialogue principale (write-line "yes_no_box : dialog { key = \"titre\"; spacer;" file) (if (vl-consp msg) (progn (write-line ": paragraph {" file) (foreach l msg (write-line (strcat ": text_part{ label = \"" l "\";}") file) ) (write-line "}" file) ) (write-line (strcat ": text { label = \"" msg "\"; }") file) ) (write-line "spacer; yes_no; }" file) (close file) ;; Ouvrir la boite de dialogue (setq dcl_id (load_dialog temp)) (if (not (new_dialog "yes_no_box" dcl_id)) (exit) ) (set_tile "titre" title) (action_tile "accept" "(done_dialog 1)") (setq status (start_dialog)) (unload_dialog dcl_id) ;; Supprimer le fichier (vl-file-delete temp) ;; Renvoyer le résultat (Oui = 1 , Non = 0) status )
-
- 1
-
-
Tout d'abord, merci à @Luna et @Olivier Eckmann pour avoir précisé mon propos. Il faut bien distinguer une sélection par l'utilisateur (SelectOnScreen) d'un traitement de l'entièreté de l'espace objet ou du dessin. Dans le premier cas, il n'est pas question de performance puisqu'il y a une intervention de l'utilisateur. Il s'agit de l'aider à faire sa sélection en ne mettant en surbrillance que les entités concernées. Dans le second cas, si les filtres de sélection permettent effectivement un gain de performance avec les langages de très haut niveau comme le LISP ou le VBA (ce n'est plus vrai avec .NET ou ObjectARX) ce gain n'est pas toujours perceptible. Par contre, comme le disais @didier ("le "style" est important aussi"), l'utilisation des filtres permet d'écrire code plus concis, plus déclaratif donc plus facilement maintenable. Sinon, il est vrai qu'on ne peut pas tout faire directement avec les filtres (ex: les valeurs des propriétés des blocs dynamiques). Dans tous les cas, les demandes initiales concernaient la syntaxe des filtres de sélection ce à quoi d'aucuns ont semble-t-il répondu, la question de savoir si "on est fan" ou pas est un autre sujet...
-
De plus, lors d'une sélection par l'utilisateur (SelectOnScreen), le filtre de sélection permet de ne mettre en surbrillance que les entités concernées. Sinon, je conçois que les filtres de sélection ne sont pas d'un accès très intuitifs dans les langages qui ne sont pas aussi familiers avec les codes DXF qu'AutoLISP, et plus particulièrement avec le VBA à cause de la transposition de la liste de paires en une paire de listes.
-
[Résolu] Déplacement dans un calque par Lisp
(gile) a répondu à un(e) sujet de barbichette dans AutoCAD 2020-2024
Dans ce cas, une macro de commande devrait suffire. -
[Résolu] Déplacement dans un calque par Lisp
(gile) a répondu à un(e) sujet de barbichette dans AutoCAD 2020-2024
PS : éviter les accents, les espaces et autres caractères spéciaux excepté le souligner (_) dans les noms de symboles (calques, blocs, fonctions LISP, etc), t'évitera bien des déboires ultérieurs...
