Aller au contenu

(gile)

Moderateurs
  • Compteur de contenus

    12 247
  • Inscription

  • Dernière visite

  • Jours gagnés

    209

Tout ce qui a été posté par (gile)

  1. Salut; Désolé de te contredire didier mais la réponse#2 de Vincent P. fonctionne. Si la sélection ne contient que des blocs, même différents, dont un ou plusieurs attributs ont la même étiquette, ceux-ci apparaîtront bien dans la fenêtre des propriétés. http://gile.pagesperso-orange.fr/Attributs_blocs_differents.png
  2. (gile)

    Ventilation de surfaces

    Salut, Je n'ai pas trop de temps et didier semble avoir pris les choses en main donc je me contenterais d'une suggestion : regarder du côté des champs dynamique et des formules utilisables dans ces champs.
  3. (gile)

    Ventilation de surfaces

    "le transposer par écrit", c'est précisément ce qu'on fait quand on écrit un programme, c'est pourquoi je me suis permis d'insister pour que tu le fasses d'abord en français. On peut maintenant essayer de résoudre chacune des étapes, séparément dans un premier temps, en fonction de ce que sais déjà faire. Pour la saisie des données, par exemple, tu auras besoin d'utiliser entsel pour inviter l'utilisateur à sélectionner une polyligne, mais aussi initget pour lui permettre d'entrer des options (Coeff ou Base), d'utiliser if ou cond pour analyser l'entrée utilisateur, le tout probablement dans une boucle while tant que le résultat n'est pas une polyligne.
  4. (gile)

    Ventilation de surfaces

    Je ré-essaye une dernière fois. Il faut que tu réalises bien qu'en programmation tu t'adresses à une machine qui, certes calcule très vite, mais est complètement dénuée d'intelligence et d'intuition. Il faut donc que tu lui donnes dans le détail toutes les instructions nécessaires pour obtenir le résultat désiré. Dis toi qu'il faut faire de même quand tu t'adresses à des humains à qui tu demandes de l'aide. - À commencer par les données en entrée, lesquelles sont spécifiées par l'utilisateur, lesquelles sont des constantes définies "en dur" dans le programme. - Puis quelles sont les opérations à effectuer avec ces données pour arriver aux résultats souhaités. - Et pour finir, que faire avec ces résultats. Quand tu auras clairement définit chacune de ces taches, la structure de ton programme sera faite, il ne restera plus qu'à coder.
  5. (gile)

    Ventilation de surfaces

    Pour abonder dans le sens de didier, partir d'un code existant dont on pense qu'il fait "un peu" ce qu'on souhaite est rarement une bonne idée, et ce n'est jamais une bonne idée quand on ne comprends pas tout ou parie de ce code. Comme je l'ai déjà dit, TotalArea est un des LISP les plus complexes que j'ai publié et ce n'est certainement pas une bonne base pour débuter. Vouloir mettre à jour dynamiquement des attributs liés à une polyligne à l'aide réacteurs quand on ne sais pas bien comment modifier une valeur d'attribut, c'est un peu comme vouloir courir un marathon quand on sait à peine marcher.
  6. (gile)

    Ventilation de surfaces

    Salut, Sans vouloir aucunement préjuger tes capacités en LISP, je tiens quand même à signaler que vouloir modifier TotalArea nécessite une bonne connaissance de concepts avancés de Visual LISP comme, entre autres, les réacteurs. Ceci dit, si tu veux qu'on puisse t'aider, tu devrais montrer ce que tu as déjà essayer d'écrire pour ta fonction et expliquer clairement comment, à partir des données en entrée (le coefficient spécifié par l'utilisateur et l'ire d'une polyligne) tu procèdes pour arriver aux résultats escomptés. Ceci s'appelle l'algorithme et souvent, un algorithme correctement décrit représente l'essentiel du travail, sa conversion en code est alors évidente.
  7. (gile)

    While

    Salut, while boucle tant que la condition (ici la variable text) n'est pas nil. Donc, (if (/= text nil) sera toujours vrai (l'expression est donc inutile) et text ne sera jamais nil mais une erreur sera générée si (car (entsel "Choix du texte: ")) renvoie nil (si l'utilisateur ne sélectionne pas de texte), parce que (entget nil) génère une erreur. Autrement dit (car (entsel ...)) peut renvoyer nil mais pas (entget ...). C'est donc sur le résultat de (car (entsel ...)) qu'il faut boucler. (defun c:test (/ p1 p2 diff ang text elst) (setq p1 (getpoint "\nPoint 1: ") p2 (getpoint "\nPoint 2: ") ) (setq diff (mapcar '- p2 p1) ang (atan (/ (cadr diff) (car diff))) ) (while (setq text (car (entsel "Choix du texte: "))) (setq elst (entget text)) (entmod (subst (cons 50 ang) (assoc 50 elst) elst)) ) (princ) )
  8. Salut, Encore une fois, il s'agit des types de ligne complexe DGN (issus de Microstation). Les versions récentes d'AutoCAD (depuis 2015) permettent de purger ces types de ligne à condition d'avoir coché "Purger automatiquement les données non référencées" (il peut être nécessaire de fermer puis rouvrir la boite de dialogue PURGER pour voir apparaître ces types de ligne). La commande native n'arrive toutefois pas à les purger tous. JAV les purge (suppression de dictionnaires ?) avec une meilleure efficacité. RadicalPurge ne purge pas ces types de ligne, mais son grand frère, BatchPurge, en plus d'offrir une interface pour le traitement par lot, permet de supprimer ces types de ligne de façon plus radicale que la commande native. Fichier original : 5.04Mo Fichier purgé avec PURGER (A2019) : 478Ko Fichier purgé avec BatchPurge : 38.2Ko
  9. Salut, Personnellement, j'utiliserais un tableau. Mais si tu veux faire ça en texte multiligne, tu peux utiliser les colonnes des textes multiligne (inconvénient la largeur de toutes les colonnes est identique. Dans le contenu du texte multiligne, "\P" signifie un saut de ligne et "\N" un saut de colonne. On remplit les lignes d'une colonne avant de passer à la suivante. Exemple : var produits = new[] { "ALSAN Primaire P100", "EIF Sopradère", "Elastophène Flam 70" }; var fournisseurs = new[] { "Soprema", "Soprema", "Soprema" }; var epaisseurs = new[] { "ép. 10 mm", "ép. 10 mm", "ép. 10 mm" }; var mtext = new MText(); mtext.Contents = // contenu du texte multiligne string.Join("\\P", produits) + "\\N" + string.Join("\\P", fournisseurs) + "\\N" + string.Join("\\P", epaisseurs); mtext.TextHeight = textHeight; // hauteur de texte mtext.SetStaticColumns(textHeight * 20.0, 0.0, 3); // largeur de colone = 20 * hauteur de texte mtext.Height = textHeight * 2 * produits.Length; // hauteur du mtext (2 * hauteur de texte * nombre de lignes)
  10. Salut, Peut-être un problème avec la mise à l'échelle. Essaye d'appeler SetHatchPattern() après avoir spécifié le motif. acHatch.PatternScale = 0.07; acHatch.SetHatchPattern(HatchPatternType.PreDefined, "AR-CONC");
  11. Salut, List est une collection générique où T peut être remplacé par n'importe quel type .NET (class, struct, enum, interface, ...). Il est donc tout à fait possible de créer une liste d'instance de la classe MText. Mais encore une fois, si tu veux avoir de l'aide, essaye d'être plus clair dans tes demandes, le plus simple étant de montrer une extrait de code qui illustre ta demande. PS: ta question semble n'avoir rien à voir avec WPF.
  12. Salut Certes c'est un indéniable progrès par rapport à développer dans le bloc-note ou notepad++, mais il me semble qu'on est loin de l'éditeur Visual LISP (VLIDE) en terme d'intégration à AutoCAD (ou de l'éditeur BLADE de BricsCAD). Si je comprends bien, il s'agit d'un débogueur AutoLISP proposé comme extension pour Visual Studio Code. Visual Studio Code est un éditeur de code multi langage extensible (à ne pas confondre avec Visual Studio, l'IDE de la plateforme .NET beaucoup plus puissant). Si la présentation est plus "moderne" que celle de l'éditeur Visual LISP, les fonctionnalités ne sont pas les mêmes et le processus de débogage est forcément plus lourd. En fait, il est similaire à ce qu'on fait en .NET : on code dans l'éditeur en plaçant éventuellement des points d'arrêt, puis on lance ZWCAD (AutoCAD) en mode débogage depuis l'éditeur, puis on charge le code dans AutoCAD pour pouvoir enfin exécuter le code.
  13. Salut, Vite fait à partir de vieux trucs. Ça ne traite pas les OD. (defun c:p3d2d (/ *error* ss elev xdataType xdataValue) (vl-load-com) (or *acdoc* (setq *acdoc* (vla-get-ActiveDocument (vlax-get-acad-object))) ) (defun *error* (msg) (and msg (/= mas "Fonction annulée") (princ (strcat "\nErreur: " msg)) ) (vla-EndUndoMark *acdoc*) (princ) ) (if (ssget '((0 . "POLYLINE") (-4 . "&") (70 . 8))) (progn (vla-StartUndoMark *acdoc*) (vlax-for p3d (setq ss (vla-get-ActiveSelectionSet *acdoc*)) (setq elev (caddr (vlax-curve-getStartPoint p3d)) p2d (vlax-invoke (if (= 1 (getvar 'cvport)) (vla-get-PaperSpace *acdoc*) (vla-get-ModelSpace *acdoc*) ) 'addLightWeightPolyline (apply 'append (mapcar '(lambda (x) (list (car x) (cadr x)) ) (3d-coord->pt-lst (vlax-get p3d 'Coordinates)) ) ) ) ) (vla-put-Closed p2d (vla-get-Closed p3d)) (vla-put-Elevation p2d elev) (vla-GetXdata p3d "" 'xdataType 'xdataValue) (if xdataType (vla-SetXdata p2d xdataType xdataValue) ) ) (vla-delete ss) (vla-EndUndoMark *acdoc*) ) ) (*error* nil) ) ;;; 3d-coord->pt-lst ;;; Convertit une liste de coordonnées 3D en liste de points ;;; (3d-coord->pt-lst '(1.0 2.0 3.0 4.0 5.0 6.0)) -> ((1.0 2.0 3.0) (4.0 5.0 6.0)) (defun 3d-coord->pt-lst (lst) (if lst (cons (list (car lst) (cadr lst) (caddr lst)) (3d-coord->pt-lst (cdddr lst)) ) ) )
  14. La documentation Autodesk concerne essentiellement l'API .NET d'AutoCAD et suppose les bases de .NET (et donc de la POO comme acquises). Je te recommande fortement de commencer avec des tutoriels généraux sur C#/.NET hors AutoCAD pour te familiariser avec les notions de classe, d'héritage, d'encapsulation, de polymorphisme, etc.
  15. Salut, Petit rappel. Quand on appelle une commande depuis AutolISP avec la fonction command, les options peuvent différer de celles de la commande appelée directement. De plus, les options des commandes changent parfois avec les nouvelles versions et la fonction AutoLISP command peut ne pas refléter ces changements. Dans ce cas, la fonction initcommandversion permet de forcer la version de la commande utilisée par command. Après un rapide test, cette séquence semble fonctionner correctement (testé sur 2014 et 2019) (setq ent (car (entsel))) (setq pt (getpoint "\nPoint de base: ")) (command "_.rotate" ent "" pt "_copy" "_reference" pt pause pause) Il y a quelque temps, j'avais fait une petite vidéo qui donnait une méthode pour construire pas à pas un appel AutoLISP à command en utilisant les bons arguments.
  16. Salut Ta question n'est pas claire. Un dessin AutoCAD est comparable à une base de données, il existe d'ailleurs une classe Database unique pour chaque dessin (tous les objets dérivant de DBObject constituent cette base de donnée). Tu trouveras dans l'aide aux développeurs les sections ObjectARX: Managed .NET Developer's Guide (.NET) et ObjectARX: Managed .NET Reference Guide La première contient les bases pour commencer à programmer AutoCAD avec .NET* dont une section Understand the AutoCAD Object Hierarchy (.NET) qui donne un aperçu de la façon dont est organisée la "base de données" AutoCAD (il manque les dictionnaires (DBDIctionary) qui sont aussi utilisés pour stocker des données non-graphiques), la seconde l'ensemble des classes, structures, etc. de l'API .NET d'AutoCAD. Si tu as, comme il se doit**, installé le SDK de la version d'ObjectARX que tu cibles, dans le dossier ObjectArx\ClassMap, tu trouveras un fichier classmap.dwg qui décrit les hiérarchies des classes. *je pense toutefois qu'il est indispensable d'avoir acquis auparavant les bases de .NET et de la Programmation Orientée Objet. ** il est fortement recommandé d'installer le SDK ObjectARX qui contient une documentation des références .NET et ObjectARX automatiquement intégrée à l'Intellisense de Visual Studio depuis les dernières versions et il est préférable de référencer les bibliothèques AutoCAD depuis le dossier ObjectARX 20XX\inc plutôt que depuis le répertoire d'installation.
  17. Salut, EntityJig est utilisé avec une entité unique, DrawJig avec un ou plusieurs objets Drawable. les deux permettent l'utilisation des accrochages aux objets. Dans ton cas, je pense donc que tu devrais utiliser une classe héritant de DrawJig. Ci dessous un exemple simple. using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.Runtime; namespace DragBalloonSample { public class Commandss { [CommandMethod("BALLOON")] public void DragBalloon() { Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; PromptPointResult ppr = doc.Editor.GetPoint("\nSpecify the first point of line: "); if (ppr.Status != PromptStatus.OK) return; Point3d basePt = ppr.Value.TransformBy(ed.CurrentUserCoordinateSystem); using (Transaction tr = db.TransactionManager.StartTransaction()) using (Circle circle = new Circle(basePt, Vector3d.ZAxis, 3.0)) using (Line line = new Line(basePt, basePt + Vector3d.XAxis)) { BalloonJig jig = new BalloonJig(circle, line); PromptResult pr = ed.Drag(jig); if (pr.Status == PromptStatus.OK) { ObjectIdCollection ids = new ObjectIdCollection(); circle.TransformBy(jig.Displacement); line.TransformBy(jig.RotateScale); BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite); ids.Add(btr.AppendEntity(circle)); tr.AddNewlyCreatedDBObject(circle, true); ids.Add(btr.AppendEntity(line)); tr.AddNewlyCreatedDBObject(line, true); } tr.Commit(); } } class BalloonJig : DrawJig { private Circle circle; private Line line; private double radius; private Point3d basePoint, center; public Matrix3d Displacement { get; private set; } public Matrix3d RotateScale { get; private set; } public BalloonJig(Circle circle, Line line) { this.circle = circle; radius = circle.Radius; this.line = line; basePoint = line.StartPoint; } protected override bool WorldDraw(Autodesk.AutoCAD.GraphicsInterface.WorldDraw draw) { Autodesk.AutoCAD.GraphicsInterface.WorldGeometry geo = draw.Geometry; if (geo != null) { geo.PushModelTransform(Displacement); geo.Draw(circle); geo.PopModelTransform(); geo.PushModelTransform(RotateScale); geo.Draw(line); geo.PopModelTransform(); } return true; } protected override SamplerStatus Sampler(JigPrompts prompts) { JigPromptPointOptions opts = new JigPromptPointOptions("\nSpecify the circle center: "); opts.UserInputControls = UserInputControls.NullResponseAccepted; PromptPointResult ppr = prompts.AcquirePoint(opts); if (ppr.Value.IsEqualTo(center)) return SamplerStatus.NoChange; center = ppr.Value; Vector3d disp = basePoint.GetVectorTo(center); double angle = Vector3d.XAxis.GetAngleTo(disp, Vector3d.ZAxis); double scale = basePoint.DistanceTo(center) - radius; Displacement = Matrix3d.Displacement(disp); RotateScale = Matrix3d.Rotation(angle, Vector3d.ZAxis, basePoint) * Matrix3d.Scaling(scale, basePoint); return SamplerStatus.OK; } } } }
  18. Salut et bienvenue, Quand on veut agir sur un document AutoCAD depuis une interface non modale il faut impérativement verrouiller ce document. On peut le faire avec la méthode Document.LockDocument() dans une instruction using pour s'assurer que le document sera automatiquement déverrouillé. using (acdoc.LockDocument()) using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction()) { // ... } Mais il est préférable de définir la tache à accomplir dans une commande personnalisée (CommandMethod) et d'appeler cette commande avec SendStringToExecute() de façon à laisser le soin à AutoCAD de s'occuper du verrouillage / déverrouillage du document. Ceci permet permet aussi de mieux séparer ce qui concerne l'interface de ce qui concerne le "métier" (AutoCAD) pratique généralement privilégiée avec WPF. Tu peux voir ce tutoriel à propos des interfaces utilisateur avec AutoCAD .NET. PS. quand tu postes du code utilise les bbcodes (le bouton : ).
  19. En l'état, la fonction getbases supporte les cylindres et les cônes tronqués qu'ils soient circulaires ou elliptiques, que les bases soient perpendiculaire à l'axe ou non, qu'ils aient été créés avec les primitives (CYLINDRE ou CONE) ou par extrusion* ou lissage. Autrement dit, les solides avec deux bases circulaires ou elliptiques et une seule face d'enroulement. *l'extrusion d'une ellipse avec un angle ne génère pas un cône elliptique (les bases sont des Splines)
  20. Les fonctions vlax-curve-* sont tes amies pour déterminer l'index du segment sélectionné. On peut les utiliser avec un nom d'entité (ENAME) et la fonction getpropertyvalue (if (and (setq ent (entsel "\nSélectionnez un segment de polyligne: ")) (setq pt (cadr ent)) ; point cliqué (setq pl (car ent)) ; entité sélectionnée (= (getpropertyvalue pl "LocalizedName") "Polyligne") ; contrôle du type d'entité (setq pt (vlax-curve-getClosestPointTo pl (trans pt 1 0))) ; point sur la polyligne le plus proche du point cliqué (setq pa (fix (vlax-curve-getParamAtPoint pl pt))) ; index du segment sélectionné ) (getpropertyvalue pl "Vertices" pa "StartWidth") ; largeur de départ du segment ) Ou avec un vla-object et les fonctions vla-* (if (and (setq ent (entsel "\nsélectionnez un segment de polyligne: ")) (setq pt (cadr ent)) ; point cliqué (setq pl (vlax-ename->vla-object (car ent))) ; entité sélectionnée convertie en vla-object (= (vla-get-ObjectName pl) "AcDbPolyline") ; contrôle du type d'entité (setq pt (vlax-curve-getClosestPointTo pl (trans pt 1 0))) ; point sur la polyligne le plus proche du point cliqué (setq pa (fix (vlax-curve-getParamAtPoint pl pt))) ; index du segment sélectionné ) (progn (vla-GetWidth pl pa 'startWidth 'endWidth) startWidth ; largeur de départ du segment ) ) Sans les fonctions vlax-curve-*, il faudrait faire un peu de géométrie analytique avec les données DXF.
  21. Malheureusement oui... Ne serait-ce pas plutôt un lissage ? En tout cas, je n'ai pas ce problème avec un lissage (testé sur 2014 et 2019). Avec quelle version travailles-tu ? J'ai essayé de faire une autre routine qui renvoie les données DXF des bases d'un cylindre ou tronc de cône. (defun getBases (brepList / shells faces bases winding) (if (and ;; une seule entrée "COMPLEX" (= (car brepList) "COMPLEX") ;; une seule entrée "SHELL" (= (length (setq shells (cdr brepList))) 1) ;; trois entrées "FACE" (= (length (setq faces (cdar shells))) 3) ;; dont deux faces avec une seule entrée "LOOP" (= (length (setq bases (mapcar 'cadadr (vl-remove-if-not '(lambda (face) (= 2 (length face)) ) faces ) ) ) ) 2 ) ;; et une face avec deux entrées "LOOP" (= (length (setq winding (vl-some '(lambda (face) (if (= (length face) 3) (mapcar 'cadr (cdr face)) ) ) faces ) ) ) 2 ) ;; qui sont identiques à celles des deux autres faces (member (car bases) winding) (member (cadr bases) winding) ;; et qui représentent toutes deux des cercles ou des ellipses (vl-every '(lambda (loop) (member (cdar loop) '("CIRCLE" "ELLIPSE"))) bases) ) bases ) )
  22. Effectivement, le type LOOPWINDING semble avoir disparu au profit des LOOPEXTERIOR dans les nouvelles versions (je teste habituellement avec A2014 qui se lance plus rapidement). C'est dommage, la présence de LOOPWINDING suffisait à garantir qu'on était en présence d'un cylindre ou d'un tronc de cône.
  23. Si tu passes une liste retournée par gc-brep à getWindingLoops, la fonction renvoie une liste contenant les données DXF des deux 'boucles d'enroulement' du solide, ou nil si ce n'est ni un cylindre ni un cône tronqué. Utilisée dans ta fonction 'traite-solide', ça permet de contrôler si l'entité représente bien un cylindre ou un cône tronqué. (defun traite-solide (ent / loops c1 c2 ty d1 d2 l nb) (if (setq loops (getWindingLoops (gc-brep ent))) (progn (setq c1 (car loops) c2 (cadr loops) d1 (rtos (round (* 2 (cdr (assoc 40 c1))) 0.005) 2 2) d2 (rtos (round (* 2 (cdr (assoc 40 c2))) 0.005) 2 2) l (rtos (distance (cdr (assoc 10 c1)) (cdr (assoc 10 c2))) 2 2) nb 1 ) (if (/= d1 d2) (setq ty "reduc" l "np" ) (setq ty "cyl") ) (list ty d1 d2 l nb) ) ) )
  24. Salut, À ma connaissance, il n'y a rien en AutoLISP / Visual LISP pour récupérer ce type de données géométriques. C'est pourquoi, j'avais essayé d'exposer à AutoLISP l'API .NET BREP (Boundary REPresentation, ou représentation du contour en français). Voir ce sujet. Cette routine devrait retourner une liste de deux listes "type DXF" pour les bases (cercles ou ellipses) d'un solide 3d figurant un cylindre ou d'un cône troqué. ;; getWindingLoops ;; Retourne une liste contenant les données des deux 'boucles d'enroulement' (cercle ou ellipse) ;; d'un cône tronqué ou d'un cylindre (Solide3d) ;; ;; Argument ;; brepList une liste telle que retournée par la fonction gc-brep (defun getWindingLoops (brepList / shells faces) (if (and (= (car brepList) "COMPLEX") ; une seule entrée COMPLEX (= (length (setq shells (cdr brepList))) 1) ; une seule enveloppe ("SHELL") (= (length (setq faces (cdar shells))) 3) ; 3 faces ) (mapcar 'cadr (cdar (vl-remove-if-not '(lambda (x) (= (caadr x) "LOOPWINDING")) faces))) ) )
  25. Non, il n'y a pas d'autre moyen. vla-get-blocks comme vla-get-Layers, ou vla-get-Layouts, etc. retournent des collections d'objets non graphiques contenus dans des "tables" ou des "dictionnaires". Pour les entités graphiques on est toujours obligé de parcourir le (ou les) espace() et ou définition(s) de bloc qui les contiennent (ces instances de AcDbBlockTableRecord peuvent être vues comme des collections d'entités graphiques). Les sélections sans spécifications géométriques (point, fenêtre, capture, trajet, etc.) même quand elles sont filtrées procèdent de même, en parcourant toute la base de données (ou le ou les espaces s'ils sont filtrés). Seule exception, une sélection de toutes les référence d'un bloc peut se faire directement depuis la définition du bloc (le "BlockRecord" plus précisément), voir ce sujet.
×
×
  • 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é