-
-
Save AlexisTheLarge/d0f8602c030733ccbafa9d6e8fd50666 to your computer and use it in GitHub Desktop.
// ==UserScript== | |
// @name Face Angle Capture | |
// @namespace http://github.com/AlexisTheLarge | |
// @version 1.3 | |
// @description Capture angles from 3D face reconstruction automatically | |
// @author Alexis_TheLarge | |
// @match http://cvl-demos.cs.nott.ac.uk/vrn/view.php* | |
// @grant GM_addStyle | |
// @grant GM.addStyle | |
// @require https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js | |
// @require https://cdnjs.cloudflare.com/ajax/libs/three.js/88/three.min.js | |
// @require https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.5/jszip.min.js | |
// @require https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.3/FileSaver.min.js | |
// ==/UserScript== | |
GM.addStyle("button.button.purple {background-color: #E80C7A !important; width: 100% !important; cursor:pointer; }"); | |
GM.addStyle("#ProgressOverlay {color:white; width: 462px; height:462px; background-color: rgba(0,0,0,0.4); position: absolute; top: 0; left: 0; padding-top:40%; padding-left:10%; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box;"); | |
GM.addStyle("#myProgress { width: 80%; background-color: white;} #myBar { width: 1%; height: 30px; background-color: #E80C7A; }"); | |
var progress = 1; | |
var step = 100/130; | |
var progressbar = null; | |
var progress_container = null; | |
(function() { | |
'use strict'; | |
window.addEventListener('load', function() { | |
var viewer_frame = document.getElementById("viewer_frame"); | |
progress_container = document.createElement('div'); | |
progress_container.innerHTML = '<p>Capturing Angles...</p><div id="myProgress"><div id="myBar"></div></div>'; | |
progress_container.setAttribute ('id', 'ProgressOverlay'); | |
progress_container.style.display = 'none'; | |
viewer_frame.appendChild(progress_container); | |
var viewer_controls = document.getElementById("viewer_controls"); | |
var hr = viewer_controls.getElementsByTagName("hr")[0]; | |
var zNode = document.createElement('p'); | |
zNode.innerHTML = '<button id="generateAnglesButton" class="button purple" type="button">Capture angles</button>'; | |
viewer_controls.insertBefore(zNode, hr); | |
document.getElementById ("generateAnglesButton").addEventListener ( | |
"click", ButtonClickAction, false | |
); | |
}, false); | |
})(); | |
function ButtonClickAction (zEvent) { | |
generate_angles(); | |
} | |
/* jshint ignore:start */ | |
async function generate_angles() { | |
if (typeof objname === 'undefined') { | |
var objname = unsafeWindow.objname; | |
} | |
objpath = "queue/obj/" + objname + ".obj"; | |
jpgpath = "queue/obj/" + objname + ".jpg"; | |
progressbar = document.getElementById("myBar"); | |
progress_container.style.display = 'block'; | |
var zip = new JSZip(); | |
await generate(zip, 'a_', function(){}); | |
await generate(zip, 'b_', function(face, plane, pivot, scene) { | |
var axis = new THREE.Vector3( 1, 0, 0 ).normalize(); | |
rotate(face, plane, pivot, scene, axis, ((Math.PI*0.5)/5)); | |
}); | |
await generate(zip, 'ba_', function(face, plane, pivot, scene) { | |
var axis_y = new THREE.Vector3( 1, 0, 0 ).normalize(); | |
var axis_z = new THREE.Vector3( 0, 0, 1 ).normalize(); | |
rotate(face, plane, pivot, scene, axis_y, ((Math.PI*0.5)/5)); | |
rotate(face, plane, pivot, scene, axis_z, ((Math.PI*0.5)/7)); | |
}); | |
await generate(zip, 'bb_', function(face, plane, pivot, scene) { | |
var axis_y = new THREE.Vector3( 1, 0, 0 ).normalize(); | |
var axis_z = new THREE.Vector3( 0, 0, 1 ).normalize(); | |
rotate(face, plane, pivot, scene, axis_y, ((Math.PI*0.5)/5)); | |
rotate(face, plane, pivot, scene, axis_z, -((Math.PI*0.5)/7)); | |
}); | |
await generate(zip, 'c_', function(face, plane, pivot, scene) { | |
var axis = new THREE.Vector3( 1, 0, 0 ).normalize(); | |
rotate(face, plane, pivot, scene, axis, ((Math.PI*0.5)/2)); | |
}); | |
await generate(zip, 'ca_', function(face, plane, pivot, scene) { | |
var axis_y = new THREE.Vector3( 1, 0, 0 ).normalize(); | |
var axis_z = new THREE.Vector3( 0, 0, 1 ).normalize(); | |
rotate(face, plane, pivot, scene, axis_y, ((Math.PI*0.5)/2)); | |
rotate(face, plane, pivot, scene, axis_z, ((Math.PI*0.5)/5)); | |
}); | |
await generate(zip, 'cb_', function(face, plane, pivot, scene) { | |
var axis_y = new THREE.Vector3( 1, 0, 0 ).normalize(); | |
var axis_z = new THREE.Vector3( 0, 0, 1 ).normalize(); | |
rotate(face, plane, pivot, scene, axis_y, ((Math.PI*0.5)/2)); | |
rotate(face, plane, pivot, scene, axis_z, -((Math.PI*0.5)/5)); | |
}); | |
await generate(zip, 'd_', function(face, plane, pivot, scene) { | |
var axis = new THREE.Vector3( 1, 0, 0 ).normalize(); | |
rotate(face, plane, pivot, scene, axis, -((Math.PI*0.5)/5)); | |
}); | |
await generate(zip, 'da_', function(face, plane, pivot, scene) { | |
var axis_y = new THREE.Vector3( 1, 0, 0 ).normalize(); | |
var axis_z = new THREE.Vector3( 0, 0, 1 ).normalize(); | |
rotate(face, plane, pivot, scene, axis_y, -((Math.PI*0.5)/5)); | |
rotate(face, plane, pivot, scene, axis_z, ((Math.PI*0.5)/7)); | |
}); | |
await generate(zip, 'db_', function(face, plane, pivot, scene) { | |
var axis_y = new THREE.Vector3( 1, 0, 0 ).normalize(); | |
var axis_z = new THREE.Vector3( 0, 0, 1 ).normalize(); | |
rotate(face, plane, pivot, scene, axis_y, -((Math.PI*0.5)/5)); | |
rotate(face, plane, pivot, scene, axis_z, -((Math.PI*0.5)/7)); | |
}); | |
await generate(zip, 'e_', function(face, plane, pivot, scene) { | |
var axis = new THREE.Vector3( 1, 0, 0 ).normalize(); | |
rotate(face, plane, pivot, scene, axis, -((Math.PI*0.5)/2)); | |
}); | |
await generate(zip, 'ea_', function(face, plane, pivot, scene) { | |
var axis_y = new THREE.Vector3( 1, 0, 0 ).normalize(); | |
var axis_z = new THREE.Vector3( 0, 0, 1 ).normalize(); | |
rotate(face, plane, pivot, scene, axis_y, -((Math.PI*0.5)/2)); | |
rotate(face, plane, pivot, scene, axis_z, ((Math.PI*0.5)/5)); | |
}); | |
await generate(zip, 'eb_', function(face, plane, pivot, scene) { | |
var axis_y = new THREE.Vector3( 1, 0, 0 ).normalize(); | |
var axis_z = new THREE.Vector3( 0, 0, 1 ).normalize(); | |
rotate(face, plane, pivot, scene, axis_y, -((Math.PI*0.5)/2)); | |
rotate(face, plane, pivot, scene, axis_z, -((Math.PI*0.5)/5)); | |
}); | |
/*jshint ignore:end */ | |
zip.generateAsync({type:"blob"}) | |
.then(function(content) { | |
// Force down of the Zip file | |
saveAs(content, "face_angles.zip"); | |
progress_container.style.display = 'none'; | |
progress = 1; | |
progressbar.style.width = progress + '%'; | |
location.reload(); | |
}); | |
function generate(zip, prefix, pretransform) { | |
camera = new THREE.OrthographicCamera(-96, 96, -96, 96, 1, 1000); | |
camera.up.set( 0, 1, 0 ); | |
camera.position.x = 80; | |
camera.position.y = 0; | |
camera.position.z = 100; | |
camera.zoom = 1; | |
camera.updateProjectionMatrix(); | |
scene = new THREE.Scene(); | |
scene.position.z = 0; | |
scene.position.y = 0; | |
var geometry = new THREE.BoxBufferGeometry( 1, 1, 1 ); | |
var material_p = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); | |
var mesh = new THREE.Mesh( geometry, material_p ); | |
mesh.position.y = -96; | |
mesh.position.x = -96; | |
mesh.position.z = -30; | |
var pivot = new THREE.Object3D(); | |
pivot.add( mesh ); | |
scene.add( pivot ); | |
var manager = new THREE.LoadingManager(); | |
var material = new THREE.MeshBasicMaterial({ | |
map : THREE.ImageUtils.loadTexture(jpgpath), | |
}); | |
// plane | |
plane = new THREE.Mesh(new THREE.PlaneGeometry(192, 192), material); | |
plane.material.side = THREE.DoubleSide; | |
plane.scale.y = -1; | |
if (document.getElementById('checkBackground').checked) { | |
scene.add(plane); | |
} | |
face = null; | |
renderer = new THREE.WebGLRenderer({ alpha: true }); | |
renderer.setPixelRatio( 1 ); | |
renderer.setSize( 320,320 ); | |
return new Promise((resolve, reject) => { | |
var loader = new THREE.OBJVertexColorLoader(manager); | |
loader.load(objpath, function (object) { | |
object.children[0].material.side = THREE.DoubleSide; | |
object.translateX(-96); | |
object.translateY(-96); | |
object.translateZ(-30); | |
scene.add(object); | |
face = object; | |
render(); | |
pretransform(face, plane, pivot, scene); | |
for (var i = 0; i < 10 ; i++) { | |
var axis = new THREE.Vector3( 0, 1, 0 ).normalize(); | |
rotate(face, plane, pivot, scene, axis, ((Math.PI*0.5)/10)); | |
imgData = renderer.domElement.toDataURL("image/jpeg").split(',')[1]; | |
zip.file(prefix+i+".jpg", imgData, {base64: true}); | |
progress += step; | |
progressbar.style.width = progress + '%'; | |
} | |
resolve(true); | |
}, function() {}, function () {}); | |
}); | |
} | |
function rotate(face, plane, pivot, scene, axis, angle) { | |
pivot_rotate(face, scene, pivot, angle, axis); | |
pivot_rotate(plane, scene, pivot, angle, axis); | |
render(); | |
} | |
function render() { | |
camera.lookAt(scene.position); | |
renderer.render(scene, camera); | |
} | |
function pivot_rotate(object, scene, pivot, angle, axis){ | |
pivot_attach(object, scene, pivot); | |
pivot.rotateOnAxis(axis,angle); | |
pivot_detach(object, scene, pivot); | |
} | |
function pivot_attach(object, scene, pivot) { | |
pivot.updateMatrixWorld(); | |
THREE.SceneUtils.attach( object, scene, pivot ); | |
} | |
function pivot_detach(object, scene, pivot) { | |
pivot.updateMatrixWorld(); | |
object.updateMatrixWorld(); // if not done by the renderer | |
THREE.SceneUtils.detach( object, pivot, scene ); | |
pivot.rotation.set( 0, 0, 0 ); | |
} | |
} | |
THREE.OBJVertexColorLoader = function (manager) { | |
this.manager = (manager !== undefined) ? manager : THREE.DefaultLoadingManager; | |
this.materials = null; | |
}; | |
THREE.OBJVertexColorLoader.prototype = { | |
constructor: THREE.OBJVertexColorLoader, | |
load: function (url, onLoad, onProgress, onError) { | |
var scope = this; | |
var loader = new THREE.XHRLoader(scope.manager); | |
loader.setPath(this.path); | |
loader.load(url, function (text) { | |
onLoad(scope.parse(text)); | |
}, onProgress, onError); | |
}, | |
setPath: function (value) { | |
this.path = value; | |
}, | |
parse: function (text) { | |
var container = new THREE.Group(); | |
var geometry = new THREE.Geometry(); | |
var vertices = []; | |
var vertexColors = []; | |
var faces = []; | |
// v float float float float float float (vertex with rgb) | |
var vertex_colour_pattern = /^v\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)/; | |
// f vertex vertex vertex ... | |
var face_pattern1 = /^f\s+(-?\d+)\s+(-?\d+)\s+(-?\d+)(?:\s+(-?\d+))?/; | |
var lines = text.split('\n'); | |
for (var i = 0; i < lines.length; i++) { | |
var line = lines[i]; | |
line = line.trim(); | |
var result; | |
if (line.length === 0 || line.charAt(0) === '#') { | |
continue; | |
} else if ((result = vertex_colour_pattern.exec(line)) !== null) { | |
vertices.push( | |
new THREE.Vector3(parseFloat(result[1]), parseFloat(result[2]), parseFloat(result[3])) | |
); | |
vertexColors.push(new THREE.Color(parseFloat(result[4]), parseFloat(result[5]), parseFloat(result[6]))); | |
} else if ((result = face_pattern1.exec(line)) !== null) { | |
faces.push(new THREE.Face3(result[1] - 1, result[2] - 1, result[3] - 1)); | |
} | |
} | |
for (var i = 0; i < vertices.length; i++) { | |
geometry.vertices.push(vertices[i]); | |
} | |
for (var i = 0; i < faces.length; i++) { | |
faces[i].vertexColors[0] = vertexColors[faces[i].a]; | |
faces[i].vertexColors[1] = vertexColors[faces[i].b]; | |
faces[i].vertexColors[2] = vertexColors[faces[i].c]; | |
geometry.faces.push(faces[i]); | |
} | |
var material = new THREE.MeshBasicMaterial({ vertexColors: THREE.VertexColors }); | |
var mesh = new THREE.Mesh(geometry, material); | |
container.add(mesh); | |
return container; | |
} | |
}; |
Seems the scripts doesen't work anymore with firefox?
Yeah it recently broke with both Firefox and Chrome. I think maybe an update to grease/tamper monkey broke it. I have tried contacting the author but he hasn't replied. Hopefully it gets updated but I am looking for someone to fix it as the errors are listed if you open up the script, I just don't have the ability to fix it myself. If I get any updates I'll let you know.
Yeah it recently broke with both Firefox and Chrome.
Working for me currently, though it seems the script is only matching HTTP and not HTTPS. Add the following at the top of the script under the HTTP entry & it will match HTTPS too:
// @match https://cvl-demos.cs.nott.ac.uk/vrn/view.php*
Oh wow, I feel like an idiot. Thanks for pointing that out man, works like a charm now.
Sincerely appreciated.
Seems the scripts doesen't work anymore with firefox?