UNPKG

@csi-foxbyte/cityjson-to-3d-tiles

Version:

A Node.js library that converts CityJSON files into Cesium 3D Tiles—complete with automatic texture atlas packing, Basis compression, three LOD levels, and customizable threading.

2 lines • 4.3 kB
import {Document}from'@gltf-transform/core';import {prune,dedup,flatten,weld,join,normals}from'@gltf-transform/functions';import {readFile}from'fs/promises';import re from'path';import oe from'proj4';import {Vector3}from'three';import {getIO}from'../3dtiles/io.js';import {mergeTextures}from'../functions/mergeTextures.js';import {padTextures}from'../functions/padTextures.js';import {buildGeometryInstance}from'./buildGeometryInstance.js';import {triangulate3DPolygon,getBBoxesFromMeshes}from'./helpers.js';async function Ie({appearance:h,cityJson:a,dest:B,folderPath:k,geometry:C,id:E,src:U,vertices:W,noTransform:N,dbInstance:X}){if(!C)return [];const P=await getIO(),G=oe(U,B);let r=null;const M=[];for(let o of C){if(o.type==="GeometryInstance"){M.push(...await buildGeometryInstance(E,a,B,o,P,X));continue}switch(o.type){case "CompositeSolid":throw new Error("CompositeSolid not implemented yet!");case "MultiLineString":throw new Error("MultiLineString not implemented yet!");case "MultiPoint":throw new Error("MultiPoint not implemented yet!");case "MultiSolid":throw new Error("MultiSolid not implemented yet!");case "CompositeSurface":case "MultiSurface":case "Solid":{if(o.type==="Solid"&&o.boundaries.length>1)continue;const y=o.texture?.[h]!==void 0,S=[];let w=null;const D=new Set;let O=[],p=[],c=null;o.type==="Solid"&&(p=o.boundaries[0],y&&(c=o?.texture?.[h].values[0])),o.type==="MultiSurface"&&(p=o.boundaries,y&&(c=o.texture?.[h].values)),o.type==="CompositeSurface"&&(p=o.boundaries,y&&(c=o.texture?.[h].values));const t=new Document,L=t.getRoot(),R=t.createScene();L.setDefaultScene(R);const A=t.createBuffer(),v=t.createNode();R.addChild(v);const V=t.createMesh();v.setMesh(V);for(let n=0;n<p.length;n++){const l=p[n],d=[],m=[];for(let e=0;e<l.length;e++){const b=l[e],x=[];for(const f of b){const T=W[f];x.push(T);}if(y&&(c[n][e]??[]).length>1){w=c[n][e][0],D.add(w);for(const f of c[n][e].slice(1)){const T=a.appearance?.["vertices-texture"][f];m.push(T[0],1-T[1]);}}d.push(x);}const I=triangulate3DPolygon(d),s=d.flat().flatMap(e=>N?e:[e[0]*a.transform.scale[0]+a.transform.translate[0],e[1]*a.transform.scale[1]+a.transform.translate[1],e[2]*a.transform.scale[2]+a.transform.translate[2]]);if(!I)continue;const i=new Array(s.length);if(N)for(let e=0;e<s.length;e+=3)r||(r=new Vector3(s[0],s[1],s[2])),i[e+0]=s[e+0]-r.x,i[e+1]=s[e+1]-r.y,i[e+2]=s[e+2]-r.z;else for(let e=0;e<s.length;e+=3){const[b,x,f]=G.forward([s[e+0],s[e+1],s[e+2]]);r||(r=new Vector3(b,x,f)),i[e+0]=b-r.x,i[e+1]=f-r.z,i[e+2]=-(x-r.y);}const z=t.createMaterial("UNTEXTURED"),g=t.createPrimitive();g.setMaterial(z),S.push({indices:new Int16Array(I),position:new Float32Array(i),uvs:new Float32Array(m)});const Z=t.createAccessor().setBuffer(A).setArray(new Float32Array(i)).setType("VEC3");if(m.length!==0){const e=t.createAccessor().setBuffer(A).setArray(new Float32Array(m)).setType("VEC2");g.setAttribute("TEXCOORD_0",e);}else {const e=t.createMaterial();e.setName("UNTEXTURED"),g.setMaterial(e);}const H=t.createAccessor().setBuffer(A).setArray(new Int16Array(I)).setType("SCALAR");if(g.setAttribute("POSITION",Z).setIndices(H).setMode(4),w){const e=a.appearance?.textures[w];z.setName(e.image),O.push(e.image);}if(V.addPrimitive(g),m.length!==0&&i.length/3!==m.length/2)throw new Error("!!!!")}if(!r){if(S.length!==0)throw new Error("FISHY");return []}v.setTranslation([r.x,r.z,-r.y]);let F=[];if(D.size>1){for(const n of t.getRoot().listMaterials()){if(n.getName()==="UNTEXTURED")continue;const l=await readFile(re.join(k,n.getName())),d=t.createTexture().setImage(l).setMimeType("image/png");n.setBaseColorTexture(d);}await padTextures(t,4),F=await mergeTextures(t,void 0,void 0,true,false),await t.transform(prune());}await t.transform(dedup(),flatten(),weld({}),join(),normals());const{cartographicBox:u}=getBBoxesFromMeshes(S,r),Y=await P.writeBinary(t);M.push({cartographicBoxMaxX:u.max.x,cartographicBoxMaxY:u.max.y,cartographicBoxMaxZ:u.max.z,cartographicBoxMinX:u.min.x,cartographicBoxMinY:u.min.y,cartographicBoxMinZ:u.min.z,id:E,serializedDoc:Y,isInstanced:false,texturePaths:O,collectedTextures:F.map(({texture:n,name:l})=>({buffer:n.getImage(),name:l}))});break}}}return M}export{Ie as buildGeometry};//# sourceMappingURL=buildGeometry.js.map //# sourceMappingURL=buildGeometry.js.map