Ejemplo n.º 1
0
 internal DictionaryObject(DxfObject owner)
     : base(DxfObjectCode.Dictionary)
 {
     this.isHardOwner = false;
     this.cloning = DictionaryCloningFlags.KeepExisting;
     this.entries = new Dictionary<string, string>();
     this.Owner = owner;
 }
Ejemplo n.º 2
0
        ///  <summary>
        ///  Initializes a new instance of the <c>ImageDef</c> class.
        ///  </summary>
        ///  <param name="fileName">Image file name with full or relative path.</param>
        ///  <param name="name">Image definition name, if null or empty the file name without the extension will be used.</param>
        /// <remarks>
        ///  <para>
        ///  The name assigned to the image definition must be unique.
        ///  </para>
        ///  <para>
        ///  Supported image formats: BMP, JPG, PNG, TIFF.<br />
        ///  Even thought AutoCAD supports more image formats, this constructor is restricted to the ones the .net library supports in common with AutoCAD.
        ///  Use the generic constructor instead.
        ///  </para>
        ///  <para>
        ///  Note (this is from the ACAD docs): AutoCAD 2000, AutoCAD LT 2000, and later releases do not support LZW-compressed TIFF files,
        ///  with the exception of English language versions sold in the US and Canada.<br />
        ///  If you have TIFF files that were created using LZW compression and want to insert them into a drawing 
        ///  you must save the TIFF files with LZW compression disabled.
        ///  </para>
        /// </remarks>
        public ImageDef(string fileName, string name)
            : base(name, DxfObjectCode.ImageDef, true)
        {
            if (string.IsNullOrEmpty(fileName))
                throw new ArgumentNullException("fileName", "The image file name cannot be null or empty.");

            FileInfo info = new FileInfo(fileName);
            if (!info.Exists)
                throw new FileNotFoundException("Image file not found", fileName);

            this.fileName = fileName;

            try
            {
                using (Image bitmap = Image.FromFile(fileName))
                {
                    this.width = bitmap.Width;
                    this.height = bitmap.Height;
                    this.horizontalResolution = bitmap.HorizontalResolution;
                    this.verticalResolution = bitmap.VerticalResolution;
                    // the System.Drawing.Image stores the image resolution in inches
                    this.resolutionUnits = ImageResolutionUnits.Inches;
                }
            }
            catch (Exception)
            {
                throw new ArgumentException("Image file not supported.", fileName);
            }

            this.reactors = new Dictionary<string, ImageDefReactor>();
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Initializes a new instance of the <c>ImageDef</c> class.
        /// </summary>
        /// <param name="fileName">Image file name with full or relative path.</param>
        /// <param name="name">Image definition name, if null or empty the file name without the extension will be used.</param>
        /// <param name="width">Image width in pixels.</param>
        /// <param name="horizontalResolution">Image horizontal resolution in pixels.</param>
        /// <param name="height">Image height in pixels.</param>
        /// <param name="verticalResolution">Image vertical resolution in pixels.</param>
        /// <param name="units">Image resolution units.</param>
        /// <remarks>
        /// <para>
        /// The name assigned to the image definition must be unique.
        /// </para>
        /// <para>
        /// This is a generic constructor for all image formats supported by AutoCAD, note that not all AutoCAD versions support the same image formats.
        /// </para>
        /// <para>
        /// Note (this is from the ACAD docs): AutoCAD 2000, AutoCAD LT 2000, and later releases do not support LZW-compressed TIFF files,
        /// with the exception of English language versions sold in the US and Canada.<br />
        /// If you have TIFF files that were created using LZW compression and want to insert them into a drawing 
        /// you must save the TIFF files with LZW compression disabled.
        /// </para>
        /// </remarks>
        public ImageDef(string fileName, string name, int width, double horizontalResolution, int height, double verticalResolution, ImageResolutionUnits units)
            : base(name, DxfObjectCode.ImageDef, true)
        {
            if (string.IsNullOrEmpty(fileName))
                throw new ArgumentNullException("fileName", "The image file name cannot be null or empty.");

            this.fileName = fileName;
            this.width = width;
            this.height = height;
            this.horizontalResolution = horizontalResolution;
            this.verticalResolution = verticalResolution;
            this.resolutionUnits = units;

            this.reactors = new Dictionary<string, ImageDefReactor>();
        }
Ejemplo n.º 4
0
        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;
        }
Ejemplo n.º 5
0
        public void WriteDictionary(Dictionary dictionary)
        {
            //if (this.activeTable != StringCode.ObjectsSection)
            //{
            //    throw new InvalidDxfTableException(this.activeTable, this.file);
            //}

            this.WriteCodePair(0, StringCode.Dictionary);
            this.WriteCodePair(5, Convert.ToString(10, 16));
            this.WriteCodePair(100, SubclassMarker.Dictionary);
            this.WriteCodePair(281, 1);
            this.WriteCodePair(3, dictionary);
            this.WriteCodePair(350, Convert.ToString(11, 16));

            this.WriteCodePair(0, StringCode.Dictionary);
            this.WriteCodePair(5, Convert.ToString(11, 16));
            this.WriteCodePair(100, SubclassMarker.Dictionary);
            this.WriteCodePair(281, 1);
        }
Ejemplo n.º 6
0
        private void WriteXData(Dictionary<ApplicationRegistry, XData> xData)
        {
            if (xData == null)
                return;

            foreach (ApplicationRegistry appReg in xData.Keys)
            {
                this.WriteCodePair(XDataCode.AppReg, appReg);
                foreach (XDataRecord x in xData[appReg].XDataRecord)
                {
                    this.WriteCodePair(x.Code, x.Value.ToString());
                }
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Initializes a new instance of the <c>DxfDocument</c> class.
        /// </summary>
        /// <param name="drawingVariables"><see cref="HeaderVariables">Drawing variables</see> of the document.</param>
        /// <param name="createDefaultObjects">Check if the default objects need to be created.</param>
        internal DxfDocument(HeaderVariables drawingVariables, bool createDefaultObjects)
            : base("DOCUMENT")
        {
            this.comments = new List<string> {"Dxf file generated by netDxf https://netdxf.codeplex.com, Copyright(C) 2009-2016 Daniel Carvajal, Licensed under LGPL"};
            this.Owner = null;
            this.drawingVariables = drawingVariables;
            this.NumHandles = this.AsignHandle(0);
            this.DimensionBlocksGenerated = 0;
            this.GroupNamesGenerated = 0;
            this.AddedObjects = new Dictionary<string, DxfObject>
            {
                {this.Handle, this}
            }; // keeps track of the added objects

            this.activeLayout = Layout.ModelSpaceName;

            // entities lists
            this.arcs = new List<Arc>();
            this.ellipses = new List<Ellipse>();
            this.dimensions = new List<Dimension>();
            this.faces3d = new List<Face3d>();
            this.solids = new List<Solid>();
            this.traces = new List<Trace>();
            this.inserts = new List<Insert>();
            this.lwPolylines = new List<LwPolyline>();
            this.polylines = new List<Polyline>();
            this.polyfaceMeshes = new List<PolyfaceMesh>();
            this.lines = new List<Line>();
            this.circles = new List<Circle>();
            this.points = new List<Point>();
            this.texts = new List<Text>();
            this.mTexts = new List<MText>();
            this.hatches = new List<Hatch>();
            this.splines = new List<Spline>();
            this.images = new List<Image>();
            this.mLines = new List<MLine>();
            this.rays = new List<Ray>();
            this.xlines = new List<XLine>();
            this.viewports = new List<Viewport>();
            this.meshes = new List<Mesh>();
            this.leaders = new List<Leader>();
            this.tolerances = new List<Tolerance>();
            this.underlays = new List<Underlay>();
            this.wipeouts = new List<Wipeout>();
            this.attributeDefinitions = new List<AttributeDefinition>();

            if (createDefaultObjects)
                this.AddDefaultObjects();
        }
Ejemplo n.º 8
0
        private void ReadBlocks()
        {
            Debug.Assert(this.chunk.ReadString() == DxfObjectCode.BlocksSection);

            // the blocks list will be added to the document after reading the blocks section to handle possible nested insert cases.
            Dictionary<string, Block> blocks = new Dictionary<string, Block>(StringComparer.OrdinalIgnoreCase);

            this.chunk.Next();
            while (this.chunk.ReadString() != DxfObjectCode.EndSection)
            {
                switch (this.chunk.ReadString())
                {
                    case DxfObjectCode.BeginBlock:
                        Block block = this.ReadBlock();
                        blocks.Add(block.Name, block);
                        break;
                    default:
                        this.chunk.Next();
                        break;
                }
            }

            // post process the possible nested blocks,
            // in nested blocks (blocks that contains Insert entities) the block definition might be defined AFTER the insert that references them
            foreach (KeyValuePair<Insert, string> pair in this.nestedInserts)
            {
                Insert insert = pair.Key;
                insert.Block = blocks[pair.Value];
                foreach (Attribute att in insert.Attributes)
                {
                    // attribute definitions might be null if an INSERT entity attribute has not been defined in the block
                    AttributeDefinition attDef;
                    if (insert.Block.AttributeDefinitions.TryGetValue(att.Tag, out attDef))
                        att.Definition = attDef;
                    att.Owner = insert;
                }
                // in the case the insert belongs to a *PaperSpace# the insert owner has not been assigned yet,
                // in this case the owner units are the document units and will be assigned at the end with the rest of the entities
                if (insert.Owner != null)
                {
                    // apply the units scale to the insertion scale (this is for nested blocks)
                    double scale = UnitHelper.ConversionFactor(insert.Owner.Record.Units, insert.Block.Record.Units);
                    insert.Scale *= scale;
                }
            }
            foreach (KeyValuePair<Dimension, string> pair in this.nestedDimensions)
            {
                Dimension dim = pair.Key;
                dim.Block = blocks[pair.Value];
            }

            // add the blocks to the document
            // the block entities will not be added to the document at this point
            // entities like MLine and Image require information that is defined AFTER the block section,
            // this is the case of the MLineStyle and ImageDefinition that are described in the objects section
            foreach (Block block in blocks.Values)
                this.doc.Blocks.Add(block, false);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Reads the whole stream.
        /// </summary>
        /// <param name="stream">Stream.</param>
        public DxfDocument Read(Stream stream)
        {
            if (stream == null)
                throw new ArgumentNullException(nameof(stream));

            string dwgcodepage = CheckHeaderVariable(stream, HeaderVariableCode.DwgCodePage, out this.isBinary);

            try
            {
                if (this.isBinary)
                {
                    Encoding encoding;
                    DxfVersion version = DxfDocument.CheckDxfFileVersion(stream, out this.isBinary);
                    if (version >= DxfVersion.AutoCad2007)
                        encoding = Encoding.UTF8; // the strings in a dxf binary file seems to be stored as UTF8 even if the file looks like ANSI
                    else
                    {
                        if (string.IsNullOrEmpty(dwgcodepage))
                            encoding = Encoding.GetEncoding(Encoding.Default.WindowsCodePage); // use the default windows code page, if unable to read the code page header variable.
                        else
                        {
                            int codepage;
                            encoding = Encoding.GetEncoding(int.TryParse(dwgcodepage.Split('_')[1], out codepage) ? codepage : Encoding.Default.WindowsCodePage);
                        }
                    }
                    this.chunk = new BinaryCodeValueReader(new BinaryReader(stream), encoding);
                }
                else
                {
                    Encoding encoding;
                    Encoding encodingType = EncodingType.GetType(stream);
                    bool isUnicode = (encodingType.EncodingName == Encoding.UTF8.EncodingName) ||
                                     (encodingType.EncodingName == Encoding.BigEndianUnicode.EncodingName) ||
                                     (encodingType.EncodingName == Encoding.Unicode.EncodingName);

                    if (isUnicode)
                        encoding = Encoding.UTF8;
                    else
                    {
                        // if the file is not UTF-8 use the code page provided by the dxf file
                        if (string.IsNullOrEmpty(dwgcodepage))
                            encoding = Encoding.GetEncoding(Encoding.Default.WindowsCodePage); // use the default windows code page, if unable to read the code page header variable.
                        else
                        {
                            int codepage;
                            encoding = Encoding.GetEncoding(!int.TryParse(dwgcodepage.Split('_')[1], out codepage) ? Encoding.Default.WindowsCodePage : codepage);
                        }
                    }
                    this.chunk = new TextCodeValueReader(new StreamReader(stream, encoding, true));
                }
            }
            catch (Exception ex)
            {
                throw new IOException("Unknown error opening the reader.", ex);
            }

            this.doc = new DxfDocument(new HeaderVariables(), false);

            this.entityList = new Dictionary<EntityObject, string>();
            this.viewports = new Dictionary<Viewport, string>();
            this.hatchToPaths = new Dictionary<Hatch, List<HatchBoundaryPath>>();
            this.hatchContourns = new Dictionary<HatchBoundaryPath, List<string>>();
            this.decodedStrings = new Dictionary<string, string>();
            this.leaderAnnotation = new Dictionary<Leader, string>();

            // blocks
            this.nestedInserts = new Dictionary<Insert, string>();
            this.nestedDimensions = new Dictionary<Dimension, string>();
            this.blockRecords = new Dictionary<string, BlockRecord>(StringComparer.OrdinalIgnoreCase);
            this.blockEntities = new Dictionary<Block, List<EntityObject>>();

            // objects
            this.dictionaries = new Dictionary<string, DictionaryObject>(StringComparer.OrdinalIgnoreCase);
            this.groupEntities = new Dictionary<Group, List<string>>();
            this.dimStyleToHandles = new Dictionary<DimensionStyle, string[]>();
            this.imageDefReactors = new Dictionary<string, ImageDefinitionReactor>(StringComparer.OrdinalIgnoreCase);
            this.imgDefHandles = new Dictionary<string, ImageDefinition>(StringComparer.OrdinalIgnoreCase);
            this.imgToImgDefHandles = new Dictionary<Image, string>();
            this.mLineToStyleNames = new Dictionary<MLine, string>();
            this.underlayToDefinitionHandles = new Dictionary<Underlay, string>();
            this.underlayDefHandles = new Dictionary<string, UnderlayDefinition>();

            // for layouts errors workarounds
            this.blockRecordPointerToLayout = new Dictionary<string, BlockRecord>(StringComparer.OrdinalIgnoreCase);
            this.orphanLayouts = new List<Layout>();

            this.chunk.Next();

            // read the comments at the head of the file, any other comments will be ignored
            // they sometimes hold information about the program that has generated the dxf
            // binary files do not contain any comments
            this.doc.Comments.Clear();
            while (this.chunk.Code == 999)
            {
                this.doc.Comments.Add(this.chunk.ReadString());
                this.chunk.Next();
            }

            while (this.chunk.ReadString() != DxfObjectCode.EndOfFile)
            {
                if (this.chunk.ReadString() == DxfObjectCode.BeginSection)
                {
                    this.chunk.Next();
                    switch (this.chunk.ReadString())
                    {
                        case DxfObjectCode.HeaderSection:
                            this.ReadHeader();
                            break;
                        case DxfObjectCode.ClassesSection:
                            this.ReadClasses();
                            break;
                        case DxfObjectCode.TablesSection:
                            this.ReadTables();
                            break;
                        case DxfObjectCode.BlocksSection:
                            this.ReadBlocks();
                            break;
                        case DxfObjectCode.EntitiesSection:
                            this.ReadEntities();
                            break;
                        case DxfObjectCode.ObjectsSection:
                            this.ReadObjects();
                            break;
                        case DxfObjectCode.ThumbnailImageSection:
                            this.ReadThumbnailImage();
                            break;
                        case DxfObjectCode.AcdsDataSection:
                            this.ReadAcdsData();
                            break;
                        default:
                            throw new Exception(string.Format("Unknown section {0}.", this.chunk.ReadString()));
                    }
                }
                this.chunk.Next();
            }
            stream.Position = 0;

            // perform all necessary post processes
            this.PostProcesses();

            // to play safe we will add the default table objects to the document in case they do not exist,
            // if they already present nothing is overridden
            // add default layer
            this.doc.Layers.Add(Layer.Default);

            // add default line types
            this.doc.Linetypes.Add(Linetype.ByLayer);
            this.doc.Linetypes.Add(Linetype.ByBlock);
            this.doc.Linetypes.Add(Linetype.Continuous);

            // add default text style
            this.doc.TextStyles.Add(TextStyle.Default);

            // add default application registry
            this.doc.ApplicationRegistries.Add(ApplicationRegistry.Default);

            // add default dimension style
            this.doc.DimensionStyles.Add(DimensionStyle.Default);

            // add default MLine style
            this.doc.MlineStyles.Add(MLineStyle.Default);

            this.doc.ActiveLayout = Layout.ModelSpaceName;

            return this.doc;
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Initializes a new instance of the <c>ImageDefinition</c> class.
        /// </summary>
        /// <param name="fileName">Image file name with full or relative path.</param>
        /// <param name="name">Image definition name.</param>
        /// <param name="width">Image width in pixels.</param>
        /// <param name="horizontalResolution">Image horizontal resolution in pixels.</param>
        /// <param name="height">Image height in pixels.</param>
        /// <param name="verticalResolution">Image vertical resolution in pixels.</param>
        /// <param name="units">Image resolution units.</param>
        /// <remarks>
        /// <para>
        /// The name assigned to the image definition must be unique.
        /// </para>
        /// <para>
        /// This is a generic constructor for all image formats supported by AutoCAD, note that not all AutoCAD versions support the same image formats.
        /// </para>
        /// <para>
        /// Note (this is from the ACAD docs): AutoCAD 2000, AutoCAD LT 2000, and later releases do not support LZW-compressed TIFF files,
        /// with the exception of English language versions sold in the US and Canada.<br />
        /// If you have TIFF files that were created using LZW compression and want to insert them into a drawing 
        /// you must save the TIFF files with LZW compression disabled.
        /// </para>
        /// </remarks>
        public ImageDefinition(string fileName, string name, int width, double horizontalResolution, int height, double verticalResolution, ImageResolutionUnits units)
            : base(name, DxfObjectCode.ImageDef, false)
        {
            if (string.IsNullOrEmpty(fileName))
                throw new ArgumentNullException(nameof(fileName), "The image file name should be at least one character long.");

            this.fileName = fileName;
            this.width = width;
            this.height = height;
            this.horizontalResolution = horizontalResolution;
            this.verticalResolution = verticalResolution;
            this.resolutionUnits = units;

            this.reactors = new Dictionary<string, ImageDefinitionReactor>();
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Reads the whole stream.
        /// </summary>
        /// <param name="stream">Stream.</param>
        public DxfDocument Read(Stream stream)
        {
            if (stream == null)
                throw new ArgumentNullException("stream", "The stream cannot be null");

            string dwgcodepage = CheckHeaderVariable(stream, HeaderVariableCode.DwgCodePage, out this.isBinary);

            try
            {
                if (this.isBinary)
                {
                    Encoding encoding;
                    DxfVersion version = DxfDocument.CheckDxfFileVersion(stream, out this.isBinary);
                    if (version >= DxfVersion.AutoCad2007)
                        encoding = Encoding.UTF8; // the strings in a dxf binary file seems to be stored as UTF8 even if the file looks like ANSI
                    else
                    {
                        if (string.IsNullOrEmpty(dwgcodepage))
                            encoding = Encoding.GetEncoding(Encoding.Default.WindowsCodePage); // use the default windows code page, if unable to read the code page header variable.
                        else
                        {
                            int codepage;
                            if (!int.TryParse(dwgcodepage.Split('_')[1], out codepage))
                                encoding = Encoding.GetEncoding(Encoding.Default.WindowsCodePage); // use the default windows code page, if unable to read the code page header variable.
                            else
                                encoding = Encoding.GetEncoding(codepage);
                        }
                    }
                    this.chunk = new BinaryCodeValueReader(new BinaryReader(stream), encoding);
                }
                else
                {
                    Encoding encoding;
                    Encoding encodingType = EncodingType.GetType(stream);
                    bool isUnicode = (encodingType.EncodingName == Encoding.UTF8.EncodingName) ||
                                     (encodingType.EncodingName == Encoding.BigEndianUnicode.EncodingName) ||
                                     (encodingType.EncodingName == Encoding.Unicode.EncodingName);

                    if (isUnicode)
                        encoding = Encoding.UTF8;
                    else
                    {
                        // if the file is not UTF-8 use the code page provided by the dxf file
                        if (string.IsNullOrEmpty(dwgcodepage))
                            encoding = Encoding.GetEncoding(Encoding.Default.WindowsCodePage); // use the default windows code page, if unable to read the code page header variable.
                        else
                        {
                            int codepage;
                            if (!int.TryParse(dwgcodepage.Split('_')[1], out codepage))
                                encoding = Encoding.GetEncoding(Encoding.Default.WindowsCodePage); // use the default windows code page, if unable to read the code page header variable.
                            else
                                encoding = Encoding.GetEncoding(codepage); // use the default windows code page, if unable to read the code page header variable.
                        }
                    }
                    this.chunk = new TextCodeValueReader(new StreamReader(stream, encoding, true));
                }
            }
            catch (Exception ex)
            {
                throw (new DxfException("Unknown error opening the reader.", ex));
            }

            this.doc = new DxfDocument(new HeaderVariables(), false);

            this.entityList = new Dictionary<EntityObject, string>();
            this.viewports = new Dictionary<Viewport, string>();
            this.hatchToPaths = new Dictionary<Hatch, List<HatchBoundaryPath>>();
            this.hatchContourns = new Dictionary<HatchBoundaryPath, List<string>>();
            this.decodedStrings = new Dictionary<string, string>();

            // blocks
            this.nestedInserts = new Dictionary<Insert, string>();
            this.nestedDimensions = new Dictionary<Dimension, string>();
            this.blockRecords = new Dictionary<string, BlockRecord>(StringComparer.OrdinalIgnoreCase);
            this.blockEntities = new Dictionary<Block, List<EntityObject>>();

            // objects
            this.dictionaries = new Dictionary<string, DictionaryObject>(StringComparer.OrdinalIgnoreCase);
            this.groupEntities = new Dictionary<Group, List<string>>();
            this.dimStyleToHandles = new Dictionary<DimensionStyle, string[]>();
            this.imageDefReactors = new Dictionary<string, ImageDefReactor>(StringComparer.OrdinalIgnoreCase);
            this.imgDefHandles = new Dictionary<string, ImageDef>(StringComparer.OrdinalIgnoreCase);
            this.imgToImgDefHandles = new Dictionary<Image, string>();
            this.mLineToStyleNames = new Dictionary<MLine, string>();

            // for layouts errors workarounds
            this.blockRecordPointerToLayout = new Dictionary<string, BlockRecord>(StringComparer.OrdinalIgnoreCase);
            this.orphanLayouts = new List<Layout>();

            this.chunk.Next();

            // read the comments at the head of the file, any other comments will be ignored
            // they sometimes hold information about the program that has generated the dxf
            // binary files do not contain any comments
            this.doc.Comments.Clear();
            while (this.chunk.Code == 999)
            {
                this.doc.Comments.Add(this.chunk.ReadString());
                this.chunk.Next();
            }

            while (this.chunk.ReadString() != DxfObjectCode.EndOfFile)
            {
                if (this.chunk.ReadString() == DxfObjectCode.BeginSection)
                {
                    this.chunk.Next();
                    switch (this.chunk.ReadString())
                    {
                        case DxfObjectCode.HeaderSection:
                            this.ReadHeader();
                            break;
                        case DxfObjectCode.ClassesSection:
                            this.ReadClasses();
                            break;
                        case DxfObjectCode.TablesSection:
                            this.ReadTables();
                            break;
                        case DxfObjectCode.BlocksSection:
                            this.ReadBlocks();
                            break;
                        case DxfObjectCode.EntitiesSection:
                            this.ReadEntities();
                            break;
                        case DxfObjectCode.ObjectsSection:
                            this.ReadObjects();
                            break;
                        case DxfObjectCode.ThumbnailImageSection:
                            this.ReadThumbnailImage();
                            break;
                        case DxfObjectCode.AcdsDataSection:
                            this.ReadAcdsData();
                            break;
                        default:
                            throw new InvalidDxfSectionException(this.chunk.ReadString(), string.Format("Unknown section {0}.", this.chunk.ReadString()));
                    }
                }
                this.chunk.Next();
            }
            stream.Position = 0;

            // post process the dimension style list to assign the variables DIMTXSTY, DIMBLK, DIMBLK1, DIMBLK2, DIMLTYPE, DILTEX1, and DIMLTEX2
            foreach (KeyValuePair<DimensionStyle, string[]> pair in this.dimStyleToHandles)
            {
                DimensionStyle defaultDim = DimensionStyle.Default;

                BlockRecord record;

                record = this.doc.GetObjectByHandle(pair.Value[0]) as BlockRecord;
                pair.Key.DIMBLK = record == null ? null : this.doc.Blocks[record.Name];

                record = this.doc.GetObjectByHandle(pair.Value[1]) as BlockRecord;
                pair.Key.DIMBLK1 = record == null ? null : this.doc.Blocks[record.Name];

                record = this.doc.GetObjectByHandle(pair.Value[2]) as BlockRecord;
                pair.Key.DIMBLK2 = record == null ? null : this.doc.Blocks[record.Name];

                TextStyle txtStyle;

                txtStyle = this.doc.GetObjectByHandle(pair.Value[3]) as TextStyle;
                pair.Key.DIMTXSTY = txtStyle == null ? this.doc.TextStyles[defaultDim.DIMTXSTY.Name] : this.doc.TextStyles[txtStyle.Name];

                LineType ltype;

                ltype = this.doc.GetObjectByHandle(pair.Value[4]) as LineType;
                pair.Key.DIMLTYPE = ltype == null ? this.doc.LineTypes[defaultDim.DIMLTYPE.Name] : this.doc.LineTypes[ltype.Name];

                ltype = this.doc.GetObjectByHandle(pair.Value[5]) as LineType;
                pair.Key.DIMLTEX1 = ltype == null ? this.doc.LineTypes[defaultDim.DIMLTEX1.Name] : this.doc.LineTypes[ltype.Name];

                ltype = this.doc.GetObjectByHandle(pair.Value[6]) as LineType;
                pair.Key.DIMLTEX2 = ltype == null ? this.doc.LineTypes[defaultDim.DIMLTEX2.Name] : this.doc.LineTypes[ltype.Name];
            }

            // post process the image list to assign their image definitions.
            foreach (KeyValuePair<Image, string> pair in this.imgToImgDefHandles)
            {
                Image image = pair.Key;
                image.Definition = this.imgDefHandles[pair.Value];
                image.Definition.Reactors.Add(image.Handle, this.imageDefReactors[image.Handle]);

                // we still need to set the definitive image size, now that we know all units involved
                double factor = UnitHelper.ConversionFactor(this.doc.DrawingVariables.InsUnits, this.doc.RasterVariables.Units);
                image.Width *= factor;
                image.Height *= factor;
            }

            // post process the MLines to assign their MLineStyle
            foreach (KeyValuePair<MLine, string> pair in this.mLineToStyleNames)
            {
                MLine mline = pair.Key;
                mline.Style = this.GetMLineStyle(pair.Value);
            }

            // post process the entities of the blocks
            foreach (KeyValuePair<Block, List<EntityObject>> pair in this.blockEntities)
            {
                Block block = pair.Key;
                foreach (EntityObject entity in pair.Value)
                {
                    // now that we have all information required by the block entities we can add them to the document
                    // entities like MLine and Image require information that is defined AFTER the block section,
                    // this is the case of the MLineStyle and ImageDef that are described in the objects section
                    block.Entities.Add(entity);
                }
            }

            // add the dxf entities to the document
            foreach (KeyValuePair<EntityObject, string> pair in this.entityList)
            {
                Layout layout;
                Block block;
                if (pair.Value == null)
                {
                    // the Model layout is the default in case the entity has not one defined
                    layout = this.doc.Layouts[Layout.ModelSpaceName];
                    block = layout.AssociatedBlock;
                }
                else
                {
                    block = this.GetBlock(((BlockRecord) this.doc.GetObjectByHandle(pair.Value)).Name);
                    layout = block.Record.Layout;
                }

                // the viewport with id 1 is stored directly in the layout since it has no graphical representation
                Viewport viewport = pair.Key as Viewport;
                if (viewport != null)
                {
                    if (viewport.Id == 1)
                    {
                        // the base layout viewport has always id = 1 and we will not add it to the entities list of the document.
                        // this viewport has no graphical representation, it is the view of the paper space layout itself and it does not show the model.
                        layout.Viewport = viewport;
                        layout.Viewport.Owner = block;
                    }
                    else
                    {
                        this.doc.ActiveLayout = layout.Name;
                        this.doc.AddEntity(pair.Key, false, false);
                    }
                }
                else
                {
                    // apply the units scale to the insertion scale (this is for not nested blocks)
                    Insert insert = pair.Key as Insert;
                    if (insert != null)
                    {
                        double scale = UnitHelper.ConversionFactor(this.doc.DrawingVariables.InsUnits, insert.Block.Record.Units);
                        insert.Scale *= scale;
                    }
                    this.doc.ActiveLayout = layout.Name;
                    this.doc.AddEntity(pair.Key, false, false);
                }
            }

            // assign a handle to the default layout viewports
            foreach (Layout layout in this.doc.Layouts)
            {
                if (layout.Viewport == null) continue;

                if (string.IsNullOrEmpty(layout.Viewport.Handle))
                    this.doc.NumHandles = layout.Viewport.AsignHandle(this.doc.NumHandles);
            }

            // post process viewports clipping boundaries
            foreach (KeyValuePair<Viewport, string> pair in this.viewports)
            {
                EntityObject entity = this.doc.GetObjectByHandle(pair.Value) as EntityObject;
                if (entity != null )
                    pair.Key.ClippingBoundary = entity;
            }

            // post process the hatch boundary paths
            foreach (KeyValuePair<Hatch, List<HatchBoundaryPath>> pair in this.hatchToPaths)
            {
                Hatch hatch = pair.Key;
                foreach (HatchBoundaryPath path in pair.Value)
                {
                    List<string> entities = this.hatchContourns[path];
                    foreach (string handle in entities)
                    {
                        EntityObject entity = this.doc.GetObjectByHandle(handle) as EntityObject;
                        if (entity != null)
                            path.AddContour(entity);
                    }
                    hatch.BoundaryPaths.Add(path);
                }
            }

            // post process group entities
            foreach (KeyValuePair<Group, List<string>> pair in this.groupEntities)
            {
                foreach (string handle in pair.Value)
                {
                    EntityObject entity = this.doc.GetObjectByHandle(handle) as EntityObject;
                    if (entity != null)
                        pair.Key.Entities.Add(entity);
                }
            }

            // to play safe we will add the default table objects to the document in case they do not exist,
            // if they already present nothing is overridden
            // add default layer
            this.doc.Layers.Add(Layer.Default);

            // add default line types
            this.doc.LineTypes.Add(LineType.ByLayer);
            this.doc.LineTypes.Add(LineType.ByBlock);
            this.doc.LineTypes.Add(LineType.Continuous);

            // add default text style
            this.doc.TextStyles.Add(TextStyle.Default);

            // add default application registry
            this.doc.ApplicationRegistries.Add(ApplicationRegistry.Default);

            // add default dimension style
            this.doc.DimensionStyles.Add(DimensionStyle.Default);

            // add default MLine style
            this.doc.MlineStyles.Add(MLineStyle.Default);

            this.doc.ActiveLayout = Layout.ModelSpaceName;

            return this.doc;
        }