Skip to content

Instantly share code, notes, and snippets.

@yorikvanhavre
Created April 2, 2012 18:51
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save yorikvanhavre/2286282 to your computer and use it in GitHub Desktop.
Save yorikvanhavre/2286282 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')
@jlstanus
Copy link

jlstanus commented Oct 26, 2017

Hello @yorikvanhavre how an i use it in Freecad? Or there is an other tool to convert to WebGL?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment