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); }
private IEnumerable <CurveCrossingInfo> FilterCrossInfos(IEnumerable <CurveCrossingInfo> crossInfos, out IEnumerable <CurveCrossingInfo> duplicateEntities) { duplicateEntities = new List <CurveCrossingInfo>(); var result = new List <CurveCrossingInfo>(); foreach (var curveCrossingInfo in crossInfos) { // Filter out duplicate entities if (AreDuplicateEntities(curveCrossingInfo)) { ((List <CurveCrossingInfo>)duplicateEntities).Add(curveCrossingInfo); continue; } var sourcePoints = CurveUtils.GetCurveEndPoints(curveCrossingInfo.SourceId, _transaction); var targetPoints = new Point3d[0]; if (curveCrossingInfo.TargetId != curveCrossingInfo.SourceId) { targetPoints = CurveUtils.GetCurveEndPoints(curveCrossingInfo.TargetId, _transaction); } sourcePoints = DistinctEndPoints(sourcePoints); targetPoints = DistinctEndPoints(targetPoints); var points = new List <Point3d>(); foreach (var point3D in curveCrossingInfo.IntersectPoints) { // Whether point3D is end point of each cuve //// If sourcePoints.Length is 1 or 0, means it's a loop, loop need to be splitted. //if (sourcePoints.Length >= 2 && sourcePoints.Contains(point3D) && // targetPoints.Length >= 2 && targetPoints.Contains(point3D)) // continue; // If curveCrossingInfo.SourceId == curveCrossingInfo.TargetId, it's a self intersection. if (sourcePoints.Contains(point3D) && targetPoints.Contains(point3D) && curveCrossingInfo.SourceId != curveCrossingInfo.TargetId) { continue; } points.Add(point3D); } if (points.Count > 0) { var newCrossingInfo = new CurveCrossingInfo(curveCrossingInfo.SourceId, curveCrossingInfo.TargetId, points.ToArray()); result.Add(newCrossingInfo); } } return(result); }
private IEnumerable <CurveCrossingInfo> GetCrossingInfosFromIntersections(List <IntersectionInfo> infos) { var result = new List <CurveCrossingInfo>(); var dictionary = new Dictionary <KeyValuePair <ObjectId, ObjectId>, List <Point3d> >(); foreach (var info in infos) { var pair1 = new KeyValuePair <ObjectId, ObjectId>(info.SourceId, info.TargetId); var pair2 = new KeyValuePair <ObjectId, ObjectId>(info.TargetId, info.SourceId); if (dictionary.ContainsKey(pair1)) { var val = dictionary[pair1]; if (!val.Contains(info.IntersectPoint)) { val.Add(info.IntersectPoint); } } else if (dictionary.ContainsKey(pair2)) { var val = dictionary[pair2]; if (!val.Contains(info.IntersectPoint)) { val.Add(info.IntersectPoint); } } else { var list = new List <Point3d>(); list.Add(info.IntersectPoint); dictionary[pair1] = list; } } foreach (var pair in dictionary) { var crossingInfo = new CurveCrossingInfo(pair.Key.Key, pair.Key.Value, pair.Value.ToArray()); result.Add(crossingInfo); } return(result); //var watch = Stopwatch.StartNew(); //var sourceIdGroups = infos.GroupBy(it => it.SourceId); //HashSet<KeyValuePair<ObjectId, ObjectId>> visited = new HashSet<KeyValuePair<ObjectId, ObjectId>>(); //foreach (var sourceIdGroup in sourceIdGroups) //{ // var subSourceIdGroups = sourceIdGroup.GroupBy(it => it.TargetId); // foreach (var subSourceIdGroup in subSourceIdGroups) // { // if (visited.Contains(new KeyValuePair<ObjectId, ObjectId>(subSourceIdGroup.Key, sourceIdGroup.Key))) // continue; // var points = new List<Point3d>(); // foreach (var intersection in subSourceIdGroup) // { // if (points.Contains(intersection.IntersectPoint)) // continue; // points.Add(intersection.IntersectPoint); // } // // Search the target group by TargetId. // var targetGroup = sourceIdGroups.FirstOrDefault(it => it.Key == subSourceIdGroup.Key); // if (targetGroup != null) // { // // Continue group by SourceId (the TargetId in targetIdGroups) // var subTargetGroups = targetGroup.GroupBy(it => it.TargetId); // var subTargetGroup = subTargetGroups.FirstOrDefault(it => it.Key == sourceIdGroup.Key); // if (subTargetGroup != null) // { // foreach (var intersection in subTargetGroup) // { // if (points.Contains(intersection.IntersectPoint)) // continue; // points.Add(intersection.IntersectPoint); // } // } // } // if (points.Count > 0) // { // var crossingInfo = new CurveCrossingInfo(sourceIdGroup.Key, subSourceIdGroup.Key, points.ToArray()); // result.Add(crossingInfo); // } // visited.Add(new KeyValuePair<ObjectId, ObjectId>(sourceIdGroup.Key, subSourceIdGroup.Key)); // } //} //return result; }
private IEnumerable <CurveCrossingInfo> SearchDuplicateInfo(KeyValuePair <ObjectId, CurveVertex[]> curveInfo, CurveVertexKdTree <CurveVertex> kdTree, Dictionary <ObjectId, CurveVertex[]> curveInfos, List <Tuple <ObjectId, ObjectId> > visited) { List <CurveCrossingInfo> crossingInfos = new List <CurveCrossingInfo>(); HashSet <ObjectId> candidates = null; Dictionary <ObjectId, List <Point3d> > candidatePoints = new Dictionary <ObjectId, List <Point3d> >(); foreach (var vertex in curveInfo.Value) { var neighbours = kdTree.NearestNeighbours(vertex.Point.ToArray(), _tolerance); neighbours = neighbours.Except(new CurveVertex[] { vertex }); // If there is no neighbour vertex, just return. if (!neighbours.Any()) { if (candidates != null) { candidates = null; } break; } if (candidates == null) { candidates = new HashSet <ObjectId>(neighbours.Select(it => it.Id)); foreach (var id in candidates) { var points = neighbours.Where(it => it.Id == id) .Select(it => it.Point); candidatePoints[id] = new List <Point3d>(points); } } else { candidates.IntersectWith(neighbours.Select(it => it.Id)); if (candidates.Count <= 0) { break; } foreach (var id in candidates) { var points = candidatePoints[id]; var newPoints = neighbours .Where(it => it.Id == id) .Select(it => it.Point); foreach (var newPoint in newPoints) { if (!points.Contains(newPoint)) { points.Add(newPoint); } } } } } if (candidates != null && candidates.Count > 0) { foreach (var candidate in candidates) { // If self, just continue. if (candidate == curveInfo.Key) { continue; } var existing = visited.FirstOrDefault(it => (it.Item1 == curveInfo.Key && it.Item2 == candidate) || (it.Item1 == candidate && it.Item2 == curveInfo.Key)); if (existing != null) { continue; } visited.Add(new Tuple <ObjectId, ObjectId>(curveInfo.Key, candidate)); // Check whether they have same number of vertices. if (curveInfos[candidate].Length != candidatePoints[candidate].Count) { continue; } var points = curveInfo.Value.Select(it => it.Point).ToArray(); var crossingInfo = new CurveCrossingInfo(curveInfo.Key, candidate, points); crossingInfos.Add(crossingInfo); } } return(crossingInfos); }