Beispiel #1
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);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
        }