Author Topic: AutoCAD 2009,. Net API, to obtain certain information from entering the block  (Read 1859 times)

0 Members and 1 Guest are viewing this topic.

Andrey Bushman

  • Swamp Rat
  • Posts: 860
There is a definition of a dynamic block (see attached file). In determining the unit I have created a number of pens with which the entry block can be modified (stretched). Screen:



I need to programmatically find out the length of the horizontal line, selected on the screenshot. I created a hidden attribute called X2, and tied it to the desired property of primitive to me, putting a tick, they say "take the size of entering the block. " When creating a new occurrence of the attribute value is filled. But later, after a stretch in the screenshot shown on the handle, the attribute value X2 is no longer changing (regen / regenall not help). Why X2 is not changed? Maybe you can somehow otherwise identify how stretched the line (actually I need the coordinates of its end, for which we stretch) ...
 
Through. Net API I can freely assume that the attribute value, and therefore undertook to solve the problem through the attribute bound to the desired property through the field ...

kaefer

  • Swamp Rat
  • Posts: 572
I need to programmatically find out the length of the horizontal line, selected on the screenshot. I created a hidden attribute called X2, and tied it to the desired property of primitive to me, putting a tick, they say "take the size of entering the block. " When creating a new occurrence of the attribute value is filled. But later, after a stretch in the screenshot shown on the handle, the attribute value X2 is no longer changing (regen / regenall not help). Why X2 is not changed?

I'll try to answer your second question first. You have as field expression:
Code: [Select]
%<\AcObjProp.16.2 Object(%<\_ObjId 2119169736>%,1).Length \f "%lu2%zs8">%That means you're querying the length of the object indicated, presumably the parameter residing in your block definition.

Instead, you want to query the actual parameter, that would look more like this:
Code: [Select]
%<\AcObjProp.16.2 Object(?BlockRefId,1).Parameter(39).UpdatedDistance \f "%lu2">%
Your first question then answers itself: After the UPDATEFIELD command, just read the AttributeReference.TextString property.

Andrey Bushman

  • Swamp Rat
  • Posts: 860
Issue has been resolved. Run succeeded in two ways:
1. After an additional attribute (tied it to the extended property of the block and hid it from the user). See attached file.
Programmatically extract this information is very simple, showing an example if anyone will be interested in:
Code: [Select]
            #region Нагрузки
            pso = new PromptSelectionOptions();
            pso.MessageForAdding = string.Format("\n{0}", Resource.SelectPointForces);
            sf = new SelectionFilter(new TypedValue[] {
                //На всякий случай уточняю, что это должно быть вхождение блока, а не примитив некой именованной группы
                new TypedValue((int)DxfCode.Start, "INSERT"),
                new TypedValue((int)DxfCode.BlockName, "Load")
            });
            psr = ed.GetSelection(pso, sf);
            if (psr.Status != PromptStatus.OK)
                return;
            ed.WriteMessage(string.Format(Resource.PointForcesCount, psr.Value.Count));
            using (Transaction tr = db.TransactionManager.StartTransaction()) {
                sb.AppendLine("#MATRIX LOADS (0 TO 2)");
                sb.AppendLine("//X;P");
                foreach (SelectedObject item in psr.Value) {
                    BlockReference br = (BlockReference)tr.GetObject(item.ObjectId, OpenMode.ForRead);
                    Dictionary<string, string> dict = new Dictionary<string, string>();
                    dict.Add("X", br.Position.X.ToString());
                    foreach (ObjectId item2 in br.AttributeCollection) {
                        AttributeReference ar = (AttributeReference)tr.GetObject(item2, OpenMode.ForRead);
                        dict.Add(ar.Tag, ar.TextString);
                    }
                    sb.AppendLine(string.Format("{0};{1}", dict["X"], dict["Value"]));
                }
                sb.AppendLine("#ENDMATRIX");
            }
            #endregion


2. The second option is more interesting - without creating an additional attribute that directly to the software by reading the values ​​of extended properties entering the unit:
Code: [Select]
            #region Распределённые нагрузки
            pso = new PromptSelectionOptions();
            pso.MessageForAdding = string.Format("\n{0}", Resource.DistributedLoadSelection);
            sf = new SelectionFilter(new TypedValue[] {
                //На всякий случай уточняю, что это должно быть вхождение блока, а не примитив некой именованной группы
                new TypedValue((int)DxfCode.Start, "INSERT"),
                //Для динамических имя меняется. Фильтром их нельзя найти, поэтому следующая строка кода закомментирована
                //new TypedValue((int)DxfCode.BlockName, "DistributedLoad")
            });
            psr = ed.GetSelection(pso, sf);
            if (psr.Status != PromptStatus.OK)
                return;
            ed.WriteMessage(string.Format(Resource.SupportsCount, psr.Value.Count));
            using (Transaction tr = db.TransactionManager.StartTransaction()) {
                //Выбираю только те примитивы, которые являются вхождениями интересующего меня динамического блока ("DISTRIBUTEDLOAD")
                BlockReference[] brs = psr.Value.Cast<SelectedObject>().Select(n=>(BlockReference)tr.GetObject(n.ObjectId, OpenMode.ForRead))
                    .Where(n => ((BlockTableRecord)tr.GetObject(n.DynamicBlockTableRecord, OpenMode.ForRead)).Name.ToUpper() == "DISTRIBUTEDLOAD").ToArray();
                //Если имеются вхождения блоков распределённой нагрузки - обрабатываю их
                if (brs.Length > 0) {
                    sb.AppendLine("#MATRIX DIST_LOAD (0 TO 3)");
                    sb.AppendLine("//Index;X1;X2");
                    foreach (BlockReference item in brs) {
                        Dictionary<string, string> dict = new Dictionary<string, string>();
                        dict.Add("X1", item.Position.X.ToString());
                        foreach (ObjectId item2 in item.AttributeCollection) {
                            AttributeReference ar = (AttributeReference)tr.GetObject(item2, OpenMode.ForRead);
                            dict.Add(ar.Tag, ar.TextString);
                        }
                        //Ищу расширенное свойство, значение которого меня интересует...
                        DynamicBlockReferenceProperty prop = item.DynamicBlockReferencePropertyCollection.Cast<DynamicBlockReferenceProperty>()
                            .First(n => n.PropertyName == "Distance1");
                        double x2 = (double)prop.Value;
                        sb.AppendLine(string.Format("{0};{1};{2}", dict["INDEX"], dict["X1"], dict["X1"] + x2));
                    }
                    sb.AppendLine("#ENDMATRIX");
                }
            }
            #endregion

Andrey Bushman

  • Swamp Rat
  • Posts: 860
kaefer, thanks for the reply.