TheSwamp

Code Red => .NET => Topic started by: It's Alive! on January 01, 2010, 11:22:25 AM

Title: SelectionFilterBuilder
Post by: It's Alive! on January 01, 2010, 11:22:25 AM
Just reading David's blog  http://blog.davidkblackmon.com/  
here is my easier way for C#  :laugh:

Code: [Select]
using System.Collections.Generic;
using System.Text;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;

namespace ExecMethod
{
 public class SelectionFilterBuilder : List<TypedValue>
 {
  public SelectionFilterBuilder()
  {
  }
  public SelectionFilterBuilder(DxfCode code, params string[] list)
  {
   base.Add(new TypedValue((short)code, FormatString(list)));
  }
  // Methods
  public void AddDxfCode(DxfCode code, object val)
  {
   base.Add(new TypedValue((short)code, val));
  }

  public void AddEntityFilter(params string[] list)
  {
   base.Add(new TypedValue(0, FormatString(list)));
  }

  public void AddLayerFilter(params string[] list)
  {
   base.Add(new TypedValue(8, FormatString(list)));
  }

  internal static string FormatString(params string[] list)
  {
   StringBuilder sb = new StringBuilder();
   foreach (string s in list)
   {
    sb.Append(s);
    sb.Append(",");
   }
   sb.Remove(sb.Length - 1, 1);
   return sb.ToString();
  }

  public static implicit operator SelectionFilter(SelectionFilterBuilder src)
  {
   return new SelectionFilter(src.ToArray());
  }
 }
}

then

Code: [Select]
 [CommandMethod("doit")]
  static public void doit()
  {
   Editor acDocEd = Application.DocumentManager.MdiActiveDocument.Editor;

   var builder = new SelectionFilterBuilder();
   builder.AddEntityFilter("CIRCLE","LINE");
   builder.AddLayerFilter("1","2");
   var acSSPrompt = acDocEd.GetSelection(builder);

   if (acSSPrompt.Status == PromptStatus.OK)
   {
    SelectionSet acSSet = acSSPrompt.Value;
    Application.ShowAlertDialog(String.Format("{0}: ",acSSet.Count));
    return;
   }
   Application.ShowAlertDialog("Number of objects selected: 0");
  }

or

Code: [Select]
  [CommandMethod("doit")]
  static public void doit()
  {
   Editor acDocEd = Application.DocumentManager.MdiActiveDocument.Editor;
   var builder = new SelectionFilterBuilder(DxfCode.Start, "CIRCLE","LINE");
   var acSSPrompt = acDocEd.GetSelection(builder);

   if (acSSPrompt.Status == PromptStatus.OK)
   {
    SelectionSet acSSet = acSSPrompt.Value;
    Application.ShowAlertDialog(String.Format("{0}: ",acSSet.Count));
    return;
   }
   Application.ShowAlertDialog("Number of objects selected: 0");
  }
Title: Re: SelectionFilterBuilder
Post by: xsfhlzh on January 03, 2010, 09:41:15 AM
That's good
I have improved a bit, so that may be more concise writing

Code: [Select]
using System;
using System.Collections.Generic;
using System.Text;

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

namespace TlsCad.Collections
{
    /// <summary>
    /// TypedValue Collection
    /// </summary>
    public class ResultList : List<TypedValue>
    {

        public ResultList()
            : base()
        { }

        public ResultList(IEnumerable<TypedValue> collection)
            : base(collection)
        { }

        public void Add(int typeCode, object obj)
        {
            base.Add(new TypedValue(typeCode, obj));
        }

        public void Add(LispDataType type, object obj)
        {
            base.Add(new TypedValue((int)type, obj));
        }

        public void Add(DxfCode type, object obj)
        {
            base.Add(new TypedValue((int)type, obj));
        }

        public override string ToString()
        {
            return ((ResultBuffer)this).ToString();
        }

        public static implicit operator TypedValue[](ResultList rlst)
        {
            return rlst.ToArray();
        }

        public static implicit operator ResultBuffer(ResultList rlst)
        {
            return new ResultBuffer(rlst.ToArray());
        }

        public static implicit operator SelectionFilter(ResultList rlst)
        {
            return new SelectionFilter(rlst.ToArray());
        }

    }
}

Test Code
Code: [Select]
            PromptSelectionResult res4 =
                ed.SelectAll(
                    new ResultList
                    {
                        {-4,"<or"},
                            {-4,"<and"},
                                {0, "Line"},
                                {8, "01"},
                            {-4,"and>"},
                            {-4,"<and"},
                                {0, "Circle"},
                                {8, "02"},
                            {-4,"and>"},
                        {-4,"or>"}
                    });
Title: Re: SelectionFilterBuilder
Post by: xsfhlzh on January 03, 2010, 09:47:39 AM
Another version

Code: [Select]
using System;
using System.Collections.Generic;
using System.Text;

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

namespace TlsCad.Collections
{

    /// <summary>
    /// TypedValue Tree
    /// </summary>
    ///

    public enum ResultType
    {
        Node,
        List,
        DottedPair,
        RelationalOperator,
        LogicalOperator,
    }



    public class ResultTree : IEnumerable
    {
        ResultType _type;
        TypedValue _value;
        List<ResultTree> _lst = new List<ResultTree>();

        public ResultTree this[int index]
        {
            get
            {
                if (_lst.Count==0)
                {
                    if(index==0)
                    {
                        return this;
                    }
                }
                else
                {
                    if (index>=0 && index < _lst.Count)
                    {
                        return _lst[index];
                    }
                }

                return null;

            }
        }

        public TypedValue TypedValue
        {
            get { return _value; }
        }

        public List<ResultTree> Nodes
        {
            get { return _lst; }
        }

        public ResultType Type
        {
            get { return _type; }
        }

        public ResultTree()
        {
            _type = ResultType.Node;
        }

        public ResultTree(TypedValue value)
            :this()
        {
            _value = value;
        }

        public ResultTree(int typeCode, object obj)
            : this(new TypedValue(typeCode, obj))
        { }

        public ResultTree(LispDataType type, object obj)
            : this(new TypedValue((int)type, obj))
        { }

        public ResultTree(DxfCode type, object obj)
            : this(new TypedValue((int)type, obj))
        { }


        public ResultTree(string operatorContext, bool isLogicalOperator)
        {
            _type = isLogicalOperator ? ResultType.LogicalOperator : ResultType.RelationalOperator;
            _value = new TypedValue(-4, operatorContext);
        }

        public ResultTree(string operatorContext)
            : this(operatorContext, true)
        { }

        public ResultTree(ResultType type)
        {
            _type = type;
        }

        public void Add(TypedValue value)
        {
            _lst.Add(new ResultTree(value));
        }

        public void Add(int typeCode, object obj)
        {
            _lst.Add(new ResultTree(typeCode, obj));
        }

        public void Add(LispDataType type, object obj)
        {
            _lst.Add(new ResultTree(type, obj));
        }

        public void Add(DxfCode type, object obj)
        {
            _lst.Add(new ResultTree(type, obj));
        }

        public void Add(ResultTree rt)
        {
            _lst.Add(rt);
        }

        public void Add(short value)
        {
            _lst.Add(new ResultTree(LispDataType.Int16, value));
        }

        public void Add(int value)
        {
            _lst.Add(new ResultTree(LispDataType.Int32, value));
        }

        public void Add(double value)
        {
            _lst.Add(new ResultTree(LispDataType.Double, value));
        }

        public void Add(string value)
        {
            _lst.Add(new ResultTree(LispDataType.Text, value));
        }

        public void Add(Point2d value)
        {
            _lst.Add(new ResultTree(LispDataType.Point2d, value));
        }

        public void Add(Point3d value)
        {
            _lst.Add(new ResultTree(LispDataType.Point3d, value));
        }

        public void Add(ObjectId value)
        {
            _lst.Add(new ResultTree(LispDataType.ObjectId, value));
        }

        public void Add(SelectionSet value)
        {
            _lst.Add(new ResultTree(LispDataType.SelectionSet, value));
        }

        public static implicit operator SelectionFilter(ResultTree rtree)
        {
            return new SelectionFilter(rtree.ToArray());
        }

        public static implicit operator ResultBuffer(ResultTree rtree)
        {
            return new ResultBuffer(rtree.ToArray());
        }

        public TypedValue[] ToArray()
        {
            List<TypedValue> values = new List<TypedValue>();
            GetValues(values);
            return values.ToArray();
        }

        private void GetValues(List<TypedValue> values)
        {
            switch (_type)
            {
                case  ResultType.Node:
                    if (_lst.Count == 0)
                    {
                        values.Add(_value);
                    }
                    else
                    {
                        _lst.ForEach(rtree => rtree.GetValues(values));
                    }
                    break;
                case ResultType.List:
                    values.Add(new TypedValue((int)LispDataType.ListBegin));
                    _lst.ForEach(rtree => rtree.GetValues(values));
                    values.Add(new TypedValue((int)LispDataType.ListEnd));
                    break;
                case ResultType.DottedPair:
                    values.Add(new TypedValue((int)LispDataType.ListBegin));
                    _lst.ForEach(rtree => rtree.GetValues(values));
                    values.Add(new TypedValue((int)LispDataType.DottedPair));
                    break;
                case ResultType.RelationalOperator:
                    values.Add(_value);
                    _lst.ForEach(rtree => rtree.GetValues(values));
                    break;
                case ResultType.LogicalOperator:
                    values.Add(new TypedValue(-4, "<" + _value.Value));
                    _lst.ForEach(rtree => rtree.GetValues(values));
                    values.Add(new TypedValue(-4, _value.Value + ">"));
                    break;

            }

        }

        #region IEnumerable 成员

        IEnumerator IEnumerable.GetEnumerator()
        {
            return _lst.GetEnumerator();
        }

        #endregion
    }
}

The complete test code
Code: [Select]
        [CommandMethod("t9")]
        public static void Test9()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            PromptSelectionResult res1 =
                ed.SelectAll(
                    new ResultTree
                    {
                        new ResultTree(">,>,*",false)
                        {
                            {10, new Point3d()}
                        },
                        new ResultTree("<,<,*",false)
                        {
                            {10,new Point3d(10,10,0)}
                        }
                    });

            PromptSelectionResult res2 =
                ed.SelectAll(
                    new ResultList
                    {
                        {-4,">,>,*"},
                        {10, new Point3d()},
                        {-4,"<,<,*"},
                        {10,new Point3d(10,10,0)}
                    });


            PromptSelectionResult res3 =
                ed.SelectAll(
                    new ResultTree("or")
                    {
                        new ResultTree("and")
                        {
                            {0, "Line"},
                            {8, "01"}
                        },
                        new ResultTree("and")
                        {
                            {0, "Circle"},
                            {8, "02"}
                        }
                    });

            PromptSelectionResult res4 =
                ed.SelectAll(
                    new ResultList
                    {
                        {-4,"<or"},
                            {-4,"<and"},
                                {0, "Line"},
                                {8, "01"},
                            {-4,"and>"},
                            {-4,"<and"},
                                {0, "Circle"},
                                {8, "02"},
                            {-4,"and>"},
                        {-4,"or>"}
                    });
           

        }

        [CommandMethod("t10")]
        public static void Test10()
        {

            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            PromptEntityResult res = ed.GetEntity("Select a Entity:");

            using (DBTransaction tr = new DBTransaction())
            {
                tr.OpenRegAppTable(OpenMode.ForWrite);
                tr.RegApp("MyApp");
                Entity ent = tr.GetObject(res.ObjectId, OpenMode.ForWrite) as Entity;

                ent.XData =
                    new ResultList
                    {
                        {1001, "MyApp"},
                        {1000, "This is a Test"},
                        {DxfCode.ExtendedDataInteger16, 12}
                    };
            }
        }

        [LispFunction("lsptest1")]
        public static ResultBuffer LTest1(ResultBuffer rb)
        {

            ResultTree rtree =
                new ResultTree(ResultType.List)
                {
                    1,
                    new ResultTree(ResultType.DottedPair)
                    {
                        10,
                        new Point3d(10, 10, 0)
                    }
                };

            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            return rtree;

        }
Title: Re: SelectionFilterBuilder
Post by: It's Alive! on January 03, 2010, 09:53:37 AM
Nice work! That's similar to  this http://www.theswamp.org/index.php?topic=14495.msg186823#msg186823

I think the goal was to remove the need to remember the DXF group codes or having to look up from an Enum,
and maybe something like AddEntityFilter or AddLayerFilter would make building the filter more intuitive
Title: Re: SelectionFilterBuilder
Post by: penchaoxp on January 03, 2010, 09:57:28 AM
ding
Title: Re: SelectionFilterBuilder
Post by: xsfhlzh on January 03, 2010, 10:16:54 AM
Nice work! That's similar to  this http://www.theswamp.org/index.php?topic=14495.msg186823#msg186823

I think the goal was to remove the need to remember the DXF group codes or having to look up from an Enum,
and maybe something like AddEntityFilter or AddLayerFilter would make building the filter more intuitive


However, the complex filtering is not a good realization of
For example, to select "01-layer line" or "02-layer Circle"

Can look at the code ResultTree class
Title: Re: SelectionFilterBuilder
Post by: It's Alive! on January 03, 2010, 06:05:09 PM
I agree, it would be difficult to build complex selection set filters with a user friendly class.
I like your ResultTree class, that's great work!
Title: Re: SelectionFilterBuilder
Post by: xsfhlzh on January 03, 2010, 08:45:09 PM
I agree, it would be difficult to build complex selection set filters with a user friendly class.
I like your ResultTree class, that's great work!


Thanks Daniel, I am truly honored.
Title: Re: SelectionFilterBuilder
Post by: xsfhlzh on January 04, 2010, 08:10:59 AM
Operator Overloading
This is more fun,:)
Code: [Select]
using System;
using System.Collections.Generic;
using System.Text;

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

namespace TlsCad.Collections
{

    public enum ResultType
    {
        Node,
        List,
        DottedPair,
        RelationalOperator,
        LogicalOperator,
    }

    /// <summary>
    /// TypedValue Tree
    /// </summary>
    public class ResultTree : IEnumerable
    {
        ResultType _type;
        TypedValue _value;
        List<ResultTree> _lst = new List<ResultTree>();

        public ResultTree this[int index]
        {
            get
            {
                if (_lst.Count==0)
                {
                    if(index==0)
                    {
                        return this;
                    }
                }
                else
                {
                    if (index>=0 && index < _lst.Count)
                    {
                        return _lst[index];
                    }
                }

                return null;

            }
        }

        public TypedValue TypedValue
        {
            get { return _value; }
        }

        public List<ResultTree> Nodes
        {
            get { return _lst; }
        }

        public ResultType Type
        {
            get { return _type; }
        }

        #region IEnumerable 成员

        IEnumerator IEnumerable.GetEnumerator()
        {
            return _lst.GetEnumerator();
        }

        #endregion

        public ResultTree()
        {
            _type = ResultType.Node;
        }

        public ResultTree(TypedValue value)
            :this()
        {
            _value = value;
        }

        public ResultTree(int typeCode, object obj)
            : this(new TypedValue(typeCode, obj))
        { }

        public ResultTree(LispDataType type, object obj)
            : this(new TypedValue((int)type, obj))
        { }

        public ResultTree(DxfCode type, object obj)
            : this(new TypedValue((int)type, obj))
        { }


        public ResultTree(string operatorContext, bool isLogicalOperator)
        {
            _type = isLogicalOperator ? ResultType.LogicalOperator : ResultType.RelationalOperator;
            _value = new TypedValue(-4, operatorContext);
        }

        public ResultTree(string operatorContext)
            : this(operatorContext, true)
        { }

        public ResultTree(ResultType type)
        {
            _type = type;
        }

        public void Add(TypedValue value)
        {
            _lst.Add(new ResultTree(value));
        }

        public void Add(int typeCode, object obj)
        {
            _lst.Add(new ResultTree(typeCode, obj));
        }

        public void Add(LispDataType type, object obj)
        {
            _lst.Add(new ResultTree(type, obj));
        }

        public void Add(DxfCode type, object obj)
        {
            _lst.Add(new ResultTree(type, obj));
        }

        public void Add(ResultTree rt)
        {
            _lst.Add(rt);
        }

        public void Add(short value)
        {
            _lst.Add(new ResultTree(LispDataType.Int16, value));
        }

        public void Add(int value)
        {
            _lst.Add(new ResultTree(LispDataType.Int32, value));
        }

        public void Add(double value)
        {
            _lst.Add(new ResultTree(LispDataType.Double, value));
        }

        public void Add(string value)
        {
            _lst.Add(new ResultTree(LispDataType.Text, value));
        }

        public void Add(Point2d value)
        {
            _lst.Add(new ResultTree(LispDataType.Point2d, value));
        }

        public void Add(Point3d value)
        {
            _lst.Add(new ResultTree(LispDataType.Point3d, value));
        }

        public void Add(ObjectId value)
        {
            _lst.Add(new ResultTree(LispDataType.ObjectId, value));
        }

        public void Add(SelectionSet value)
        {
            _lst.Add(new ResultTree(LispDataType.SelectionSet, value));
        }

        private void GetValues(List<TypedValue> values)
        {
            switch (_type)
            {
                case  ResultType.Node:
                    if (_lst.Count == 0)
                    {
                        values.Add(_value);
                    }
                    else
                    {
                        _lst.ForEach(rtree => rtree.GetValues(values));
                    }
                    break;
                case ResultType.List:
                    values.Add(new TypedValue((int)LispDataType.ListBegin));
                    _lst.ForEach(rtree => rtree.GetValues(values));
                    values.Add(new TypedValue((int)LispDataType.ListEnd));
                    break;
                case ResultType.DottedPair:
                    values.Add(new TypedValue((int)LispDataType.ListBegin));
                    _lst.ForEach(rtree => rtree.GetValues(values));
                    values.Add(new TypedValue((int)LispDataType.DottedPair));
                    break;
                case ResultType.RelationalOperator:
                    values.Add(_value);
                    _lst.ForEach(rtree => rtree.GetValues(values));
                    break;
                case ResultType.LogicalOperator:
                    values.Add(new TypedValue(-4, "<" + _value.Value));
                    _lst.ForEach(rtree => rtree.GetValues(values));
                    values.Add(new TypedValue(-4, _value.Value + ">"));
                    break;

            }
        }

        public TypedValue[] ToArray()
        {
            List<TypedValue> values = new List<TypedValue>();
            GetValues(values);
            return values.ToArray();
        }

        public static implicit operator SelectionFilter(ResultTree rtree)
        {
            return new SelectionFilter(rtree.ToArray());
        }

        public static implicit operator ResultBuffer(ResultTree rtree)
        {
            return new ResultBuffer(rtree.ToArray());
        }

        public override string ToString()
        {
            return ((ResultBuffer)this).ToString();
        }

        private void MakeLogicalOperator(string operatorContext, ResultTree res)
        {
            if (_type == ResultType.LogicalOperator && _value.Value.ToString() == operatorContext)
            {
                _lst.ForEach(rtree => res.Add(rtree));
            }
            else
            {
                res.Add(this);
            }
        }

        public static ResultTree operator !(ResultTree rt1)
        {
            ResultTree rt = new ResultTree("not") { rt1 };
            return rt;
        }

        public static ResultTree operator &(ResultTree rt1, ResultTree rt2)
        {

            ResultTree rt = new ResultTree("and");
            rt1.MakeLogicalOperator("and", rt);
            rt2.MakeLogicalOperator("and", rt);
            return rt;

        }

        public static ResultTree operator |(ResultTree rt1, ResultTree rt2)
        {
            ResultTree rt = new ResultTree("or");
            rt1.MakeLogicalOperator("or", rt);
            rt2.MakeLogicalOperator("or", rt);
            return rt;
        }

        public static ResultTree operator ^(ResultTree rt1, ResultTree rt2)
        {
            return
                new ResultTree("xor")
                {
                    rt1,
                    rt2
                };
        }


    }
}

test code
Code: [Select]
            ResultTree rt =
                new ResultTree(0, "Line") & new ResultTree(8, "01") & !new ResultTree(10, new Point3d())
                |
                new ResultTree(0, "Circle") & new ResultTree(8, "02");

            Application.ShowAlertDialog(rt.ToString());
Title: Re: SelectionFilterBuilder
Post by: Bryco on January 10, 2010, 12:35:03 PM
I've been testing selectionsets versus objectIds for a selectall.
If you are only checking for types (circle arc etc) the objectId method is always faster.
However when you also check for layers etc, the selectionset is faster.
The function below is fairly easy to use
Code: [Select]
         static ObjectIdCollection SelectAll(string dxfNames)
         {
             dxfNames = dxfNames.ToUpper();
             string[] dxf=dxfNames.Split(new char[] {','},StringSplitOptions.RemoveEmptyEntries);
             Document doc = acadApp.DocumentManager.MdiActiveDocument;
             Database db = doc.Database;
             ObjectIdCollection ids = new ObjectIdCollection();
             using (Transaction tr = db.TransactionManager.StartTransaction())
             {
                 BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                 DBDictionary ld = (DBDictionary)tr.GetObject(db.LayoutDictionaryId, OpenMode.ForRead);
                 Layout layout = null;
                 foreach (DBDictionaryEntry l in ld)
                 {
                     layout = tr.GetObject(l.m_value, OpenMode.ForRead) as Layout;
                     BlockTableRecord space = (BlockTableRecord)tr.GetObject
                         (layout.BlockTableRecordId, OpenMode.ForRead);
                     foreach (ObjectId id in space)
                     {
                         foreach (string name in dxf)
                         {
                             if (id.ObjectClass.DxfName == name)
                             {
                                 ids.Add(id);
                                 break;
                             }
                         }
                     }
                 }
                 tr.Commit();
             }
             return ids;
         } // end SelectAll
and how to call it
Code: [Select]
move = Matrix3d.Displacement(new Vector3d(0, -1, 0));
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                foreach (ObjectId id in SelectAll("Line,Arc,Circle,ellipse"))
                {     
                    c = (Curve)tr.GetObject(id, OpenMode.ForRead);
                    if (c.Layer == "0")
                    {
                        count++;
                        c.UpgradeOpen();
                        c.TransformBy(move);
                    }
                }
                tr.Commit();
            }
Title: Re: SelectionFilterBuilder
Post by: It's Alive! on January 11, 2010, 03:57:39 AM
what about this?  :lol:

Code: [Select]
using System.Collections.Generic;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using AcDb = Autodesk.AutoCAD.DatabaseServices;

[assembly: CommandClass(typeof(ExecMethod.Commands))]
namespace ExecMethod
{
 public class ObjectIdDictionary : Dictionary<string, List<ObjectId>>
 {
  private ObjectIdDictionary() { }
  public ObjectIdDictionary(Database database, ObjectId spaceid)
  {
   AcDb.TransactionManager manager = database.TransactionManager;
   using (Transaction transaction = manager.StartTransaction())
   {
    BlockTableRecord blockTableRecord =
     transaction.GetObject(spaceid, OpenMode.ForRead)
     as BlockTableRecord;
    foreach (ObjectId e in blockTableRecord)
    {
     string key = e.ObjectClass.DxfName;
     if (this.ContainsKey(key))
      this[key].Add(e);
     else
      this.Add(key, new List<ObjectId> { e });
    }
    transaction.Commit();
   }
  }
 }

 public static class Commands
 {
  [CommandMethod("doit")]
  static public void doit()
  {
   Database database = HostApplicationServices.WorkingDatabase;
   ObjectIdDictionary dict = new ObjectIdDictionary(database, database.CurrentSpaceId);

   AcDb.TransactionManager manager = database.TransactionManager;
   using (Transaction transaction = manager.StartTransaction())
   {
    if (dict.ContainsKey("POINT"))
    {
     foreach (ObjectId e in dict["POINT"])
     {
      DBPoint o = transaction.GetObject(e, OpenMode.ForWrite) as DBPoint;
      o.ColorIndex = 1;
     }
    }

    if (dict.ContainsKey("LINE"))
    {
     foreach (ObjectId e in dict["LINE"])
     {
      Line o = transaction.GetObject(e, OpenMode.ForWrite) as Line;
      o.ColorIndex = 2;
     }
    }

    if (dict.ContainsKey("LWPOLYLINE"))
    {
     foreach (ObjectId e in dict["LWPOLYLINE"])
     {
      Polyline o = transaction.GetObject(e, OpenMode.ForWrite) as Polyline;
      o.ColorIndex = 3;
     }
    }

    if (dict.ContainsKey("CIRCLE"))
    {
     foreach (ObjectId e in dict["CIRCLE"])
     {
      Circle o = transaction.GetObject(e, OpenMode.ForWrite) as Circle;
      o.ColorIndex = 4;
     }
     transaction.Commit();
    }
   }
  }
 }
}
Title: Re: SelectionFilterBuilder
Post by: xsfhlzh on January 11, 2010, 06:51:11 AM
I agree, but only through AC2010
Test it use Linq :-)

Code: [Select]
        [CommandMethod("t8")]
        public static void Test8()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForRead);

                var dict = from ObjectId id in btr
                         group id by id.ObjectClass.DxfName;

               
                foreach (var ids in dict)
                {

                    switch (ids.Key)
                    {
                        case "LINE":
                            foreach (var id in ids)
                            {
                                Entity ent = id.GetObject(OpenMode.ForWrite) as Entity;
                                ent.ColorIndex = 1;
                            }
                            break;
                        case "CIRCLE":
                            foreach (var id in ids)
                            {
                                Entity ent = id.GetObject(OpenMode.ForWrite) as Entity;
                                ent.ColorIndex = 3;
                            }
                            break;
                    }
                }

                tr.Commit();
            }
        }
Title: Re: SelectionFilterBuilder
Post by: It's Alive! on January 11, 2010, 07:58:16 AM
Ha! that is cool   8-)
Title: Re: SelectionFilterBuilder
Post by: Bryco on January 11, 2010, 10:50:42 AM
The linq is about the same as Daniel's dictionary method (sometimes slightly slower)
Both are faster than mine which seems to point to objectidcollections being a bit slow.
It seems the dwg gets bigger, so I think you need to delete the dictionary after using it.
Title: Re: SelectionFilterBuilder
Post by: It's Alive! on January 11, 2010, 05:33:59 PM
Bryco, compare this to yours for speed

Code: [Select]
static ObjectIdCollection SelectAll(string dxfNames)
  {
   dxfNames = dxfNames.ToUpper();
   List<String> dxf = new List<string>
    (dxfNames.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries));
   Document doc = AcAp.Application.DocumentManager.MdiActiveDocument;
   Database db = doc.Database;
   ObjectIdCollection ids = new ObjectIdCollection();
   using (Transaction tr = db.TransactionManager.StartTransaction())
   {
    BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
    DBDictionary ld = (DBDictionary)tr.GetObject(db.LayoutDictionaryId, OpenMode.ForRead);
    Layout layout = null;
    foreach (DBDictionaryEntry l in ld)
    {
     layout = tr.GetObject(l.m_value, OpenMode.ForRead) as Layout;
     BlockTableRecord space = (BlockTableRecord)tr.GetObject
         (layout.BlockTableRecordId, OpenMode.ForRead);

     foreach (ObjectId id in space)
     {
       if (dxf.Contains(id.ObjectClass.DxfName))
       {
        ids.Add(id);
       }
     }
    }
    tr.Commit();
   }
   return ids;
  } // end SelectAll
Title: Re: SelectionFilterBuilder
Post by: Bryco on January 11, 2010, 06:44:49 PM
That's the one I compared it to. I guess a collection is in inherently slower as it adds indexing.
Title: Re: SelectionFilterBuilder
Post by: It's Alive! on January 11, 2010, 07:47:45 PM
I had changed your inner loop, I just wondered if it made a difference
Title: Re: SelectionFilterBuilder
Post by: Bryco on January 12, 2010, 09:56:30 AM
SelectionSet count w/ 2 types  = 44 time=2880
using this filter filter = new TypedValue[] { new TypedValue(0, "Line,Arc,Circle,ellipse"), new TypedValue(8, "0") };
Objectid count w/ 2 types selectall = 44 time=10740
using "Line,Arc,Circle,ellipse" and then selectall as  I wrote then checking  for layer 0
Objectid count w/ 2 types selectall2 = 44 time=10940
using "Line,Arc,Circle,ellipse" and then selectall as  Daniel wrote then checking  for layer 0
dictionary = 44 time=7900   Daniel's dictioary
dictionary = 44 time=7940  xsfhlzh's Linq

There are almost 90000 entities in the dwg.

Daniel your version looks like it would do better but it still must go through the same amount of steps