Example #1
0
        //public const int kRoutingOffset = 1 + (int)CategoryIndex.LastCategory;

        public bool TryGetRoute(ref RoutingTable table, CategoryGroupIndex inputIndex, out CategoryRoutingRow routingRow)
        {
            var tableIndex = startIndex + (int)inputIndex;// (inputIndex == CategoryGroupIndex.First) ? (int)CategoryGroupIndex.First : ((int)inputIndex - kRoutingOffset);

            if (tableIndex < startIndex || tableIndex >= endIndex)
            {
                routingRow = new CategoryRoutingRow(inputIndex);
                return(false);
            }

            //Debug.Assert(inputIndex == table.Value.inputs[tableIndex]);
            routingRow = table.routingRows[tableIndex];
            return(true);
        }
Example #2
0
        void IntersectLoopsJob(HashedVertices brushVertices,

                               NativeListArray <int> .NativeList loopIndices,
                               int surfaceLoopIndex,

                               NativeListArray <int> holeIndices,
                               NativeList <SurfaceInfo> allInfos,
                               NativeListArray <Edge> allEdges,

                               NativeListArray <Edge> .NativeList intersectionLoop,
                               CategoryGroupIndex intersectionCategory,
                               SurfaceInfo intersectionInfo)
        {
            if (intersectionLoop.Length == 0)
            {
                return;
            }

            //Debug.Assert(allEdges.Length == allInfos.Length);
            //Debug.Assert(allInfos.Length == holeIndices.Length);

            var currentLoopEdges   = allEdges[surfaceLoopIndex];
            var currentInfo        = allInfos[surfaceLoopIndex];
            var currentHoleIndices = holeIndices[surfaceLoopIndex];

            // It might look like we could just set the interiorCategory of brush_intersection here, and let all other cut loops copy from it below,
            // but the same brush_intersection might be used by another categorized_loop and then we'd try to reroute it again, which wouldn't work
            //brush_intersection.interiorCategory = newHoleCategory;

            if (currentLoopEdges.Length == 0)
            {
                return;
            }

            var maxLength = math.max(intersectionLoop.Length, currentLoopEdges.Length);

            if (maxLength < 3)
            {
                return;
            }

            int inside2 = 0, outside2 = 0;
            var categories2      = stackalloc EdgeCategory[currentLoopEdges.Length];
            var treeSpacePlanes1 = brushTreeSpacePlanes[intersectionInfo.brushNodeIndex];

            for (int e = 0; e < currentLoopEdges.Length; e++)
            {
                var category = BooleanEdgesUtility.CategorizeEdge(currentLoopEdges[e], ref treeSpacePlanes1.Value.treeSpacePlanes, intersectionLoop, brushVertices);
                categories2[e] = category;
                if (category == EdgeCategory.Inside)
                {
                    inside2++;
                }
                else if (category == EdgeCategory.Outside)
                {
                    outside2++;
                }
            }
            var aligned2 = currentLoopEdges.Length - (inside2 + outside2);

            int inside1 = 0, outside1 = 0;
            var categories1      = stackalloc EdgeCategory[intersectionLoop.Length];
            var treeSpacePlanes2 = brushTreeSpacePlanes[currentInfo.brushNodeIndex];

            for (int e = 0; e < intersectionLoop.Length; e++)
            {
                var category = BooleanEdgesUtility.CategorizeEdge(intersectionLoop[e], ref treeSpacePlanes2.Value.treeSpacePlanes, currentLoopEdges, brushVertices);
                categories1[e] = category;
                if (category == EdgeCategory.Inside)
                {
                    inside1++;
                }
                else if (category == EdgeCategory.Outside)
                {
                    outside1++;
                }
            }
            var aligned1 = intersectionLoop.Length - (inside1 + outside1);

            // Completely outside
            if ((inside1 + aligned1) == 0 && (aligned2 + inside2) == 0)
            {
                return;
            }

            if ((inside1 + (inside2 + aligned2)) < 3)
            {
                return;
            }

            // Completely aligned
            if (((outside1 + inside1) == 0 && (outside2 + inside2) == 0) ||
                // polygon1 edges Completely inside polygon2
                (inside1 == 0 && outside2 == 0))
            {
                // New polygon overrides the existing polygon
                currentInfo.interiorCategory = intersectionCategory;
                allInfos[surfaceLoopIndex]   = currentInfo;
                //Debug.Assert(holeIndices.IsAllocated(surfaceLoopIndex));
                return;
            }


            var outEdges       = stackalloc Edge[maxLength];
            var outEdgesLength = 0;

            // polygon2 edges Completely inside polygon1
            if (outside1 == 0 && inside2 == 0)
            {
                // polygon1 Completely inside polygon2
                for (int n = 0; n < intersectionLoop.Length; n++)
                {
                    outEdges[outEdgesLength] = intersectionLoop[n];
                    outEdgesLength++;
                }
                //OperationResult.Polygon1InsidePolygon2;
            }
            else
            {
                //int outEdgesLength = 0; // Can't read from outEdges.Length since it's marked as WriteOnly
                for (int e = 0; e < intersectionLoop.Length; e++)
                {
                    var category = categories1[e];
                    if (category == EdgeCategory.Inside)
                    {
                        outEdges[outEdgesLength] = intersectionLoop[e];
                        outEdgesLength++;
                    }
                }

                for (int e = 0; e < currentLoopEdges.Length; e++)
                {
                    var category = categories2[e];
                    if (category != EdgeCategory.Outside)
                    {
                        outEdges[outEdgesLength] = currentLoopEdges[e];
                        outEdgesLength++;
                    }
                }
                //OperationResult.Cut;
            }

            if (outEdgesLength < 3)
            {
                return;
            }

            // FIXME: when brush_intersection and categorized_loop are grazing each other,
            //          technically we cut it but we shouldn't be creating it as a separate polygon + hole (bug7)

            // the output of cutting operations are both holes for the original polygon (categorized_loop)
            // and new polygons on the surface of the brush that need to be categorized
            intersectionInfo.interiorCategory = intersectionCategory;


            if (currentHoleIndices.Length > 0 &&
                // TODO: fix touching not being updated properly
                brushesTouchedByBrushes.ContainsKey(currentInfo.brushNodeIndex))
            {
                // Figure out why this is seemingly not necessary?
                var intersectedHoleIndices       = stackalloc int[currentHoleIndices.Length];
                var intersectedHoleIndicesLength = 0;

                // the output of cutting operations are both holes for the original polygon (categorized_loop)
                // and new polygons on the surface of the brush that need to be categorized

                ref var brushesTouchedByBrush = ref brushesTouchedByBrushes[currentInfo.brushNodeIndex].Value;
                ref var brushIntersections    = ref brushesTouchedByBrushes[currentInfo.brushNodeIndex].Value.brushIntersections;