@sohale/implisolid
Version:
A Solid Modelling Kernel in Javascript based on Implicit Surfaces, for MP5 file format
1,393 lines (1,123 loc) • 74.1 kB
HTML
<html>
<head>
<meta charset="utf-8"/>
</head>
<style>
.stat-panel{
position:fixed;
top:0px;
right:0px;
width:100px;
/* z-index:1000; */
}
</style>
<body>
<canvas id="my_canvas"></canvas>
<!--
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r77/three.js">
</script> -->
<!--script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r73/three.js">
</script-->
<!--<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r71/three.js">
</script>-->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r79/three.js">
</script>
<script type="text/javascript" src="./three_r79.js">
</script>
<!-- <script type="text/javascript" src="./three-r77.js"></script> -->
<!--script type="text/javascript" src="https://raw.githubusercontent.com/mrdoob/three.js/69079243426506ed86d0d0ea71b4fdda9dbb2f88/examples/js/controls/OrbitControls.js"></script
-->
<!-- Refused to execute script '...' because its MIME type ('text/plain') is not executable, and strict MIME type checking is enabled.
-->
<script>
function assert(cond, message) {
if (!cond) {
console.error(message);
throw new Exception("assert ", message);
}
}
function _expect(cond, message) {
if (!cond) {
console.error(message);
}
}
</script>
<script>
/** Asynchronously does a series of calls to the function update_mc(). */
var callMultipleTimes = function() {
// private:
var last_active = 0;
var intervals_counter = 0;
function function_body(implisolid_, update_callback, burst_count, interval_msec) {
/** Asynchronously does a series of calls to the function update_callback().
Previous name: update_mc_mul tiple() */
var BURST_COUNT = burst_count; //2; // 50;
var INTERVAL_MSEC = interval_msec; //8-1; //40 // 1 // in Milliseconds
// Works well on too small values of INTERVAL_MSEC (Semaphore).
// The main algorithm performs much faster when this interval is larger (>100). Becasue of `gc`.
var already_busy_doing_it=0; // semaphore. (Refractory). Fast x1.
var burst_counter = 0;
intervals_counter++;
if(intervals_counter>1) //dont start if there is already one running
{
intervals_counter--;
return;
}
last_active = setInterval (
function()
{
if(!last_active)
console.error("!last_active");
burst_counter++; // mc_icounter
console.error(BURST_COUNT);
if(burst_counter<BURST_COUNT) //This code is amazingly similar to Bursting dyamics in neurons.
{
if(already_busy_doing_it<1) //removable
{
already_busy_doing_it++;
update_callback(implisolid_, 0.2/10.*5 /5.);
if(already_busy_doing_it>1)
console.error(">>>already_busy_doing_it:"+already_busy_doing_it);
if(!last_active)
console.error("!last_active");
already_busy_doing_it--;
}else{
console.log("hit");
}
}
else
{
// The interval has finished its job. Time to go.
if(!last_active)
console.error("!last_active");
clearInterval(last_active); // But then don't we need to wait until the last one is finished?
intervals_counter--; // Allow next one in future
burst_counter = 0;
last_active = 0;
}
},
INTERVAL_MSEC
);
}
return function_body;
}();
</script>
<!--script type="text/javascript" src="./ww_geometry77.js"></script-->
<script type="text/javascript" src="../js_iteration_2/geometry79.js"></script>
<!--<script type="text/javascript" src="../js_iteration_2/geometry73.js"></script>-->
<script>
// Default (mock) OrbitControl to void breaking the program if the orbitcontrol is not found.
THREE.OrbitControls = function() {
this.target = new THREE.Vector3();
this.addEventListener = function(){};
}
</script>
<script type="text/javascript" src="./controls/OrbitControls_r79.js"></script>
<!-- <script type="text/javascript" src="../js_iteration_2/bbox_calculations.js"></script> -->
<!--<body>-->
This file uses ImpliSolid's Geometry class. (unlike <a href="mcc2_3js.html">mcc2_3js.html</a>)
<br>
<script>
'use strict';
const THREEJS_R71 = "r71";
const THREEJS_R77 = "r77";
const THREEJS_R79 = "r79";
const threejs_rev = THREEJS_R79;
var produce_object;
var main;
// Thi method creates an object which is identical to ImpliSolid object in implisolid.js
// Todo: merge these two and remove this.
// polygoniser_service
function init_polygonizer()
{
//too late for pre-run
//Module.preRun.push(letmeknow,memoryprofiler_add_hooks, letmeknow = function (){console.log("ok");});
//Module={preRun:[letmeknow, memoryprofiler_add_hooks]};
//main = Module.cwrap('main', 'number', []);
// produce_object = Module.cwrap('produce_object_old2', null, ['number', 'number', 'number', 'number', 'number']);
var s_service={};
s_service.build_geometry = Module.cwrap('build_geometry', null, [ 'string', 'string']);
s_service.get_v_size = Module.cwrap('get_v_size', 'number', []);
s_service.get_f_size = Module.cwrap('get_f_size', 'number', []);
s_service.get_v = Module.cwrap('get_v', null, ['number']);
s_service.get_f = Module.cwrap('get_f', null, ['number']);
s_service.get_v_ptr = Module.cwrap('get_v_ptr', 'number', []);
s_service.get_f_ptr = Module.cwrap('get_f_ptr', 'number', []);
s_service.finish_geometry = Module.cwrap('finish_geometry', null, []);
s_service.set_object = Module.cwrap('set_object', 'number', ['string', 'number']);
s_service.unset_object = Module.cwrap('unset_object', 'number', ['number']);
s_service.set_x = Module.cwrap('set_x', 'number', ['number', 'number']);
s_service.unset_x = Module.cwrap('unset_x', null, []);
s_service.calculate_implicit_values = Module.cwrap('calculate_implicit_values', null, []);
s_service.get_values_ptr = Module.cwrap('get_values_ptr', 'number', []);
s_service.get_values_size = Module.cwrap('get_values_size', 'number', []);
s_service.calculate_implicit_gradients = Module.cwrap('calculate_implicit_gradients', null, []);
s_service.get_gradients_ptr = Module.cwrap('get_gradients_ptr', 'number', []);
s_service.get_gradients_size = Module.cwrap('get_gradients_size', 'number', []);
s_service.get_pointset_ptr = Module.cwrap('get_pointset_ptr', 'number', ['string']);
s_service.get_pointset_size = Module.cwrap('get_pointset_size', 'number', ['string']);
s_service.about = Module.cwrap('about', null, []);
s_service.init = function(){ s_service.needs_deallocation = false; }
s_service.finish_with = function (){
//after the last round.
if(!implisolid_.needs_deallocation)
console.error("cannot `finish_geometry()`. Geometry not produced.");
//todo: try-catch
//d(1);
implisolid_.finish_geometry();
implisolid_.needs_deallocation = false;
//todo(sohail): Why implisolid_ is used here? We should use 'this'.
}
s_service.set_vect = function (float32Array){
if (float32Array.length % 3 != 0) {console.error("bad input array");};
var nverts = float32Array.length / 3;
const _FLOAT_SIZE = Float32Array.BYTES_PER_ELEMENT;
var verts_space = Module._malloc(_FLOAT_SIZE*3*nverts);
Module.HEAPF32.subarray(verts_space/_FLOAT_SIZE, verts_space/_FLOAT_SIZE + 3*nverts).set(float32Array);
var result = this.set_x(verts_space, nverts);
console.log("set_x() result: "+result);
if (!result) {console.error("Something went wrong: ", result);}
Module._free( verts_space );
}
s_service.update_geometry = function(geometry, ignoreNormals) {
var implicit_service = this;
const _FLOAT_SIZE = Float32Array.BYTES_PER_ELEMENT;
const _INT_SIZE = Uint32Array.BYTES_PER_ELEMENT;
const POINTS_PER_FACE = 3;
var nverts = implicit_service.get_v_size();
var nfaces = implicit_service.get_f_size();
if(nfaces > 0){
var verts_address = implicit_service.get_v_ptr();
var faces_address = implicit_service.get_f_ptr();
var verts = Module.HEAPF32.subarray(
verts_address/_FLOAT_SIZE,
verts_address/_FLOAT_SIZE + 3*nverts);
var faces = Module.HEAPU32.subarray(
faces_address/_INT_SIZE,
faces_address/_INT_SIZE + nfaces * POINTS_PER_FACE);
}
else{
console.log("empty implicit");
var verts = new Float32Array([0,0,0, 1,0,0, 1,1,0, 0,1,0, 0,0,1, 1,0,1, 1,1,1, 0,1,1 ]);
var faces = new Uint32Array([0,1,2, 0,2,3, 0,4,5, 0,5,1, 1,5,6, 1,6,2, 2,6,3, 3,6,7, 4,5,6, 5,6,7]);
}
return geometry.update_geometry1(verts, faces, ignoreNormals, false);
};
s_service.make_normals_into_geometry = function(geom, mp5_str, x, ignore_root_matrix) {
var implicit_service = s_service;
const _FLOAT_SIZE = Float32Array.BYTES_PER_ELEMENT;
var result1 =
implicit_service.set_object(mp5_str, ignore_root_matrix);
console.log("SET_OBJECT() RESULTS:", result1);
implicit_service.set_vect(x); // overhead
implicit_service.calculate_implicit_gradients(true); // Why TRUE doe snot have any effect?
var ptr = implicit_service.get_gradients_ptr();
var ptr_len = implicit_service.get_gradients_size();
var gradients = Module.HEAPF32.subarray(ptr/_FLOAT_SIZE, ptr/_FLOAT_SIZE + ptr_len);
//console.log("grad len = " + ptr_len+ " grad = " + gradients); // x 4
//for( var i = 0 ; i < ptr_len; i++) {
// gradients[i] += Math.random() * 0.2;
//}
/*
for( var i = 0 ; i < ptr_len; i++) {
gradients[i] += (Math.random()*2-1) * 0.2*10;
}
*/
/*
for( var i = 0 ; i < ptr_len/3; i++) {
var x = gradients[i * 3 + 0 ];
var y = gradients[i * 3 + 1 ];
var z = gradients[i * 3 + 2 ];
gradients[i * 3 + 0 ] = z;
gradients[i * 3 + 1 ] = x;
gradients[i * 3 + 2 ] = y;
}
*/
geom.update_normals_from_array(gradients);
implicit_service.unset_x();
var result1 =
implicit_service.unset_object(1);
console.log("UNSET_OBJ() RESULTS:", result1);
};
s_service.init();
//console.log("ok");
return s_service;
}
</script>
<script>
'use strict';
function setShapeMatrix2Eye(shape_matrix, sz) {
if (typeof sz == "undefined")
sz = 1.0;
for(var ii=0; ii<16; ii++) {
shape_matrix[0] = 0;
}
shape_matrix[0] = 1 * sz;
shape_matrix[5] = 1 * sz;
shape_matrix[10] = 1 * sz;
shape_matrix[15] = 1;
shape_matrix[3] = 0;
shape_matrix[7] = 0;
shape_matrix[11] = 0;
}
</script>
<script>
var MP5_GENERIC_EXAMPLE_MOON = {
"printerSettings":{
"name":"test", "layerThickness":0.2, "emptyLayer":0, "infillSpace":4, "topThickness":0.6, "paramSamples":75,
"speedRate":1000, "circleSpeedRate":1000, "temperature":220, "inAirSpeed":7000, "flowRate":0.035,
"criticalLength":35, "retractionSpeed":2400, "retractionLength":5, "shellNumber":3, "material":"PLA 2.85mm",
"autoZScar":true, "zScarGap":0.5, "critLayerTime":6, "filamentDiameter":2.85 },
"mp5-version":"0.3",
"root":{
"type":"root",
"children":[
{
"type":"Difference",
"protected":false,
"children":[
{
"type":"cylinder",
"displayColor":{ "x":0.77, "y":0.04, "z":0.18 },
"matrix":[ 42.5, 0, 0, 0, 0, 49.6, 0, 0, 0, 0, 10, 0, 0, 0, 0, 1 ],
"index":652818
},
{
"type":"Difference",
"protected":false,
"children":[
{
"type":"cylinder",
"displayColor":{"x":0.82, "y":0.66, "z":0.74 },
"matrix":[10, 0, 0, 0, 0, 10, 0, 0, 0, 0, 10, 0, 0, 0, 0, 1],
"index":1272174
},
{
"type":"cylinder",
"displayColor":{"x":0.11, "y":0.076,"z":0.63 },
"matrix":[10, 0, 0, 0.66, 0, 10, 0, 6.22, 0, 0, 10, 0.00001, 0, 0, 0, 1 ],
"index":2463576
}
],
"displayColor":{ "x":0.66, "y":0.45, "z":0.72 },
"matrix":[2.38, 0, 0, 0.36, 0, 2.38, 0, 0.56, 0, 0, 2.38, 6.9, 0, 0, 0, 1],
"index":413872
}
],
"displayColor":{"x":0.55, "y":0.07, "z":0.12 },
"matrix":[ 1, 0, 0, 0.33, 0, 1, 0, 0.156, 0, 0, 1, 0.000000000000014, 0, 0, 0, 1],
"index":6565922
}
]
}
};
var sz0 = 100.0;
var HEART = '{"printerSettings":{"name":"test","layerThickness":0.2,"emptyLayer":0,"infillSpace":4,"topThickness":0.6,"paramSamples":75,"speedRate":1000,"circleSpeedRate":1000,"temperature":220,"inAirSpeed":7000,"flowRate":0.035,"criticalLength":35,"retractionSpeed":2400,"retractionLength":5,"shellNumber":3,"material":"PLA 2.85mm","autoZScar":true,"zScarGap":0.5,"critLayerTime":6,"filamentDiameter":2.85},"mp5-version":"0.3","root":{"type":"root","children":[{"type":"Union","protected":false,"children":[{"type":"cylinder","displayColor":{"x":0.9661750055896976,"y":0.8085857086202395,"z":0.41578037212168595},"matrix":[10,0,0,-3.7368777450135866,0,10,0,-1.9559832356144682,0,0,10,1.7323194345664206e-7,0,0,0,1],"index":7575510},{"type":"cube","displayColor":{"x":0.23399071378141634,"y":0.31584816496653323,"z":0.35457351563365425},"matrix":[10,0,0,1.867397834493545,0,10,0,-1.7325527119763677,0,0,10,-9.734106853898084e-10,0,0,0,1],"index":5587759},{"type":"cylinder","displayColor":{"x":0.43814645627496795,"y":0.39556472441055845,"z":0.3415798414286939},"matrix":[10,0,0,1.8694799105200275,0,10,0,3.688535947590836,0,0,10,-1.7225853365943067e-7,0,0,0,1],"index":6657333}],"initialSize":{"x":1,"y":1,"z":1},"displayColor":{"x":0.6470588235294118,"y":0.2784313725490196,"z":0.5882352941176471},"matrix":[10.0,0,0,82.63768850593796,0,10.0,0,126.37324151118989,0,0,10.0,5.000000079354265,0,0,0,1],"index":4872526}]}}';
HEART = JSON.parse(HEART);
setShapeMatrix2Eye(HEART.root.children[0].matrix, sz0);
HEART = JSON.stringify(HEART);
var MOON = '{"printerSettings":{"name":"test","layerThickness":0.2,"emptyLayer":0,"infillSpace":4,"topThickness":0.6,"paramSamples":75,"speedRate":1000,"circleSpeedRate":1000,"temperature":220,"inAirSpeed":7000,"flowRate":0.035,"criticalLength":35,"retractionSpeed":2400,"retractionLength":5,"shellNumber":3,"material":"PLA 2.85mm","autoZScar":true,"zScarGap":0.5,"critLayerTime":6,"filamentDiameter":2.85},"mp5-version":"0.3","root":{"type":"root","children":[{"type":"Difference","protected":false,"children":[{"type":"cylinder","displayColor":{"x":0.7675997200783986,"y":0.03892568708507049,"z":0.1754374135888661},"matrix":[35,0,0,0,0,35,0,0,0,0,9,0,0,0,0,1],"index":652818},{"type":"Difference","protected":false,"children":[{"type":"cylinder","displayColor":{"x":0.8122645344236872,"y":0.657334404743416,"z":0.7357336310755096},"matrix":[10,0,0,0,0,10,0,0,0,0,10,0,0,0,0,1],"index":1272174},{"type":"cylinder","displayColor":{"x":0.11421729990684737,"y":0.07562705374348999,"z":0.6324600862122098},"matrix":[10,0,0,0.658889604636343,0,10,0,6.215549332615993,0,0,10,1.3327027659215673e-7,0,0,0,1],"index":2463576}],"initialSize":{"x":1,"y":1,"z":1},"displayColor":{"x":0.6627450980392157,"y":0.4549019607843137,"z":0.7215686274509804},"matrix":[2.381193509886417,0,0,0.3600215429489424,0,2.381193509886417,0,0.5604901669421452,0,0,2.381193509886417,6.9059681360437395,0,0,0,1],"index":413872}],"initialSize":{"x":1,"y":1,"z":1},"displayColor":{"x":0.5529411764705883,"y":0.06666666666666667,"z":0.11764705882352941},"matrix":[1,0,0,0.32938436512727,0,1,0,0.15604124684634,0,0,1,0.000000000000014,0,0,0,1],"index":6565922}]}}';
var SIMPLE_CONE = '{"printerSettings":{},"mp5-version":"0.3","root":{"type":"root","children":[{"type":"icone","displayColor":{"x":0.7,"y":0.7,"z":0.7},"matrix":[8,0,0,0,0,8,0,0,0,0,8,0,0,0,0,1],"index":9185154}]}}';
</script>
<script>
'use strict';
//'use asm';
//'use strict';
//Version 1 has flaws: _free()s before returning the verts.
//var CALL_VERSION = 2; //1 or 2
const VERBOSE = false;
//todo: reaplce _FLOAT_SIZE with Float32Array.
//const _FLOAT_SIZE = 4; //Float32Array.BYTES_PER_ELEMENT
//const _INT_SIZE = 4;
var global_time = 0;
'use strict';
var global_verts_copy = null;
var global_gradients_copy = null;
// const MESH_SCALE = 300/10;
const MESH_SCALE = 1.0;
const ARROWS_COUNT = 20*10;
var global_mp5 = "***";
function provide_input (subjective_time, is_update_mode) {
// is_update_mode: 0 => init
// is_update_mode: 1 => update
// is_update_mode: 2 => deprecated (used in make_geometry_old1() )
// asked for:
var shape_json, polygonization_json;
const DONT_CHANGE = false; // should be false
if (DONT_CHANGE || is_update_mode == 0) {
var r = subjective_time;
// var ellipsoid_radius = 8.0 * 0.1; // r;
var ellipsoid_radius = 8.0; // r;
var sphere_dict1 = {
type: "ellipsoid",
//radius: subjective_time,
matrix:[
ellipsoid_radius, 0,0, 0,
0,ellipsoid_radius, 0, 0,
0,0,ellipsoid_radius * 0.5 , 0,
0,0,0, 1]
};
var sphere_dict = {
type: "Union",
matrix:[
1, 0,0, 0,
0,1, 0, 0,
0,0,1, 0,
0,0,0, 1],
children: [sphere_dict1, sphere_dict1]
};
//global_mp5 = mp5_json_0;
var mp5_json_sphere_dict= JSON.parse(JSON.stringify(MP5_GENERIC_EXAMPLE_MOON));
mp5_json_sphere_dict.root.children=[sphere_dict];
var SPHERE = JSON.stringify(mp5_json_sphere_dict);
// console.log(SPHERE);
var tetrahedron_dict = {
type: "tetrahedron",
corners: [[0, 0, 5],[0, 10, 0],[10, 0, 0],[0, 0, -5]],
matrix:[
1, 0,0, 0,
0,1, 0, 0,
0,0,1, 0,
0,0,0, 1]
};
var mp5_json_tetrahedron_dict= JSON.parse(JSON.stringify(MP5_GENERIC_EXAMPLE_MOON));
mp5_json_tetrahedron_dict.root.children=[tetrahedron_dict];
var TETRAHEDRON = JSON.stringify(mp5_json_tetrahedron_dict);
// Select the object to display
// var mp5_json = HEART; const BB_SIZE = 9;
// var mp5_json = MOON; const BB_SIZE = 9+9;
// var mp5_json = TETRAHEDRON; const BB_SIZE = 9;
// var mp5_json = SPHERE; const BB_SIZE = 9;
var mp5_json = SIMPLE_CONE; const BB_SIZE = 12.0/10.0;
var shape_dict = JSON.parse(mp5_json).root.children[0];
if(is_update_mode == 0) {
var sz = 1.;
} else {
var sz = r;
}
/*
HEART.root.children[0].matrix[0] = sz;
HEART.root.children[0].matrix[5] = sz;
HEART.root.children[0].matrix[10] = sz;
*/
// Scale the object
shape_dict.matrix[0] = sz;
shape_dict.matrix[5] = sz;
shape_dict.matrix[10] = sz;
/*
// Move the object
shape_dict.matrix[3] = 0;
shape_dict.matrix[7] = 0;
shape_dict.matrix[11] = 0;
*/
if(false) {
setShapeMatrix2Eye(shape_dict.matrix);
}
//var bb = getBoundingBoxForTree();
mp5_json = JSON.stringify(shape_dict);
global_mp5 = mp5_json;
console.log(mp5_json);
var x0=0, y0=0, z0=0;
//var BB_SIZE = 18;
//const BB_SIZE = 9;
var mc_properties_json = JSON.stringify({
resolution: Math.floor(28/2*2/2*2 /4*4 /2 ),
box: {xmin: x0-BB_SIZE, xmax: x0+BB_SIZE, ymin: y0-BB_SIZE , ymax: y0+BB_SIZE, zmin: z0-BB_SIZE, zmax: z0+BB_SIZE},
ignore_root_matrix: false,
/*
vresampl: {iters: 3, c: 1.0},
projection: {enabled: 1},
qem: {enabled: 1},
*/
vresampl: {iters: 3, c: 1.0},
projection: {enabled: 1},
qem: {enabled: 1},
subdiv: {enabled: 1},
//overall_repeats: 3,
overall_repeats: 3,
debug: {
enabled_pointsets: 0,
// only_rank
post_subdiv_noise: 0.0,
},
// bug: When vresampl.iters is large, the centroid projection projects into 0 (0,0,0)
});
shape_json = mp5_json;
polygonization_json = mc_properties_json;
var tuple = [shape_json, polygonization_json];
return tuple;
}
//Alternatively, use a growing sphere only.
if(is_update_mode == 1 || is_update_mode == 2) {
//d("2 G.");
var x0=0, y0=0, z0=0;
const BB_SIZE = 9;
var r = subjective_time * 5;
//var BB_SIZE = 6.;
var mc_properties_json = JSON.stringify({
resolution: 14*2 / 2 * 2, // 28,
box: {xmin: x0-BB_SIZE, xmax: x0+BB_SIZE, ymin: y0-BB_SIZE , ymax: y0+BB_SIZE, zmin: z0-BB_SIZE, zmax: z0+BB_SIZE},
ignore_root_matrix: false,
// makes things very slow
vresampl: {iters: 1, c: 1.0},
projection: {enabled: 1},
qem: {enabled: 1},
});
//implisolid_.build_geometry( 28, mc_properties_json, "sphere", subjective_time);
/*
var mp5_json = JSON.stringify({
type: "ellipsoid",
//radius: r, //boudbl_mushroom only
matrix:[
r, 0,0, x0,
0,r, 0, y0,
0,0, r, z0,
0,0,0, 1]
});
shape_json = mp5_json;
*/
var d = JSON.parse(global_mp5);
var updated_size = r / 10.;
d.matrix[0] = updated_size;
d.matrix[5] = updated_size;
d.matrix[10] = updated_size;
shape_json = JSON.stringify(d);;
// shape_json = global_mp5;
polygonization_json = mc_properties_json;
//global_mp5 is not updated here. It is the original object before the update.
var tuple = [shape_json, polygonization_json];
return tuple;
}
/*
if(is_update_mode == 2) {
//not used anymore
//console.log(implisolid_);
//d("2 G..");
var x0=0, y0=0, z0=0;
var r = subjective_time;
var mc_properties_json = JSON.stringify({
resolution: 28,
box: {xmin: x0-1, xmax: x0+1, ymin: y0-1 , ymax: y0+1, zmin: z0-1, zmax: z0+1}
});
var mp5_json = JSON.stringify({
type: "egg",
//radius: 3.0, //double_mushroom only
matrix:[
r, 0,0, x0,
0,r, 0, y0,
0,0,r, z0,
0,0,0, 1]
});
shape_json = mp5_json;
polygonization_json = mc_properties_json;
var tuple = [shape_json, polygonization_json];
return tuple;
}
*/
}
function prepare_gradients1(implicit_service, shape_json, verts) {
var ignore_root_matrix = true;
const _FLOAT_SIZE = Float32Array.BYTES_PER_ELEMENT;
var result1 =
implicit_service.set_object(shape_json, ignore_root_matrix);
console.log("SET_OBJECT() RESULTS:", result1);
implicit_service.set_vect(verts); // overhead
implicit_service.calculate_implicit_gradients(true); // Why TRUE doe snot have any effect?
var ptr = implicit_service.get_gradients_ptr();
var ptr_len = implicit_service.get_gradients_size();
var gradients = Module.HEAPF32.subarray(ptr/_FLOAT_SIZE, ptr/_FLOAT_SIZE + ptr_len);
for( var i = 0 ; i < ptr_len; i++) {
// gradients[i] += (Math.random() *2 -1.0 )* 0.2;
}
// geom.update_normals_from_array(gradients);
return gradients;
}
function release_gradients1(implicit_service) {
implicit_service.unset_x();
var result1 =
implicit_service.unset_object(1);
console.log("UNSET_OBJ() RESULTS:", result1);
}
// DRY 6 folds!
function clone_array_float(verts) {
var raw_buffer = new ArrayBuffer( Float32Array.BYTES_PER_ELEMENT * verts.length);
var g = new Float32Array(raw_buffer);
g.subarray(0, verts.length).set(new Float32Array(verts));
return g;
}
function concatenate_array_float(verts1, verts2) {
var n1 = verts1.length;
var n2 = verts2.length;
var raw_buffer = new ArrayBuffer( Float32Array.BYTES_PER_ELEMENT * (n1 + n2) );
var verts12 = new Float32Array(raw_buffer);
verts12.subarray(0, n1).set(new Float32Array(verts1));
verts12.subarray(n1, (n1+n2)).set(new Float32Array(verts2)); // deliberate bug for TDD
return verts12;
}
function make_indices_for_n1_n2(n) {
var n1 = n;
var raw_buffer = new ArrayBuffer( Uint32Array.BYTES_PER_ELEMENT * (n1) * 3 );
var indices12 = new Uint32Array(raw_buffer);
for (var i=0; i < n1; i++) {
indices12[i * 3] = i;
indices12[i * 3 + 1] = i + n1; //i + n1;
indices12[i * 3 + 2] = i; //i + n1;
}
assert(indices12.length == n1 * 3);
return indices12;
}
/*
function clone_array_int(indices) {
var raw_buffer = new ArrayBuffer( Uint32Array.BYTES_PER_ELEMENT * indices.length);
var g = new Uint32Array(raw_buffer);
g.subarray(0, indices.length).set(new Uint32Array(indices));
return g;
}
*/
/*
Three ways:
1- make_geometry_oldold()
2- make_geometry_old1()
3- make_geometry_new2()
*/
function make_geometry_new2(implisolid_, shape_json, polygonization_json, reusable_geometry, re_allocate_buffers)
{
//console.log(shape_json);
//console.log(polygonization_json);
// reusable_geometry is not used;
var startTime = new Date();
if(implisolid_.needs_deallocation) { // Remove data from last round.
//console.log("implisolid_.needs_deallocation " + implisolid_.needs_deallocation);
//d(1);
implisolid_.finish_geometry();
implisolid_.needs_deallocation = false;
}
else{
//console.error("Should not get here");
//implisolid_.finish_geometry();
//implisolid_.needs_deallocation = false;
}
//implisolid_.finish_geometry();
//d("2 G");
//28*2 --> 27 sec 28->3.75--7 msec?
//////////////////////
//var mp5_json = "";
//var mc_properties_json = "";
//implisolid_.build_geometry( 28, mc_properties, "sphere", subjective_time);
//implisolid_.build_geometry( mp5_json , mc_properties_json);
try{
implisolid_.build_geometry( shape_json , polygonization_json);
} catch(e) {
console.error(e);
Module={}; // avoids calling Module.dynCall_vii(), etc.
}
//implicit_double_mushroom center will be zero.
implisolid_.needs_deallocation = true;
var nverts = implisolid_.get_v_size();
var nfaces = implisolid_.get_f_size();
if(VERBOSE){
console.log(nverts);
}
var verts_address = implisolid_.get_v_ptr();
var faces_address = implisolid_.get_f_ptr();
//no need to free anymore!
const _FLOAT_SIZE = Float32Array.BYTES_PER_ELEMENT;
var verts = Module.HEAPF32.subarray(verts_address/_FLOAT_SIZE, verts_address/_FLOAT_SIZE + 3*nverts);
const _INT_SIZE = Uint32Array.BYTES_PER_ELEMENT;
var faces = Module.HEAPU32.subarray(faces_address/_INT_SIZE, faces_address/_INT_SIZE + 3*nfaces);
/*
// Uncomment for visualising the mesh's normals when set according to Implicit gradients.
var gradients = prepare_gradients1(implisolid_, shape_json, verts);
global_verts_copy = clone_array_float(verts);
global_gradients_copy = clone_array_float(gradients);
*/
//verts[2] -= 0.1;
//verts[2 + nverts*3-3] += 0.3;
//var geom = new WGeometry77(verts, faces);
//var geom = new MyBufferGeometry77(verts, faces, re_allocate_buffers);
if(threejs_rev === THREEJS_R71) {
var geom = new LiveBufferGeometry71(verts, faces, re_allocate_buffers);
} else if(threejs_rev === THREEJS_R77) {
var geom = new MyBufferGeometry77(verts, faces, re_allocate_buffers);
} else if(threejs_rev === THREEJS_R79) {
//LiveBufferGeometry79( verts_, faces_, pre_allocate_, min_faces_capacity_, min_verts_capacity_)
var min_faces_capacity_ = 0, min_verts_capacity_ = 0;
var geom = new LiveBufferGeometry79(
verts, faces,
re_allocate_buffers,
min_faces_capacity_, min_verts_capacity_);
//, gradients); // Alternative: specify normals at creation of LiveGeometry. But this is fine.
//geom.update_geometry(implisolid_, true);
implisolid_.update_geometry(geom, true);
// Alternative: specify normals at creation of LiveGeometry. But this is fine.
implisolid_.make_normals_into_geometry(geom, shape_json, verts, false);
/*
var n = implisolid_.get_pointset_size("post_p_centroids");
var centroids = get_emc_array(
implisolid_.get_pointset_ptr("post_p_centroids")
, n * 3 );
implisolid_.make_normals_into_geometry(geom, shape_json, centroids, false);
*/
}
/*
release_gradients1(implisolid_);
*/
if(VERBOSE){
console.log("nverts : "+ nverts);
console.log("nfaces : "+ nfaces);
}
var endTime = new Date();
var timeDiff = endTime - startTime;
//console.log("Time: "+timeDiff+ " msec.");
report_time(timeDiff, function(){hist();});
return geom;
}
// todo: should work with point_count==0
function get_emc_array(verts_address, point_count) {
// var verts_address = implisolid_.get_pointset_ptr(name);
// var point_count = implisolid_.get_pointset_size(name);
const _FLOAT_SIZE = Float32Array.BYTES_PER_ELEMENT;
var float_array = Module.HEAPF32.subarray(verts_address/_FLOAT_SIZE, verts_address/_FLOAT_SIZE + 1 * point_count);
// console.error(float_array);
if (point_count == 0) {
console.warn("Error: zero points", point_count);
//return // null; // make_empty_lines_mesh();
}
return float_array;
}
function make_pointset(implisolid_, name, point_size, color_r, color_g, color_b) {
// r79 only
// var point_size = 15.0; // millimeters
var scale_up = 1.0;
point_size = point_size !== undefined? point_size : 15.0;
color_r = color_r !== undefined? color_r : 0.9;
color_g = color_g !== undefined? color_g : 0.9;
color_b = color_b !== undefined? color_b : 0.9;
// var dx = Math.random() * 1.0 * scale_up * 1;
// var dy = Math.random() * 1.0 * scale_up * 1;
// var dz = Math.random() * 1.0 * scale_up * 1;
// var dx = 1.0 * scale_up * 1;
// var dy = 1.0 * scale_up * 1;
// var dz = 1.0 * scale_up * 1;
var dx = 0, dy = 0, dz = 0;
/*
var verts_address = implisolid_.get_pointset_ptr(name);
var point_count = implisolid_.get_pointset_size(name);
const _FLOAT_SIZE = Float32Array.BYTES_PER_ELEMENT;
var verts = Module.HEAPF32.subarray(verts_address/_FLOAT_SIZE, verts_address/_FLOAT_SIZE + 3 * point_count);
*/
var point_count = implisolid_.get_pointset_size(name);
if (point_count == 0) {
return make_empty_lines_mesh();
}
var verts = get_emc_array(implisolid_.get_pointset_ptr(name), 3 * point_count );
// console.error(verts);
var geometry = new THREE.BufferGeometry();
var positions = verts; //new Float32Array( point_count * 3 );
var colors = new Float32Array( point_count * 3 );
for ( var i = 0; i < positions.length; i += 3 ) {
positions[ i ] = positions[ i ] * scale_up + dx;
positions[ i + 1 ] = positions[ i + 1 ] * scale_up + dy;
positions[ i + 2 ] = positions[ i + 2 ] * scale_up + dz;
}
for ( var i = 0; i < positions.length; i += 3 ) {
colors[ i ] = color_r;
colors[ i + 1 ] = color_g;
colors[ i + 2 ] = color_b;
}
geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
geometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) );
geometry.computeBoundingSphere();
//geometry is ready
var material = new THREE.PointsMaterial( { size: point_size, vertexColors: THREE.VertexColors } );
var points = new THREE.Points( geometry, material );
return points;
}
function make_lines_mesh_v1(verts12, indices12, color) {
if (indices12.length == 0) {
console.error("Warning: indices12.length =", indices12.length);
}
var re_allocate_buffers;
//var geom = new LiveBufferGeometry79( verts12, indices12, re_allocate_buffers=true, 0, 0);
var geom = new LiveBufferGeometry79( new Float32Array(new ArrayBuffer(0)), new Uint32Array(new ArrayBuffer(0)), re_allocate_buffers="Deliberately Empty", 0, 0);
geom.update_geometry1(verts12, indices12, true, true);
var wireframe_material = new THREE.MeshBasicMaterial( {
color: color, wireframe: true, opacity:0.9, transparent: true,} );
var wire_msh = new THREE.Mesh(geom, wireframe_material);
return wire_msh;
}
function make_empty_lines_mesh() {
return new THREE.LineSegments(new THREE.BoxGeometry(0.33333,0.3333333,0.33333333));
}
function make_vectorfield_flow_lines_v1(implisolid_, name1, name2, point_size) {
// works!
// vector field flow
/*
var color_r, color_g, color_b;
color_r = color_r !== undefined? color_r : 0.9;
color_g = color_g !== undefined? color_g : 0.9;
color_b = color_b !== undefined? color_b : 0.9;
*/
if (implisolid_.get_pointset_ptr(name1) == 0) {
}
var verts1 = get_emc_array(implisolid_.get_pointset_ptr(name1)+120*3*4*0, 3 * implisolid_.get_pointset_size(name1) + 0 );
var verts2 = get_emc_array(implisolid_.get_pointset_ptr(name2)+120*3*4*0, 3 * implisolid_.get_pointset_size(name2) + 0 );
var n1 = verts1.length / 3;
var n2 = verts2.length / 3;
if (n1 == 0) {
return make_empty_lines_mesh();
}
/*
n1 = 4*10;
n2 = 4*10;
var debug_mode = true;
verts1 = verts1.subarray(0, n1 * 3);
verts2 = verts2.subarray(0, n2 * 3);
*/
var verts12 = concatenate_array_float(verts1, verts2);
/*
var raw_buffer = new ArrayBuffer( Float32Array.BYTES_PER_ELEMENT * (n1 + n2) * 3);
var verts12 = new Float32Array(raw_buffer);
// var verts12 = new Float32Array(n1 + n2);
verts12.subarray(0, n1 * 3).set(new Float32Array(verts1));
verts12.subarray(n1 * 3, (n1+n2) * 3).set(new Float32Array(verts2)); // deliberate bug for TDD
*/
/*
for( var i=0; i<n2; i++) {
var b = (i+n1)*3;
verts12[b + 0] += (Math.random()*2-1)*10;
verts12[b + 1] += (Math.random()*2-1)*10;
verts12[b + 2] += (Math.random()*2-1)*10;
}
*/
if (n1 !== n2) {
console.error("Need to have the same number of elements.");
}
/*
// I don't use a geometry mesh with wiredframe. I use a LineSegments that uses a BufferGeometry
var raw_buffer = new ArrayBuffer( Uint32Array.BYTES_PER_ELEMENT * (n1) * 2 );
var indices12 = new Uint32Array(raw_buffer);
for (var i=0; i < n1; i++) {
indices12[i * 2] = i;
indices12[i * 2 + 1] = i ; //+ n1; //i+1; //i + n1;
// indices12[i * 2] = 0;
// indices12[i * 2 + 1] = i;
}
*/
var indices12 = make_indices_for_n1_n2(n1);
/*
var raw_buffer = new ArrayBuffer( Uint32Array.BYTES_PER_ELEMENT * (n1) * 3 );
var indices12 = new Uint32Array(raw_buffer);
for (var i=0; i < n1; i++) {
indices12[i * 3] = i;
indices12[i * 3 + 1] = i + n1; //i + n1;
indices12[i * 3 + 2] = i; //i + n1;
}
assert(indices12.length == n1 * 3);
*/
var wire_msh = make_lines_mesh_v1(verts12, indices12, 0xffffff);
/*
var line_material = new THREE.LineBasicMaterial({ vertexColors: THREE.VertexColors });
var wire_msh = new THREE.LineSegments(geom, line_material);
*/
return wire_msh;
}
function make_vectorfield_flow_lines_v2(implisolid_, name1, name2, point_size) {
// vector field flow. Without using LiveGEometry (and using LineSegments)
// does not work
/*
var color_r, color_g, color_b;
color_r = color_r !== undefined? color_r : 0.9;
color_g = color_g !== undefined? color_g : 0.9;
color_b = color_b !== undefined? color_b : 0.9;
*/
/*
var positions = [];
var next_positions_index = 0;
var colors = [];
var indices_array = [];
*/
var verts1 = get_emc_array(implisolid_.get_pointset_ptr(name1), 3 * implisolid_.get_pointset_size(name1) );
var verts2 = get_emc_array(implisolid_.get_pointset_ptr(name2), 3 * implisolid_.get_pointset_size(name2) );
var n1 = verts1.length / 3;
var n2 = verts2.length / 3;
assert(n1 > 0);
var verts12 = concatenate_array_float(verts1, verts2);
/*
var raw_buffer = new ArrayBuffer( Float32Array.BYTES_PER_ELEMENT * (n1 + n2) * 3);
var verts12 = new Float32Array(raw_buffer);
// var verts12 = new Float32Array(n1 + n2);
verts12.subarray(0, n1 * 3).set(new Float32Array(verts1));
verts12.subarray(n1 * 3, (n1+n2) * 3).set(new Float32Array(verts2)); // deliberate bug for TDD
*/
if (n1 !== n2) {
console.error("Need to have the same number of elements.");
}
// I don't use a geometry mesh with wiredframe. I use a LineSegments that uses a BufferGeometry
var raw_buffer = new ArrayBuffer( Uint16Array.BYTES_PER_ELEMENT * (n1) * 2 );
var indices12 = new Uint16Array(raw_buffer);
for (var i=0; i < n1; i++) {
indices12[i * 2] = i;
indices12[i * 2 + 1] = i + n1; //i+1; //i + n1;
}
var raw_buffer = new ArrayBuffer( Float32Array.BYTES_PER_ELEMENT * (n1) * 3 );
var colors_ta = new Float32Array(raw_buffer);
for (var i=0; i < n1; i++) {
colors_ta[i * 3] = (i/10.0) % 1.0;
colors_ta[i + 3 + 1] = (i/10.0) % 1.0;
colors_ta[i + 3 + 2] = (i/10.0) % 1.0;
}
// var indices12 = new Uint16Array( indices_array );
// var verts12 = new Float32Array( positions );
// var colors_ta = new Float32Array( colors );
var geom = new THREE.BufferGeometry();
geom.setIndex( new THREE.BufferAttribute( indices12, 1 ) );
geom.addAttribute( 'position', new THREE.BufferAttribute( verts12, 3 ) );
geom.addAttribute( 'color', new THREE.BufferAttribute( colors_ta, 3 ) );
geom.computeBoundingSphere();
// var line_material = new THREE.LineBasicMaterial({ vertexColors: THREE.VertexColors });
var line_material = new THREE.MeshBasicMaterial( {
color: 0xffffff, wireframe: true, opacity:0.8, transparent: true,} );
var wire_msh = new THREE.LineSegments(geom, line_material);
return wire_msh;
}
function hairy_object_based_on_vectors(vects, gradients, alpha1, alpha2, color) {
var n = gradients.length / 3;
var n1 = vects.length / 3;
assert(n == n1);
var arrow_tips = new Float32Array(new ArrayBuffer( n * 3 * Float32Array.BYTES_PER_ELEMENT));
var arrow_bases = new Float32Array(new ArrayBuffer( n * 3 * Float32Array.BYTES_PER_ELEMENT));
for (var i = 0; i < n; ++i) {
for (var d = 0; d < 3; d++) {
var j = (i * 3) + d;
arrow_tips[j] = vects[j] + alpha2 * gradients[j];
arrow_bases[j] = vects[j] + alpha1 * gradients[j];
}
}
var verts12 = concatenate_array_float(arrow_bases, arrow_tips);
/*
// repeated code
var raw_buffer = new ArrayBuffer( Float32Array.BYTES_PER_ELEMENT * (n + n) * 3);
var verts12 = new Float32Array(raw_buffer);
verts12.subarray(0, n * 3).set(new Float32Array(arrow_bases));
verts12.subarray(n * 3, (n+n) * 3).set(new Float32Array(arrow_tips)); //
*/
var indices12 = make_indices_for_n1_n2(n);
/*
//repeated code
var raw_buffer = new ArrayBuffer( Uint32Array.BYTES_PER_ELEMENT * (n) * 3 );
var indices12 = new Uint32Array(raw_buffer);
for (var i=0; i < n; i++) {
indices12[i * 3] = i;
indices12[i * 3 + 1] = i + n; //i + n;
indices12[i * 3 + 2] = i + n; //i + n;
}
assert(indices12.length == n * 3);
*/
var wire_msh = make_lines_mesh_v1(verts12, indices12, color)
return wire_msh;
}
function visualise_normals(implisolid_, shape_json, pointset_label, alpha1, alpha2, color) {
/*
Draws lines from alpha1*grad to alpha2*grad.
alpha1,2 are the start and end of the lines parallel to the gradients. Most likely negative alpha values are used.
alpha=0 means points specified from the pointset specified by label pointset_label. Using color.
Example: alpha1=0.0 and alpha2=-1.0 will draw normals (outwards). color = 0x88ff00;
*/
// todo: refactor
var n = implisolid_.get_pointset_size(pointset_label);
if (n == 0) {
return make_empty_lines_mesh();
}
var verts = get_emc_array(implisolid_.get_pointset_ptr(pointset_label),
n * 3 );
// verts = arrow_bases
// see update_arrows()
var ignore_root_matrix = false;
var mp5_str = shape_json;
// console.error(mp5_str);
var result1 =
implisolid_.set_object(mp5_str, ignore_root_matrix);
console.log("SET_OBJECT() RESULTS:", result1);
implisolid_.set_vect(verts);
implisolid_.calculate_implicit_gradients();
const _FLOAT_SIZE = Float32Array.BYTES_PER_ELEMENT;
var ptr = implisolid_.get_gradients_ptr();
var ptr_len = implisolid_.get_gradients_size();
var gradients = Module.HEAPF32.subarray(
ptr/_FLOAT_SIZE, ptr/_FLOAT_SIZE + ptr_len);
assert(ptr_len == n*3);
for (var i = 0; i < n; ++i) {
var r = Math.sqrt(gradients[i*3 + 0] * gradients[i*3 + 0] + gradients[i*3 + 1] * gradients[i*3 + 1] + gradients[i*3 + 2] * gradients[i*3 + 2]);
gradients[i*3 + 0] /= r;
gradients[i*3 + 1] /= r;
gradients[i*3 + 2] /= r;
}
var wire_msh = hairy_object_based_on_vectors(verts, gradients, alpha1, alpha2, color);
/*
var raw_buffer = new ArrayBuffer( n * 3 * Float32Array.BYTES_PER_ELEMENT);
var arrow_tips = new Float32Array(raw_buffer);
var raw_buffer = new ArrayBuffer( n * 3 * Float32Array.BYTES_PER_ELEMENT);
var arrow_bases = new Float32Array(raw_buffer);
for (var i = 0; i < n; ++i) {
for (var d = 0; d < 3; d++) {
var j = (i * 3) + d;
arrow_tips[j] = verts[j] + alpha2 * gradients[j];
arrow_bases[j] = verts[j] + alpha1 * gradients[j];
}
}
// repeated code
var raw_buffer = new ArrayBuffer( Float32Array.BYTES_PER_ELEMENT * (n + n) * 3);
var verts12 = new Float32Array(raw_buffer);
verts12.subarray(0, n * 3).set(new Float32Array(arrow_bases));
verts12.subarray(n * 3, (n+n) * 3).set(new Float32Array(arrow_tips)); //
//repeated code
var raw_buffer = new ArrayBuffer( Uint32Array.BYTES_PER_ELEMENT * (n) * 3 );
var indices12 = new Uint32Array(raw_buffer);
for (var i=0; i < n; i++) {
indices12[i * 3] = i;
indices12[i * 3 + 1] = i + n; //i + n;
indices12[i * 3 + 2] = i + n; //i + n;
}
assert(indices12.length == n * 3);
var wire_msh = make_lines_mesh_v1(verts12, indices12, color)
*/
implisolid_.unset_x();
var result1 =
implisolid_.unset_object(1);
console.log("UNSET_OBJ() RESULTS:", result1);
return wire_msh;
}
function my_assert(cond, text){if(!cond){console.error("ASSERT FAILED: "); if(text) console.log(text);}}
//unload
function update_reused_geometry(implisolid_, mp5_json, mc_properties_json, geometry) {
//console.log(mp5_json);
//console.log(mc_properties_json);
var startTime = new Date();
//console.log(implisolid_.needs_deallocation);
if(implisolid_.needs_deallocation) { // Remove data from last round.
//d(1);
implisolid_.finish_geometry();
implisolid_.needs_deallocation = false;
}
if(implisolid_.needs_deallocation)
console.error("not deallocated.");
try{
implisolid_.build_geometry( mp5_json , mc_properties_json);
//implicit_double_mushroom center will be zero.
implisolid_.needs_deallocation = true;
}catch(err){
console.error("An error occured during MCC C++")
console.info(err);
}finally {
}
var ignore_normals = false
// geometry. update_geometry (implisolid_, ignore_normals);
implisolid_. update_geometry (geometry, ignore_normals);
var endTime = new Date();
var timeDiff = endTime - startTime;
//console.log(nv3 + " , " + nf3);
//console.log("Time: "+timeDiff+ " msec.");
report_time(timeDiff);
}
'use strict';
//*************** Arrow Functions ****************************
/*
function make_arrow(){
// Create an arrow and add it to the scene.
var dir = new THREE.Vector3( 10, 4, 0);
var origin = new THREE.Vector3(0, 0, 0);
var length = 10;
var hex = 0xffff00;
var arrowHelper = new THREE.ArrowHelper(dir, origin, length, hex);
scene.add(arrowHelper);
console.log("Arrow");
return arrowHelper;
}
*/
function make_multiple_arrows(n) {
/**
* Create an arrow and add it to the scene.
*/
var arrowHelpers = [];
for(var i=0;i<n;i++) {
var dir = new THREE.Vector3( 10, 4, 0);
var origin = new THREE.Vector3(0, 0, 0);
var length = 10;
var hex = 0xffff00;
var arrowHelper = new THREE.ArrowHelper(dir, origin, length, hex);
scene.add(arrowHelper);
arrowHelpers.push(arrowHelper);
console.log("Arrow");
}
return arrowHelpers;
}
function update_arrows(arrows, implisolid_, mp5_str, n, ignore_root_matrix) {
/**
* Update the arrow parameters
*/
var vlist = new Float32Array(n*3);
for(var i=0;i<n;i++) {
var x = MESH_SCALE*10 * (Math.random()*2 - 1.);
var y = MESH_SCALE*10 * (Math.random()*2 - 1.);
var z = MESH_SCALE*10 * (Math.random()*2 - 1.);
/*vlist.push(x);
vlist.push(y);
vlist.push(z);*/
vlist[i*3+0] = x;
vlist[i*3+1] = y;
vlist[i*3+2] = z;
}
//var _verts = new Float32Array([x, y, z]);
//var _verts = new Float32Array(vlist);
var _verts = vlist;
assert(_verts instanceof Float32Array);
var result1 =
implisolid_.set_object(mp5_str, ignore_root_matrix);
console.log("SET_OBJECT() RESULTS:", result1);
implisolid_.set_vect(_verts);
implisolid_.calculate_implicit_gradients();
const _FLOAT_SIZE = Float32Array.BYTES_PER_ELEMENT;
var ptr = implisolid_.get_gradients_ptr();
var ptr_len = implisolid_.get_gradients_size();
var g = Module.HEAPF32.subarray(ptr/_FLOAT_SIZE, ptr/_FLOAT_SIZE + ptr_len);
//console.log("grad len = " + ptr_len+ " grad = " + g); // x 4
var dir = null;
for(var i=0;i<n;i++) {
//if not bush
var x = _verts[i*3 + 0];
var y = _verts[i*3 + 1];
var z = _verts[i*3 + 2];
var gx = g[i*3 + 0];
var gy = g[i*3 + 1];
var gz = g[i*3 + 2];
//implisolid_.unset_x();
//implisolid_.unset_object(1);
//console.log("*****************************************")
//console.log(arrow.position);
//console.log("*****************************************")
//arrow.setLength(200*Math.random());
var l = Math.sqrt(gx*gx + gy*gy + gz*gz);
//l = l * 100/10000;
//console.log("l: "+l);
var ls = MESH_SCALE*1.5;
arrows[i].position.set(x, y, z);
arrows[i].setLength(ls);
// This can easily get broken. i.e. by multiplying ls.
if (!dir) {
dir = new THREE.Vector3( 0, 0, 0);
}
dir.set(-gx/l, -gy/l, -gz/l);
arrows[i].setDirection(dir);
//console.log("change_arrow");
}
implisolid_.unset_x();
var result1 =
implisolid_.unset_object(1);
console.log("UNSET_OBJ() RESULTS:", result1);
}
// **************************************************************
// global variables for meshes that are accessed and updated in the render loop, etc.
var mesh_solid;
var mesh2_tiny_box_wireframe;
var m