Пример #1
2
        private static void AssociativeHatches()
        {
            DxfDocument dxf = new DxfDocument(DxfVersion.AutoCad2010);

            LwPolyline poly = new LwPolyline();
            poly.Vertexes.Add(new LwPolylineVertex(-10, -10));
            poly.Vertexes.Add(new LwPolylineVertex(10, -10));
            poly.Vertexes.Add(new LwPolylineVertex(10, 10));
            poly.Vertexes.Add(new LwPolylineVertex(-10, 10));
            // optionally you can the normal of the polyline, by default it is the UnitZ vector
            //poly.Normal = new Vector3(1.0);
            poly.IsClosed = true;


            HatchBoundaryPath boundary = new HatchBoundaryPath(new List<EntityObject> { poly });
            HatchPattern pattern = HatchPattern.Line;
            pattern.Scale = 10;
            pattern.Angle = 45;

            // the hatch boundary can be set in the hatch constructor or it can be added later
            //Hatch hatch = new Hatch(pattern, new[]{boundary}, true);

            Hatch hatch = new Hatch(pattern, true);
            // you will need to manually set the hatch normal to the boundary normal if it is not the UnitZ,
            // to work properly all boundary entities must belong to the same plane
            //hatch.Normal = poly.Normal;

            // the hatch boundary can be set in the hatch constructor or it can be added later, remember hatches with no boundaries will not be saved
            hatch.BoundaryPaths.Add(boundary);
            Circle circle = new Circle(Vector2.Zero, 5);
            // all boundary entities should have the same normal, by default it is the UnitZ
            // the hatch will not handle the normals of the different boundary path, you will have to make sure they all lay on the same plane
            //circle.Normal = poly.Normal;

            hatch.BoundaryPaths.Add(new HatchBoundaryPath(new List<EntityObject> { circle }));
            // when an associative hatch is added to a document the referenced boundary entities will be added too
            dxf.AddEntity(hatch);
            dxf.Save("Hatch.dxf");


            DxfDocument dxf2 = DxfDocument.Load("Hatch.dxf");
            // you can remove boundaries from a hatch
            dxf2.Hatches[0].BoundaryPaths.Remove(dxf2.Hatches[0].BoundaryPaths[1]);
            // and add new ones
            LwPolyline p = new LwPolyline();
            p.Vertexes.Add(new LwPolylineVertex(-20, -20));
            p.Vertexes.Add(new LwPolylineVertex(20, -20));
            p.Vertexes.Add(new LwPolylineVertex(20, 20));
            p.Vertexes.Add(new LwPolylineVertex(-20, 20));
            p.IsClosed = true;
            dxf2.Hatches[0].BoundaryPaths.Add(new HatchBoundaryPath(new List<EntityObject> { p }));
            dxf2.Save("Hatch add and remove boundaries.dxf");


            DxfDocument dxf3 = DxfDocument.Load("Hatch.dxf");
            // unlinking the boundary entities from a hatch will not automatically remove them from the document, you can use the returned list to delete them
            // unlinking the boundary will make the hatch non-associative 
            List<EntityObject> oldBoundary = dxf3.Hatches[0].UnLinkBoundary();
            dxf3.RemoveEntity(oldBoundary);

            // we can recreate the hatch boundary and optionally linking it, thus making it associative,
            // if the hatch is associative and belongs to a document the new entities will also be automatically added to the same document
            List<EntityObject> newBoundary = dxf3.Hatches[0].CreateBoundary(true);

            dxf3.Save("Hatch new contour.dxf");

            DxfDocument dxf4 = DxfDocument.Load("Hatch.dxf");
            // if the hatch is associative, it is possible to modify the entities that make the boundary
            // for non-associative the list of entities will contain zero items
            if (dxf4.Hatches[0].Associative)
            {
                // this will only work for associative hatches
                HatchBoundaryPath path = dxf4.Hatches[0].BoundaryPaths[0];
                LwPolyline entity = (LwPolyline) path.Entities[0];
                entity.Vertexes[2].Position = new Vector2(15, 15);
                // after modifying the boundary entities, it is necessary to rebuild the edges
                path.Update();
                dxf4.Save("Hatch change boundary.dxf");
            }
        }
Пример #2
0
        /// <summary>
        /// Creates a new HatchBoundaryPath that is a copy of the current instance.
        /// </summary>
        /// <returns>A new HatchBoundaryPath that is a copy of this instance.</returns>
        public object Clone()
        {
            HatchBoundaryPath copy;

            //// the hatch is associative
            if (this.contour.Count > 0)
            {
                List <EntityObject> copyContour = new List <EntityObject>();
                foreach (EntityObject entity in this.contour)
                {
                    copyContour.Add((EntityObject)entity.Clone());
                }
                copy = new HatchBoundaryPath(copyContour);
            }
            else
            {
                List <Edge> copyEdges = new List <Edge>();
                foreach (Edge edge in this.edges)
                {
                    copyEdges.Add((Edge)edge.Clone());
                }
                copy = new HatchBoundaryPath(copyEdges);
            }
            //copy.PathType = this.pathType;
            return(copy);
        }
Пример #3
0
        protected virtual void OnHatchBoundaryPathRemovedEvent(HatchBoundaryPath item)
        {
            HatchBoundaryPathRemovedEventHandler ae = this.HatchBoundaryPathRemoved;

            if (ae != null)
            {
                ae(this, new ObservableCollectionEventArgs <HatchBoundaryPath>(item));
            }
        }
Пример #4
0
 /// <summary>
 /// Convert a netDXF HatchBoundaryPath to a Nucleus PolyCurve
 /// or PolyLine
 /// </summary>
 /// <param name="path"></param>
 /// <returns></returns>
 public static Curve Convert(nDE.HatchBoundaryPath path)
 {
     PolyCurve result = new PolyCurve();
     foreach (nDE.HatchBoundaryPath.Edge edge in path.Edges)
     {
         VertexGeometry edgeRep = Convert(edge.ConvertTo());
         if (edgeRep != null && edgeRep is Curve)
         {
             result.Add((Curve)edgeRep);
         }
     }
     if (result.IsPolyline()) return result.ToPolyLine();
     else return result;
 }
Пример #5
0
        /// <summary>
        /// Convert a Nucleus curve to a netDXF HatchBoundaryPath
        /// </summary>
        /// <param name="curve"></param>
        /// <returns></returns>
        public static nDE.HatchBoundaryPath ConvertToBoundary(Curve curve)
        {
            IEnumerable <nDE.EntityObject> pathObjs;

            if (!(curve is PolyLine))
            {
                pathObjs = Convert(curve);
            }
            else
            {
                pathObjs = Convert(((PolyLine)curve).ToPolyCurve());
            }
            var result = new nDE.HatchBoundaryPath(pathObjs);//Convert(curve));

            return(result);
        }
Пример #6
0
        /// <summary>
        /// Creates a new HatchBoundaryPath that is a copy of the current instance.
        /// </summary>
        /// <returns>A new HatchBoundaryPath that is a copy of this instance.</returns>
        public object Clone()
        {
            List <Edge> copyEdges = new List <Edge>();

            foreach (Edge edge in this.edges)
            {
                copyEdges.Add((Edge)edge.Clone());
            }

            HatchBoundaryPath copy = new HatchBoundaryPath(copyEdges)
            {
                pathType = this.pathType
            };

            return(copy);
        }
Пример #7
0
        private void CreateHatchBoundsAndEntitiess(Test2d.XPathGeometry pg, double dx, double dy, out ICollection<HatchBoundaryPath> bounds, out ICollection<EntityObject> entities)
        {
            bounds = new List<HatchBoundaryPath>();
            entities = new List<EntityObject>();

            // TODO: FillMode = pg.FillRule == Test2d.XFillRule.EvenOdd ? FillMode.Alternate : FillMode.Winding;

            foreach (var pf in pg.Figures)
            {
                var edges = new List<EntityObject>();
                var startPoint = pf.StartPoint;

                foreach (var segment in pf.Segments)
                {
                    if (segment is Test2d.XArcSegment)
                    {
                        throw new NotSupportedException("Not supported segment type: " + segment.GetType());
                        //var arcSegment = segment as Test2d.XArcSegment;
                        // TODO: Convert WPF/SVG elliptical arc segment format to DXF ellipse arc.
                        //startPoint = arcSegment.Point;
                    }
                    else if (segment is Test2d.XBezierSegment)
                    {
                        var bezierSegment = segment as Test2d.XBezierSegment;
                        var dxfSpline = CreateCubicSpline(
                            startPoint.X + dx,
                            startPoint.Y + dy,
                            bezierSegment.Point1.X + dx,
                            bezierSegment.Point1.Y + dy,
                            bezierSegment.Point2.X + dx,
                            bezierSegment.Point2.Y + dy,
                            bezierSegment.Point3.X + dx,
                            bezierSegment.Point3.Y + dy);
                        edges.Add(dxfSpline);
                        entities.Add((Spline)dxfSpline.Clone());
                        startPoint = bezierSegment.Point3;
                    }
                    else if (segment is Test2d.XLineSegment)
                    {
                        var lineSegment = segment as Test2d.XLineSegment;
                        var dxfLine = CreateLine(
                            startPoint.X + dx,
                            startPoint.Y + dy,
                            lineSegment.Point.X + dx,
                            lineSegment.Point.Y + dy);
                        edges.Add(dxfLine);
                        entities.Add((Line)dxfLine.Clone());
                        startPoint = lineSegment.Point;
                    }
                    else if (segment is Test2d.XPolyBezierSegment)
                    {
                        var polyBezierSegment = segment as Test2d.XPolyBezierSegment;
                        if (polyBezierSegment.Points.Count >= 3)
                        {
                            var dxfSpline = CreateCubicSpline(
                                startPoint.X + dx,
                                startPoint.Y + dy,
                                polyBezierSegment.Points[0].X + dx,
                                polyBezierSegment.Points[0].Y + dy,
                                polyBezierSegment.Points[1].X + dx,
                                polyBezierSegment.Points[1].Y + dy,
                                polyBezierSegment.Points[2].X + dx,
                                polyBezierSegment.Points[2].Y + dy);
                            edges.Add(dxfSpline);
                            entities.Add((Spline)dxfSpline.Clone());
                        }

                        if (polyBezierSegment.Points.Count > 3
                            && polyBezierSegment.Points.Count % 3 == 0)
                        {
                            for (int i = 3; i < polyBezierSegment.Points.Count; i += 3)
                            {
                                var dxfSpline = CreateCubicSpline(
                                    polyBezierSegment.Points[i - 1].X + dx,
                                    polyBezierSegment.Points[i - 1].Y + dy,
                                    polyBezierSegment.Points[i].X + dx,
                                    polyBezierSegment.Points[i].Y + dy,
                                    polyBezierSegment.Points[i + 1].X + dx,
                                    polyBezierSegment.Points[i + 1].Y + dy,
                                    polyBezierSegment.Points[i + 2].X + dx,
                                    polyBezierSegment.Points[i + 2].Y + dy);
                                edges.Add(dxfSpline);
                                entities.Add((Spline)dxfSpline.Clone());
                            }
                        }

                        startPoint = polyBezierSegment.Points.Last();
                    }
                    else if (segment is Test2d.XPolyLineSegment)
                    {
                        var polyLineSegment = segment as Test2d.XPolyLineSegment;
                        if (polyLineSegment.Points.Count >= 1)
                        {
                            var dxfLine = CreateLine(
                                startPoint.X + dx,
                                startPoint.Y + dy,
                                polyLineSegment.Points[0].X + dx,
                                polyLineSegment.Points[0].Y + dy);
                            edges.Add(dxfLine);
                            entities.Add((Line)dxfLine.Clone());
                        }

                        if (polyLineSegment.Points.Count > 1)
                        {
                            for (int i = 1; i < polyLineSegment.Points.Count; i++)
                            {
                                var dxfLine = CreateLine(
                                    polyLineSegment.Points[i - 1].X + dx,
                                    polyLineSegment.Points[i - 1].Y + dy,
                                    polyLineSegment.Points[i].X + dx,
                                    polyLineSegment.Points[i].Y + dy);
                                edges.Add(dxfLine);
                                entities.Add((Line)dxfLine.Clone());
                            }
                        }

                        startPoint = polyLineSegment.Points.Last();
                    }
                    else if (segment is Test2d.XPolyQuadraticBezierSegment)
                    {
                        var polyQuadraticSegment = segment as Test2d.XPolyQuadraticBezierSegment;
                        if (polyQuadraticSegment.Points.Count >= 2)
                        {
                            var dxfSpline = CreateQuadraticSpline(
                                startPoint.X + dx,
                                startPoint.Y + dy,
                                polyQuadraticSegment.Points[0].X + dx,
                                polyQuadraticSegment.Points[0].Y + dy,
                                polyQuadraticSegment.Points[1].X + dx,
                                polyQuadraticSegment.Points[1].Y + dy);
                            edges.Add(dxfSpline);
                            entities.Add((Spline)dxfSpline.Clone());
                        }

                        if (polyQuadraticSegment.Points.Count > 2
                            && polyQuadraticSegment.Points.Count % 2 == 0)
                        {
                            for (int i = 3; i < polyQuadraticSegment.Points.Count; i += 3)
                            {
                                var dxfSpline = CreateQuadraticSpline(
                                    polyQuadraticSegment.Points[i - 1].X + dx,
                                    polyQuadraticSegment.Points[i - 1].Y + dy,
                                    polyQuadraticSegment.Points[i].X + dx,
                                    polyQuadraticSegment.Points[i].Y + dy,
                                    polyQuadraticSegment.Points[i + 1].X + dx,
                                    polyQuadraticSegment.Points[i + 1].Y + dy);
                                edges.Add(dxfSpline);
                                entities.Add((Spline)dxfSpline.Clone());
                            }
                        }

                        startPoint = polyQuadraticSegment.Points.Last();
                    }
                    else if (segment is Test2d.XQuadraticBezierSegment)
                    {
                        var qbezierSegment = segment as Test2d.XQuadraticBezierSegment;
                        var dxfSpline = CreateQuadraticSpline(
                            startPoint.X + dx,
                            startPoint.Y + dy,
                            qbezierSegment.Point1.X + dx,
                            qbezierSegment.Point1.Y + dy,
                            qbezierSegment.Point2.X + dx,
                            qbezierSegment.Point2.Y + dy);
                        edges.Add(dxfSpline);
                        entities.Add((Spline)dxfSpline.Clone());
                        startPoint = qbezierSegment.Point2;
                    }
                    else
                    {
                        throw new NotSupportedException("Not supported segment type: " + segment.GetType());
                    }
                }

                // TODO: Add support for pf.IsClosed

                var path  = new HatchBoundaryPath(edges);
                bounds.Add(path);
            }
        }
Пример #8
0
        private void WriteHatchBoundaryPathData(HatchBoundaryPath.Edge entity)
        {
            if (entity.Type == HatchBoundaryPath.EdgeType.Arc)
            {
                this.chunk.Write(72, (short) 2); // Edge type (only if boundary is not a polyline): 1 = Line; 2 = Circular arc; 3 = Elliptic arc; 4 = Spline

                HatchBoundaryPath.Arc arc = (HatchBoundaryPath.Arc) entity;

                this.chunk.Write(10, arc.Center.X);
                this.chunk.Write(20, arc.Center.Y);
                this.chunk.Write(40, arc.Radius);
                this.chunk.Write(50, arc.StartAngle);
                this.chunk.Write(51, arc.EndAngle);
                this.chunk.Write(73, arc.IsCounterclockwise ? (short) 1 : (short) 0);
            }
            else if (entity.Type == HatchBoundaryPath.EdgeType.Ellipse)
            {
                this.chunk.Write(72, (short) 3); // Edge type (only if boundary is not a polyline): 1 = Line; 2 = Circular arc; 3 = Elliptic arc; 4 = Spline

                HatchBoundaryPath.Ellipse ellipse = (HatchBoundaryPath.Ellipse) entity;

                this.chunk.Write(10, ellipse.Center.X);
                this.chunk.Write(20, ellipse.Center.Y);
                this.chunk.Write(11, ellipse.EndMajorAxis.X);
                this.chunk.Write(21, ellipse.EndMajorAxis.Y);
                this.chunk.Write(40, ellipse.MinorRatio);
                this.chunk.Write(50, ellipse.StartAngle);
                this.chunk.Write(51, ellipse.EndAngle);
                this.chunk.Write(73, ellipse.IsCounterclockwise ? (short) 1 : (short) 0);
            }
            else if (entity.Type == HatchBoundaryPath.EdgeType.Line)
            {
                this.chunk.Write(72, (short) 1); // Edge type (only if boundary is not a polyline): 1 = Line; 2 = Circular arc; 3 = Elliptic arc; 4 = Spline

                HatchBoundaryPath.Line line = (HatchBoundaryPath.Line) entity;

                this.chunk.Write(10, line.Start.X);
                this.chunk.Write(20, line.Start.Y);
                this.chunk.Write(11, line.End.X);
                this.chunk.Write(21, line.End.Y);
            }
            else if (entity.Type == HatchBoundaryPath.EdgeType.Polyline)
            {
                HatchBoundaryPath.Polyline poly = (HatchBoundaryPath.Polyline) entity;
                this.chunk.Write(72, (short) 1); // Has bulge flag
                this.chunk.Write(73, poly.IsClosed ? (short) 1 : (short) 0);
                this.chunk.Write(93, poly.Vertexes.Length);

                foreach (Vector3 vertex in poly.Vertexes)
                {
                    this.chunk.Write(10, vertex.X);
                    this.chunk.Write(20, vertex.Y);
                    this.chunk.Write(42, vertex.Z);
                }
            }
            else if (entity.Type == HatchBoundaryPath.EdgeType.Spline)
            {
                this.chunk.Write(72, (short) 4); // Edge type (only if boundary is not a polyline): 1 = Line; 2 = Circular arc; 3 = Elliptic arc; 4 = Spline

                HatchBoundaryPath.Spline spline = (HatchBoundaryPath.Spline) entity;

                // another dxf inconsistency!; while the Spline entity degree is written as a short (code 71)
                // the degree of a hatch boundary path spline is written as an int (code 94)
                this.chunk.Write(94, (int) spline.Degree);
                this.chunk.Write(73, spline.IsRational ? (short) 1 : (short) 0);
                this.chunk.Write(74, spline.IsPeriodic ? (short) 1 : (short) 0);

                // now the number of knots and control points of a spline are written as an int, as it should be.
                // but in the Spline entities they are defined as shorts. Guess what, while you can avoid writing these two codes for the Spline entity, now they are required.
                this.chunk.Write(95, spline.Knots.Length);
                this.chunk.Write(96, spline.ControlPoints.Length);

                foreach (double knot in spline.Knots)
                    this.chunk.Write(40, knot);
                foreach (Vector3 point in spline.ControlPoints)
                {
                    this.chunk.Write(10, point.X);
                    this.chunk.Write(20, point.Y);
                    if (spline.IsRational) this.chunk.Write(42, point.Z);
                }

                //this.chunk.Write(96, spline.FitPoints.Length);
                //foreach (Vector2 point in spline.FitPoints)
                //{
                //    this.chunk.Write(11, point.X);
                //    this.chunk.Write(21, point.Y);
                //}
                //if (spline.StartTangent != null)
                //{
                //    this.chunk.Write(12, spline.StartTangent.Value.X);
                //    this.chunk.Write(22, spline.StartTangent.Value.Y);
                //}
                //if (spline.EndTangent != null)
                //{
                //    this.chunk.Write(12, spline.EndTangent.Value.X);
                //    this.chunk.Write(22, spline.EndTangent.Value.Y);
                //}

                // this information is only required for AutoCAD version 2010
                // stores information about spline fit points (the spline entity has no fit points and no tangent info)
                // another dxf inconsistency!; while the number of fit points of Spline entity is written as a short (code 74)
                // the number of fit points of a hatch boundary path spline is written as an int (code 97)
                if (this.doc.DrawingVariables.AcadVer >= DxfVersion.AutoCad2010) this.chunk.Write(97, 0);
            }
        }
        /// <summary>
        /// Creates a new HatchBoundaryPath that is a copy of the current instance.
        /// </summary>
        /// <returns>A new HatchBoundaryPath that is a copy of this instance.</returns>
        public object Clone()
        {
            List<Edge> copyEdges = new List<Edge>();
            foreach (Edge edge in this.edges)
                copyEdges.Add((Edge) edge.Clone());

            HatchBoundaryPath copy = new HatchBoundaryPath(copyEdges)
            {
                pathTypeFlag = this.pathTypeFlag
            };

            return copy;
        }
Пример #10
0
 protected virtual void OnHatchBoundaryPathRemovedEvent(HatchBoundaryPath item)
 {
     HatchBoundaryPathRemovedEventHandler ae = this.HatchBoundaryPathRemoved;
     if (ae != null)
         ae(this, new ObservableCollectionEventArgs<HatchBoundaryPath>(item));
 }
Пример #11
0
        private HatchBoundaryPath ReadEdgePolylineBoundaryPath()
        {
            HatchBoundaryPath.Polyline poly = new HatchBoundaryPath.Polyline();

            this.chunk.Next();

            bool hasBulge = this.chunk.ReadShort() != 0; // code 72
            this.chunk.Next();

            // is polyline closed
            poly.IsClosed = this.chunk.ReadShort() != 0; // code 73
            this.chunk.Next();

            int numVertexes = this.chunk.ReadInt(); // code 93
            poly.Vertexes = new Vector3[numVertexes];
            this.chunk.Next();

            for (int i = 0; i < numVertexes; i++)
            {
                double bulge = 0.0;
                double x = this.chunk.ReadDouble(); // code 10
                this.chunk.Next();
                double y = this.chunk.ReadDouble(); // code 20
                this.chunk.Next();
                if (hasBulge)
                {
                    bulge = this.chunk.ReadDouble(); // code 42
                    this.chunk.Next();
                }
                poly.Vertexes[i] = new Vector3(x, y, bulge);
            }
            HatchBoundaryPath path = new HatchBoundaryPath(new List<HatchBoundaryPath.Edge> {poly});

            // read all referenced entities
            Debug.Assert(this.chunk.Code == 97, "The reference count code 97 was expected.");
            int numBoundaryObjects = this.chunk.ReadInt();
            this.hatchContourns.Add(path, new List<string>(numBoundaryObjects));
            this.chunk.Next();
            for (int i = 0; i < numBoundaryObjects; i++)
            {
                Debug.Assert(this.chunk.Code == 330, "The reference handle code 330 was expected.");
                this.hatchContourns[path].Add(this.chunk.ReadString());
                this.chunk.Next();
            }

            return path;
        }
Пример #12
0
        private HatchBoundaryPath ReadEdgeBoundaryPath(int numEdges)
        {
            // the information of the boundary path data always appear exactly as it is read
            List<HatchBoundaryPath.Edge> entities = new List<HatchBoundaryPath.Edge>();
            this.chunk.Next();

            while (entities.Count < numEdges)
            {
                // Edge type (only if boundary is not a polyline): 1 = Line; 2 = Circular arc; 3 = Elliptic arc; 4 = Spline
                HatchBoundaryPath.EdgeType type = (HatchBoundaryPath.EdgeType) this.chunk.ReadShort();
                switch (type)
                {
                    case HatchBoundaryPath.EdgeType.Line:
                        this.chunk.Next();
                        // line
                        double lX1 = this.chunk.ReadDouble(); // code 10
                        this.chunk.Next();
                        double lY1 = this.chunk.ReadDouble(); // code 20
                        this.chunk.Next();
                        double lX2 = this.chunk.ReadDouble(); // code 11
                        this.chunk.Next();
                        double lY2 = this.chunk.ReadDouble(); // code 21
                        this.chunk.Next();

                        HatchBoundaryPath.Line line = new HatchBoundaryPath.Line
                        {
                            Start = new Vector2(lX1, lY1),
                            End = new Vector2(lX2, lY2)
                        };
                        entities.Add(line);
                        break;
                    case HatchBoundaryPath.EdgeType.Arc:
                        this.chunk.Next();
                        // circular arc
                        double aX = this.chunk.ReadDouble(); // code 10
                        this.chunk.Next();
                        double aY = this.chunk.ReadDouble(); // code 40
                        this.chunk.Next();
                        double aR = this.chunk.ReadDouble(); // code 40
                        this.chunk.Next();
                        double aStart = this.chunk.ReadDouble(); // code 50
                        this.chunk.Next();
                        double aEnd = this.chunk.ReadDouble(); // code 51
                        this.chunk.Next();
                        bool aCCW = this.chunk.ReadShort() != 0; // code 73
                        this.chunk.Next();

                        HatchBoundaryPath.Arc arc = new HatchBoundaryPath.Arc
                        {
                            Center = new Vector2(aX, aY),
                            Radius = aR,
                            StartAngle = aStart,
                            EndAngle = aEnd,
                            IsCounterclockwise = aCCW
                        };
                        entities.Add(arc);
                        break;
                    case HatchBoundaryPath.EdgeType.Ellipse:
                        this.chunk.Next();
                        // elliptic arc
                        double eX = this.chunk.ReadDouble(); // code 10
                        this.chunk.Next();
                        double eY = this.chunk.ReadDouble(); // code 20
                        this.chunk.Next();
                        double eAxisX = this.chunk.ReadDouble(); // code 11
                        this.chunk.Next();
                        double eAxisY = this.chunk.ReadDouble(); // code 21
                        this.chunk.Next();
                        double eAxisRatio = this.chunk.ReadDouble(); // code 40
                        this.chunk.Next();
                        double eStart = this.chunk.ReadDouble(); // code 50
                        this.chunk.Next();
                        double eEnd = this.chunk.ReadDouble(); // code 51
                        this.chunk.Next();
                        bool eCCW = this.chunk.ReadShort() != 0; // code 73
                        this.chunk.Next();

                        HatchBoundaryPath.Ellipse ellipse = new HatchBoundaryPath.Ellipse
                        {
                            Center = new Vector2(eX, eY),
                            EndMajorAxis = new Vector2(eAxisX, eAxisY),
                            MinorRatio = eAxisRatio,
                            StartAngle = eStart,
                            EndAngle = eEnd,
                            IsCounterclockwise = eCCW
                        };

                        entities.Add(ellipse);
                        break;
                    case HatchBoundaryPath.EdgeType.Spline:
                        this.chunk.Next();
                        // spline

                        short degree = (short) this.chunk.ReadInt(); // code 94
                        this.chunk.Next();

                        bool isRational = this.chunk.ReadShort() != 0; // code 73
                        this.chunk.Next();

                        bool isPeriodic = this.chunk.ReadShort() != 0; // code 74
                        this.chunk.Next();

                        int numKnots = this.chunk.ReadInt(); // code 95
                        double[] knots = new double[numKnots];
                        this.chunk.Next();

                        int numControlPoints = this.chunk.ReadInt(); // code 96
                        Vector3[] controlPoints = new Vector3[numControlPoints];
                        this.chunk.Next();

                        for (int i = 0; i < numKnots; i++)
                        {
                            knots[i] = this.chunk.ReadDouble(); // code 40
                            this.chunk.Next();
                        }

                        for (int i = 0; i < numControlPoints; i++)
                        {
                            double x = this.chunk.ReadDouble(); // code 10
                            this.chunk.Next();

                            double y = this.chunk.ReadDouble(); // code 20
                            this.chunk.Next();

                            // control point weight might not be present
                            double w = 1.0;
                            if (this.chunk.Code == 42)
                            {
                                w = this.chunk.ReadDouble(); // code 42
                                this.chunk.Next();
                            }

                            controlPoints[i] = new Vector3(x, y, w);
                        }

                        // this information is only required for AutoCAD version 2010 and newer
                        // stores information about spline fit point (the spline entity does not make use of this information)
                        if (this.doc.DrawingVariables.AcadVer >= DxfVersion.AutoCad2010)
                        {
                            int numFitData = this.chunk.ReadInt(); // code 97
                            this.chunk.Next();
                            for (int i = 0; i < numFitData; i++)
                            {
                                //double fitX = this.chunk.ReadDouble(); // code 11
                                this.chunk.Next();
                                //double fitY = this.chunk.ReadDouble(); // code 21
                                this.chunk.Next();
                            }

                            // the info on start tangent might not appear
                            if (this.chunk.Code == 12)
                            {
                                //double startTanX = this.chunk.ReadDouble(); // code 12
                                this.chunk.Next();
                                //double startTanY = this.chunk.ReadDouble(); // code 22
                                this.chunk.Next();
                            }
                            // the info on end tangent might not appear
                            if (this.chunk.Code == 13)
                            {
                                //double endTanX = this.chunk.ReadDouble(); // code 13
                                this.chunk.Next();
                                //double endTanY = this.chunk.ReadDouble(); // code 23
                                this.chunk.Next();
                            }
                        }

                        HatchBoundaryPath.Spline spline = new HatchBoundaryPath.Spline
                        {
                            Degree = degree,
                            IsPeriodic = isPeriodic,
                            IsRational = isRational,
                            ControlPoints = controlPoints,
                            Knots = knots
                        };

                        entities.Add(spline);
                        break;
                }
            }

            HatchBoundaryPath path = new HatchBoundaryPath(entities);

            // read all referenced entities
            Debug.Assert(this.chunk.Code == 97, "The reference count code 97 was expected.");
            int numBoundaryObjects = this.chunk.ReadInt();
            this.hatchContourns.Add(path, new List<string>(numBoundaryObjects));
            this.chunk.Next();
            for (int i = 0; i < numBoundaryObjects; i++)
            {
                Debug.Assert(this.chunk.Code == 330, "The reference handle code 330 was expected.");
                this.hatchContourns[path].Add(this.chunk.ReadString());
                this.chunk.Next();
            }

            return path;
        }
Пример #13
0
        private static void WriteSplineBoundaryHatch()
        {

            List<SplineVertex> ctrlPoints = new List<SplineVertex>
                                                {
                                                    new SplineVertex(new Vector3(0, 0, 0)),
                                                    new SplineVertex(new Vector3(25, 50, 0)),
                                                    new SplineVertex(new Vector3(50, 0, 0)),
                                                    new SplineVertex(new Vector3(75, 50, 0)),
                                                    new SplineVertex(new Vector3(100, 0, 0))
                                                };

            // hatch with single closed spline boundary path
            Spline spline = new Spline(ctrlPoints, 3, true); // closed periodic

            List<HatchBoundaryPath> boundary = new List<HatchBoundaryPath>();

            HatchBoundaryPath path = new HatchBoundaryPath(new List<EntityObject> {spline});
            boundary.Add(path);
            Hatch hatch = new Hatch(HatchPattern.Line, boundary, true);
            hatch.Pattern.Angle = 45;
            hatch.Pattern.Scale = 10;

            DxfDocument dxf = new DxfDocument();
            dxf.AddEntity(hatch);
            dxf.AddEntity(spline);
            dxf.Save("hatch closed spline.dxf");
            dxf = DxfDocument.Load("hatch closed spline.dxf");
            dxf.DrawingVariables.AcadVer = DxfVersion.AutoCad2010;
            dxf.Save("hatch closed spline 2010.dxf");

            // hatch boundary path with spline and line
            Spline openSpline = new Spline(ctrlPoints, 3);
            Line line = new Line(ctrlPoints[0].Position, ctrlPoints[ctrlPoints.Count - 1].Position);

            List<HatchBoundaryPath> boundary2 = new List<HatchBoundaryPath>();
            HatchBoundaryPath path2 = new HatchBoundaryPath(new List<EntityObject> { openSpline, line });
            boundary2.Add(path2);
            Hatch hatch2 = new Hatch(HatchPattern.Line, boundary2, true);
            hatch2.Pattern.Angle = 45;
            hatch2.Pattern.Scale = 10;

            DxfDocument dxf2 = new DxfDocument();
            dxf2.AddEntity(hatch2);
            dxf2.AddEntity(openSpline);
            dxf2.AddEntity(line);
            dxf2.Save("hatch open spline.dxf");
            dxf2 = DxfDocument.Load("hatch open spline.dxf");
            dxf.DrawingVariables.AcadVer = DxfVersion.AutoCad2010;
            dxf2.Save("hatch open spline 2010.dxf");

        }