.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Creating an anonymous block with attributes

2 REPLIES 2
Reply
Message 1 of 3
MrRamsden
1582 Views, 2 Replies

Creating an anonymous block with attributes

I'm trying to create blocks on the fly by drawing a polyline, using a jig, and then grabbing that polyline and creating a block from it.

 

I'm not interested in block names, so anonymous blocks seem to be the way to go. I've successfully managed to create the block and even add attributes to it. However, if I try and use battman or attsync AutoCAD tells me that "This drawing contains no attributed blocks." I can however double-click on the block and go to the enhanced attribute editor, which shows me the attributes with the tags I've given them. Exploding the block reveals that there is no nesting occuring.

 

My attributes seem to be stck in limbo...

 

The function that creates the stand is:

 

{
        Transaction trans = ed.Document.TransactionManager.StartOpenCloseTransaction();

        try
        {
            //create new instance of the polyline jig
            polylineJig.polylineJig plJig = new polylineJig.polylineJig();

            promptStatusResult = plJig.newJig();
            if (promptStatusResult != PromptStatus.OK)
            {
                return;
            }

            //select the last created object (in this case, the polyline)
            PromptSelectionResult psr = ed.SelectLast();

            if (psr != null)
            {
                BlockTable blockTable = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForWrite);
                BlockTableRecord space = (BlockTableRecord)trans.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);

                //create an anonymous block
                BlockTableRecord newBtr = new BlockTableRecord();
                newBtr.Name = "*U";

                //set the origin to the left most vertex
                newBtr.Origin = findBasePoint(psr);

                //if there is an origin
                if (newBtr.Origin != null)
                {
                    //add the new block table record to the block table
                    blockTable.Add(newBtr);

                    //add new block to database
                    trans.AddNewlyCreatedDBObject(newBtr, true);

                    //add the objectIds of the selected objects (polyline) to the objectId collection
                    ObjectId[] IDs = psr.Value.GetObjectIds();
                    ObjectIdCollection objIdCol = new ObjectIdCollection();

                    foreach (ObjectId ID in IDs)
                    {
                        objIdCol.Add(ID);
                    }

                    //move the objectIds to the new blockTable
                    newBtr.AssumeOwnershipOf(objIdCol);

                    //create a new block reference from the block table record
                    BlockReference newBlock = new BlockReference(newBtr.Origin, newBtr.ObjectId);
                    space.AppendEntity(newBlock);
                    trans.AddNewlyCreatedDBObject(newBlock, true);

                    //create attInfo dictionary
                    Dictionary<ObjectId, AttInfo> attInfo = new Dictionary<ObjectId, AttInfo>();

                    addXrecords(ref newBlock);
                    addAttributes(ref newBlock, ref attInfo);
                    setAttributes(ref newBlock);

                    trans.Commit();
                    trans.Dispose();
                }
                else
                {
                    trans.Abort();
                }
            }            

        }
        catch (System.Exception ex)
        {
            ed.WriteMessage("\n Something failed: " + ex.ToString());
            trans.Abort();
        }
    }

 

The addAttributes function:

 

private void addAttributes(ref BlockReference block, ref Dictionary<ObjectId, AttInfo> attInfo)
    {
        Transaction trans = ed.Document.TransactionManager.StartTransaction();
        try
        {
            string[] tags = {"NO", "COMPANY", "AREA"};
            AttachmentPoint[] points = {AttachmentPoint.TopLeft, AttachmentPoint.MiddleMid, AttachmentPoint.BottomRight};

            for( int i = 0; i < tags.Length; i++){
                //create an attribute reference
                AttributeReference attRef = new AttributeReference();
                attRef.Tag = tags[i];
                attRef.Justify = points[i];
                attRef.Visible = true;
                attRef.Position = block.Position;
                attRef.AlignmentPoint = block.Position;                

                ObjectId attRefId = new ObjectId();
                attRefId = block.AttributeCollection.AppendAttribute(attRef);

                if (attRef.Tag != "STANDAREA")
                    attRef.TextString = "";
                else
                {

                    //check for extension dictionary
                    if (attRef.ExtensionDictionary.IsNull)
                        attRef.CreateExtensionDictionary();
                    DBDictionary extDict = (DBDictionary)trans.GetObject(attRef.ExtensionDictionary, OpenMode.ForRead);

                    //check for field dictionary
                    if (!extDict.Contains("ACAD_FIELD"))
                    {
                        DBDictionary acadFieldDict = new DBDictionary();
                        extDict.UpgradeOpen();
                        extDict.SetAt("ACAD_FIELD", acadFieldDict);
                    }
                    DBDictionary fieldDict = (DBDictionary)trans.GetObject(extDict.GetAt("ACAD_FIELD"), OpenMode.ForRead);

                    //check for field
                    if (!fieldDict.Contains("TEXT"))
                    {
                        Field textField = new Field();
                        fieldDict.SetAt("TEXT", textField);
                    }
                    Field field = (Field)trans.GetObject(fieldDict.GetAt("TEXT"), OpenMode.ForWrite);

                    string stringID = block.ObjectId.OldIdPtr.ToString();
                    string updateString = "%<\\AcObjProp.16.2 Object(%<\\_ObjId " + pLine.ObjectId + ">%,1).Area \\f " + "\"" + "%lu2%zs12%ct8[1e-006]" + "\"" + ">%";
                    string fieldCode = field.GetFieldCode(FieldCodeFlags.AddMarkers);
                    string newFieldCode = fieldCode.Replace("?BlockRefId", updateString);
                    field.SetFieldCode(newFieldCode);
                }

                trans.AddNewlyCreatedDBObject(attRef, true);

                //initialise dictionary with object id of attref and attdef info
                attInfo.Add(attRefId, new AttInfo(attRef.Position, attRef.AlignmentPoint, attRef.Justify != AttachmentPoint.BaseLeft));
                
            }

            trans.Commit();
            trans.Dispose();

            ed.WriteMessage("\naddAttributes completed successfully");
        }
        catch (Autodesk.AutoCAD.Runtime.Exception ex)
        {
            ed.WriteMessage("\naddAttributes()");
            ed.WriteMessage("\nError: " + ex.Message);
            trans.Abort();        
        }
        
    }

The field code is taken from another one of my files, which works, but uses an existing block definition within the drawing. As this is creating an anonymous block, there is no existing block definition, save the one I create earlier on in the calling function.

 

I've attached the file for anyone to look at/play with.

 

Hopefully I'm doing something wrong that's obvious to one of you gurus. Any advice would be greatly appreciated.

 

MrRamsden

2 REPLIES 2
Message 2 of 3
Alfred.NESWADBA
in reply to: MrRamsden

Hi,

 

>> Hopefully I'm doing something wrong

😉 ... never read such a wish in a forum, great! 🙂

 

OK, your problem is, that you added some attribtue-references to the blockreferences .... but you didn't add objects of type AttributeDefinition to the BlockTableRecord(s).

 

So if you try to insert a self-defined block into the drawing using the INSERT-command ... you will not be asked for attributes as the blockdefinition has none.

 

The job for you is: add AttributeDefinitions to the BlockTableRecord, then you will be able to use BATTMAN for these block-definitions.

 

Good luck, - alfred -

------------------------------------------------------------------------------------
Alfred NESWADBA
Ingenieur Studio HOLLAUS ... www.hollaus.at ... blog.hollaus.at ... CDay 2024
------------------------------------------------------------------------------------
(not an Autodesk consultant)
Message 3 of 3
MrRamsden
in reply to: MrRamsden

Thanks Alfred

 

I've ended up using much more of my previous code than I had anticipated.

 

Now I've just got to work out fields again; creating once from scratch, rather than replacing the value of another as I did before.

 

Thanks again,

 

MrRamsden

 

ps. I was alluding to the fact that one of you lovely people would spot the problem easily, as you did, rather than actually hoping I was doing something wrong Smiley Wink

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost