Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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

This comment has been minimized.

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
You can’t perform that action at this time.