static Mesh PerformOperation(Mesh a, Mesh b, CsgFunctionHandler fun) { CsgNode A = new CsgNode(PolygonsFromMesh(a)); CsgNode B = new CsgNode(PolygonsFromMesh(b)); CsgNode AB = fun(A, B); List <CsgPolygon> polygons = AB.GetAllPolygons(); return(MeshFromPolygons(polygons)); }
// Return a list of all polygons in this BSP tree. public static int GetTotalPolygons(CsgNode root) { int total = 0; if (root != null) { total += GetTotalPolygons(root.back); total += GetTotalPolygons(root.front); total += root.polygons.Count; } return(total); }
// Remove all polygons in this BSP tree that are inside the other BSP tree // `bsp`. public void ClipTo(CsgNode other) { this.polygons = other.ClipPolygons(this.polygons); if (this.front != null) { this.front.ClipTo(other); } if (this.back != null) { this.back.ClipTo(other); } }
// Return a new CSG solid representing space both this solid and in the // solid `csg`. Neither this solid nor the solid `csg` are modified. // // A.intersect(B) // // +-------+ // | | // | A | // | +--+----+ = +--+ // +----+--+ | +--+ // | B | // | | // +-------+ // public static CsgNode Intersect(CsgNode a1, CsgNode b1) { CsgNode a = a1.Clone(); CsgNode b = b1.Clone(); a.Invert(); b.ClipTo(a); b.Invert(); a.ClipTo(b); b.ClipTo(a); a.BuildFromPolygons(b.GetAllPolygons()); a.Invert(); CsgNode ret = new CsgNode(a.GetAllPolygons()); return ret; }
// Return a new CSG solid representing space in either this solid or in the // solid `csg`. Neither this solid nor the solid `csg` are modified. // // +-------+ +-------+ // | | | | // | A | | | // | +--+----+ = | +----+ // +----+--+ | +----+ | // | B | | | // | | | | // +-------+ +-------+ // public static CsgNode Union(CsgNode a1, CsgNode b1) { CsgNode a = a1.Clone(); CsgNode b = b1.Clone(); a.ClipTo(b); b.ClipTo(a); b.Invert(); b.ClipTo(a); b.Invert(); a.BuildFromPolygons(b.GetAllPolygons()); CsgNode ret = new CsgNode(a.GetAllPolygons()); return(ret); }
public CsgNode Clone() { CsgNode ret = new CsgNode(); ret.polygons = this.polygons; ret.plane = this.plane; if (this.front != null) { ret.front = this.front.Clone(); } if (this.back != null) { ret.back = this.back.Clone(); } return(ret); }
// Convert solid space to empty space and empty space to solid space. public void Invert() { for (int i = 0; i < this.polygons.Count; i++) { this.polygons[i].flip(); } this.plane.flip(); if (this.front != null) { this.front.Invert(); } if (this.back != null) { this.back.Invert(); } CsgNode hold = this.front; this.front = this.back; this.back = hold; }
// Build a BSP tree out of `polygons`. When called on an existing tree, the // new polygons are filtered down to the bottom of the tree and become new // nodes there. Each set of polygons is partitioned using the first polygon // (no heuristic is used to pick a good split). public void BuildFromPolygons(List <CsgPolygon> list) { if (list.Count <= 0) { return; } if (!this.plane.ok()) { this.plane = list[0].plane; } List <CsgPolygon> list_front = new List <CsgPolygon>(); List <CsgPolygon> list_back = new List <CsgPolygon>(); for (int i = 0; i < list.Count; i++) { this.plane.SplitPolygon(list[i], this.polygons, this.polygons, list_front, list_back); int count = CsgNode.GetTotalPolygons(this); } if (list_front.Count > 0) { if (this.front == null) { this.front = new CsgNode(); } this.front.BuildFromPolygons(list_front); } if (list_back.Count > 0) { if (this.back == null) { this.back = new CsgNode(); } this.back.BuildFromPolygons(list_back); } }
public CsgNode(List<CsgPolygon> list) { front = null; back = null; BuildFromPolygons(list); }
public CsgNode() { front = null; back = null; }
// Build a BSP tree out of `polygons`. When called on an existing tree, the // new polygons are filtered down to the bottom of the tree and become new // nodes there. Each set of polygons is partitioned using the first polygon // (no heuristic is used to pick a good split). public void BuildFromPolygons(List<CsgPolygon> list) { if (list.Count <= 0) return; if (!this.plane.ok()) this.plane = list[0].plane; List<CsgPolygon> list_front = new List<CsgPolygon>(); List<CsgPolygon> list_back = new List<CsgPolygon>(); for (int i = 0; i < list.Count; i++) { this.plane.SplitPolygon(list[i], this.polygons, this.polygons, list_front, list_back); int count = CsgNode.GetTotalPolygons(this); } if (list_front.Count > 0) { if (this.front == null) this.front = new CsgNode(); this.front.BuildFromPolygons(list_front); } if (list_back.Count > 0) { if (this.back == null) this.back = new CsgNode(); this.back.BuildFromPolygons(list_back); } }
public CsgNode Clone() { CsgNode ret = new CsgNode(); ret.polygons = this.polygons; ret.plane = this.plane; if (this.front != null) { ret.front = this.front.Clone(); } if (this.back != null) { ret.back = this.back.Clone(); } return ret; }
// Return a list of all polygons in this BSP tree. public static int GetTotalPolygons(CsgNode root) { int total = 0; if (root != null) { total += GetTotalPolygons(root.back); total += GetTotalPolygons(root.front); total += root.polygons.Count; } return total; }
public CsgNode(List <CsgPolygon> list) { front = null; back = null; BuildFromPolygons(list); }
private static Mesh PerformOperation(Mesh a, Mesh b, CsgFunctionHandler fun) { CsgNode A = new CsgNode(PolygonsFromMesh(a)); CsgNode B = new CsgNode(PolygonsFromMesh(b)); CsgNode AB = fun(A, B); List<CsgPolygon> polygons = AB.GetAllPolygons(); return MeshFromPolygons(polygons); }