This project has moved. For the latest updates, please go here.

Insert Block with attribute problem

Jul 3, 2015 at 8:03 AM
Edited Jul 3, 2015 at 9:24 AM
Hi everyone,
i've got an issue regard an insert block with load method. Here's the code:
public static void CreateDrawing(string SavePath)
        {
            //Create a new DXF
            var DXFOutput = new netDxf.DxfDocument();
            //Create a new Layer
            var TestLayer = new netDxf.Tables.Layer("Test Layer");
            //set a color variable used for set the color to the layer
            var Color = new netDxf.AciColor(255, 0, 0);
            //Set the layer color
            TestLayer.Color = Color;
            //Add the layer to the drawing
            DXFOutput.Layers.Add(TestLayer);
            //Set the path to the dxf file used as a block
            string filePath = "testblock.dxf";
            //Create a new vector to use as insert position for the block
            netDxf.Vector2 GlobalPosition = new netDxf.Vector2(0, 0);
            //Create a new block
            netDxf.Blocks.Block TestBlock;
            //Use the external dxf as source for the block
            TestBlock = netDxf.Blocks.Block.Load(filePath);
             //add the block to the drawing
            DXFOutput.Blocks.Add(TestBlock);
            //Create an insertentities
            var InsertBlock = new netDxf.Entities.Insert(TestBlock, GlobalPosition);
            //Add the block to the drawing
            DXFOutput.AddEntity(InsertBlock);
            //Save the document
            DXFOutput.Save(SavePath);
        }
The problem is that when the TestBlock = netDxf.Blocks.Block.Load(filePath); is executed it return void that means that it cannot load the file.
The file got some attribute definition that i want define when i insert the block in the drawing; if i remove the attribute in the drawing used as block everything works fine.
So it's possible load the drawing as block with the attribute definition?
If yes, how can i do it?
Thanks
Coordinator
Jul 3, 2015 at 4:40 PM
If you use the release build of the library both the DxfDocument.Load and the Block.Load methods will return null if for whatever reason a problem has been found during the loading process, if you use the debug build they will raise an exception.

Your problem is actually a bug with the Block.Create method that is called by the Block.Load(). Here you have a quick fix for it, for the moment and until a new update arrives, just substitute the existing Create method code in the Block class by:
public static Block Create(DxfDocument doc, string name)
{
    Block block = new Block(name);
    block.position = doc.DrawingVariables.InsBase;
    block.Record.Units = doc.DrawingVariables.InsUnits;
    List<DxfObject> entities = doc.Layouts.GetReferences(Layout.ModelSpaceName);
    foreach (DxfObject dxfObject in entities)
    {
        EntityObject entity = dxfObject as EntityObject;
        if (entity == null) continue;
        EntityObject clone = (EntityObject)entity.Clone();
        AttributeDefinition attdef = clone as AttributeDefinition;
        if (attdef != null)
        {
            block.AttributeDefinitions.Add(attdef);
            continue;
        }
        block.Entities.Add(clone);
    }
    return block;
}
The Save method was also buggy, if you need substitute it by:
public bool Save(string file, DxfVersion version, bool isBinary = false)
{
    DxfDocument dwg = new DxfDocument(version);
    dwg.DrawingVariables.InsBase = this.position;
    dwg.DrawingVariables.InsUnits = this.Record.Units;
    foreach (EntityObject entity in this.entities)
        dwg.AddEntity((EntityObject)entity.Clone());
    foreach (AttributeDefinition attdef in this.attributes.Values)
        dwg.AddEntity((EntityObject)attdef.Clone());
    return dwg.Save(file, isBinary);
}
Daniel
Jul 5, 2015 at 8:36 PM
Thank you the fix works! Keep up the good work for this project, i wish you all the best!
Jul 23, 2015 at 2:03 PM
Edited Jul 23, 2015 at 2:04 PM
Hello again, unfortunately i've found another issue regarding the insertion of attribute, this time the problem is a first chance exception due to a null reference in the file DxfWriter in the IO Folder.
The problem occours when i try to save the document in the following method:
        private void WriteAttribute(Attribute attrib)
        {
            
            this.chunk.Write(0, attrib.CodeName);
            this.chunk.Write(5, attrib.Handle);
            
            this.chunk.Write(330, attrib.Owner.Owner.Handle); //this is where the error appear line 2840, the attrib.Owner is set to null and i don't know why

            this.chunk.Write(100, SubclassMarker.Entity);

            this.chunk.Write(8, this.EncodeNonAsciiCharacters(attrib.Layer.Name));
unfortunately this error is random and i don't understand where is the problem (sometimes the file will be saved without problem and sometimes the exception due to a null reference appear).
Additional information is that the part of my program that take care about the document creation and save process run in a backgroundworker.
The code is similar to the early posted but if you need my code just ask :)
Coordinator
Jul 26, 2015 at 6:04 PM
I really have no clue why this is happening. The attribute's owner is assigned during its creation in the Insert constructor. Are you sure it is the attrib.Owner which is returning null and not the attrib.Owner.Owner? If this is the case and if you are running the document creation and the save process in different processes, perhaps that random exception lies there. Perhaps the save process is started before the creation has finished, since, from what you said, you are running them in a background worker.

You can safely delete the line "this.chunk.Write(330, attrib.Owner.Owner.Handle);" since it seems that information is not really used. As a matter of fact is should have been "this.chunk.Write(330, attrib.Owner.Handle);". That being said, and if the origin of your problem lies in sharing information between different threads, I cannot assure you that a different problem might appear somewhere else.

Daniel
Jul 27, 2015 at 2:41 PM
Edited Jul 27, 2015 at 2:43 PM
I deleted the line of code and i found that some attribute definition defined in some block inside the drawing will not appear anymore and the document will be saved as usual; when i put back the piece of code the issue will appear again.
So i think that the problem was in my drawing and when you want insert a drawing as a block with other block with attribute definition inside this issue could appear (until now i don't have problem). I used the burst command in AutoCAD for eliminate those block and everything works fine, the next time i will make my drawing without block inside,
Thanks for the support.