// Function to find out all of the possibly intersecting pairs of triangles, and also to find out which triangles are not possibly intersecting anything public static void CullIntersections(CSGModel a, CSGModel b, SparseBoolMatrix.PairCallback pairCallback, SafeTriangleCallback safeCallback) { ModelIntersectTree tree = new ModelIntersectTree(a, b); // create the tree (operations are done automatically by the constructor // make lists of all the triangle indices in each of the input objects HashSet<long> aSafe = new HashSet<long>(); HashSet<long> bSafe = new HashSet<long>(); foreach (long i in tree.allItems[0]) aSafe.Add(i); foreach (long j in tree.allItems[1]) bSafe.Add(j); // iterate through all of the pairs tree.ForLeafLevelPairs( (i, j) => { aSafe.Remove(i); // if an item is in a pair with another item, it isn't safe, so we remove it from the safe list bSafe.Remove(j); pairCallback(i, j); // call the user-defined callback }); foreach (long i in aSafe) // let the user know which ones were determined to be 'safe' safeCallback(0, i); foreach (long j in bSafe) safeCallback(1, j); }
public CSGShape(CSGModel model, CSGSourceTriangle triangleBasis) : this() { parentTriangle = triangleBasis; foreach (CSGVertex vert in triangleBasis.sourceVerts) boundary.Add(vert); for (int i = 0; i < 3; i++) { CSGEdge edge = model.GetEdge(boundary[i], boundary[(i + 1) % 3], true); edge.SetAsNeighbor(this); edges.Add(edge); } }
public CSGSourceTriangle(CSGModel model, CSGVertex[] verts, VInfo[] vinfos) : this() { this.model = model; for(int i = 0; i< 3;i++) { sourceVerts[i] = verts[i]; vertexVInfos[verts[i].id] = vinfos[i]; } ComputePlane(); divisions.Add(new CSGShape(model, this)); }
public CSGSourceTriangle(CSGModel model, CSGVertex[] verts, VInfo[] vinfos) : this() { this.model = model; for (int i = 0; i < 3; i++) { sourceVerts[i] = verts[i]; vertexVInfos[verts[i].id] = vinfos[i]; } ComputePlane(); divisions.Add(new CSGShape(model, this)); }
public CSGShape(CSGModel model, CSGSourceTriangle triangleBasis) : this() { parentTriangle = triangleBasis; foreach (CSGVertex vert in triangleBasis.sourceVerts) { boundary.Add(vert); } for (int i = 0; i < 3; i++) { CSGEdge edge = model.GetEdge(boundary[i], boundary[(i + 1) % 3], true); edge.SetAsNeighbor(this); edges.Add(edge); } }
// Function to find out all of the possibly intersecting pairs of triangles, and also to find out which triangles are not possibly intersecting anything public static void CullIntersections(CSGModel a, CSGModel b, SparseBoolMatrix.PairCallback pairCallback, SafeTriangleCallback safeCallback) { ModelIntersectTree tree = new ModelIntersectTree(a, b); // create the tree (operations are done automatically by the constructor // make lists of all the triangle indices in each of the input objects HashSet <long> aSafe = new HashSet <long>(); HashSet <long> bSafe = new HashSet <long>(); foreach (long i in tree.allItems[0]) { aSafe.Add(i); } foreach (long j in tree.allItems[1]) { bSafe.Add(j); } // iterate through all of the pairs tree.ForLeafLevelPairs( (i, j) => { aSafe.Remove(i); // if an item is in a pair with another item, it isn't safe, so we remove it from the safe list bSafe.Remove(j); pairCallback(i, j); // call the user-defined callback }); foreach (long i in aSafe) // let the user know which ones were determined to be 'safe' { safeCallback(0, i); } foreach (long j in bSafe) { safeCallback(1, j); } }
// Interesting constructor // Does the populating of the tree and whatnot automatically, given the objects to populate it with public ModelIntersectTree(CSGModel a, CSGModel b) { AABB a_box = a.ComputeAABB(); AABB b_box = b.ComputeAABB(); if (!AABB.CheckIntersection(a_box, b_box)) return; AABB intersection = AABB.Intersection(a_box, b_box); BoundsInit(intersection, 5); foreach (Octree.Item item in a.GetSourceTriangleOctreeData()) if (item.obj is CSGSourceTriangle) { allItems[0].Add((item.obj as CSGSourceTriangle).id); InsertItem(0, item); } foreach (Octree.Item item in b.GetSourceTriangleOctreeData()) if (item.obj is CSGSourceTriangle) { allItems[1].Add((item.obj as CSGSourceTriangle).id); InsertItem(1, item); } }
// Similar, but without the part for finding out all the stuff stuff that's safe public static void CullIntersections(CSGModel a, CSGModel b, SparseBoolMatrix.PairCallback pairCallback) { ModelIntersectTree tree = new ModelIntersectTree(a, b); // create the tree (operations are done automatically by the constructor tree.ForLeafLevelPairs(pairCallback); // iterate through all of the pairs and call the user-defined callback }
// clone a model and transform its verts and vinfos (scraps any WIP intersection info) public CSGModel CloneAndTransform(ModelUtil.CopyAndTransformVert vertCopier, ModelUtil.CopyAndTransformVInfo vinfoCopier) { CSGModel result = new CSGModel(); Dictionary<long, CSGVertex> vertexMapping = new Dictionary<long, CSGVertex>(); Dictionary<long, CSGEdge> edgeMapping = new Dictionary<long, CSGEdge>(); Dictionary<long, CSGShape> shapeMapping = new Dictionary<long, CSGShape>(); Dictionary<long, CSGSourceTriangle> triangleMapping = new Dictionary<long, CSGSourceTriangle>(); foreach (CSGVertex vert in vertices) { CSGVertex v = new CSGVertex(); vertexMapping[vert.id] = v; result.vertices.Add(v); } foreach (CSGEdge edge in edges) { CSGEdge e = new CSGEdge(); edgeMapping[edge.id] = e; result.edges.Add(e); } foreach (CSGShape shape in shapes) { CSGShape s = new CSGShape(); shapeMapping[shape.id] = s; result.shapes.Add(s); } foreach (CSGSourceTriangle triangle in sourceTriangles) { CSGSourceTriangle t = new CSGSourceTriangle(); triangleMapping[triangle.id] = t; result.sourceTriangles.Add(t); } foreach (CSGVertex iVertex in vertices) { CSGVertex rVertex = vertexMapping[iVertex.id]; if(iVertex.parentTriangle != null) rVertex.parentTriangle = triangleMapping[iVertex.parentTriangle.id]; vertCopier(iVertex.position, out rVertex.position); foreach(CSGEdge edge in iVertex.neighbors) rVertex.neighbors.Add(edgeMapping[edge.id]); } foreach (CSGEdge iEdge in edges) { CSGEdge rEdge = edgeMapping[iEdge.id]; if(iEdge.parentTriangle != null) rEdge.parentTriangle = triangleMapping[iEdge.parentTriangle.id]; for (int i = 0; i < 2; i++) { rEdge.endpoints[i] = vertexMapping[iEdge.endpoints[i].id]; if (iEdge.separatedShapes[i] != null) rEdge.separatedShapes[i] = shapeMapping[iEdge.separatedShapes[i].id]; } } foreach (CSGSourceTriangle iTriangle in sourceTriangles) { CSGSourceTriangle rTriangle = triangleMapping[iTriangle.id]; for (int i = 0; i < 3; i++) rTriangle.sourceVerts[i] = vertexMapping[iTriangle.sourceVerts[i].id]; foreach (long key in iTriangle.vertexVInfos.Keys) { VInfo vinfo; vinfoCopier(iTriangle.vertexVInfos[key], out vinfo); rTriangle.vertexVInfos[key] = vinfo; } } foreach (CSGShape iShape in shapes) { CSGShape rShape = shapeMapping[iShape.id]; rShape.parentTriangle = triangleMapping[iShape.parentTriangle.id]; foreach (CSGVertex vert in iShape.boundary) rShape.boundary.Add(vertexMapping[vert.id]); foreach (List<CSGVertex> iHole in iShape.holes) { List<CSGVertex> rHole = new List<CSGVertex>(); foreach (CSGVertex vert in iHole) rHole.Add(vertexMapping[vert.id]); rShape.holes.Add(rHole); } foreach (CSGEdge iEdge in iShape.edges) rShape.edges.Add(edgeMapping[iEdge.id]); } return result; }
// clone a model and transform its verts and vinfos (scraps any WIP intersection info) public CSGModel CloneAndTransform(ModelUtil.CopyAndTransformVert vertCopier, ModelUtil.CopyAndTransformVInfo vinfoCopier) { CSGModel result = new CSGModel(); Dictionary <long, CSGVertex> vertexMapping = new Dictionary <long, CSGVertex>(); Dictionary <long, CSGEdge> edgeMapping = new Dictionary <long, CSGEdge>(); Dictionary <long, CSGShape> shapeMapping = new Dictionary <long, CSGShape>(); Dictionary <long, CSGSourceTriangle> triangleMapping = new Dictionary <long, CSGSourceTriangle>(); foreach (CSGVertex vert in vertices) { CSGVertex v = new CSGVertex(); vertexMapping[vert.id] = v; result.vertices.Add(v); } foreach (CSGEdge edge in edges) { CSGEdge e = new CSGEdge(); edgeMapping[edge.id] = e; result.edges.Add(e); } foreach (CSGShape shape in shapes) { CSGShape s = new CSGShape(); shapeMapping[shape.id] = s; result.shapes.Add(s); } foreach (CSGSourceTriangle triangle in sourceTriangles) { CSGSourceTriangle t = new CSGSourceTriangle(); triangleMapping[triangle.id] = t; result.sourceTriangles.Add(t); } foreach (CSGVertex iVertex in vertices) { CSGVertex rVertex = vertexMapping[iVertex.id]; if (iVertex.parentTriangle != null) { rVertex.parentTriangle = triangleMapping[iVertex.parentTriangle.id]; } vertCopier(iVertex.position, out rVertex.position); foreach (CSGEdge edge in iVertex.neighbors) { rVertex.neighbors.Add(edgeMapping[edge.id]); } } foreach (CSGEdge iEdge in edges) { CSGEdge rEdge = edgeMapping[iEdge.id]; if (iEdge.parentTriangle != null) { rEdge.parentTriangle = triangleMapping[iEdge.parentTriangle.id]; } for (int i = 0; i < 2; i++) { rEdge.endpoints[i] = vertexMapping[iEdge.endpoints[i].id]; if (iEdge.separatedShapes[i] != null) { rEdge.separatedShapes[i] = shapeMapping[iEdge.separatedShapes[i].id]; } } } foreach (CSGSourceTriangle iTriangle in sourceTriangles) { CSGSourceTriangle rTriangle = triangleMapping[iTriangle.id]; for (int i = 0; i < 3; i++) { rTriangle.sourceVerts[i] = vertexMapping[iTriangle.sourceVerts[i].id]; } foreach (long key in iTriangle.vertexVInfos.Keys) { VInfo vinfo; vinfoCopier(iTriangle.vertexVInfos[key], out vinfo); rTriangle.vertexVInfos[key] = vinfo; } } foreach (CSGShape iShape in shapes) { CSGShape rShape = shapeMapping[iShape.id]; rShape.parentTriangle = triangleMapping[iShape.parentTriangle.id]; foreach (CSGVertex vert in iShape.boundary) { rShape.boundary.Add(vertexMapping[vert.id]); } foreach (List <CSGVertex> iHole in iShape.holes) { List <CSGVertex> rHole = new List <CSGVertex>(); foreach (CSGVertex vert in iHole) { rHole.Add(vertexMapping[vert.id]); } rShape.holes.Add(rHole); } foreach (CSGEdge iEdge in iShape.edges) { rShape.edges.Add(edgeMapping[iEdge.id]); } } return(result); }
// Similar, but without the part for finding out all the stuff stuff that's safe public static void CullIntersections(CSGModel a, CSGModel b, SparseBoolMatrix.PairCallback pairCallback) { ModelIntersectTree tree = new ModelIntersectTree(a, b); // create the tree (operations are done automatically by the constructor tree.ForLeafLevelPairs(pairCallback); // iterate through all of the pairs and call the user-defined callback }