• Industries
  • Products
  • Buy
  • Services & Support
  • Communities
  • Discussion Groups

    .NET

    Reply
    Active Contributor
    Posts: 26
    Registered: ‎08-29-2008

    Creating an anonymous block with attributes

    400 Views, 2 Replies
    04-10-2012 04:31 AM

    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

    Please use plain text.
    *Expert Elite*
    Posts: 6,463
    Registered: ‎06-29-2007

    Re: Creating an anonymous block with attributes

    04-10-2012 04:44 AM in reply to: MrRamsden

    Hi,

     

    >> Hopefully I'm doing something wrong

    :smileywink: ... never read such a wish in a forum, great! :smileyhappy:

     

    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
    -------------------------------------------------------------------------
    Please use plain text.
    Active Contributor
    Posts: 26
    Registered: ‎08-29-2008

    Re: Creating an anonymous block with attributes

    04-10-2012 09:20 AM 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 :smileywink:

    Please use plain text.