示例#1
0
        /// <summary>
        /// Reads a poly line from the DXF file and construct a boundary from the geometry and extended attributes
        /// defining the boundary type and name
        /// </summary>
        /// <param name="closedPolyLinesOnly"></param>
        /// <param name="atEof"></param>
        /// <param name="boundary"></param>
        /// <returns></returns>
        public bool GetBoundaryFromPolyLineEntity(bool closedPolyLinesOnly, out bool atEof, out PolyLineBoundary boundary)
        {
            var loadError        = false;
            var polyLineIsClosed = false;

            atEof    = GetStartOfNextEntity(out var DXFRec);
            boundary = null;

            if (atEof)
            {
                return(false);
            }

            boundary = new PolyLineBoundary();

            var testString = DXFRec.s.ToUpper(CultureInfo.InvariantCulture);

            switch (testString)
            {
            // ReSharper disable once StringLiteralTypo
            case "POLYLINE":
                ReadPolyLine(out loadError, false, boundary, out polyLineIsClosed);
                break;

            // ReSharper disable once StringLiteralTypo
            case "LWPOLYLINE":
                ReadPolyLine(out loadError, true, boundary, out polyLineIsClosed);
                break;
            }

            return(!loadError && (polyLineIsClosed || !closedPolyLinesOnly));
        }
示例#2
0
        /* Todo: Extrusion not supported
         * private bool CheckExtrusionRecord(DXFRecord rec)
         * {
         * // Returns True if the record is a non default extrusion record
         *
         * return ((rec.recType == 210) && (rec.r != 0.0)) ||
         *       ((rec.recType == 220) && (rec.r != 0.0)) ||
         *       ((rec.recType == 230) && (rec.r != 1.0));
         * }
         */

        /// <summary>
        /// Reads the entirety of a polyline from the DXF file
        /// </summary>
        /// <param name="loadError"></param>
        /// <param name="lwPolyLine"></param>
        /// <param name="entity"></param>
        /// <param name="polyLineIsClosed"></param>
        public void ReadPolyLine(out bool loadError,
                                 bool lwPolyLine,
                                 PolyLineBoundary entity,
                                 out bool polyLineIsClosed)
        {
            const double EPSILON = 0.000001;

            int       FetchIndex;
            int       NumArrayEntries;
            DXFRecord rec;
            XYZ       lastPt = XYZ.Null, pt;
            bool      PaperSpace;
            // Todo: Extrusion is not taken into account
            // bool extruded;
            long PolyLineFlags;
//      double bulge;
            long NVertices;
            long VertexNum;
            long CurveSmoothing;
            // Todo extrusion not supported XYZ Extrusion;
            bool   PolyLineIs3D;
            double DefaultPolyLineHeight;
            var    ExtendedAttrName = "";

            var PolyLineRecords = new List <DXFRecord>();

            // This function allows us to reread the first few record in the poly line.
            bool GetDXFRecord(out DXFRecord record)
            {
                if (FetchIndex < NumArrayEntries)
                {
                    record = PolyLineRecords[FetchIndex];
                    FetchIndex++;
                    return(true);
                }

                return(ReadDXFRecord(out record));
            }

            void LoadSimplePolyLine()
            {
                //  Load all vertices in the poly line
                var FirstPoint = true;

                while ((rec.s == "VERTEX") || (lwPolyLine && (VertexNum < NVertices)))
                {
//          double nextBulge = 0;
                    var VertexFlags = 0;
                    var Rec10Count  = 0;
                    pt.Z = Consts.NullDouble;

                    do
                    {
                        if (!GetDXFRecord(out rec))
                        {
                            return;
                        }

                        switch (rec.recType)
                        {
                        case 10:
                            Rec10Count++;
                            if (Rec10Count == 1)
                            {
                                pt.X = rec.r * DXFImportConvFactor;
                            }
                            break;

                        case 20:
                            pt.Y = rec.r * DXFImportConvFactor;
                            break;

                        case 30:
                            if (PolyLineIs3D)
                            {
                                pt.Z = rec.r * DXFImportConvFactor;
                            }
                            break;

//              case 42:
//                nextBulge = rec.r;
//                break;

//              case 62 : ; //SetPen (pen,rec.i);
//                break;
                        case 70:
                            VertexFlags = (ushort)rec.i;
                            break;
                        }
                    } while (!(rec.recType == 0 || (lwPolyLine && Rec10Count == 2)));

                    // If we are reading in a 2D poly line, then the heights of all the
                    // vertices in the poly line should be set to the elevation read in from
                    // the 38 field in the POLY LINE entity (ie: any elevation read in for
                    // the vertex is discarded. This also applies to LW POLY LINE entities.
                    // Note: This could have been achieved by initializing
                    // the value of pt.z before the repeat loop, but this explicit
                    // behaviour is more evident as to its purpose.
                    if (!PolyLineIs3D)
                    {
                        pt.Z = DefaultPolyLineHeight;
                    }

                    // Todo: Extrusion is not taken into account
                    //if (extruded && !PolyLineIs3D)
                    //  AdjustForExtrusion(pt.x, pt.y, pt.z, Extrusion);

                    if (lwPolyLine)
                    {
                        FetchIndex--; // Reprocess the last record
                        VertexNum++;
                    }

                    if ((VertexFlags & kSplineFrameControlPointFlag) != kSplineFrameControlPointFlag)
                    {
                        bool IsDuplicateVertex;
                        if (FirstPoint)
                        {
                            IsDuplicateVertex = false;
                        }
                        else
                        {
                            IsDuplicateVertex = (Math.Abs(pt.X - lastPt.X) < EPSILON) &&
                                                (Math.Abs(pt.Y - lastPt.Y) < EPSILON) &&
                                                (!PolyLineIs3D || (Math.Abs(pt.Z - lastPt.Z) < EPSILON));
                        }

                        // Determine if the vertex we have just read in is the same as the previous vertex.
                        // If it is, then don't create entities for it
                        if (!IsDuplicateVertex)
                        {
                            // Add the vertex to the fence
                            entity.Boundary.Points.Add(new FencePoint(pt.X, pt.Y));
                        }

//            bulge = nextBulge;

                        if (!IsDuplicateVertex)
                        {
                            FirstPoint = false;
                            lastPt     = pt;
                        }
                    }
                }
            }

            void ProcessNonVertexRecord()
            {
                switch (rec.recType)
                {
                case 8:
                    //load := SetCurrentLayer (rec.s,pen);
                    break;

                // 30 record is height for all vertices in a 2D poly line
                case 30:
                    DefaultPolyLineHeight = rec.r * DXFImportConvFactor;
                    break;

                // 38 record is height for all vertices in a lightweight poly line
                case 38:
                    DefaultPolyLineHeight = rec.r * DXFImportConvFactor;
                    break;

                case 62:
                    //SetPen (pen,rec.i);
                    break;

                case 67:
                    PaperSpace = rec.i != 0;
                    break;

                case 70:
                    PolyLineFlags = rec.i;
                    break;

                case 75:
                    /*Curves and smooth surface type (optional; default = 0); integer codes, not bit-coded:
                     * 0 = No smooth surface fitted
                     * 5 = Quadratic B-spline surface
                     * 6 = Cubic B-spline surface
                     * 8 = Bezier surface */
                    CurveSmoothing = rec.i;
                    break;

                case 90:
                    NVertices = rec.i;
                    break;

                /* Todo: Extrusion not supported
                 * case 210:
                 * Extrusion.X = rec.r;
                 * break;
                 * case 220:
                 * Extrusion.Y = rec.r;
                 * break;
                 * case 230:
                 * Extrusion.Z = rec.r;
                 * break;
                 */

                case 1001:
                    ExtendedAttrName = rec.s.ToUpper(CultureInfo.InvariantCulture); // Registered application name (up to 31 bytes) in extended data
                    break;

                case 1000: // ASCII string in extended attrs (up to 255 bytes)
                case 1070:
                    if (ExtendedAttrName == "TRIMBLEBNDYTYPE")
                    {
                        entity.Type = (DXFLineWorkBoundaryType)rec.i;
                    }
                    else if (ExtendedAttrName == "TRIMBLENAME")
                    {
                        entity.Name = rec.s;
                    }
                    break;
                }
            }

            bool IsPolyLineClosed()
            {
                XYZ pt_start, pt_end;

                var SavedFetchIndex = FetchIndex;

                // Start vertex...
                pt_start.X = PolyLineRecords[FetchIndex].r * DXFImportConvFactor;
                pt_start.Y = PolyLineRecords[FetchIndex + 1].r * DXFImportConvFactor;

                if (PolyLineIs3D)
                {
                    pt_start.Z = PolyLineRecords[FetchIndex + 2].r * DXFImportConvFactor;
                }
                else
                {
                    pt_start.Z = Consts.NullDouble;
                }

                do
                {
                    if (!GetDXFRecord(out rec))
                    {
                        return(false);
                    }
                } while (rec.recType != 0);

                // End vertex...
                if (PolyLineIs3D)
                {
                    pt_end.Z = PolyLineRecords[FetchIndex - 2].r * DXFImportConvFactor;
                    pt_end.Y = PolyLineRecords[FetchIndex - 3].r * DXFImportConvFactor;
                    pt_end.X = PolyLineRecords[FetchIndex - 4].r * DXFImportConvFactor;
                }
                else
                {
                    pt_end.Y = PolyLineRecords[FetchIndex - 2].r * DXFImportConvFactor;
                    pt_end.X = PolyLineRecords[FetchIndex - 3].r * DXFImportConvFactor;
                    pt_end.Z = Consts.NullDouble;
                }

                FetchIndex = SavedFetchIndex;

                return((Math.Abs(pt_start.X - pt_end.X) < EPSILON) &&
                       (Math.Abs(pt_start.Y - pt_end.Y) < EPSILON) &&
                       (!PolyLineIs3D || (Math.Abs(pt_start.Z - pt_end.Z) < EPSILON)));
            }

            loadError  = true;
            PaperSpace = false;
            // Todo extruded = false;
//      bulge = 0;
            NVertices             = 0;
            VertexNum             = 0;
            PolyLineFlags         = 0;
            DefaultPolyLineHeight = Consts.NullDouble;
            CurveSmoothing        = 0;
            // Todo Extrusion = DefaultExtrusion;
            pt = XYZ.Null;
            polyLineIsClosed = false;

            //--------------------------------------------
            // This is a bit grubby, but in my defense we had to handle extrusions for
            // LW POLY LINE entities.  In this case we have to read the entire entity looking
            // for extrusion records before we use the point.
            FetchIndex = 0;

            do
            {
                if (!ReadDXFRecord(out rec))
                {
                    return;
                }

                ProcessNonVertexRecord();

                PolyLineRecords.Add(rec);
                FetchIndex++;
            } while (rec.recType != 0); // Start of next entity

            polyLineIsClosed = (PolyLineFlags & kPolylineIsClosed) == kPolylineIsClosed;
            PolyLineIs3D     = !lwPolyLine &&
                               (((PolyLineFlags & kPolylineIs3D) == kPolylineIs3D) ||
                                ((PolyLineFlags & kPolylineIsPolyfaceMesh) == kPolylineIsPolyfaceMesh));

            // Todo: extruded = CheckExtrusionRecord(Extrusion);

            NumArrayEntries = FetchIndex;

            if (lwPolyLine)
            {
                _reuseRecord = true; // load_entities needs to read this record
            }
            //--------------------------------------------
            // Read poly line header values
            FetchIndex = 0; // Reprocess the records that have already been read.
            do
            {
                if (!GetDXFRecord(out rec))
                {
                    return;
                }

                ProcessNonVertexRecord();
            } while (!((rec.recType == 0) || (lwPolyLine && (rec.recType == 10)))); // Start of first vertex
            //--------------------------------------------

            if (lwPolyLine)
            {
                FetchIndex--; // Reprocess the last record
            }
            // Check whether the poly line is closed if the internal flag indicates it is not...
            polyLineIsClosed = polyLineIsClosed || (lwPolyLine && IsPolyLineClosed());

            if (!PaperSpace)
            {
                if ((PolyLineFlags & kPolylineIsPolyfaceMesh) == kPolylineIsPolyfaceMesh)
                {
                    // We no longer load poly face meshes as background line work...
                }
                else // It's a poly line of some form
                {
                    if (!lwPolyLine &&
                        (CurveSmoothing == kQuadraticBSplineSmoothing) ||
                        (CurveSmoothing == kCubicBSplineSmoothing))
                    {
                        // Spline fit poly lines are not supported here
                    }
                    else
                    {
                        LoadSimplePolyLine();
                    }
                }
            }
            else
            {
                // ReSharper disable once StringLiteralTypo
                //  Scan past SEQ END for standard 3D poly lines
                if (!lwPolyLine)
                {
                    while ((rec.recType != 0) || (rec.s != "SEQEND"))
                    {
                        if (!ReadDXFRecord(out rec))
                        {
                            return;
                        }
                    }
                }
            }

            loadError = false;
        }