Aller au contenu

[Résolu] Yin Yang


didier

Messages recommandés

Coucou

 

Ça y est j'ai écrit mon premier "programme" avec C#

Il est certain que c'est perfectible aussi je vous le soumets pour critique et évolution car j'ai des questions :

Pour mémoire le but est de dessiner ceci :

06-10-16 14-46-01.png

Actuellement avec le code qui suit j'en suis là :

06-10-16 14-47-01.png

 

Le code est le suivant :



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using AcAp = Autodesk.AutoCAD.ApplicationServices.Application;

namespace yin_yang
{
public class Class1
{
   	[CommandMethod("Yin_Yang")]
   	public void Test()
   	{
       	Document doc = AcAp.DocumentManager.MdiActiveDocument;
       	Database db = doc.Database;
       	Editor ed = doc.Editor;

       	using (Transaction transac = db.TransactionManager.StartTransaction())
       	{
           	BlockTable bktb = transac.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
           	BlockTableRecord bkTbRc = transac.GetObject(bktb[blockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
           	PromptPointOptions ppo = new PromptPointOptions("\nCentre du Cercle : ");//ppo pour PromptPointOptions
           	PromptPointResult ppr = ed.GetPoint(ppo);//ppr pour PromptPointResult
           	if (ppr.Status == PromptStatus.OK)
           	{
               	Point3d p1 = ppr.Value;
               	ppo.Message = "\nRayon du cercle englobant : ";
               	ppo.BasePoint = p1;
               	ppo.UseBasePoint = true;
               	ppr = ed.GetPoint(ppo);

               	if (ppr.Status == PromptStatus.OK)
               	{
                   	Point3d p2 = ppr.Value;
                   	double rayon = p1.DistanceTo(p2);
                   	Point3d center = p1;
                   	
                   	//////////////// la polyligne courbe etérieure verticale                    	
                   	Polyline acPoly = new Polyline();
                   	acPoly.SetDatabaseDefaults();
                   	acPoly.AddVertexAt(0, new Point2d(p1.X, p1.Y + rayon), 0, 0, 0);
                   	acPoly.AddVertexAt(1, new Point2d(p1.X, p1.Y - rayon), 0, 0, 0);
                   	//acPoly.AddVertexAt(2, new Point2d(p1.X, p1.Y - rayon), 0, 0, 0);
                   	acPoly.TransformBy(ed.CurrentUserCoordinateSystem);//coordonnées de la polyligne dans le scu courant

                   	acPoly.SetBulgeAt(0, -1);//bulge sur le premier vertex, bulge 1 est un demi-cercle
                   	
                   	bkTbRc.AppendEntity(acPoly);//ajout de la polyligne dans la base
                   	transac.AddNewlyCreatedDBObject(acPoly, true);
                   	/////////////////////
                   	Polyline acPoly2 = new Polyline();
                   	acPoly2.SetDatabaseDefaults();
                   	acPoly2.AddVertexAt(0, new Point2d(p1.X, p1.Y + rayon), 0, 0, 0);
                   	acPoly2.AddVertexAt(1, new Point2d(p1.X, p1.Y - rayon), 0, 0, 0);
                   	//acPoly.AddVertexAt(2, new Point2d(p1.X, p1.Y - rayon), 0, 0, 0);
                   	acPoly2.TransformBy(ed.CurrentUserCoordinateSystem);//coordonnées de la polyligne dans le scu courant

                   	acPoly2.SetBulgeAt(0, 1);//bulge sur le premier vertex, bulge 1 est un demi-cercle
                   	
                   	bkTbRc.AppendEntity(acPoly2);//ajout de la polyligne dans la base
                   	transac.AddNewlyCreatedDBObject(acPoly2, true);
                   	/////////////////////

                   	Point3d centre_cercle_haut = new Point3d(p1.X, (p1.Y + (rayon / 2)),0);
                   	double rayon_cercle_haut = rayon / 4;
                   	Vector3d normal = new Vector3d(0.0, 0.0, 1.0);

                   	using (Circle cercle_haut = new Circle(centre_cercle_haut, normal, rayon_cercle_haut))
                   	{
                       	cercle_haut.TransformBy(ed.CurrentUserCoordinateSystem);//coordonnées du cercle dans le scu courant
                       	bkTbRc.AppendEntity(cercle_haut);
                       	transac.AddNewlyCreatedDBObject(cercle_haut, true);
                   	}

                   	Point3d centre_cercle_bas = new Point3d(p1.X, (p1.Y - (rayon / 2)), 0);
                   	double rayon_cercle_bas = rayon / 4;

                   	//using (Circle cercle_bas = new Circle(centre_cercle_bas, normal, rayon_cercle_bas))
                   	//{
                   	Circle cercle_bas = new Circle(centre_cercle_bas, normal, rayon_cercle_bas);
                       	cercle_bas.TransformBy(ed.CurrentUserCoordinateSystem);//coordonnées du cercle dans le scu courant
                       	bkTbRc.AppendEntity(cercle_bas);
                       	transac.AddNewlyCreatedDBObject(cercle_bas, true);
                   	//}
                   	
                   	//////////////// la polyligne courbe centrale verticale                    	
                   	Polyline acPoly3 = new Polyline();
                   	acPoly3.SetDatabaseDefaults();
                   	acPoly3.AddVertexAt(0, new Point2d(p1.X, p1.Y + rayon), 0, 0, 0);
                   	acPoly3.AddVertexAt(1, new Point2d(p1.X, p1.Y), 0, 0, 0);
                   	acPoly3.AddVertexAt(2, new Point2d(p1.X, p1.Y - rayon), 0, 0, 0);
                   	acPoly3.TransformBy(ed.CurrentUserCoordinateSystem);//coordonnées de la polyligne dans le scu courant

                   	acPoly3.SetBulgeAt(0, -1);//bulge sur le premier vertex, bulge 1 est un demi-cercle
                   	acPoly3.SetBulgeAt(1, 1);//bulge sur le deuxième vertex, bulge 1 est un demi-cercle
                   	
                   	bkTbRc.AppendEntity(acPoly3);//ajout de la polyligne dans la base
                   	transac.AddNewlyCreatedDBObject(acPoly3, true);
                   	///////////////////////////////////////

                   	//ObjectIdCollection acObjIdColl = new ObjectIdCollection();
                   	//acObjIdColl.Add(acPoly.ObjectId);
                   	//acObjIdColl.Add(acPoly3.ObjectId);
                   	//acObjIdColl.Add(cercle_bas.ObjectId);
                   	
                   	//Hatch acHatch = new Hatch();
                   	//bkTbRc.AppendEntity(acHatch);
                   	//transac.AddNewlyCreatedDBObject(acHatch, true);

                   	//acHatch.SetDatabaseDefaults();
                   	//acHatch.SetHatchPattern(HatchPatternType.PreDefined, "SOLID");
                   	////acHatch.Associative = true;
                   	//acHatch.AppendLoop(HatchLoopTypes.Outermost, acObjIdColl);
                   	//acHatch.EvaluateHatch(true);
               	}
           	}
           	transac.Commit();
           	ed.Command("_zoom", "_extents");
           	ed.Command("zoom", "0.75xp");
       	}
   	}
}
}





 

Les questions maintenant :

Quelle différence entre le dessin des cercles (je pense que c'est valable pour toute entité)

Faut-il commencer par :

using (Circle cercle_haut = new Circle(centre_cercle_haut, normal, rayon_cercle_haut)) { ... }

ou

Circle cercle_bas = new Circle(centre_cercle_bas, normal, rayon_cercle_bas); ...;

 

Ensuite vous remarquez que les hachures sont en commentaires

C'est parce-que dès que j'ajoute "cercle_bas" dans la collection acObjIdColl

Ça plante

J'arrive à hachurer si je ne mets pas cercle_bas dans la collection.

 

Je remercie celles et ceux qui vont regarder ce message et me répondre

 

Ouah !!! je fais du C#, je vais devenir un grand garçon (ça y est ma mégalo reprend le dessus, calmez-moi)

 

Amicalement

Lien vers le commentaire
Partager sur d’autres sites

Peut-être avec "acHatch.HatchStyle.Normal"

 

Mais mes connaissances en C# sont bien moindre que les tiennes...

Windows 11 / AutoCAD 2024

Sur terre, il y a 10 types de personnes, celles qui comptent en binaire et les autres (developpez.net).
Davantage d'avantages, avantagent davantage (Bobby Lapointe).
La connaissance s'accroît quand on la partage (Socrate).
Tant va la cruche à l'eau que l'habit n'amasse pas mousse avant de l'avoir tué. (Moi)

Lien vers le commentaire
Partager sur d’autres sites

Coucou

 

J'explique le principe car tout le monde n'est pas dans ma tête (quoiqu'il y en ait du monde dans cette caboche !!!)

 

Je dessine une polyligne verticale

Je lui affecte un bulge de -1, ce qui en fait un demi-cercle vertical

Je dessine une polyligne verticale

Je lui affecte un bulge de 1, ce qui en fait un demi-cercle vertical(dans l'autre sens)

Les deux forment un cercle en apparence

 

Je dessine une polyligne verticale qui part du point de départ de la première

Qui passe par le "centre" du cercle

Et va au point "quadrant" du cercle (celui du sud)

Je lui affecte un bulge de -1 sur le vertex 0, ce qui en fait un demi-cercle vertical

Je lui affecte un bulge de 1 sur le vertex 0, ce qui en fait un demi-cercle vertical (dans l'autre sens)

 

Ensuite je dessine deux petits cercles, eux sont bien des entités "circle"

 

J'ajoute la poly 1 la poly2 et le cercle du bas à la collection

Puis je créée une hachure avec cette sélection

C'est actuellement ici que le bât blesse

 

Amicalement

Lien vers le commentaire
Partager sur d’autres sites

Coucou

 

tu as complètement raison Olivier et je te remercie de ta réponse

ceci est confirmé et expliqué sur ce site

 

je suivais une logique "AutoCAD" et je créais une collection de tous les objets pour imiter les hachures

en fait il faut hachurer l'extérieur

puis en retirer l'intérieur

ce n'est pas plus illogique mais il faut le savoir.

 

j'en suis donc arrivé à ce résultat :

 

et je ne voulais pas lâcher l'affaire sans réussite, j'y suis arrivé grâce à votre aide, merci.

 

 

avec ce code :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using AcAp = Autodesk.AutoCAD.ApplicationServices.Application;

namespace yin_yang
{
public class Class1
{
   	[CommandMethod("Yin_Yang")]
   	public void Test()
   	{
       	Document doc = AcAp.DocumentManager.MdiActiveDocument;
       	Database db = doc.Database;
       	Editor ed = doc.Editor;

       	using (Transaction transac = db.TransactionManager.StartTransaction())
       	{
           	BlockTable bktb = transac.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
           	BlockTableRecord bkTbRc =  transac.GetObject(bktb[blockTableRecord.ModelSpace], OpenMode.ForWrite)  as BlockTableRecord;
           	PromptPointOptions ppo = new PromptPointOptions("\nCentre du Cercle : ");//ppo pour PromptPointOptions
           	PromptPointResult ppr = ed.GetPoint(ppo);//ppr pour PromptPointResult
           	if (ppr.Status == PromptStatus.OK)
           	{
               	Point3d p1 = ppr.Value;
               	ppo.Message = "\nRayon du cercle englobant : ";
               	ppo.BasePoint = p1;
               	ppo.UseBasePoint = true;
               	ppr = ed.GetPoint(ppo);

               	if (ppr.Status == PromptStatus.OK)
               	{
                   	Point3d p2 = ppr.Value;
                   	double rayon = p1.DistanceTo(p2);
                   	Point3d center = p1;
                   	
                   	//////////////// la polyligne courbe à droite extérieure verticale                    	
                   	Polyline acPoly = new Polyline();
                   	acPoly.SetDatabaseDefaults();
                   	acPoly.AddVertexAt(0, new Point2d(p1.X, p1.Y + rayon), 0, 0, 0);
                   	acPoly.AddVertexAt(1, new Point2d(p1.X, p1.Y - rayon), 0, 0, 0);
                   	acPoly.TransformBy(ed.CurrentUserCoordinateSystem);//coordonnées de la polyligne dans le scu courant
                   	acPoly.SetBulgeAt(0, -1);//bulge sur le premier vertex, bulge 1 est un demi-cercle
                   	//acPoly.ColorIndex = 1; passe la polyligne en rouge pour repérage                    	
                   	bkTbRc.AppendEntity(acPoly);//ajout de la polyligne dans la base
                   	transac.AddNewlyCreatedDBObject(acPoly, true);
                   	////fin de la polyligne courbe à droite extérieure verticale

                   	////début de la polyligne courbe à gauche extérieure verticale
                   	Polyline acPoly2 = new Polyline();
                   	acPoly2.SetDatabaseDefaults();
                   	acPoly2.AddVertexAt(0, new Point2d(p1.X, p1.Y + rayon), 0, 0, 0);
                   	acPoly2.AddVertexAt(1, new Point2d(p1.X, p1.Y - rayon), 0, 0, 0);
                   	acPoly2.TransformBy(ed.CurrentUserCoordinateSystem);//coordonnées de la polyligne dans le scu courant
                   	acPoly2.SetBulgeAt(0, 1);//bulge sur le premier vertex, bulge 1 est un demi-cercle
                   	bkTbRc.AppendEntity(acPoly2);//ajout de la polyligne dans la base
                   	transac.AddNewlyCreatedDBObject(acPoly2, true);
                   	////fin de la polyligne courbe à gauche extérieure verticale

                   	Point3d centre_cercle_haut = new Point3d(p1.X, (p1.Y + (rayon / 2)),0);
                   	double rayon_cercle_haut = rayon / 4;
                   	Vector3d normal = new Vector3d(0.0, 0.0, 1.0);

                   	using (Circle cercle_haut = new Circle(centre_cercle_haut, normal, rayon_cercle_haut))
                   	{
                       	cercle_haut.TransformBy(ed.CurrentUserCoordinateSystem);//coordonnées du cercle dans le scu courant
                       	bkTbRc.AppendEntity(cercle_haut);
                       	transac.AddNewlyCreatedDBObject(cercle_haut, true);
                   	}

                   	Point3d centre_cercle_bas = new Point3d(p1.X, (p1.Y - (rayon / 2)), 0);
                   	double rayon_cercle_bas = rayon / 4;

                   	//using (Circle cercle_bas = new Circle(centre_cercle_bas, normal, rayon_cercle_bas))
                   	//{
                   	Circle cercle_bas = new Circle(centre_cercle_bas, normal, rayon_cercle_bas);
                       	cercle_bas.TransformBy(ed.CurrentUserCoordinateSystem);//coordonnées du cercle dans le scu courant
                       	bkTbRc.AppendEntity(cercle_bas);
                       	transac.AddNewlyCreatedDBObject(cercle_bas, true);
                   	cercle_bas.ColorIndex = 1;
                   	//}

                   	//////////////// la polyligne courbe centrale verticale                    	
                   	Polyline acPoly3 = new Polyline();
                   	acPoly3.SetDatabaseDefaults();
                   	acPoly3.AddVertexAt(0, new Point2d(p1.X, p1.Y + rayon), 0, 0, 0);
                   	acPoly3.AddVertexAt(1, new Point2d(p1.X, p1.Y), 0, 0, 0);
                   	acPoly3.AddVertexAt(2, new Point2d(p1.X, p1.Y - rayon), 0, 0, 0);
                   	acPoly3.TransformBy(ed.CurrentUserCoordinateSystem);//coordonnées de la polyligne dans le scu courant

                   	acPoly3.SetBulgeAt(0, -1);//bulge sur le premier vertex, bulge 1 est un demi-cercle
                   	acPoly3.SetBulgeAt(1, 1);//bulge sur le deuxième vertex, bulge 1 est un demi-cercle
                   	acPoly3.ColorIndex = 1;

                   	bkTbRc.AppendEntity(acPoly3);//ajout de la polyligne dans la base
                   	transac.AddNewlyCreatedDBObject(acPoly3, true);
                   	
                   	//////dessin des hachures
                   	ObjectIdCollection acObjIdColl = new ObjectIdCollection();
                   	////acObjIdColl.Add(cercle_bas.ObjectId);
                   	acObjIdColl.Add(acPoly.ObjectId);
                   	acObjIdColl.Add(acPoly3.ObjectId);

                   	// Create the hatch object and append it to the block table record
                   	Hatch acHatch = new Hatch();
                   	bkTbRc.AppendEntity(acHatch);
                   	transac.AddNewlyCreatedDBObject(acHatch, true);


                   	//// Set the properties of the hatch object
                   	//// Associative must be set after the hatch object is appended to the 
                   	//// block table record and before AppendLoop
                   	acHatch.SetDatabaseDefaults();
                   	acHatch.SetHatchPattern(HatchPatternType.PreDefined, "SOLID");
                   	acHatch.Associative = true;

                   	// Add the outer boundary
                   	acHatch.AppendLoop(HatchLoopTypes.External, acObjIdColl);

                   	// Add the inner boundary
                   	acHatch.AppendLoop(HatchLoopTypes.Default, new ObjectIdCollection { cercle_bas.ObjectId });


                   	/////acHatch.AppendLoop(HatchLoopTypes.Outermost, acObjIdColl);
                   	acHatch.EvaluateHatch(true);


               	}
           	}
           	transac.Commit();
           	ed.Command("_zoom", "_extents");
           	ed.Command("zoom", "0.75xp");
       	}
   	}
}
}

 

 

je continue ...

 

Amicalement

Lien vers le commentaire
Partager sur d’autres sites

Salut didier,

 

Je suis très content que tu aies réussi à faire ça (et je sais que tu as tapé le moindre point virgule).

 

Le YinYang est un bon exercice, j'en avais fait toute une série en LISP du plus simple avec des (command ...) au plus sophistiqué avec grread.

 

J'ai essayé de refaire un peu la même chose avec C# (ça fait des exemples).

 

Depuis AutoCAD 2015, on peut utiliser la méthode Editor.Command() qui fonctionne un peu comme la fonction LISP command.

 

using Autodesk.AutoCAD.ApplicationServices.Core;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;

namespace YinYangSample
{
   public class YinYangCommand1
   {
       [CommandMethod("YY1")]   
       public void YinYangCmd()
       {
           // l'éditeur du document actif
           Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;

           // invite à spécifier le centre
           PromptPointResult ppr = ed.GetPoint("\nCentre du cercle: ");
           if (ppr.Status != PromptStatus.OK) return;
           Point3d center = ppr.Value;

           // invite à spécifier le rayon
           PromptDistanceOptions pdo = new PromptDistanceOptions("\nRayon du cercle: ");
           pdo.BasePoint = center;
           pdo.UseBasePoint = true;
           PromptDoubleResult pdr = ed.GetDistance(pdo);
           if (pdr.Status != PromptStatus.OK) return;
           double radius = pdr.Value;

           // calculs des points
           Point3d p1 = new Point3d(center.X, center.Y + radius, 0);
           Point3d p2 = new Point3d(center.X, center.Y - radius, 0);
           Point3d p3 = new Point3d(center.X + 0.5 * radius, center.Y, 0);
           Point3d c1 = new Point3d(center.X, center.Y + radius * 0.5, 0);
           Point3d c2 = new Point3d(center.X, center.Y - radius* 0.5, 0);

           // appels de commandes
           ed.Command("_.pline", p1, "_arc", "_direction", "@1,0,0", center, p2, p1, p2, "");
           ed.Command("_.circle", c1, radius * 0.25);
           ed.Command("_.circle", c2, radius * 0.25);
           ed.Command("_bhatch", "_properties", "SOLID", p3, c1, "");
       }
   }
}

 

Avec .NET pour afficher dynamiquement les modifications d'une ou plusieurs entités en fonction de la position du curseur, on utilise des"jigs", il s'agit des classes qui dérivent de EntityJig (une seule entité) ou de DrawJig (plusieurs entités) qu'on définit selon les besoins.

Ici, il s'agit de remplacer la ligne élastique utilisée dans l'invite pour spécifier rayon par un affichage dynamique de toute la géométrie (moins les hachures).

 

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.Runtime;
using AcDb = Autodesk.AutoCAD.DatabaseServices;

namespace YinYangSample
{
   public class YinYangCommand2
   {
       [CommandMethod("YY2")]
       public void YinYangCmd()
       {
           var doc = Application.DocumentManager.MdiActiveDocument;
           var db = doc.Database;
           var ed = doc.Editor;

           // in vite à spécifier le centre
           var ptRes = ed.GetPoint("\nCentre du cercle: ");
           if (ptRes.Status != PromptStatus.OK) return;
           var center = ptRes.Value;

           using (var tr = db.TransactionManager.StartTransaction())
           {
               // création des polylignes et des cercles pour un symbole de rayon = 1
               using (var pline1 = new AcDb.Polyline())
               using (var pline2 = new AcDb.Polyline())
               using (var circle1 = new Circle())
               using (var circle2 = new Circle())
               {
                   // ajout des sommets et bulges à la première polyligne
                   pline1.AddVertexAt(0, new Point2d(center.X, center.Y + 1.0), -1.0, 0.0, 0.0);
                   pline1.AddVertexAt(1, new Point2d(center.X, center.Y), 1.0, 0.0, 0.0);
                   pline1.AddVertexAt(2, new Point2d(center.X, center.Y - 1.0), 1.0, 0.0, 0.0);
                   pline1.AddVertexAt(3, new Point2d(center.X, center.Y + 1.0), 1.0, 0.0, 0.0);

                   // ajout des sommets et bulges à la deuxième polyligne
                   pline2.AddVertexAt(0, new Point2d(center.X, center.Y + 1.0), 1.0, 0.0, 0.0);
                   pline2.AddVertexAt(1, new Point2d(center.X, center.Y - 1.0), 1.0, 0.0, 0.0);

                   // cercle haut
                   circle1.Center = new Point3d(center.X, center.Y + 0.5, 0.0);
                   circle1.Radius = 0.2;

                   // cercle bas
                   circle2.Center = new Point3d(center.X, center.Y - 0.5, 0.0);
                   circle2.Radius = 0.2;

                   Entity[] entities = { pline1, pline2, circle1, circle2 };

                   // création d'une instance de YinYangJig
                   var jig = new YinYangJig(entities, center);
                   // utilisation du jig pour l'invite à spécifier le rayon
                   var pr = ed.Drag(jig);

                   // si l'utilisateur n'a pas fait annulé
                   if (pr.Status == PromptStatus.OK)
                   {
                       // ajout des entités à l'espace courant et mise à l'échelle en fonction de rayon spécifié
                       var space = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                       foreach (var ent in entities)
                       {
                           ent.TransformBy(jig.Scale);
                           space.AppendEntity(ent);
                           tr.AddNewlyCreatedDBObject(ent, true);
                       }

                       // ajout des hachures
                       var hatch1 = new Hatch();
                       space.AppendEntity(hatch1);
                       tr.AddNewlyCreatedDBObject(hatch1, true);
                       hatch1.Associative = true;
                       hatch1.SetHatchPattern(HatchPatternType.PreDefined, "SOLID");
                       hatch1.AppendLoop(HatchLoopTypes.Outermost, new ObjectIdCollection { pline1.ObjectId });
                       hatch1.AppendLoop(HatchLoopTypes.Default, new ObjectIdCollection { circle2.ObjectId });
                       hatch1.EvaluateHatch(false);

                       var hatch2 = new Hatch();
                       space.AppendEntity(hatch2);
                       tr.AddNewlyCreatedDBObject(hatch2, true);
                       hatch2.Associative = true;
                       hatch2.SetHatchPattern(HatchPatternType.PreDefined, "SOLID");
                       hatch2.AppendLoop(HatchLoopTypes.Outermost, new ObjectIdCollection { circle1.ObjectId });
                       hatch1.EvaluateHatch(false);
                   }
               }
               tr.Commit();
           }
       }

       // classe pour mettre dynamiquement la géométrie à l'échelle en fonction de la position du curseur
       class YinYangJig : DrawJig
       {
           // champs privés
           Entity[] entities;
           Point3d center;
           double radius;

           // propriété : matrice de transformation de la mise à l'échelle
           public Matrix3d Scale { get; private set; }

           // constructeur : initialisation des champs privés en fonction des paramètres
           public YinYangJig(Entity[] entities, Point3d center)
           {
               this.entities = entities;
               this.center = center;
           }

           // substitution de la méthode de la classe de base : 
           // invite à spécifier le rayon
           protected override SamplerStatus Sampler(JigPrompts prompts)
           {
               // options de l'invite
               var opts = new JigPromptDistanceOptions("\nRayon du cercle: ");
               opts.BasePoint = center;
               opts.UseBasePoint = true;
               opts.UserInputControls = UserInputControls.Accept3dCoordinates;

               // résultat de l'invite
               var result = prompts.AcquireDistance(opts);
               // si le curseur n'a pas bougé
               if (result.Value == radius)
                   return SamplerStatus.NoChange;
               // s'il a bougé : mise à jour du champ radius et de la matrice de mise à l'échelle
               radius = result.Value;
               Scale = Matrix3d.Scaling(radius, center);
               return SamplerStatus.OK;
           }

           // substitution de la méthode de la classe de base : 
           // re-dessine la géométrie en fonction de la valeur actuelle de la matrice
           protected override bool WorldDraw(WorldDraw draw)
           {
               var geometry = draw.Geometry;
               if (geometry != null)
               {
                   geometry.PushModelTransform(Scale);
                   foreach (var entity in entities) geometry.Draw(entity);
                   geometry.PopModelTransform();
               }
               return true;
           }
       }
   }
}

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

Lien vers le commentaire
Partager sur d’autres sites

Re,

 

Quelle différence entre le dessin des cercles (je pense que c'est valable pour toute entité)

Faut-il commencer par :

using (Circle cercle_haut = new Circle(centre_cercle_haut, normal, rayon_cercle_haut)) { ... }

ou

Circle cercle_bas = new Circle(centre_cercle_bas, normal, rayon_cercle_bas); ...;

Le code ci dessus illustre ça.

Une instruction using est un moyen simple de garantir que la méthode Dispose() (pour la libération des ressources) soit bien appelée sur les objets auxquels elle s'applique à la fin du bloc de code (même si une exception en interrompait l'exécution).

 

Dans l'API AutoCAD, nombre d'objets sont des enveloppes (wrappers) d'objets "non-managés", c'est le cas de tous les objets résidents de la base de données (entités, tables, dictionnaires), et doivent impérativement être explicitement libérés avec Dispose() ou une instruction using.

 

Donc quand le programme crée une nouvelle entité avec new Circle() par exemple, il est responsable d'en libérer les ressources avec Dispose().

 

L'utilisation d'une transaction permet de déléguer cette tache à la transaction à condition que les objets aient été ajoutés à la transaction (AddNewlyCreatedObject) ou aient été ouverts par elle.

 

            using (var tr = db.TransactionManager.StartTransaction())
           {
               var space = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
               var circle = new Circle(Point3d.Origin, Vector3d.ZAxis, 10.0);

               // il pourrait se passer des choses ici...

               space.AppendEntity(circle);
               tr.AddNewlyCreatedDBObject(circle, true);

               tr.Commit(); // <- enregistrement des modifications (ajout du cercle)

           } // <- libération des ressources de la transaction, de l'espace courant et du cercle.

 

Dans l'exemple ci-dessus, si une exception intervient entre le moment où le cercle a été créé avec new Circle() et le moment où il aurait été ajouté à la transaction, ses ressources ne seront pas libérées avec celles de la transaction (et celle de l'espace courant).

Ceci peut provoquer une erreur fatale dans AutoCAD dans un laps de temps imprévisible.

C'est pour ça qu'il est plus prudent (ou nécessaire comme dans le 2ème exemple du message précédent) d'utiliser une instruction using quand on crée de nouveaux objets qui implémentent IDispoable.

 

                using (var circle = new Circle(Point3d.Origin, Vector3d.ZAxis, 10.0))
               {
                   if (condition)
                   {
                       var space = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                       space.AppendEntity(circle);
                       tr.AddNewlyCreatedDBObject(circle, true);
                   }
                   else
                   {
                       // si condition == false, le cercle n'est pas ajouté à la transaction
                   }
               } // <- libération des ressources du cercle.

               tr.Commit();

           } // <- libération des ressources de la transaction et de l'espace courant.

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

Lien vers le commentaire
Partager sur d’autres sites

Coucou

 

Gilles,

 

Je te remercie de tes félicitations qui sont des encouragements

Ton YY2 est superbe, quand je serai grand c'est comme ça que je veux faire

Mais il n'est pas question de bruler les étapes, je dois encore travailler en application console pour comprendre quelques subtilités et quelques cas particuliers plus ou moins sombres que je dois mettre en pleine lumière.

J'ai fait ça dans AutoCAD car je n'ai pas pu résister à l'envie de me frotter au dessin.

Je vais aussi regarder du côté des "forms" qui doivent être, à mes yeux, une alternative au DCL.

J'ai aussi des idées de programmes à tester dans le dessin (des dizaines).

Je vais sans doute reprendre ce que j'ai "bien fait" en lisp dans un premier temps.

Je te tiens et je vous tiens au courant des évolutions, car évolution il y aura.

 

J'ai noté aussi ta clarification sur l'utilisation de using et si j'ai bien compris c'est la bonne méthode

du moins la méthode qui si elle allonge le code le rend plus stable, c'est que je veux dire par "bonne méthode".

Il ne faut pas toujours se contenter d'un truc "qui marche" il faut faire un truc qui marche "toujours".

 

À bientôt pour de nouvelles aventures et encore merci à Olivier qui m'a remis sur la bonne voie avec mes hachures récalcitrantes..

 

 

Amicalement

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é