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