@sohale/implisolid
Version:
A Solid Modelling Kernel in Javascript based on Implicit Surfaces, for MP5 file format
1,475 lines (1,177 loc) • 50.4 kB
HTML
<html>
<head>
<meta charset="utf-8"/>
</head>
<style>
.stat-panel{
position:fixed;
top:0px;
right:0px;
width:100px;
/* z-index:1000; */
}
.mycanvas {
/* width: 100%; */
/* Will not work ion canvas, because the size is later changed by JS code. Note that "width=" attriute and css width are independent: one is the pixels resolution and the other one is appearance onle, regarless of the actual pixels (resolution). */
}
</style>
<body>
<canvas class=mycanvas id="my_canvas"></canvas>
<!-- To show the histogram: Uncomment the following <div> to reveal the histogram graph, also uncomment the line that says: //hist_delayed(); -->
<div id="chart_div" class="stat-panel" no_style="width: 900px; height: 500px;">
</div>
This file uses ImpliSolid's Geometry class. (unlike <a href="mcc2_3js.html">mcc2_3js.html</a>).
<br/>
Press SHIFT to animate. *
</body>
<!--
<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>
// 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>
function my_assert(cond, text){
if (!cond) {
console.error("ASSERT FAILED: ");
if(text)
console.log(text);
}
}
function my_assert(cond, message) {
if (!cond) {
if (message)
console.error("assert failed: ", message);
else
console.error("assert failed");
throw new Error("assert failed: ", message);
}
}
assert = my_assert;
function _expect(cond, message) {
if (!cond) {
console.error(message);
}
}
</script>
<!-- function callMultipleTimes (implisolid_, update_callback, burst_count, interval_msec): -->
<script type="text/javascript" src="../js_iteration_2/js/call_multiple_times.js"></script>
<!--script type="text/javascript" src="./legacy/geometry77.js"></script-->
<script type="text/javascript" src="../js_iteration_2/geometry79.js"></script>
<!--<script type="text/javascript" src="../js_iteration_2/js/geometry73.js"></script>-->
<!-- <script type="text/javascript" src="../js_iteration_2/bbox_calculations.js"></script> -->
<script type="text/javascript" src="../js_iteration_2/implisolid_main.js"></script>
<script type="text/javascript" src="../js_iteration_2/examples/js/example_objects.js"></script>
<script type="text/javascript" src="../js_iteration_2/js/js_utils.js"></script> <!-- stuff used by pointset_utils.js -->
<script type="text/javascript" src="../js_iteration_2/js/pointset_utils.js"></script>
<script type="text/javascript" src="../js_iteration_2/js/arrow_utils.js"></script>
<script type="text/javascript" src="../js_iteration_2/examples/js/example_materials.js"></script>
<script type="text/javascript" src="../js_iteration_2/examples/js/performance_graphs.js"></script>
<script type="text/javascript" src="../js_iteration_2/examples/js/misc_props.js"></script>
<!-- Graph -->
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<!--<div id="chart_div" style="width: 900px; height: 500px;"></div>-->
<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;
</script>
<!--
<script>
// This 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={}; //destroying. for test
s_service.__update_geometry = function(geometry, ignoreNormals) {
// refactor as: get_latest_vf()
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={}; //destroying. for test
s_service.init();
//console.log("ok");
//return s_service;
return {};
}
</script>
-->
<script>
'use strict';
</script>
<script>
</script>
<script>
'use strict'; //'use asm';
//Version 1 has flaws: _free()s before returning the verts.
//var CALL_VERSION = 2; //1 or 2
const VERBOSE = false;
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;
//globals.global_mp5 = "***";
// some code moved into js_utils.js
/*
Three ways:
1- make_geometry_oldold()
2- make_geometry_old1()
3- make_geometry_new2()
*/
/*
function ___make_geometry_new2(implisolid_, shape_json, polygonization_json, re_allocate_buffers, geom_callback)
{
//console.log(shape_json);
//console.log(polygonization_json);
// reusable_geometry =null, 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);
var geom = geom_callback(verts,faces, re_allocate_buffers);
var endTime = new Date();
var timeDiff = endTime - startTime;
//console.log("Time: "+timeDiff+ " msec.");
report_time(timeDiff, function(){hist();});
return geom;
}
*/
var geom_callback__1 = function (verts, faces, re_allocate_buffers) {
/*
// 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.
*/
var min_faces_capacity_ = 0, min_verts_capacity_ = 0; // force zero initial allocation
var geom = new LiveBufferGeometry79(
verts, faces,
re_allocate_buffers,
min_faces_capacity_, min_verts_capacity_);
//geom.update_geometry(implisolid_, true);
//implisolid_.update_geometry(geom, true);
IMPLICIT.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);
IMPLICIT.make_normals_into_geometry(geom, shape_json, verts, false);
/*
var n = implisolid_.get_pointset_size("post_p_centroids");
var centroids = PS_UTILS.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);
}
return geom;
}
//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);
// called after build_geometry()
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';
// **************************************************************
// global variables for meshes that are accessed and updated in the render loop, etc.
var globals = {};
globals.mesh_solid = null;
globals.mesh_wireframe = null;
globals.normals = null;
globals.arrows = null;
globals.chosen_matrial = null;
globals.global_mp5 = "***";
var mesh2_tiny_box_wireframe;
var materials_list; //, material_f;
var material_wireframe;
//var last_geometry = null;
// DEMO CONFIGURATIONS
const CHOSEN_MATERIAL_INDEX = 2; //14;
//2; nice //3;
// 7 = colourful
// 3 = ?
//1: grayscale boring phong.
//2: faceted. (good for debug / shape study)
//3: colorful
//4: semi opaque (good for debug / shape study)
//6: striped
//7: rainbow
//8 is wireframe
//9: plain white?
//10: changing peach
//11: changing cyan
//12: ??? white?
//13: proper Phong (As in WeDesign.Live)
//14: Phong but semi-transparent
const SHOW_WIREFRAME = false;
const SHOW_SOLID = true;
const PERSPECTIVE = false;
function init_scene(IMPLICIT, shape_json, polygonization_json) {
// determins the size & location of the grid, the location of the camera, and the size of the small cube in center (reference cube).
var GRID_CELL_SIZE = 1.0;
scene = new THREE.Scene();
//var WIDTH = 300, HEIGHT = 300;
var WIDTH = window.innerWidth,
HEIGHT = window.innerHeight - 0*200; //for memory profiler
if (PERSPECTIVE) {
camera = new THREE.PerspectiveCamera( 75, WIDTH / HEIGHT, 1, 10000 );
// ( fov, aspect, near, far )
} else {
// Use Orthogaphic camera
var span_per_pixel = 1.0/800.0*2000.0/30.0;
var x0 = WIDTH/2.0*span_per_pixel;
var y0 = HEIGHT/2.0*span_per_pixel;
camera = new THREE.OrthographicCamera( -x0, +x0, -y0, +y0, 1, 10000 ); // ( left, right, top, bottom, near, far )
}
camera.position.set(0, 0, 40*GRID_CELL_SIZE); // 40*25; //1000;
// Grid
var grid = grid_bed(GRID_CELL_SIZE);
scene.add( grid );
materials_list = look_nice();
globals.chosen_matrial = materials_list[CHOSEN_MATERIAL_INDEX];
//globals.chosen_matrial = new THREE.MeshBasicMaterial( {
// color: 0xaaffff, wireframe: false, opacity:0.5, transparent: true,
// side:THREE.DoubleSide } );
//THREE.FrontSide or THREE.BackSide or THREE.DoubleSide.
material_wireframe = new THREE.MeshBasicMaterial( {
color: 0xff0000, wireframe: true, opacity:0.3, transparent: true,} );
// //if(delta_t === undefined)
// var delta_t = 0.2;
// // Subjective time!
// global_time += delta_t;
var geometry = null;
//geometry = new THREE.BoxGeometry( 200, 200, 200 );
/*
if(CALL_VERSION==1){
//geometry = make_geometry_oldold(shape_json, polygonization_json);
}
else
*/
{
/* OLD
geometry = make_geometry_new2(implisolid_, shape_json, polygonization_json, true, geom_callback__1);
*/
var ignore_root_matrix = false;
console.warn("bad: ignore_root_matrix not known", ignore_root_matrix);
geometry = IMPLICIT.getLiveGeometry_from_json(shape_json, polygonization_json, true, geom_callback__1, ignore_root_matrix);
}
//last_geometry = geometry;
if(SHOW_WIREFRAME){
globals.mesh_wireframe = new THREE.Mesh( geometry, material_wireframe );
globals.mesh_wireframe.position.set( 0, 0, 0 );
globals.mesh_wireframe.scale.set( MESH_SCALE, MESH_SCALE, MESH_SCALE );
scene.add( globals.mesh_wireframe );
}
//this.fromBufferGeometry( new THREE.SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) );
//material_f = new THREE.MeshBasicMaterial( { color: 0xffffff, wireframe: false, opacity:0.4, transparent: true } );
if(SHOW_SOLID){
//globals.mesh_solid = new THREE.Mesh( geometry, material_f );
//nice ones: 2, 3, (checked until 4)
globals.mesh_solid = new THREE.Mesh( geometry, globals.chosen_matrial );
globals.mesh_solid.position.set( 0, 0, 0 );
globals.mesh_solid.scale.set( MESH_SCALE, MESH_SCALE, MESH_SCALE );
scene.add( globals.mesh_solid );
}
/*
var points2 = PS_UTILS.make_pointset("pre_resampling_vertices", 8.0 / 4.0, 0.9, 0.0, 0.0); // Red: before
scene.add( points2 );
var points1 = PS_UTILS.make_pointset("post_resampling_vertices", 10.0 / 4.0, 0.9, 0.9, 0.0); // Yellow: after
scene.add( points1 );
*/
/*
var points2 = PS_UTILS.make_pointset("pre_qem_verts", 2.0 / 30.0, 0.9, 0.0, 0.0); // Red: before
scene.add( points2 );
*/
/*
var points1q = PS_UTILS.make_pointset("post_qem_verts", 2.5 / 30.0 * 6.0, 0.9, 0.9, 0.0); // Yellow: after
scene.add( points1q );
*/
var alpha1 = -0.3, alpha2 = -0.6;
var norms_ = PS_UTILS.visualise_normals(shape_json, "post_p_centroids", alpha1, alpha2, 0x009900); // 0x00ff00 // 0x88ff00
if (norms_) {
scene.add(norms_);
}
globals.normals = norms_;
var points2 = PS_UTILS.make_pointset("pre_p_centroids", 8.0 / 4.0*2 / 30.0, 0.9, 0.0, 0.0); // Red: before
// scene.add( points2 );
var points1 = PS_UTILS.make_pointset("post_p_centroids", 10.0 / 4.0 / 30.0, 0.9, 0.9, 0.0); // Yellow: after
scene.add( points1 );
/*
// "Centroid Projection"'s result.
var vectorfield = PS_UTILS.make_vectorfield_flow_lines_v1("pre_p_centroids", "post_p_centroids");
scene.add( vectorfield );
*/
// "QEM"'s result.
var vectorfield = PS_UTILS.make_vectorfield_flow_lines_v1("pre_qem_verts", "post_qem_verts");
scene.add( vectorfield );
// Visualising the normal vectors as queried and applied on t geometry. Normal vector for vertices is a bad idea. Need to see how normal vectors can be specified for facets of BufferGeometry.
if ( global_verts_copy && global_gradients_copy ) {
var hairy_m = PS_UTILS.hairy_object_based_on_vectors(global_verts_copy, global_gradients_copy, 0.0, 1.0, 0x777700);
scene.add( hairy_m );
}
// choose what is visible and what is not
// globals.mesh_solid.visible = false;
// points1.visible = false;
//points2.visible = false;
// globals.mesh_wireframe.visible = false;
// vectorfield.visiable = false;
// norms_.visible = false;
// globals.normals.visible = false;
/*
var points2 = PS_UTILS.make_pointset("pre_qem_verts", 8.0 / 4.0, 0.9, 0.0, 0.0); // Red: before
scene.add( points2 );
var points1 = PS_UTILS.make_pointset("post_qem_verts", 10.0 / 4.0, 0.9, 0.9, 0.0); // Yellow: after
scene.add( points1 );
*/
// Show a cube in center
var geo2 = new THREE.BoxGeometry( GRID_CELL_SIZE, GRID_CELL_SIZE, GRID_CELL_SIZE );
mesh2_tiny_box_wireframe = new THREE.Mesh( geo2, material_wireframe );
mesh2_tiny_box_wireframe .position.set( 0, 0, 0 );
scene.add( mesh2_tiny_box_wireframe );
//mesh2_tiny_box_wireframe .scale.set( 10, 10, 10 );
var dirLight = new THREE.DirectionalLight(0xffffff, 1);
dirLight.position.set(100, 100, 50);
scene.add(dirLight);
var dirLight2 = new THREE.DirectionalLight(0x00ffff, 1);
dirLight2.position.set(-100, -100, -50);
scene.add(dirLight2);
//var arrow = make_arrow();
//global_arrow = arrow;
var arrows__ = make_multiple_arrows(ARROWS_COUNT);
globals.arrows = arrows__;
if(VERBOSE){
console.log("RENDERER");
}
var render_canvas = document.getElementById( 'my_canvas' );
my_assert(render_canvas);
console.log(render_canvas);
renderer = new THREE.WebGLRenderer( { antialias: true, canvas: render_canvas } );
//renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setSize( WIDTH, HEIGHT );
document.body.appendChild( renderer.domElement );
/*
function callMultipleTimes() {
var mc_icounter=0;
setInterval(function(){ if(mc_icounter<10) update_mc(implisolid_, 0.2/10.*5); mc_icounter++; }, 30);
}
*/
function doKeyDownListener(event) {
const CONTROL_KEY = 17;
const SHIFT_KEY = 16;
if ( event.keyCode == SHIFT_KEY ) {
var BURST_COUNT = 5; // 50;
var INTERVAL_MSEC = 100; // 8-1; //40 // 1 // in Milliseconds
//update_mc(implisolid_);
callMultipleTimes (BURST_COUNT, INTERVAL_MSEC, function(){
update_mc(IMPLICIT, 0.2/10.*5 /5.);
});
//change_arrow(arrow, implisolid_, globals.global_mp5);
}
else
console.log("\"keydown\" code", event.keyCode);
}
window.addEventListener( "keydown", doKeyDownListener, false ); // keydown keypress
// CONTROLS
//see https://github.com/mrdoob/three.js/blob/master/examples/webgl_geometry_teapot.html
var cameraControls = new THREE.OrbitControls( camera, renderer.domElement );
cameraControls.rotateSpeed = 1.5;
cameraControls.zoomSpeed = 1.2;
cameraControls.panSpeed = 0.8;
cameraControls.enableZoom = true;
cameraControls.enablePan = true;
cameraControls.enableDamping = true;
cameraControls.dampingFactor = 0.6; //0.9; // 1.0; //motile: 0.3;
/*
cameraControls.constraint.smoothZoom = true;
cameraControls.constraint.zoomDampingFactor = 0.2;
cameraControls.constraint.smoothZoomSpeed = 5.0;
*/
cameraControls.target.set( 0, 0, 0 );
cameraControls.addEventListener( 'change', function () {;} );
}
function update_mc(implisolid_, delta_t){
if(delta_t === undefined)
delta_t = 0.2;
// Subjective time!
global_time += delta_t;
var tuple = provide_input(global_time, 1, globals);
var shape_json = tuple.shape_json;
var polygonization_json = tuple.polygonization_json;
assert(typeof polygonization_json !== "string");
//Three modes of speed here for (UPDATE_SAME_GEOM_OBJECT, EVEN_REUSE_MESH_OBJECT):
// (false, false) // Creates a new Geometry object at each loop iteration.
// (true, false) // Keeps geometry object instance
// (true, true) // Keeps mesh instance (as well as geometry)
var UPDATE_SAME_GEOM_OBJECT = true; //Will not even call the constructor
var EVEN_REUSE_MESH_OBJECT = true;
if( EVEN_REUSE_MESH_OBJECT && ! UPDATE_SAME_GEOM_OBJECT)
console.error("Wrong condition.");
if(SHOW_SOLID){
var p1 = [globals.mesh_solid.position, globals.mesh_solid.rotation];
}
if(SHOW_WIREFRAME){
var p2 = [globals.mesh_wireframe.position, globals.mesh_wireframe.rotation];
}
// g i.e. actual_current_active_geom
var g = null;
if(SHOW_SOLID){
g = globals.mesh_solid.geometry;
}
if(SHOW_WIREFRAME){
g = globals.mesh_wireframe.geometry;
}
my_assert(g, "SHOW_SOLID and SHOW_WIREFRAME cannot be both false.");
if(!EVEN_REUSE_MESH_OBJECT){
if(SHOW_SOLID){
scene.remove(globals.mesh_solid);
}
if(SHOW_WIREFRAME){
scene.remove(globals.mesh_wireframe);
}
}
var reused_last_geom = g;
//Not sure about the condision
if(!UPDATE_SAME_GEOM_OBJECT){
if(SHOW_SOLID){
g.dispose();
g = null;
// reused_last_geom is not null and will remain. It is not recommended to use reused_last_geom.
}
//globals.mesh_wireframe.geometry.dispose(); // Don't do it twice!
}
// var reused_last_geom = g;
if(!EVEN_REUSE_MESH_OBJECT){
globals.mesh_solid = null;
globals.mesh_wireframe = null;
}
var geometry = null;
if(UPDATE_SAME_GEOM_OBJECT) {
geometry = g;
//update_reused_geometry(implisolid_, global_time, geometry);
// shape_json: from update,
//OLD// update_reused_geometry(implisolid_, shape_json, polygonization_json, geometry);
var ignoreNormals = false;
IMPLICIT.update_geometry_from_json(geometry, shape_json, polygonization_json, ignoreNormals)
}
else {
/*
if(CALL_VERSION==1){
//geometry = make_geometry_oldold(shape_json, polygonization_json);
}
else
*/
{
//reused_last_geom = null;
//OLD// geometry = make_geometry_new2(implisolid_, shape_json, polygonization_json, false, geom_callback__1); //FALSE??
}
var ignoreNormals = false;
geometry = IMPLICIT.getLiveGeometry(shape_json, polygonization_json, ignoreNormals)
};
/*
"";
for(var i=0;i<10*3;i++){
//geometry.attributes.position.setXYZ( i, x, y, z );
geometry.attributes.position.array[i] += 0.0002 * (i% 2);
//geometry.index.array[ i ] += (i % 2)*40 ;
var nverts = geometry.attributes.position.count/3;
geometry.index.array[ i ] = (geometry.index.array[ i ] % (nverts));
}
//geometry.attributes.position.needsUpdate = true;
//geometry.index.needsUpdate = true;
"";
*/
/*
// SLOW. But using -o3 compilation it can make a nice live smooth QEM demo.
if (globals.normals) {
scene.remove(globals.normals);
globals.normals = null
}
var alpha = 60.0;
var norms_ = PS_UTILS.visualise_normals(globals.global_mp5, "post_p_centroids", 0, alpha, 0x009900); // 0x00ff00 // 0x88ff00
scene.add(norms_);
globals.normals = norms_;
*/
/*
var ignore_root_matrix = false;
update_arrows(globals.arrows, implisolid_, globals.global_mp5, ARROWS_COUNT, ignore_root_matrix);
*/
if(!EVEN_REUSE_MESH_OBJECT){
if(SHOW_WIREFRAME){
globals.mesh_wireframe = new THREE.Mesh( geometry, material_wireframe );
globals.mesh_wireframe.scale.set( MESH_SCALE, MESH_SCALE, MESH_SCALE );
//copy so that we dont lose the rotation, position of the meshes.
globals.mesh_wireframe.position.copy(p2[0]);
globals.mesh_wireframe.rotation.copy(p2[1]);
scene.add( globals.mesh_wireframe );
}
/*var material1 = new THREE.MeshPhongMaterial( {
color: 0xaaaaaa, specular: 0xffffff, shininess: 250,
side: THREE.DoubleSide, vertexColors: THREE.VertexColors
} );
globals.mesh_solid = new THREE.Mesh( geometry, material1 );
*/
if(SHOW_SOLID){
globals.mesh_solid = new THREE.Mesh( geometry, globals.chosen_matrial );
// //globals.mesh_solid.position.set( 0, 0, 0 );
globals.mesh_solid.scale.set( MESH_SCALE, MESH_SCALE, MESH_SCALE );
globals.mesh_solid.position.copy(p1[0]);
globals.mesh_solid.rotation.copy(p1[1]);
scene.add( globals.mesh_solid );
}
}
}
function animate() {
requestAnimationFrame( animate );
//Updating the meshes
var SPEED = 0 * 3. / 100;
if(globals.mesh_wireframe){
globals.mesh_wireframe.rotation.x += 0.01*SPEED;
globals.mesh_wireframe.rotation.y += 0.02*SPEED;
}
if(globals.mesh_solid){
globals.mesh_solid.rotation.x += 0.01*SPEED;
globals.mesh_solid.rotation.y += 0.02*SPEED;
}
mesh2_tiny_box_wireframe .rotation.z += 0.01*SPEED;
mesh2_tiny_box_wireframe .rotation.y += 0.02*SPEED;
//Updating the matrials
//material update callback
//materials_list[ materials_list.length - 2 ].emissive.setHSL( 0.54, 1, 0.35 * ( 0.5 + 0.5 * Math.sin( 35 * global_time / 20. ) ) );
//materials_list[ materials_list.length - 3 ].emissive.setHSL( 0.04, 1, 0.35 * ( 0.5 + 0.5 * Math.cos( 35 * global_time / 20.) ) );
renderer.render( scene, camera );
}
var scene, camera, renderer;
//var geometry;
</script>
<!--script type="text/javascript" src="wwexample1.js"></script-->
<script type="text/javascript">
if(0){
//worker example
if (window.Worker) {
var myWorker = new Worker("wwexample1.js");
myWorker.postMessage({a:3, b:6});
myWorker.postMessage({a:8, b:9});
myWorker.onmessage = function(e) {
console.log('I received this from worker');
//console.log(e);
console.log(e.data);
/*
bubbles : false
cancelBubble : false
cancelable : false
currentTarget : Worker
data : Object
defaultPrevented : false
eventPhase : 0
isTrusted : true
isTrusted : true
lastEventId : ""
origin : ""
path : Array[0]
ports : Array[0]
returnValue : true
source : null
srcElement : Worker
target : Worker
timeStamp : 1555.6200000000001
type : "message"
*/
}
}
else{
console.warning("Your browser does not support WebWorkers. See http://stackoverflow.com/questions/4739916/what-browsers-currently-support-web-workers ");
}
}
</script>
<script>
'use strict';
// global
var IMPLICIT;
var PS_UTILS;
// The code that runs immediately after finishing loading of the Emscripten-generated js.
function set_off() {
console.log("ready.");
assert = my_assert;
IMPLICIT = _on_cpp_loaded(); // from implisolid_main.js
PS_UTILS = new PS_UTILS_CLASS(IMPLICIT);
//if(delta_t === undefined)
var delta_t = 0.2;
// Subjective time!
global_time += delta_t;
var d = provide_input(global_time, 0, globals);
var shape_json = d.shape_json;
var polygonization_json = JSON.stringify(d.polygonization_json);
init_scene(IMPLICIT, shape_json, polygonization_json);
animate();
};
</script>
<!-- Memory profiler code by "jj" from https://groups.google.com/forum/#!topic/emscripten-discuss/HtAzVposlX4 -->
<!-- Uncomment the following for foreround (non-webworker) demo-->
< ! - -
<script type="text/javascript" src="../js_iteration_2/js/lib/memoryprofiler.js"></script>
<script>
//function letmeknow(){console.log("Loading memory profiler");}
var Module;
if (!Module)
Module =
{
preRun:[
letmeknow=function (){console.log("Loading memory profiler");},
// memoryprofiler_add_hooks
],
onRuntimeInitialized: set_off,
memoryInitializerPrefixURL: "../build/",
};
</script>
<script type="text/javascript" src="../build/mcc2.compiled.js"></script>
- - >
<!--script>
var g1;
var g2;
var worker = new Worker('../build/mcc2.compiled.js');
var worker2 = new Worker('worker_test.js');
/* Usage:
* worker.postMessage({funcName: "worker_api__started"});
* Also see: ~/install/emsdk_portable/emscripten/master/src/library_browser.js at emscripten_call_worker() :1323 emscripten_call_worker()
* What is Runtime.getFuncWrapper(func, 'vi')(arg); ?
*/
/*
var transferObject = {
'funcName': funcName,
'callbackId': callbackId,
'data': data ? new Uint8Array({{{ makeHEAPView('U8', 'data', 'data + size') }}}) : 0
};
See:
https://kripken.github.io/emscripten-site/docs/api_reference/emscripten.h.html#c.emscripten_call_worker
https://kripken.github.io/emscripten-site/docs/api_reference/emscripten.h.html#c.emscripten_worker_respond
Q: Why do we need emscripten_get_worker_queue_size() ?
See:
~/install/emsdk_portable/emscripten/master/src$ grep -rnw '.' -i -e "worker"
*/
function send1() {
const callbackId = -1;
var dataArray = new Uint8Array([3,2,1]);
// Cracking the protocol used by Emscripten
var temp_copy=null;
worker.postMessage(
temp_copy={
funcName: "worker_api__started",
callbackId: callbackId,
data: dataArray? dataArray : 0,
// 'finalResponse': false,
}, dataArray?[dataArray.buffer]:[]
);
worker2.postMessage(temp_copy);
}
/*
//var REAL_V = 1; // enum
// var cb_revkeys = {[REAL_V]: "REAL_V", REAL_V: 1};
var cb_keys = {REAL_V: 1, build_geometry: 2}; // enum
//var cb_revkeys =
// {[cb_keys.REAL_V]: "REAL_V", [cb_keys.build_geometry]: "build_geometry"};
var cb_funcNames =
{[cb_keys.REAL_V]: "worker_api__verts", [cb_keys.build_geometry]: "build_geometry"};
// in fact it's better to use emscripten's!
// console.log(cb_revkeys);
*/
// cb_info (for : callback_info)
// Keeps the info necessary to communicate to the Web-Worker's API
var api_info = {
REAL_V: {
funcName: "worker_api__verts",
callbackId: 1,
},
/*
build_geometry: {
funcName: "build_geometry",
callbackId: 2,
},
*/
test: {
funcName: "workerapi_make_geometry_part1",
callbackId: 3,
},
};
// Maps the callback int id into the key name in api_info dict. For fast lookup.
var api_revlookup = {
[api_info.REAL_V]: "REAL_V",
// [api_info.build_geometry]: "build_geometry",
[api_info.test]: "test",
};
function send_worker_simple_request(fname) {
// no data
const callbackId = -1;
// Cracking the protocol used by Emscripten
var temp_copy = null;
worker.postMessage(
temp_copy = {
funcName: fname,
callbackId: callbackId,
data: 0,
// 'finalResponse': false,
}
);
worker2.postMessage(temp_copy);
}
// function send_worker_request_va(fname, callbackId) {
function send_worker_request_va() {
// no data
//
// // const callbackId = REAL_V;
//const callbackId = cb_keys.REAL_V;
// // Cracking the protocol used by Emscripten
//var fname = cb_funcNames[callbackId]; //"worker_api__verts";
const callbackId = api_info.REAL_V.callbackId;
var fname = api_info.REAL_V.funcName;
worker.postMessage(
{
funcName: fname,
callbackId: callbackId,
data: 0,
// 'finalResponse': false,
}
);
}
function build_geometry_w() {
worker.postMessage(
{
funcName: api_info.build_geometry.funcName,
callbackId: api_info.build_geometry.callbackId,
data: 0,
// 'finalResponse': false,
}
);
}
function test_data_worker(data) {
console.log("test_data_worker");
var temp_copy;
worker.postMessage(
temp_copy={
funcName: api_info.test.funcName,
callbackId: api_info.test.callbackId,
data: data, //[12345678, 3], // turns this into a two bytes!
// 'finalResponse': false,
}
// [data]
);
console.info(temp_copy, api_info.test.funcName);
console.info("data", data);
worker2.postMessage(temp_copy);
if (false) {
var a1 = new Float32Array([1,2,3.1415926536123456789012345678901234567890,4]);
worker2.postMessage(a1);
/*
*[12345678,2]
*/
}
}
function request() {
// send_worker_simple_request("worker_api__verts");
// send_worker_request_va();
var x0=0, y0=0, z0=0;
var mp5_json = SIMPLE_CONE; const BB_SIZE = 12.0/10.0;
var mc_params = {
resolution: Math.floor(14 ),
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},
subdiv: {enabled: 1},
overall_repeats: 1,
debug: {
enabled_pointsets: 0,
post_subdiv_noise: 0.0,
},
};
var mcsettings = JSON.stringify(mc_params);
// build_geometry_w(mp5_json, mcsettings);
//test_data_worker([12345678, 3,5,1,3]);
//var b1 = new Uint8Array([5,6,1000,10]);
var b1 = new Uint16Array([5,6,1000,10]);
if (false)
test_data_worker(b1);
// new idea!
var r = new Float32Array([3.141592651234567890123456780,1,2,3,4,5,6,7,8,9,0.5,1.5,2.5])
var b=new Uint8Array(r.buffer);
if (false)
test_data_worker(b);
console.log("---------------------");
test_data_worker(b);
//test_data_worker([b, 60, b]);
//test_data_worker({b1:b, d:60, b2:b});
/*
* [1,2] -> 1 02 //
* [12345678,2] -> 4e 02 // turns this into a two bytes!
* [12345677, 3] -> 4d 03
* ["hi.abc", 3] -> 00 03
*/
}
worker.addEventListener('message', function(event) {
// event.data == {callbackId: -1, finalResponse: true, data: 0}
//console.log('Worker said: ', event.data);
console.log("Message received from worker:", event.data); // event
// Reinterpret data
g = event.data;
g2 = new Float32Array(g.data.buffer);
console.log(g2);
// problem! Identify the result ID. Callback IS needed.
switch (event.data.callbackId) {
case cb_keys.REAL_V:
console.log("REAL_V REAL_V REAL_V ");
g = event.data;
g2 = new Float32Array(g.data.buffer);
console.log(g2);
}
}, false);
/*
worker.onmessage = function(event) {
console.log("Message received from worker:", event);
console.log(event.data);
}
*/
</script-->
<script>
'use strict';
var merge_dicts_nonrecursive = merge_dicts_nonrecursive?merge_dicts_nonrecursive:function() {
var merged_dict = {};
var nargs = arguments.length;
for (var arg_i = 0; arg_i < nargs; arg_i++) {
var newarg = arguments[arg_i];
for (var key in newarg) {
if (newarg.hasOwnProperty(key)) {
merged_dict[key] = newarg[key];
}
}
}
return merged_dict;
};
/*
function make_demo_dict() {
console.error("Use provide_input() instead.");
//var mp5_json = SIMPLE_CONE; const BB_SIZE = 12.0/10.0;
// 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 * 10.0;
var shape_dict = JSON.parse(mp5_json).root.children[0];
var x0=0, y0=0, z0=0;
return {
shape_dict: shape_dict,
bbox: {
min: {
x: x0-BB_SIZE, y: y0-BB_SIZE, z: z0-BB_SIZE
},
max: {
x: x0+BB_SIZE, y: y0+BB_SIZE, z: z0+BB_SIZE
}
},
};
}
*/
function demo1() { // request()
console.log("demo1");
var dct = provide_input(global_time, 0, globals);
var shape_json = dct.shape_json; // aleady stringified
// var polygonization_settings_json = JSON.stringify(dct.polygonization_json);
var points = new Float32Array([3.141592651234567890123456780,1,2,3,4,5,6,7,8,9,0.5,1.5,2.5, -1,-1])
// var b = new Uint8Array(r.buffer);
IMPLICIT_WORKER.wapi_query_implicit_values(23451, shape_json, points, function c3(returned_result, call_identification, shape_id) {
console.info("Returned: ALL-POINTS-OUTSIDE-OR-ON = ", returned_result, "shape_id", shape_id);
if (call_identification) console.info("Unique Call Identification Id:", call_identification);
console.info("demo1() done");
});
// wreq.mp5_str = JSON.stringify(shape_dict); // '{}';
// wreq.points = points;
// //worker.postMessage([b,r]);
// worker.postMessage(wreq);
}
</script >
<script type="text/javascript" src="../js_iteration_2/js/implisolid_worker.js"></script>
<script>
function demo2() {
//var rrq = make_demo_dict();
// var bbox = {min: {x:-10, y:-10, z:-10}, max:{x:10, y:10, z:10}};
var dct = provide_input(global_time, 0, globals);
var shape_json = dct.shape_json; // aleady stringified
var polygonization_settings_json = JSON.stringify(dct.polygonization_json);
console.info("demo2", dct);
//avoid calling IMPLICIT.make_polygonization_settings();
IMPLICIT_WORKER.getLiveGeometry_from_json(22345, shape_json, polygonization_settings_json, function (geom, shape_id){
console.info(geom, "shape_id", shape_id);
if (globals.mesh_solid) {scene.remove(globals.mesh_solid); globals.mesh_solid = null;}
if (globals.mesh_wireframe) {scene.remove(globals.mesh_wireframe); globals.mesh_wireframe = null;}
globals.mesh_solid = new THREE.Mesh( geom, globals.chosen_matrial );
globals.mesh_solid.position.set( 5*0, 5*0, 2*0 );
globals.mesh_solid.scale.set( MESH_SCALE, MESH_SCALE, MESH_SCALE );
scene.add( globals.mesh_solid );
console.info("demo2() done");
});
}
function demo3(ver) {
console.info("demo3 ver"+ver);
// global_time += 2;
global_time = 4;
var dct = provide_input(global_time, 1, globals);
var shape_json = dct.shape_json; // aleady stringified
var polygonization_settings_json = JSON.stringify(dct.polygonization_json);
var stt = new Date();
var shape_id = 45454;
if (ver == 1) {
IMPLICIT_WORKER.update_geometry_from_json_ver1(globals.mesh_solid.geometry, shape_id, shape_json, polygonization_settings_json, function(shape_id, result){
console.info("demo3() done", "called on shape:", shape_id);
console.info("TIME: ", new Date() - stt);
});
} else if (ver == 2) {
IMPLICIT_WORKER.update_geometry_from_json_ver2(globals.mesh_solid.geometry, shape_id, shape_json, polygonization_settings_json, function(shape_id, result){
console.info("demo3() done ", "called on shape:", shape_id);
console.info("TIME: ", new Date() - stt);
});
} else {
console.error("Sorry. use (1) or (2)");
}
}
function demo4() {
console.info("demo4: Query implicit values for collision detection. Tests query_implicit_values_old()");
var demoshape = provide_input(global_time += 0.5, 1, globals);
var shapejson = JSON.stringify(demoshape.shape_json);
console.log(shapejson);
var points = new Float32Array([3.141592651234567890123456780,1,2,3,4,5,6,7,8,9,0.5,1.5,2.5, -1,-1])
for (var i=0;i<points.length;++i) points[i] *= 0.0001;
console.log(points);
var reduce_type = "any-inside";
//{return_callback_id:_callback_id, returned_data: result_values, call_id: _call_id, shape_index: shape_index}
IMPLICIT_WORKER.query_implicit_values_old(345123, shapejson, points, reduce_type, 0.0001, function c3(returned_result, call_identification, shape_id) {
//returned_result.shape_index // this should be better on the
console.info("Returned: "+reduce_type+" = ", returned_result, "called on shape:", shape_id);
if (call_identification) console.info("Unique Call Identification Id:", call_identification);
console.info("demo4() done");
});
}
function demo5() {
console.info("demo5: Query a normal. Tests query_a_normal()");
var demoshape = provide_input(global_time, 1, globals);
var shapejson = JSON.stringify(demoshape.shape_json);
var points = new Float32Array([3.141592651234567890123456780,1,2])
console.log(points);
IMPLICIT_WORKER.wapi_query_a_normal (123123, shapejson, points, function c3(returned_result, call_identification, shape