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); }
public static IEnumerable <KeyValuePair <CurveSegment, CurveSegment> > SearchNearSegments(IEnumerable <ObjectId> selectedObjectIds, double tolerance) { var segments = GetAllCurveSegments(selectedObjectIds, tolerance, onlyForClosedPolygon: true); var vertices = new List <CollisionVertex>(); foreach (var segment in segments) { var collisionVertices = segment.MiniBoundingBox.Select(it => new CollisionVertex() { Point = new Point3d(it.X, it.Y, 0.0), Segment = segment }); vertices.AddRange(collisionVertices); } // Create kd tree var kdTree = new CurveVertexKdTree <CollisionVertex>(vertices, it => it.Point.ToArray(), ignoreZ: true); // Use kd tree to check collision bounding box's intersection var segmentPairs = new HashSet <KeyValuePair <CurveSegment, CurveSegment> >(); foreach (var segment in segments) { var extents = segment.GetExtents(); if (extents == null) { continue; } var minPoint = extents.Value.MinPoint; var maxPoint = extents.Value.MaxPoint; var nearVertices = kdTree.BoxedRange(new double[] { minPoint.X, minPoint.Y, 0.0 }, new double[] { maxPoint.X, maxPoint.Y, 0.0 }); foreach (var collisionVertex in nearVertices) { if (collisionVertex.Segment.EntityId == segment.EntityId || segmentPairs.Contains(new KeyValuePair <CurveSegment, CurveSegment>(segment, collisionVertex.Segment)) || segmentPairs.Contains(new KeyValuePair <CurveSegment, CurveSegment>(collisionVertex.Segment, segment))) { continue; } var boundingBox = segment.MiniBoundingBox.ToList(); boundingBox.Add(segment.MiniBoundingBox[0]); if (!ComputerGraphics.IsInPolygon(boundingBox.ToArray(), new Point2d(collisionVertex.Point.X, collisionVertex.Point.Y), 4)) { continue; } segmentPairs.Add(new KeyValuePair <CurveSegment, CurveSegment>(segment, collisionVertex.Segment)); } } return(segmentPairs); }
IEnumerable <ObjectId> GetNearPolygonIds(CurveVertexKdTree <CurveVertex> kdTree, ObjectId polygonId, HashSet <ObjectId> visitedIds, Transaction transaction) { var result = new HashSet <ObjectId>(); var curve = (Curve)transaction.GetObject(polygonId, OpenMode.ForRead); var extents = curve.GeometricExtents; var dir = (extents.MaxPoint - extents.MinPoint).GetNormal(); // 向外扩张0.1 var minPoint = extents.MinPoint - dir * 0.1; var maxPoint = extents.MaxPoint + dir * 0.1; var nearVertices = kdTree.BoxedRange(minPoint.ToArray(), maxPoint.ToArray()); foreach (var curveVertex in nearVertices) { // 不要包含本身 if (curveVertex.Id == polygonId || visitedIds.Contains(curveVertex.Id)) { continue; } result.Add(curveVertex.Id); } return(result); }
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(); } }
private IEnumerable <IntersectionInfo> GetUnderShootIntersections2(IEnumerable <ObjectId> selectedObjectIds, IEnumerable <CurveVertex> danglingVertices, double tolerance, Transaction transaction) { if (danglingVertices == null || !danglingVertices.Any()) { return(new List <IntersectionInfo>()); } var intersectMap = new Dictionary <CurveVertex, List <CurveVertex> >(); var desireExtendTypes = new Dictionary <CurveVertex, ExtendType>(); foreach (var vertex in danglingVertices) { var curve = transaction.GetObject(vertex.Id, OpenMode.ForRead); var desiredExtend = CurveUtils.GetExtendType((Curve)curve, vertex.Point); desireExtendTypes[vertex] = desiredExtend; } // 创建一个kdtree var kdTree = new CurveVertexKdTree <CurveVertex>(danglingVertices, it => it.Point.ToArray(), ignoreZ: true); foreach (var objectId in selectedObjectIds) { var curve = transaction.GetObject(objectId, OpenMode.ForRead) as Curve; if (curve == null) { continue; } // 预检 var curveExtents = curve.GeometricExtents; var vertices = kdTree.BoxedRange(curveExtents.MinPoint.ToArray(), curveExtents.MaxPoint.ToArray()); if (vertices == null || !vertices.Any()) { continue; } var segments = CurveUtils.GetSegment2dsOfCurve(curve, transaction); var segmentsForCollision = segments.Select(it => new CurveSegmentForCollision() { LineSegment = it, EntityId = objectId, MiniBoundingBox = CurveSegmentForCollision.CreateCollisionBoundingBox(it, tolerance) }); foreach (var curveSegmentForCollision in segmentsForCollision) { var extents = curveSegmentForCollision.GetExtents(); if (extents == null) { continue; } var minPoint = extents.Value.MinPoint; var maxPoint = extents.Value.MaxPoint; var nearVertices = kdTree.BoxedRange(new double[] { minPoint.X, minPoint.Y, 0.0 }, new double[] { maxPoint.X, maxPoint.Y, 0.0 }); if (!nearVertices.Any()) { continue; } var boundingBox = curveSegmentForCollision.MiniBoundingBox.ToList(); boundingBox.Add(curveSegmentForCollision.MiniBoundingBox[0]); foreach (var curveVertex in nearVertices) { if (!ComputerGraphics.IsInPolygon(boundingBox.ToArray(), new Point2d(curveVertex.Point.X, curveVertex.Point.Y), 4)) { continue; } var danglingCurve = (Curve)transaction.GetObject(curveVertex.Id, OpenMode.ForRead); var danglingSegment = GetExtendLineSegment(danglingCurve, curveVertex.Point, transaction); var danglineLine = new Line2d(danglingSegment.StartPoint, danglingSegment.EndPoint); var intersectPoints = danglineLine.IntersectWith(curveSegmentForCollision.LineSegment); if (intersectPoints == null || intersectPoints.Length <= 0) { continue; } var intersectPoint2D = intersectPoints[0]; var param = danglingSegment.GetParameterOf(intersectPoint2D); var extendType = CurveIntersectUtils.ParamToExtendTypeForLine(param); if (extendType != desireExtendTypes[curveVertex]) { continue; } var intersectPoint = new Point3d(intersectPoint2D.X, intersectPoint2D.Y, 0); var dist = (intersectPoint - curveVertex.Point).Length; if (dist.Larger(tolerance)) { continue; } List <CurveVertex> intersectList; intersectMap.TryGetValue(curveVertex, out intersectList); if (intersectList == null) { intersectList = new List <CurveVertex>(); intersectMap[curveVertex] = intersectList; } intersectList.Add(new CurveVertex(intersectPoint, curveSegmentForCollision.EntityId)); } } } // 分析交点 var result = new List <IntersectionInfo>(); foreach (var pair in intersectMap) { var vertex = pair.Key; var extendVertices = pair.Value; var nearest = extendVertices[0]; var nearsetDist = (nearest.Point - vertex.Point).Length; for (int i = 1; i < extendVertices.Count; i++) { var dist = (extendVertices[i].Point - vertex.Point).Length; if (dist < nearsetDist) { nearsetDist = dist; nearest = extendVertices[i]; } } result.Add(new IntersectionInfo(vertex.Id, desireExtendTypes[vertex], nearest.Id, ExtendType.None, nearest.Point)); } return(result); }
/// <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; }