/// <summary> /// Moves, scales, and/or rotates the current entity given a 3x3 transformation matrix and a translation vector. /// </summary> /// <param name="transformation">Transformation matrix.</param> /// <param name="translation">Translation vector.</param> /// <remarks> /// Non-uniform scaling is not supported for multilines. /// Explode the entity and, in case round end caps has been applied, convert the arcs into ellipse arcs and transform them instead. /// </remarks> public override void TransformBy(Matrix3 transformation, Vector3 translation) { Vector3 newNormal; double newElevation; double newScale; newNormal = transformation * Normal; newElevation = Elevation; newScale = newNormal.Modulus(); Matrix3 transOW = MathHelper.ArbitraryAxis(Normal); Matrix3 transWO = MathHelper.ArbitraryAxis(newNormal).Transpose(); for (int i = 0; i < Vertexes.Count; i++) { Vector2 position; Vector2 direction; Vector2 mitter; Vector3 v = transOW * new Vector3(Vertexes[i].Position.X, Vertexes[i].Position.Y, Elevation); v = transformation * v + translation; v = transWO * v; position = new Vector2(v.X, v.Y); newElevation = v.Z; v = transOW * new Vector3(Vertexes[i].Direction.X, Vertexes[i].Direction.Y, Elevation); v = transformation * v; v = transWO * v; direction = new Vector2(v.X, v.Y); v = transOW * new Vector3(Vertexes[i].Miter.X, Vertexes[i].Miter.Y, Elevation); v = transformation * v; v = transWO * v; mitter = new Vector2(v.X, v.Y); List <double>[] newDistances = new List <double> [style.Elements.Count]; for (int j = 0; j < style.Elements.Count; j++) { newDistances[j] = new List <double>(); for (int k = 0; k < Vertexes[i].Distances[j].Count; k++) { newDistances[j].Add(Vertexes[i].Distances[j][k] * newScale); } } vertexes[i] = new MLineVertex(position, direction, mitter, newDistances); } Elevation = newElevation; Normal = newNormal; Scale *= newScale; }
/// <summary> /// Decompose the actual multiline in its internal entities, <see cref="Line">lines</see> and <see cref="Arc">arcs</see>. /// </summary> /// <returns>A list of <see cref="Line">lines</see> and <see cref="Arc">arcs</see> that made up the multiline.</returns> public List <EntityObject> Explode() { List <EntityObject> entities = new List <EntityObject>(); Matrix3 transformation = MathHelper.ArbitraryAxis(this.Normal); // precomputed points at mline vertexes for start and end caps calculations Vector2[][] cornerVextexes = new Vector2[this.vertexes.Count][]; for (int i = 0; i < this.vertexes.Count; i++) { MLineVertex vertex = this.vertexes[i]; MLineVertex nextVertex; if (this.IsClosed && i == this.vertexes.Count - 1) { nextVertex = this.vertexes[0]; } else if (!this.IsClosed && i == this.vertexes.Count - 1) { continue; } else { nextVertex = this.vertexes[i + 1]; cornerVextexes[i + 1] = new Vector2[this.style.Elements.Count]; } cornerVextexes[i] = new Vector2[this.style.Elements.Count]; for (int j = 0; j < this.style.Elements.Count; j++) { if (vertex.Distances[j].Count == 0) { continue; } Vector2 refStart = vertex.Position + vertex.Miter * vertex.Distances[j][0]; cornerVextexes[i][j] = refStart; for (int k = 1; k < vertex.Distances[j].Count; k++) { Vector2 start = refStart + vertex.Direction * vertex.Distances[j][k]; Vector2 end; if (k >= vertex.Distances[j].Count - 1) { end = nextVertex.Position + nextVertex.Miter * nextVertex.Distances[j][0]; if (!this.IsClosed) { cornerVextexes[i + 1][j] = end; } } else { end = refStart + vertex.Direction * vertex.Distances[j][k + 1]; k++; // skip next segment it is a blank space } Line line = this.CreateLine(start, end, this.style.Elements[j].Color, this.style.Elements[j].Linetype); line.TransformBy(transformation, Vector3.Zero); entities.Add(line); } } } if (this.style.Flags.HasFlag(MLineStyleFlags.DisplayJoints)) { AciColor color1 = this.style.Elements[0].Color; AciColor color2 = this.style.Elements[this.style.Elements.Count - 1].Color; Linetype linetype1 = this.style.Elements[0].Linetype; Linetype linetype2 = this.style.Elements[this.style.Elements.Count - 1].Linetype; for (int i = 0; i < cornerVextexes.Length; i++) { if (!this.IsClosed && (i == 0 || i == cornerVextexes.Length - 1)) { continue; } Vector2 start = cornerVextexes[i][0]; Vector2 end = cornerVextexes[i][cornerVextexes[0].Length - 1]; entities.AddRange(this.CreateSquareCap(start, end, transformation, color1, linetype1, color2, linetype2)); } } // when the mline is closed there are no caps if (this.IsClosed) { return(entities); } if (!this.NoStartCaps) { if (this.style.Flags.HasFlag(MLineStyleFlags.StartRoundCap)) { AciColor color1 = this.style.Elements[0].Color; AciColor color2 = this.style.Elements[this.style.Elements.Count - 1].Color; Linetype linetype1 = this.style.Elements[0].Linetype; Linetype linetype2 = this.style.Elements[this.style.Elements.Count - 1].Linetype; Vector2 start = cornerVextexes[0][0]; Vector2 end = cornerVextexes[0][cornerVextexes[0].Length - 1]; entities.AddRange(this.scale >= 0 ? this.CreateRoundCap(start, end, transformation, color1, linetype1, color2, linetype2) : this.CreateRoundCap(end, start, transformation, color2, linetype2, color1, linetype1)); } if (this.style.Flags.HasFlag(MLineStyleFlags.StartInnerArcsCap)) { int j = (int)(this.style.Elements.Count / 2.0); // Math.Floor for (int i = 1; i < j; i++) { AciColor color1 = this.style.Elements[i].Color; AciColor color2 = this.style.Elements[this.style.Elements.Count - 1 - i].Color; Linetype linetype1 = this.style.Elements[i].Linetype; Linetype linetype2 = this.style.Elements[this.style.Elements.Count - 1 - i].Linetype; Vector2 start = cornerVextexes[0][i]; Vector2 end = cornerVextexes[0][cornerVextexes[0].Length - 1 - i]; entities.AddRange(this.scale >= 0 ? this.CreateRoundCap(start, end, transformation, color1, linetype1, color2, linetype2) : this.CreateRoundCap(end, start, transformation, color2, linetype2, color1, linetype1)); } } if (this.style.Flags.HasFlag(MLineStyleFlags.StartSquareCap)) { AciColor color1 = this.style.Elements[0].Color; AciColor color2 = this.style.Elements[this.style.Elements.Count - 1].Color; Linetype linetype1 = this.style.Elements[0].Linetype; Linetype linetype2 = this.style.Elements[this.style.Elements.Count - 1].Linetype; Vector2 start = cornerVextexes[0][0]; Vector2 end = cornerVextexes[0][cornerVextexes[0].Length - 1]; entities.AddRange(this.CreateSquareCap(start, end, transformation, color1, linetype1, color2, linetype2)); } } if (!this.NoEndCaps) { if (this.style.Flags.HasFlag(MLineStyleFlags.EndRoundCap)) { AciColor color1 = this.style.Elements[this.style.Elements.Count - 1].Color; AciColor color2 = this.style.Elements[0].Color; Linetype linetype1 = this.style.Elements[this.style.Elements.Count - 1].Linetype; Linetype linetype2 = this.style.Elements[0].Linetype; Vector2 start = cornerVextexes[this.vertexes.Count - 1][cornerVextexes[0].Length - 1]; Vector2 end = cornerVextexes[this.vertexes.Count - 1][0]; entities.AddRange(this.scale >= 0 ? this.CreateRoundCap(start, end, transformation, color1, linetype1, color2, linetype2) : this.CreateRoundCap(end, start, transformation, color2, linetype2, color1, linetype1)); } if (this.style.Flags.HasFlag(MLineStyleFlags.EndInnerArcsCap)) { int j = (int)(this.style.Elements.Count / 2.0); // Math.Floor for (int i = 1; i < j; i++) { AciColor color1 = this.style.Elements[this.style.Elements.Count - 1 - i].Color; AciColor color2 = this.style.Elements[i].Color; Linetype linetype1 = this.style.Elements[this.style.Elements.Count - 1 - i].Linetype; Linetype linetype2 = this.style.Elements[i].Linetype; Vector2 start = cornerVextexes[this.vertexes.Count - 1][cornerVextexes[0].Length - 1 - i]; Vector2 end = cornerVextexes[this.vertexes.Count - 1][i]; entities.AddRange(this.scale >= 0 ? this.CreateRoundCap(start, end, transformation, color1, linetype1, color2, linetype2) : this.CreateRoundCap(end, start, transformation, color2, linetype2, color1, linetype1)); } } if (this.style.Flags.HasFlag(MLineStyleFlags.EndSquareCap)) { AciColor color1 = this.style.Elements[this.style.Elements.Count - 1].Color; AciColor color2 = this.style.Elements[0].Color; Linetype linetype1 = this.style.Elements[this.style.Elements.Count - 1].Linetype; Linetype linetype2 = this.style.Elements[0].Linetype; Vector2 start = cornerVextexes[this.vertexes.Count - 1][cornerVextexes[0].Length - 1]; Vector2 end = cornerVextexes[this.vertexes.Count - 1][0]; entities.AddRange(this.CreateSquareCap(start, end, transformation, color1, linetype1, color2, linetype2)); } } return(entities); }
/// <summary> /// Calculates the internal information of the multiline vertexes. /// </summary> /// <remarks> /// <para> /// This function needs to be called manually when any modification is done that affects the final shape of the multiline. /// </para> /// <para> /// If the vertex distance list needs to be edited to represent trimmed multilines this function needs to be called prior to any modification. /// It will calculate the minimum information needed to build a correct multiline. /// </para> /// </remarks> public void Update() { if (vertexes.Count == 0) { return; } double reference = 0.0; switch (justification) { case MLineJustification.Top: reference = -style.Elements[0].Offset; break; case MLineJustification.Zero: reference = 0.0; break; case MLineJustification.Bottom: reference = -style.Elements[style.Elements.Count - 1].Offset; break; } Vector2 prevDir; if (vertexes[0].Position.Equals(vertexes[vertexes.Count - 1].Position)) { prevDir = Vector2.UnitY; } else { prevDir = vertexes[0].Position - vertexes[vertexes.Count - 1].Position; prevDir.Normalize(); } for (int i = 0; i < vertexes.Count; i++) { Vector2 position = vertexes[i].Position; Vector2 mitter; Vector2 dir; if (i == 0) { if (vertexes[i + 1].Position.Equals(position)) { dir = Vector2.UnitY; } else { dir = vertexes[i + 1].Position - position; dir.Normalize(); } if (IsClosed) { mitter = prevDir - dir; mitter.Normalize(); } else { mitter = MathHelper.Transform(dir, style.StartAngle * MathHelper.DegToRad, CoordinateSystem.Object, CoordinateSystem.World); mitter.Normalize(); } } else if (i + 1 == vertexes.Count) { if (IsClosed) { if (vertexes[0].Position.Equals(position)) { dir = Vector2.UnitY; } else { dir = vertexes[0].Position - position; dir.Normalize(); } mitter = prevDir - dir; mitter.Normalize(); } else { dir = prevDir; mitter = MathHelper.Transform(dir, style.EndAngle * MathHelper.DegToRad, CoordinateSystem.Object, CoordinateSystem.World); mitter.Normalize(); } } else { if (vertexes[i + 1].Position.Equals(position)) { dir = Vector2.UnitY; } else { dir = vertexes[i + 1].Position - position; dir.Normalize(); } mitter = prevDir - dir; mitter.Normalize(); } prevDir = dir; List <double>[] distances = new List <double> [style.Elements.Count]; double angleMitter = Vector2.Angle(mitter); double angleDir = Vector2.Angle(dir); double cos = Math.Cos(angleMitter + (MathHelper.HalfPI - angleDir)); for (int j = 0; j < style.Elements.Count; j++) { double distance = (style.Elements[j].Offset + reference) / cos; distances[j] = new List <double> { distance *scale, 0.0 }; } vertexes[i] = new MLineVertex(position, dir, -mitter, distances); } }
/// <summary> /// Decompose the actual multiline in its internal entities, <see cref="Line">lines</see> and <see cref="Arc">arcs</see>. /// </summary> /// <returns>A list of <see cref="Line">lines</see> and <see cref="Arc">arcs</see> that made up the multiline.</returns> /// <exception cref="InvalidOperationException">An exception will be thrown if the number of distances for a given MLineStyleElement is not an even number.</exception> public List <EntityObject> Explode() { Matrix3 transformation = MathHelper.ArbitraryAxis(Normal); List <EntityObject> entities = new List <EntityObject>(); // precomputed points at mline vertexes for start and end caps calculations Vector2[][] cornerVextexes = new Vector2[vertexes.Count][]; for (int i = 0; i < vertexes.Count; i++) { MLineVertex vertex = vertexes[i]; MLineVertex nextVertex; if (IsClosed && i == vertexes.Count - 1) { nextVertex = vertexes[0]; } else if (!IsClosed && i == vertexes.Count - 1) { continue; } else { nextVertex = vertexes[i + 1]; cornerVextexes[i + 1] = new Vector2[style.Elements.Count]; } cornerVextexes[i] = new Vector2[style.Elements.Count]; for (int j = 0; j < style.Elements.Count; j++) { if (style.Elements.Count % 2 != 0) { throw new InvalidOperationException("The number of distances for a given MLineStyleElement must be an even number."); } Vector2 refStart = vertex.Position + vertex.Miter * vertex.Distances[j][0]; cornerVextexes[i][j] = refStart; for (int k = 1; k < vertex.Distances[j].Count; k++) { Vector2 start = refStart + vertex.Direction * vertex.Distances[j][k]; Vector2 end; if (k >= vertex.Distances[j].Count - 1) { end = nextVertex.Position + nextVertex.Miter * nextVertex.Distances[j][0]; if (!IsClosed) { cornerVextexes[i + 1][j] = end; } } else { end = refStart + vertex.Direction * vertex.Distances[j][k + 1]; k++; // skip next segment it is a blank space } Line line = CreateLine(start, end, style.Elements[j].Color, style.Elements[j].Linetype); line.TransformBy(transformation, Vector3.Zero); entities.Add(line); } } } if (style.Flags.HasFlag(MLineStyleFlags.DisplayJoints)) { AciColor color1 = style.Elements[0].Color; AciColor color2 = style.Elements[style.Elements.Count - 1].Color; Linetype linetype1 = style.Elements[0].Linetype; Linetype linetype2 = style.Elements[style.Elements.Count - 1].Linetype; bool trim = !color1.Equals(color2) || !linetype1.Equals(linetype2); for (int i = 0; i < cornerVextexes.Length; i++) { if (!IsClosed && (i == 0 || i == cornerVextexes.Length - 1)) { continue; } Vector2 start = cornerVextexes[i][0]; Vector2 end = cornerVextexes[i][cornerVextexes[0].Length - 1]; Vector2 midPoint = Vector2.MidPoint(start, end); if (trim) { Line line1 = CreateLine(start, midPoint, color1, linetype1); line1.TransformBy(transformation, Vector3.Zero); entities.Add(line1); Line line2 = CreateLine(midPoint, end, color2, linetype2); line2.TransformBy(transformation, Vector3.Zero); entities.Add(line2); } else { Line line = CreateLine(start, end, color1, linetype1); line.TransformBy(transformation, Vector3.Zero); entities.Add(line); } } } // when the mline is closed there are no caps if (IsClosed) { return(entities); } if (!NoStartCaps) { if (style.Flags.HasFlag(MLineStyleFlags.StartRoundCap)) { AciColor color1 = style.Elements[0].Color; AciColor color2 = style.Elements[style.Elements.Count - 1].Color; Linetype linetype1 = style.Elements[0].Linetype; Linetype linetype2 = style.Elements[style.Elements.Count - 1].Linetype; bool trim = !color1.Equals(color2) || !linetype1.Equals(linetype2); Vector2 center = Vector2.MidPoint(cornerVextexes[0][0], cornerVextexes[0][cornerVextexes.Length - 1]); Vector2 start = cornerVextexes[0][0]; //Vector2 end = cornerVextexes[0][cornerVextexes[0].Length - 1]; double startAngle = Vector2.Angle(start - center) * MathHelper.RadToDeg; //double endAngle = Vector2.Angle(end - center) * MathHelper.RadToDeg; double endAngle = startAngle + 180.0; double radius = (start - center).Modulus(); if (trim) { double midAngle = startAngle + 90.0; Arc arc1 = CreateArc(center, radius, startAngle, midAngle, color1, linetype1); arc1.TransformBy(transformation, Vector3.Zero); entities.Add(arc1); Arc arc2 = CreateArc(center, radius, midAngle, endAngle, color2, linetype2); arc2.TransformBy(transformation, Vector3.Zero); entities.Add(arc2); } else { Arc arc = CreateArc(center, radius, startAngle, endAngle, color1, linetype1); arc.TransformBy(transformation, Vector3.Zero); entities.Add(arc); } } if (style.Flags.HasFlag(MLineStyleFlags.StartInnerArcsCap)) { Vector2 center = Vector2.MidPoint(cornerVextexes[0][0], cornerVextexes[0][cornerVextexes.Length - 1]);; int j = (int)Math.Floor(style.Elements.Count / 2.0); for (int i = 1; i < j; i++) { AciColor color1 = style.Elements[i].Color; AciColor color2 = style.Elements[style.Elements.Count - 1 - i].Color; Linetype linetype1 = style.Elements[i].Linetype; Linetype linetype2 = style.Elements[style.Elements.Count - 1 - i].Linetype; bool trim = !color1.Equals(color2) || !linetype1.Equals(linetype2); Vector2 start = cornerVextexes[0][i]; //Vector2 end = cornerVextexes[0][cornerVextexes[0].Length - 1 - i]; double startAngle = Vector2.Angle(start - center) * MathHelper.RadToDeg; //double endAngle = Vector2.Angle(end - center) * MathHelper.RadToDeg; double endAngle = startAngle + 180.0; double radius = (start - center).Modulus(); if (trim) { double midAngle = startAngle + 90.0; Arc arc1 = CreateArc(center, radius, startAngle, midAngle, color1, linetype1); arc1.TransformBy(transformation, Vector3.Zero); entities.Add(arc1); Arc arc2 = CreateArc(center, radius, midAngle, endAngle, color2, linetype2); arc2.TransformBy(transformation, Vector3.Zero); entities.Add(arc2); } else { Arc arc = CreateArc(center, radius, startAngle, endAngle, color1, linetype1); arc.TransformBy(transformation, Vector3.Zero); entities.Add(arc); } } } if (style.Flags.HasFlag(MLineStyleFlags.StartSquareCap)) { AciColor color1 = style.Elements[0].Color; AciColor color2 = style.Elements[style.Elements.Count - 1].Color; Linetype linetype1 = style.Elements[0].Linetype; Linetype linetype2 = style.Elements[style.Elements.Count - 1].Linetype; bool trim = !color1.Equals(color2) || !linetype1.Equals(linetype2); Vector2 start = cornerVextexes[0][0]; Vector2 end = cornerVextexes[0][cornerVextexes[0].Length - 1]; Vector2 midPoint = Vector2.MidPoint(start, end); if (trim) { Line line1 = CreateLine(start, midPoint, color1, linetype1); line1.TransformBy(transformation, Vector3.Zero); entities.Add(line1); Line line2 = CreateLine(midPoint, end, color2, linetype2); line2.TransformBy(transformation, Vector3.Zero); entities.Add(line2); } else { Line line = CreateLine(start, end, color1, linetype1); line.TransformBy(transformation, Vector3.Zero); entities.Add(line); } } } if (!NoEndCaps) { if (style.Flags.HasFlag(MLineStyleFlags.EndRoundCap)) { AciColor color1 = style.Elements[0].Color; AciColor color2 = style.Elements[style.Elements.Count - 1].Color; Linetype linetype1 = style.Elements[0].Linetype; Linetype linetype2 = style.Elements[style.Elements.Count - 1].Linetype; bool trim = !color1.Equals(color2) || !linetype1.Equals(linetype2); Vector2 center = Vector2.MidPoint(cornerVextexes[vertexes.Count - 1][0], cornerVextexes[vertexes.Count - 1][cornerVextexes.Length - 1]); Vector2 start = cornerVextexes[vertexes.Count - 1][cornerVextexes[0].Length - 1]; //Vector2 end = cornerVextexes[this.vertexes.Count - 1][0]; double startAngle = Vector2.Angle(start - center) * MathHelper.RadToDeg; //double endAngle = Vector2.Angle(end - center) * MathHelper.RadToDeg; double endAngle = startAngle + 180.0; double radius = (start - center).Modulus(); if (trim) { double midAngle = startAngle + 90.0; Arc arc1 = CreateArc(center, radius, midAngle, endAngle, color1, linetype1); arc1.TransformBy(transformation, Vector3.Zero); entities.Add(arc1); Arc arc2 = CreateArc(center, radius, startAngle, midAngle, color2, linetype2); arc2.TransformBy(transformation, Vector3.Zero); entities.Add(arc2); } else { Arc arc = CreateArc(center, radius, startAngle, endAngle, color1, linetype1); arc.TransformBy(transformation, Vector3.Zero); entities.Add(arc); } } if (style.Flags.HasFlag(MLineStyleFlags.EndInnerArcsCap)) { Vector2 center = Vector2.MidPoint(cornerVextexes[vertexes.Count - 1][0], cornerVextexes[vertexes.Count - 1][cornerVextexes.Length - 1]); int j = (int)Math.Floor(style.Elements.Count / 2.0); for (int i = 1; i < j; i++) { AciColor color1 = style.Elements[i].Color; AciColor color2 = style.Elements[style.Elements.Count - 1 - i].Color; Linetype linetype1 = style.Elements[i].Linetype; Linetype linetype2 = style.Elements[style.Elements.Count - 1 - i].Linetype; bool trim = !color1.Equals(color2) || !linetype1.Equals(linetype2); Vector2 start = cornerVextexes[vertexes.Count - 1][cornerVextexes[0].Length - 1 - i]; //Vector2 end = cornerVextexes[this.vertexes.Count - 1][i]; double startAngle = Vector2.Angle(start - center) * MathHelper.RadToDeg; //double endAngle = Vector2.Angle(end - center) * MathHelper.RadToDeg; double endAngle = startAngle + 180.0; double radius = (start - center).Modulus(); if (trim) { double midAngle = startAngle + 90.0; Arc arc1 = CreateArc(center, radius, midAngle, endAngle, color1, linetype1); arc1.TransformBy(transformation, Vector3.Zero); entities.Add(arc1); Arc arc2 = CreateArc(center, radius, startAngle, midAngle, color2, linetype2); arc2.TransformBy(transformation, Vector3.Zero); entities.Add(arc2); } else { Arc arc = CreateArc(center, radius, startAngle, endAngle, color1, linetype1); arc.TransformBy(transformation, Vector3.Zero); entities.Add(arc); } } } if (style.Flags.HasFlag(MLineStyleFlags.EndSquareCap)) { AciColor color1 = style.Elements[0].Color; AciColor color2 = style.Elements[style.Elements.Count - 1].Color; Linetype linetype1 = style.Elements[0].Linetype; Linetype linetype2 = style.Elements[style.Elements.Count - 1].Linetype; bool trim = !color1.Equals(color2) || !linetype1.Equals(linetype2); Vector2 start = cornerVextexes[vertexes.Count - 1][cornerVextexes[0].Length - 1]; Vector2 end = cornerVextexes[vertexes.Count - 1][0]; Vector2 midPoint = Vector2.MidPoint(start, end); if (trim) { Line line1 = CreateLine(midPoint, end, color1, linetype1); line1.TransformBy(transformation, Vector3.Zero); entities.Add(line1); Line line2 = CreateLine(start, midPoint, color2, linetype2); line2.TransformBy(transformation, Vector3.Zero); entities.Add(line2); } else { Line line = CreateLine(start, end, color1, linetype1); line.TransformBy(transformation, Vector3.Zero); entities.Add(line); } } } return(entities); }
private List<MLineVertex> ReadMLineSegments(int numVertexes, int numStyleElements, Vector3 normal, out double elevation) { elevation = 0.0; List<MLineVertex> segments = new List<MLineVertex>(); Matrix3 trans = MathHelper.ArbitraryAxis(normal).Traspose(); for (int i = 0; i < numVertexes; i++) { Vector3 vertex = new Vector3(); vertex.X = this.chunk.ReadDouble(); // code 11 this.chunk.Next(); vertex.Y = this.chunk.ReadDouble(); // code 21 this.chunk.Next(); vertex.Z = this.chunk.ReadDouble(); // code 31 this.chunk.Next(); Vector3 dir = new Vector3(); dir.X = this.chunk.ReadDouble(); // code 12 this.chunk.Next(); dir.Y = this.chunk.ReadDouble(); // code 22 this.chunk.Next(); dir.Z = this.chunk.ReadDouble(); // code 32 this.chunk.Next(); Vector3 mitter = new Vector3(); mitter.X = this.chunk.ReadDouble(); // code 13 this.chunk.Next(); mitter.Y = this.chunk.ReadDouble(); // code 23 this.chunk.Next(); mitter.Z = this.chunk.ReadDouble(); // code 33 this.chunk.Next(); List<double>[] distances = new List<double>[numStyleElements]; for (int j = 0; j < numStyleElements; j++) { distances[j] = new List<double>(); short numDistances = this.chunk.ReadShort(); // code 74 this.chunk.Next(); for (short k = 0; k < numDistances; k++) { distances[j].Add(this.chunk.ReadDouble()); // code 41 this.chunk.Next(); } // no more info is needed, fill parameters are not supported short numFillParams = this.chunk.ReadShort(); // code 75 this.chunk.Next(); for (short k = 0; k < numFillParams; k++) { //double param = this.chunk.ReadDouble(); // code 42 this.chunk.Next(); } } // we need to convert WCS coordinates to OCS coordinates if (!normal.Equals(Vector3.UnitZ)) { vertex = trans*vertex; dir = trans*dir; mitter = trans*mitter; } MLineVertex segment = new MLineVertex(new Vector2(vertex.X, vertex.Y), new Vector2(dir.X, dir.Y), new Vector2(mitter.X, mitter.Y), distances); elevation = vertex.Z; segments.Add(segment); } return segments; }