Aller au contenu

Clip détail


(gile)

Messages recommandés

Salut,

 

Encore une fois, le cadeau de fin d'année est un peu à la bourre.

Il s'agit d'un petit plugin qui met en œuvre une API que je viens de découvrir en essayant d'aider quelqu'un sur le forum AutoCAD .NET d'Autodesk.

En gros, ça permet de faire un EXTRIM 'non destructif' avec un cercle et d'insérer le résultat à l'échelle spécifiée, un peu comme on ferait une vue de détail.

Ça fonctionne avec toutes les entités curvilignes exceptés les splines et les polylignes splinées fermées.

 

 

Télecharger ClipDetailSetup.msi et lancer l'installeur.

La commande DETAIL sera disponible pour toutes les versions d'AutoCAD 2013-2018 installées.

Gilles Chanteau - gileCAD -
Développements sur mesure pour AutoCAD
ADSK_Expert_Elite_Icon_S_Color_Blk_125.png

Lien vers le commentaire
Partager sur d’autres sites

Le code pour ceux que ça intéresse.

 

La classe Commands.

using Autodesk.AutoCAD.ApplicationServices.Core;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.ExportLayout; // reference: AcExportLayoutEx.dll
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using System.Collections.Generic;

[assembly: CommandClass(typeof(ClipDetail.Commands))]

namespace ClipDetail
{
   public class Commands
   {
       [CommandMethod("DETAIL", CommandFlags.Modal)]
       public void Detail()
       {
           var doc = Application.DocumentManager.MdiActiveDocument;
           var db = doc.Database;
           var ed = doc.Editor;

           var ppo = new PromptPointOptions(LocalizedResource.CenterMessage);
           var ppr = ed.GetPoint(ppo);
           if (ppr.Status != PromptStatus.OK)
               return;

           using (var tr = db.TransactionManager.StartTransaction())
           using (var circle = new Circle(ppr.Value, Vector3d.ZAxis, 1.0))
           {
               circle.TransformBy(ed.CurrentUserCoordinateSystem);
               var jig = new CircleJig(circle);
               var pr = ed.Drag(jig);
               if (pr.Status != PromptStatus.OK)
                   return;

               var curSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
               curSpace.AppendEntity(circle);
               tr.AddNewlyCreatedDBObject(circle, true);

               var psr = ed.SelectTrimmableCurves(circle.GeometricExtents);
               if (psr.Status != PromptStatus.OK)
                   return;

               var curveIds = psr.Value.GetObjectIds();
               var toCloneIds = new ObjectIdCollection();
               toCloneIds.Add(circle.ObjectId);
               var trimmedIds = new ObjectIdCollection();

               using (var nestedTr = db.TransactionManager.StartOpenCloseTransaction())
               {
                   foreach (ObjectId id in curveIds)
                   {
                       using (var trimmer = new Trimmer())
                       {
                           var entity = (Entity)nestedTr.GetObject(id, OpenMode.ForWrite);
                           trimmer.Trim(entity, circle);
                           if (trimmer.HasAccurateResults)
                           {
                               foreach (Entity ent in trimmer.TrimResultObjects)
                               {
                                   ent.SetPropertiesFrom(entity);
                                   curSpace.AppendEntity(ent);
                                   nestedTr.AddNewlyCreatedDBObject(ent, true);
                                   trimmedIds.Add(ent.ObjectId);
                               }
                           }
                           if (trimmer.EntityCompletelyInside)
                           {
                               toCloneIds.Add(entity.ObjectId);
                           }
                       }
                   }
                   nestedTr.Commit();
               }

               var details = new List<Entity>();
               if (toCloneIds.Count > 0)
               {
                   var mapping = new IdMapping();
                   db.DeepCloneObjects(toCloneIds, db.CurrentSpaceId, mapping, false);
                   foreach (IdPair pair in mapping)
                   {
                       if (pair.IsCloned && pair.IsPrimary)
                       {
                           details.Add((Entity)tr.GetObject(pair.Value, OpenMode.ForWrite));
                       }
                   }
               }
               foreach (ObjectId id in trimmedIds)
               {
                   details.Add((Entity)tr.GetObject(id, OpenMode.ForWrite));
               }

               var clipJig = new ClipJig(details, circle.Center);
               do { pr = ed.Drag(clipJig); }
               while (pr.Status == PromptStatus.Keyword);

               if (pr.Status != PromptStatus.OK)
                   return;

               foreach (var ent in details)
               {
                   ent.TransformBy(clipJig.Transform);
               }

               tr.Commit();
           }
       }
   }
}

 

La classe CircleJig

using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;

namespace ClipDetail
{
   class CircleJig : EntityJig
   {
       Circle circle;
       double radius;
       Point3d basePoint;

       public CircleJig(Circle circle) : base(circle)
       {
           this.circle = circle;
           basePoint = circle.Center;
           radius = circle.Radius;
       }

       protected override SamplerStatus Sampler(JigPrompts prompts)
       {
           var options = new JigPromptDistanceOptions($"\n{LocalizedResource.RadiusMessage}: ");
           options.BasePoint = basePoint;
           options.UseBasePoint = true;
           options.Cursor = CursorType.RubberBand;
           options.UserInputControls =
               UserInputControls.Accept3dCoordinates |
               UserInputControls.UseBasePointElevation;
           var result = prompts.AcquireDistance(options);
           if (result.Value == 0.0 || result.Value == radius)
               return SamplerStatus.NoChange;
           radius = result.Value;
           return SamplerStatus.OK;
       }

       protected override bool Update()
       {
           circle.Radius = radius;
           return true;
       }
   }
}

 

La classe ClipJig

using Autodesk.AutoCAD.ApplicationServices.Core;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.GraphicsInterface;
using System.Collections.Generic;

using static ClipDetail.LocalizedResource;

namespace ClipDetail
{
   class ClipJig : DrawJig
   {
       List<Entity> entities;
       Point3d basePoint, dragPoint;
       double scale = 1.0;
       Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;

       public Matrix3d Transform { get; private set; }

       public ClipJig(List<Entity> entities, Point3d basePoint)
       {
           this.entities = entities;
           this.basePoint = basePoint;
       }

       protected override SamplerStatus Sampler(JigPrompts prompts)
       {
           var options = new JigPromptPointOptions($"\n{InsertionMessage}: ");
           options.Keywords.Add(ScaleKeyword);
           options.AppendKeywordsToMessage = true;
           options.Keywords.Default = ScaleKeyword;
           options.BasePoint = basePoint;
           options.UseBasePoint = true;
           options.UserInputControls =
               UserInputControls.Accept3dCoordinates |
               UserInputControls.NullResponseAccepted |
               UserInputControls.UseBasePointElevation;
           var result = prompts.AcquirePoint(options);
           if (result.Status == PromptStatus.Keyword)
           {
               PromptForScale();
               return SamplerStatus.OK;
           }
           if (result.Value.IsEqualTo(dragPoint))
               return SamplerStatus.NoChange;
           dragPoint = result.Value;
           return SamplerStatus.OK;
       }

       protected override bool WorldDraw(WorldDraw draw)
       {
           Transform =
               Matrix3d.Displacement(basePoint.GetVectorTo(dragPoint)) *
               Matrix3d.Scaling(scale, basePoint);
           var geo = draw.Geometry;
           if (geo != null)
           {
               geo.PushModelTransform(Transform);
               foreach (var ent in entities)
               {
                   geo.Draw(ent);
               }
               geo.PopModelTransform();
           }
           return true;
       }

       private void PromptForScale()
       {
           var options = new PromptDoubleOptions($"\n{ScaleMessage}: ");
           options.DefaultValue = scale;
           options.UseDefaultValue = true;
           options.AllowNone = true;
           options.AllowZero = false;
           options.AllowNegative = false;
           var result = ed.GetDouble(options);
           if (result.Status == PromptStatus.OK)
               scale = result.Value;
       }
   }
}

 

La classe EditorExtension

using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using System;

namespace ClipDetail
{
   static class EditorExtension
   {
       public static void Zoom(this Editor ed, Extents3d ext)
       {
           if (ed == null)
               throw new ArgumentNullException(nameof(ed));
           using (ViewTableRecord view = ed.GetCurrentView())
           {
               var worldToEye = Matrix3d.WorldToPlane(view.ViewDirection) *
                   Matrix3d.Displacement(Point3d.Origin - view.Target) *
                   Matrix3d.Rotation(view.ViewTwist, view.ViewDirection, view.Target);
               ext.TransformBy(worldToEye);
               view.Width = ext.MaxPoint.X - ext.MinPoint.X;
               view.Height = ext.MaxPoint.Y - ext.MinPoint.Y;
               view.CenterPoint = new Point2d(
                   (ext.MaxPoint.X + ext.MinPoint.X) / 2.0,
                   (ext.MaxPoint.Y + ext.MinPoint.Y) / 2.0);
               ed.SetCurrentView(view);
           }
       }

       public static PromptSelectionResult SelectTrimmableCurves(this Editor ed, Extents3d extents)
       {
           var filter = new SelectionFilter(new[]
           {
               new TypedValue(-4, "<OR"),
               new TypedValue(0, "ARC,CIRCLE,ELLIPSE,LINE,LWPOLYLINE,RAY,XLINE"),
               new TypedValue(-4, "<AND"),
               new TypedValue(0, "POLYLINE"),
               new TypedValue(-4, "<NOT"),
               new TypedValue(-4, "<OR"),
               new TypedValue(-4, "&="),
               new TypedValue(70, 5),
               new TypedValue(-4, "&"),
               new TypedValue(70, 16 | 32 | 64),
               new TypedValue(-4, "OR>"),
               new TypedValue(-4, "NOT>"),
               new TypedValue(-4, "AND>"),
               new TypedValue(-4, "OR>")
           });
           PromptSelectionResult result;
           using (var view = ed.GetCurrentView())
           {
               ed.Zoom(extents);
               extents.TransformBy(ed.CurrentUserCoordinateSystem.Inverse());
               result = ed.SelectCrossingWindow(extents.MinPoint, extents.MaxPoint, filter);
               ed.SetCurrentView(view);
           }
           return result;
       }
   }
}

 

Les messages d'invite et mots clés sont définis dans le fichier de ressources LocalizedResource.fr.resx pour faciliter la localisation.

CenterMessage	        Spécifiez le centre du cercle	
InsertionMessage	Spécifiez le point d'insertion	
RadiusMessage	        Spécifiez le rayon du cercle	
ScaleKeyword	        Echelle	
ScaleMessage	        Spécifiez le facteur d'échelle	

Gilles Chanteau - gileCAD -
Développements sur mesure pour AutoCAD
ADSK_Expert_Elite_Icon_S_Color_Blk_125.png

Lien vers le commentaire
Partager sur d’autres sites

Bonjour,

 

Je ne voudrais pas être rabat-joie, mes tes applications en Net ne sont souvent accessible que pour ceux qui sont administrateur de leur poste. Dès qu'on est en entreprise, plus moyen de profiter de quoi que ce soit. Bien sur on peut demander aux admins, mais ils sont souvent réticents à tout plug-in installé en admin, ou alors il faut palabrer des heures pour dire que c'est inoffensif.

 

Donc ça doit être très bien, mais je ne peux en juger...

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

Lien vers le commentaire
Partager sur d’autres sites

Re,

 

Salut Gilles,

 

Merci, je suis content que tu apprécies.

 

Par exemple :

 

En Topographie : Zoom sur la position d'une borne, zoom sur le point d'une station, etc,..

En Travaux Publics : Plein de détail dans tous les sens !!

En bâtiment : En exe, tous les détails de réalisation (je vous laisse imaginer,..)

Etc,..

 

Et comme dis plus haut, tous les métiers vont s'y retrouver.

 

Surtout, ce qui m'impressionne chez toi (en plus de ton grand sens du partage , bien entendu !) c'est le plaisir de partager quelque chose que tu viens toi même de découvrir et que tu t'empresse dans faire profiter la communauté. Je ne parle pas non plus de l'idée de base de l'utilité du programme ainsi créé. Perso, je ne l'avais même pas imaginer alors que je m'en sers au quotidien dans l'espace papier.

 

A ce propos, ce programme pourrait aussi fonctionner en espace papier ?

 

Je ne sais pas si ma question est pertinente, mais perso, je fais très souvent des fenêtres de détail dans les espaces papiers, en fonction des besoins du plan et du destinataire,..

 

Merci d'avance de ta réponse,

Civil 3D 2024 - COVADIS_18.2

https://www.linkedin...3%ABt-95313341/

Lien vers le commentaire
Partager sur d’autres sites

Pour bonuscad et tous ceux qui ont des autorisations restreintes mais me font confiance et voudraient essayer en cachette de leur chef:


     
  • Télécharger ClipDetail.zip.
  • Débloquer le ZIP (clic droit > Propriétés > onglet Général > Débloquer)
  • Extraire le contenu (ClipDetail.dll et dossier fr) dans un même dossier (pour avoir l'interface en français)
  • Charger la DLL depuis AutoCAD avec la commande NETLOAD.

 

lili2006,

en espace objet papier, je pense qu'il est (beaucoup) plus pertinent d'utiliser des fenêtre et des échelles.

Gilles Chanteau - gileCAD -
Développements sur mesure pour AutoCAD
ADSK_Expert_Elite_Icon_S_Color_Blk_125.png

Lien vers le commentaire
Partager sur d’autres sites

Re,

 

Du coup, avec cet outil, oui mais avant pas possible !!

 

C'est surtout que dans l'espace papier, selon le destinataire du plan (plombier, électricien, maçon, ...), je n'affiche pas les mêmes détails, donc, il faudrait que je gère le calque de destination au lancement du prog pour pouvoir jouer les affichages en EP, ce qui n'est pas un problème en le lançant depuis une palette d'outils ou encore un bouton radio avec la macro qui va bien, ..

Civil 3D 2024 - COVADIS_18.2

https://www.linkedin...3%ABt-95313341/

Lien vers le commentaire
Partager sur d’autres sites

Après un test, avec les dll c'est OK sous Map2014.

 

J'ai déjà eu besoin de ce style de détail que je faisais alors avec des fmult polygonale en espace papier: c'est bien aussi mais un peu plus pénible à mettre en place.

 

Là c'est beaucoup plus rapide, mais il faut surveiller la géométrie originale qui pourrait changer et ne pas oublier de refaire le détail.

 

J'aurai bien soumis l'idée des MPOLYGON, mais comme elles sont proches des entités HATCH qui ne sont pas incluses, j'ai peur que mon souhait ne soit pas réalisable.

 

Mais je garde ce dll sous le coude, il est fort probable qu'il puisse me servir.

 

Merci pour le partage.

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

Lien vers le commentaire
Partager sur d’autres sites

Salut Gile,

ce plug-in pourra me servir lorsque je fais de petits détails de construction mécanique

même si le principe reste dangereux:

Là c'est beaucoup plus rapide, mais il faut surveiller la géométrie originale qui pourrait changer et ne pas oublier de refaire le détail.

Pour en faire un utilitaire "trop génial", il faudrait:

- créer une entrée de dictionnaire qui garde en mémoire

o la zone du détail

o la liste des entités base du détail

- créer un réacteur persistant entre les entités base et l'entrée de dictionnaire

- qui régénère (ou non) le détail lorsque les entités de base sont modifiées

 

mais bon, je reconnais que c'est un peut réinventer la modélisation, ce n'est pas ton propos.

 

par contre,comme tu as laissé le code, je risque bien de m'en servir pour générer automatiquement des détails de chambre de vanne.

 

merci !

Gégé

----------------------------------------------------------------------

Site: https://www.g-eaux.fr

Blog: http://g-eaux.over-blog.com

Lien vers le commentaire
Partager sur d’autres sites

En 2004, je me souviens d'un gars, sur le swamp, qui avait publié une dll fantastique pour mon usage. Le gars l'avait fournie en déclarant qu'il l'avait faite "hier soir" B)

Elle prenait des objets 3D et créait en 2 coups de cuillère à pot, une vue terrible de mes objets, rabattues, bien aplanie, une sorte d'ancêtre du plutôt mauvais APLANIRGEOM. Offerte juste parce que je parlais de mes batailles de l'époque. Que les buggeuses vues de base (sur 2016 pour moi) obligent encore à livrer d'ailleurs.

J'ai pu l'utiliser pendant plusieurs versions, un régal.

 

DETAIL, je peux aussi en avoir besoin un jour. Malheureusement mes dessins sont souvent bourrés de blocs et de blocs imbriqués, et ton outil ne les prendra pas dans cette version, et pour cause (dépasser-pas ou pas dépasser, déjà). Mais c'est une excellente idée.

 

On a vraiment accès à des outils dingues avec ces types de développement.

Bureau d'études dessin.

Spécialiste Escaliers

Développement - Formation

 

./__\.
(.°=°.)
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é