Add Block to DxfDocument (not insert)

Jan 28, 2013 at 3:28 PM

Hi, is possible to add a Block to a DxfDocument object?

I am using an old version (0.1.2.0).

PS: this library is awesome! Thanks for your hard work.

 

Jan 28, 2013 at 9:12 PM

I did something just recently that may work. I use the normal load for a DXFDocument, and then I add the DXFDocument as a block to the current doc.

//something like this

  DxfDocument dxfblock = new DxfDocument();
    dxfblock.Load(blockfile);
    block = dxf.AddBlock(dxfblock);

//add block function

   public Block AddBlock(DxfDocument dxf)
        {

            Block block = new Block(dxf.FileName);

            foreach (Layer layer in dxf.Layers)
            {
                if (!this.layers.ContainsKey(layer.Name))
                {
                    AddLayer(layer);
                }
            }

            foreach (LineType lineType in dxf.LineTypes)
            {
                if (!this.lineTypes.ContainsKey(lineType.Name))
                {
                    AddLineType(lineType);
                }
            }

            foreach (TextStyle textStyle in dxf.TextStyles)
            {
                if (!this.textStyles.ContainsKey(textStyle.Name))
                {
                    AddTextStyle(textStyle);
                }
            }

            foreach (DimensionStyle dimStyle in dxf.DimStyles)
            {
                if (!this.dimStyles.ContainsKey(dimStyle.Name))
                {
                    AddDimensionStyle(dimStyle);
                }
            }

            foreach (Block blockdef in dxf.Blocks)
            {
                if (!this.blocks.ContainsKey(blockdef.Name))
                {
                    AddBlock(blockdef);
                }
            }

            foreach (AttributeDefinition attribute in dxf.Attributes)
            {
                block.Attributes.Add(attribute.Id, attribute);
            }

            block.Entities.AddRange(dxf.Arcs);
            block.Entities.AddRange(dxf.Circles);
            block.Entities.AddRange(dxf.Ellipses);
            block.Entities.AddRange(dxf.Points);
            block.Entities.AddRange(dxf.Faces3d);
            block.Entities.AddRange(dxf.Solids);
            block.Entities.AddRange(dxf.LwPolylines);
            block.Entities.AddRange(dxf.Polylines);
            block.Entities.AddRange(dxf.PolyfaceMesh);
            block.Entities.AddRange(dxf.Lines);
            block.Entities.AddRange(dxf.Inserts);
            block.Entities.AddRange(dxf.Texts);
            block.Entities.AddRange(dxf.MTexts);
            block.Entities.AddRange(dxf.Hatches);
            block.Entities.AddRange(dxf.Dimensions);

            foreach (ApplicationRegistry appReg in dxf.AppRegisterNames)
                {
                    if (!this.appRegisterNames.ContainsKey(appReg.Name))
                    {
                        this.appRegisterNames.Add(appReg.Name, appReg);
                        this.handleCount = appReg.AsignHandle(this.handleCount);
                    }
                }

            AddBlock(block);

            return block;
        }




Jan 28, 2013 at 10:36 PM

Thank you, I will try it.

Coordinator
Jan 29, 2013 at 1:12 AM

@articx

The first thing I would strongly recommend you it is to upgrade your code to the latest commit. It was in a later version where I made public methods to get and add elements to the table lists (layers, line types, text styles, dimension styles, block definitions, image definitions, and application registries). In older versions they were there but they were private and I will not be able to support any problems you might have.

The answer to your question is yes, here you have an example on how to do it (with the latest source code):

// create the block definition
Block block = new Block("MyBlock");
// add the entities that you want in the block
block.Entities.Add(new Line(new Vector3(0, 0, 0), new Vector3(100, 100, 0)));
// create the document
DxfDocument dxf = new DxfDocument();
// add the block definition to the block table list (this is the function that was private in earlier versions, check the changelog.txt)
dxf.AddBlock(block);
// and save the file, no visible entities will appear if you try to open the drawing but the block will be there
dxf.Save("Block definiton.dxf", DxfVersion.AutoCad2000);

@gjsmith13

One thing that I was thinking to implement is external references, that will make it easier to create a block from the whole content of a dxf file.

Your code will only work with the latest version, previously the block did not support all avaliable entities. Try to use the way of creating blocks that is shown in the example above, you don't really need to manually add layers, line types, text styles, dimension styles, block definitions, image definitions, and application registries to the document, the DxfDocument.AddEntity() and the DxfDocument.AddBlock() will take care of it.

Daniel

Jan 29, 2013 at 3:19 AM

@haplokuon

yeah my issue was all our blocks are in external references, but we don't necessarily want to have to send along all the external block files. over 300 component blocks exist but the drawing may only require a small set of those. so we pull those in, position and set attributes accordingly, and save everything in one file.

so to solve that  I  copied all the defs to the main dxf file, create the block and copy all the entities to the block.

granted this was just a proof of concept, but it seemed to work pretty well

Jan 29, 2013 at 3:32 AM

@articx

sorry I misunderstood...I thought you were trying to add a block *from* a dxf document

Jan 29, 2013 at 12:00 PM

@haplokuon

Thanks, thats exactly what I need, but sadly I tried to update to the latest version before but had problems loading some dxf files (with hatchs). I will try again because there are so many new features you added.

BTW I am using netDxf in a visual sewer editor to load blocks (and display them using WPF), and to generate dxf files, netDxf helped me a lot, even with the alpha version I'm using.

@gjsmith13

I will be more specific the next time :-)

Coordinator
Jan 29, 2013 at 5:25 PM

Check the dxf version of the dxf files that are giving you problems, if they are version prior to AutoCAD2000 there is nothing I can do; but I would recommend to upgrade the files to AutoCAD2000 or later version. The library you are using is the one prior of dropping support for AutoCAD12. There is one thing you still can do, you can edit the read code to avoid the entities giving you problems. The Load code will try to open earlier versions but errors may arise, that is why I am thinking of blocking all versions prior to AutoCAD2000 and add a function to check the dxf file version without having to read the whole file.

If the dxf files are one of the supported versions, perhaps there is a bug and I will have to take a look at them.

Daniel