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