diff --git a/README.md b/README.md index 8d3a1b9..ec64d5d 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Solid mesh modeling for three.js. ## Installation -Via npm ( `npm i ycw/three-csg-modeller#v0.1.7` ) +Via npm ( `npm i ycw/three-csg-modeller#v0.1.8` ) ```js import Modeller from "three-csg-modeller" @@ -26,7 +26,7 @@ import Modeller from "three-csg-modeller" Via cdn ```js -import Modeller from "https://cdn.jsdelivr.net/gh/ycw/three-csg-modeller@0.1.7/dist/lib.esm.js" +import Modeller from "https://cdn.jsdelivr.net/gh/ycw/three-csg-modeller@0.1.8/dist/lib.esm.js" ``` ## Usage diff --git a/dist/lib.esm.js b/dist/lib.esm.js index 991a493..4ce95a7 100644 --- a/dist/lib.esm.js +++ b/dist/lib.esm.js @@ -1,2 +1,2 @@ -function t(){this.polygons=[]}t.fromPolygons=function(n){var o=new t;return o.polygons=n,o},t.prototype={clone:function(){var n=new t;return n.polygons=this.polygons.map((function(t){return t.clone()})),n},toPolygons:function(){return this.polygons},union:function(n){var o=new t.Node(this.clone().polygons),e=new t.Node(n.clone().polygons);return o.clipTo(e),e.clipTo(o),e.invert(),e.clipTo(o),e.invert(),o.build(e.allPolygons()),t.fromPolygons(o.allPolygons())},subtract:function(n){var o=new t.Node(this.clone().polygons),e=new t.Node(n.clone().polygons);return o.invert(),o.clipTo(e),e.clipTo(o),e.invert(),e.clipTo(o),e.invert(),o.build(e.allPolygons()),o.invert(),t.fromPolygons(o.allPolygons())},intersect:function(n){var o=new t.Node(this.clone().polygons),e=new t.Node(n.clone().polygons);return o.invert(),e.clipTo(o),e.invert(),o.clipTo(e),e.clipTo(o),o.build(e.allPolygons()),o.invert(),t.fromPolygons(o.allPolygons())},inverse:function(){var t=this.clone();return t.polygons.map((function(t){t.flip()})),t}},t.Vector=function(t,n,o){3==arguments.length?(this.x=t,this.y=n,this.z=o):"x"in t?(this.x=t.x,this.y=t.y,this.z=t.z):(this.x=t[0],this.y=t[1],this.z=t[2])},t.Vector.prototype={clone:function(){return new t.Vector(this.x,this.y,this.z)},negated:function(){return new t.Vector(-this.x,-this.y,-this.z)},plus:function(n){return new t.Vector(this.x+n.x,this.y+n.y,this.z+n.z)},minus:function(n){return new t.Vector(this.x-n.x,this.y-n.y,this.z-n.z)},times:function(n){return new t.Vector(this.x*n,this.y*n,this.z*n)},dividedBy:function(n){return new t.Vector(this.x/n,this.y/n,this.z/n)},dot:function(t){return this.x*t.x+this.y*t.y+this.z*t.z},lerp:function(t,n){return this.plus(t.minus(this).times(n))},length:function(){return Math.sqrt(this.dot(this))},unit:function(){return this.dividedBy(this.length())},cross:function(n){return new t.Vector(this.y*n.z-this.z*n.y,this.z*n.x-this.x*n.z,this.x*n.y-this.y*n.x)}},t.Vertex=function(n,o,e,i){this.pos=new t.Vector(n),this.normal=o&&new t.Vector(o),this.uv=e&&e.clone(),this.color=i&&new t.Vector(i)},t.Vertex.prototype={clone:function(){return new t.Vertex(this.pos.clone(),this.normal&&this.normal.clone(),this.uv&&this.uv.clone(),this.color&&this.color.clone())},flip:function(){this.normal&&(this.normal=this.normal.negated())},interpolate:function(n,o){return new t.Vertex(this.pos.lerp(n.pos,o),this.normal&&n.normal&&this.normal.lerp(n.normal,o),this.uv&&n.uv&&this.uv.clone().lerp(n.uv,o),this.color&&n.color&&this.color.lerp(n.color,o))}},t.Plane=function(t,n){this.normal=t,this.w=n},t.Plane.EPSILON=1e-5,t.Plane.fromPoints=function(n,o,e){var i=o.minus(n).cross(e.minus(n)).unit();return new t.Plane(i,i.dot(n))},t.Plane.prototype={clone:function(){return new t.Plane(this.normal.clone(),this.w)},flip:function(){this.normal=this.normal.negated(),this.w=-this.w},splitPolygon:function(n,o,e,i,s){for(var r=0,l=[],h=0;ht.Plane.EPSILON?1:0;r|=c,l.push(c)}switch(r){case 0:(this.normal.dot(n.plane.normal)>0?o:e).push(n);break;case 1:i.push(n);break;case 2:s.push(n);break;case 3:var a=[],u=[];for(h=0;h=3&&i.push(new t.Polygon(a,n.shared)),u.length>=3&&s.push(new t.Polygon(u,n.shared))}}},t.Polygon=function(n,o){this.vertices=n,this.shared=o,this.plane=t.Plane.fromPoints(n[0].pos,n[1].pos,n[2].pos)},t.Polygon.prototype={clone:function(){var n=this.vertices.map((function(t){return t.clone()}));return new t.Polygon(n,this.shared)},flip:function(){this.vertices.reverse().map((function(t){t.flip()})),this.plane.flip()}},t.Node=function(t){this.plane=null,this.front=null,this.back=null,this.polygons=[],t&&this.build(t)},t.Node.prototype={clone:function(){var n=new t.Node;return n.plane=this.plane&&this.plane.clone(),n.front=this.front&&this.front.clone(),n.back=this.back&&this.back.clone(),n.polygons=this.polygons.map((function(t){return t.clone()})),n},invert:function(){for(var t=0;t 65535"),c.index=new t.Uint32BufferAttribute(x,1));c.setAttribute("position",new t.BufferAttribute(s,3)),p&&c.setAttribute("normal",new t.BufferAttribute(r,3));f&&c.setAttribute("uv",new t.BufferAttribute(l,2));y&&c.setAttribute("color",new t.BufferAttribute(h,3));return u}(this._THREE,this._csg)}static _fromMesh(o,e){return function(o,e){const i=new n(o);return i._csg=t.fromPolygons(function(n,o){const e=o.clone();e.updateMatrix();const{matrix:i}=e,s=!i.equals(new n.Matrix4),r=[],l=o.geometry.attributes.position.array,{normal:h,uv:c,color:a}=o.geometry.attributes,u=h&&h.array,p=c&&c.array,f=a&&a.array,y=o.geometry.index&&o.geometry.index.array,g=o.geometry.groups,m=y?y.length:l.length/3;for(let e=0;e=t&&et.Plane.EPSILON?1:0;s|=c,l.push(c)}switch(s){case 0:(this.normal.dot(n.plane.normal)>0?o:e).push(n);break;case 1:r.push(n);break;case 2:i.push(n);break;case 3:var a=[],u=[];for(h=0;h=3&&r.push(new t.Polygon(a,n.shared)),u.length>=3&&i.push(new t.Polygon(u,n.shared))}}},t.Polygon=function(n,o){this.vertices=n,this.shared=o,this.plane=t.Plane.fromPoints(n[0].pos,n[1].pos,n[2].pos)},t.Polygon.prototype={clone:function(){var n=this.vertices.map((function(t){return t.clone()}));return new t.Polygon(n,this.shared)},flip:function(){this.vertices.reverse().map((function(t){t.flip()})),this.plane.flip()}},t.Node=function(t){this.plane=null,this.front=null,this.back=null,this.polygons=[],t&&this.build(t)},t.Node.prototype={clone:function(){var n=new t.Node;return n.plane=this.plane&&this.plane.clone(),n.front=this.front&&this.front.clone(),n.back=this.back&&this.back.clone(),n.polygons=this.polygons.map((function(t){return t.clone()})),n},invert:function(){for(var t=0;t 65535"),c.index=new t.Uint32BufferAttribute(x,1));c.setAttribute("position",new t.BufferAttribute(i,3)),p&&c.setAttribute("normal",new t.BufferAttribute(s,3));f&&c.setAttribute("uv",new t.BufferAttribute(l,2));y&&c.setAttribute("color",new t.BufferAttribute(h,3));return u}(this._THREE,this._csg)}static _fromMesh(o,e){return function(o,e){const r=new n(o);return r._csg=t.fromPolygons(function(n,o){const e=o.clone();e.updateMatrix();const{matrix:r}=e,i=!r.equals(new n.Matrix4),s=[],l=o.geometry.attributes.position.array,{normal:h,uv:c,color:a}=o.geometry.attributes,u=h&&h.array,p=c&&c.array,f=a&&a.array,y=o.geometry.index&&o.geometry.index.array,g=y?y.length:l.length/3,m=Array.isArray(o.material)?o.geometry.groups:[{start:0,count:g,materialIndex:0}];for(const{start:e,count:h,materialIndex:c}of m){const a=Array.isArray(o.material)?o.material[c]:o.material;for(let o=e;o 0) vertex((i + 1) / slices, j / stacks);\r\n// if (j < stacks - 1) vertex((i + 1) / slices, (j + 1) / stacks);\r\n// vertex(i / slices, (j + 1) / stacks);\r\n// polygons.push(new CSG.Polygon(vertices));\r\n// }\r\n// }\r\n// return CSG.fromPolygons(polygons);\r\n// };\r\n\r\n// // Construct a solid cylinder. Optional parameters are `start`, `end`,\r\n// // `radius`, and `slices`, which default to `[0, -1, 0]`, `[0, 1, 0]`, `1`, and\r\n// // `16`. The `slices` parameter controls the tessellation.\r\n// // \r\n// // Example usage:\r\n// // \r\n// // var cylinder = CSG.cylinder({\r\n// // start: [0, -1, 0],\r\n// // end: [0, 1, 0],\r\n// // radius: 1,\r\n// // slices: 16\r\n// // });\r\n// CSG.cylinder = function(options) {\r\n// options = options || {};\r\n// var s = new CSG.Vector(options.start || [0, -1, 0]);\r\n// var e = new CSG.Vector(options.end || [0, 1, 0]);\r\n// var ray = e.minus(s);\r\n// var r = options.radius || 1;\r\n// var slices = options.slices || 16;\r\n// var axisZ = ray.unit(), isY = (Math.abs(axisZ.y) > 0.5);\r\n// var axisX = new CSG.Vector(isY, !isY, 0).cross(axisZ).unit();\r\n// var axisY = axisX.cross(axisZ).unit();\r\n// var start = new CSG.Vertex(s, axisZ.negated());\r\n// var end = new CSG.Vertex(e, axisZ.unit());\r\n// var polygons = [];\r\n// function point(stack, slice, normalBlend) {\r\n// var angle = slice * Math.PI * 2;\r\n// var out = axisX.times(Math.cos(angle)).plus(axisY.times(Math.sin(angle)));\r\n// var pos = s.plus(ray.times(stack)).plus(out.times(r));\r\n// var normal = out.times(1 - Math.abs(normalBlend)).plus(axisZ.times(normalBlend));\r\n// return new CSG.Vertex(pos, normal);\r\n// }\r\n// for (var i = 0; i < slices; i++) {\r\n// var t0 = i / slices, t1 = (i + 1) / slices;\r\n// polygons.push(new CSG.Polygon([start, point(0, t0, -1), point(0, t1, -1)]));\r\n// polygons.push(new CSG.Polygon([point(0, t1, 0), point(0, t0, 0), point(1, t0, 0), point(1, t1, 0)]));\r\n// polygons.push(new CSG.Polygon([end, point(1, t1, 1), point(1, t0, 1)]));\r\n// }\r\n// return CSG.fromPolygons(polygons);\r\n// };\r\n\r\n// # class Vector\r\n\r\n// Represents a 3D vector.\r\n// \r\n// Example usage:\r\n// \r\n// new CSG.Vector(1, 2, 3);\r\n// new CSG.Vector([1, 2, 3]);\r\n// new CSG.Vector({ x: 1, y: 2, z: 3 });\r\n\r\nCSG.Vector = function (x, y, z) {\r\n if (arguments.length == 3) {\r\n this.x = x;\r\n this.y = y;\r\n this.z = z;\r\n } else if ('x' in x) {\r\n this.x = x.x;\r\n this.y = x.y;\r\n this.z = x.z;\r\n } else {\r\n this.x = x[0];\r\n this.y = x[1];\r\n this.z = x[2];\r\n }\r\n};\r\n\r\nCSG.Vector.prototype = {\r\n clone: function () {\r\n return new CSG.Vector(this.x, this.y, this.z);\r\n },\r\n\r\n negated: function () {\r\n return new CSG.Vector(-this.x, -this.y, -this.z);\r\n },\r\n\r\n plus: function (a) {\r\n return new CSG.Vector(this.x + a.x, this.y + a.y, this.z + a.z);\r\n },\r\n\r\n minus: function (a) {\r\n return new CSG.Vector(this.x - a.x, this.y - a.y, this.z - a.z);\r\n },\r\n\r\n times: function (a) {\r\n return new CSG.Vector(this.x * a, this.y * a, this.z * a);\r\n },\r\n\r\n dividedBy: function (a) {\r\n return new CSG.Vector(this.x / a, this.y / a, this.z / a);\r\n },\r\n\r\n dot: function (a) {\r\n return this.x * a.x + this.y * a.y + this.z * a.z;\r\n },\r\n\r\n lerp: function (a, t) {\r\n return this.plus(a.minus(this).times(t));\r\n },\r\n\r\n length: function () {\r\n return Math.sqrt(this.dot(this));\r\n },\r\n\r\n unit: function () {\r\n return this.dividedBy(this.length());\r\n },\r\n\r\n cross: function (a) {\r\n return new CSG.Vector(\r\n this.y * a.z - this.z * a.y,\r\n this.z * a.x - this.x * a.z,\r\n this.x * a.y - this.y * a.x\r\n );\r\n }\r\n};\r\n\r\n// # class Vertex\r\n\r\n// Represents a vertex of a polygon. Use your own vertex class instead of this\r\n// one to provide additional features like texture coordinates and vertex\r\n// colors. Custom vertex classes need to provide a `pos` property and `clone()`,\r\n// `flip()`, and `interpolate()` methods that behave analogous to the ones\r\n// defined by `CSG.Vertex`. This class provides `normal` so convenience\r\n// functions like `CSG.sphere()` can return a smooth vertex normal, but `normal`\r\n// is not used anywhere else.\r\n\r\nCSG.Vertex = function (pos, normal, uv, color) {\r\n this.pos = new CSG.Vector(pos);\r\n this.normal = normal && new CSG.Vector(normal);\r\n this.uv = uv && uv.clone(); // uv is a `THREE.Vector2`.\r\n this.color = color && new CSG.Vector(color);\r\n};\r\n\r\nCSG.Vertex.prototype = {\r\n clone: function () {\r\n return new CSG.Vertex(\r\n this.pos.clone(),\r\n this.normal && this.normal.clone(),\r\n this.uv && this.uv.clone(),\r\n this.color && this.color.clone()\r\n );\r\n },\r\n\r\n // Invert all orientation-specific data (e.g. vertex normal). Called when the\r\n // orientation of a polygon is flipped.\r\n flip: function () {\r\n if (this.normal) {\r\n this.normal = this.normal.negated();\r\n }\r\n },\r\n\r\n // Create a new vertex between this vertex and `other` by linearly\r\n // interpolating all properties using a parameter of `t`. Subclasses should\r\n // override this to interpolate additional properties.\r\n interpolate: function (other, t) {\r\n return new CSG.Vertex(\r\n this.pos.lerp(other.pos, t),\r\n this.normal && other.normal && this.normal.lerp(other.normal, t),\r\n this.uv && other.uv && this.uv.clone().lerp(other.uv, t),\r\n this.color && other.color && this.color.lerp(other.color, t),\r\n );\r\n }\r\n};\r\n\r\n// # class Plane\r\n\r\n// Represents a plane in 3D space.\r\n\r\nCSG.Plane = function (normal, w) {\r\n this.normal = normal;\r\n this.w = w;\r\n};\r\n\r\n// `CSG.Plane.EPSILON` is the tolerance used by `splitPolygon()` to decide if a\r\n// point is on the plane.\r\nCSG.Plane.EPSILON = 1e-5;\r\n\r\nCSG.Plane.fromPoints = function (a, b, c) {\r\n var n = b.minus(a).cross(c.minus(a)).unit();\r\n return new CSG.Plane(n, n.dot(a));\r\n};\r\n\r\nCSG.Plane.prototype = {\r\n clone: function () {\r\n return new CSG.Plane(this.normal.clone(), this.w);\r\n },\r\n\r\n flip: function () {\r\n this.normal = this.normal.negated();\r\n this.w = -this.w;\r\n },\r\n\r\n // Split `polygon` by this plane if needed, then put the polygon or polygon\r\n // fragments in the appropriate lists. Coplanar polygons go into either\r\n // `coplanarFront` or `coplanarBack` depending on their orientation with\r\n // respect to this plane. Polygons in front or in back of this plane go into\r\n // either `front` or `back`.\r\n splitPolygon: function (polygon, coplanarFront, coplanarBack, front, back) {\r\n var COPLANAR = 0;\r\n var FRONT = 1;\r\n var BACK = 2;\r\n var SPANNING = 3;\r\n\r\n // Classify each point as well as the entire polygon into one of the above\r\n // four classes.\r\n var polygonType = 0;\r\n var types = [];\r\n for (var i = 0; i < polygon.vertices.length; i++) {\r\n var t = this.normal.dot(polygon.vertices[i].pos) - this.w;\r\n var type = (t < -CSG.Plane.EPSILON) ? BACK : (t > CSG.Plane.EPSILON) ? FRONT : COPLANAR;\r\n polygonType |= type;\r\n types.push(type);\r\n }\r\n\r\n // Put the polygon in the correct list, splitting it when necessary.\r\n switch (polygonType) {\r\n case COPLANAR:\r\n (this.normal.dot(polygon.plane.normal) > 0 ? coplanarFront : coplanarBack).push(polygon);\r\n break;\r\n case FRONT:\r\n front.push(polygon);\r\n break;\r\n case BACK:\r\n back.push(polygon);\r\n break;\r\n case SPANNING:\r\n var f = [], b = [];\r\n for (var i = 0; i < polygon.vertices.length; i++) {\r\n var j = (i + 1) % polygon.vertices.length;\r\n var ti = types[i], tj = types[j];\r\n var vi = polygon.vertices[i], vj = polygon.vertices[j];\r\n if (ti != BACK) f.push(vi);\r\n if (ti != FRONT) b.push(ti != BACK ? vi.clone() : vi);\r\n if ((ti | tj) == SPANNING) {\r\n var t = (this.w - this.normal.dot(vi.pos)) / this.normal.dot(vj.pos.minus(vi.pos));\r\n var v = vi.interpolate(vj, t);\r\n f.push(v);\r\n b.push(v.clone());\r\n }\r\n }\r\n if (f.length >= 3) front.push(new CSG.Polygon(f, polygon.shared));\r\n if (b.length >= 3) back.push(new CSG.Polygon(b, polygon.shared));\r\n break;\r\n }\r\n }\r\n};\r\n\r\n// # class Polygon\r\n\r\n// Represents a convex polygon. The vertices used to initialize a polygon must\r\n// be coplanar and form a convex loop. They do not have to be `CSG.Vertex`\r\n// instances but they must behave similarly (duck typing can be used for\r\n// customization).\r\n// \r\n// Each convex polygon has a `shared` property, which is shared between all\r\n// polygons that are clones of each other or were split from the same polygon.\r\n// This can be used to define per-polygon properties (such as surface color).\r\n\r\nCSG.Polygon = function (vertices, shared) {\r\n this.vertices = vertices;\r\n this.shared = shared;\r\n this.plane = CSG.Plane.fromPoints(vertices[0].pos, vertices[1].pos, vertices[2].pos);\r\n};\r\n\r\nCSG.Polygon.prototype = {\r\n clone: function () {\r\n var vertices = this.vertices.map(function (v) { return v.clone(); });\r\n return new CSG.Polygon(vertices, this.shared);\r\n },\r\n\r\n flip: function () {\r\n this.vertices.reverse().map(function (v) { v.flip(); });\r\n this.plane.flip();\r\n }\r\n};\r\n\r\n// # class Node\r\n\r\n// Holds a node in a BSP tree. A BSP tree is built from a collection of polygons\r\n// by picking a polygon to split along. That polygon (and all other coplanar\r\n// polygons) are added directly to that node and the other polygons are added to\r\n// the front and/or back subtrees. This is not a leafy BSP tree since there is\r\n// no distinction between internal and leaf nodes.\r\n\r\nCSG.Node = function (polygons) {\r\n this.plane = null;\r\n this.front = null;\r\n this.back = null;\r\n this.polygons = [];\r\n if (polygons) this.build(polygons);\r\n};\r\n\r\nCSG.Node.prototype = {\r\n clone: function () {\r\n var node = new CSG.Node();\r\n node.plane = this.plane && this.plane.clone();\r\n node.front = this.front && this.front.clone();\r\n node.back = this.back && this.back.clone();\r\n node.polygons = this.polygons.map(function (p) { return p.clone(); });\r\n return node;\r\n },\r\n\r\n // Convert solid space to empty space and empty space to solid space.\r\n invert: function () {\r\n for (var i = 0; i < this.polygons.length; i++) {\r\n this.polygons[i].flip();\r\n }\r\n this.plane.flip();\r\n if (this.front) this.front.invert();\r\n if (this.back) this.back.invert();\r\n var temp = this.front;\r\n this.front = this.back;\r\n this.back = temp;\r\n },\r\n\r\n // Recursively remove all polygons in `polygons` that are inside this BSP\r\n // tree.\r\n clipPolygons: function (polygons) {\r\n if (!this.plane) return polygons.slice();\r\n var front = [], back = [];\r\n for (var i = 0; i < polygons.length; i++) {\r\n this.plane.splitPolygon(polygons[i], front, back, front, back);\r\n }\r\n if (this.front) front = this.front.clipPolygons(front);\r\n if (this.back) back = this.back.clipPolygons(back);\r\n else back = [];\r\n return front.concat(back);\r\n },\r\n\r\n // Remove all polygons in this BSP tree that are inside the other BSP tree\r\n // `bsp`.\r\n clipTo: function (bsp) {\r\n this.polygons = bsp.clipPolygons(this.polygons);\r\n if (this.front) this.front.clipTo(bsp);\r\n if (this.back) this.back.clipTo(bsp);\r\n },\r\n\r\n // Return a list of all polygons in this BSP tree.\r\n allPolygons: function () {\r\n var polygons = this.polygons.slice();\r\n if (this.front) polygons = polygons.concat(this.front.allPolygons());\r\n if (this.back) polygons = polygons.concat(this.back.allPolygons());\r\n return polygons;\r\n },\r\n\r\n // Build a BSP tree out of `polygons`. When called on an existing tree, the\r\n // new polygons are filtered down to the bottom of the tree and become new\r\n // nodes there. Each set of polygons is partitioned using the first polygon\r\n // (no heuristic is used to pick a good split).\r\n build: function (polygons) {\r\n if (!polygons.length) return;\r\n if (!this.plane) this.plane = polygons[0].plane.clone();\r\n var front = [], back = [];\r\n for (var i = 0; i < polygons.length; i++) {\r\n this.plane.splitPolygon(polygons[i], this.polygons, this.polygons, front, back);\r\n }\r\n if (front.length) {\r\n if (!this.front) this.front = new CSG.Node();\r\n this.front.build(front);\r\n }\r\n if (back.length) {\r\n if (!this.back) this.back = new CSG.Node();\r\n this.back.build(back);\r\n }\r\n }\r\n};\r\n","import CSG from \"../lib/csg.js\"\r\n\r\nexport default class Model {\r\n\r\n constructor(THREE) {\r\n this._THREE = THREE;\r\n this._csg = null;\r\n }\r\n\r\n union(model) {\r\n return csgToModel(this._THREE, this._csg.union(model._csg));\r\n }\r\n\r\n subtract(model) {\r\n return csgToModel(this._THREE, this._csg.subtract(model._csg));\r\n }\r\n\r\n intersect(model) {\r\n return csgToModel(this._THREE, this._csg.intersect(model._csg));\r\n }\r\n\r\n applyMatrix4(matrix) {\r\n const mesh = this.build();\r\n mesh.geometry.applyMatrix4(matrix);\r\n return Model._fromMesh(this._THREE, mesh);\r\n }\r\n\r\n build() {\r\n return csgToMesh(this._THREE, this._csg);\r\n }\r\n\r\n static _fromMesh(THREE, mesh) {\r\n return meshToModel(THREE, mesh);\r\n }\r\n\r\n}\r\n\r\n\r\n\r\n// -\r\n// Construct a `Model` from CSG instance.\r\n//\r\nfunction csgToModel(THREE, csg) {\r\n const m = new Model(THREE);\r\n m._csg = csg;\r\n return m;\r\n}\r\n\r\n\r\n\r\n// -\r\n// Construct a `Model` from `THREE.Mesh`.\r\n// \r\nfunction meshToModel(THREE, mesh) {\r\n const m = new Model(THREE);\r\n m._csg = CSG.fromPolygons(meshToPolygons(THREE, mesh));\r\n return m;\r\n}\r\n\r\n\r\n\r\n// -\r\n// Construct `CSG.Polygon`s from a `THREE.Mesh`.\r\n//\r\nfunction meshToPolygons(THREE, mesh) {\r\n\r\n // Compute transformation matrix. The matrix is applied to geometry\r\n // during \"populate position attribute\" step. This will save one loop.\r\n const clone = mesh.clone();\r\n clone.updateMatrix();\r\n const { matrix } = clone;\r\n const shouldApplyMatrix = !matrix.equals(new THREE.Matrix4());\r\n\r\n // Array of `CSG.Polygon`.\r\n const polygons = [];\r\n\r\n const positions = mesh.geometry.attributes.position.array;\r\n const { normal, uv, color } = mesh.geometry.attributes;\r\n const normals = normal && normal.array;\r\n const uvs = uv && uv.array;\r\n const colors = color && color.array;\r\n const indices = mesh.geometry.index && mesh.geometry.index.array;\r\n const groups = mesh.geometry.groups;\r\n const vertexCount = indices ? indices.length : positions.length / 3;\r\n\r\n // Loop through vertices to create `CSG.Polygon` for each 3-vertices.\r\n // - Each `CSG.Polygon` contains `CSG.Vertex[]` and a `THREE.Material`.\r\n // - A `CSG.Vertex` must contain `.pos` (CSG.Vector) and optionally include \r\n // `normal` (CSG.Vector), `uv` (THREE.Vector2) and `color` (CSG.Vector). \r\n\r\n for (let i = 0; i < vertexCount; i += 3) {\r\n const vertices = [];\r\n for (let j = 0; j < 3; ++j) {\r\n const n = indices ? indices[i + j] : i + j;\r\n vertices.push(new CSG.Vertex(\r\n shouldApplyMatrix\r\n ? new THREE.Vector3().fromArray(positions, 3 * n).applyMatrix4(matrix)\r\n : positions.subarray(3 * n, 3 * n + 3),\r\n normals && normals.subarray(3 * n, 3 * n + 3),\r\n uvs && new THREE.Vector2().fromArray(uvs, 2 * n),\r\n colors && colors.subarray(3 * n, 3 * n + 3)\r\n ));\r\n }\r\n\r\n // Probing `Material` from `geom.groups` only makes sense if `mesh.material` is an array.\r\n if (Array.isArray(mesh.material)) {\r\n let material;\r\n for (const { start, count, materialIndex } of groups) {\r\n if (i >= start && i < start + count) {\r\n material = mesh.material[materialIndex];\r\n break;\r\n }\r\n }\r\n polygons.push(new CSG.Polygon(vertices, material));\r\n }\r\n else {\r\n // `mesh.material` is a single `Material`, it's safe to ignore `groups`.\r\n polygons.push(new CSG.Polygon(vertices, mesh.material));\r\n }\r\n }\r\n\r\n return polygons;\r\n}\r\n\r\n\r\n\r\n// -\r\n// Construct a `THREE.Mesh` from a CSG instance. The mesh will contain an indexed\r\n// BufferGeometry which buffer attributes are sorted by `Material`.\r\n// \r\nfunction csgToMesh(THREE, csg) {\r\n \r\n // Group vertices by `Material` and find vertex count in same loop. \r\n const polygons = csg.toPolygons();\r\n const matMap = new Map(); // Map\r\n let vertexCount = 0;\r\n for (const { vertices, shared: material } of polygons) {\r\n if (matMap.has(material)) {\r\n matMap.get(material).push(vertices);\r\n }\r\n else {\r\n matMap.set(material, [vertices]);\r\n }\r\n vertexCount += vertices.length;\r\n }\r\n\r\n // Alloc TypedArrays to hold buffer attributes data.\r\n const positions = new Float32Array(vertexCount * 3);\r\n const normals = new Float32Array(vertexCount * 3);\r\n const uvs = new Float32Array(vertexCount * 2);\r\n const colors = new Float32Array(vertexCount * 3);\r\n\r\n // Populate `.attributes`, `.index`, `.groups` and `mesh.material` in same loop.\r\n const geom = new THREE.BufferGeometry();\r\n const materials = [];\r\n const mesh = new THREE.Mesh(geom, materials);\r\n\r\n let start = 0;\r\n let count = 0; // indices count of the current render group.\r\n let materialIndex = 0;\r\n\r\n let positionsIdx = 0;\r\n let normalsIdx = 0;\r\n let uvsIdx = 0;\r\n let colorsIdx = 0;\r\n\r\n let someHasNormal; // truthy/falsy;\r\n let someHasUv; // ditto\r\n let someHasColor; // ditto\r\n\r\n const indices = []; // holding actual data of element index buffer\r\n let index = 0; // index number already used\r\n\r\n for (const [material, vertsArray] of matMap.entries()) {\r\n count = 0;\r\n for (const verts of vertsArray) {\r\n\r\n // Populate indices\r\n for (let i = 1, I = verts.length - 1; i < I; ++i) {\r\n indices.push(index, index + i, index + i + 1);\r\n }\r\n index += verts.length;\r\n count += (verts.length - 2) * 3;\r\n\r\n // Populate buffer attributes\r\n for (const { pos, normal, uv, color } of verts) {\r\n // `position`\r\n positions[positionsIdx++] = pos.x;\r\n positions[positionsIdx++] = pos.y;\r\n positions[positionsIdx++] = pos.z;\r\n \r\n // `normal`\r\n someHasNormal || (someHasNormal = normal);\r\n if (normal) {\r\n normals[normalsIdx++] = normal.x;\r\n normals[normalsIdx++] = normal.y;\r\n normals[normalsIdx++] = normal.z;\r\n }\r\n else {\r\n normalsIdx += 3;\r\n }\r\n\r\n // `uv`\r\n someHasUv || (someHasUv = uv);\r\n if (uv) {\r\n uvs[uvsIdx++] = uv.x;\r\n uvs[uvsIdx++] = uv.y;\r\n }\r\n else {\r\n uvsIdx += 2;\r\n }\r\n\r\n // `color`\r\n someHasColor || (someHasColor = color);\r\n if (color) {\r\n colors[colorsIdx++] = color.x;\r\n colors[colorsIdx++] = color.y;\r\n colors[colorsIdx++] = color.z;\r\n }\r\n else {\r\n colorsIdx += 3;\r\n }\r\n }\r\n }\r\n\r\n materials.push(material);\r\n geom.addGroup(start, count, materialIndex);\r\n start += count;\r\n materialIndex += 1;\r\n }\r\n\r\n // Set element index buffer.\r\n\r\n if (index <= 65535) {\r\n geom.index = new THREE.Uint16BufferAttribute(indices, 1);\r\n }\r\n else {\r\n console.warn(\"index > 65535\");\r\n geom.index = new THREE.Uint32BufferAttribute(indices, 1);\r\n }\r\n\r\n // Set buffer attributes.\r\n\r\n geom.setAttribute(\"position\", new THREE.BufferAttribute(positions, 3));\r\n\r\n if (someHasNormal) {\r\n geom.setAttribute(\"normal\", new THREE.BufferAttribute(normals, 3));\r\n }\r\n\r\n if (someHasUv) {\r\n geom.setAttribute(\"uv\", new THREE.BufferAttribute(uvs, 2));\r\n }\r\n\r\n if (someHasColor) {\r\n geom.setAttribute(\"color\", new THREE.BufferAttribute(colors, 3));\r\n }\r\n\r\n return mesh;\r\n}\r\n","import Model from \"./Model.js\"\r\n\r\nexport default class Modeller {\r\n\r\n constructor(THREE) {\r\n this._THREE = THREE;\r\n }\r\n\r\n model(mesh) {\r\n return Model._fromMesh(this._THREE, mesh);\r\n }\r\n\r\n}"],"names":["CSG","this","polygons","fromPolygons","csg","prototype","clone","map","p","toPolygons","union","a","Node","b","clipTo","invert","build","allPolygons","subtract","intersect","inverse","flip","Vector","x","y","z","arguments","length","negated","plus","minus","times","dividedBy","dot","lerp","t","Math","sqrt","unit","cross","Vertex","pos","normal","uv","color","interpolate","other","Plane","w","EPSILON","fromPoints","c","n","splitPolygon","polygon","coplanarFront","coplanarBack","front","back","polygonType","types","i","vertices","type","push","plane","f","j","ti","tj","vi","vj","v","Polygon","shared","reverse","node","temp","clipPolygons","slice","concat","bsp","Model","[object Object]","THREE","_THREE","_csg","model","csgToModel","matrix","mesh","geometry","applyMatrix4","_fromMesh","matMap","Map","vertexCount","material","has","get","set","positions","Float32Array","normals","uvs","colors","geom","BufferGeometry","materials","Mesh","someHasNormal","someHasUv","someHasColor","start","count","materialIndex","positionsIdx","normalsIdx","uvsIdx","colorsIdx","indices","index","vertsArray","entries","verts","I","addGroup","Uint16BufferAttribute","console","warn","Uint32BufferAttribute","setAttribute","BufferAttribute","csgToMesh","m","updateMatrix","shouldApplyMatrix","equals","Matrix4","attributes","position","array","groups","Vector3","fromArray","subarray","Vector2","Array","isArray","meshToPolygons","meshToModel"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"lib.esm.js","sources":["../lib/csg.js","../src/Model.js","../src/index.js"],"sourcesContent":["// Constructive Solid Geometry (CSG) is a modeling technique that uses Boolean\r\n// operations like union and intersection to combine 3D solids. This library\r\n// implements CSG operations on meshes elegantly and concisely using BSP trees,\r\n// and is meant to serve as an easily understandable implementation of the\r\n// algorithm. All edge cases involving overlapping coplanar polygons in both\r\n// solids are correctly handled.\r\n// \r\n// Example usage:\r\n// \r\n// var cube = CSG.cube();\r\n// var sphere = CSG.sphere({ radius: 1.3 });\r\n// var polygons = cube.subtract(sphere).toPolygons();\r\n// \r\n// ## Implementation Details\r\n// \r\n// All CSG operations are implemented in terms of two functions, `clipTo()` and\r\n// `invert()`, which remove parts of a BSP tree inside another BSP tree and swap\r\n// solid and empty space, respectively. To find the union of `a` and `b`, we\r\n// want to remove everything in `a` inside `b` and everything in `b` inside `a`,\r\n// then combine polygons from `a` and `b` into one solid:\r\n// \r\n// a.clipTo(b);\r\n// b.clipTo(a);\r\n// a.build(b.allPolygons());\r\n// \r\n// The only tricky part is handling overlapping coplanar polygons in both trees.\r\n// The code above keeps both copies, but we need to keep them in one tree and\r\n// remove them in the other tree. To remove them from `b` we can clip the\r\n// inverse of `b` against `a`. The code for union now looks like this:\r\n// \r\n// a.clipTo(b);\r\n// b.clipTo(a);\r\n// b.invert();\r\n// b.clipTo(a);\r\n// b.invert();\r\n// a.build(b.allPolygons());\r\n// \r\n// Subtraction and intersection naturally follow from set operations. If\r\n// union is `A | B`, subtraction is `A - B = ~(~A | B)` and intersection is\r\n// `A & B = ~(~A | ~B)` where `~` is the complement operator.\r\n// \r\n// ## License\r\n// \r\n// Copyright (c) 2011 Evan Wallace (http://madebyevan.com/), under the MIT license.\r\n\r\n// # class CSG\r\n\r\n// Holds a binary space partition tree representing a 3D solid. Two solids can\r\n// be combined using the `union()`, `subtract()`, and `intersect()` methods.\r\n\r\nexport default function CSG() {\r\n this.polygons = [];\r\n};\r\n\r\n// Construct a CSG solid from a list of `CSG.Polygon` instances.\r\nCSG.fromPolygons = function (polygons) {\r\n var csg = new CSG();\r\n csg.polygons = polygons;\r\n return csg;\r\n};\r\n\r\nCSG.prototype = {\r\n clone: function () {\r\n var csg = new CSG();\r\n csg.polygons = this.polygons.map(function (p) { return p.clone(); });\r\n return csg;\r\n },\r\n\r\n toPolygons: function () {\r\n return this.polygons;\r\n },\r\n\r\n // Return a new CSG solid representing space in either this solid or in the\r\n // solid `csg`. Neither this solid nor the solid `csg` are modified.\r\n // \r\n // A.union(B)\r\n // \r\n // +-------+ +-------+\r\n // | | | |\r\n // | A | | |\r\n // | +--+----+ = | +----+\r\n // +----+--+ | +----+ |\r\n // | B | | |\r\n // | | | |\r\n // +-------+ +-------+\r\n // \r\n union: function (csg) {\r\n var a = new CSG.Node(this.clone().polygons);\r\n var b = new CSG.Node(csg.clone().polygons);\r\n a.clipTo(b);\r\n b.clipTo(a);\r\n b.invert();\r\n b.clipTo(a);\r\n b.invert();\r\n a.build(b.allPolygons());\r\n return CSG.fromPolygons(a.allPolygons());\r\n },\r\n\r\n // Return a new CSG solid representing space in this solid but not in the\r\n // solid `csg`. Neither this solid nor the solid `csg` are modified.\r\n // \r\n // A.subtract(B)\r\n // \r\n // +-------+ +-------+\r\n // | | | |\r\n // | A | | |\r\n // | +--+----+ = | +--+\r\n // +----+--+ | +----+\r\n // | B |\r\n // | |\r\n // +-------+\r\n // \r\n subtract: function (csg) {\r\n var a = new CSG.Node(this.clone().polygons);\r\n var b = new CSG.Node(csg.clone().polygons);\r\n a.invert();\r\n a.clipTo(b);\r\n b.clipTo(a);\r\n b.invert();\r\n b.clipTo(a);\r\n b.invert();\r\n a.build(b.allPolygons());\r\n a.invert();\r\n return CSG.fromPolygons(a.allPolygons());\r\n },\r\n\r\n // Return a new CSG solid representing space both this solid and in the\r\n // solid `csg`. Neither this solid nor the solid `csg` are modified.\r\n // \r\n // A.intersect(B)\r\n // \r\n // +-------+\r\n // | |\r\n // | A |\r\n // | +--+----+ = +--+\r\n // +----+--+ | +--+\r\n // | B |\r\n // | |\r\n // +-------+\r\n // \r\n intersect: function (csg) {\r\n var a = new CSG.Node(this.clone().polygons);\r\n var b = new CSG.Node(csg.clone().polygons);\r\n a.invert();\r\n b.clipTo(a);\r\n b.invert();\r\n a.clipTo(b);\r\n b.clipTo(a);\r\n a.build(b.allPolygons());\r\n a.invert();\r\n return CSG.fromPolygons(a.allPolygons());\r\n },\r\n\r\n // Return a new CSG solid with solid and empty space switched. This solid is\r\n // not modified.\r\n inverse: function () {\r\n var csg = this.clone();\r\n csg.polygons.map(function (p) { p.flip(); });\r\n return csg;\r\n }\r\n};\r\n\r\n// // Construct an axis-aligned solid cuboid. Optional parameters are `center` and\r\n// // `radius`, which default to `[0, 0, 0]` and `[1, 1, 1]`. The radius can be\r\n// // specified using a single number or a list of three numbers, one for each axis.\r\n// // \r\n// // Example code:\r\n// // \r\n// // var cube = CSG.cube({\r\n// // center: [0, 0, 0],\r\n// // radius: 1\r\n// // });\r\n// CSG.cube = function(options) {\r\n// options = options || {};\r\n// var c = new CSG.Vector(options.center || [0, 0, 0]);\r\n// var r = !options.radius ? [1, 1, 1] : options.radius.length ?\r\n// options.radius : [options.radius, options.radius, options.radius];\r\n// return CSG.fromPolygons([\r\n// [[0, 4, 6, 2], [-1, 0, 0]],\r\n// [[1, 3, 7, 5], [+1, 0, 0]],\r\n// [[0, 1, 5, 4], [0, -1, 0]],\r\n// [[2, 6, 7, 3], [0, +1, 0]],\r\n// [[0, 2, 3, 1], [0, 0, -1]],\r\n// [[4, 5, 7, 6], [0, 0, +1]]\r\n// ].map(function(info) {\r\n// return new CSG.Polygon(info[0].map(function(i) {\r\n// var pos = new CSG.Vector(\r\n// c.x + r[0] * (2 * !!(i & 1) - 1),\r\n// c.y + r[1] * (2 * !!(i & 2) - 1),\r\n// c.z + r[2] * (2 * !!(i & 4) - 1)\r\n// );\r\n// return new CSG.Vertex(pos, new CSG.Vector(info[1]));\r\n// }));\r\n// }));\r\n// };\r\n\r\n// // Construct a solid sphere. Optional parameters are `center`, `radius`,\r\n// // `slices`, and `stacks`, which default to `[0, 0, 0]`, `1`, `16`, and `8`.\r\n// // The `slices` and `stacks` parameters control the tessellation along the\r\n// // longitude and latitude directions.\r\n// // \r\n// // Example usage:\r\n// // \r\n// // var sphere = CSG.sphere({\r\n// // center: [0, 0, 0],\r\n// // radius: 1,\r\n// // slices: 16,\r\n// // stacks: 8\r\n// // });\r\n// CSG.sphere = function(options) {\r\n// options = options || {};\r\n// var c = new CSG.Vector(options.center || [0, 0, 0]);\r\n// var r = options.radius || 1;\r\n// var slices = options.slices || 16;\r\n// var stacks = options.stacks || 8;\r\n// var polygons = [], vertices;\r\n// function vertex(theta, phi) {\r\n// theta *= Math.PI * 2;\r\n// phi *= Math.PI;\r\n// var dir = new CSG.Vector(\r\n// Math.cos(theta) * Math.sin(phi),\r\n// Math.cos(phi),\r\n// Math.sin(theta) * Math.sin(phi)\r\n// );\r\n// vertices.push(new CSG.Vertex(c.plus(dir.times(r)), dir));\r\n// }\r\n// for (var i = 0; i < slices; i++) {\r\n// for (var j = 0; j < stacks; j++) {\r\n// vertices = [];\r\n// vertex(i / slices, j / stacks);\r\n// if (j > 0) vertex((i + 1) / slices, j / stacks);\r\n// if (j < stacks - 1) vertex((i + 1) / slices, (j + 1) / stacks);\r\n// vertex(i / slices, (j + 1) / stacks);\r\n// polygons.push(new CSG.Polygon(vertices));\r\n// }\r\n// }\r\n// return CSG.fromPolygons(polygons);\r\n// };\r\n\r\n// // Construct a solid cylinder. Optional parameters are `start`, `end`,\r\n// // `radius`, and `slices`, which default to `[0, -1, 0]`, `[0, 1, 0]`, `1`, and\r\n// // `16`. The `slices` parameter controls the tessellation.\r\n// // \r\n// // Example usage:\r\n// // \r\n// // var cylinder = CSG.cylinder({\r\n// // start: [0, -1, 0],\r\n// // end: [0, 1, 0],\r\n// // radius: 1,\r\n// // slices: 16\r\n// // });\r\n// CSG.cylinder = function(options) {\r\n// options = options || {};\r\n// var s = new CSG.Vector(options.start || [0, -1, 0]);\r\n// var e = new CSG.Vector(options.end || [0, 1, 0]);\r\n// var ray = e.minus(s);\r\n// var r = options.radius || 1;\r\n// var slices = options.slices || 16;\r\n// var axisZ = ray.unit(), isY = (Math.abs(axisZ.y) > 0.5);\r\n// var axisX = new CSG.Vector(isY, !isY, 0).cross(axisZ).unit();\r\n// var axisY = axisX.cross(axisZ).unit();\r\n// var start = new CSG.Vertex(s, axisZ.negated());\r\n// var end = new CSG.Vertex(e, axisZ.unit());\r\n// var polygons = [];\r\n// function point(stack, slice, normalBlend) {\r\n// var angle = slice * Math.PI * 2;\r\n// var out = axisX.times(Math.cos(angle)).plus(axisY.times(Math.sin(angle)));\r\n// var pos = s.plus(ray.times(stack)).plus(out.times(r));\r\n// var normal = out.times(1 - Math.abs(normalBlend)).plus(axisZ.times(normalBlend));\r\n// return new CSG.Vertex(pos, normal);\r\n// }\r\n// for (var i = 0; i < slices; i++) {\r\n// var t0 = i / slices, t1 = (i + 1) / slices;\r\n// polygons.push(new CSG.Polygon([start, point(0, t0, -1), point(0, t1, -1)]));\r\n// polygons.push(new CSG.Polygon([point(0, t1, 0), point(0, t0, 0), point(1, t0, 0), point(1, t1, 0)]));\r\n// polygons.push(new CSG.Polygon([end, point(1, t1, 1), point(1, t0, 1)]));\r\n// }\r\n// return CSG.fromPolygons(polygons);\r\n// };\r\n\r\n// # class Vector\r\n\r\n// Represents a 3D vector.\r\n// \r\n// Example usage:\r\n// \r\n// new CSG.Vector(1, 2, 3);\r\n// new CSG.Vector([1, 2, 3]);\r\n// new CSG.Vector({ x: 1, y: 2, z: 3 });\r\n\r\nCSG.Vector = function (x, y, z) {\r\n if (arguments.length == 3) {\r\n this.x = x;\r\n this.y = y;\r\n this.z = z;\r\n } else if ('x' in x) {\r\n this.x = x.x;\r\n this.y = x.y;\r\n this.z = x.z;\r\n } else {\r\n this.x = x[0];\r\n this.y = x[1];\r\n this.z = x[2];\r\n }\r\n};\r\n\r\nCSG.Vector.prototype = {\r\n clone: function () {\r\n return new CSG.Vector(this.x, this.y, this.z);\r\n },\r\n\r\n negated: function () {\r\n return new CSG.Vector(-this.x, -this.y, -this.z);\r\n },\r\n\r\n plus: function (a) {\r\n return new CSG.Vector(this.x + a.x, this.y + a.y, this.z + a.z);\r\n },\r\n\r\n minus: function (a) {\r\n return new CSG.Vector(this.x - a.x, this.y - a.y, this.z - a.z);\r\n },\r\n\r\n times: function (a) {\r\n return new CSG.Vector(this.x * a, this.y * a, this.z * a);\r\n },\r\n\r\n dividedBy: function (a) {\r\n return new CSG.Vector(this.x / a, this.y / a, this.z / a);\r\n },\r\n\r\n dot: function (a) {\r\n return this.x * a.x + this.y * a.y + this.z * a.z;\r\n },\r\n\r\n lerp: function (a, t) {\r\n return this.plus(a.minus(this).times(t));\r\n },\r\n\r\n length: function () {\r\n return Math.sqrt(this.dot(this));\r\n },\r\n\r\n unit: function () {\r\n return this.dividedBy(this.length());\r\n },\r\n\r\n cross: function (a) {\r\n return new CSG.Vector(\r\n this.y * a.z - this.z * a.y,\r\n this.z * a.x - this.x * a.z,\r\n this.x * a.y - this.y * a.x\r\n );\r\n }\r\n};\r\n\r\n// # class Vertex\r\n\r\n// Represents a vertex of a polygon. Use your own vertex class instead of this\r\n// one to provide additional features like texture coordinates and vertex\r\n// colors. Custom vertex classes need to provide a `pos` property and `clone()`,\r\n// `flip()`, and `interpolate()` methods that behave analogous to the ones\r\n// defined by `CSG.Vertex`. This class provides `normal` so convenience\r\n// functions like `CSG.sphere()` can return a smooth vertex normal, but `normal`\r\n// is not used anywhere else.\r\n\r\nCSG.Vertex = function (pos, normal, uv, color) {\r\n this.pos = new CSG.Vector(pos);\r\n this.normal = normal && new CSG.Vector(normal);\r\n this.uv = uv && uv.clone(); // uv is a `THREE.Vector2`.\r\n this.color = color && new CSG.Vector(color);\r\n};\r\n\r\nCSG.Vertex.prototype = {\r\n clone: function () {\r\n return new CSG.Vertex(\r\n this.pos.clone(),\r\n this.normal && this.normal.clone(),\r\n this.uv && this.uv.clone(),\r\n this.color && this.color.clone()\r\n );\r\n },\r\n\r\n // Invert all orientation-specific data (e.g. vertex normal). Called when the\r\n // orientation of a polygon is flipped.\r\n flip: function () {\r\n if (this.normal) {\r\n this.normal = this.normal.negated();\r\n }\r\n },\r\n\r\n // Create a new vertex between this vertex and `other` by linearly\r\n // interpolating all properties using a parameter of `t`. Subclasses should\r\n // override this to interpolate additional properties.\r\n interpolate: function (other, t) {\r\n return new CSG.Vertex(\r\n this.pos.lerp(other.pos, t),\r\n this.normal && other.normal && this.normal.lerp(other.normal, t),\r\n this.uv && other.uv && this.uv.clone().lerp(other.uv, t),\r\n this.color && other.color && this.color.lerp(other.color, t),\r\n );\r\n }\r\n};\r\n\r\n// # class Plane\r\n\r\n// Represents a plane in 3D space.\r\n\r\nCSG.Plane = function (normal, w) {\r\n this.normal = normal;\r\n this.w = w;\r\n};\r\n\r\n// `CSG.Plane.EPSILON` is the tolerance used by `splitPolygon()` to decide if a\r\n// point is on the plane.\r\nCSG.Plane.EPSILON = 1e-5;\r\n\r\nCSG.Plane.fromPoints = function (a, b, c) {\r\n var n = b.minus(a).cross(c.minus(a)).unit();\r\n return new CSG.Plane(n, n.dot(a));\r\n};\r\n\r\nCSG.Plane.prototype = {\r\n clone: function () {\r\n return new CSG.Plane(this.normal.clone(), this.w);\r\n },\r\n\r\n flip: function () {\r\n this.normal = this.normal.negated();\r\n this.w = -this.w;\r\n },\r\n\r\n // Split `polygon` by this plane if needed, then put the polygon or polygon\r\n // fragments in the appropriate lists. Coplanar polygons go into either\r\n // `coplanarFront` or `coplanarBack` depending on their orientation with\r\n // respect to this plane. Polygons in front or in back of this plane go into\r\n // either `front` or `back`.\r\n splitPolygon: function (polygon, coplanarFront, coplanarBack, front, back) {\r\n var COPLANAR = 0;\r\n var FRONT = 1;\r\n var BACK = 2;\r\n var SPANNING = 3;\r\n\r\n // Classify each point as well as the entire polygon into one of the above\r\n // four classes.\r\n var polygonType = 0;\r\n var types = [];\r\n for (var i = 0; i < polygon.vertices.length; i++) {\r\n var t = this.normal.dot(polygon.vertices[i].pos) - this.w;\r\n var type = (t < -CSG.Plane.EPSILON) ? BACK : (t > CSG.Plane.EPSILON) ? FRONT : COPLANAR;\r\n polygonType |= type;\r\n types.push(type);\r\n }\r\n\r\n // Put the polygon in the correct list, splitting it when necessary.\r\n switch (polygonType) {\r\n case COPLANAR:\r\n (this.normal.dot(polygon.plane.normal) > 0 ? coplanarFront : coplanarBack).push(polygon);\r\n break;\r\n case FRONT:\r\n front.push(polygon);\r\n break;\r\n case BACK:\r\n back.push(polygon);\r\n break;\r\n case SPANNING:\r\n var f = [], b = [];\r\n for (var i = 0; i < polygon.vertices.length; i++) {\r\n var j = (i + 1) % polygon.vertices.length;\r\n var ti = types[i], tj = types[j];\r\n var vi = polygon.vertices[i], vj = polygon.vertices[j];\r\n if (ti != BACK) f.push(vi);\r\n if (ti != FRONT) b.push(ti != BACK ? vi.clone() : vi);\r\n if ((ti | tj) == SPANNING) {\r\n var t = (this.w - this.normal.dot(vi.pos)) / this.normal.dot(vj.pos.minus(vi.pos));\r\n var v = vi.interpolate(vj, t);\r\n f.push(v);\r\n b.push(v.clone());\r\n }\r\n }\r\n if (f.length >= 3) front.push(new CSG.Polygon(f, polygon.shared));\r\n if (b.length >= 3) back.push(new CSG.Polygon(b, polygon.shared));\r\n break;\r\n }\r\n }\r\n};\r\n\r\n// # class Polygon\r\n\r\n// Represents a convex polygon. The vertices used to initialize a polygon must\r\n// be coplanar and form a convex loop. They do not have to be `CSG.Vertex`\r\n// instances but they must behave similarly (duck typing can be used for\r\n// customization).\r\n// \r\n// Each convex polygon has a `shared` property, which is shared between all\r\n// polygons that are clones of each other or were split from the same polygon.\r\n// This can be used to define per-polygon properties (such as surface color).\r\n\r\nCSG.Polygon = function (vertices, shared) {\r\n this.vertices = vertices;\r\n this.shared = shared;\r\n this.plane = CSG.Plane.fromPoints(vertices[0].pos, vertices[1].pos, vertices[2].pos);\r\n};\r\n\r\nCSG.Polygon.prototype = {\r\n clone: function () {\r\n var vertices = this.vertices.map(function (v) { return v.clone(); });\r\n return new CSG.Polygon(vertices, this.shared);\r\n },\r\n\r\n flip: function () {\r\n this.vertices.reverse().map(function (v) { v.flip(); });\r\n this.plane.flip();\r\n }\r\n};\r\n\r\n// # class Node\r\n\r\n// Holds a node in a BSP tree. A BSP tree is built from a collection of polygons\r\n// by picking a polygon to split along. That polygon (and all other coplanar\r\n// polygons) are added directly to that node and the other polygons are added to\r\n// the front and/or back subtrees. This is not a leafy BSP tree since there is\r\n// no distinction between internal and leaf nodes.\r\n\r\nCSG.Node = function (polygons) {\r\n this.plane = null;\r\n this.front = null;\r\n this.back = null;\r\n this.polygons = [];\r\n if (polygons) this.build(polygons);\r\n};\r\n\r\nCSG.Node.prototype = {\r\n clone: function () {\r\n var node = new CSG.Node();\r\n node.plane = this.plane && this.plane.clone();\r\n node.front = this.front && this.front.clone();\r\n node.back = this.back && this.back.clone();\r\n node.polygons = this.polygons.map(function (p) { return p.clone(); });\r\n return node;\r\n },\r\n\r\n // Convert solid space to empty space and empty space to solid space.\r\n invert: function () {\r\n for (var i = 0; i < this.polygons.length; i++) {\r\n this.polygons[i].flip();\r\n }\r\n this.plane.flip();\r\n if (this.front) this.front.invert();\r\n if (this.back) this.back.invert();\r\n var temp = this.front;\r\n this.front = this.back;\r\n this.back = temp;\r\n },\r\n\r\n // Recursively remove all polygons in `polygons` that are inside this BSP\r\n // tree.\r\n clipPolygons: function (polygons) {\r\n if (!this.plane) return polygons.slice();\r\n var front = [], back = [];\r\n for (var i = 0; i < polygons.length; i++) {\r\n this.plane.splitPolygon(polygons[i], front, back, front, back);\r\n }\r\n if (this.front) front = this.front.clipPolygons(front);\r\n if (this.back) back = this.back.clipPolygons(back);\r\n else back = [];\r\n return front.concat(back);\r\n },\r\n\r\n // Remove all polygons in this BSP tree that are inside the other BSP tree\r\n // `bsp`.\r\n clipTo: function (bsp) {\r\n this.polygons = bsp.clipPolygons(this.polygons);\r\n if (this.front) this.front.clipTo(bsp);\r\n if (this.back) this.back.clipTo(bsp);\r\n },\r\n\r\n // Return a list of all polygons in this BSP tree.\r\n allPolygons: function () {\r\n var polygons = this.polygons.slice();\r\n if (this.front) polygons = polygons.concat(this.front.allPolygons());\r\n if (this.back) polygons = polygons.concat(this.back.allPolygons());\r\n return polygons;\r\n },\r\n\r\n // Build a BSP tree out of `polygons`. When called on an existing tree, the\r\n // new polygons are filtered down to the bottom of the tree and become new\r\n // nodes there. Each set of polygons is partitioned using the first polygon\r\n // (no heuristic is used to pick a good split).\r\n build: function (polygons) {\r\n if (!polygons.length) return;\r\n if (!this.plane) this.plane = polygons[0].plane.clone();\r\n var front = [], back = [];\r\n for (var i = 0; i < polygons.length; i++) {\r\n this.plane.splitPolygon(polygons[i], this.polygons, this.polygons, front, back);\r\n }\r\n if (front.length) {\r\n if (!this.front) this.front = new CSG.Node();\r\n this.front.build(front);\r\n }\r\n if (back.length) {\r\n if (!this.back) this.back = new CSG.Node();\r\n this.back.build(back);\r\n }\r\n }\r\n};\r\n","import CSG from \"../lib/csg.js\"\r\n\r\nexport default class Model {\r\n\r\n constructor(THREE) {\r\n this._THREE = THREE;\r\n this._csg = null;\r\n }\r\n\r\n union(model) {\r\n return csgToModel(this._THREE, this._csg.union(model._csg));\r\n }\r\n\r\n subtract(model) {\r\n return csgToModel(this._THREE, this._csg.subtract(model._csg));\r\n }\r\n\r\n intersect(model) {\r\n return csgToModel(this._THREE, this._csg.intersect(model._csg));\r\n }\r\n\r\n applyMatrix4(matrix) {\r\n const mesh = this.build();\r\n mesh.geometry.applyMatrix4(matrix);\r\n return Model._fromMesh(this._THREE, mesh);\r\n }\r\n\r\n build() {\r\n return csgToMesh(this._THREE, this._csg);\r\n }\r\n\r\n static _fromMesh(THREE, mesh) {\r\n return meshToModel(THREE, mesh);\r\n }\r\n\r\n}\r\n\r\n\r\n\r\n// -\r\n// Construct a `Model` from CSG instance.\r\n//\r\nfunction csgToModel(THREE, csg) {\r\n const m = new Model(THREE);\r\n m._csg = csg;\r\n return m;\r\n}\r\n\r\n\r\n\r\n// -\r\n// Construct a `Model` from `THREE.Mesh`.\r\n// \r\nfunction meshToModel(THREE, mesh) {\r\n const m = new Model(THREE);\r\n m._csg = CSG.fromPolygons(meshToPolygons(THREE, mesh));\r\n return m;\r\n}\r\n\r\n\r\n\r\n// -\r\n// Construct `CSG.Polygon`s from a `THREE.Mesh`.\r\n//\r\nfunction meshToPolygons(THREE, mesh) {\r\n\r\n // Compute transformation matrix. The matrix is applied to geometry\r\n // during \"populate position attribute\" step. This will save one loop.\r\n const clone = mesh.clone();\r\n clone.updateMatrix();\r\n const { matrix } = clone;\r\n const shouldApplyMatrix = !matrix.equals(new THREE.Matrix4());\r\n\r\n // Array of `CSG.Polygon`.\r\n const polygons = [];\r\n\r\n const positions = mesh.geometry.attributes.position.array;\r\n const { normal, uv, color } = mesh.geometry.attributes;\r\n const normals = normal && normal.array;\r\n const uvs = uv && uv.array;\r\n const colors = color && color.array;\r\n const indices = mesh.geometry.index && mesh.geometry.index.array;\r\n const count = indices ? indices.length : positions.length / 3;\r\n\r\n // Populate polygons; create `CSG.Polygon` for each 3-vertices.\r\n // - `CSG.Polygon` contains `CSG.Vertex[]` and `THREE.Material`.\r\n // - `CSG.Vertex` must contain `.pos` (CSG.Vector) and optionally include \r\n // `normal` (CSG.Vector), `uv` (THREE.Vector2) and `color` (CSG.Vector). \r\n\r\n const groups = Array.isArray(mesh.material)\r\n ? mesh.geometry.groups\r\n : [{ start: 0, count, materialIndex: 0 }];\r\n\r\n for (const { start, count, materialIndex } of groups) {\r\n const material = Array.isArray(mesh.material) \r\n ? mesh.material[materialIndex]\r\n : mesh.material; \r\n for (let i = start; i < start + count; i += 3) {\r\n const vertices = [];\r\n for (let j = 0; j < 3; ++j) {\r\n const n = indices ? indices[i + j] : i + j;\r\n vertices.push(new CSG.Vertex(\r\n shouldApplyMatrix\r\n ? new THREE.Vector3().fromArray(positions, 3 * n).applyMatrix4(matrix)\r\n : positions.subarray(3 * n, 3 * n + 3),\r\n normals && normals.subarray(3 * n, 3 * n + 3),\r\n uvs && new THREE.Vector2().fromArray(uvs, 2 * n),\r\n colors && colors.subarray(3 * n, 3 * n + 3)\r\n ));\r\n }\r\n polygons.push(new CSG.Polygon(vertices, material));\r\n }\r\n }\r\n\r\n return polygons;\r\n}\r\n\r\n\r\n\r\n// -\r\n// Construct a `THREE.Mesh` from a CSG instance. The mesh will contain an indexed\r\n// BufferGeometry which buffer attributes are sorted by `Material`.\r\n// \r\nfunction csgToMesh(THREE, csg) {\r\n\r\n // Group vertices by `Material` and find vertex count in same loop. \r\n const polygons = csg.toPolygons();\r\n const matMap = new Map(); // Map\r\n let vertexCount = 0;\r\n for (const { vertices, shared: material } of polygons) {\r\n if (matMap.has(material)) {\r\n matMap.get(material).push(vertices);\r\n }\r\n else {\r\n matMap.set(material, [vertices]);\r\n }\r\n vertexCount += vertices.length;\r\n }\r\n\r\n // Alloc TypedArrays to hold buffer attributes data.\r\n const positions = new Float32Array(vertexCount * 3);\r\n const normals = new Float32Array(vertexCount * 3);\r\n const uvs = new Float32Array(vertexCount * 2);\r\n const colors = new Float32Array(vertexCount * 3);\r\n\r\n // Result mesh.\r\n const geom = new THREE.BufferGeometry();\r\n const materials = [];\r\n const mesh = new THREE.Mesh(geom, materials);\r\n \r\n // Populate geometry (`geom.attributes`, `geom.index`, `geom.groups`) and \r\n // meterials (`mesh.material`) in same loop.\r\n let start = 0;\r\n let count = 0; // indices count of the current render group.\r\n let materialIndex = 0;\r\n\r\n let positionsIdx = 0;\r\n let normalsIdx = 0;\r\n let uvsIdx = 0;\r\n let colorsIdx = 0;\r\n\r\n let someHasNormal; // truthy/falsy;\r\n let someHasUv; // ditto\r\n let someHasColor; // ditto\r\n\r\n const indices = []; // holding actual data of element index buffer\r\n let index = 0; // index number already used\r\n\r\n for (const [material, vertsArray] of matMap.entries()) {\r\n count = 0;\r\n for (const verts of vertsArray) {\r\n\r\n // Populate indices\r\n for (let i = 1, I = verts.length - 1; i < I; ++i) {\r\n indices.push(index, index + i, index + i + 1);\r\n }\r\n index += verts.length;\r\n count += (verts.length - 2) * 3;\r\n\r\n // Populate buffer attributes\r\n for (const { pos, normal, uv, color } of verts) {\r\n // `position`\r\n positions[positionsIdx++] = pos.x;\r\n positions[positionsIdx++] = pos.y;\r\n positions[positionsIdx++] = pos.z;\r\n\r\n // `normal`\r\n someHasNormal || (someHasNormal = normal);\r\n if (normal) {\r\n normals[normalsIdx++] = normal.x;\r\n normals[normalsIdx++] = normal.y;\r\n normals[normalsIdx++] = normal.z;\r\n }\r\n else {\r\n normalsIdx += 3;\r\n }\r\n\r\n // `uv`\r\n someHasUv || (someHasUv = uv);\r\n if (uv) {\r\n uvs[uvsIdx++] = uv.x;\r\n uvs[uvsIdx++] = uv.y;\r\n }\r\n else {\r\n uvsIdx += 2;\r\n }\r\n\r\n // `color`\r\n someHasColor || (someHasColor = color);\r\n if (color) {\r\n colors[colorsIdx++] = color.x;\r\n colors[colorsIdx++] = color.y;\r\n colors[colorsIdx++] = color.z;\r\n }\r\n else {\r\n colorsIdx += 3;\r\n }\r\n }\r\n }\r\n\r\n materials.push(material);\r\n geom.addGroup(start, count, materialIndex);\r\n start += count;\r\n materialIndex += 1;\r\n }\r\n\r\n // Set element index buffer.\r\n\r\n if (index <= 65535) {\r\n geom.index = new THREE.Uint16BufferAttribute(indices, 1);\r\n }\r\n else {\r\n console.warn(\"index > 65535\");\r\n geom.index = new THREE.Uint32BufferAttribute(indices, 1);\r\n }\r\n\r\n // Set buffer attributes.\r\n\r\n geom.setAttribute(\"position\", new THREE.BufferAttribute(positions, 3));\r\n\r\n if (someHasNormal) {\r\n geom.setAttribute(\"normal\", new THREE.BufferAttribute(normals, 3));\r\n }\r\n\r\n if (someHasUv) {\r\n geom.setAttribute(\"uv\", new THREE.BufferAttribute(uvs, 2));\r\n }\r\n\r\n if (someHasColor) {\r\n geom.setAttribute(\"color\", new THREE.BufferAttribute(colors, 3));\r\n }\r\n\r\n return mesh;\r\n}\r\n","import Model from \"./Model.js\"\r\n\r\nexport default class Modeller {\r\n\r\n constructor(THREE) {\r\n this._THREE = THREE;\r\n }\r\n\r\n model(mesh) {\r\n return Model._fromMesh(this._THREE, mesh);\r\n }\r\n\r\n}"],"names":["CSG","this","polygons","fromPolygons","csg","prototype","clone","map","p","toPolygons","union","a","Node","b","clipTo","invert","build","allPolygons","subtract","intersect","inverse","flip","Vector","x","y","z","arguments","length","negated","plus","minus","times","dividedBy","dot","lerp","t","Math","sqrt","unit","cross","Vertex","pos","normal","uv","color","interpolate","other","Plane","w","EPSILON","fromPoints","c","n","splitPolygon","polygon","coplanarFront","coplanarBack","front","back","polygonType","types","i","vertices","type","push","plane","f","j","ti","tj","vi","vj","v","Polygon","shared","reverse","node","temp","clipPolygons","slice","concat","bsp","Model","[object Object]","THREE","_THREE","_csg","model","csgToModel","matrix","mesh","geometry","applyMatrix4","_fromMesh","matMap","Map","vertexCount","material","has","get","set","positions","Float32Array","normals","uvs","colors","geom","BufferGeometry","materials","Mesh","someHasNormal","someHasUv","someHasColor","start","count","materialIndex","positionsIdx","normalsIdx","uvsIdx","colorsIdx","indices","index","vertsArray","entries","verts","I","addGroup","Uint16BufferAttribute","console","warn","Uint32BufferAttribute","setAttribute","BufferAttribute","csgToMesh","m","updateMatrix","shouldApplyMatrix","equals","Matrix4","attributes","position","array","groups","Array","isArray","Vector3","fromArray","subarray","Vector2","meshToPolygons","meshToModel"],"mappings":"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"} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index ca1a0cf..cf8cf0b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "three-csg-modeller", - "version": "0.1.7", + "version": "0.1.8", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index af406a7..4567a7e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "three-csg-modeller", - "version": "0.1.7", + "version": "0.1.8", "description": "Solid mesh modeling for three.js", "repository": "github:ycw/three-csg-modeller", "author": "ycw (https://github.com/ycw)",