Ejemplo n.º 1
0
        /// <summary>
        /// Search real intersections of bsp node
        /// </summary>
        /// <param name="node"></param>
        private void SearchRealIntersectionsOfNode(CurveBspNode node, List <IntersectionInfo> intersections, HashSet <CurveVertex> vertexIntersects, bool includeInline)
        {
            var segments = node.Segments;

            foreach (var bspSegment in segments)
            {
                if (bspSegment.StartSplitInfos != null)
                {
                    foreach (var splitInfo in bspSegment.StartSplitInfos)
                    {
                        var intersection = CreateRealIntersectionInfo(splitInfo,
                                                                      bspSegment.LineSegment.StartPoint, bspSegment.EntityId, vertexIntersects);

                        if (intersection != null)
                        {
                            intersections.Add(intersection);
                        }
                    }
                }
                if (bspSegment.EndSplitInfos != null)
                {
                    foreach (var splitInfo in bspSegment.EndSplitInfos)
                    {
                        var intersection = CreateRealIntersectionInfo(splitInfo,
                                                                      bspSegment.LineSegment.EndPoint, bspSegment.EntityId, vertexIntersects);

                        if (intersection != null)
                        {
                            intersections.Add(intersection);
                        }
                    }
                }
            }

            // Inline segments's comparasion
            if (segments.Length > 1 && includeInline)
            {
                var inlineIntersections = InlineSegmentsIntersections(segments);
                intersections.AddRange(inlineIntersections);
            }

            if (node.LeftChild != null)
            {
                SearchRealIntersectionsOfNode(node.LeftChild, intersections, vertexIntersects, includeInline);
            }

            if (node.RightChild != null)
            {
                SearchRealIntersectionsOfNode(node.RightChild, intersections, vertexIntersects, includeInline);
            }
        }
Ejemplo n.º 2
0
        public Curve2dBspTree(IEnumerable <BspSegment> segments)
        {
            if (segments == null)
            {
                throw new ArgumentNullException("segments");
            }
            int numProc = System.Environment.ProcessorCount;

            this._parallelDepth = -1;
            while (numProc >> ++this._parallelDepth > 1)
            {
                ;
            }
            this.Root = Create(segments, 0, null, false);
        }
Ejemplo n.º 3
0
        void SearchNearSegmentsSegmentsOfNode(CurveBspNode node, HashSet <KeyValuePair <BspSegment, BspSegment> > result)
        {
            var segments = node.Segments;

            foreach (var bspSegment in segments)
            {
                var originalestTarget = GetOriginalSourceBspSegment(bspSegment);
                if (bspSegment.StartSplitInfos != null)
                {
                    foreach (var splitInfo in bspSegment.StartSplitInfos)
                    {
                        // Self intersect is ignored.
                        if (splitInfo.SourceSegment.EntityId == bspSegment.EntityId)
                        {
                            continue;
                        }

                        // If not real intersection.
                        var extendType = CurveIntersectUtils.ParamToExtendTypeForLine(splitInfo.SourceParam);
                        if (extendType != ExtendType.None)
                        {
                            continue;
                        }

                        var originalestSource = GetOriginalSourceBspSegment(splitInfo.SourceSegment);
                        if (result.Contains(new KeyValuePair <BspSegment, BspSegment>(originalestSource, originalestTarget)) ||
                            result.Contains(new KeyValuePair <BspSegment, BspSegment>(originalestTarget, originalestSource)))
                        {
                            continue;
                        }

                        result.Add(new KeyValuePair <BspSegment, BspSegment>(originalestSource, originalestTarget));
                    }
                }
                if (bspSegment.EndSplitInfos != null)
                {
                    foreach (var splitInfo in bspSegment.EndSplitInfos)
                    {
                        // Self intersect is ignored.
                        if (splitInfo.SourceSegment.EntityId == bspSegment.EntityId)
                        {
                            continue;
                        }

                        // If not real intersection.
                        var extendType = CurveIntersectUtils.ParamToExtendTypeForLine(splitInfo.SourceParam);
                        if (extendType != ExtendType.None)
                        {
                            continue;
                        }

                        var originalestSource = GetOriginalSourceBspSegment(splitInfo.SourceSegment);
                        if (result.Contains(new KeyValuePair <BspSegment, BspSegment>(originalestSource, originalestTarget)) ||
                            result.Contains(new KeyValuePair <BspSegment, BspSegment>(originalestTarget, originalestSource)))
                        {
                            continue;
                        }

                        result.Add(new KeyValuePair <BspSegment, BspSegment>(originalestSource, originalestTarget));
                    }
                }
            }

            if (node.LeftChild != null)
            {
                SearchNearSegmentsSegmentsOfNode(node.LeftChild, result);
            }

            if (node.RightChild != null)
            {
                SearchNearSegmentsSegmentsOfNode(node.RightChild, result);
            }
        }
Ejemplo n.º 4
0
        private CurveBspNode Create(IEnumerable <BspSegment> segments, int depth, CurveBspNode parent, bool isLeft)
        {
            if (segments == null || !segments.Any())
            {
                return(null);
            }

            BspSegment segment = null;

            // We need to make sure segment is not a point
            foreach (var bspSegment in segments)
            {
                var startPoint = bspSegment.LineSegment.StartPoint;
                var endPoint   = bspSegment.LineSegment.EndPoint;
                if (startPoint != endPoint)
                {
                    segment = bspSegment;
                    break;
                }
            }

            if (segment == null)
            {
                return(null);
            }

            var node = new CurveBspNode(segment);

            node.Depth  = depth;
            node.Parent = parent;
            node.IsLeft = isLeft;

            // Left segments
            var leftSegments = new List <BspSegment>();
            // Right segments
            var rightSegments = new List <BspSegment>();
            // Inline segments
            var inlineSegments = new List <BspSegment>();

            inlineSegments.Add(segment);

            var leftSegsStartOnSplitLine  = new List <BspSegment>();
            var leftSegsEndOnSplitLine    = new List <BspSegment>();
            var rightSegsStartOnSplitLine = new List <BspSegment>();
            var rightSegsEndOnSplitLine   = new List <BspSegment>();

            foreach (var nextSegment in segments)
            {
                if (nextSegment == segment)
                {
                    continue;
                }

                BspSegment left, right, inline;
                double     startVal, endVal;
                SplitSegment(segment, nextSegment, out left, out right, out inline, out startVal, out endVal);
                if (left != null)
                {
                    leftSegments.Add(left);
                }
                if (right != null)
                {
                    rightSegments.Add(right);
                }
                if (inline != null)
                {
                    inlineSegments.Add(inline);
                }

                if (left != null && right == null)
                {
                    if (startVal.EqualsWithTolerance(0.0))
                    {
                        leftSegsStartOnSplitLine.Add(left);
                    }
                    else if (endVal.EqualsWithTolerance(0.0))
                    {
                        leftSegsEndOnSplitLine.Add(left);
                    }
                }
                else if (left == null && right != null)
                {
                    if (startVal.EqualsWithTolerance(0.0))
                    {
                        rightSegsStartOnSplitLine.Add(right);
                    }
                    else if (endVal.EqualsWithTolerance(0.0))
                    {
                        rightSegsEndOnSplitLine.Add(right);
                    }
                }
            }

            // Update node's segment's information.
            if (inlineSegments.Count > 1)
            {
                node.Segments = inlineSegments.ToArray();
                // Update all left segments and right segment's split info
                foreach (var leftSegment in leftSegments)
                {
                    UpdateSplitInfoForInlineSegments(leftSegment, inlineSegments);
                }
                foreach (var rightSegment in rightSegments)
                {
                    UpdateSplitInfoForInlineSegments(rightSegment, inlineSegments);
                }
            }

            //
            if (leftSegsStartOnSplitLine.Count > 0)
            {
                foreach (var bspSegment in leftSegsStartOnSplitLine)
                {
                    var startPoint     = bspSegment.LineSegment.StartPoint;
                    var rightStartSegs = rightSegsStartOnSplitLine.Where(
                        it => it.LineSegment.StartPoint.IsEqualTo(startPoint));
                    var rightEndSegs = rightSegsEndOnSplitLine.Where(
                        it => it.LineSegment.EndPoint.IsEqualTo(startPoint));
                    var splitInfos = new List <BspSplitInfo>();
                    foreach (var rightStartSeg in rightStartSegs)
                    {
                        splitInfos.Add(new BspSplitInfo()
                        {
                            IsSplitted    = false,
                            SourceSegment = rightStartSeg,
                            SourceParam   = 0.0
                        });
                    }
                    foreach (var rightEndSeg in rightEndSegs)
                    {
                        splitInfos.Add(new BspSplitInfo()
                        {
                            IsSplitted    = false,
                            SourceSegment = rightEndSeg,
                            SourceParam   = 1.0
                        });
                    }
                    if (splitInfos.Count > 0)
                    {
                        if (bspSegment.StartSplitInfos != null && bspSegment.StartSplitInfos.Length > 0)
                        {
                            splitInfos.InsertRange(0, bspSegment.StartSplitInfos);
                        }
                        bspSegment.StartSplitInfos = splitInfos.ToArray();
                    }
                }
            }

            if (leftSegsEndOnSplitLine.Count > 0)
            {
                foreach (var bspSegment in leftSegsEndOnSplitLine)
                {
                    var endPoint       = bspSegment.LineSegment.EndPoint;
                    var rightStartSegs = rightSegsStartOnSplitLine.Where(
                        it => it.LineSegment.StartPoint.IsEqualTo(endPoint));
                    var rightEndSegs = rightSegsEndOnSplitLine.Where(
                        it => it.LineSegment.EndPoint.IsEqualTo(endPoint));
                    var splitInfos = new List <BspSplitInfo>();
                    foreach (var rightStartSeg in rightStartSegs)
                    {
                        splitInfos.Add(new BspSplitInfo()
                        {
                            IsSplitted    = false,
                            SourceSegment = rightStartSeg,
                            SourceParam   = 0.0
                        });
                    }
                    foreach (var rightEndSeg in rightEndSegs)
                    {
                        splitInfos.Add(new BspSplitInfo()
                        {
                            IsSplitted    = false,
                            SourceSegment = rightEndSeg,
                            SourceParam   = 1.0
                        });
                    }
                    if (splitInfos.Count > 0)
                    {
                        if (bspSegment.EndSplitInfos != null && bspSegment.EndSplitInfos.Length > 0)
                        {
                            splitInfos.InsertRange(0, bspSegment.EndSplitInfos);
                        }
                        bspSegment.EndSplitInfos = splitInfos.ToArray();
                    }
                }
            }

            if (depth < this._parallelDepth)
            {
                // Parellel to improve performance.
                System.Threading.Tasks.Parallel.Invoke(
                    () => node.LeftChild  = Create(leftSegments, depth + 1, node, true),
                    () => node.RightChild = Create(rightSegments, depth + 1, node, false));
            }
            else
            {
                node.LeftChild  = Create(leftSegments, depth + 1, node, true);
                node.RightChild = Create(rightSegments, depth + 1, node, false);
            }

            return(node);
        }