예제 #1
0
        //public static bool IsInclude(Curve sourceCurve, Curve targetCurve, Transaction transaction)
        //{
        //    var sourceVertices = CurveUtils.GetDistinctVertices(sourceCurve, transaction).ToList();
        //    var sourceVertices2d = sourceVertices.Select(it => new Point2d(it.X, it.Y)).ToList();
        //    if (sourceVertices2d[0] != sourceVertices2d[sourceVertices2d.Count - 1])
        //        sourceVertices2d.Add(sourceVertices2d[0]);
        //    var sourcePolygon = sourceVertices2d.ToArray();

        //    var targetVertices = CurveUtils.GetDistinctVertices(targetCurve, transaction).ToList();
        //    foreach (var targetVertex in targetVertices)
        //    {
        //        var point2D = new Point2d(targetVertex.X, targetVertex.Y);
        //        if (!ComputerGraphics.IsInPolygon(sourcePolygon, point2D, sourcePolygon.Length - 1))
        //            return false;
        //    }

        //    // There is a case, a polyon's all vertices are on another concave polygon, but the former is not in the latter.
        //    // So we need to use the former's edge middle points to check.
        //    if (targetVertices[0] != targetVertices[targetVertices.Count - 1])
        //        targetVertices.Add(targetVertices[0]);
        //    var middlePoints = GetAllMiddlePoints(targetVertices);
        //    foreach (var middlePoint in middlePoints)
        //    {
        //        var point2D = new Point2d(middlePoint.X, middlePoint.Y);
        //        if (!ComputerGraphics.IsInPolygon(sourcePolygon, point2D, sourcePolygon.Length - 1))
        //            return false;
        //    }

        //    return true;
        //}

        public static bool IsInclude(Curve sourceCurve, Curve targetCurve, Transaction transaction)
        {
            var sourceVertices = CurveUtils.GetDistinctVertices(sourceCurve, transaction);
            var targetVertices = CurveUtils.GetDistinctVertices(targetCurve, transaction);

            return(IsInclude(sourceVertices, targetVertices));
        }
예제 #2
0
        private bool AreDuplicateEntities(CurveCrossingInfo crossInfo)
        {
            if (crossInfo.SourceId == crossInfo.TargetId)
            {
                return(false);
            }

            // Check whether all the intersection points are curve's vertices.
            var sourceVertices = CurveUtils.GetDistinctVertices(crossInfo.SourceId, _transaction);
            var targetVertices = CurveUtils.GetDistinctVertices(crossInfo.TargetId, _transaction);
            var sourceCount    = sourceVertices.Count();
            var targetCount    = targetVertices.Count();

            if (sourceCount != targetCount)
            {
                return(false);
            }

            if (sourceCount != crossInfo.IntersectPoints.Length)
            {
                return(false);
            }

            foreach (var point in crossInfo.IntersectPoints)
            {
                if (!sourceVertices.Contains(point) || !targetVertices.Contains(point))
                {
                    return(false);
                }
            }
            return(true);
        }
예제 #3
0
        private IEnumerable <CurveCrossingInfo> SearchDuplicateEntities2(ObjectId curveId, CurveVertexKdTree <CurveVertex> kdTree,
                                                                         HashSet <KeyValuePair <ObjectId, ObjectId> > visited, Transaction transaction)
        {
            var result = new List <CurveCrossingInfo>();
            var curve  = transaction.GetObject(curveId, OpenMode.ForRead) as Curve;

            if (curve == null)
            {
                return(new List <CurveCrossingInfo>());
            }
            var extents      = curve.GeometricExtents;
            var nearVertices = kdTree.BoxedRange(extents.MinPoint.ToArray(), extents.MaxPoint.ToArray());

            foreach (var nearVertex in nearVertices)
            {
                if (nearVertex.Id == curveId ||
                    visited.Contains(new KeyValuePair <ObjectId, ObjectId>(curveId, nearVertex.Id)) ||
                    visited.Contains(new KeyValuePair <ObjectId, ObjectId>(nearVertex.Id, curveId)))
                {
                    continue;
                }
                var sourceVertices = CurveUtils.GetDistinctVertices(curve, transaction);
                var targetVertices = CurveUtils.GetDistinctVertices(nearVertex.Id, transaction);
                var identical      = PolygonIncludeSearcher.AreIdenticalCoordinates(sourceVertices, targetVertices);
                if (identical)
                {
                    result.Add(new CurveCrossingInfo(curveId, nearVertex.Id, sourceVertices.ToArray()));
                }
                visited.Add(new KeyValuePair <ObjectId, ObjectId>(curveId, nearVertex.Id));
            }
            return(result);
        }
예제 #4
0
        private IEnumerable <Point3d> CheckSharpCorners(ObjectId curveId, Transaction transaction)
        {
            var result           = new List <Point3d>();
            var distinctVertices = CurveUtils.GetDistinctVertices(curveId, transaction);

            // 保证首尾点不相同
            if (distinctVertices[0] == distinctVertices[distinctVertices.Count - 1])
            {
                distinctVertices.RemoveAt(distinctVertices.Count - 1);
            }
            for (int i = 0; i < distinctVertices.Count; i++)
            {
                var current = distinctVertices[i];
                var prev    = distinctVertices[(i - 1 + distinctVertices.Count) % distinctVertices.Count];
                var next    = distinctVertices[(i + 1) % distinctVertices.Count];
                var prevDir = prev - current;
                var nextDir = next - current;
                var angle   = prevDir.GetAngleTo(nextDir);
                if (angle.SmallerOrEqual(Tolerance / 180.0 * Math.PI))
                {
                    result.Add(current);
                }
            }
            return(result);
        }
예제 #5
0
        public override void Check(IEnumerable <ObjectId> selectedObjectIds)
        {
            if (!selectedObjectIds.Any())
            {
                return;
            }

            // 1. Create a kd tree
            var database    = Database;
            var allVertices = new List <CurveVertex>();

            using (var transaction = database.TransactionManager.StartTransaction())
            {
                foreach (var objectId in selectedObjectIds)
                {
                    var curve = transaction.GetObject(objectId, OpenMode.ForRead) as Curve;
                    if (curve == null)
                    {
                        continue;
                    }
                    var vertices = CurveUtils.GetDistinctVertices(curve, transaction);
                    allVertices.AddRange(vertices.Select(it => new CurveVertex(it, objectId)));
                }
                transaction.Commit();
            }
            var kdTree = new CurveVertexKdTree <CurveVertex>(allVertices, it => it.Point.ToArray(), ignoreZ: true);

            // 3. Filter out points that on same curve
            var visited = new HashSet <CurveVertex>();

            using (var tolerance = new SafeToleranceOverride(1E-5, 1E-5))
                foreach (var curveVertex in allVertices)
                {
                    if (visited.Contains(curveVertex))
                    {
                        continue;
                    }

                    var nears     = kdTree.NearestNeighbours(curveVertex.Point.ToArray(), _tolerance);
                    var qualified = new List <CurveVertex>();
                    qualified.Add(curveVertex);
                    foreach (var near in nears)
                    {
                        visited.Add(near);
                        if (near.Point == curveVertex.Point)
                        {
                            continue;
                        }
                        qualified.Add(near);
                    }
                    if (qualified.Count > 1)
                    {
                        _nearVertices.Add(qualified);
                    }
                }
        }
예제 #6
0
        public override void Check(IEnumerable <ObjectId> selectedObjectIds)
        {
            if (!selectedObjectIds.Any())
            {
                return;
            }

            var group = CalculateIntersectionKdTree(selectedObjectIds, true, Editor);

            // Check each intersection whether it's a missing vertex.
            var database = Editor.Document.Database;

            using (var transaction = database.TransactionManager.StartTransaction())
            {
                foreach (var pair in group)
                {
                    var curve = transaction.GetObject(pair.Key, OpenMode.ForRead) as Curve;
                    if (curve == null)
                    {
                        continue;
                    }

                    var vertices         = CurveUtils.GetDistinctVertices(curve, transaction);
                    var noneVertexPoints = new List <Point3d>();
                    foreach (var point in pair.Value)
                    {
                        var ret = CheckPointIsVertex(vertices, point, transaction);
                        if (!ret)
                        {
                            noneVertexPoints.Add(point);
                        }
                    }

                    if (noneVertexPoints.Count > 0)
                    {
                        _missingVertexInfos.Add(new MissingVertexInfo()
                        {
                            PolylineId = pair.Key,
                            Positions  = noneVertexPoints
                        });
                    }
                }
                transaction.Commit();
            }

            //foreach (var info in _missingVertexInfos)
            //{
            //    Editor.WriteMessage("\n{0}:", info.PolylineId.Handle.ToString());
            //    foreach (var point in info.Positions)
            //    {
            //        Editor.WriteMessage(" {0} ", point.ToString());
            //    }
            //    Editor.WriteMessage("\n");
            //}
        }
예제 #7
0
        /// <summary>
        /// Build a linked list for vertices.
        /// </summary>
        /// <param name="curve"></param>
        /// <param name="transaction"></param>
        /// <param name="isLoop">Indicate whether the curve is a loop</param>
        /// <returns></returns>
        public static LinkedPoint GetLinkedPoints(Curve curve, Transaction transaction, bool isLoop)
        {
            var vertices = CurveUtils.GetDistinctVertices(curve, transaction);

            // Make sure the first point is not equal to the last one.
            if (vertices.Count > 1 && vertices[0] == vertices[vertices.Count - 1])
            {
                vertices.RemoveAt(vertices.Count - 1);
            }

            return(GetLinkedPoints(vertices, isLoop));
        }
예제 #8
0
        public static void TestConvexHull()
        {
            var currentDoc = Application.DocumentManager.MdiActiveDocument;
            var editor     = currentDoc.Editor;
            var database   = currentDoc.Database;
            // Only select polyline and polyline 2d.
            ObjectId polylineId = ObjectId.Null;

            while (true)
            {
                var options = new PromptEntityOptions("\n选择一条曲线:");
                var result  = editor.GetEntity(options);
                if (result.Status == PromptStatus.OK)
                {
                    polylineId = result.ObjectId;
                    break;
                }

                if (result.Status == PromptStatus.Cancel)
                {
                    break;
                }

                editor.WriteMessage("\n选择无效");
            }

            if (polylineId.IsNull)
            {
                return;
            }

            using (var transaction = database.TransactionManager.StartTransaction())
            {
                IEnumerable <Point3d> points = CurveUtils.GetDistinctVertices(polylineId, transaction);
                var convex = new ConvexHull <Point3d>(points, it => it.X, it => it.Y,
                                                      (x, y) => new Point3d(x, y, 0), (a, b) => a == b);
                convex.CalcConvexHull();

                var hullPoints = convex.GetResultsAsArrayOfPoint();
                var polyline   = new Autodesk.AutoCAD.DatabaseServices.Polyline();
                for (int i = 0; i < hullPoints.Length; i++)
                {
                    polyline.AddVertexAt(i, new Point2d(hullPoints[i].X, hullPoints[i].Y), 0, 1, 1);
                }
                polyline.ColorIndex = 2;

                var modelspaceId = SymbolUtilityServices.GetBlockModelSpaceId(database);
                var modelspace   = transaction.GetObject(modelspaceId, OpenMode.ForWrite) as BlockTableRecord;
                modelspace.AppendEntity(polyline);
                transaction.AddNewlyCreatedDBObject(polyline, true);
                transaction.Commit();
            }
        }
예제 #9
0
        public override void Check(IEnumerable <ObjectId> selectedObjectIds)
        {
            if (!selectedObjectIds.Any())
            {
                return;
            }

            var database = Editor.Document.Database;
            var group    = CalculateIntersection(selectedObjectIds, true, database);

            // Check each intersection whether it's a missing vertex.
            // TODO: 用一个比较低的精度去比较一个交点是否是顶点
            using (var tolerance = new SafeToleranceOverride(_tolerance, _tolerance))
                using (var transaction = database.TransactionManager.StartTransaction())
                {
                    foreach (var pair in group)
                    {
                        var curve = transaction.GetObject(pair.Key, OpenMode.ForRead) as Curve;
                        if (curve == null)
                        {
                            continue;
                        }

                        var vertices         = CurveUtils.GetDistinctVertices(curve, transaction);
                        var noneVertexPoints = new List <Point3d>();
                        foreach (var point in pair.Value)
                        {
                            var ret = CheckPointIsVertex(vertices, point, transaction);
                            if (!ret)
                            {
                                noneVertexPoints.Add(point);
                            }
                        }

                        if (noneVertexPoints.Count > 0)
                        {
                            _missingVertexInfos.Add(new MissingVertexInfo()
                            {
                                PolylineId = pair.Key,
                                Positions  = noneVertexPoints
                            });
                        }
                    }
                    transaction.Commit();
                }
        }
예제 #10
0
        CurveVertexKdTree <CurveVertex> CreatePolygonKdTree(IEnumerable <ObjectId> objectIds, Transaction transaction)
        {
            var vertices = new List <CurveVertex>();

            foreach (var objectId in objectIds)
            {
                var points = CurveUtils.GetDistinctVertices(objectId, transaction);
                if (points[0] == points[points.Count - 1])
                {
                    points.RemoveAt(points.Count - 1);
                }
                vertices.AddRange(points.Select(it => new CurveVertex(it, objectId)));
            }

            var kdTree = new CurveVertexKdTree <CurveVertex>(vertices, it => it.Point.ToArray(), ignoreZ: true);

            return(kdTree);
        }
예제 #11
0
        private CurveVertexKdTree <CurveVertex> BuildCurveVertexKdTree2(IEnumerable <ObjectId> allIds, Transaction transaction)
        {
            var allVertices = new List <CurveVertex>();

            foreach (var id in allIds)
            {
                var points = CurveUtils.GetDistinctVertices(id, transaction);
                if (!points.Any())
                {
                    continue;
                }

                var vertices = points.Select(it => new CurveVertex(it, id));

                allVertices.AddRange(vertices);
            }

            var kdTree = new CurveVertexKdTree <CurveVertex>(allVertices, it => it.Point.ToArray(), ignoreZ: true);

            return(kdTree);
        }
예제 #12
0
        private void BuildCurveVertexKdTree(IEnumerable <ObjectId> allIds, Transaction transaction,
                                            out Dictionary <ObjectId, CurveVertex[]> curveVertices, out CurveVertexKdTree <CurveVertex> kdTree)
        {
            curveVertices = new Dictionary <ObjectId, CurveVertex[]>();
            var allVertices = new List <CurveVertex>();

            foreach (var id in allIds)
            {
                var points = CurveUtils.GetDistinctVertices(id, transaction);
                if (!points.Any())
                {
                    continue;
                }

                var vertices = points.Select(it => new CurveVertex(it, id));
                curveVertices[id] = vertices.ToArray();

                allVertices.AddRange(vertices);
            }

            kdTree = new CurveVertexKdTree <CurveVertex>(allVertices, it => it.Point.ToArray(), ignoreZ: true);
        }
예제 #13
0
        public override void Check(IEnumerable <ObjectId> selectedObjectIds)
        {
            if (!selectedObjectIds.Any())
            {
                return;
            }

            var allVertices = new List <CurveVertex>();
            var curveIds    = new List <ObjectId>();

            using (var transaction = this.Database.TransactionManager.StartTransaction())
            {
                foreach (var objId in selectedObjectIds)
                {
                    var curve = transaction.GetObject(objId, OpenMode.ForRead) as Curve;
                    if (curve == null)
                    {
                        continue;
                    }
                    if (!IsCurveClosed(curve))
                    {
                        continue;
                    }

                    curveIds.Add(objId);
                    var vertices = CurveUtils.GetDistinctVertices(curve, transaction);
                    allVertices.AddRange(vertices.Select(it => new CurveVertex(it, objId)));
                }
                transaction.Commit();
            }
            var kdTree = new CurveVertexKdTree <CurveVertex>(allVertices, it => it.Point.ToArray(), ignoreZ: true);

            // Use kd tree to check include.
            var analyzed = new HashSet <KeyValuePair <ObjectId, ObjectId> >();

            using (var transaction = this.Database.TransactionManager.StartTransaction())
            {
                foreach (var objectId in curveIds)
                {
                    var curve        = transaction.GetObject(objectId, OpenMode.ForRead) as Curve;
                    var extents      = curve.GeometricExtents;
                    var nearVertices = kdTree.BoxedRange(extents.MinPoint.ToArray(), extents.MaxPoint.ToArray());

                    foreach (var curveVertex in nearVertices)
                    {
                        if (curveVertex.Id == objectId ||
                            analyzed.Contains(new KeyValuePair <ObjectId, ObjectId>(objectId, curveVertex.Id)))
                        {
                            continue;
                        }

                        analyzed.Add(new KeyValuePair <ObjectId, ObjectId>(objectId, curveVertex.Id));
                        var targetCurve = transaction.GetObject(curveVertex.Id, OpenMode.ForRead) as Curve;
                        if (IsInclude(curve, targetCurve, transaction))
                        {
                            _includePolygons.Add(new KeyValuePair <ObjectId, ObjectId>(objectId, curveVertex.Id));
                        }
                    }
                }
                transaction.Commit();
            }
        }
예제 #14
0
        /// <summary>
        /// 检查和sourceIds相交的objectIds
        /// </summary>
        /// <param name="objectIds"></param>
        /// <param name="sourceIds"></param>
        public void Check(IEnumerable <ObjectId> objectIds, IEnumerable <ObjectId> sourceIds)
        {
            if (!objectIds.Any() || !sourceIds.Any())
            {
                return;
            }

            var database = Editor.Document.Database;
            // Build a kd tree for searching intersection
            var allVertices     = new List <CurveVertex>();
            var closedSourceIds = new List <ObjectId>();

            using (var transaction = database.TransactionManager.StartTransaction())
            {
                foreach (var objectId in objectIds)
                {
                    var curve = transaction.GetObject(objectId, OpenMode.ForRead) as Curve;
                    if (curve == null)
                    {
                        continue;
                    }
                    if (!IsCurveClosed(curve))
                    {
                        continue;
                    }

                    var vertices = CurveUtils.GetDistinctVertices(curve, transaction);
                    allVertices.AddRange(vertices.Select(it => new CurveVertex(it, objectId)));
                    curve.Dispose();
                }

                foreach (var sourceId in sourceIds)
                {
                    var curve = transaction.GetObject(sourceId, OpenMode.ForRead) as Curve;
                    if (curve == null)
                    {
                        continue;
                    }
                    if (!IsCurveClosed(curve))
                    {
                        continue;
                    }

                    closedSourceIds.Add(sourceId);
                    curve.Dispose();
                }
                transaction.Commit();
            }

            // Create a kdTree
            var kdTree = new CurveVertexKdTree <CurveVertex>(allVertices, it => it.Point.ToArray(), ignoreZ: true);

            // Use kd tree to check intersect.
            var intersects = new List <PolygonIntersect>();
            var analyzed   = new HashSet <KeyValuePair <ObjectId, ObjectId> >();

            using (var transaction = database.TransactionManager.StartTransaction())
            {
                foreach (var objectId in closedSourceIds)
                {
                    var curve        = transaction.GetObject(objectId, OpenMode.ForRead) as Curve;
                    var extents      = curve.GeometricExtents;
                    var nearVertices = kdTree.BoxedRange(extents.MinPoint.ToArray(), extents.MaxPoint.ToArray());

                    foreach (var curveVertex in nearVertices)
                    {
                        if (curveVertex.Id == objectId ||
                            analyzed.Contains(new KeyValuePair <ObjectId, ObjectId>(objectId, curveVertex.Id)))
                        {
                            continue;
                        }

                        analyzed.Add(new KeyValuePair <ObjectId, ObjectId>(objectId, curveVertex.Id));
                        var polygonIntersect = AnalyzePolygonIntersection(objectId, curveVertex.Id, transaction);
                        if (polygonIntersect != null)
                        {
                            var sourceId = polygonIntersect.Value.SourceId;
                            var targetId = polygonIntersect.Value.TargetId;
                            var existing = intersects.FirstOrDefault(it => it.SourceId == sourceId && it.TargetId == targetId ||
                                                                     it.SourceId == targetId && it.TargetId == sourceId);
                            if (existing.Equals(default(PolygonIntersect)))
                            {
                                intersects.Add(polygonIntersect.Value);
                            }
                        }
                    }
                }
                transaction.Commit();
            }
            _intersects = intersects;
        }
예제 #15
0
        public static Dictionary <ObjectId, List <Point3d> > GetCrotchPoints(Database database,
                                                                             IEnumerable <ObjectId> parcelIds)
        {
            var result = new Dictionary <ObjectId, List <Point3d> >();
            // Create a kd tree.
            var allVertices = new List <CurveVertex>();

            using (var transaction = database.TransactionManager.StartTransaction())
            {
                foreach (var objId in parcelIds)
                {
                    var curve = transaction.GetObject(objId, OpenMode.ForRead) as Curve;
                    if (curve == null)
                    {
                        continue;
                    }
                    var vertices = CurveUtils.GetDistinctVertices(curve, transaction);
                    allVertices.AddRange(vertices.Select(it => new CurveVertex(it, objId)));
                }
                transaction.Commit();
            }
            var kdTree = new CurveVertexKdTree <CurveVertex>(allVertices, it => it.Point.ToArray(), ignoreZ: true);

            // 搜索三岔口
            //using (var tolerance = new ToleranceOverrule(null))
            using (var transaction = database.TransactionManager.StartTransaction())
            {
                foreach (var parcelId in parcelIds)
                {
                    var curve = transaction.GetObject(parcelId, OpenMode.ForRead) as Curve;
                    if (curve == null)
                    {
                        continue;
                    }

                    var ptLink     = LinkedPoint.GetLinkedPoints(curve, transaction, isLoop: true);
                    var ptTraverse = ptLink;
                    // Use records to improve performance.
                    var records = new Dictionary <LinkedPoint, IEnumerable <CurveVertex> >();
                    while (ptTraverse != null)
                    {
                        var prev = ptTraverse.Prev;
                        var next = ptTraverse.Next;
                        if (!records.ContainsKey(prev))
                        {
                            records[prev] = kdTree.NearestNeighbours(prev.Point.ToArray(), radius: 0.001);
                        }
                        if (!records.ContainsKey(ptTraverse))
                        {
                            records[ptTraverse] = kdTree.NearestNeighbours(ptTraverse.Point.ToArray(), radius: 0.001);
                        }
                        if (!records.ContainsKey(next))
                        {
                            records[next] = kdTree.NearestNeighbours(next.Point.ToArray(), radius: 0.001);
                        }

                        foreach (var vertex in records[ptTraverse])
                        {
                            if (result.ContainsKey(parcelId) && result[parcelId].Contains(vertex.Point))
                            {
                                continue;
                            }

                            if (vertex.Id == parcelId || vertex.Point != ptTraverse.Point)
                            {
                                continue;
                            }
                            var prevVertex = new CurveVertex(prev.Point, vertex.Id);
                            var nextVertex = new CurveVertex(next.Point, vertex.Id);
                            if (records[prev].Contains(prevVertex) && records[next].Contains(nextVertex))
                            {
                                continue;
                            }

                            List <Point3d> list = null;
                            if (result.ContainsKey(parcelId))
                            {
                                list = result[parcelId];
                            }
                            else
                            {
                                list             = new List <Point3d>();
                                result[parcelId] = list;
                            }
                            list.Add(ptTraverse.Point);
                        }

                        ptTraverse = ptTraverse.Next;
                        if (ptTraverse == ptLink)
                        {
                            break;
                        }
                    }
                }
                transaction.Commit();
            }

            return(result);
        }
예제 #16
0
        public override void Check(IEnumerable <ObjectId> selectedObjectIds)
        {
            if (selectedObjectIds == null || !selectedObjectIds.Any())
            {
                return;
            }

            var regions = new List <IsolatedRegion>();

            using (var transaction = Database.TransactionManager.StartTransaction())
            {
                // Create a kdtree, for near searching
                var kdTree  = CreatePolygonKdTree(selectedObjectIds, transaction);
                var visited = new HashSet <ObjectId>();

                foreach (var objectId in selectedObjectIds)
                {
                    if (visited.Contains(objectId))
                    {
                        continue;
                    }

                    // 防止二次访问,造成无限循环
                    visited.Add(objectId);

                    var contour  = CurveUtils.GetDistinctVertices(objectId, transaction);
                    var idsGroup = new List <ObjectId>()
                    {
                        objectId
                    };
                    var unionableIds = new List <ObjectId>()
                    {
                        objectId
                    };
                    while (unionableIds.Count > 0)
                    {
                        var newUnionableIds = new List <ObjectId>();
                        foreach (var unionableId in unionableIds)
                        {
                            // Get near polygon Ids
                            var nearIds = GetNearPolygonIds(kdTree, unionableId, visited, transaction);
                            foreach (var nearId in nearIds)
                            {
                                var            nearPoints   = CurveUtils.GetDistinctVertices(nearId, transaction);
                                List <Point3d> unionPolygon = null;
                                var            unionable    = AnalyzePolygonsUnionable(contour, nearPoints, out unionPolygon);
                                if (unionable)
                                {
                                    newUnionableIds.Add(nearId);
                                    visited.Add(nearId);
                                    idsGroup.Add(nearId);
                                    contour = unionPolygon;
                                }
                            }
                        }

                        unionableIds = newUnionableIds;
                    }

                    regions.Add(new IsolatedRegion()
                    {
                        Contour  = contour,
                        CurveIds = idsGroup
                    });
                }
                transaction.Commit();
            }

            _isolatedRegions = regions;
        }
예제 #17
0
        private PolygonIntersect?AnalyzePolygonIntersection(ObjectId sourceId, ObjectId targetId, Transaction transaction)
        {
            var sourceCurve = transaction.GetObject(sourceId, OpenMode.ForRead) as Curve;
            var targetCurve = transaction.GetObject(targetId, OpenMode.ForRead) as Curve;

            if (!IsCurveClosed(sourceCurve) || !IsCurveClosed(targetCurve))
            {
                return(null);
            }

            // Use clipper to calculate the intersection
            var precision = 0.000001;
            var subject   = new List <List <IntPoint> >(1);
            var clipper   = new List <List <IntPoint> >(1);
            var result    = new List <List <IntPoint> >();

            var sourceVertices = CurveUtils.GetDistinctVertices(sourceCurve, transaction);
            var targetVertices = CurveUtils.GetDistinctVertices(targetCurve, transaction);

            var subjectPath = sourceVertices.Select(it => new IntPoint(it.X / precision, it.Y / precision)).ToList();
            var clipperPath = targetVertices.Select(it => new IntPoint(it.X / precision, it.Y / precision)).ToList();

            subject.Add(subjectPath);
            clipper.Add(clipperPath);
            var cpr = new Clipper();

            cpr.AddPaths(subject, PolyType.ptSubject, true);
            cpr.AddPaths(clipper, PolyType.ptClip, true);
            cpr.Execute(ClipType.ctIntersection, result, PolyFillType.pftNonZero, PolyFillType.pftNonZero);
            if (result.Count <= 0)
            {
                //Editor.WriteMessage("有相交,但Clipper没有计算出相交部分");
                return(null);
            }

            var intersectPaths = new List <Polyline>();

            foreach (var path in result)
            {
                var points   = path.Select(it => new Point3d(it.X * precision, it.Y * precision, 0.0)).ToArray();
                var polyline = CreatePolygon(points);
                // If the polygon's area is very small, just ignore, or it will bother user.
                var intersectArea = polyline.Area;
                if (intersectArea.Smaller(0.001))
                {
                    polyline.Dispose();
                    continue;
                }
                else if (TargetAreaRatio != null)
                {
                    var targetArea = targetCurve.Area;
                    if ((intersectArea / targetArea).Smaller(TargetAreaRatio.Value))
                    {
                        polyline.Dispose();
                        continue;
                    }
                }
                intersectPaths.Add(polyline);
            }

            if (intersectPaths.Count <= 0)
            {
                return(null);
            }

            // 将包含的情况排除
            if (intersectPaths.Count == 1)
            {
                var intersectPoints = CurveUtils.GetDistinctVertices(intersectPaths[0], null);
                var qualified       = IsIntersectQualified(sourceId, sourceVertices, targetId, targetVertices, intersectPoints, transaction);
                if (!qualified)
                {
                    intersectPaths[0].Dispose();
                    intersectPaths.Clear();
                    return(null);
                }
            }

            return(new PolygonIntersect()
            {
                SourceId = sourceId,
                TargetId = targetId,
                Intersections = intersectPaths
            });
        }