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
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 -
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