Author Topic: How do I make a Typed Value for the actual color of an entity in Autocad .NET  (Read 5036 times)

0 Members and 1 Guest are viewing this topic.

damien_conroy

  • Mosquito
  • Posts: 4
I'm trying to select by color using the typed value below in a selection filter:

new TypedValue((int)DxfCode.Color, myColor)

The problem with this is that some entities have the color values 'byblock' or 'bylayer'. Is there a way to filter on the actual color value being displayed on screen?

I'm trying to select polylines in a large number of files, some with polylines on the wrong layer so I need to select by color too.


kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2166
  • class keyThumper<T>:ILazy<T>
Hi Damien, welcome to theSwamp.

Correct me if I'm incorrect please.

You want the program to select for you ( without your picking )
   Ignoring Frozen and locked and off Layers
   All polylines in the modelspace that either :
       have their color property set to <yourColor> OR
       if the pline has color ByLayer, and
           the Layer color is <yourColor>
   return the selection in an ObjectID array for you to work with

Is this the goal ??

If so, I'll have a play tonight. ( in about 5 hours )

Regards,
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2166
  • class keyThumper<T>:ILazy<T>
>>> some entities have the color values 'byblock' or 'bylayer'.

 'byblock' concerns me a bit. Do you want to also select plines inside blocks ??
or just those in ModelSpace ?


Added a note to explain.
long story short.
polylines in blocks don't actually live in modelspace, their home is the block.
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8928
  • AKA Daniel
seems like it would be easier to to iterate the space, since you already have to walk the layers

pseudo code
Code - Python: [Select]
  1. def getPlineIdsByColor(btr : Db.BlockTableRecord,clr : Db.Color) ->list[Db.ObjectId]:
  2.     ids = []
  3.     for id in btr.objectIds():
  4.         if not id.isDerivedFrom(Db.Polyline.desc()):
  5.             continue
  6.        
  7.         pline = Db.Polyline(id)
  8.         plineColor = pline.color()
  9.        
  10.         if plineColor.isByLayer():
  11.             layer = Db.LayerTableRecord(pline.layerId())
  12.             if layer.color() == clr:
  13.                 ids.append(id)
  14.         elif plineColor == clr:
  15.             ids.append(id)
  16.            
  17.     return ids
  18.  
« Last Edit: July 21, 2023, 03:24:58 AM by Pai Mei »

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2166
  • class keyThumper<T>:ILazy<T>
Got home early, so . .

according to the specs  :)

This is a little raw, and could do with some polish, but I think it will give you a good start.


Code - C#: [Select]
  1. using Autodesk.AutoCAD.DatabaseServices;
  2. using Autodesk.AutoCAD.EditorInput;
  3. using Autodesk.AutoCAD.Geometry;
  4. using Autodesk.AutoCAD.Runtime;
  5. using Kdub.Common;
  6. using System.Collections.Generic;
  7.  
  8. using CadApp = Autodesk.AutoCAD.ApplicationServices.Application;
  9. using Colors = Autodesk.AutoCAD.Colors;
  10.  
  11. [assembly: CommandClass(typeof(Common_Testing.Commands))]
  12.  
  13. namespace Common_Testing
  14. {
  15.    public class Commands
  16.    {
  17.       [CommandMethod("TEST_PL")]
  18.       public static void Test_PL()
  19.       {
  20.          var doc = CadApp.DocumentManager.MdiActiveDocument;
  21.          var db = doc.Database;
  22.          var ed = doc.Editor;
  23.  
  24.          int ByColorCount = 0;
  25.          int ByLayerCount = 0;
  26.          int targetColorIndex = 1;  // red
  27.          Colors.Color ACItargetColor = Colors.Color.FromColorIndex(Colors.ColorMethod.ByAci, (short)targetColorIndex);
  28.  
  29.          List<ObjectId> plineIds = new List<ObjectId>();
  30.  
  31.          using (Transaction tr = db.TransactionManager.StartTransaction())
  32.          {
  33.             var blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
  34.             var layerTable = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);
  35.             var modelSpace = (BlockTableRecord)tr.GetObject(blockTable[BlockTableRecord.ModelSpace], OpenMode.ForRead);
  36.  
  37.             RXClass polylineClass = RXObject.GetClass(typeof(Polyline));
  38.  
  39.             foreach (ObjectId objectId in modelSpace) // Look for Polylines
  40.             {
  41.                if (objectId.ObjectClass.IsDerivedFrom(polylineClass))
  42.                {
  43.                   var pline = (Polyline)tr.GetObject(objectId, OpenMode.ForRead);
  44.  
  45.                   if (pline.ColorIndex == targetColorIndex)
  46.                   {
  47.                      plineIds.Add(objectId);
  48.                      ByColorCount++;
  49.                   }
  50.                   else if (pline.Color.IsByLayer)
  51.                   {
  52.                      var layerId = layerTable[pline.Layer];
  53.  
  54.                      var layerRecord = (LayerTableRecord)tr.GetObject(layerId, OpenMode.ForRead);
  55.                      if (layerRecord.Color == ACItargetColor)
  56.                      {
  57.                         plineIds.Add(objectId);
  58.                         ByLayerCount++;
  59.                      }
  60.                   }
  61.                }
  62.             }
  63.             tr.Commit();
  64.          }
  65.          ed.WriteMessage($"{ByColorCount} ByColor Matches found\n");
  66.          ed.WriteMessage($"{ByLayerCount} ByLayer Matches found\n");
  67.       }
  68.    }
  69. }
  70.  

edit : cleanup
« Last Edit: July 21, 2023, 04:58:24 AM by kdub_nz »
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2166
  • class keyThumper<T>:ILazy<T>
Nice Daniel.

trounced me by 5 minutes ;)

looks like it helped with your Python Dev too :)  way cool.

Mine could do with being popped into a callable method.

. . after the opp comments :)
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8928
  • AKA Daniel
Exactly what I was thinking, the lisp sample I linked was injecting all the layers that have that color into the filter.
At that point, might as well just iterate the entities

Oops yes, it was a good python test, I missed the equal operator in my color wrapper, so yeah, I need to fix that
« Last Edit: July 21, 2023, 03:54:30 AM by Pai Mei »

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2166
  • class keyThumper<T>:ILazy<T>
Refactored to have a Main entry method and 2 supporting methods.

Works as anticipated: all polylines that were either Color 1 or on ByLayer Color 1 were changed to Color index 42   :-D

Code - C#: [Select]
  1. using Autodesk.AutoCAD.DatabaseServices;
  2. using Autodesk.AutoCAD.Runtime;
  3. using System.Collections.Generic;
  4. using CadApp = Autodesk.AutoCAD.ApplicationServices.Application;
  5. using Colors = Autodesk.AutoCAD.Colors;
  6.  
  7. [assembly: CommandClass(typeof(Common_Testing.Commands))]
  8.  
  9. namespace Common_Testing
  10. {
  11.    public class Commands
  12.    {
  13.       [CommandMethod("TEST_PLLayers")]
  14.       public static void Main_PLLayers()
  15.       {
  16.          var doc = CadApp.DocumentManager.MdiActiveDocument;
  17.          var db = doc.Database;
  18.          var ed = doc.Editor;
  19.  
  20.          int targetColorIndex = 1;
  21.  
  22.          using (Transaction tr = db.TransactionManager.StartTransaction())
  23.          {
  24.             List<ObjectId> resultList = CheckPolylineColors(db, targetColorIndex);
  25.  
  26.             // handle the returned polyline ObjectId's
  27.             //
  28.             int newColorIndex = 42;
  29.  
  30.             ChangePolylineColors(db, resultList, newColorIndex);
  31.  
  32.             tr.Commit();
  33.          }
  34.       }
  35.  
  36.       public static void ChangePolylineColors(Database db, List<ObjectId> plines, int colorIndex)
  37.       {
  38.          using Transaction tr = db.TransactionManager.TopTransaction;
  39.          {
  40.             foreach (ObjectId objectId in plines)
  41.             {
  42.                Polyline? pline = (Polyline)tr.GetObject(objectId, OpenMode.ForWrite);
  43.                if (pline != null)
  44.                {
  45.                   pline.ColorIndex = colorIndex;
  46.                }
  47.             }
  48.          }
  49.       }
  50.  
  51.       public static List<ObjectId> CheckPolylineColors(Database db, int targetColorIndex)
  52.       {
  53.          var ed = CadApp.DocumentManager.MdiActiveDocument.Editor;
  54.          List<ObjectId> plineIds = new List<ObjectId>();
  55.          Colors.Color ACItargetColor = Colors.Color.FromColorIndex(Colors.ColorMethod.ByAci, (short)targetColorIndex);
  56.          int ByColorCount = 0;
  57.          int ByLayerCount = 0;
  58.  
  59.          using Transaction tr = db.TransactionManager.TopTransaction;
  60.          {
  61.             var blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
  62.             var layerTable = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);
  63.             var modelSpace = (BlockTableRecord)tr.GetObject(blockTable[BlockTableRecord.ModelSpace], OpenMode.ForRead);
  64.  
  65.             RXClass polylineClass = RXObject.GetClass(typeof(Polyline));
  66.  
  67.             foreach (ObjectId objectId in modelSpace) // Look for Polylines
  68.             {
  69.                if (objectId.ObjectClass.IsDerivedFrom(polylineClass))
  70.                {
  71.                   var pline = (Polyline)tr.GetObject(objectId, OpenMode.ForRead);
  72.                   if (pline.ColorIndex == targetColorIndex)
  73.                   {
  74.                      plineIds.Add(objectId);
  75.                      ByColorCount++;
  76.                   }
  77.                   else if (pline.Color.IsByLayer)
  78.                   {
  79.                      var layerId = layerTable[pline.Layer];
  80.                      var layerRecord = (LayerTableRecord)tr.GetObject(layerId, OpenMode.ForRead);
  81.                      if (layerRecord.Color == ACItargetColor)
  82.                      {
  83.                         plineIds.Add(objectId);
  84.                         ByLayerCount++;
  85.                      }
  86.                   }
  87.                }
  88.             }
  89.          }
  90.          ed.WriteMessage($"{ByColorCount} ByColor Matches found\n");
  91.          ed.WriteMessage($"{ByLayerCount} ByLayer Matches found\n");
  92.  
  93.          return plineIds;
  94.       }
  95.    }
  96. }
  97.  
  98.  
  99.  
  100.  




« Last Edit: July 21, 2023, 06:06:25 AM by kdub_nz »
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8928
  • AKA Daniel
Nice code!

gile

  • Gator
  • Posts: 2522
  • Marseille, France
Hi,

Here's a way to build a selection filter.
Code - C#: [Select]
  1. var color = Color.FromColorIndex(ColorMethod.ByAci, (short)colorIndex);
  2. var layerNames = new List<string>();
  3. using (var tr = new OpenCloseTransaction())
  4. {
  5.     var layerTable = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);
  6.     foreach (ObjectId id in layerTable)
  7.     {
  8.         var layer = (LayerTableRecord)tr.GetObject(id, OpenMode.ForRead);
  9.         if (layer.Color == color)
  10.         {
  11.             layerNames.Add(layer.Name);
  12.         }
  13.     }
  14. }
  15.  
  16. var filter = new SelectionFilter(new[]
  17. {
  18.     new TypedValue(-4, "<or"),
  19.     new TypedValue(62, colorIndex),
  20.     new TypedValue(-4, "<and"),
  21.     new TypedValue(62, 256),
  22.     new TypedValue(8, string.Join(",", layerNames)),
  23.     new TypedValue(-4, "and>"),
  24.     new TypedValue(-4, "or>")
  25. });
Speaking English as a French Frog

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8928
  • AKA Daniel
nice gile!

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8928
  • AKA Daniel
thinking, I suppose using a selection set filter won’t work with true color?

gile

  • Gator
  • Posts: 2522
  • Marseille, France
thinking, I suppose using a selection set filter won’t work with true color?

Yes it does.
Code - C#: [Select]
  1.         [CommandMethod("CMD")]
  2.         public static void Cmd()
  3.         {
  4.             var doc = Application.DocumentManager.MdiActiveDocument;
  5.             var db = doc.Database;
  6.             var ed = doc.Editor;
  7.  
  8.             var color = Color.FromRgb(200, 120, 50);
  9.  
  10.             var layerNames = new List<string>();
  11.             using (var tr = new OpenCloseTransaction())
  12.             {
  13.                 var layerTable = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);
  14.                 foreach (ObjectId id in layerTable)
  15.                 {
  16.                     var layer = (LayerTableRecord)tr.GetObject(id, OpenMode.ForRead);
  17.                     if (layer.Color == color)
  18.                     {
  19.                         layerNames.Add(layer.Name);
  20.                     }
  21.                 }
  22.             }
  23.  
  24.             var filter = new SelectionFilter(new[]
  25.             {
  26.                 new TypedValue(-4, "<or"),
  27.                 new TypedValue(420, color.Red << 16 | color.Green << 8 | color.Blue ),
  28.                 new TypedValue(-4, "<and"),
  29.                 new TypedValue(62, 256),
  30.                 new TypedValue(8, string.Join(",", layerNames)),
  31.                 new TypedValue(-4, "and>"),
  32.                 new TypedValue(-4, "or>")
  33.             });
  34.  
  35.             var selection = ed.GetSelection(filter);
  36.  
  37.             if (selection.Status == PromptStatus.OK)
  38.                 ed.SetImpliedSelection(selection.Value);
  39.         }
Speaking English as a French Frog

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8928
  • AKA Daniel
Awesome!

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2166
  • class keyThumper<T>:ILazy<T>

Nice Gilles,
I'd forgotten how expressive the filters can be !

and I s'pose having the user actually select the candidated would be more familiar.

Regards,
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.