UNPKG

mesh-simplifier

Version:

Collection of mesh simplification methods written in Typescript

11 lines (10 loc) 11.8 kB
/* Copyright (c) 2020-present NAVER Corp. name: mesh-simplifier license: MIT author: NAVER Corp. repository: https://github.com/naver/mesh-simplifier version: 1.0.1 */ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("three")):"function"==typeof define&&define.amd?define(["three"],e):(t="undefined"!=typeof globalThis?globalThis:t||self).MeshSimplifier=e(t.THREE)}(this,function(f){"use strict";var t=function(){return(t=Object.assign||function(t){for(var e,r=1,n=arguments.length;r<n;r++)for(var i in e=arguments[r])Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t}).apply(this,arguments)},x=function(){function r(t,e,r){void 0===e&&(e=0),void 0===r&&(r=0),this.x=t=void 0===t?0:t,this.y=e,this.z=r}var t=r.prototype;return r.addVectors=function(t,e){return(new r).copy(t).add(e)},r.subVectors=function(t,e){return(new r).copy(t).sub(e)},t.copy=function(t){return this.x=t.x,this.y=t.y,this.z=t.z,this},t.add=function(t){return this.x+=t.x,this.y+=t.y,this.z+=t.z,this},t.sub=function(t){return this.x-=t.x,this.y-=t.y,this.z-=t.z,this},t.dot=function(t){var e=this,r=e.x,n=e.y,e=e.z;return r*t.x+n*t.y+e*t.z},t.cross=function(t){var e=this,r=e.x,n=e.y,i=e.z,s=t.x,e=t.y,t=t.z;return this.x=n*t-i*e,this.y=i*s-r*t,this.z=r*e-n*s,this},t.normalize=function(){var t=this.length();return 0<t&&(this.x*=t=1/t,this.y*=t,this.z*=t),this},t.length=function(){var t=this.x,e=this.y,r=this.z;return Math.sqrt(t*t+e*e+r*r)},t.scaleSclar=function(t){return this.x*=t,this.y*=t,this.z*=t,this},r}(),r=function(){return function(t){this.originalIndex=t,this.v=[0,0,0],this.err=[0,0,0,0],this.deleted=!1,this.dirty=!1,this.n=new x}}(),l=function(){function i(t,e,r,n,i,s,o,a,u,c){void 0===t&&(t=0),void 0===e&&(e=0),void 0===r&&(r=0),void 0===n&&(n=0),void 0===i&&(i=0),void 0===s&&(s=0),void 0===o&&(o=0),void 0===a&&(a=0),void 0===u&&(u=0),void 0===c&&(c=0),this.m=new Array(10),this.set(t,e,r,n,i,s,o,a,u,c)}var t=i.prototype;return i.makePlane=function(t,e,r,n){return new i(t*t,t*e,t*r,t*n,e*e,e*r,e*n,r*r,r*n,n*n)},t.copy=function(t){t=t.m;return this.m=t.concat(),this},t.set=function(t,e,r,n,i,s,o,a,u,c){var h=this.m;h[0]=t,h[1]=e,h[2]=r,h[3]=n,h[4]=i,h[5]=s,h[6]=o,h[7]=a,h[8]=u,h[9]=c},t.det=function(t,e,r,n,i,s,o,a,u){var c=this.m;return c[t]*c[i]*c[u]+c[r]*c[n]*c[a]+c[e]*c[s]*c[o]-c[r]*c[i]*c[o]-c[t]*c[s]*c[a]-c[e]*c[n]*c[u]},t.add=function(t){var e=this.m,t=t.m;return this.set(e[0]+t[0],e[1]+t[1],e[2]+t[2],e[3]+t[3],e[4]+t[4],e[5]+t[5],e[6]+t[6],e[7]+t[7],e[8]+t[8],e[9]+t[9]),this},i}(),n=function(){return function(t){this.originalIndex=t,this.p=new x,this.tstart=0,this.tcount=0,this.q=new l,this.border=!1}}(),s=function(){return function(){this.tid=0,this.tvertex=0}}(),h=function(){return function(t,e,r){this.a=t,this.b=e,this.c=r}}(),i=function(){function t(){this._diff=0,this._startTime=null}var e=t.prototype;return Object.defineProperty(e,"diff",{get:function(){return this._diff},enumerable:!1,configurable:!0}),e.start=function(){"undefined"!=typeof process&&process.hrtime?this._startTime=process.hrtime():this._startTime=Date.now()},e.end=function(){var t;null!=this._startTime&&("undefined"!=typeof process&&process.hrtime?(t=1e3*((t=process.hrtime(this._startTime))[0]+1e-9*t[1]),this._diff=t):this._diff=Date.now()-this._startTime,this._startTime=null)},t}(),e={__proto__:null,FastQuadric:function(){function t(t){var e=void 0===t?{}:t,t=e.targetPercentage,t=void 0===t?.5:t,e=e.aggressiveness,e=void 0===e?7:e;this._triangles=[],this._vertices=[],this._refs=[],this.targetPercentage=t,this.aggressiveness=e,this._timer=new i}var e=t.prototype;return Object.defineProperty(e,"timeConsumed",{get:function(){return this._timer.diff},enumerable:!1,configurable:!0}),e.simplify=function(t){var e=this,r=this._timer;return r.start(),t.geometries?t.geometries.forEach(function(t){e._process(t)}):this._process(t),r.end(),this},e._process=function(t){this._getData(t);var e=this._triangles,r=this._vertices,n=this._refs,i=this.targetPercentage,s=this.aggressiveness,o=this._triangles.length*i;e.forEach(function(t){return t.deleted=!1});for(var a=0,u=[],c=[],h=e.length,f=0;f<100&&!(h-a<=o);f++){f%5==0&&this._updateMesh(f),e.forEach(function(t){return t.dirty=!1});for(var l=1e-9*Math.pow(f+3,s),d=e.length-1;0<=d;d--){var v=e[d];if(!(v.err[3]>l||v.deleted||v.dirty)){for(var p=0;p<3;p++)if(v.err[p]<l){var g=v.v[p],_=v.v[(p+1)%3],y=r[g],m=r[_];if(!y.border&&!m.border){var b=new x;if(this._calculateError(g,_,b),u.splice(0),c.splice(0),!this._flipped(b,_,y,u)&&!this._flipped(b,g,m,c)){y.p=b,y.q.add(m.q);b=n.length;a+=this._updateTriangles(g,y,u),a+=this._updateTriangles(g,m,c);m=n.length-b;y.tstart=b,y.tcount=m;break}}}if(h-a<=o)break}}}this._compactMesh(),this._setData(t)},e._getData=function(t){t=t.prepare();this._vertices=t.vertices.map(function(t,e){e=new n(e);return e.p.copy(t),e}),this._triangles=t.faces.map(function(t,e){e=new r(e);return e.v=[t.a,t.b,t.c],e}),this._refs=[]},e._setData=function(t){var e=this._triangles,r=this._vertices.map(function(t){return t.p}),n=e.map(function(t){t=t.v;return new h(t[0],t[1],t[2])}),i=this._vertices.map(function(t){return t.originalIndex}),e=this._triangles.map(function(t){return t.originalIndex});t.update({vertices:r,faces:n,unculledVertices:i,unculledFaces:e})},e._flipped=function(t,e,r,n){for(var i=this._triangles,s=this._vertices,o=this._refs,a=0;a<r.tcount;a++){var u=o[r.tstart+a],c=i[u.tid];if(!c.deleted){var h=u.tvertex,u=c.v[(h+1)%3],h=c.v[(h+2)%3];if(u!==e&&h!==e){u=x.subVectors(s[u].p,t),h=x.subVectors(s[h].p,t);if(u.normalize(),h.normalize(),.999<Math.abs(u.dot(h)))return!0;h=(new x).copy(u).cross(h);if(h.normalize(),n[a]=!1,h.dot(c.n)<.2)return!0}else n[a]=!0}}return!1},e._updateTriangles=function(t,e,r){for(var n=this._triangles,i=this._refs,s=new x,o=0,a=0;a<e.tcount;a++){var u=i[e.tstart+a],c=n[u.tid];c.deleted||(r[a]?(c.deleted=!0,o++):(c.v[u.tvertex]=t,c.dirty=!0,c.err[0]=this._calculateError(c.v[0],c.v[1],s),c.err[1]=this._calculateError(c.v[1],c.v[2],s),c.err[2]=this._calculateError(c.v[2],c.v[0],s),c.err[3]=Math.min(c.err[0],c.err[1],c.err[2]),i.push(u)))}return o},e._updateMesh=function(t){var i=this,c=this._vertices,h=this._refs;0<t?this._triangles=this._triangles.filter(function(t){return!t.deleted}):(c.forEach(function(t){return t.q=new l}),this._triangles.forEach(function(t){var e=t.v.map(function(t){return c[t].p}),r=x.subVectors(e[1],e[0]).cross(x.subVectors(e[2],e[0])).normalize();t.n=r;var n=l.makePlane(r.x,r.y,r.z,-r.dot(e[0]));t.v.forEach(function(t){return c[t].q.add(n)})}),this._triangles.forEach(function(r){var n=new x;r.v.forEach(function(t,e){r.err[e]=i._calculateError(t,r.v[(e+1)%3],n)})})),c.forEach(function(t){t.tstart=0,t.tcount=0});var f=this._triangles;f.forEach(function(t){t.v.forEach(function(t){return c[t].tcount++})});var e=0;c.forEach(function(t){t.tstart=e,e+=t.tcount,t.tcount=0});for(var r=h.length;r<3*f.length;r++)h[r]=new s;f.forEach(function(t,e){for(var r=0;r<3;r++){var n=c[t.v[r]];h[n.tstart+n.tcount].tid=e,h[n.tstart+n.tcount].tvertex=r,n.tcount++}}),0===t&&(c.forEach(function(t){return t.border=!1}),c.forEach(function(t){for(var e=[],r=[],n=0;n<t.tcount;n++)for(var i=h[t.tstart+n].tid,s=f[i],o=0;o<3;o++){for(var a=s.v[o],u=0;u<e.length&&r[u]!==a;)u++;u===e.length?(e.push(1),r.push(a)):e[u]++}for(o=0;o<e.length;o++)1===e[o]&&(c[r[o]].border=!0)}))},e._calculateError=function(t,e,r){var n=this._vertices,i=n[t],s=n[e],o=(new l).copy(i.q).add(s.q),a=i.border&&s.border,u=o.det(0,1,2,1,4,5,2,5,7),c=0;return 0===u||a?(t=i.p,n=s.p,e=new x(.5*(t.x+n.x),.5*(t.y+n.y),.5*(t.z+n.z)),a=this._vertexError(o,t),i=this._vertexError(o,n),s=this._vertexError(o,e),a===(c=Math.min(a,i,s))&&r.copy(t),i===c&&r.copy(n),s===c&&r.copy(e)):(r.x=-1/u*o.det(1,2,3,4,5,6,5,7,8),r.y=1/u*o.det(0,2,3,1,5,6,2,7,8),r.z=-1/u*o.det(0,1,3,1,4,6,2,5,8),c=this._vertexError(o,r)),c},e._vertexError=function(t,e){var r=e.x,n=e.y,e=e.z,t=t.m;return t[0]*r*r+2*t[1]*r*n+2*t[2]*r*e+2*t[3]*r+t[4]*n*n+2*t[5]*n*e+2*t[6]*n+t[7]*e*e+2*t[8]*e+t[9]},e._compactMesh=function(){this._triangles=this._triangles.filter(function(t){return!t.deleted});var t=this._triangles,n=this._vertices;n.forEach(function(t){return t.tcount=0}),t.forEach(function(t){t.v.forEach(function(t){n[t].tcount=1})});var e=0;n.forEach(function(t){0<t.tcount&&(t.tstart=e,n[e].originalIndex=t.originalIndex,n[e].p=t.p,e++)}),t.forEach(function(r){r.v.forEach(function(t,e){r.v[e]=n[t].tstart})}),n.splice(e)},t}()},o={__proto__:null,Vector3:x,Face3:h,SymmetricMatrix:l},a=function(){function t(t){this.originalGeometry=t}var e=t.prototype;return e.prepare=function(){for(var t=this.originalGeometry,e=t.attributes.position,r=t.index,n=null!==(t=null==e?void 0:e.count)&&void 0!==t?t:0,i=(null!==(t=null==r?void 0:r.count)&&void 0!==t?t:0)/3,s=new Array(n),o=new Array(i),a=0;a<n;a++){var u=e.itemSize*a,c=e.array;s[a]=new x(c[u+0],c[u+1],c[u+2])}for(a=0;a<i;a++){u=3*a,c=r.array;o[a]=new h(c[u+0],c[u+1],c[u+2])}return{vertices:s,faces:o}},e.update=function(t){var r,n,e=t.vertices,i=t.faces,s=t.unculledVertices,t=this.originalGeometry;t.hasAttribute("uv")&&(r=new Float32Array(2*e.length),n=t.attributes.uv,s.forEach(function(t,e){e*=2;r[0+e]=n.getX(t),r[1+e]=n.getY(t)}),t.setAttribute("uv",new f.BufferAttribute(r,2)));var s=(s=e.length)<256?Uint8Array:s<65536?Uint16Array:Uint32Array,o=new Float32Array(3*e.length),a=new s(3*i.length);e.forEach(function(t,e){e*=3;o[0+e]=t.x,o[1+e]=t.y,o[2+e]=t.z}),i.forEach(function(t,e){e*=3;a[0+e]=t.a,a[1+e]=t.b,a[2+e]=t.c});e=new f.BufferAttribute(o,3),i=new f.BufferAttribute(a,1);return t.setAttribute("position",e),t.setIndex(i),t.computeVertexNormals(),this},t}(),u={__proto__:null,ThreeGeometry:a},c=["alphaMap","aoMap","bumpMap","displacementMap","emissiveMap","envMap","lightMap","map","metalnessMap","normalMap"],d={__proto__:null,ThreeAdapter:function(){function t(t,e){this.object=(e=void 0===e?!1:e)?t.clone():t,e&&this._cloneMeshes(t)}var e=t.prototype;return Object.defineProperty(e,"geometries",{get:function(){var e=[];return this.object.traverse(function(t){t.isMesh&&(t=new a(t.geometry),e.push(t))}),e},enumerable:!1,configurable:!0}),e._cloneMeshes=function(t){var r=this,n=[],e=[];t.traverse(function(t){t.isMesh&&n.push(t)}),this.object.traverse(function(t){t.isMesh&&e.push(t)}),e.forEach(function(t,e){e=n[e];t.geometry=t.geometry.clone(),t.material=Array.isArray(t.material)?t.material.map(function(t){return r._cloneMaterial(t)}):r._cloneMaterial(t.material),t.isSkinnedMesh&&r._skinnedMeshToMesh(t,e.skeleton)})},e._cloneMaterial=function(t){var e=t.clone();if("MeshStandardMaterial"===t.type){var r=t;c.forEach(function(t){var e;null!=r[t]&&(e=r[t],r[t]=r[t].clone(),r[t].needsUpdate=!0,"metalnessMap"===t&&e===r.roughnessMap&&(r.roughnessMap=r.metalnessMap))})}else for(var n in e)e[n]&&e[n].isTexture&&(e[n]=e[n].clone(),e[n].needsUpdate=!0);return e.needsUpdate=!0,e},e._skinnedMeshToMesh=function(s,t){var e=s.geometry,o=e.attributes.position,a=e.attributes.skinIndex,u=e.attributes.skinWeight;s.updateMatrixWorld(),t.update();for(var c=t.boneMatrices,h=new f.Matrix4,r=0;r<o.count;r++)!function(t){h.identity();var r=new f.Vector4;r.set(0,0,0,0);var n=new f.Vector4;n.set(o.getX(t),o.getY(t),o.getZ(t),1).applyMatrix4(s.bindMatrix);var e=[u.getX(t),u.getY(t),u.getZ(t),u.getW(t)],i=[a.getX(t),a.getY(t),a.getZ(t),a.getW(t)];e.forEach(function(t,e){t=(new f.Matrix4).fromArray(c,16*i[e]).multiplyScalar(t);r.add(n.clone().applyMatrix4(t))});e=r.applyMatrix4(s.bindMatrixInverse);o.setXYZ(t,e.x,e.y,e.z)}(r);e=s.parent,t=new f.Mesh(s.geometry,s.material).copy(s);t.geometry.deleteAttribute("skinIndex"),t.geometry.deleteAttribute("skinWeight"),e.remove(s),e.add(t)},t}()};return t(t(t(t({},e),o),u),d)}); //# sourceMappingURL=mesh-simplifier.min.js.map