Skip to content

Instantly share code, notes, and snippets.

@zgao4
Forked from yorikvanhavre/webgl.py
Created October 22, 2015 04:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zgao4/813832b68315678cce6e to your computer and use it in GitHub Desktop.
Save zgao4/813832b68315678cce6e to your computer and use it in GitHub Desktop.
A FreeCAD webGL maker
import FreeCAD,WebGui
SCALE = 10 # global scale modifier
template = """<!DOCTYPE HTML>
<html lang="en">
<head>
<title>FreeCAD webGL viewer</title>
<meta charset="utf-8">
<style type="text/css">
body {
background-color: #888888;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<div id="container"></div>
<script type="text/javascript" src="./Three.js"></script>
<!-- FreeCAD:ShapeDefs -->
<script type="text/javascript">
var camera, scene, renderer, object;
var targetRotation = 0;
var targetRotationOnMouseDown = 0;
var targetRotationY = 0;
var targetRotationYOnMouseDown = 0;
var mouseX = 0;
var mouseXOnMouseDown = 0;
var mouseY = 0;
var mouseYOnMouseDown = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
init();
setInterval( loop, 1000 / 60 );
function init() {
var container = document.getElementById( 'container' );
camera = new THREE.Camera( 50, window.innerWidth / window.innerHeight, 1, 2000 );
camera.position.z = 1000;
scene = new THREE.Scene();
scene.addLight( new THREE.AmbientLight( 0x0ff20 ) );
light1 = new THREE.PointLight( 0xff0040 );
scene.addLight( light1 );
<!-- FreeCAD:ShapeCreate -->
//renderer = new THREE.CanvasRenderer();
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
}
function onDocumentMouseDown( event ) {
event.preventDefault();
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
document.addEventListener( 'mouseup', onDocumentMouseUp, false );
document.addEventListener( 'mouseout', onDocumentMouseOut, false );
mouseXOnMouseDown = event.clientX - windowHalfX;
mouseYOnMouseDown = event.clientY - windowHalfY;
targetRotationOnMouseDown = targetRotation;
}
function onDocumentMouseMove( event ) {
mouseX = event.clientX - windowHalfX;
mouseY = event.clientY - windowHalfY;
targetRotation = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.02;
targetRotationY = targetRotationYOnMouseDown + ( mouseY - mouseYOnMouseDown ) * 0.02;
}
function onDocumentMouseUp( event ) {
document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
}
function onDocumentMouseOut( event ) {
document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
}
function loop() {
var time = new Date().getTime() * 0.0005;
//object.rotation.x -= 0.005;
//object.rotation.y -= 0.01;
object.rotation.y += ( targetRotation - object.rotation.y ) * 0.02;
object.rotation.x += ( targetRotationY - object.rotation.x ) * 0.02;
renderer.render(scene, camera);
}
</script>
</body>
</html>"""
def to3js(obj):
"""Converts a freecad object to three.js javascript code"""
if not obj.isDerivedFrom("Part::Feature"):
return ''
# header
js = "var Shape" + obj.Name + " = function () {\n"
js += "var scope = this;\n"
js += "THREE.Geometry.call( this );\n\n"
# create mesh
m = obj.Shape.tessellate(1)
# export vertices
for v in m[0]:
js += "v(%.4f,%.4f,%.4f);\n"%(v.x,v.y,v.z)
js += "\n"
# export faces
index = 0
for f in m[1]:
js += "f3(%i,%i,%i);\n"%(f[0],f[1],f[2])
# make all work
js += "this.sortFacesByMaterial();\n"
js += "function v( x, y, z ) {\n"
js += "scope.vertices.push( new THREE.Vertex( new THREE.Vector3( x, y, z ) ) );\n"
js += "}\n"
js += "function f3( a, b, c , nx, ny, nz) {\n"
js += "scope.faces.push( new THREE.Face3( a, b, c , nx && ny && nz ? new THREE.Vector3( nx, ny, nz ) : null ) );\n"
js += "}\n"
js += "}\n\n"
js += "Shape" + obj.Name + ".prototype = new THREE.Geometry();\n"
js += "Shape" + obj.Name + ".prototype.constructor = Shape" + obj.Name + ";"
return js
def getHTML(objs):
"""gets an html page with the given objects"""
shapedefs = ""
shapecreates = ""
for obj in objs:
shapedefs += '<script type="text/javascript">\n' + to3js(obj) + "\n</script>\n"
shapecreates += "object = new THREE.Mesh( new Shape" + obj.Name + "(), new THREE.MeshNormalMaterial({opacity:1,shading:THREE.SmoothShading}) );\n"
shapecreates += "object.overdraw = true;\nobject.scale.x = object.scale.y = object.scale.z =" + str(SCALE) + ".;\nscene.addObject( object );\n"
html = template.replace("<!-- FreeCAD:ShapeDefs -->",shapedefs)
html = html.replace("<!-- FreeCAD:ShapeCreate -->",shapecreates)
return html
def getObjects():
"""Returns viible objects from the active documnt"""
objs = []
for obj in FreeCAD.ActiveDocument.Objects:
if obj.ViewObject.isVisible():
objs.append(obj)
return objs
def show():
"""Opens a webGL viewer with the scene contents"""
html = getHTML(getObjects())
WebGui.openBrowserHTML(html,'file://' + FreeCAD.getResourceDir() + 'Mod/Web/WebGL/','WebGL viewer')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment