public List <BasicModelVert> Trim(RegionKeepCondition keepCondition) // hypothetically, only one of keepInside or keepOutside should be true { List <List <int> > regions = DivideIntoRegions(); int numRegions = regions.Count; List <BasicModelVert> result = new List <BasicModelVert>(); RegionBehavior[] behaviors = new RegionBehavior[numRegions]; for (int i = 0; i < numRegions; i++) { List <PreResultTriangle> regionTriangles = new List <PreResultTriangle>(); foreach (int j in regions[i]) { regionTriangles.Add(triangles[j]); } RegionBehavior behavior = behaviors[i] = keepCondition(regionTriangles); if (behavior != RegionBehavior.Delete) { if (behavior == RegionBehavior.Normal) { foreach (int index in regions[i]) { result.AddRange(triangles[index].verts); } } else { int[] winding = new int[] { 2, 1, 0 }; int numTriangles = regions[i].Count; for (int j = 0; j < numTriangles; j++) { int index = regions[i][j]; foreach (int k in winding) { BasicModelVert vert = triangles[regions[i][j]].verts[k]; vert.normal = -vert.normal; result.Add(vert); } } } } } return(result); }
// hypothetically, only one of keepInside or keepOutside should be true public List<BasicModelVert> Trim(RegionKeepCondition keepCondition) { List<List<int>> regions = DivideIntoRegions(); int numRegions = regions.Count; List<BasicModelVert> result = new List<BasicModelVert>(); RegionBehavior[] behaviors = new RegionBehavior[numRegions]; for (int i = 0; i < numRegions; i++) { List<PreResultTriangle> regionTriangles = new List<PreResultTriangle>(); foreach(int j in regions[i]) regionTriangles.Add(triangles[j]); RegionBehavior behavior = behaviors[i] = keepCondition(regionTriangles); if (behavior != RegionBehavior.Delete) { if (behavior == RegionBehavior.Normal) { foreach (int index in regions[i]) result.AddRange(triangles[index].verts); } else { int[] winding = new int[] {2, 1, 0 }; int numTriangles = regions[i].Count; for (int j = 0; j < numTriangles; j++) { int index = regions[i][j]; foreach(int k in winding) { BasicModelVert vert = triangles[regions[i][j]].verts[k]; vert.normal = -vert.normal; result.Add(vert); } } } } } return result; }
// Returns the sort of RegionKeepCondition to be used if the user doesn't manually specify one to use in place of it // // It's called "majority condition" because it does some odd number of ray tests to figure out whether the region is "inside" or "outside", // and whichever it finds more often is the one it goes with... // // To avoid random flukes, basically public static RegionKeepCondition MajorityCondition(Predicate <Vec3> insideTestFunction, RegionBehavior insideBehavior, RegionBehavior outsideBehavior) { return(new RegionKeepCondition( (triangles) => { int inside = 0, outside = 0; for (int i = 0; i < 23; i++) { if (insideTestFunction(triangles[Random3D.RandInt(triangles.Count)].GetCenterPoint())) { inside++; } else { outside++; } } return (inside > outside) ? insideBehavior : outsideBehavior; })); }
// Returns the sort of RegionKeepCondition to be used if the user doesn't manually specify one to use in place of it // // It's called "majority condition" because it does some odd number of ray tests to figure out whether the region is "inside" or "outside", // and whichever it finds more often is the one it goes with... // // To avoid random flukes, basically public static RegionKeepCondition MajorityCondition(Predicate<Vec3> insideTestFunction, RegionBehavior insideBehavior, RegionBehavior outsideBehavior) { return new RegionKeepCondition( (triangles) => { int inside = 0, outside = 0; for (int i = 0; i < 23; i++) if (insideTestFunction(triangles[Random3D.RandInt(triangles.Count)].GetCenterPoint())) inside++; else outside++; return (inside > outside) ? insideBehavior : outsideBehavior; }); }