UNPKG

@sohale/implisolid

Version:

A Solid Modelling Kernel in Javascript based on Implicit Surfaces, for MP5 file format

625 lines (463 loc) 17.4 kB
<html> <head> <meta charset="utf-8"/> </head> <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="./geometry77.js"></script> <script type="text/javascript" src="./controls/OrbitControls.js"></script> <!--<body>--> Based on MCC1 <br> <script> 'use strict'; var main; function init_polygonizer() { main = Module.cwrap('main', 'number', []); var newProducer={}; newProducer.build_geometry = Module.cwrap('build_geometry', null, ['number', 'number', 'string', 'number']); newProducer.get_v_size = Module.cwrap('get_v_size', 'number', []); newProducer.get_f_size = Module.cwrap('get_f_size', 'number', []); newProducer.get_v = Module.cwrap('get_v', null, ['number']); newProducer.get_f = Module.cwrap('get_f', null, ['number']); newProducer.get_v_ptr = Module.cwrap('get_v_ptr', 'number', []); newProducer.get_f_ptr = Module.cwrap('get_f_ptr', 'number', []); newProducer.finish_geometry = Module.cwrap('finish_geometry', null, []); // newProducer.about = Module.cwrap('about', null, []); // this is used for version purposes in the current html file newProducer.init = function(){ newProducer.needs_deallocation = false; } newProducer.finish_with = function (){ if(!newPolygonizer.needs_deallocation) console.error("cannot `finish_geometry()`. Geometry not produced."); newPolygonizer.finish_geometry(); newPolygonizer.needs_deallocation = false; } newProducer.init(); return newProducer; } </script> <script> 'use strict'; const VERBOSE = false; var WIREFRAME = false; const _FLOAT_SIZE = 4; const _INT_SIZE = 4; var global_time = 0; 'use strict'; var call_multiple_times = function() { var last_active = 0; var intervals_counter = 0; function _call_multiple_times(newPolygonizer, update_mc) { var BURST_COUNT = 50; var INTERVAL_MSEC = 8-1; var already_busy_doing_it=0; var burst_counter = 0; intervals_counter++; if(intervals_counter>1) { intervals_counter--; return; } last_active = setInterval ( function() { if(!last_active) console.error("!last_active"); burst_counter++; if(burst_counter<BURST_COUNT) { if(already_busy_doing_it<1) { already_busy_doing_it++; update_mc(newPolygonizer, 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 { if(!last_active) console.error("!last_active"); clearInterval(last_active); intervals_counter--; burst_counter = 0; last_active = 0; } }, INTERVAL_MSEC ); } return _call_multiple_times; }(); function make_geometry_new2(newPolygonizer, subjective_time, reusable_geometry, re_allocate_buffers) { var startTime = new Date(); if(newPolygonizer.needs_deallocation) { newPolygonizer.finish_geometry(); newPolygonizer.needs_deallocation = false; } else{ } newPolygonizer.build_geometry( 28, 1.0, subjective_time); newPolygonizer.needs_deallocation = true; var nverts = newPolygonizer.get_v_size(); var nfaces = newPolygonizer.get_f_size(); if(VERBOSE){ console.log(nverts); } var verts_address = newPolygonizer.get_v_ptr(); var faces_address = newPolygonizer.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 + 3*nfaces); var geom = new MyBufferGeometry77(verts, faces, re_allocate_buffers); if(VERBOSE){ console.log("nverts : "+ nverts); console.log("nfaces : "+ nfaces); } var endTime = new Date(); var timeDiff = endTime - startTime; report_time(timeDiff, function(){hist();}); return geom; } function my_assert(cond, text){if(!cond){console.error("ASSERT FAILED: "); if(text) console.log(text);}} function update_reused_geometry(newPolygonizer, subjective_time, geometry) { var startTime = new Date(); if(newPolygonizer.needs_deallocation) { newPolygonizer.finish_geometry(); newPolygonizer.needs_deallocation = false; } if(newPolygonizer.needs_deallocation) console.error("not deallocated."); try{ newPolygonizer.build_geometry( 28, 1.0, subjective_time); newPolygonizer.needs_deallocation = true; }catch(err){ console.error("An error occured dugin MCC C++") console.info(err); }finally { } // geometry. update_geometry (newPolygonizer); newPolygonizer. update_geometry (geometry); var endTime = new Date(); var timeDiff = endTime - startTime; report_time(timeDiff); } 'use strict'; var mesh_solid; var mesh2_tiny_box_wireframe; var materials_list; var material_wireframe; var mesh_wireframe = null; const CHOSEN_MATERIAL_INDEX = 2; //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 var chosen_matrial; const SHOW_WIREFRAME = true; const SHOW_SOLID = true; function init_scene(newPolygonizer) { scene = new THREE.Scene(); var WIDTH = window.innerWidth, HEIGHT = window.innerHeight - 200; //for memory profiler camera = new THREE.PerspectiveCamera( 75, WIDTH / HEIGHT, 1, 10000 ); camera.position.z = 1000; materials_list = look_nice(scene); chosen_matrial = materials_list[CHOSEN_MATERIAL_INDEX]; material_wireframe = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true, opacity:0.3, transparent: true,} ); var delta_t = 0.2; global_time += delta_t; var geometry = null; geometry = make_geometry_new2(newPolygonizer, global_time, null, true); if(SHOW_WIREFRAME){ mesh_wireframe = new THREE.Mesh( geometry, material_wireframe ); mesh_wireframe.position.set( 0, 0, 0 ); mesh_wireframe.scale.set( 300, 300, 300 ); scene.add( mesh_wireframe ); } if(SHOW_SOLID){ mesh_solid = new THREE.Mesh( geometry, chosen_matrial ); mesh_solid.position.set( 0, 0, 0 ); mesh_solid.scale.set( 300, 300, 300 ); scene.add( mesh_solid ); } var geo2 = new THREE.BoxGeometry( 20, 20, 20 ); 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 ); var dirLight = new THREE.DirectionalLight(0xffffff, 1); dirLight.position.set(100, 100, 50); scene.add(dirLight); if(VERBOSE){ console.log("RENDERER"); } var render_canvas = document.getElementById( 'my_canvas' ); console.log(render_canvas); renderer = new THREE.WebGLRenderer( { antialias: true, canvas: render_canvas } ); renderer.setSize( WIDTH, HEIGHT ); document.body.appendChild( renderer.domElement ); function doKeyDownListener(event) { if ( event.keyCode == 17 ) { call_multiple_times(newPolygonizer, update_mc); } else console.log(event.keyCode); } window.addEventListener( "keydown", doKeyDownListener, false ); var cameraControls = new THREE.OrbitControls( camera, renderer.domElement ); cameraControls.target.set( 0, 0, 0 ); cameraControls.addEventListener( 'change', function () {;} ); } function update_mc(newPolygonizer, delta_t){ var UPDATE_SAME_GEOM_OBJECT = true; var EVEN_REUSE_MESH_OBJECT = true; if( EVEN_REUSE_MESH_OBJECT && ! UPDATE_SAME_GEOM_OBJECT) console.error("Wrong condition."); if(SHOW_SOLID){ var p1 = [mesh_solid.position, mesh_solid.rotation]; } if(SHOW_WIREFRAME){ var p2 = [mesh_wireframe.position, mesh_wireframe.rotation]; } var g = null; if(SHOW_SOLID){ g = mesh_solid.geometry; } if(SHOW_WIREFRAME){ g = 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(mesh_solid); } if(SHOW_WIREFRAME){ scene.remove(mesh_wireframe); } } var reused_last_geom = g; if(!UPDATE_SAME_GEOM_OBJECT){ if(SHOW_SOLID){ g.dispose(); g = null; } } if(!EVEN_REUSE_MESH_OBJECT){ mesh_solid = null; mesh_wireframe = null; } if(delta_t === undefined) delta_t = 0.2; global_time += delta_t; var geometry = null; if(UPDATE_SAME_GEOM_OBJECT) { geometry = g; update_reused_geometry(newPolygonizer, global_time, geometry); } else { geometry = make_geometry_new2(newPolygonizer, global_time, null, false); }; if(!EVEN_REUSE_MESH_OBJECT){ if(SHOW_WIREFRAME){ mesh_wireframe = new THREE.Mesh( geometry, material_wireframe ); mesh_wireframe.scale.set( 300, 300, 300 ); //copy so that we dont lose the rotation, position of the meshes. mesh_wireframe.position.copy(p2[0]); mesh_wireframe.rotation.copy(p2[1]); scene.add( mesh_wireframe ); } if(SHOW_SOLID){ mesh_solid = new THREE.Mesh( geometry, chosen_matrial ); mesh_solid.scale.set( 300, 300, 300 ); mesh_solid.position.copy(p1[0]); mesh_solid.rotation.copy(p1[1]); scene.add( mesh_solid ); } } } function generateTexture() { var canvas = document.createElement( 'canvas' ); canvas.width = 256; canvas.height = 256; var context = canvas.getContext( '2d' ); var image = context.getImageData( 0, 0, 256, 256 ); var x = 0, y = 0; for ( var i = 0, j = 0, l = image.data.length; i < l; i += 4, j ++ ) { x = j % 256; y = x == 0 ? y + 1 : y; image.data[ i ] = 255; image.data[ i + 1 ] = 255; image.data[ i + 2 ] = 255; image.data[ i + 3 ] = Math.floor( x ^ y ); } context.putImageData( image, 0, 0 ); return canvas; } function look_nice(scene){ var materials = []; // Grid var line_material = new THREE.LineBasicMaterial( { color: 0x303030 } ); var _geometry = new THREE.Geometry(); var floor = -75, step = 25; for ( var i = 0; i <= 40; i ++ ) { _geometry.vertices.push( new THREE.Vector3( - 500, floor, i * step - 500 ) ); _geometry.vertices.push( new THREE.Vector3( 500, floor, i * step - 500 ) ); _geometry.vertices.push( new THREE.Vector3( i * step - 500, floor, -500 ) ); _geometry.vertices.push( new THREE.Vector3( i * step - 500, floor, 500 ) ); } var grid_lines = new THREE.LineSegments( _geometry, line_material ); scene.add( grid_lines ); // Materials var texture = new THREE.Texture( generateTexture() ); texture.needsUpdate = true; materials.push( new THREE.MeshLambertMaterial( { map: texture, transparent: true } ) ); materials.push( new THREE.MeshLambertMaterial( { color: 0xdddddd, shading: THREE.FlatShading } ) ); materials.push( new THREE.MeshPhongMaterial( { color: 0xdddddd, specular: 0x009900, shininess: 30, shading: THREE.FlatShading } ) ); materials.push( new THREE.MeshNormalMaterial( ) ); materials.push( new THREE.MeshBasicMaterial( { color: 0xffaa00, transparent: true, blending: THREE.AdditiveBlending } ) ); materials.push( new THREE.MeshLambertMaterial( { color: 0xdddddd, shading: THREE.SmoothShading } ) ); materials.push( new THREE.MeshPhongMaterial( { color: 0xdddddd, specular: 0x009900, shininess: 30, shading: THREE.SmoothShading, map: texture, transparent: true } ) ); materials.push( new THREE.MeshNormalMaterial( { shading: THREE.SmoothShading, } )); materials.push( new THREE.MeshBasicMaterial( { color: 0xffaa00, wireframe: true } ) ); materials.push( new THREE.MeshDepthMaterial() ); materials.push( new THREE.MeshLambertMaterial( { color: 0x666666, emissive: 0xff0000, shading: THREE.SmoothShading } ) ); materials.push( new THREE.MeshPhongMaterial( { color: 0x000000, specular: 0x666666, emissive: 0xff0000, shininess: 10, shading: THREE.SmoothShading, opacity: 0.9, transparent: true } ) ); materials.push( new THREE.MeshBasicMaterial( { map: texture, transparent: true } ) ); return materials; } var time_queue = []; var time_queue__last_timeout = 0; function report_time(time_msec, callback){ time_queue.push(time_msec); if(time_queue__last_timeout){ clearTimeout(time_queue__last_timeout); time_queue__last_timeout = 0; } time_queue__last_timeout = setTimeout(function(){ console.log("Time: (msec)"); console.log(time_queue); if(callback) callback(); time_queue = []; time_queue__last_timeout =0; }, 1000); } function animate() { requestAnimationFrame( animate ); //Updating the meshes var SPEED = 3. / 100; if(mesh_wireframe){ mesh_wireframe.rotation.x += 0.01*SPEED; mesh_wireframe.rotation.y += 0.02*SPEED; } if(mesh_solid){ mesh_solid.rotation.x += 0.01*SPEED; 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; renderer.render( scene, camera ); } var scene, camera, renderer; window.setTimeout( 3000); </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.data); } } else{ console.warning("Your browser does not support WebWorkers. See http://stackoverflow.com/questions/4739916/what-browsers-currently-support-web-workers "); } } </script> <!-- Graph --> <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script> <script> var ggraph = 0; function show_hist(data_array){ if(ggraph==0){ add_graph_div(); google.charts.load("current", {packages:["corechart"]}); } google.charts.setOnLoadCallback(drawChart); function drawChart() { var data = google.visualization.arrayToDataTable(data_array); var options = { title: 'Time ( Milliseconds )', legend: { position: 'none' }, colors: ['#e7711c'], histogram: { bucketSize: 1, }, hAxis: { ticks: (Array.from(Array(30*1.).keys())).map(function(x){return x/1.;}, Number), }, }; var div_element = document.getElementById('chart_div'); console.log(div_element); var chart = new google.visualization.Histogram(div_element); chart.draw(data, options); } ggraph++; } var global_histogram_accumulator = []; function hist_delayed() { var a = time_queue; if(global_histogram_accumulator.length==0){ global_histogram_accumulator.push(["Time"]); } var UPPER_BOUND = 12; for(var i=0;i<a.length;i++){ if(a[i]<=UPPER_BOUND) global_histogram_accumulator.push([a[i]*1.]); } show_hist(global_histogram_accumulator); } function hist(){ } function add_graph_div(){ } </script> <script> // The code that runs immediately after finishing loading of the Emscripten-generated js. function set_off() { console.log("ready."); var newPolygonizer = init_polygonizer(); init_scene(newPolygonizer); animate(); }; </script> <!-- Memory profiler code by "jj" from https://groups.google.com/forum/#!topic/emscripten-discuss/HtAzVposlX4 --> <script type="text/javascript" src="./lib/memoryprofiler.js"></script> <script> Module={preRun:[ letmeknow=function (){console.log("Loading memory profiler");}, // memoryprofiler_add_hooks ], onRuntimeInitialized: set_off, }; </script> <script type="text/javascript" src="mcc2_MS.cpp.js"></script>