private IPolyline ReadPolyline(ref CodeValuePair code) { string handle = string.Empty; Layer layer = Layer.Default; AciColor color = AciColor.ByLayer; LineType lineType = LineType.ByLayer; PolylineTypeFlags flags = PolylineTypeFlags.OpenPolyline; double elevation = 0.0; float thickness = 0.0f; Vector3d normal = Vector3d.UnitZ; List<Vertex> vertexes = new List<Vertex>(); Dictionary<ApplicationRegistry, XData> xData = new Dictionary<ApplicationRegistry, XData>(); //int numVertexes = -1; //int numFaces = -1; code = this.ReadCodePair(); while (code.Code != 0) { switch (code.Code) { case 5: handle = code.Value; code = this.ReadCodePair(); break; case 8: layer = this.GetLayer(code.Value); code = this.ReadCodePair(); break; case 62: color = new AciColor(short.Parse(code.Value)); code = this.ReadCodePair(); break; case 6: lineType = this.GetLineType(code.Value); code = this.ReadCodePair(); break; case 30: elevation = double.Parse(code.Value); code = this.ReadCodePair(); break; case 39: thickness = float.Parse(code.Value); code = this.ReadCodePair(); break; case 70: flags = (PolylineTypeFlags) (int.Parse(code.Value)); code = this.ReadCodePair(); break; case 71: //this field might not exist for polyface meshes, we cannot depend on it //numVertexes = int.Parse(code.Value); code = this.ReadCodePair(); code = this.ReadCodePair(); break; case 72: //this field might not exist for polyface meshes, we cannot depend on it //numFaces = int.Parse(code.Value); code = this.ReadCodePair(); break; case 210: normal.X = double.Parse(code.Value); code = this.ReadCodePair(); break; case 220: normal.Y = double.Parse(code.Value); code = this.ReadCodePair(); break; case 230: normal.Z = double.Parse(code.Value); code = this.ReadCodePair(); break; case 1001: XData xDataItem = this.ReadXDataRecord(code.Value, ref code); xData.Add(xDataItem.ApplicationRegistry, xDataItem); break; default: if (code.Code >= 1000 && code.Code <= 1071) throw new DxfInvalidCodeValueEntityException(code.Code, code.Value, this.file, "The extended data of an entity must start with the application registry code " + this.fileLine); code = this.ReadCodePair(); break; } } //begin to read the vertex list if (code.Value != DxfObjectCode.Vertex) throw new DxfEntityException(DxfObjectCode.Polyline, this.file, "Vertex not found in line " + this.fileLine); while (code.Value != StringCode.EndSequence) { if (code.Value == DxfObjectCode.Vertex) { Debug.Assert(code.Code == 0); Vertex vertex = this.ReadVertex(ref code); vertexes.Add(vertex); } } // read the end end sequence object until a new element is found if (code.Value != StringCode.EndSequence) throw new DxfEntityException(DxfObjectCode.Polyline, this.file, "End sequence entity not found in line " + this.fileLine); code = this.ReadCodePair(); string endSequenceHandle = string.Empty; Layer endSequenceLayer = layer; while (code.Code != 0) { switch (code.Code) { case 5: endSequenceHandle = code.Value; code = this.ReadCodePair(); break; case 8: endSequenceLayer = this.GetLayer(code.Value); code = this.ReadCodePair(); break; default: code = this.ReadCodePair(); break; } } IPolyline pol; bool isClosed = false; if ((flags & PolylineTypeFlags.ClosedPolylineOrClosedPolygonMeshInM) == PolylineTypeFlags.ClosedPolylineOrClosedPolygonMeshInM) { isClosed = true; } //to avoid possible error between the vertex type and the polyline type //the polyline type will decide which information to use from the read vertex if ((flags & PolylineTypeFlags.Polyline3D) == PolylineTypeFlags.Polyline3D) { List<Polyline3dVertex> polyline3dVertexes = new List<Polyline3dVertex>(); foreach (Vertex v in vertexes) { Polyline3dVertex vertex = new Polyline3dVertex { Color = v.Color, Layer = v.Layer, LineType = v.LineType, Location = v.Location, Handle = v.Handle }; vertex.XData = v.XData; polyline3dVertexes.Add(vertex); } ////posible error avoidance, the polyline is marked as polyline3d code:(70,8) but the vertex is marked as PolylineVertex code:(70,0) //if (v.Type == EntityType.PolylineVertex) //{ // Polyline3dVertex polyline3dVertex = new Polyline3dVertex(((PolylineVertex)v).Location.X, ((PolylineVertex)v).Location.Y,0); // polyline3dVertexes.Add(polyline3dVertex); //} //else //{ // polyline3dVertexes.Add((Polyline3dVertex)v); //} //} pol = new Polyline3d(polyline3dVertexes, isClosed) { Handle = handle }; ((Polyline3d) pol).EndSequence.Handle = endSequenceHandle; ((Polyline3d) pol).EndSequence.Layer = endSequenceLayer; } else if ((flags & PolylineTypeFlags.PolyfaceMesh) == PolylineTypeFlags.PolyfaceMesh) { //the vertex list created contains vertex and face information List<PolyfaceMeshVertex> polyfaceVertexes = new List<PolyfaceMeshVertex>(); List<PolyfaceMeshFace> polyfaceFaces = new List<PolyfaceMeshFace>(); foreach (Vertex v in vertexes) { if ((v.Flags & (VertexTypeFlags.PolyfaceMeshVertex | VertexTypeFlags.Polygon3dMesh)) == (VertexTypeFlags.PolyfaceMeshVertex | VertexTypeFlags.Polygon3dMesh)) { PolyfaceMeshVertex vertex = new PolyfaceMeshVertex { Color = v.Color, Layer = v.Layer, LineType = v.LineType, Location = v.Location, Handle = v.Handle }; vertex.XData = xData; polyfaceVertexes.Add(vertex); } else if ((v.Flags & (VertexTypeFlags.PolyfaceMeshVertex)) == (VertexTypeFlags.PolyfaceMeshVertex)) { PolyfaceMeshFace vertex = new PolyfaceMeshFace { Color = v.Color, Layer = v.Layer, LineType = v.LineType, VertexIndexes = v.VertexIndexes, Handle = v.Handle }; vertex.XData = xData; polyfaceFaces.Add(vertex); } //if (v.Type == EntityType.PolyfaceMeshVertex) //{ // polyfaceVertexes.Add((PolyfaceMeshVertex) v); //} //else if (v.Type == EntityType.PolyfaceMeshFace) //{ // polyfaceFaces.Add((PolyfaceMeshFace) v); //} //else //{ // throw new EntityDxfException(v.Type.ToString(), this.file, "Error in vertex type."); //} } pol = new PolyfaceMesh(polyfaceVertexes, polyfaceFaces) { Handle = handle }; ((PolyfaceMesh) pol).EndSequence.Handle = endSequenceHandle; ((PolyfaceMesh) pol).EndSequence.Layer = endSequenceLayer; } else { List<PolylineVertex> polylineVertexes = new List<PolylineVertex>(); foreach (Vertex v in vertexes) { PolylineVertex vertex = new PolylineVertex { Location = new Vector2d(v.Location.X, v.Location.Y), BeginThickness = v.BeginThickness, Bulge = v.Bulge, Color = v.Color, EndThickness = v.EndThickness, Layer = v.Layer, LineType = v.LineType, Handle = v.Handle }; vertex.XData = xData; ////posible error avoidance, the polyline is marked as polyline code:(70,0) but the vertex is marked as Polyline3dVertex code:(70,32) //if (v.Type==EntityType.Polyline3dVertex) //{ // PolylineVertex polylineVertex = new PolylineVertex(((Polyline3dVertex)v).Location.X, ((Polyline3dVertex)v).Location.Y); // polylineVertexes.Add(polylineVertex); //} //else //{ // polylineVertexes.Add((PolylineVertex) v); //} polylineVertexes.Add(vertex); } pol = new Polyline(polylineVertexes, isClosed) { Thickness = thickness, Elevation = elevation, Normal = normal, Handle = handle }; ((Polyline) pol).EndSequence.Handle = endSequenceHandle; ((Polyline) pol).EndSequence.Layer = endSequenceLayer; } pol.Color = color; pol.Layer = layer; pol.LineType = lineType; pol.XData = xData; return pol; }
private EntityObject ReadPolyline() { // the entity Polyline in dxf can actually hold three kinds of entities // 3d polyline is the generic polyline // polyface mesh // polylines 2d is the old way of writing polylines the AutoCAD2000 and newer always use LwPolylines to define a 2d polyline // this way of reading 2d polylines is here for compatibility reasons with older dxf versions. PolylinetypeFlags flags = PolylinetypeFlags.OpenPolyline; PolylineSmoothType smoothType = PolylineSmoothType.NoSmooth; double elevation = 0.0; double thickness = 0.0; Vector3 normal = Vector3.UnitZ; List<Vertex> vertexes = new List<Vertex>(); List<XData> xData = new List<XData>(); this.chunk.Next(); while (this.chunk.Code != 0) { switch (this.chunk.Code) { case 30: elevation = this.chunk.ReadDouble(); this.chunk.Next(); break; case 39: thickness = this.chunk.ReadDouble(); this.chunk.Next(); break; case 70: flags = (PolylinetypeFlags) this.chunk.ReadShort(); this.chunk.Next(); break; case 75: smoothType = (PolylineSmoothType) this.chunk.ReadShort(); this.chunk.Next(); break; case 71: //this field might not exist for polyface meshes, we cannot depend on it //numVertexes = int.Parse(code.Value); code = this.ReadCodePair(); this.chunk.Next(); break; case 72: //this field might not exist for polyface meshes, we cannot depend on it this.chunk.Next(); break; case 210: normal.X = this.chunk.ReadDouble(); this.chunk.Next(); break; case 220: normal.Y = this.chunk.ReadDouble(); this.chunk.Next(); break; case 230: normal.Z = this.chunk.ReadDouble(); this.chunk.Next(); break; case 1001: string appId = this.DecodeEncodedNonAsciiCharacters(this.chunk.ReadString()); XData data = this.ReadXDataRecord(this.GetApplicationRegistry(appId)); xData.Add(data); break; default: if (this.chunk.Code >= 1000 && this.chunk.Code <= 1071) throw new Exception("The extended data of an entity must start with the application registry code."); this.chunk.Next(); break; } } //begin to read the vertex list (although it is not recommended the vertex list might have 0 entries) while (this.chunk.ReadString() != DxfObjectCode.EndSequence) { if (this.chunk.ReadString() == DxfObjectCode.Vertex) { Vertex vertex = this.ReadVertex(); vertexes.Add(vertex); } } // read the end sequence object until a new element is found this.chunk.Next(); string endSequenceHandle = null; while (this.chunk.Code != 0) { switch (this.chunk.Code) { case 5: endSequenceHandle = this.chunk.ReadHex(); this.chunk.Next(); break; case 8: // the polyline EndSequence layer should be the same as the polyline layer this.chunk.Next(); break; default: this.chunk.Next(); break; } } EntityObject pol; bool isClosed = flags.HasFlag(PolylinetypeFlags.ClosedPolylineOrClosedPolygonMeshInM); //to avoid possible error between the vertex type and the polyline type //the polyline type will decide which information to use from the read vertex if (flags.HasFlag(PolylinetypeFlags.Polyline3D)) { List<PolylineVertex> polyline3dVertexes = new List<PolylineVertex>(); foreach (Vertex v in vertexes) { PolylineVertex vertex = new PolylineVertex { Flags = v.Flags, Position = v.Position, Handle = v.Handle, }; polyline3dVertexes.Add(vertex); } pol = new Polyline(polyline3dVertexes, isClosed) { Flags = flags, SmoothType = smoothType, Normal = normal }; ((Polyline) pol).EndSequence.Handle = endSequenceHandle; } else if (flags.HasFlag(PolylinetypeFlags.PolyfaceMesh)) { //the vertex list created contains vertex and face information List<PolyfaceMeshVertex> polyfaceVertexes = new List<PolyfaceMeshVertex>(); List<PolyfaceMeshFace> polyfaceFaces = new List<PolyfaceMeshFace>(); foreach (Vertex v in vertexes) { if (v.Flags.HasFlag(VertexTypeFlags.PolyfaceMeshVertex | VertexTypeFlags.Polygon3dMesh)) { PolyfaceMeshVertex vertex = new PolyfaceMeshVertex { Location = v.Position, Handle = v.Handle, }; polyfaceVertexes.Add(vertex); } else if (v.Flags.HasFlag(VertexTypeFlags.PolyfaceMeshVertex)) { PolyfaceMeshFace vertex = new PolyfaceMeshFace(v.VertexIndexes) { Handle = v.Handle }; polyfaceFaces.Add(vertex); } } pol = new PolyfaceMesh(polyfaceVertexes, polyfaceFaces) { Normal = normal }; ((PolyfaceMesh) pol).EndSequence.Handle = endSequenceHandle; } else { List<LwPolylineVertex> polylineVertexes = new List<LwPolylineVertex>(); foreach (Vertex v in vertexes) { LwPolylineVertex vertex = new LwPolylineVertex { Position = new Vector2(v.Position.X, v.Position.Y), StartWidth = v.StartWidth, Bulge = v.Bulge, EndWidth = v.EndWidth, }; polylineVertexes.Add(vertex); } pol = new LwPolyline(polylineVertexes, isClosed) { Flags = flags, Thickness = thickness, Elevation = elevation, Normal = normal, }; } pol.XData.AddRange(xData); return pol; }