// Currently this is the only constructor, and it requires an OperationType value // It will automatically generate the RegionKeepCondition delegate functions (via MajorityCondition) public CSG(OperationType op) { first_keep = MajorityCondition( ((p) => second_blob.IsPointInside(p)), DoesOpAccept(op, 0, true) ? invert_first ? RegionBehavior.Flip : RegionBehavior.Normal : RegionBehavior.Delete, DoesOpAccept(op, 0, false) ? invert_first ? RegionBehavior.Flip : RegionBehavior.Normal : RegionBehavior.Delete); second_keep = MajorityCondition( ((p) => first_blob.IsPointInside(p)), DoesOpAccept(op, 1, true) ? invert_first ? RegionBehavior.Flip : RegionBehavior.Normal : RegionBehavior.Delete, DoesOpAccept(op, 1, false) ? invert_first ? RegionBehavior.Flip : RegionBehavior.Normal : RegionBehavior.Delete); }
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; }
// After the cuts are done, finds continuous regions of the surface of one of the input models and returns the properly trimmed/flipped regions protected virtual List <BasicModelVert> ScrapTrimmedStuff(List <BasicModelVert> safeZone, List <BasicModelVert> notsafeZone, List <Vec3[]> cutEdges, RegionKeepCondition regionCondition) { PreResultModel prm = new PreResultModel(); prm.ProhibitEdges(cutEdges); prm.AddTriangles(notsafeZone); prm.AddTriangles(safeZone); return(prm.Trim(regionCondition)); }
// After the cuts are done, finds continuous regions of the surface of one of the input models and returns the properly trimmed/flipped regions protected virtual List<BasicModelVert> ScrapTrimmedStuff(List<BasicModelVert> safeZone, List<BasicModelVert> notsafeZone, List<Vec3[]> cutEdges, RegionKeepCondition regionCondition) { PreResultModel prm = new PreResultModel(); prm.ProhibitEdges(cutEdges); prm.AddTriangles(notsafeZone); prm.AddTriangles(safeZone); return prm.Trim(regionCondition); }