📜 ⬆️ ⬇️

Creating plug-ins for AutoCAD using the .NET API (part 6 - finding and changing objects in a drawing)

This is the sixth part of the cycle about the development of plug-ins for AutoCAD. In her talk about finding objects in the drawing, as well as about their change.

public static string disclaimer = "          AutoCAD.   –      ."; 


Introduction


In the first part of the article we will look at the search for objects in the drawing, in the second - we will briefly discuss their change. However, before we start examining these questions, let's prepare a test case framework that we will use throughout the paper.
')
The example will be simple, but rather voluminous. We will create two layers with the names “layer-1” and “layer-2” (in total, together with the zero layer, which is in each drawing, we get three layers). We will also add two block definitions with the names “block-1” (it will consist of a circle, a line and a polyline) and “block-2” (it will consist of a circle and two lines). After that, put on the drawing several graphic objects:

Well, for complete happiness, we will paint the whole thing in pink, blue and lime colors.

Nb:
The choice of not too standard colors is due to the fact that preparing code samples for articles is a mortal longing, and I want to at least somehow revive this process.
Having painted the first lines, I suddenly remembered the Rainbow flag and even thought about inserting it into the article ...
But secondly, I do not support this movement so much, and firstly, the flag is much more complicated than the three lines. Well, it nafig.

The code implementing this action plan is shown below. All the operations performed: the creation of layers and definitions of the block, the insertion of text, graphic primitives and the occurrences of the block - we have already considered in previous articles of the cycle. The only thing that has not been considered yet is the task of the layer and color for the drawing object, but it takes literally one line of code and, I hope, will not cause difficulties.

So, create a project, perform the initial setup (specify the .NET version, disable CopyLocal ) and connect the already familiar AcMgd and AcDbMgd libraries . Next, we put there the functions that create the objects for our example.

Code:
 using System; using System.Collections.Generic; using Autodesk.AutoCAD.Runtime; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.EditorInput; using acad = Autodesk.AutoCAD.ApplicationServices.Application; namespace HabrPlug_SearchAndRescue { public class ClassMyAutoCADDLL_SearchAndRescue { public class Commands : IExtensionApplication { //   Autodesk.AutoCAD.Colors.Color color_Pink = Autodesk.AutoCAD.Colors.Color.FromRgb(255, 128, 255); Autodesk.AutoCAD.Colors.Color color_Blue = Autodesk.AutoCAD.Colors.Color.FromRgb(0, 200, 255); Autodesk.AutoCAD.Colors.Color color_LightGreen = Autodesk.AutoCAD.Colors.Color.FromRgb(128, 255, 64); // ID  "layer-1"  "layer-2" ObjectId layer_1; ObjectId layer_2; //   public void createLayers() { //       Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; //   using (DocumentLock docloc = acDoc.LockDocument()) { //   using (Transaction tr = acCurDb.TransactionManager.StartTransaction()) { //     LayerTable acLyrTbl = tr.GetObject(acCurDb.LayerTableId, OpenMode.ForWrite) as LayerTable; //        LayerTableRecord acLyrTblRec_1 = new LayerTableRecord(); acLyrTblRec_1.Name = "layer-1"; //      ,  ID    layer_1 = acLyrTbl.Add(acLyrTblRec_1); //      tr.AddNewlyCreatedDBObject(acLyrTblRec_1, true); //        LayerTableRecord acLyrTblRec_2 = new LayerTableRecord(); acLyrTblRec_2.Name = "layer-2"; //      ,  ID    layer_2 = acLyrTbl.Add(acLyrTblRec_2); //      tr.AddNewlyCreatedDBObject(acLyrTblRec_2, true); //   tr.Commit(); } } } //    "block-1" public void createBlock_1() { //        Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; //    const string blockName = "block-1"; //   Transaction tr = db.TransactionManager.StartTransaction(); using (tr) { //      BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite); // ,        ;   -    if (bt.Has(blockName)) { return; } //    ,    BlockTableRecord btr = new BlockTableRecord(); btr.Name = blockName; //           bt.Add(btr); tr.AddNewlyCreatedDBObject(btr, true); //     //   Circle acCircle = new Circle(); //     acCircle.SetDatabaseDefaults(); acCircle.Center = Point3d.Origin; acCircle.Radius = 25; //          btr.AppendEntity(acCircle); tr.AddNewlyCreatedDBObject(acCircle, true); //   Line acLine = new Line(new Point3d(18, 18, 0), new Point3d(35, 35, 0)); //         acLine.SetDatabaseDefaults(); //          btr.AppendEntity(acLine); tr.AddNewlyCreatedDBObject(acLine, true); //   Polyline acPolyline = new Polyline(); //         acPolyline.SetDatabaseDefaults(); //     acPolyline.AddVertexAt(0, new Point2d(20, 35), 0, 0, 0); acPolyline.AddVertexAt(1, new Point2d(35, 35), 0, 0, 0); acPolyline.AddVertexAt(2, new Point2d(35, 20), 0, 0, 0); //          btr.AppendEntity(acPolyline); tr.AddNewlyCreatedDBObject(acPolyline, true); //   tr.Commit(); } } //    "block-2" public void createBlock_2() { //        Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; //    const string blockName = "block-2"; //   Transaction tr = db.TransactionManager.StartTransaction(); using (tr) { //      BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite); // ,        ;   -    if (bt.Has(blockName)) { return; } //    ,    BlockTableRecord btr = new BlockTableRecord(); btr.Name = blockName; //           bt.Add(btr); tr.AddNewlyCreatedDBObject(btr, true); //     //   Circle acCircle = new Circle(); //     acCircle.SetDatabaseDefaults(); acCircle.Center = Point3d.Origin; acCircle.Radius = 25; //         btr.AppendEntity(acCircle); tr.AddNewlyCreatedDBObject(acCircle, true); //    Line acLine_1 = new Line(new Point3d(0, -25, 0), new Point3d(0, -50, 0)); //         acLine_1.SetDatabaseDefaults(); //          btr.AppendEntity(acLine_1); tr.AddNewlyCreatedDBObject(acLine_1, true); //    Line acLine_2 = new Line(new Point3d(-7, -39, 0), new Point3d(7, -39, 0)); //         acLine_2.SetDatabaseDefaults(); //          btr.AppendEntity(acLine_2); tr.AddNewlyCreatedDBObject(acLine_2, true); //   tr.Commit(); } } //      public void layer_0_createObjects() { //       Document doc = acad.DocumentManager.MdiActiveDocument; Database db = doc.Database; //   using (Transaction tr = db.TransactionManager.StartTransaction()) { //     BlockTable acBlkTbl; acBlkTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable; //    (Model Space) -          BlockTableRecord ms = tr.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; //    Line acLine_1 = new Line(new Point3d(225, 225, 0), new Point3d(225, 175, 0)); //         acLine_1.SetDatabaseDefaults(); //        acLine_1.Layer = "0"; acLine_1.Color = color_Pink; //          ms.AppendEntity(acLine_1); tr.AddNewlyCreatedDBObject(acLine_1, true); //    Line acLine_2 = new Line(new Point3d(250, 225, 0), new Point3d(250, 175, 0)); //         acLine_2.SetDatabaseDefaults(); //        acLine_2.Layer = "0"; acLine_2.Color = color_Blue; //          ms.AppendEntity(acLine_2); tr.AddNewlyCreatedDBObject(acLine_2, true); //    Line acLine_3 = new Line(new Point3d(275, 225, 0), new Point3d(275, 175, 0)); //         acLine_3.SetDatabaseDefaults(); //        acLine_3.Layer = "0"; acLine_3.Color = color_LightGreen; //          ms.AppendEntity(acLine_3); tr.AddNewlyCreatedDBObject(acLine_3, true); //    Polyline acPolyline = new Polyline(); //         acPolyline.SetDatabaseDefaults(); //     acPolyline.AddVertexAt(0, new Point2d(300, 225), 0, 0, 0); acPolyline.AddVertexAt(1, new Point2d(325, 175), 0, 0, 0); acPolyline.AddVertexAt(2, new Point2d(350, 225), 0, 0, 0); //        acPolyline.Layer = "0"; acPolyline.Color = color_Pink; //          ms.AppendEntity(acPolyline); tr.AddNewlyCreatedDBObject(acPolyline, true); //    Circle acCircle = new Circle(); //     acCircle.SetDatabaseDefaults(); acCircle.Center = new Point3d(400, 200, 0); acCircle.Radius = 25; //        acCircle.Layer = "0"; acCircle.Color = color_Blue; //          ms.AppendEntity(acCircle); tr.AddNewlyCreatedDBObject(acCircle, true); //    DBText text = new DBText(); text.Position = new Point3d(450, 175, 0); text.Height = 50; text.TextString = "HABR!"; //        text.Layer = "0"; text.Color = color_LightGreen; //          ms.AppendEntity(text); tr.AddNewlyCreatedDBObject(text, true); //   tr.Commit(); } } //     "layer-1" public void layer_1_createObjects() { //       Document doc = acad.DocumentManager.MdiActiveDocument; Database db = doc.Database; //   using (Transaction tr = db.TransactionManager.StartTransaction()) { //           // (         ) ObjectId currentLayer = db.Clayer; db.Clayer = layer_1; //     BlockTable acBlkTbl; acBlkTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable; //    (Model Space) -          BlockTableRecord ms = tr.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; //    Line acLine_1 = new Line(new Point3d(225, 25, 0), new Point3d(225, -25, 0)); //     acLine_1.SetDatabaseDefaults(); acLine_1.Color = color_Pink; //          ms.AppendEntity(acLine_1); tr.AddNewlyCreatedDBObject(acLine_1, true); //    Line acLine_2 = new Line(new Point3d(250, 25, 0), new Point3d(250, -25, 0)); //     acLine_2.SetDatabaseDefaults(); acLine_2.Color = color_Blue; //          ms.AppendEntity(acLine_2); tr.AddNewlyCreatedDBObject(acLine_2, true); //    Circle acCircle = new Circle(); //     acCircle.SetDatabaseDefaults(); acCircle.Center = new Point3d(300, 0, 0); acCircle.Radius = 25; acCircle.Color = color_LightGreen; //          ms.AppendEntity(acCircle); tr.AddNewlyCreatedDBObject(acCircle, true); //    DBText text = new DBText(); //     text.Position = new Point3d(350, -25, 0); text.Height = 50; text.TextString = "HABR!"; text.Color = color_Pink; //          ms.AppendEntity(text); tr.AddNewlyCreatedDBObject(text, true); //    "block-1" //      BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); //  ObjectID  ObjectId btrId = bt["block-1"]; //    ,   ID   BlockReference br = new BlockReference(new Point3d(600, 0, 0), btrId); //          ms.AppendEntity(br); tr.AddNewlyCreatedDBObject(br, true); //      db.Clayer = currentLayer; //   tr.Commit(); } } //     "layer-2" public void layer_2_createObjects() { //       Document doc = acad.DocumentManager.MdiActiveDocument; Database db = doc.Database; //   using (Transaction tr = db.TransactionManager.StartTransaction()) { //           // (         ) ObjectId currentLayer = db.Clayer; db.Clayer = layer_2; //     BlockTable acBlkTbl; acBlkTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable; //    (Model Space) -          BlockTableRecord ms = tr.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; //    Line acLine_1 = new Line(new Point3d(225, -175, 0), new Point3d(225, -225, 0)); //     acLine_1.SetDatabaseDefaults(); acLine_1.Color = color_Pink; //          ms.AppendEntity(acLine_1); tr.AddNewlyCreatedDBObject(acLine_1, true); //    Arc acArc = new Arc(new Point3d(250, -200, 0), 25, -45 / 180.0 * Math.PI, 45 / 180.0 * Math.PI); //     acArc.SetDatabaseDefaults(); acArc.Color = color_Blue; //          ms.AppendEntity(acArc); tr.AddNewlyCreatedDBObject(acArc, true); //    Circle acCircle = new Circle(); //     acCircle.SetDatabaseDefaults(); acCircle.Center = new Point3d(325, -200, 0); acCircle.Radius = 25; acCircle.Color = color_LightGreen; //          ms.AppendEntity(acCircle); tr.AddNewlyCreatedDBObject(acCircle, true); //    "block-1" //      BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); //  ObjectID  ObjectId btrId = bt["block-1"]; //    ,   ID   BlockReference br = new BlockReference(new Point3d(400, -200, 0), btrId); //          ms.AppendEntity(br); tr.AddNewlyCreatedDBObject(br, true); //    "block-2" //  ObjectID  btrId = bt["block-2"]; //    ,   ID   br = new BlockReference(new Point3d(475, -200, 0), btrId); //          ms.AppendEntity(br); tr.AddNewlyCreatedDBObject(br, true); //      db.Clayer = currentLayer; //   tr.Commit(); } } //      public void Initialize() { createLayers(); createBlock_1(); createBlock_2(); layer_0_createObjects(); layer_1_createObjects(); layer_2_createObjects(); } //  Terminate() ,    IExtensionApplication public void Terminate() { } } } } 

Result:


The code is simple and shouldn't raise questions of principle. Let's quickly go over some of the nuances.

The first moment: performing operations inside the Initialize () method
To begin with, we note that the creation of all the necessary objects occurs right during the loading of the plug-in. Since the created objects are necessary for us to work with examples and are necessary for the work of any of the plug-in commands, they seem to be created within the Initialize() method.

However, how correct and reasonable this is is a very controversial question. First, creating something automatically, we thereby deprive the user of the choice and put it in front of a fun fact: hello, man, you have now ten new layers and a hundred new objects on your drawing!

It will be fun, but not too much. Especially the user.

The second trouble is that the user can accidentally or intentionally remove some of the created objects from the drawing. And in this case, he will not be able to re-create these objects; for this, he will have to close and restart AutoCAD.

In general, with the execution of actions when loading a plug-in, you need to be “gentler, more tender” (c). Jokes with this are quite permissible in an educational example, but in practice it is worth thinking three times before using Initialize() . Ideally, there should be only concrete and metal structures in those areas of the code that:
  1. Does not interfere with the user and will not create an excessive load on the drawing.
  2. They will never need to be called again (or the user should have a way to make this call - remember the example from the paragraph above about accidental deletion of drawing objects).

Nb:
Now, with a shudder, I entered the repository with the code of a real project, closed my eyes, opened my eyes ...
Uh, all right. The above rules are almost met.
...
How does it say something? "Who can not work - teaches"?


The second moment: setting the object layer in two ways
When objects fill the null layer (the layer_0_createObjects() function), belonging to this layer is clearly indicated for each object created. Example:

 acLine_1.Layer = "0"; 

This is understandable and easy, but when working with a large number of objects, you can easily forget to set a layer, which is not good.

Nb:
Life example: the author of the article faithfully copied paste into the function layer_1_createObjects() code to insert a line from the function layer_0_createObjects() into the drawing, forgetting to change the layer to a new one. The search for the error and its correction took some time. Realizing that this would have to be done with all the primitives, the author went out of line and decided to do everything in a different way.
So this part of the article was born.)

An alternative way to reduce the likelihood of such an error was briefly mentioned in a previous article on layers. This is the use of the Clayer property.

The essence of the method is that if we do not specify a layer at all when creating the object, it will be automatically assigned based on the value of the Clayer property of the database of the current document. You can view this value like this:

 Document doc = acad.DocumentManager.MdiActiveDocument; Database db = doc.Database; ObjectId currentLayer = db.Clayer; 

The value is assigned in the same way:

 Document doc = acad.DocumentManager.MdiActiveDocument; Database db = doc.Database; db.Clayer = layer_1; // layer_1 - ObjectID   

And this is how you can get the ObjectID layer, knowing its name:

 Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; using (DocumentLock docloc = acDoc.LockDocument()) { using (Transaction tr = acCurDb.TransactionManager.StartTransaction()) { LayerTable acLyrTbl = tr.GetObject(acCurDb.LayerTableId, OpenMode.ForWrite) as LayerTable; ObjectId layer_objID = acLyrTbl["someLayer"] } } 

In our example, in order not to refer to the layer table every time, I created two global variables, layer_1 and layer_2 , into which I save the ObjectID layers “layer-1” and “layer-2” when they were created. And later, in the layer_1_createObjects() and layer_2_createObjects() procedures, I use the following construction:

 // ... ObjectId currentLayer = db.Clayer; db.Clayer = layer_1; // ... //    // ... db.Clayer = currentLayer; // ... 

Why do I need to save the current Clayer value and restore it at the end of the function?
Well, one of the reasons is that the user after the work of our function could continue to add objects to the same layer as before the work of our procedure.
The second reason is not to get confused and then find out why the objects are not added there in half of the launches.
, , , . But why?


The third moment: safety

: « »

, . — , , .

. : , — , . . , - .

, , , .


Now that we have discussed the features of the example, we can finally go to the search for objects in the drawing. We will examine two different approaches: viewing drawing objects through accessing an object ModelSpaceand obtaining identifiers of drawing objects using a method Editor.SelectAll().

Nb:
. , .

- , , .

1 Search for drawing objects by referring to an object ModelSpace


1.1 Iteration over all objects in the drawing


To begin, let's see how you can loop through all the objects in the drawing.

The principle is simple: open the model space ( ModelSpace) and get links to all the objects inside it. Then we cast these objects to type Entityand process the properties we need.

The example is almost entirely borrowed from here .

Code:
 [CommandMethod("Habr_IterateThroughAllObjects_1")] public void iterateThroughAllObjects() { //    Database db = HostApplicationServices.WorkingDatabase; //   using (Transaction tr = db.TransactionManager.StartTransaction()) { //      (ModelSpace) BlockTableRecord ms = (BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead); // ""       foreach (ObjectId id in ms) { //       Entity Entity entity = (Entity)tr.GetObject(id, OpenMode.ForRead); //     (entity.Layer),  (entity.GetType().ToString())   (entity.Color)   acad.DocumentManager.MdiActiveDocument.Editor.WriteMessage(string.Format("\nLayer:{0}; Type:{1}; Color: {2},{3},{4}\n", entity.Layer, entity.GetType().ToString(), entity.Color.Red.ToString(), entity.Color.Green.ToString(), entity.Color.Blue.ToString())); } tr.Commit(); } } 

Result:



, , : 16 , .

: WorkingDatabase HostApplicationServices . , ( ) . — GetBlockModelSpaceId() SymbolUtilityServices , ObjectId ( ModelSpace ).

, , :
 //      ( 1) [CommandMethod("Habr_IterateThroughAllObjects_1")] public void iterateThroughAllObjects() { //       Document doc = acad.DocumentManager.MdiActiveDocument; Database db = doc.Database; //   using (Transaction tr = db.TransactionManager.StartTransaction()) { //      (ModelSpace) //     BlockTable acBlkTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable; //    (Model Space) -          BlockTableRecord ms = tr.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; // ""       foreach (ObjectId id in ms) { //       Entity Entity entity = (Entity)tr.GetObject(id, OpenMode.ForRead); //     (entity.Layer),  (entity.GetType().ToString())   (entity.Color)   acad.DocumentManager.MdiActiveDocument.Editor.WriteMessage(string.Format("\nLayer:{0}; Type:{1}; Color: {2},{3},{4}\n", entity.Layer, entity.GetType().ToString(), entity.Color.Red.ToString(), entity.Color.Green.ToString(), entity.Color.Blue.ToString())); } tr.Commit(); } } 

.

Nb:
SymbolUtilityServices (.).

, , Entity ( ) , .

1.2


Let's try to select all the circles. Let's make it on the basis of the previous example.

We will act like this: browse through all the objects in the drawing in order, define the type of each object; if the object turns out to be a circle, we will display information about it in the console. In the last article, we already had a link (English), which describes five ways to find out the type of object. As always, let's not deviate from the traditions and use one of the easiest ways:

 if (entity.GetType() == typeof(Circle)) //    - ,   

Code:
 [CommandMethod("Habr_FindCircles_1")] public void findCircles_1() { //    Database db = HostApplicationServices.WorkingDatabase; //   using (Transaction tr = db.TransactionManager.StartTransaction()) { //      (ModelSpace) BlockTableRecord ms = (BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead); // ""       foreach (ObjectId id in ms) { //       Entity Entity entity = (Entity)tr.GetObject(id, OpenMode.ForRead); //    -    ,      if (entity.GetType() == typeof(Circle)) { acad.DocumentManager.MdiActiveDocument.Editor.WriteMessage(string.Format("\nLayer:{0}; Type:{1}; Color: {2},{3},{4}\n", entity.Layer, entity.GetType().ToString(), entity.Color.Red.ToString(), entity.Color.Green.ToString(), entity.Color.Blue.ToString())); } } tr.Commit(); } } 

Result:


Works.

Similarly, you can try other types. For example, find all lines:

 if (entity.GetType() == typeof(Line)) 

Find all annotations (text elements):

 if (entity.GetType() == typeof(DBText)) 

All block entries:

 if (entity.GetType() == typeof(BlockReference)) 

.

, , — — AutoCAD.

1.3


- — , . .

:

 if (entity.GetType() == typeof(Circle)) 



 if (entity.Color == Autodesk.AutoCAD.Colors.Color.FromRgb(128, 255, 64)) 

, .)

Code:
 //      ( 1) [CommandMethod("Habr_FindLightGreenObjects_1")] public void findLightGreenObjects_1() { //    Database db = HostApplicationServices.WorkingDatabase; //   using (Transaction tr = db.TransactionManager.StartTransaction()) { //      (ModelSpace) BlockTableRecord ms = (BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead); // ""       foreach (ObjectId id in ms) { //       Entity Entity entity = (Entity)tr.GetObject(id, OpenMode.ForRead); //    - ,     ,      if (entity.Color == Autodesk.AutoCAD.Colors.Color.FromRgb(128, 255, 64)) { acad.DocumentManager.MdiActiveDocument.Editor.WriteMessage(string.Format("\nLayer:{0}; Type:{1}; Color: {2},{3},{4}\n", entity.Layer, entity.GetType().ToString(), entity.Color.Red.ToString(), entity.Color.Green.ToString(), entity.Color.Blue.ToString())); } } tr.Commit(); } } 

Result:


— , :

 if (entity.Layer == "0") 

Nb:
. Visual Studio " Entity test; test. " — IntelliSense . Entity:


Entity , : , . . , - , , .

«block-1». Entity ; Name BlockReference .

Code:
 [CommandMethod("Habr_FindBlocks_1")] public void findBlocks_1() { //    Database db = HostApplicationServices.WorkingDatabase; //   using (Transaction tr = db.TransactionManager.StartTransaction()) { //      (ModelSpace) BlockTableRecord ms = (BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead); // ""       foreach (ObjectId id in ms) { //       Entity Entity entity = (Entity)tr.GetObject(id, OpenMode.ForRead); // ,      if (entity.GetType() == typeof(BlockReference)) { //   -     BlockReference BlockReference br = (BlockReference)entity; //      - "block-1",     ,      if (br.Name == "block-1") { acad.DocumentManager.MdiActiveDocument.Editor.WriteMessage(string.Format("\nLayer:{0}; Type:{1}; Color: {2},{3},{4}\n", entity.Layer, entity.GetType().ToString(), entity.Color.Red.ToString(), entity.Color.Green.ToString(), entity.Color.Blue.ToString())); } } } tr.Commit(); } } 

«block-1».

2 Editor.SelectAll()


2.1


: Kean Walmsley (.). , AutoCAD DevBlog (.) Autodesk (rus).

, : , .

, , .

Code:
 //      ( 2) [CommandMethod("Habr_IterateThroughAllObjects_2")] public void iterateThroughAllObjects_2() { //    Editor   Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; //       // !         ! PromptSelectionResult selRes = ed.SelectAll(); //    -    if (selRes.Status != PromptStatus.OK) { ed.WriteMessage("\nError!\n"); return; } //   ID  ObjectId[] ids = selRes.Value.GetObjectIds(); //   using (Transaction tr = db.TransactionManager.StartTransaction()) { // ""     foreach (ObjectId id in ids) { //       Entity Entity entity = (Entity)tr.GetObject(id, OpenMode.ForRead); //     (entity.Layer),  (entity.GetType().ToString())   (entity.Color)   acad.DocumentManager.MdiActiveDocument.Editor.WriteMessage(string.Format("\nLayer:{0}; Type:{1}; Color: {2},{3},{4}\n", entity.Layer, entity.GetType().ToString(), entity.Color.Red.ToString(), entity.Color.Green.ToString(), entity.Color.Blue.ToString())); } tr.Commit(); } } 

Result:


We call the method Editor.SelectAll(). Since no filters are specified, we must return the identifiers ( ObjectID) of all objects in the drawing. They are written to a type variable PromptSelectionResult. Just in case, you need to make sure that the method worked correctly - for this we check the status of the result ( PromptSelectionResult.Status). If something is wrong, the value of this property will be different from PromptStatus.OK- in this case we terminate the function.

If the method Editor.SelectAll()worked correctly, we get the identifiers of all objects returned by this method. For this we use the method PromptSelectionResult.Value.GetObjectIds(). After that, we simply process all the objects in the loop - just like in the first section, when we turned to ModelSpace.

An important point ! According to its (.), Editor.SelectAll() , ( locked ) ( frozen ). , , : Editor.SelectAll() , , . Kean Walmsley (.), AutoCAD Devblog (.), Autodesk (.).

, : AutoCAD 2010 . , it will work in newer versions of the .NET API. But that this is an error in the documentation or a bug in the API, which one day, perhaps, it will be fixed, I can’t say.

A brief summary: be careful with this.

Another important point . To use the method Editor.SelectAll(), it is obviously necessary to have a class object Editor. When working with a document that is directly open in AutoCAD, there will be no problems; but using this method to process databases of third-party documents (which are not currently open in AutoCAD) will not work (Engl.).

2.2 Using Filters


Let's try to select all the circles again. Of course, you can do everything similarly to the previous section: to get the identifiers of all objects and see the type of each object - it will work. However, when using the method Editor.SelectAll()there is an opportunity to act differently.

The principle is this: first, we set a filter for objects using a class SelectionFilter, and then we apply this filter in the method Editor.SelectAll(). As a result, we are left with only objects that satisfy the condition of the filter.

Code:
 [CommandMethod("Habr_FindCircles_2")] public void findCircles_2() { //    Editor   Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; //  ,        TypedValue[] filterlist = new TypedValue[1]; //   (0) ,      //   ("CIRCLE") -   filterlist[0] = new TypedValue(0, "CIRCLE"); //   SelectionFilter filter = new SelectionFilter(filterlist); //         // !         ! PromptSelectionResult selRes = ed.SelectAll(filter); //    -    if (selRes.Status != PromptStatus.OK) { ed.WriteMessage("\nError!\n"); return; } //   ID  ObjectId[] ids = selRes.Value.GetObjectIds(); //   using (Transaction tr = db.TransactionManager.StartTransaction()) { // ""     foreach (ObjectId id in ids) { //       Entity Entity entity = (Entity)tr.GetObject(id, OpenMode.ForRead); //    ,      acad.DocumentManager.MdiActiveDocument.Editor.WriteMessage(string.Format("\nLayer:{0}; Type:{1}; Color: {2},{3},{4}\n", entity.Layer, entity.GetType().ToString(), entity.Color.Red.ToString(), entity.Color.Green.ToString(), entity.Color.Blue.ToString())); } tr.Commit(); } } 

Result:


Works.Now let's see how.)

So, a method Editor.SelectAll()can take on an input an object of the type SelectionFilterthat sets the filter. This filter is initialized with an array of type objects TypedValue. The constructor TypedValuetakes two parameters as input:

 public TypedValue(int typeCode, object value); 

These values ​​are associated with the format of DXF (rus). This is what the documentation says about it :
The document is a specific version. This is a group code. A group code is the value of the data element follows. The data element for a given object (or record) type. DXF format. The DXF format is the same when used with applications (AutoLISP and ARX). However, there are some minor data differences for some data groups.

Google Translate:
DXF AutoCAD . , , . , . ( ). DXF. DXF AutoLISP, ARX, .

In the above example, we indicated as the typeCodevalue 0. Where it came from and what it means - you can see in the list (eng.)

Just in case I will duplicate the list here:
-5: APP: persistent reactor chain
-4: APP: conditional operator (used only with ssget)
-3: APP: extended data (XDATA) sentinel (fixed)
-2: APP: entity name reference (fixed)
-1: APP: entity name. This changes each time a drawing is opened. It is never saved. (fixed)
0: Text string indicating the entity type (fixed)
1: Primary text value for an entity
2: Name (attribute tag, block name, and so on)
3-4: Other textual or name values
5: Entity handle. Text string of up to 16: hexadecimal digits (fixed)
6: Linetype name (fixed)
7: Text style name (fixed)
8: Layer name (fixed)
9: DXF: variable name identifier (used only in HEADER section of the DXF file).
10: Primary point. This is the start point of a line or text entity, center of a circle, and so on.
DXF: X value of the primary point (followed by Y and Z value codes 20: and 30)
APP: 3D point (list of three reals)
11-18: Other points.
DXF: X value of other points (followed by Y value codes 21-28: and Z value codes 31-38)
APP: 3D point (list of three reals)
20, 30: DXF: Y and Z values of the primary point
21-28, 31-37: DXF: Y and Z values of other points
38: DXF: entity's elevation if nonzero.
39: Entity's thickness if nonzero (fixed)
40-48: Floating-point values (text height, scale factors, and so on)
48: Linetype scale. Floating-point scalar value. Default value is defined for all entity types.
49: Repeated floating-point value. Multiple 49: groups may appear in one entity for variable-length tables (such as the dash lengths in the LTYPE table). A 7x group always appears before the first 49 group to specify the table length.
50-58: Angles (output in degrees to DXF files and radians through AutoLISP and ARX applications).
60: Entity visibility. Integer value. Absence or 0: indicates visibility; 1 indicates invisibility.
62: Color number (fixed)
66: "Entities follow" flag (fixed)
67: Space--that is, model or paper space (fixed)
68: APP: identifies whether viewport is on but fully off screen; is not active or is off.
69: APP: viewport identification number.
70-78: Integer values, such as repeat counts, flag bits, or modes
90-99: 32-bit integer values
100: Subclass data marker (with derived class name as a string). Required for all objects and entity classes that are derived from another concrete class to segregate data defined by different classes in the inheritance chain for the same object.
This is in addition to the requirement for DXF names for each distinct concrete class derived from ARX (see "Subclass Markers").
102: Control string, followed by "{<arbitrary name>" or "}". Similar to the xdata 1002: group code, except that when the string begins with "{", it can be followed by an arbitrary string whose interpretation is up to the application. The only other allowable control string is "}" as a group terminator. As noted before, AutoCAD does not interpret these strings except during drawing audit operations; they are for application use.
105: DIMVAR symbol table entry object handle
210: Extrusion direction (fixed).
DXF: X value of extrusion direction
APP: 3D extrusion direction vector
220, 230: DXF: Y and Z values of the extrusion direction
280-289: 8-bit integer values
300-309: Arbitrary text strings
310-319: Arbitrary binary chunks with same representation and limits as 1004: group codes: hexadecimal strings of up to 254 characters represent data chunks of up to 127 bytes.
320-329: Arbitrary object handles. Handle values that are taken "as is." They are not translated during INSERT and XREF operations.
330-339: Soft-pointer handle. Arbitrary soft pointers to other objects within same DXF file or drawing. Translated during INSERT and XREF operations.
340-349: Hard-pointer handle. Arbitrary hard pointers to other objects within same DXF file or drawing. Translated during INSERT and XREF operations.
350-359: Soft-owner handle. Arbitrary soft ownership links to other objects within same DXF file or drawing. Translated during INSERT and XREF operations.
360-369: Hard-owner handle. Arbitrary hard ownership links to other objects within same DXF file or drawing. Translated during INSERT and XREF operations.
999: DXF: The 999: group code indicates that the line following it is a comment string. DXFOUT does not include such groups in a DXF output file, but DXFIN honors them and ignores the comments. You can use the 999 group to include comments in a DXF file that you've edited.
1000: ASCII string (up to 255: bytes long) in extended data.
1001: Registered application name (ASCII string up to 31: bytes long) for extended data.
1002: Extended data control string ("{"or "}").
1003: Extended data layer name.
1004: Chunk of bytes (up to 127: bytes long) in extended data.
1005: Entity handle in extended data. Text string of up to 16: hexadecimal digits
1010: A point in extended data
DXF: X value (followed by 1020: and 1030 groups)
APP: 3D point
1020, 1030: DXF: Y and Z values of a point
1011: A 3D world space position in extended data
DXF: X value (followed by 1021: and 1031 groups)
APP: 3D point
1021, 1031: DXF: Y and Z values of a World space position
1012: A 3D world space displacement in extended data
DXF: X value (followed by 1022: and 1032 groups)
APP: 3D vector
1022, 1032: DXF: Y and Z values of a World space displacement
1013: A 3D world space direction in extended data.
DXF: X value (followed by 1022: and 1032 groups)
APP: 3D vector
1023, 1033: DXF: Y and Z values of a World space direction
1040: Extended data floating-point value.
1041: Extended data distance value.
1042: Extended data scale factor.
1070: Extended data 16-bit signed integer.
1071: Extended data 32-bit signed long.

The fifth sixth line in the list is this:
0: Text string indicating the entity type (fixed)

Thus, the code "0" corresponds to the type of object.

Nb:
API Autodesk.AutoCAD.DatabaseServices.DxfCode :

 [Wrapper("AcDb::DxfCode")] public enum DxfCode { Invalid = -9999, XDictionary = -6, PReactors = -5, Operator = -4, XDataStart = -3, FirstEntityId = -2, HeaderId = -2, End = -1, Start = 0, XRefPath = 1, Text = 1, AttributeTag = 2, ShapeName = 2, BlockName = 2, SymbolTableName = 2, MlineStyleName = 2, SymbolTableRecordName = 2, Description = 3, TextFontFile = 3, AttributePrompt = 3, LinetypeProse = 3, DimStyleName = 3, DimPostString = 3, CLShapeName = 4, DimensionAlternativePrefixSuffix = 4, TextBigFontFile = 4, SymbolTableRecordComments = 4, Handle = 5, DimensionBlock = 5, LinetypeName = 6, DimBlk1 = 6, DimBlk2 = 7, TextStyleName = 7, LayerName = 8, CLShapeText = 9, XCoordinate = 10, YCoordinate = 20, ZCoordinate = 30, Elevation = 38, Thickness = 39, TxtSize = 40, ViewportHeight = 40, Real = 40, ViewWidth = 41, TxtStyleXScale = 41, ViewportAspect = 41, TxtStylePSize = 42, ViewLensLength = 42, ViewFrontClip = 43, ViewBackClip = 44, ShapeXOffset = 44, ViewHeight = 45, ShapeYOffset = 45, ShapeScale = 46, PixelScale = 47, LinetypeScale = 48, DashLength = 49, MlineOffset = 49, LinetypeElement = 49, ViewportSnapAngle = 50, Angle = 50, ViewportTwist = 51, Visibility = 60, LayerLinetype = 61, Color = 62, HasSubentities = 66, ViewportVisibility = 67, ViewportActive = 68, ViewportNumber = 69, Int16 = 70, ViewMode = 71, TxtStyleFlags = 71, RegAppFlags = 71, CircleSides = 72, LinetypeAlign = 72, ViewportZoom = 73, LinetypePdc = 73, ViewportIcon = 74, ViewportSnap = 75, ViewportGrid = 76, ViewportSnapStyle = 77, ViewportSnapPair = 78, Int32 = 90, Subclass = 100, EmbeddedObjectStart = 101, ControlString = 102, DimVarHandle = 105, UcsOrg = 110, UcsOrientationX = 111, UcsOrientationY = 112, XReal = 140, ViewBrightness = 141, ViewContrast = 142, Int64 = 160, XInt16 = 170, NormalX = 210, NormalY = 220, NormalZ = 230, XXInt16 = 270, Int8 = 280, RenderMode = 281, Bool = 290, XTextString = 300, BinaryChunk = 310, ArbitraryHandle = 320, SoftPointerId = 330, HardPointerId = 340, SoftOwnershipId = 350, HardOwnershipId = 360, LineWeight = 370, PlotStyleNameType = 380, PlotStyleNameId = 390, ExtendedInt16 = 400, LayoutName = 410, ColorRgb = 420, ColorName = 430, Alpha = 440, GradientObjType = 450, GradientPatType = 451, GradientTintType = 452, GradientColCount = 453, GradientAngle = 460, GradientShift = 461, GradientTintVal = 462, GradientColVal = 463, GradientName = 470, Comment = 999, ExtendedDataAsciiString = 1000, ExtendedDataRegAppName = 1001, ExtendedDataControlString = 1002, ExtendedDataLayerName = 1003, ExtendedDataBinaryChunk = 1004, ExtendedDataHandle = 1005, ExtendedDataXCoordinate = 1010, ExtendedDataWorldXCoordinate = 1011, ExtendedDataWorldXDisp = 1012, ExtendedDataWorldXDir = 1013, ExtendedDataYCoordinate = 1020, ExtendedDataWorldYCoordinate = 1021, ExtendedDataWorldYDisp = 1022, ExtendedDataWorldYDir = 1023, ExtendedDataZCoordinate = 1030, ExtendedDataWorldZCoordinate = 1031, ExtendedDataWorldZDisp = 1032, ExtendedDataWorldZDir = 1033, ExtendedDataReal = 1040, ExtendedDataDist = 1041, ExtendedDataScale = 1042, ExtendedDataInteger16 = 1070, ExtendedDataInteger32 = 1071, } 

,

 filterlist[0] = new TypedValue(0, "CIRCLE"); 



 filterlist[0] = new TypedValue((int)DxfCode.Start, "CIRCLE"); 

!

, 0 «Start». I have no idea.

, (, , ). Autodesk.AutoCAD.DatabaseServices.DxfCode , (, , ). (, , ). ! — , .

— . — , .

Quickly run through the simple features of the filters.

Of course, we can not only search the circle. Find all the lines:

 filterlist[0] = new TypedValue((int)DxfCode.Start, "LINE"); 

Find all occurrences of blocks:

 filterlist[0] = new TypedValue((int)DxfCode.Start, "INSERT"); 

Nb:
(.).

, :
3DFACE
3DSOLID
ACAD_PROXY_ENTITY
ARC
ARCALIGNEDTEXT
ATTDEF
ATTRIB
BODY
CIRCLE
DIMENSION
ELLIPSE
HATCH
IMAGE
INSERT
LEADER
LINE
LWPOLYLINE
MLINE
MTEXT
OLEFRAME
OLE2FRAME
POINT
POLYLINE
RAY
REGION
RTEXT
SEQEND
SHAPE
SOLID
SPLINE
TEXT
TOLERANCE
TRACE
VERTEX
VIEWPORT
WIPEOUT
XLINE

"INSERT" .

Find all the objects on the layer "layer-1":

 filterlist[0] = new TypedValue((int)DxfCode.LayerName, "layer-1"); 

In one object TypedValueyou can list several names separated by commas. In this case, the conditions will be combined with the operation "OR" ("OR").

Let's find all the objects that are lines OR circles:

 filterlist[0] = new TypedValue((int)DxfCode.Start, "LINE,CIRCLE"); 

Find all objects that are on the layer-1 layer OR layer-2:

 filterlist[0] = new TypedValue((int)DxfCode.LayerName, "layer-1,layer-2"); 

IMPORTANT : after the comma between the parameters to be combined there MUST NOT be a space!

Finally, you can add multiple objectsTypedValueto an array of conditions. In this case, the conditions will be combined with the operation "AND" ("AND").

Find all the objects that are lines And are on the zero layer:

 TypedValue[] filterlist = new TypedValue[2]; filterlist[0] = new TypedValue((int)DxfCode.Start, "CIRCLE"); filterlist[1] = new TypedValue((int)DxfCode.LayerName, "0"); 

Find all entries of the block-1:

 TypedValue[] filterlist = new TypedValue[2]; filterlist[0] = new TypedValue((int)DxfCode.Start, "INSERT"); filterlist[1] = new TypedValue((int)DxfCode.BlockName, "block-1"); 

Find all objects that are lines AND are on the zero layer OR layer "layer-1":

 TypedValue[] filterlist = new TypedValue[2]; filterlist[0] = new TypedValue((int)DxfCode.Start, "LINE"); filterlist[1] = new TypedValue((int)DxfCode.LayerName, "0,layer-1"); 

Well, it seems and does not hurt ... It was. For now.

2.3 Filters are more complicated


( ) Kean Walmsley.

«layer-1» «layer-2». , , TypedValue : , , — .

, :

(( == «layer-1») ( == «»)) (( == «layer-2») ( == «»))

AutoCAD :


TypedValue :

 TypedValue[] filterlist = new TypedValue[10]; filterlist[0] = new TypedValue((int)DxfCode.Operator, "<OR"); filterlist[1] = new TypedValue((int)DxfCode.Operator, "<AND"); filterlist[2] = new TypedValue((int)DxfCode.LayerName, "layer-1"); filterlist[3] = new TypedValue((int)DxfCode.Start, "LINE"); filterlist[4] = new TypedValue((int)DxfCode.Operator, "AND>"); filterlist[5] = new TypedValue((int)DxfCode.Operator, "<AND"); filterlist[6] = new TypedValue((int)DxfCode.LayerName, "layer-2"); filterlist[7] = new TypedValue((int)DxfCode.Start, "CIRCLE"); filterlist[8] = new TypedValue((int)DxfCode.Operator, "AND>"); filterlist[9] = new TypedValue((int)DxfCode.Operator, "OR>"); 

AutoCAD:
Layer:layer-2; Type:Autodesk.AutoCAD.DatabaseServices.Circle; Color: 128,255,64
Layer:layer-1; Type:Autodesk.AutoCAD.DatabaseServices.Line; Color: 0,200,255
Layer:layer-1; Type:Autodesk.AutoCAD.DatabaseServices.Line; Color: 255,128,255

: , , , OR, AND, NOT, XOR…

Nb:
Seriously? XOR? , … , .
, ? - ? , ?

(.).

, . …

3


In addition Editor.SelectAll(), there are a number of other ways to search (more precisely, selection) objects in the drawing. Here are the links: English documentation , Russian translation .

As you can see, there are ten more more focused options than Editor.SelectAll(). But we considered the most powerful of them.

Offtopic: promised bloody details (you can skip)
, . , , — ?

, , , , — (.), hwd , , .

( ModelSpace ), . , , , ..

Code:
 //      ( 3) // !   ! [CommandMethod("Habr_IterateThroughAllObjects_3")] public void iterateThroughAllObjects_3() { Database db = HostApplicationServices.WorkingDatabase; Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; long amount = 0; Dictionary<string, int> d = new Dictionary<string, int>(); ObjectId id = ObjectId.Null; for (long i = db.BlockTableId.Handle.Value; i < db.Handseed.Value; i++) { Handle h = new Handle(i); if (db.TryGetObjectId(h, out id) && !id.IsNull && id.IsValid && !id.IsErased) { string t = id.ObjectClass.DxfName; amount++; if(d.ContainsKey(t)) d[t]++; else d.Add(t, 1); } } foreach(KeyValuePair<string,int> kvp in d) ed.WriteMessage("\n{0}: {1} ", kvp.Key, kvp.Value); ed.WriteMessage("\nTotal {0} objects in drawing\n", amount); } 

( ):
Command: Habr_IterateThroughAllObjects_3
TABLE: 11
DICTIONARY: 16
ACDBDICTIONARYWDFLT: 1
ACDBPLACEHOLDER: 1
LAYER: 3
STYLE: 2
APPID: 7
LTYPE: 3
MLINESTYLE: 1
BLOCK_RECORD: 5
BLOCK: 5
ENDBLK: 5
LAYOUT: 3
DIMSTYLE: 3
DICTIONARYVAR: 7
TABLESTYLE: 1
VPORT: 1
MATERIAL: 3
VISUALSTYLE: 19
SCALE: 17
MLEADERSTYLE: 2
XRECORD: 4
FONT_TABLE_RECORD: 2
CIRCLE: 5
LINE: 9
LWPOLYLINE: 2
TEXT: 2
INSERT: 3
ARC: 1
Total 144 objects in drawing

- . , , , . — , welcome! … , .

UPD.: .

4 Modification of objects


It seems to me that the modification of objects is much simpler than the search. Here is the basic principle: after receiving ObjectID, we open the object itself, bring it to the desired type and make the necessary changes to the properties. Well, or remove the object from the drawing, using the appropriate method.

4.1 Removing an object from a drawing


To remove an object from the drawing:
  1. open object for writing;
  2. call method Erase();
  3. .

: (.), (.).

.

Code:
 [CommandMethod("Habr_EraseCircles_2")] public void eraseCircles_2() { //    Editor   Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; //  ,        TypedValue[] filterlist = new TypedValue[1]; //   (0) ,      //   ("CIRCLE") -   filterlist[0] = new TypedValue(0, "CIRCLE"); //   SelectionFilter filter = new SelectionFilter(filterlist); //         // !         ! PromptSelectionResult selRes = ed.SelectAll(filter); //    -    if (selRes.Status != PromptStatus.OK) { ed.WriteMessage("\nError!\n"); return; } //   ID  ObjectId[] ids = selRes.Value.GetObjectIds(); //   using (Transaction tr = db.TransactionManager.StartTransaction()) { // ""     foreach (ObjectId id in ids) { //       Entity Entity entity = (Entity)tr.GetObject(id, OpenMode.ForRead); //      entity.UpgradeOpen(); //   entity.Erase(); } tr.Commit(); } } 

Result:


, UpgradeOpen() , :

 Entity entity = (Entity)tr.GetObject(id, OpenMode.ForWrite); entity.Erase(); 

Important! — , :



try...catch . - :

 Entity entity = (Entity)tr.GetObject(id, OpenMode.ForRead); try { entity.UpgradeOpen(); entity.Erase(); } catch () { ed.WriteMessage("\nSomething went wrong...\n"); } 

AutoCAD.

Nb:
, try...catch — . , eOnLockedLayer , , Autodesk.AutoCAD.Runtime.Exception ( ErrorStatus ) — - :

 catch (Autodesk.AutoCAD.Runtime.Exception ex) { if (ex.ErrorStatus == ErrorStatus.OnLockedLayer) { ... } } 

— , «», , , — , _. -, , . .

— — .

UPD.: Andrey Bushman suggested that the method GetObject, generally speaking, has the following signature:

 GetObject(ObjectId id, OpenMode mode, Boolean openErased, Boolean forceOpenOnLockedLayer) 

The last parameter allows you to work with locked layers as well. For example, here is the code I have correctly worked even with a blocked layer:

 Entity entity = (Entity)tr.GetObject(id, OpenMode.ForWrite, false, true); entity.Erase(); 

After completion of the transaction, the state of the layer on which the object is located does not change.

In general, it seems that instead of a construction, try...catchyou can use a parameter forceOpenOnLockedLayer. In this case, we discard the method UpgradeOpen()and immediately open the object with GetObject()the write method ( OpenMode.ForWrite) with the flag set forceOpenOnLockedLayer.

4.2 Changing typical properties of objects


« » , AutoCAD. , , .

:
  1. ;
  2. ;
  3. .

.

Code:
 [CommandMethod("Habr_RepaintOrange_2")] public void repaintOrange_2() { //    Editor   Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; //       // !         ! PromptSelectionResult selRes = ed.SelectAll(); //    -    if (selRes.Status != PromptStatus.OK) { ed.WriteMessage("\nError!\n"); return; } //   ID  ObjectId[] ids = selRes.Value.GetObjectIds(); //   using (Transaction tr = db.TransactionManager.StartTransaction()) { // ""     foreach (ObjectId id in ids) { //       Entity Entity entity = (Entity)tr.GetObject(id, OpenMode.ForRead); //     entity.UpgradeOpen(); //     entity.Color = Autodesk.AutoCAD.Colors.Color.FromRgb(255, 128, 0); } tr.Commit(); } } 

Result:


. — , :

- Color:


.

, Entity . , 146% , . — forceOpenOnLockedLayer try...catch .

4.3


, . Entity , , , . Circle :

Code:
 [CommandMethod("Habr_ModifyCircles_2")] public void modifyCircles_2() { //    Editor   Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; //  ,        TypedValue[] filterlist = new TypedValue[1]; //   (0) ,      //   ("CIRCLE") -   filterlist[0] = new TypedValue(0, "CIRCLE"); //   SelectionFilter filter = new SelectionFilter(filterlist); //         // !         ! PromptSelectionResult selRes = ed.SelectAll(filter); //    -    if (selRes.Status != PromptStatus.OK) { ed.WriteMessage("\nError!\n"); return; } //   ID  ObjectId[] ids = selRes.Value.GetObjectIds(); //   using (Transaction tr = db.TransactionManager.StartTransaction()) { // ""     foreach (ObjectId id in ids) { //       Circle Circle cir = (Circle)tr.GetObject(id, OpenMode.ForRead); //     cir.UpgradeOpen(); //   cir.Radius = cir.Radius * 2; } tr.Commit(); } } 

Result:


Works.

Of course, you need to make sure that we are dealing with circles. Attempting to cast to a type Circle, for example, the occurrence of a block will not end well:



Use a construct try...catch! Or at least provide filtering, as in our example, or check the type immediately before the cast:

 Entity ent = (Entity)tr.GetObject(id, OpenMode.ForRead); if (ent.GetType() == typeof(Circle)) { Circle cir = (Circle)tr.GetObject(id, OpenMode.ForRead); } 

I emphasize that neither the filter nor the check will not protect against the situation with a blocked layer and an error eOnLockedLayer. To combat it, use either a flag forceOpenOnLockedLayer, or a construct try...catch, or filters / checks that will cut off blocked objects.

4.4 Moving Simple Objects


If the position of an object in the drawing is specified by a single point (as, for example, a circle or a block), then to move this shape, just change the corresponding property. For example, let's move all occurrences of blocks to the origin:

Code:
 [CommandMethod("Habr_MoveBlocks_2")] public void moveBlocks_2() { //    Editor   Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; //  ,        TypedValue[] filterlist = new TypedValue[1]; //   (0) ,      //   ("CIRCLE") -   filterlist[0] = new TypedValue(0, "INSERT"); //   SelectionFilter filter = new SelectionFilter(filterlist); //         // !         ! PromptSelectionResult selRes = ed.SelectAll(filter); //    -    if (selRes.Status != PromptStatus.OK) { ed.WriteMessage("\nError!\n"); return; } //   ID  ObjectId[] ids = selRes.Value.GetObjectIds(); //   using (Transaction tr = db.TransactionManager.StartTransaction()) { // ""     foreach (ObjectId id in ids) { //       BlockReference BlockReference br = (BlockReference)tr.GetObject(id, OpenMode.ForRead); //     br.UpgradeOpen(); //    br.Position = Point3d.Origin; } tr.Commit(); } } 

Result:


An analogue of a property Positionfor a circle is a property Center.

4.5 Complex object operations


AutoCAD .NET API allows you to scale and rotate objects. Probably, it is even possible to somehow modify the vertices of polygons and broken lines. Unfortunately, I did not work with such things and I can’t say anything about it.

If you have to start searching for information, you can refer to the .NET API manual ( link (eng.), Mirror (eng.)). Well, AutoCAD forums to help. You can also ask a question in the forums of the Autodesk Programmers' Community in the CIS .

application


Just in case - here is the final version of the code containing the main examples reviewed.
 using System; using System.Collections.Generic; using Autodesk.AutoCAD.Runtime; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.EditorInput; using acad = Autodesk.AutoCAD.ApplicationServices.Application; namespace HabrPlug_SearchAndRescue { public class ClassMyAutoCADDLL_SearchAndRescue { public class Commands : IExtensionApplication { //   Autodesk.AutoCAD.Colors.Color color_Pink = Autodesk.AutoCAD.Colors.Color.FromRgb(255, 128, 255); Autodesk.AutoCAD.Colors.Color color_Blue = Autodesk.AutoCAD.Colors.Color.FromRgb(0, 200, 255); Autodesk.AutoCAD.Colors.Color color_LightGreen = Autodesk.AutoCAD.Colors.Color.FromRgb(128, 255, 64); // ID  "layer-1"  "layer-2" ObjectId layer_1; ObjectId layer_2; //   public void createLayers() { //       Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; //   using (DocumentLock docloc = acDoc.LockDocument()) { //   using (Transaction tr = acCurDb.TransactionManager.StartTransaction()) { //     LayerTable acLyrTbl = tr.GetObject(acCurDb.LayerTableId, OpenMode.ForWrite) as LayerTable; //        LayerTableRecord acLyrTblRec_1 = new LayerTableRecord(); acLyrTblRec_1.Name = "layer-1"; //      ,  ID    layer_1 = acLyrTbl.Add(acLyrTblRec_1); //      tr.AddNewlyCreatedDBObject(acLyrTblRec_1, true); //        LayerTableRecord acLyrTblRec_2 = new LayerTableRecord(); acLyrTblRec_2.Name = "layer-2"; //      ,  ID    layer_2 = acLyrTbl.Add(acLyrTblRec_2); //      tr.AddNewlyCreatedDBObject(acLyrTblRec_2, true); //   tr.Commit(); } } } //    "block-1" public void createBlock_1() { //        Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; //    const string blockName = "block-1"; //   Transaction tr = db.TransactionManager.StartTransaction(); using (tr) { //      BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite); // ,        ;   -    if (bt.Has(blockName)) { return; } //    ,    BlockTableRecord btr = new BlockTableRecord(); btr.Name = blockName; //           bt.Add(btr); tr.AddNewlyCreatedDBObject(btr, true); //     //   Circle acCircle = new Circle(); //     acCircle.SetDatabaseDefaults(); acCircle.Center = Point3d.Origin; acCircle.Radius = 25; //          btr.AppendEntity(acCircle); tr.AddNewlyCreatedDBObject(acCircle, true); //   Line acLine = new Line(new Point3d(18, 18, 0), new Point3d(35, 35, 0)); //         acLine.SetDatabaseDefaults(); //          btr.AppendEntity(acLine); tr.AddNewlyCreatedDBObject(acLine, true); //   Polyline acPolyline = new Polyline(); //         acPolyline.SetDatabaseDefaults(); //     acPolyline.AddVertexAt(0, new Point2d(20, 35), 0, 0, 0); acPolyline.AddVertexAt(1, new Point2d(35, 35), 0, 0, 0); acPolyline.AddVertexAt(2, new Point2d(35, 20), 0, 0, 0); //          btr.AppendEntity(acPolyline); tr.AddNewlyCreatedDBObject(acPolyline, true); //   tr.Commit(); } } //    "block-2" public void createBlock_2() { //        Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; //    const string blockName = "block-2"; //   Transaction tr = db.TransactionManager.StartTransaction(); using (tr) { //      BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite); // ,        ;   -    if (bt.Has(blockName)) { return; } //    ,    BlockTableRecord btr = new BlockTableRecord(); btr.Name = blockName; //           bt.Add(btr); tr.AddNewlyCreatedDBObject(btr, true); //     //   Circle acCircle = new Circle(); //     acCircle.SetDatabaseDefaults(); acCircle.Center = Point3d.Origin; acCircle.Radius = 25; //         btr.AppendEntity(acCircle); tr.AddNewlyCreatedDBObject(acCircle, true); //    Line acLine_1 = new Line(new Point3d(0, -25, 0), new Point3d(0, -50, 0)); //         acLine_1.SetDatabaseDefaults(); //          btr.AppendEntity(acLine_1); tr.AddNewlyCreatedDBObject(acLine_1, true); //    Line acLine_2 = new Line(new Point3d(-7, -39, 0), new Point3d(7, -39, 0)); //         acLine_2.SetDatabaseDefaults(); //          btr.AppendEntity(acLine_2); tr.AddNewlyCreatedDBObject(acLine_2, true); //   tr.Commit(); } } //      public void layer_0_createObjects() { //       Document doc = acad.DocumentManager.MdiActiveDocument; Database db = doc.Database; //   using (Transaction tr = db.TransactionManager.StartTransaction()) { //     BlockTable acBlkTbl; acBlkTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable; //    (Model Space) -          BlockTableRecord ms = tr.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; //    Line acLine_1 = new Line(new Point3d(225, 225, 0), new Point3d(225, 175, 0)); //         acLine_1.SetDatabaseDefaults(); //        acLine_1.Layer = "0"; acLine_1.Color = color_Pink; //          ms.AppendEntity(acLine_1); tr.AddNewlyCreatedDBObject(acLine_1, true); //    Line acLine_2 = new Line(new Point3d(250, 225, 0), new Point3d(250, 175, 0)); //         acLine_2.SetDatabaseDefaults(); //        acLine_2.Layer = "0"; acLine_2.Color = color_Blue; //          ms.AppendEntity(acLine_2); tr.AddNewlyCreatedDBObject(acLine_2, true); //    Line acLine_3 = new Line(new Point3d(275, 225, 0), new Point3d(275, 175, 0)); //         acLine_3.SetDatabaseDefaults(); //        acLine_3.Layer = "0"; acLine_3.Color = color_LightGreen; //          ms.AppendEntity(acLine_3); tr.AddNewlyCreatedDBObject(acLine_3, true); //    Polyline acPolyline = new Polyline(); //         acPolyline.SetDatabaseDefaults(); //     acPolyline.AddVertexAt(0, new Point2d(300, 225), 0, 0, 0); acPolyline.AddVertexAt(1, new Point2d(325, 175), 0, 0, 0); acPolyline.AddVertexAt(2, new Point2d(350, 225), 0, 0, 0); //        acPolyline.Layer = "0"; acPolyline.Color = color_Pink; //          ms.AppendEntity(acPolyline); tr.AddNewlyCreatedDBObject(acPolyline, true); //    Circle acCircle = new Circle(); //     acCircle.SetDatabaseDefaults(); acCircle.Center = new Point3d(400, 200, 0); acCircle.Radius = 25; //        acCircle.Layer = "0"; acCircle.Color = color_Blue; //          ms.AppendEntity(acCircle); tr.AddNewlyCreatedDBObject(acCircle, true); //    DBText text = new DBText(); text.Position = new Point3d(450, 175, 0); text.Height = 50; text.TextString = "HABR!"; //        text.Layer = "0"; text.Color = color_LightGreen; //          ms.AppendEntity(text); tr.AddNewlyCreatedDBObject(text, true); //   tr.Commit(); } } //     "layer-1" public void layer_1_createObjects() { //       Document doc = acad.DocumentManager.MdiActiveDocument; Database db = doc.Database; //   using (Transaction tr = db.TransactionManager.StartTransaction()) { //           // (         ) ObjectId currentLayer = db.Clayer; db.Clayer = layer_1; //     BlockTable acBlkTbl; acBlkTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable; //    (Model Space) -          BlockTableRecord ms = tr.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; //    Line acLine_1 = new Line(new Point3d(225, 25, 0), new Point3d(225, -25, 0)); //     acLine_1.SetDatabaseDefaults(); acLine_1.Color = color_Pink; //          ms.AppendEntity(acLine_1); tr.AddNewlyCreatedDBObject(acLine_1, true); //    Line acLine_2 = new Line(new Point3d(250, 25, 0), new Point3d(250, -25, 0)); //     acLine_2.SetDatabaseDefaults(); acLine_2.Color = color_Blue; //          ms.AppendEntity(acLine_2); tr.AddNewlyCreatedDBObject(acLine_2, true); //    Circle acCircle = new Circle(); //     acCircle.SetDatabaseDefaults(); acCircle.Center = new Point3d(300, 0, 0); acCircle.Radius = 25; acCircle.Color = color_LightGreen; //          ms.AppendEntity(acCircle); tr.AddNewlyCreatedDBObject(acCircle, true); //    DBText text = new DBText(); //     text.Position = new Point3d(350, -25, 0); text.Height = 50; text.TextString = "HABR!"; text.Color = color_Pink; //          ms.AppendEntity(text); tr.AddNewlyCreatedDBObject(text, true); //    "block-1" //      BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); //  ObjectID  ObjectId btrId = bt["block-1"]; //    ,   ID   BlockReference br = new BlockReference(new Point3d(600, 0, 0), btrId); //          ms.AppendEntity(br); tr.AddNewlyCreatedDBObject(br, true); //      db.Clayer = currentLayer; //   tr.Commit(); } } //     "layer-2" public void layer_2_createObjects() { //       Document doc = acad.DocumentManager.MdiActiveDocument; Database db = doc.Database; //   using (Transaction tr = db.TransactionManager.StartTransaction()) { //           // (         ) ObjectId currentLayer = db.Clayer; db.Clayer = layer_2; //     BlockTable acBlkTbl; acBlkTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable; //    (Model Space) -          BlockTableRecord ms = tr.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; //    Line acLine_1 = new Line(new Point3d(225, -175, 0), new Point3d(225, -225, 0)); //     acLine_1.SetDatabaseDefaults(); acLine_1.Color = color_Pink; //          ms.AppendEntity(acLine_1); tr.AddNewlyCreatedDBObject(acLine_1, true); //    Arc acArc = new Arc(new Point3d(250, -200, 0), 25, -45 / 180.0 * Math.PI, 45 / 180.0 * Math.PI); //     acArc.SetDatabaseDefaults(); acArc.Color = color_Blue; //          ms.AppendEntity(acArc); tr.AddNewlyCreatedDBObject(acArc, true); //    Circle acCircle = new Circle(); //     acCircle.SetDatabaseDefaults(); acCircle.Center = new Point3d(325, -200, 0); acCircle.Radius = 25; acCircle.Color = color_LightGreen; //          ms.AppendEntity(acCircle); tr.AddNewlyCreatedDBObject(acCircle, true); //    "block-1" //      BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); //  ObjectID  ObjectId btrId = bt["block-1"]; //    ,   ID   BlockReference br = new BlockReference(new Point3d(400, -200, 0), btrId); //          ms.AppendEntity(br); tr.AddNewlyCreatedDBObject(br, true); //    "block-2" //  ObjectID  btrId = bt["block-2"]; //    ,   ID   br = new BlockReference(new Point3d(475, -200, 0), btrId); //          ms.AppendEntity(br); tr.AddNewlyCreatedDBObject(br, true); //      db.Clayer = currentLayer; //   tr.Commit(); } } //      public void Initialize() { createLayers(); createBlock_1(); createBlock_2(); layer_0_createObjects(); layer_1_createObjects(); layer_2_createObjects(); } //  Terminate() ,    IExtensionApplication public void Terminate() { } ////////////////////////////////////////////////////////////// //     (<<MODEL SPACE>>) ////////////////////////////////////////////////////////////// //      ( 1) [CommandMethod("Habr_IterateThroughAllObjects_1")] public void iterateThroughAllObjects_1() { //    Database db = HostApplicationServices.WorkingDatabase; //   using (Transaction tr = db.TransactionManager.StartTransaction()) { //      (ModelSpace) BlockTableRecord ms = (BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead); // ""       foreach (ObjectId id in ms) { //       Entity Entity entity = (Entity)tr.GetObject(id, OpenMode.ForRead); //     (entity.Layer),  (entity.GetType().ToString())   (entity.Color)   acad.DocumentManager.MdiActiveDocument.Editor.WriteMessage(string.Format("\nLayer:{0}; Type:{1}; Color: {2},{3},{4}\n", entity.Layer, entity.GetType().ToString(), entity.Color.Red.ToString(), entity.Color.Green.ToString(), entity.Color.Blue.ToString())); } tr.Commit(); } } //     ( 1) [CommandMethod("Habr_FindCircles_1")] public void findCircles_1() { //    Database db = HostApplicationServices.WorkingDatabase; //   using (Transaction tr = db.TransactionManager.StartTransaction()) { //      (ModelSpace) BlockTableRecord ms = (BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead); // ""       foreach (ObjectId id in ms) { //       Entity Entity entity = (Entity)tr.GetObject(id, OpenMode.ForRead); //    -    ,      if (entity.GetType() == typeof(Circle)) { acad.DocumentManager.MdiActiveDocument.Editor.WriteMessage(string.Format("\nLayer:{0}; Type:{1}; Color: {2},{3},{4}\n", entity.Layer, entity.GetType().ToString(), entity.Color.Red.ToString(), entity.Color.Green.ToString(), entity.Color.Blue.ToString())); } } tr.Commit(); } } //      ( 1) [CommandMethod("Habr_FindLightGreenObjects_1")] public void findLightGreenObjects_1() { //    Database db = HostApplicationServices.WorkingDatabase; //   using (Transaction tr = db.TransactionManager.StartTransaction()) { //      (ModelSpace) BlockTableRecord ms = (BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead); // ""       foreach (ObjectId id in ms) { //       Entity Entity entity = (Entity)tr.GetObject(id, OpenMode.ForRead); //    - ,     ,      if (entity.Color == Autodesk.AutoCAD.Colors.Color.FromRgb(128, 255, 64)) { acad.DocumentManager.MdiActiveDocument.Editor.WriteMessage(string.Format("\nLayer:{0}; Type:{1}; Color: {2},{3},{4}\n", entity.Layer, entity.GetType().ToString(), entity.Color.Red.ToString(), entity.Color.Green.ToString(), entity.Color.Blue.ToString())); } } tr.Commit(); } } //       "block-1" ( 1) [CommandMethod("Habr_FindBlocks_1")] public void findBlocks_1() { //    Database db = HostApplicationServices.WorkingDatabase; //   using (Transaction tr = db.TransactionManager.StartTransaction()) { //      (ModelSpace) BlockTableRecord ms = (BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead); // ""       foreach (ObjectId id in ms) { //       Entity Entity entity = (Entity)tr.GetObject(id, OpenMode.ForRead); // ,      if (entity.GetType() == typeof(BlockReference)) { //   -     BlockReference BlockReference br = (BlockReference)entity; //      - "block-1",     ,      if (br.Name == "block-1") { acad.DocumentManager.MdiActiveDocument.Editor.WriteMessage(string.Format("\nLayer:{0}; Type:{1}; Color: {2},{3},{4}\n", entity.Layer, entity.GetType().ToString(), entity.Color.Red.ToString(), entity.Color.Green.ToString(), entity.Color.Blue.ToString())); } } } tr.Commit(); } } ////////////////////////////////////////////////////////////// //     (<<EDITOR.SELECTALL>>) ////////////////////////////////////////////////////////////// //      ( 2) [CommandMethod("Habr_IterateThroughAllObjects_2")] public void iterateThroughAllObjects_2() { //    Editor   Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; //       // !         ! PromptSelectionResult selRes = ed.SelectAll(); //    -    if (selRes.Status != PromptStatus.OK) { ed.WriteMessage("\nError!\n"); return; } //   ID  ObjectId[] ids = selRes.Value.GetObjectIds(); //   using (Transaction tr = db.TransactionManager.StartTransaction()) { // ""     foreach (ObjectId id in ids) { //       Entity Entity entity = (Entity)tr.GetObject(id, OpenMode.ForRead); //     (entity.Layer),  (entity.GetType().ToString())   (entity.Color)   acad.DocumentManager.MdiActiveDocument.Editor.WriteMessage(string.Format("\nLayer:{0}; Type:{1}; Color: {2},{3},{4}\n", entity.Layer, entity.GetType().ToString(), entity.Color.Red.ToString(), entity.Color.Green.ToString(), entity.Color.Blue.ToString())); } tr.Commit(); } } //     ( 2) [CommandMethod("Habr_FindCircles_2")] public void findCircles_2() { //    Editor   Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; //  ,        TypedValue[] filterlist = new TypedValue[1]; //   (0) ,      //   ("CIRCLE") -   filterlist[0] = new TypedValue(0, "CIRCLE"); //   SelectionFilter filter = new SelectionFilter(filterlist); //         // !         ! PromptSelectionResult selRes = ed.SelectAll(filter); //    -    if (selRes.Status != PromptStatus.OK) { ed.WriteMessage("\nError!\n"); return; } //   ID  ObjectId[] ids = selRes.Value.GetObjectIds(); //   using (Transaction tr = db.TransactionManager.StartTransaction()) { // ""     foreach (ObjectId id in ids) { //       Entity Entity entity = (Entity)tr.GetObject(id, OpenMode.ForRead); //    ,      acad.DocumentManager.MdiActiveDocument.Editor.WriteMessage(string.Format("\nLayer:{0}; Type:{1}; Color: {2},{3},{4}\n", entity.Layer, entity.GetType().ToString(), entity.Color.Red.ToString(), entity.Color.Green.ToString(), entity.Color.Blue.ToString())); } tr.Commit(); } } ////////////////////////////////////////////////////////////// //   ////////////////////////////////////////////////////////////// //     [CommandMethod("Habr_EraseCircles_2")] public void eraseCircles_2() { //    Editor   Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; //  ,        TypedValue[] filterlist = new TypedValue[1]; //   (0) ,      //   ("CIRCLE") -   filterlist[0] = new TypedValue(0, "CIRCLE"); //   SelectionFilter filter = new SelectionFilter(filterlist); //         // !         ! PromptSelectionResult selRes = ed.SelectAll(filter); //    -    if (selRes.Status != PromptStatus.OK) { ed.WriteMessage("\nError!\n"); return; } //   ID  ObjectId[] ids = selRes.Value.GetObjectIds(); //   using (Transaction tr = db.TransactionManager.StartTransaction()) { // ""     foreach (ObjectId id in ids) { //       Entity Entity entity = (Entity)tr.GetObject(id, OpenMode.ForRead); //      entity.UpgradeOpen(); //   entity.Erase(); } tr.Commit(); } } //         [CommandMethod("Habr_RepaintOrange_2")] public void repaintOrange_2() { //    Editor   Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; //       // !         ! PromptSelectionResult selRes = ed.SelectAll(); //    -    if (selRes.Status != PromptStatus.OK) { ed.WriteMessage("\nError!\n"); return; } //   ID  ObjectId[] ids = selRes.Value.GetObjectIds(); //   using (Transaction tr = db.TransactionManager.StartTransaction()) { // ""     foreach (ObjectId id in ids) { //       Entity Entity entity = (Entity)tr.GetObject(id, OpenMode.ForRead); //     entity.UpgradeOpen(); //     entity.Color = Autodesk.AutoCAD.Colors.Color.FromRgb(255, 128, 0); } tr.Commit(); } } //      [CommandMethod("Habr_ModifyCircles_2")] public void modifyCircles_2() { //    Editor   Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; //  ,        TypedValue[] filterlist = new TypedValue[1]; //   (0) ,      //   ("CIRCLE") -   filterlist[0] = new TypedValue(0, "CIRCLE"); //   SelectionFilter filter = new SelectionFilter(filterlist); //         // !         ! PromptSelectionResult selRes = ed.SelectAll(filter); //    -    if (selRes.Status != PromptStatus.OK) { ed.WriteMessage("\nError!\n"); return; } //   ID  ObjectId[] ids = selRes.Value.GetObjectIds(); //   using (Transaction tr = db.TransactionManager.StartTransaction()) { // ""     foreach (ObjectId id in ids) { //       Circle Circle cir = (Circle)tr.GetObject(id, OpenMode.ForRead); //     cir.UpgradeOpen(); //   cir.Radius = cir.Radius * 2; } tr.Commit(); } } //     [CommandMethod("Habr_MoveBlocks_2")] public void moveBlocks_2() { //    Editor   Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; //  ,        TypedValue[] filterlist = new TypedValue[1]; //   (0) ,      //   ("INSERT") -   filterlist[0] = new TypedValue(0, "INSERT"); //   SelectionFilter filter = new SelectionFilter(filterlist); //         // !         ! PromptSelectionResult selRes = ed.SelectAll(filter); //    -    if (selRes.Status != PromptStatus.OK) { ed.WriteMessage("\nError!\n"); return; } //   ID  ObjectId[] ids = selRes.Value.GetObjectIds(); //   using (Transaction tr = db.TransactionManager.StartTransaction()) { // ""     foreach (ObjectId id in ids) { //       BlockReference BlockReference br = (BlockReference)tr.GetObject(id, OpenMode.ForRead); //     br.UpgradeOpen(); //    br.Position = Point3d.Origin; } tr.Commit(); } } ////////////////////////////////////////////////////////////// //     (<< >>) ////////////////////////////////////////////////////////////// //      ( 3) // !   ! [CommandMethod("Habr_IterateThroughAllObjects_3")] public void iterateThroughAllObjects_3() { Database db = HostApplicationServices.WorkingDatabase; Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; long amount = 0; Dictionary<string, int> d = new Dictionary<string, int>(); ObjectId id = ObjectId.Null; for (long i = db.BlockTableId.Handle.Value; i < db.Handseed.Value; i++) { Handle h = new Handle(i); if (db.TryGetObjectId(h, out id) && !id.IsNull && id.IsValid && !id.IsErased) { string t = id.ObjectClass.DxfName; amount++; if (d.ContainsKey(t)) d[t]++; else d.Add(t, 1); } } foreach (KeyValuePair<string, int> kvp in d) ed.WriteMessage("\n{0}: {1} ", kvp.Key, kvp.Value); ed.WriteMessage("\nTotal {0} objects in drawing\n", amount); } } } } 


As always, I will be glad to any feedback and comments.

Source: https://habr.com/ru/post/262953/


All Articles