public void Write(Stream stream, DxfDocument document, bool binary)
        {
            this.doc = document;
            this.isBinary = binary;

            if (this.doc.DrawingVariables.AcadVer < DxfVersion.AutoCad2000)
                throw new NotSupportedException("Only AutoCad2000 and newer dxf versions are supported.");

            this.encodedStrings = new Dictionary<string, string>();

            // create the default PaperSpace layout in case it does not exist. The ModelSpace layout always exists
            if (this.doc.Layouts.Count == 1)
                this.doc.Layouts.Add(new Layout("Layout1"));

            // create the application registry AcCmTransparency in case it doesn't exists, it is required by the layer and entity transparency
            this.doc.ApplicationRegistries.Add(new ApplicationRegistry("AcCmTransparency"));

            // create the application registry GradientColor1ACI and GradientColor2ACI in case they don't exists , they are required by the hatch gradient pattern
            this.doc.ApplicationRegistries.Add(new ApplicationRegistry("GradientColor1ACI"));
            this.doc.ApplicationRegistries.Add(new ApplicationRegistry("GradientColor2ACI"));

            // dictionaries
            List<DictionaryObject> dictionaries = new List<DictionaryObject>();

            // Named dictionary it is always the first to appear in the object section
            DictionaryObject namedObjectDictionary = new DictionaryObject(this.doc);
            this.doc.NumHandles = namedObjectDictionary.AsignHandle(this.doc.NumHandles);
            dictionaries.Add(namedObjectDictionary);

            // create the Group dictionary, this dictionary always appear even if there are no groups in the drawing
            DictionaryObject groupDictionary = new DictionaryObject(namedObjectDictionary);
            this.doc.NumHandles = groupDictionary.AsignHandle(this.doc.NumHandles);
            foreach (Group group in this.doc.Groups.Items)
            {
                groupDictionary.Entries.Add(group.Handle, group.Name);
            }
            dictionaries.Add(groupDictionary);
            namedObjectDictionary.Entries.Add(groupDictionary.Handle, DxfObjectCode.GroupDictionary);

            // Layout dictionary
            DictionaryObject layoutDictionary = new DictionaryObject(namedObjectDictionary);
            this.doc.NumHandles = layoutDictionary.AsignHandle(this.doc.NumHandles);
            if (this.doc.Layouts.Count > 0)
            {
                foreach (Layout layout in this.doc.Layouts.Items)
                {
                    layoutDictionary.Entries.Add(layout.Handle, layout.Name);
                }
                dictionaries.Add(layoutDictionary);
                namedObjectDictionary.Entries.Add(layoutDictionary.Handle, DxfObjectCode.LayoutDictionary);
            }

            // create the Underlay definitions dictionary
            DictionaryObject dgnDefinitionDictionary = new DictionaryObject(namedObjectDictionary);
            this.doc.NumHandles = dgnDefinitionDictionary.AsignHandle(this.doc.NumHandles);
            if (this.doc.UnderlayDgnDefinitions.Count > 0)
            {
                foreach (UnderlayDgnDefinition underlayDef in this.doc.UnderlayDgnDefinitions.Items)
                {
                    dgnDefinitionDictionary.Entries.Add(underlayDef.Handle, underlayDef.Name);
                    dictionaries.Add(dgnDefinitionDictionary);
                    namedObjectDictionary.Entries.Add(dgnDefinitionDictionary.Handle, DxfObjectCode.UnderlayDgnDefinitionDictionary);
                }
            }
            DictionaryObject dwfDefinitionDictionary = new DictionaryObject(namedObjectDictionary);
            this.doc.NumHandles = dwfDefinitionDictionary.AsignHandle(this.doc.NumHandles);
            if (this.doc.UnderlayDwfDefinitions.Count > 0)
            {
                foreach (UnderlayDwfDefinition underlayDef in this.doc.UnderlayDwfDefinitions.Items)
                {
                    dwfDefinitionDictionary.Entries.Add(underlayDef.Handle, underlayDef.Name);
                    dictionaries.Add(dwfDefinitionDictionary);
                    namedObjectDictionary.Entries.Add(dwfDefinitionDictionary.Handle, DxfObjectCode.UnderlayDwfDefinitionDictionary);
                }
            }
            DictionaryObject pdfDefinitionDictionary = new DictionaryObject(namedObjectDictionary);
            this.doc.NumHandles = pdfDefinitionDictionary.AsignHandle(this.doc.NumHandles);
            if (this.doc.UnderlayPdfDefinitions.Count > 0)
            {
                foreach (UnderlayPdfDefinition underlayDef in this.doc.UnderlayPdfDefinitions.Items)
                {
                    pdfDefinitionDictionary.Entries.Add(underlayDef.Handle, underlayDef.Name);
                    dictionaries.Add(pdfDefinitionDictionary);
                    namedObjectDictionary.Entries.Add(pdfDefinitionDictionary.Handle, DxfObjectCode.UnderlayPdfDefinitionDictionary);
                }
            }

            // create the MLine style dictionary
            DictionaryObject mLineStyleDictionary = new DictionaryObject(namedObjectDictionary);
            this.doc.NumHandles = mLineStyleDictionary.AsignHandle(this.doc.NumHandles);
            if (this.doc.MlineStyles.Count > 0)
            {
                foreach (MLineStyle mLineStyle in this.doc.MlineStyles.Items)
                {
                    mLineStyleDictionary.Entries.Add(mLineStyle.Handle, mLineStyle.Name);
                }
                dictionaries.Add(mLineStyleDictionary);
                namedObjectDictionary.Entries.Add(mLineStyleDictionary.Handle, DxfObjectCode.MLineStyleDictionary);
            }

            // create the image dictionary
            DictionaryObject imageDefDictionary = new DictionaryObject(namedObjectDictionary);
            this.doc.NumHandles = imageDefDictionary.AsignHandle(this.doc.NumHandles);
            if (this.doc.ImageDefinitions.Count > 0)
            {
                foreach (ImageDefinition imageDef in this.doc.ImageDefinitions.Items)
                {
                    imageDefDictionary.Entries.Add(imageDef.Handle, imageDef.Name);
                }

                dictionaries.Add(imageDefDictionary);

                namedObjectDictionary.Entries.Add(imageDefDictionary.Handle, DxfObjectCode.ImageDefDictionary);
                namedObjectDictionary.Entries.Add(this.doc.RasterVariables.Handle, DxfObjectCode.ImageVarsDictionary);
            }

            this.doc.DrawingVariables.HandleSeed = this.doc.NumHandles.ToString("X");

            this.Open(stream, this.doc.DrawingVariables.AcadVer < DxfVersion.AutoCad2007 ? Encoding.Default : null);

            // The comment group, 999, is not used in binary DXF files.
            if (!this.isBinary)
            {
                foreach (string comment in this.doc.Comments)
                    this.WriteComment(comment);
            }

            //HEADER SECTION
            this.BeginSection(DxfObjectCode.HeaderSection);
            foreach (HeaderVariable variable in this.doc.DrawingVariables.Values)
            {
                this.WriteSystemVariable(variable);
            }
            // writing a copy of the active dimension style variables in the header section will avoid to be displayed as <style overrides> in AutoCad
            DimensionStyle activeDimStyle;
             if(this.doc.DimensionStyles.TryGetValue(this.doc.DrawingVariables.DimStyle, out activeDimStyle))
                 this.WriteActiveDimensionStyleSystemVaribles(activeDimStyle);
            this.EndSection();

            //CLASSES SECTION
            this.BeginSection(DxfObjectCode.ClassesSection);
            this.WriteRasterVariablesClass(1);
            if (this.doc.ImageDefinitions.Items.Count > 0)
            {
                this.WriteImageDefClass(this.doc.ImageDefinitions.Count);
                this.WriteImageDefRectorClass(this.doc.Images.Count);
                this.WriteImageClass(this.doc.Images.Count);
            }
            this.EndSection();

            //TABLES SECTION
            this.BeginSection(DxfObjectCode.TablesSection);

            //registered application tables
            this.BeginTable(this.doc.ApplicationRegistries.CodeName, (short) this.doc.ApplicationRegistries.Count, this.doc.ApplicationRegistries.Handle);
            foreach (ApplicationRegistry id in this.doc.ApplicationRegistries.Items)
            {
                this.WriteApplicationRegistry(id);
            }
            this.EndTable();

            //viewport tables
            this.BeginTable(this.doc.VPorts.CodeName, (short) this.doc.VPorts.Count, this.doc.VPorts.Handle);
            foreach (VPort vport in this.doc.VPorts)
            {
                this.WriteVPort(vport);
            }
            this.EndTable();

            //line type tables
            //The LTYPE table always precedes the LAYER table. I guess because the layers reference the line types,
            //why this same rule is not applied to DIMSTYLE tables is a mystery, since they also reference text styles and block records
            this.BeginTable(this.doc.LineTypes.CodeName, (short) this.doc.LineTypes.Count, this.doc.LineTypes.Handle);
            foreach (LineType lineType in this.doc.LineTypes.Items)
            {
                this.WriteLineType(lineType);
            }
            this.EndTable();

            //layer tables
            this.BeginTable(this.doc.Layers.CodeName, (short) this.doc.Layers.Count, this.doc.Layers.Handle);
            foreach (Layer layer in this.doc.Layers.Items)
            {
                this.WriteLayer(layer);
            }
            this.EndTable();

            //text style tables
            this.BeginTable(this.doc.TextStyles.CodeName, (short) this.doc.TextStyles.Count, this.doc.TextStyles.Handle);
            foreach (TextStyle style in this.doc.TextStyles.Items)
            {
                this.WriteTextStyle(style);
            }
            this.EndTable();

            //dimension style tables
            this.BeginTable(this.doc.DimensionStyles.CodeName, (short) this.doc.DimensionStyles.Count, this.doc.DimensionStyles.Handle);
            foreach (DimensionStyle style in this.doc.DimensionStyles.Items)
            {
                this.WriteDimensionStyle(style);
            }
            this.EndTable();

            //view
            this.BeginTable(this.doc.Views.CodeName, (short)this.doc.Views.Count, this.doc.Views.Handle);
            this.EndTable();

            //UCS
            this.BeginTable(this.doc.UCSs.CodeName, (short) this.doc.UCSs.Count, this.doc.UCSs.Handle);
            foreach (UCS ucs in this.doc.UCSs.Items)
            {
                this.WriteUCS(ucs);
            }
            this.EndTable();

            //block record table
            this.BeginTable(this.doc.Blocks.CodeName, (short) this.doc.Blocks.Count, this.doc.Blocks.Handle);
            foreach (Block block in this.doc.Blocks.Items)
            {
                this.WriteBlockRecord(block.Record);
            }
            this.EndTable();

            this.EndSection(); //End section tables

            //BLOCKS SECTION
            this.BeginSection(DxfObjectCode.BlocksSection);
            foreach (Block block in this.doc.Blocks.Items)
            {
                Layout layout = null;
                if (block.Name.StartsWith(Block.DefaultPaperSpaceName))
                {
                    // the entities of the layouts associated with the blocks "*Paper_Space0", "*Paper_Space1",... are included in the Blocks Section
                    string index = block.Name.Remove(0, 12);
                    if (!string.IsNullOrEmpty(index))
                    {
                        layout = block.Record.Layout;
                    }
                }
                this.WriteBlock(block, layout);
            }
            this.EndSection(); //End section blocks

            //ENTITIES SECTION
            this.BeginSection(DxfObjectCode.EntitiesSection);
            foreach (Layout layout in this.doc.Layouts)
            {
                if (!layout.IsPaperSpace) 
                {
                    // ModelSpace
                    List<DxfObject> entities = this.doc.Layouts.GetReferences(layout);
                    foreach (DxfObject o in entities)
                    {
                        this.WriteEntity(o as EntityObject, layout);
                    }
                }
                else if (layout.AssociatedBlock.Name.StartsWith(Block.DefaultPaperSpaceName))
                {
                    // only the entities of the layout associated with the block "*Paper_Space" are included in the Entities Section
                    string index = layout.AssociatedBlock.Name.Remove(0, 12);
                    if (string.IsNullOrEmpty(index))
                    {
                        this.WriteEntity(layout.Viewport, layout);
                        List<DxfObject> entities = this.doc.Layouts.GetReferences(layout);
                        foreach (DxfObject o in entities)
                        {
                            this.WriteEntity(o as EntityObject, layout);
                        }
                    }
                }
            }
            this.EndSection(); //End section entities

            //OBJECTS SECTION
            this.BeginSection(DxfObjectCode.ObjectsSection);

            foreach (DictionaryObject dictionary in dictionaries)
            {
                this.WriteDictionary(dictionary);
            }

            foreach (Group group in this.doc.Groups.Items)
            {
                this.WriteGroup(group, groupDictionary.Handle);
            }

            foreach (Layout layout in this.doc.Layouts)
            {
                this.WriteLayout(layout, layoutDictionary.Handle);
            }

            foreach (MLineStyle style in this.doc.MlineStyles.Items)
            {
                this.WriteMLineStyle(style, mLineStyleDictionary.Handle);
            }

            foreach (UnderlayDgnDefinition underlayDef in this.doc.UnderlayDgnDefinitions.Items)
            {
                this.WriteUnderlayDefinition(underlayDef, dgnDefinitionDictionary.Handle);
            }
            foreach (UnderlayDwfDefinition underlayDef in this.doc.UnderlayDwfDefinitions.Items)
            {
                this.WriteUnderlayDefinition(underlayDef, dwfDefinitionDictionary.Handle);
            }
            foreach (UnderlayPdfDefinition underlayDef in this.doc.UnderlayPdfDefinitions.Items)
            {
                this.WriteUnderlayDefinition(underlayDef, pdfDefinitionDictionary.Handle);
            }

            // the raster variables dictionary is only needed when the drawing has image entities
            if (this.doc.ImageDefinitions.Count > 0)
            {
                this.WriteRasterVariables(this.doc.RasterVariables, imageDefDictionary.Handle);
                foreach (ImageDefinition imageDef in this.doc.ImageDefinitions.Items)
                {
                    foreach (ImageDefinitionReactor reactor in imageDef.Reactors.Values)
                    {
                        this.WriteImageDefReactor(reactor);
                    }
                    this.WriteImageDef(imageDef, imageDefDictionary.Handle);
                }
            }
                
            this.EndSection(); //End section objects

            this.Close();

            stream.Position = 0;
        }
        private void WriteDictionary(DictionaryObject dictionary)
        {
            this.chunk.Write(0, DxfObjectCode.Dictionary);
            this.chunk.Write(5, dictionary.Handle);
            this.chunk.Write(330, dictionary.Owner.Handle);

            this.chunk.Write(100, SubclassMarker.Dictionary);
            this.chunk.Write(280, dictionary.IsHardOwner ? (short) 1 : (short) 0);
            this.chunk.Write(281, (short) dictionary.Cloning);

            if (dictionary.Entries == null) return;

            foreach (KeyValuePair<string, string> entry in dictionary.Entries)
            {
                this.chunk.Write(3, this.EncodeNonAsciiCharacters(entry.Value));
                this.chunk.Write(350, entry.Key);
            }
        }
Beispiel #3
0
        private void CreateObjectCollection(DictionaryObject namedDict)
        {
            string groupsHandle = null;
            string layoutsHandle = null;
            string mlineStylesHandle = null;
            string imageDefsHandle = null;
            string underlayDgnDefsHandle = null;
            string underlayDwfDefsHandle = null;
            string underlayPdfDefsHandle = null;
            foreach (KeyValuePair<string, string> entry in namedDict.Entries)
            {
                switch (entry.Value)
                {
                    case DxfObjectCode.GroupDictionary:
                        groupsHandle = entry.Key;
                        break;
                    case DxfObjectCode.LayoutDictionary:
                        layoutsHandle = entry.Key;
                        break;
                    case DxfObjectCode.MLineStyleDictionary:
                        mlineStylesHandle = entry.Key;
                        break;
                    case DxfObjectCode.ImageDefDictionary:
                        imageDefsHandle = entry.Key;
                        break;
                    case DxfObjectCode.UnderlayDgnDefinitionDictionary:
                        underlayDgnDefsHandle = entry.Key;
                        break;
                    case DxfObjectCode.UnderlayDwfDefinitionDictionary:
                        underlayDwfDefsHandle = entry.Key;
                        break;
                    case DxfObjectCode.UnderlayPdfDefinitionDictionary:
                        underlayPdfDefsHandle = entry.Key;
                        break;
                }
            }

            // create the collections with the provided handles
            this.doc.Groups = new Groups(this.doc, groupsHandle);
            this.doc.Layouts = new Layouts(this.doc, layoutsHandle);
            this.doc.MlineStyles = new MLineStyles(this.doc, mlineStylesHandle);
            this.doc.ImageDefinitions = new ImageDefinitions(this.doc, imageDefsHandle);
            this.doc.UnderlayDgnDefinitions = new UnderlayDgnDefinitions(this.doc, underlayDgnDefsHandle);
            this.doc.UnderlayDwfDefinitions = new UnderlayDwfDefinitions(this.doc, underlayDwfDefsHandle);
            this.doc.UnderlayPdfDefinitions = new UnderlayPdfDefinitions(this.doc, underlayPdfDefsHandle);
        }
Beispiel #4
0
        private void ReadObjects()
        {
            Debug.Assert(this.chunk.ReadString() == DxfObjectCode.ObjectsSection);

            this.chunk.Next();
            while (this.chunk.ReadString() != DxfObjectCode.EndSection)
            {
                switch (this.chunk.ReadString())
                {
                    case DxfObjectCode.Dictionary:
                        DictionaryObject dictionary = this.ReadDictionary();
                        this.dictionaries.Add(dictionary.Handle, dictionary);
                        // the named dictionary is always the first in the objects section
                        if (this.namedDictionary == null)
                        {
                            this.CreateObjectCollection(dictionary);
                            this.namedDictionary = dictionary;
                        }
                        break;
                    case DxfObjectCode.RasterVariables:
                        this.doc.RasterVariables = this.ReadRasterVariables();
                        break;
                    case DxfObjectCode.ImageDef:
                        ImageDefinition imageDefinition = this.ReadImageDefinition();
                        this.doc.ImageDefinitions.Add(imageDefinition, false);
                        break;
                    case DxfObjectCode.ImageDefReactor:
                        ImageDefinitionReactor reactor = this.ReadImageDefReactor();
                        if (!this.imageDefReactors.ContainsKey(reactor.ImageHandle))
                            this.imageDefReactors.Add(reactor.ImageHandle, reactor);
                        break;
                    case DxfObjectCode.MLineStyle:
                        MLineStyle style = this.ReadMLineStyle();
                        this.doc.MlineStyles.Add(style, false);
                        break;
                    case DxfObjectCode.Group:
                        Group group = this.ReadGroup();
                        this.doc.Groups.Add(group, false);
                        break;
                    case DxfObjectCode.Layout:
                        Layout layout = this.ReadLayout();
                        if (layout.AssociatedBlock == null)
                            this.orphanLayouts.Add(layout);
                        else
                            this.doc.Layouts.Add(layout, false);
                        break;
                    case DxfObjectCode.UnderlayDgnDefinition:
                        UnderlayDgnDefinition underlayDgnDef = (UnderlayDgnDefinition) this.ReadUnderlayDefinition(UnderlayType.DGN);
                        this.doc.UnderlayDgnDefinitions.Add(underlayDgnDef, false);
                        break;
                    case DxfObjectCode.UnderlayDwfDefinition:
                        UnderlayDwfDefinition underlayDwfDef = (UnderlayDwfDefinition) this.ReadUnderlayDefinition(UnderlayType.DWF);
                        this.doc.UnderlayDwfDefinitions.Add(underlayDwfDef, false);
                        break;
                    case DxfObjectCode.UnderlayPdfDefinition:
                        UnderlayPdfDefinition underlayPdfDef = (UnderlayPdfDefinition) this.ReadUnderlayDefinition(UnderlayType.PDF);
                        this.doc.UnderlayPdfDefinitions.Add(underlayPdfDef, false);
                        break;
                    default:
                        do
                            this.chunk.Next(); while (this.chunk.Code != 0);
                        break;
                }
            }

            // this will try to fix problems with layouts and model/paper space blocks
            // nothing of this is be necessary in a well formed dxf
            this.RelinkOrphanLayouts();

            // raster variables
            if (this.doc.RasterVariables == null)
                this.doc.RasterVariables = new RasterVariables();
        }
Beispiel #5
0
        private DictionaryObject ReadDictionary()
        {
            string handle = null;
            //string handleOwner = null;
            DictionaryCloningFlags clonning = DictionaryCloningFlags.KeepExisting;
            bool isHardOwner = false;
            int numEntries = 0;
            List<string> names = new List<string>();
            List<string> handlesToOwner = new List<string>();

            this.chunk.Next();
            while (this.chunk.Code != 0)
            {
                switch (this.chunk.Code)
                {
                    case 5:
                        handle = this.chunk.ReadHex();
                        this.chunk.Next();
                        break;
                    case 330:
                        //handleOwner = this.chunk.ReadHandle();
                        this.chunk.Next();
                        break;
                    case 280:
                        isHardOwner = this.chunk.ReadShort() != 0;
                        this.chunk.Next();
                        break;
                    case 281:
                        clonning = (DictionaryCloningFlags) this.chunk.ReadShort();
                        this.chunk.Next();
                        break;
                    case 3:
                        numEntries += 1;
                        names.Add(this.DecodeEncodedNonAsciiCharacters(this.chunk.ReadString()));
                        this.chunk.Next();
                        break;
                    case 350: // Soft-owner ID/handle to entry object
                        handlesToOwner.Add(this.chunk.ReadHex());
                        this.chunk.Next();
                        break;
                    case 360:
                        // Hard-owner ID/handle to entry object
                        handlesToOwner.Add(this.chunk.ReadHex());
                        this.chunk.Next();
                        break;
                    default:
                        this.chunk.Next();
                        break;
                }
            }

            //DxfObject owner = null;
            //if (handleOwner != null)
            //    owner = this.doc.AddedObjects[handleOwner];

            DictionaryObject dictionary = new DictionaryObject(null)
            {
                Handle = handle,
                IsHardOwner = isHardOwner,
                Cloning = clonning
            };

            for (int i = 0; i < numEntries; i++)
            {
                string id = handlesToOwner[i];
                if (id == null)
                    throw new NullReferenceException("Null handle in dictionary.");
                dictionary.Entries.Add(id, names[i]);
            }

            return dictionary;
        }