forked from mirror/viewstl
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fbb7f5c389 | |||
| e14585dff0 | |||
| 35626740ae | |||
| 8ee9296a7f | |||
| 35f2e54652 |
@@ -22,4 +22,20 @@ Create a new instance of Stl Viewer (simplest initiation - read and view STL fil
|
|||||||
var stl_viewer=new StlViewer(document.getElementById("stl_cont"), { models: [ {id:0, filename:"mystl.stl"} ] });
|
var stl_viewer=new StlViewer(document.getElementById("stl_cont"), { models: [ {id:0, filename:"mystl.stl"} ] });
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Dependency on JSZip library:
|
||||||
|
============================
|
||||||
|
When dealing with 3mf/vsb files you must use JSZip library - https://stuk.github.io/jszip/
|
||||||
|
- this library is not included here, you must upload it to your server and supply jszip_path and jszip_utils_path parameters:
|
||||||
|
```
|
||||||
|
var stl_viewer=new StlViewer
|
||||||
|
(
|
||||||
|
document.getElementById("stl_cont"),
|
||||||
|
{
|
||||||
|
....
|
||||||
|
jszip_path:"/<path_to_jszip>/jszip.min.js",
|
||||||
|
jszip_utils_path:"/<path_to_jszip>/jszip-utils.min.js"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
more at https://www.viewstl.com/plugin/
|
more at https://www.viewstl.com/plugin/
|
||||||
|
|||||||
Vendored
+2
-2
File diff suppressed because one or more lines are too long
+420
-34
@@ -1,24 +1,36 @@
|
|||||||
//1.10
|
//1.13.1
|
||||||
function parse_3d_file(filename, s)
|
//1.13.1 support for MagicLab colored-STL method
|
||||||
|
|
||||||
|
function parse_3d_file(filename, s, callback, jszip_path)
|
||||||
{
|
{
|
||||||
//determine type of file
|
//determine type of file
|
||||||
//console.log(filename.split('.').pop().toLowerCase());
|
//console.log(filename.split('.').pop().toLowerCase());
|
||||||
//switch (filename.split('.').pop().toLowerCase())
|
//switch (filename.split('.').pop().toLowerCase())
|
||||||
|
var res=null;
|
||||||
switch (filename.split('.').pop().split('?')[0].toLowerCase())
|
switch (filename.split('.').pop().split('?')[0].toLowerCase())
|
||||||
{
|
{
|
||||||
case "stl":
|
case "stl":
|
||||||
return parse_stl_bin(s);
|
res=parse_stl_bin(s);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "obj":
|
case "obj":
|
||||||
return parse_obj(s);
|
res=parse_obj(s);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "vf":
|
case "vf":
|
||||||
return parse_vf(arrayBufferToString(s));
|
res=parse_vf(arrayBufferToString(s));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "3mf":
|
||||||
|
parse_3mf(s, callback, jszip_path); //async function
|
||||||
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return parse_stl_bin(s);
|
res=parse_stl_bin(s);
|
||||||
//return "Unknown file type";
|
//return "Unknown file type";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (callback) callback(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
function arrayBufferToString(buffer,onSuccess,onFail)
|
function arrayBufferToString(buffer,onSuccess,onFail)
|
||||||
@@ -118,18 +130,25 @@ function parse_stl_bin(s)
|
|||||||
var vertexIndex;
|
var vertexIndex;
|
||||||
var f1,f2,f3;
|
var f1,f2,f3;
|
||||||
var v1,v2,v3;
|
var v1,v2,v3;
|
||||||
|
var color_bit=0;
|
||||||
|
var color_method_mt=false; //face colors are encoded Materialise Magics method (othereise it can be Meshlab method)
|
||||||
|
|
||||||
if (!s) return null;
|
if (!s) return null;
|
||||||
|
|
||||||
//see if this is colored STL
|
//see if this is colored STL
|
||||||
var cpos=arrayBufferToString(s.slice(0,80)).toLowerCase().indexOf("color");
|
var cpos=arrayBufferToString(s.slice(0,80)).toLowerCase().indexOf("color");
|
||||||
|
//cpos=true;
|
||||||
|
|
||||||
var fdata = new DataView(s, 0);
|
var fdata = new DataView(s, 0);
|
||||||
var only_default_color=true;
|
var have_face_colors=false;
|
||||||
|
var def_red_color=-1;
|
||||||
|
var def_green_color=-1;
|
||||||
|
var def_blue_color=-1;
|
||||||
|
|
||||||
if (cpos>-1)
|
if (cpos>-1)
|
||||||
{
|
{
|
||||||
//there is a color, get the default color
|
//there is a color (Materialise Magics format), get the default color
|
||||||
|
color_method_mt=true;
|
||||||
def_red_color=(fdata.getUint8 (cpos+6,true)) / 31;
|
def_red_color=(fdata.getUint8 (cpos+6,true)) / 31;
|
||||||
def_green_color=(fdata.getUint8 (cpos+7,true)) / 31;
|
def_green_color=(fdata.getUint8 (cpos+7,true)) / 31;
|
||||||
def_blue_color=(fdata.getUint8 (cpos+8,true)) / 31;
|
def_blue_color=(fdata.getUint8 (cpos+8,true)) / 31;
|
||||||
@@ -201,49 +220,59 @@ function parse_stl_bin(s)
|
|||||||
}
|
}
|
||||||
v3=vertexIndex;
|
v3=vertexIndex;
|
||||||
|
|
||||||
if (cpos>-1)
|
//color data (if any)
|
||||||
|
pos+=12;
|
||||||
|
face_color=fdata.getUint16(pos,true);
|
||||||
|
//color_bit=color_method_mt?1:(face_color & 1); //0000000000000001 => 1=have face color, 0=nope
|
||||||
|
color_bit=color_method_mt?1:((face_color & 32768)>>15); //1000000000000000 => 1=have face color, 0=nope
|
||||||
|
//console.log('color_bit', color_bit, face_color);
|
||||||
|
|
||||||
|
if (color_bit)
|
||||||
{
|
{
|
||||||
pos+=12;
|
if (color_method_mt)
|
||||||
|
|
||||||
//get 2 bytes of color (if any)
|
|
||||||
face_color=fdata.getUint16(pos,true);
|
|
||||||
|
|
||||||
if ((face_color==32768)||(face_color==65535))
|
|
||||||
{
|
{
|
||||||
//default color
|
if ((face_color==32768)||(face_color==65535))
|
||||||
color_red=def_red_color;
|
{
|
||||||
color_green=def_green_color;
|
//default color
|
||||||
color_blue=def_blue_color;
|
color_red=def_red_color;
|
||||||
|
color_green=def_green_color;
|
||||||
|
color_blue=def_blue_color;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
have_face_colors=true;
|
||||||
|
color_red=((face_color & 31)/31); //0000000000011111
|
||||||
|
color_green=(((face_color & 992)>>5)/31); //0000001111100000
|
||||||
|
color_blue=(((face_color & 31744)>>10)/31); //0111110000000000
|
||||||
|
|
||||||
|
//the rgb are saved in values from 0 to 31 ... for us, we want it to be 0 to 1 - hence the 31)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
only_default_color=false;
|
//meshlab color format
|
||||||
color_red=((face_color & 31)/31); //0000000000011111
|
have_face_colors=true;
|
||||||
|
color_blue=((face_color & 31)/31); //0000000000011111
|
||||||
color_green=(((face_color & 992)>>5)/31); //0000001111100000
|
color_green=(((face_color & 992)>>5)/31); //0000001111100000
|
||||||
color_blue=(((face_color & 31744)>>10)/31); //0111110000000000
|
color_red=(((face_color & 31744)>>10)/31); //0111110000000000
|
||||||
|
|
||||||
//the rgb are saved in values from 0 to 31 ... for us, we want it to be 0 to 1 - hence the 31)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//faces.push(new THREE.Face3(v1,v2,v3,1,new THREE.Color("rgb("+color_red+","+color_green+","+color_blue+")")));
|
faces.push(new Array(v1,v2,v3, color_red, color_green, color_blue));
|
||||||
faces.push(new Array(v1,v2,v3,color_red, color_green,color_blue ));
|
|
||||||
|
|
||||||
pos+=2;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//no color
|
//no color for face
|
||||||
//faces.push(new THREE.Face3(v1,v2,v3));
|
//faces.push(new THREE.Face3(v1,v2,v3));
|
||||||
faces.push(new Array(v1,v2,v3));
|
faces.push(new Array(v1,v2,v3));
|
||||||
pos+=14;
|
|
||||||
}
|
}
|
||||||
|
pos+=2;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vert_hash=null;
|
vert_hash=null;
|
||||||
|
|
||||||
//console.log("CPOS: "+cpos+" only default: "+only_default_color);
|
return ({vertices:vertices, faces:faces, colors:have_face_colors});
|
||||||
|
|
||||||
return ({vertices:vertices, faces:faces, colors:((cpos>-1)&&(!only_default_color))});
|
|
||||||
}
|
}
|
||||||
catch(err)
|
catch(err)
|
||||||
{
|
{
|
||||||
@@ -281,6 +310,363 @@ function parse_vf(s)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//returns if JSZip lib is loaded - if so, returns an instance, otherwise tries to load the lib
|
||||||
|
function init_zip(skip_load_script, jszip_path)
|
||||||
|
{
|
||||||
|
var zip=null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
zip = new JSZip();
|
||||||
|
}
|
||||||
|
catch(err)
|
||||||
|
{
|
||||||
|
if (skip_load_script) console.log('JSZip is missing', err.message);
|
||||||
|
zip=null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!zip)
|
||||||
|
{
|
||||||
|
if (!skip_load_script)
|
||||||
|
{
|
||||||
|
importScripts(jszip_path);
|
||||||
|
return init_zip(true, jszip_path); //tries again
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return zip;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parse_3mf(s, callback, jszip_path)
|
||||||
|
{
|
||||||
|
var file_txt=arrayBufferToString(s.slice(0,5));
|
||||||
|
if (file_txt=='<?xml')
|
||||||
|
return parse_3mf_from_txt(arrayBufferToString(s), callback);
|
||||||
|
|
||||||
|
var zip=init_zip(false, jszip_path);
|
||||||
|
if (!zip) return false;
|
||||||
|
|
||||||
|
var found=false;
|
||||||
|
zip.loadAsync(s).then(function ()
|
||||||
|
{
|
||||||
|
var zkeys=Object.keys(zip.files);
|
||||||
|
var i=zkeys.length;
|
||||||
|
while (i--)
|
||||||
|
{
|
||||||
|
if (zip.files[zkeys[i]].name=="3D/3dmodel.model")
|
||||||
|
{
|
||||||
|
found=true;
|
||||||
|
zip.files[zkeys[i]].async('text').then(function (fileData)
|
||||||
|
{
|
||||||
|
return parse_3mf_from_txt(fileData, callback); //'return' because our work in this loop is done
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
callback ("3D/3dmodel.model in 3mf file not found");
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function parse_3mf_from_txt(s, callback)
|
||||||
|
{
|
||||||
|
var vertices=[];
|
||||||
|
var faces=[];
|
||||||
|
|
||||||
|
var vertices_for_build=[];
|
||||||
|
var faces_for_build=[];
|
||||||
|
|
||||||
|
var have_colors=false;
|
||||||
|
|
||||||
|
var vertex_pattern = /vertex\s+.*(x|y|z)\s*=\s*([0-9,\.\"\+\-e]+)\s+.*(x|y|z)\s*=\s*([0-9,\.\"\+\-e]+)\s+.*(x|y|z)\s*=\s*([0-9,\.\"\+\-e]+)\s*/i;
|
||||||
|
var face_pattern = /triangle\s+.*(v1|v2|v3)\s*=\s*([0-9\"]+)\s+.*(v1|v2|v3)\s*=\s*([0-9\"]+)\s+.*(v1|v2|v3)\s*=\s*([0-9\"]+)\s*(?:pid=([0-9\"]+)\s+)?(?:p[1|2|3]=([0-9\"]+)\s)?\s*/i;
|
||||||
|
var res_pattern = /(?:m:\S+|basematerials)\s+id=([0-9\"]+)\s*/i;
|
||||||
|
var res_color_pattern=/(?:m:(\S+)|base)\s+.*color=([0-9A-F\"\#]+)\s*/i;
|
||||||
|
//var object_pattern = /<object\s+.*type=model.*/i;
|
||||||
|
var object_pattern = /<object\s+/i;
|
||||||
|
var component_pattern = /<component\s+.*objectid=([0-9\"]+)/i;
|
||||||
|
var item_transform_pattern = /item\s+.*objectid=([0-9\"]+)\s+.*transform=(([0-9\".e-]+\s+){12})/i;
|
||||||
|
var resources={};
|
||||||
|
var objects={};
|
||||||
|
var curr_object=null;
|
||||||
|
var curr_rid=0; //current resource id
|
||||||
|
var vcounter=0; //vertices counter
|
||||||
|
var fcounter=0; //faces counter
|
||||||
|
var build_open_pattern=/<build/i;
|
||||||
|
var build_close_pattern=/<\/build/i;
|
||||||
|
var build_item_pattern=/<item\s+.*objectid=([0-9\"]+)/i;
|
||||||
|
var lines = s.split(/[\r\n]+/g);
|
||||||
|
if (lines.length<5)
|
||||||
|
lines = s.split(/(?=<)/g); //files without new line, can happen
|
||||||
|
var build_stage=false;
|
||||||
|
|
||||||
|
for ( var i = 0; i < lines.length; i ++ )
|
||||||
|
{
|
||||||
|
var line = lines[ i ];
|
||||||
|
line = line.replace(/"/g, '');
|
||||||
|
//console.log(line);
|
||||||
|
|
||||||
|
var res=vertex_pattern.exec( line );
|
||||||
|
if ( res )
|
||||||
|
{
|
||||||
|
var v={x:0,y:0,z:0};
|
||||||
|
v[res[1]]=res[2];
|
||||||
|
v[res[3]]=res[4];
|
||||||
|
v[res[5]]=res[6];
|
||||||
|
vertices.push([v.x, v.y, v.z]);
|
||||||
|
vcounter++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var res=face_pattern.exec( line );
|
||||||
|
if ( res )
|
||||||
|
{
|
||||||
|
var f={v1:0,v2:0,v3:0};
|
||||||
|
var face_color=null;
|
||||||
|
var v_start_index=curr_object?curr_object.v_start_index:0;
|
||||||
|
|
||||||
|
f[res[1]]=parseInt(res[2])+v_start_index;
|
||||||
|
f[res[3]]=parseInt(res[4])+v_start_index;
|
||||||
|
f[res[5]]=parseInt(res[6])+v_start_index;
|
||||||
|
|
||||||
|
//maybe a color from face the itself??
|
||||||
|
if (typeof res[7] !== "undefined")
|
||||||
|
if (resources[res[7]])
|
||||||
|
if (typeof res[8] !== "undefined")
|
||||||
|
if (resources[res[7]])
|
||||||
|
if (resources[res[7]].color)
|
||||||
|
if (resources[res[7]].color[res[8]])
|
||||||
|
face_color=resources[res[7]].color[res[8]].substr(1);
|
||||||
|
|
||||||
|
//maybe a color from the object??
|
||||||
|
if ((!face_color)&&(curr_object))
|
||||||
|
{
|
||||||
|
if (typeof curr_object.pid !== "undefined")
|
||||||
|
if (typeof curr_object.pindex !== "undefined")
|
||||||
|
if (resources[curr_object.pid])
|
||||||
|
if (resources[curr_object.pid].color)
|
||||||
|
if (resources[curr_object.pid].color[curr_object.pindex])
|
||||||
|
face_color=resources[curr_object.pid].color[curr_object.pindex].substr(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (face_color)
|
||||||
|
{
|
||||||
|
have_colors=true;
|
||||||
|
face_color={red:parseInt(face_color.substr(0,2),16)/255, green:parseInt(face_color.substr(2,2),16)/255, blue:parseInt(face_color.substr(4,2),16)/255};
|
||||||
|
faces.push([f.v1, f.v2, f.v3, face_color.red, face_color.green, face_color.blue]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
faces.push([f.v1, f.v2, f.v3]);
|
||||||
|
|
||||||
|
fcounter++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var res=res_pattern.exec( line );
|
||||||
|
if ( res )
|
||||||
|
{
|
||||||
|
curr_rid=res[1];
|
||||||
|
if (!resources[curr_rid]) resources[curr_rid]={};
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var res=component_pattern.exec( line );
|
||||||
|
if ( res )
|
||||||
|
{
|
||||||
|
//console.log('component patterns: ',JSON.stringify(objects[res[1]]), res[1]);
|
||||||
|
if (!curr_object) continue;
|
||||||
|
if (!objects[res[1]]) continue;
|
||||||
|
|
||||||
|
//add new vertices to current vertices array
|
||||||
|
//console.log('old vertices', JSON.stringify(vertices));
|
||||||
|
vertices=vertices.concat(JSON.parse(JSON.stringify(vertices.slice(objects[res[1]].v_start_index, objects[res[1]].v_end_index+1)))); //the JSON is for a deep-copy, array of arrays can be tricky to just slice
|
||||||
|
|
||||||
|
//has transform?
|
||||||
|
var tres=/transform=(([0-9\".e-]+\s+){12})/i.exec( line );
|
||||||
|
if (tres)
|
||||||
|
{
|
||||||
|
var tsplit=tres[1].trim().split(/[ ,]+/);
|
||||||
|
if (tsplit.length==12)
|
||||||
|
{
|
||||||
|
var to_iv=vertices.length-1;
|
||||||
|
var from_iv=to_iv-(objects[res[1]].v_end_index-objects[res[1]].v_start_index);
|
||||||
|
transform_vertices(vertices, from_iv, to_iv, tsplit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//console.log('new vertices', JSON.stringify(vertices));
|
||||||
|
|
||||||
|
//add new faces to current faces array
|
||||||
|
var new_faces=JSON.parse(JSON.stringify(faces.slice(objects[res[1]].f_start_index, objects[res[1]].f_end_index+1))); //the JSON is for a deep-copy, array of arrays can be tricky to just slice
|
||||||
|
var vgap=vertices.length-objects[res[1]].v_end_index-1;
|
||||||
|
var findex=new_faces.length;
|
||||||
|
while (findex--)
|
||||||
|
{
|
||||||
|
new_faces[findex][0]+=vgap;
|
||||||
|
new_faces[findex][1]+=vgap;
|
||||||
|
new_faces[findex][2]+=vgap;
|
||||||
|
}
|
||||||
|
|
||||||
|
//console.log('old faces', JSON.stringify(faces));
|
||||||
|
faces=faces.concat(new_faces);
|
||||||
|
//console.log('new faces', JSON.stringify(faces));
|
||||||
|
|
||||||
|
vcounter=vertices.length;
|
||||||
|
fcounter=faces.length;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var res=object_pattern.exec( line );
|
||||||
|
if ( res )
|
||||||
|
{
|
||||||
|
var res=/id=([0-9\"]+)/i.exec( line );if (!res) continue;
|
||||||
|
if (curr_object) curr_object.v_end_index=vcounter-1;
|
||||||
|
if (curr_object) curr_object.f_end_index=fcounter-1;
|
||||||
|
|
||||||
|
var new_object={};
|
||||||
|
new_object.id=res[1];
|
||||||
|
new_object.v_start_index=vcounter; //ref to the complete vertices array
|
||||||
|
new_object.f_start_index=fcounter; //ref to the complete faces array
|
||||||
|
|
||||||
|
var res=/pid=([0-9\"]+)/i.exec( line );
|
||||||
|
if (res) new_object.pid=parseInt(res[1]);
|
||||||
|
|
||||||
|
var res=/pindex=([0-9\"]+)/i.exec( line );
|
||||||
|
if (res) new_object.pindex=parseInt(res[1]);
|
||||||
|
|
||||||
|
//console.log(JSON.stringify(curr_object));
|
||||||
|
//var old_id=curr_object?curr_object.id:null;
|
||||||
|
curr_object=new_object; //just changing reference
|
||||||
|
//console.log(old_id?JSON.stringify(objects[old_id]):'NA');
|
||||||
|
objects[curr_object.id]=curr_object;
|
||||||
|
//console.log(curr_object.id, objects[curr_object.id]);
|
||||||
|
|
||||||
|
//console.log ('********* new object', JSON.stringify(curr_object));
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var res=res_color_pattern.exec( line );
|
||||||
|
if ( res )
|
||||||
|
{
|
||||||
|
if (typeof res[1] === "undefined") res[1]="color"; //this is color of basematerials peoperty
|
||||||
|
if (!resources[curr_rid]) {console.log('warning: no source id for '+res[1]);continue;}
|
||||||
|
if (!resources[curr_rid][res[1]]) resources[curr_rid][res[1]]=[];
|
||||||
|
|
||||||
|
resources[curr_rid][res[1]].push(res[2]);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (build_open_pattern.exec( line ))
|
||||||
|
{
|
||||||
|
build_stage=true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (build_close_pattern.exec( line ))
|
||||||
|
{
|
||||||
|
build_stage=false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!build_stage) continue; //if not in build stage, we finished checking this row
|
||||||
|
|
||||||
|
var res=build_item_pattern.exec(line);
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
//console.log('build', res[1], JSON.stringify(objects));
|
||||||
|
|
||||||
|
//if (res[1]==128) continue; //*** REMOVE ME
|
||||||
|
|
||||||
|
if (!objects[res[1]]) continue;
|
||||||
|
|
||||||
|
var end_inx=(typeof objects[res[1]].v_end_index === "undefined")?(vcounter-1):objects[res[1]].v_end_index;
|
||||||
|
|
||||||
|
var res2=item_transform_pattern.exec(line);
|
||||||
|
if ( res2 )
|
||||||
|
{
|
||||||
|
var tsplit=res2[2].trim().split(/[ ,]+/);
|
||||||
|
if (tsplit.length==12)
|
||||||
|
transform_vertices(vertices, objects[res2[1]].v_start_index, end_inx, tsplit);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vertices_for_build=vertices_for_build.concat(vertices.slice(objects[res[1]].v_start_index, end_inx+1));
|
||||||
|
var vgap=vertices_for_build.length-end_inx-1;
|
||||||
|
//console.log('vgap', vgap);
|
||||||
|
|
||||||
|
|
||||||
|
var end_inx=(typeof objects[res[1]].f_end_index === "undefined")?(fcounter-1):objects[res[1]].f_end_index;
|
||||||
|
//console.log('bulding from faces',objects[res[1]].f_start_index, end_inx);
|
||||||
|
var new_faces=JSON.parse(JSON.stringify(faces.slice(objects[res[1]].f_start_index, end_inx+1))); //need a deep copy, so we won't change the old faces array
|
||||||
|
var findex=new_faces.length;
|
||||||
|
while (findex--)
|
||||||
|
{
|
||||||
|
new_faces[findex][0]+=vgap;
|
||||||
|
new_faces[findex][1]+=vgap;
|
||||||
|
new_faces[findex][2]+=vgap;
|
||||||
|
}
|
||||||
|
faces_for_build=faces_for_build.concat(new_faces);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//console.log('vertices: ', JSON.stringify(vertices));
|
||||||
|
//console.log('vertices for build: ', JSON.stringify(vertices_for_build));
|
||||||
|
//console.log('faces: ', JSON.stringify(faces));
|
||||||
|
//console.log('faces for build: ', JSON.stringify(faces_for_build));
|
||||||
|
//console.log('resources: ', JSON.stringify(resources));
|
||||||
|
//console.log('objects: ', JSON.stringify(objects));
|
||||||
|
//return;
|
||||||
|
|
||||||
|
callback({vertices:vertices_for_build, faces:faces_for_build, colors:have_colors});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function transform_vertices(vertices, from_iv, to_iv, tsplit) //transform vertices by matrix, used by parse_3mf_from_txt
|
||||||
|
{
|
||||||
|
var tvals=[[],[],[],[]];
|
||||||
|
for (var itval=0;itval<3;itval++) tvals[0][itval]=parseFloat(tsplit[itval]);tvals[0].push(0);
|
||||||
|
for (var itval=3;itval<6;itval++) tvals[1][itval-3]=parseFloat(tsplit[itval]);tvals[1].push(0);
|
||||||
|
for (var itval=6;itval<9;itval++) tvals[2][itval-6]=parseFloat(tsplit[itval]);tvals[2].push(0);
|
||||||
|
for (var itval=9;itval<12;itval++) tvals[3][itval-9]=parseFloat(tsplit[itval]);tvals[3].push(1);
|
||||||
|
//console.log('transform', tvals);
|
||||||
|
|
||||||
|
for (var iv=from_iv;iv<=to_iv;iv++)
|
||||||
|
{
|
||||||
|
//console.log('before mul', JSON.stringify(vertices[iv]));
|
||||||
|
var transform=matrix_multiply([vertices[iv].concat(1)], tvals);
|
||||||
|
vertices[iv]=[transform[0][0],transform[0][1],transform[0][2]];
|
||||||
|
//console.log('after mul', JSON.stringify(vertices[iv]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function matrix_multiply(a, b)
|
||||||
|
{
|
||||||
|
console.log()
|
||||||
|
var aNumRows = a.length, aNumCols = a[0].length,
|
||||||
|
bNumRows = b.length, bNumCols = b[0].length,
|
||||||
|
m = new Array(aNumRows); // initialize array of rows
|
||||||
|
for (var r = 0; r < aNumRows; ++r) {
|
||||||
|
m[r] = new Array(bNumCols); // initialize the current row
|
||||||
|
for (var c = 0; c < bNumCols; ++c) {
|
||||||
|
m[r][c] = 0; // initialize the current cell
|
||||||
|
for (var i = 0; i < aNumCols; ++i) {
|
||||||
|
m[r][c] += a[r][i] * b[i][c];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function geo_to_vf(geo)
|
function geo_to_vf(geo)
|
||||||
{
|
{
|
||||||
var vertices=[];
|
var vertices=[];
|
||||||
|
|||||||
Reference in New Issue
Block a user