This commit is contained in:
casperlamboo 2015-06-16 18:37:26 +02:00
parent 44994f61a8
commit d99e302c38
16 changed files with 14873 additions and 26 deletions

193
doodle_app/css/dark.css Executable file
View File

@ -0,0 +1,193 @@
.Outliner {
color: #868686;
background: #222;
padding: 0;
width: 100%;
height: 140px;
font-size: 12px;
cursor: default;
overflow: auto;
outline: none;
}
.Outliner .option {
padding: 4px;
white-space: nowrap;
}
.Outliner .option.active {
background-color: #153C5E;
}
.Panel.Collapsible.collapsed .Static .Button {
border-left-color: #444;
}
.Panel.Collapsible:not(.collapsed) .Static .Button {
border-top-color: #444;
}
input.Number {
color: #2A75B7!important;
font-size: 12px; /** TODO: Use of !imporant is not ideal **/
background-color: transparent!important; /* For now this is a quick fix a rendering issue due to inherited background */
border: 1px solid transparent;
padding: 2px;
cursor: col-resize;
}
#viewport {
position: absolute;
top: 32px;
left: 0px;
right: 300px;
bottom: 32px;
}
#viewport #info {
text-shadow: 1px 1px 0px rgba(0,0,0,0.25);
}
#script {
position: absolute;
top: 32px;
left: 0px;
right: 300px;
bottom: 32px;
opacity: 0.9;
}
#player {
position: absolute;
top: 32px;
left: 0px;
right: 300px;
bottom: 32px;
}
#menubar {
position: absolute;
width: 100%;
height: 32px;
background: #111;
padding: 0px;
margin: 0px;
right: 0px;
top: 0px;
}
#menubar .menu {
float: left;
cursor: pointer;
padding-right: 8px;
}
#menubar .menu.right {
float: right;
cursor: auto;
text-align: right;
}
#menubar .menu .title {
display: inline-block;
color: #888;
margin: 0px;
padding: 8px;
}
#menubar .menu .options {
position: absolute;
display: none;
padding: 5px 0px;
background: #111;
width: 150px;
}
#menubar .menu:hover .options {
display: block;
}
#menubar .menu .options hr {
border-color: #333;
}
#menubar .menu .options .option {
color: #888;
background-color: transparent;
padding: 5px 10px;
margin: 0px !important;
}
#menubar .menu .options .option:hover {
color: #fff;
background-color: #08f;
}
#menubar .menu .options .option:active {
background: transparent;
}
#sidebar {
position: absolute;
right: 0px;
top: 32px;
bottom: 0px;
width: 300px;
background-color: #111;
overflow: auto;
}
#sidebar * {
vertical-align: middle;
}
#sidebar input,
#sidebar textarea,
#sidebar select {
background: #222;
border: 1px solid transparent;
color: #888;
}
#sidebar .Panel {
margin-bottom: 10px;
}
#sidebar .Panel.collapsed {
margin-bottom: 0px;
}
#sidebar > .Panel {
color: #888;
padding: 10px;
border-top: 1px solid #333;
}
#sidebar .Panel.Material canvas {
border: solid 1px #5A5A5A;
}
#toolbar {
position: absolute;
left: 0px;
right: 300px;
bottom: 0px;
height: 32px;
background-color: #111;
color: #333;
}
#toolbar * {
vertical-align: middle;
}
#toolbar .Panel {
padding: 4px;
color: #888;
}
#toolbar button {
margin-right: 6px;
}

168
doodle_app/css/light.css Executable file
View File

@ -0,0 +1,168 @@
.Outliner {
color: #444;
background: #fff;
padding: 0;
width: 100%;
height: 140px;
font-size: 12px;
cursor: default;
overflow: auto;
outline: none;
}
.Outliner .option {
padding: 4px;
color: #666;
white-space: nowrap;
}
.Outliner .option.active {
background-color: #f8f8f8;
}
input.Number {
color: #0080f0!important;
font-size: 12px; /** TODO: Use of !imporant is not ideal **/
background-color: transparent!important; /* For now this is a quick fix a rendering issue due to inherited background */
border: 1px solid transparent;
padding: 2px;
cursor: col-resize;
}
#script {
position: absolute;
top: 32px;
left: 0px;
right: 300px;
bottom: 32px;
opacity: 0.9;
}
#player {
position: absolute;
top: 32px;
left: 0px;
right: 300px;
bottom: 32px;
}
#menubar {
position: absolute;
width: 100%;
height: 32px;
background: #eee;
padding: 0px;
margin: 0px;
right: 0px;
top: 0px;
}
#menubar .menu {
float: left;
cursor: pointer;
padding-right: 8px;
}
#menubar .menu.right {
float: right;
cursor: auto;
text-align: right;
}
#menubar .menu .title {
display: inline-block;
color: #888;
margin: 0px;
padding: 8px;
}
#menubar .menu .options {
position: absolute;
display: none;
padding: 5px 0px;
background: #eee;
width: 150px;
}
#menubar .menu:hover .options {
display: block;
}
#menubar .menu .options hr {
border-color: #ddd;
}
#menubar .menu .options .option {
color: #666;
background-color: transparent;
padding: 5px 10px;
margin: 0px !important;
}
#menubar .menu .options .option:hover {
color: #fff;
background-color: #08f;
}
#menubar .menu .options .option:active {
color: #666;
background: transparent;
}
#sidebar {
position: absolute;
right: 0px;
top: 32px;
bottom: 0px;
width: 300px;
background: #eee;
overflow: auto;
}
#sidebar * {
vertical-align: middle;
}
#sidebar input,
#sidebar textarea,
#sidebar select {
border: 1px solid transparent;
color: #444;
}
#sidebar .Panel {
margin-bottom: 10px;
}
#sidebar .Panel.collapsed {
margin-bottom: 0px;
}
#sidebar > .Panel {
color: #888;
padding: 10px;
border-top: 1px solid #ccc;
}
#toolbar {
position: absolute;
left: 0px;
right: 300px;
bottom: 0px;
height: 32px;
background: #eee;
color: #333;
}
#toolbar * {
vertical-align: middle;
}
#toolbar .Panel {
padding: 4px;
color: #888;
}
#toolbar button {
margin-right: 6px;
}

146
doodle_app/css/main.css Executable file
View File

@ -0,0 +1,146 @@
body {
font-family: Helvetica, Arial, sans-serif;
font-size: 14px;
margin: 0;
overflow: hidden;
}
hr {
border: 0px;
border-top: 1px solid #ccc;
}
button {
position: relative;
}
textarea {
tab-size: 4;
white-space: pre;
word-wrap: normal;
}
textarea.success {
border-color: #8b8 !important;
}
textarea.fail {
border-color: #f00 !important;
background-color: rgba(255,0,0,0.05);
}
textarea, input { outline: none; } /* osx */
.Panel {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
/* No support for these yet */
-o-user-select: none;
user-select: none;
}
.Panel.Collapsible .Static {
margin: 0px;
}
.Panel.Collapsible .Static .Button {
float: left;
margin-right: 6px;
width: 0px;
height: 0px;
border: 6px solid transparent;
}
.Panel.Collapsible.collapsed .Static .Button {
margin-top: 2px;
border-left-color: #bbb;
}
.Panel.Collapsible:not(.collapsed) .Static .Button {
margin-top: 6px;
border-top-color: #bbb;
}
.Panel.Collapsible.collapsed .Content {
display: none;
}
/* CodeMirror */
.CodeMirror {
position: absolute !important;
top: 37px;
width: 100% !important;
height: calc(100% - 37px) !important;
}
.CodeMirror .errorLine {
background: rgba(255,0,0,0.25);
}
.CodeMirror .esprima-error {
color: #f00;
text-align: right;
padding: 0px 20px;
}
/* scene types */
.type {
position:relative;
top:-2px;
padding: 0px 2px;
color: #ddd;
}
.type:after {
content: '■';
}
.Scene {
color: #ccccff;
}
.Object3D {
color: #aaaaee;
}
.Mesh {
color: #8888ee;
}
/* */
.PointLight {
color: #dddd00;
}
/* */
.Geometry {
color: #88ff88;
}
.BoxGeometry {
color: #bbeebb;
}
.TorusGeometry {
color: #aaeeaa;
}
/* */
.Material {
color: #ff8888;
}
.MeshPhongMaterial {
color: #ffaa88;
}

View File

@ -4,7 +4,12 @@
<title>Doodle 3D App</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link href="css/main.css" rel="stylesheet" />
<link id="theme" href="css/light.css" rel="stylesheet" />
<script src="../three.js-master/build/three.js"></script>
<script src="lib/paper-core.js"></script>
<script src="../three.js-master/examples/js/controls/EditorControls.js"></script>
<script src="../three.js-master/examples/js/controls/TransformControls.js"></script>
@ -13,34 +18,38 @@
<script src="../three.js-master/editor/js/libs/signals.min.js"></script>
<script src="../three.js-master/editor/js/libs/ui.js"></script>
<script src="../three.js-master/editor/js/libs/ui.three.js"></script>
<script src="../three.js-master/editor/js/Storage.js"></script>
<script src="../three.js-master/editor/js/Editor.js"></script>
<script src="../three.js-master/editor/js/Config.js"></script>
<script src="../three.js-master/editor/js/Loader.js"></script>
<script src="../three.js-master/editor/js/Viewport.js"></script>
<script src="../three.js-master/editor/js/Viewport.info.js"></script>
<style>
* {padding: 0px; margin: 0px;}
canvas {border: 1px solid black; margin: 5px;}
.menu_bar {border: 1px solid black; height: 40px; margin: 5px;}
</style>
<script src="js/DrawCanvas.js"></script>
<script src="ui/Editor.js"></script>
<script src="ui/Config.js"></script>
<script src="ui/Preview.js"></script>
<script src="ui/Design.js"></script>
</head>
<body>
<div class="menu_bar"></div>
<canvas id="design"></canvas>
<canvas id="preview"></canvas>
<div class="menu_bar"></div>
<script>
var editor = new Editor();
var editor = new Editor();
var viewport = new Viewport( editor );
var design = new Design(editor);
document.body.appendChild(design.dom);
document.body.appendChild( viewport.dom );
var preview = new Preview(editor);
document.body.appendChild(preview.dom);
var onWindowResize = function (event) {
"use strict";
editor.signals.windowResize.dispatch();
};
window.addEventListener('resize', onWindowResize, false);
onWindowResize();
</script>

View File

@ -0,0 +1,86 @@
function DrawCanvas (scene) {
"use strict";
this.domElement = document.createElement("canvas");
paper.setup(this.domElement);
var path = new paper.Path();
this.scene = scene;
this.test();
};
DrawCanvas.prototype.test = function () {
"use strict";
var scope = this;
var a = [];
var tool = new paper.Tool();
var path;
tool.onMouseDown = function (event) {
if (path) {
path.selected = false;
}
a.push(event.point);
path = new paper.Path({
segments: [event.point],
strokeColor: 'black',
fullySelected: true
});
}
tool.onMouseDrag = function(event) {
path.add(event.point);
a.push(event.point);
}
tool.onMouseUp = function (event) {
console.log(path);
var shape = new THREE.Shape();
for (var i = 0; i < a.length; i ++) {
var point = a[i % a.length];
if (i === 0) {
shape.moveTo(point.y, point.x);
}
else {
shape.lineTo(point.y, point.x);
}
}
var geometry = new THREE.ExtrudeGeometry(shape, {
amount: 40,
bevelEnabled: true,
bevelSegments: 2,
steps: 2,
bevelSize: 1,
bevelThickness: 1
});
var mesh = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({color: 0xff0000}));
mesh.rotation.x = -Math.PI/2;
mesh.position.x = -400;
mesh.position.z = 200;
a = [];
scope.scene.add(mesh);
// Select the path, so we can see its segments:
path.fullySelected = true;
}
};
DrawCanvas.prototype.setSize = function (width, height) {
"use strict";
paper.view.viewSize = new paper.Size(width, height);
paper.view.draw();
};

12694
doodle_app/lib/paper-core.js Normal file

File diff suppressed because it is too large Load Diff

69
doodle_app/ui/Config.js Executable file
View File

@ -0,0 +1,69 @@
/**
* @author mrdoob / http://mrdoob.com/
*/
var Config = function () {
var name = 'threejs-editor';
var storage = {
'autosave': true,
'project/renderer': 'WebGLRenderer',
'project/renderer/antialias': true,
'project/vr': false,
'camera/position': [ 500, 250, 500 ],
'camera/target': [ 0, 0, 0 ]
};
if ( window.localStorage[ name ] === undefined || true ) {
window.localStorage[ name ] = JSON.stringify( storage );
} else {
var data = JSON.parse( window.localStorage[ name ] );
for ( var key in data ) {
storage[ key ] = data[ key ];
}
}
return {
getKey: function ( key ) {
console.log(storage);
return storage[ key ];
},
setKey: function () { // key, value, key, value ...
for ( var i = 0, l = arguments.length; i < l; i += 2 ) {
storage[ arguments[ i ] ] = arguments[ i + 1 ];
}
window.localStorage[ name ] = JSON.stringify( storage );
console.log( '[' + /\d\d\:\d\d\:\d\d/.exec( new Date() )[ 0 ] + ']', 'Saved config to LocalStorage.' );
},
clear: function () {
delete window.localStorage[ name ];
}
}
};

30
doodle_app/ui/Design.js Normal file
View File

@ -0,0 +1,30 @@
/**
* @author mrdoob / http://mrdoob.com/
*/
var Design = function ( editor ) {
var signals = editor.signals;
var container = new UI.Panel();
container.setId( 'Design' );
container.setPosition( 'absolute' );
container.setWidth( '50%' );
container.setTop( '0px' );
container.setLeft( '0px' );
container.setBottom( '0px' );
var drawCanvas = new DrawCanvas(editor.scene);
container.dom.appendChild(drawCanvas.domElement);
signals.windowResize.add( function () {
drawCanvas.setSize( container.dom.offsetWidth, container.dom.offsetHeight );
} );
return container;
}

452
doodle_app/ui/Editor.js Executable file
View File

@ -0,0 +1,452 @@
/**
* @author mrdoob / http://mrdoob.com/
*/
var Editor = function () {
var SIGNALS = signals;
this.signals = {
editorCleared: new SIGNALS.Signal(),
savingStarted: new SIGNALS.Signal(),
savingFinished: new SIGNALS.Signal(),
transformModeChanged: new SIGNALS.Signal(),
snapChanged: new SIGNALS.Signal(),
spaceChanged: new SIGNALS.Signal(),
rendererChanged: new SIGNALS.Signal(),
sceneGraphChanged: new SIGNALS.Signal(),
cameraChanged: new SIGNALS.Signal(),
geometryChanged: new SIGNALS.Signal(),
objectSelected: new SIGNALS.Signal(),
objectFocused: new SIGNALS.Signal(),
objectAdded: new SIGNALS.Signal(),
objectChanged: new SIGNALS.Signal(),
objectRemoved: new SIGNALS.Signal(),
helperAdded: new SIGNALS.Signal(),
helperRemoved: new SIGNALS.Signal(),
materialChanged: new SIGNALS.Signal(),
fogTypeChanged: new SIGNALS.Signal(),
fogColorChanged: new SIGNALS.Signal(),
fogParametersChanged: new SIGNALS.Signal(),
windowResize: new SIGNALS.Signal(),
showGridChanged: new SIGNALS.Signal()
};
this.config = new Config();
this.storage = new Storage();
//this.loader = new Loader( this );
this.camera = new THREE.PerspectiveCamera( 50, 1, 1, 100000 );
this.camera.name = 'Camera';
this.scene = new THREE.Scene();
this.scene.name = 'Scene';
this.sceneHelpers = new THREE.Scene();
this.object = {};
this.geometries = {};
this.materials = {};
this.textures = {};
this.scripts = {};
this.selected = null;
this.helpers = {};
};
Editor.prototype = {
/*
showDialog: function ( value ) {
this.signals.showDialog.dispatch( value );
},
*/
//
setScene: function ( scene ) {
this.scene.uuid = scene.uuid;
this.scene.name = scene.name;
this.scene.userData = JSON.parse( JSON.stringify( scene.userData ) );
// avoid render per object
this.signals.sceneGraphChanged.active = false;
while ( scene.children.length > 0 ) {
this.addObject( scene.children[ 0 ] );
}
this.signals.sceneGraphChanged.active = true;
this.signals.sceneGraphChanged.dispatch();
},
//
addObject: function ( object ) {
var scope = this;
object.traverse( function ( child ) {
if ( child.geometry !== undefined ) scope.addGeometry( child.geometry );
if ( child.material !== undefined ) scope.addMaterial( child.material );
scope.addHelper( child );
} );
this.scene.add( object );
this.signals.objectAdded.dispatch( object );
this.signals.sceneGraphChanged.dispatch();
},
moveObject: function ( object, parent, before ) {
if ( parent === undefined ) {
parent = this.scene;
}
parent.add( object );
// sort children array
if ( before !== undefined ) {
var index = parent.children.indexOf( before );
parent.children.splice( index, 0, object );
parent.children.pop();
}
this.signals.sceneGraphChanged.dispatch();
},
nameObject: function ( object, name ) {
object.name = name;
this.signals.sceneGraphChanged.dispatch();
},
removeObject: function ( object ) {
if ( object.parent === undefined ) return; // avoid deleting the camera or scene
var scope = this;
object.traverse( function ( child ) {
scope.removeHelper( child );
} );
object.parent.remove( object );
this.signals.objectRemoved.dispatch( object );
this.signals.sceneGraphChanged.dispatch();
},
addGeometry: function ( geometry ) {
this.geometries[ geometry.uuid ] = geometry;
},
setGeometryName: function ( geometry, name ) {
geometry.name = name;
this.signals.sceneGraphChanged.dispatch();
},
addMaterial: function ( material ) {
this.materials[ material.uuid ] = material;
},
setMaterialName: function ( material, name ) {
material.name = name;
this.signals.sceneGraphChanged.dispatch();
},
addTexture: function ( texture ) {
this.textures[ texture.uuid ] = texture;
},
//
addHelper: function () {
var geometry = new THREE.SphereGeometry( 20, 4, 2 );
var material = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
return function ( object ) {
var helper;
if ( object instanceof THREE.Camera ) {
helper = new THREE.CameraHelper( object, 10 );
} else if ( object instanceof THREE.PointLight ) {
helper = new THREE.PointLightHelper( object, 10 );
} else if ( object instanceof THREE.DirectionalLight ) {
helper = new THREE.DirectionalLightHelper( object, 20 );
} else if ( object instanceof THREE.SpotLight ) {
helper = new THREE.SpotLightHelper( object, 10 );
} else if ( object instanceof THREE.HemisphereLight ) {
helper = new THREE.HemisphereLightHelper( object, 10 );
} else if ( object instanceof THREE.SkinnedMesh ) {
helper = new THREE.SkeletonHelper( object );
} else {
// no helper for this object type
return;
}
var picker = new THREE.Mesh( geometry, material );
picker.name = 'picker';
picker.userData.object = object;
picker.visible = false;
helper.add( picker );
this.sceneHelpers.add( helper );
this.helpers[ object.id ] = helper;
this.signals.helperAdded.dispatch( helper );
};
}(),
removeHelper: function ( object ) {
if ( this.helpers[ object.id ] !== undefined ) {
var helper = this.helpers[ object.id ];
helper.parent.remove( helper );
delete this.helpers[ object.id ];
this.signals.helperRemoved.dispatch( helper );
}
},
//
addScript: function ( object, script ) {
if ( this.scripts[ object.uuid ] === undefined ) {
this.scripts[ object.uuid ] = [];
}
this.scripts[ object.uuid ].push( script );
this.signals.scriptAdded.dispatch( script );
},
removeScript: function ( object, script ) {
if ( this.scripts[ object.uuid ] === undefined ) return;
var index = this.scripts[ object.uuid ].indexOf( script );
if ( index !== - 1 ) {
this.scripts[ object.uuid ].splice( index, 1 );
}
this.signals.scriptRemoved.dispatch( script );
},
//
select: function ( object ) {
if ( this.selected === object ) return;
var uuid = null;
if ( object !== null ) {
uuid = object.uuid;
}
this.selected = object;
this.config.setKey( 'selected', uuid );
this.signals.objectSelected.dispatch( object );
},
selectById: function ( id ) {
if ( id === this.camera.id ) {
this.select( this.camera );
return;
}
this.select( this.scene.getObjectById( id, true ) );
},
selectByUuid: function ( uuid ) {
var scope = this;
this.scene.traverse( function ( child ) {
if ( child.uuid === uuid ) {
scope.select( child );
}
} );
},
deselect: function () {
this.select( null );
},
focus: function ( object ) {
this.signals.objectFocused.dispatch( object );
},
focusById: function ( id ) {
this.focus( this.scene.getObjectById( id, true ) );
},
clear: function () {
this.camera.position.set( 500, 250, 500 );
this.camera.lookAt( new THREE.Vector3() );
var objects = this.scene.children;
while ( objects.length > 0 ) {
this.removeObject( objects[ 0 ] );
}
this.geometries = {};
this.materials = {};
this.textures = {};
this.scripts = {};
this.deselect();
this.signals.editorCleared.dispatch();
},
//
fromJSON: function ( json ) {
var loader = new THREE.ObjectLoader();
// backwards
if ( json.scene === undefined ) {
var scene = loader.parse( json );
this.setScene( scene );
return;
}
// TODO: Clean this up somehow
var camera = loader.parse( json.camera );
this.camera.position.copy( camera.position );
this.camera.rotation.copy( camera.rotation );
this.camera.aspect = camera.aspect;
this.camera.near = camera.near;
this.camera.far = camera.far;
this.setScene( loader.parse( json.scene ) );
this.scripts = json.scripts;
},
toJSON: function () {
return {
project: {
vr: this.config.getKey( 'project/vr' )
},
camera: this.camera.toJSON(),
scene: this.scene.toJSON(),
scripts: this.scripts
};
}
}

441
doodle_app/ui/Loader.js Executable file
View File

@ -0,0 +1,441 @@
/**
* @author mrdoob / http://mrdoob.com/
*/
var Loader = function ( editor ) {
var scope = this;
var signals = editor.signals;
this.loadFile = function ( file ) {
var filename = file.name;
var extension = filename.split( '.' ).pop().toLowerCase();
switch ( extension ) {
case 'awd':
var reader = new FileReader();
reader.addEventListener( 'load', function ( event ) {
var loader = new THREE.AWDLoader();
var scene = loader.parse( event.target.result );
editor.setScene( scene );
}, false );
reader.readAsArrayBuffer( file );
break;
case 'babylon':
var reader = new FileReader();
reader.addEventListener( 'load', function ( event ) {
var contents = event.target.result;
var json = JSON.parse( contents );
var loader = new THREE.BabylonLoader();
var scene = loader.parse( json );
editor.setScene( scene );
}, false );
reader.readAsText( file );
break;
case 'babylonmeshdata':
var reader = new FileReader();
reader.addEventListener( 'load', function ( event ) {
var contents = event.target.result;
var json = JSON.parse( contents );
var loader = new THREE.BabylonLoader();
var geometry = loader.parseGeometry( json );
var material = new THREE.MeshPhongMaterial();
var mesh = new THREE.Mesh( geometry, material );
mesh.name = filename;
editor.addObject( mesh );
editor.select( mesh );
}, false );
reader.readAsText( file );
break;
case 'ctm':
var reader = new FileReader();
reader.addEventListener( 'load', function ( event ) {
var data = new Uint8Array( event.target.result );
var stream = new CTM.Stream( data );
stream.offset = 0;
var loader = new THREE.CTMLoader();
loader.createModel( new CTM.File( stream ), function( geometry ) {
geometry.sourceType = "ctm";
geometry.sourceFile = file.name;
var material = new THREE.MeshPhongMaterial();
var mesh = new THREE.Mesh( geometry, material );
mesh.name = filename;
editor.addObject( mesh );
editor.select( mesh );
} );
}, false );
reader.readAsArrayBuffer( file );
break;
case 'dae':
var reader = new FileReader();
reader.addEventListener( 'load', function ( event ) {
var contents = event.target.result;
var parser = new DOMParser();
var xml = parser.parseFromString( contents, 'text/xml' );
var loader = new THREE.ColladaLoader();
loader.parse( xml, function ( collada ) {
collada.scene.name = filename;
editor.addObject( collada.scene );
editor.select( collada.scene );
} );
}, false );
reader.readAsText( file );
break;
case 'js':
case 'json':
case '3geo':
case '3mat':
case '3obj':
case '3scn':
var reader = new FileReader();
reader.addEventListener( 'load', function ( event ) {
var contents = event.target.result;
// 2.0
if ( contents.indexOf( 'postMessage' ) !== -1 ) {
var blob = new Blob( [ contents ], { type: 'text/javascript' } );
var url = URL.createObjectURL( blob );
var worker = new Worker( url );
worker.onmessage = function ( event ) {
event.data.metadata = { version: 2 };
handleJSON( event.data, file, filename );
};
worker.postMessage( Date.now() );
return;
}
// >= 3.0
var data;
try {
data = JSON.parse( contents );
} catch ( error ) {
alert( error );
return;
}
handleJSON( data, file, filename );
}, false );
reader.readAsText( file );
break;
case 'obj':
var reader = new FileReader();
reader.addEventListener( 'load', function ( event ) {
var contents = event.target.result;
var object = new THREE.OBJLoader().parse( contents );
object.name = filename;
editor.addObject( object );
editor.select( object );
}, false );
reader.readAsText( file );
break;
case 'ply':
var reader = new FileReader();
reader.addEventListener( 'load', function ( event ) {
var contents = event.target.result;
var geometry = new THREE.PLYLoader().parse( contents );
geometry.sourceType = "ply";
geometry.sourceFile = file.name;
var material = new THREE.MeshPhongMaterial();
var mesh = new THREE.Mesh( geometry, material );
mesh.name = filename;
editor.addObject( mesh );
editor.select( mesh );
}, false );
reader.readAsText( file );
break;
case 'stl':
var reader = new FileReader();
reader.addEventListener( 'load', function ( event ) {
var contents = event.target.result;
var geometry = new THREE.STLLoader().parse( contents );
geometry.sourceType = "stl";
geometry.sourceFile = file.name;
var material = new THREE.MeshPhongMaterial();
var mesh = new THREE.Mesh( geometry, material );
mesh.name = filename;
editor.addObject( mesh );
editor.select( mesh );
}, false );
if ( reader.readAsBinaryString !== undefined ) {
reader.readAsBinaryString( file );
} else {
reader.readAsArrayBuffer( file );
}
break;
/*
case 'utf8':
var reader = new FileReader();
reader.addEventListener( 'load', function ( event ) {
var contents = event.target.result;
var geometry = new THREE.UTF8Loader().parse( contents );
var material = new THREE.MeshLambertMaterial();
var mesh = new THREE.Mesh( geometry, material );
editor.addObject( mesh );
editor.select( mesh );
}, false );
reader.readAsBinaryString( file );
break;
*/
case 'vtk':
var reader = new FileReader();
reader.addEventListener( 'load', function ( event ) {
var contents = event.target.result;
var geometry = new THREE.VTKLoader().parse( contents );
geometry.sourceType = "vtk";
geometry.sourceFile = file.name;
var material = new THREE.MeshPhongMaterial();
var mesh = new THREE.Mesh( geometry, material );
mesh.name = filename;
editor.addObject( mesh );
editor.select( mesh );
}, false );
reader.readAsText( file );
break;
case 'wrl':
var reader = new FileReader();
reader.addEventListener( 'load', function ( event ) {
var contents = event.target.result;
var result = new THREE.VRMLLoader().parse( contents );
editor.setScene( result );
}, false );
reader.readAsText( file );
break;
default:
alert( 'Unsupported file format (' + extension + ').' );
break;
}
}
var handleJSON = function ( data, file, filename ) {
if ( data.metadata === undefined ) { // 2.0
data.metadata = { type: 'Geometry' };
}
if ( data.metadata.type === undefined ) { // 3.0
data.metadata.type = 'Geometry';
}
if ( data.metadata.version === undefined ) {
data.metadata.version = data.metadata.formatVersion;
}
if ( data.metadata.type === 'BufferGeometry' ) {
var loader = new THREE.BufferGeometryLoader();
var result = loader.parse( data );
var mesh = new THREE.Mesh( result );
editor.addObject( mesh );
editor.select( mesh );
} else if ( data.metadata.type.toLowerCase() === 'geometry' ) {
var loader = new THREE.JSONLoader();
var result = loader.parse( data );
var geometry = result.geometry;
var material;
if ( result.materials !== undefined ) {
if ( result.materials.length > 1 ) {
material = new THREE.MeshFaceMaterial( result.materials );
} else {
material = result.materials[ 0 ];
}
} else {
material = new THREE.MeshPhongMaterial();
}
geometry.sourceType = "ascii";
geometry.sourceFile = file.name;
var mesh;
if ( geometry.animation && geometry.animation.hierarchy ) {
mesh = new THREE.SkinnedMesh( geometry, material );
} else {
mesh = new THREE.Mesh( geometry, material );
}
mesh.name = filename;
editor.addObject( mesh );
editor.select( mesh );
} else if ( data.metadata.type.toLowerCase() === 'object' ) {
var loader = new THREE.ObjectLoader();
var result = loader.parse( data );
if ( result instanceof THREE.Scene ) {
editor.setScene( result );
} else {
editor.addObject( result );
editor.select( result );
}
} else if ( data.metadata.type.toLowerCase() === 'scene' ) {
// DEPRECATED
var loader = new THREE.SceneLoader();
loader.parse( data, function ( result ) {
editor.setScene( result.scene );
}, '' );
}
};
}

558
doodle_app/ui/Preview.js Executable file
View File

@ -0,0 +1,558 @@
/**
* @author mrdoob / http://mrdoob.com/
*/
var Preview = function ( editor ) {
var signals = editor.signals;
var container = new UI.Panel();
container.setId( 'preview' );
container.setPosition( 'absolute' );
container.setWidth( '50%' );
container.setTop( '0px' );
container.setRight( '0px' );
container.setBottom( '0px' );
var scene = editor.scene;
var sceneHelpers = editor.sceneHelpers;
var objects = [];
// helpers
var grid = new THREE.GridHelper( 200, 10 );
grid.setColors( 0x444444, 0x888888 );
sceneHelpers.add( grid );
var directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
directionalLight.position.set(0, 1, 0);
scene.add(directionalLight);
var light = new THREE.AmbientLight(0x404040); // soft white light
scene.add(light);
//
var camera = editor.camera;
camera.position.fromArray( editor.config.getKey( 'camera/position' ) );
camera.lookAt( new THREE.Vector3().fromArray( editor.config.getKey( 'camera/target' ) ) );
//
var selectionBox = new THREE.BoxHelper();
selectionBox.material.depthTest = false;
selectionBox.material.transparent = true;
selectionBox.visible = false;
sceneHelpers.add( selectionBox );
var transformControls = new THREE.TransformControls( camera, container.dom );
transformControls.addEventListener( 'change', function () {
var object = transformControls.object;
if ( object !== undefined ) {
if ( editor.helpers[ object.id ] !== undefined ) {
editor.helpers[ object.id ].update();
}
}
render();
} );
transformControls.addEventListener( 'mouseDown', function () {
controls.enabled = false;
} );
transformControls.addEventListener( 'mouseUp', function () {
signals.objectChanged.dispatch( transformControls.object );
controls.enabled = true;
} );
sceneHelpers.add( transformControls );
// fog
var oldFogType = "None";
var oldFogColor = 0xaaaaaa;
var oldFogNear = 1;
var oldFogFar = 5000;
var oldFogDensity = 0.00025;
// object picking
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
// events
var getIntersects = function ( point, object ) {
mouse.set( ( point.x * 2 ) - 1, - ( point.y * 2 ) + 1 );
raycaster.setFromCamera( mouse, camera );
if ( object instanceof Array ) {
return raycaster.intersectObjects( object );
}
return raycaster.intersectObject( object );
};
var onDownPosition = new THREE.Vector2();
var onUpPosition = new THREE.Vector2();
var onDoubleClickPosition = new THREE.Vector2();
var getMousePosition = function ( dom, x, y ) {
var rect = dom.getBoundingClientRect();
return [ ( x - rect.left ) / rect.width, ( y - rect.top ) / rect.height ];
};
var handleClick = function () {
if ( onDownPosition.distanceTo( onUpPosition ) == 0 ) {
var intersects = getIntersects( onUpPosition, objects );
if ( intersects.length > 0 ) {
var object = intersects[ 0 ].object;
if ( object.userData.object !== undefined ) {
// helper
editor.select( object.userData.object );
} else {
editor.select( object );
}
} else {
editor.select( null );
}
render();
}
};
var onMouseDown = function ( event ) {
event.preventDefault();
var array = getMousePosition( container.dom, event.clientX, event.clientY );
onDownPosition.fromArray( array );
document.addEventListener( 'mouseup', onMouseUp, false );
};
var onMouseUp = function ( event ) {
var array = getMousePosition( container.dom, event.clientX, event.clientY );
onUpPosition.fromArray( array );
handleClick();
document.removeEventListener( 'mouseup', onMouseUp, false );
};
var onTouchStart = function ( event ) {
var touch = event.changedTouches[ 0 ];
var array = getMousePosition( container.dom, touch.clientX, touch.clientY );
onDownPosition.fromArray( array );
document.addEventListener( 'touchend', onTouchEnd, false );
};
var onTouchEnd = function ( event ) {
var touch = event.changedTouches[ 0 ];
var array = getMousePosition( container.dom, touch.clientX, touch.clientY );
onUpPosition.fromArray( array );
handleClick();
document.removeEventListener( 'touchend', onTouchEnd, false );
};
var onDoubleClick = function ( event ) {
var array = getMousePosition( container.dom, event.clientX, event.clientY );
onDoubleClickPosition.fromArray( array );
var intersects = getIntersects( onDoubleClickPosition, objects );
if ( intersects.length > 0 ) {
var intersect = intersects[ 0 ];
signals.objectFocused.dispatch( intersect.object );
}
};
container.dom.addEventListener( 'mousedown', onMouseDown, false );
container.dom.addEventListener( 'touchstart', onTouchStart, false );
container.dom.addEventListener( 'dblclick', onDoubleClick, false );
// controls need to be added *after* main logic,
// otherwise controls.enabled doesn't work.
var controls = new THREE.EditorControls( camera, container.dom );
controls.center.fromArray( editor.config.getKey( 'camera/target' ) );
controls.addEventListener( 'change', function () {
transformControls.update();
signals.cameraChanged.dispatch( camera );
} );
// signals
signals.editorCleared.add( function () {
controls.center.set( 0, 0, 0 );
render();
} );
signals.transformModeChanged.add( function ( mode ) {
transformControls.setMode( mode );
} );
signals.snapChanged.add( function ( dist ) {
transformControls.setSnap( dist );
} );
signals.spaceChanged.add( function ( space ) {
transformControls.setSpace( space );
} );
signals.rendererChanged.add( function ( type, antialias ) {
container.dom.removeChild( renderer.domElement );
renderer = createRenderer( type, antialias );
renderer.setSize( container.dom.offsetWidth, container.dom.offsetHeight );
container.dom.appendChild( renderer.domElement );
render();
} );
signals.sceneGraphChanged.add( function () {
render();
} );
var saveTimeout;
signals.cameraChanged.add( function () {
if ( saveTimeout !== undefined ) {
clearTimeout( saveTimeout );
}
saveTimeout = setTimeout( function () {
editor.config.setKey(
'camera/position', camera.position.toArray(),
'camera/target', controls.center.toArray()
);
}, 1000 );
render();
} );
signals.objectSelected.add( function ( object ) {
selectionBox.visible = false;
transformControls.detach();
if ( object !== null ) {
if ( object.geometry !== undefined &&
object instanceof THREE.Sprite === false ) {
selectionBox.update( object );
selectionBox.visible = true;
}
transformControls.attach( object );
}
render();
} );
signals.objectFocused.add( function ( object ) {
controls.focus( object );
} );
signals.geometryChanged.add( function ( geometry ) {
selectionBox.update( editor.selected );
render();
} );
signals.objectAdded.add( function ( object ) {
var materialsNeedUpdate = false;
object.traverse( function ( child ) {
if ( child instanceof THREE.Light ) materialsNeedUpdate = true;
objects.push( child );
} );
if ( materialsNeedUpdate === true ) updateMaterials();
} );
signals.objectChanged.add( function ( object ) {
transformControls.update();
if ( object instanceof THREE.PerspectiveCamera ) {
object.updateProjectionMatrix();
}
if ( editor.helpers[ object.id ] !== undefined ) {
editor.helpers[ object.id ].update();
}
render();
} );
signals.objectRemoved.add( function ( object ) {
var materialsNeedUpdate = false;
object.traverse( function ( child ) {
if ( child instanceof THREE.Light ) materialsNeedUpdate = true;
objects.splice( objects.indexOf( child ), 1 );
} );
if ( materialsNeedUpdate === true ) updateMaterials();
} );
signals.helperAdded.add( function ( object ) {
objects.push( object.getObjectByName( 'picker' ) );
} );
signals.helperRemoved.add( function ( object ) {
objects.splice( objects.indexOf( object.getObjectByName( 'picker' ) ), 1 );
} );
signals.materialChanged.add( function ( material ) {
render();
} );
signals.fogTypeChanged.add( function ( fogType ) {
if ( fogType !== oldFogType ) {
if ( fogType === "None" ) {
scene.fog = null;
} else if ( fogType === "Fog" ) {
scene.fog = new THREE.Fog( oldFogColor, oldFogNear, oldFogFar );
} else if ( fogType === "FogExp2" ) {
scene.fog = new THREE.FogExp2( oldFogColor, oldFogDensity );
}
updateMaterials();
oldFogType = fogType;
}
render();
} );
signals.fogColorChanged.add( function ( fogColor ) {
oldFogColor = fogColor;
updateFog( scene );
render();
} );
signals.fogParametersChanged.add( function ( near, far, density ) {
oldFogNear = near;
oldFogFar = far;
oldFogDensity = density;
updateFog( scene );
render();
} );
signals.windowResize.add( function () {
camera.aspect = container.dom.offsetWidth / container.dom.offsetHeight;
camera.updateProjectionMatrix();
renderer.setSize( container.dom.offsetWidth, container.dom.offsetHeight );
render();
} );
signals.showGridChanged.add( function ( showGrid ) {
grid.visible = showGrid;
render();
} );
//
var createRenderer = function ( type, antialias ) {
if ( type === 'WebGLRenderer' && System.support.webgl === false ) {
type = 'CanvasRenderer';
}
var renderer = new THREE[ type ]( { antialias: antialias } );
renderer.setClearColor( clearColor );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.autoClear = false;
renderer.autoUpdateScene = false;
return renderer;
};
var clearColor = 0xaaaaaa;
var renderer = createRenderer( editor.config.getKey( 'project/renderer' ), editor.config.getKey( 'project/renderer/antialias' ) );
container.dom.appendChild( renderer.domElement );
function updateMaterials() {
editor.scene.traverse( function ( node ) {
if ( node.material ) {
node.material.needsUpdate = true;
if ( node.material instanceof THREE.MeshFaceMaterial ) {
for ( var i = 0; i < node.material.materials.length; i ++ ) {
node.material.materials[ i ].needsUpdate = true;
}
}
}
} );
}
function updateFog( root ) {
if ( root.fog ) {
root.fog.color.setHex( oldFogColor );
if ( root.fog.near !== undefined ) root.fog.near = oldFogNear;
if ( root.fog.far !== undefined ) root.fog.far = oldFogFar;
if ( root.fog.density !== undefined ) root.fog.density = oldFogDensity;
}
}
function render() {
sceneHelpers.updateMatrixWorld();
scene.updateMatrixWorld();
renderer.clear();
renderer.render( scene, camera );
renderer.render( sceneHelpers, camera );
}
return container;
}

BIN
models/sewing_machine.stl Normal file

Binary file not shown.

View File

@ -66,7 +66,7 @@ D3D.Paths.prototype.offset = function (offset) {
var solution = new ClipperLib.Paths();
var co = new ClipperLib.ClipperOffset(1, 1);
co.AddPaths(this, ClipperLib.JoinType.jtRound, ClipperLib.EndType.etClosedPolygon);
co.AddPaths(this, ClipperLib.JoinType.jtMiter, ClipperLib.EndType.etClosedPolygon);
co.Execute(solution, offset);
return new D3D.Paths(solution);

View File

@ -167,12 +167,11 @@ D3D.Slicer.prototype.slice = function (layerHeight, height) {
}
var slices = [];
var testPoints = [];
for (var layer = 1; layer < layersIntersections.length; layer ++) {
var layerIntersections = layersIntersections[layer];
var testPoints = [];
if (layerIntersections.length > 0) {
var y = layer * layerHeight;
@ -428,7 +427,7 @@ D3D.Slicer.prototype.generateSupport = function (slices, printer) {
var supportAreas = new D3D.Paths([], true);
for (var layer = slices.length - 1 - supportDistanceLayers; layer >= 0; layer --) {
if (supportAreas.length > 1) {
if (supportAreas.length > 0) {
if (layer >= supportDistanceLayers) {
var sliceSkin = slices[layer - supportDistanceLayers].getOutline();

View File

@ -8,7 +8,7 @@ var Config = function () {
var storage = {
'autosave': true,
'theme': 'css/light.css',
'theme': '../three.js-master/editor/css/light.css',
'project/renderer': 'WebGLRenderer',
'project/renderer/antialias': true,
@ -46,6 +46,8 @@ var Config = function () {
getKey: function ( key ) {
console.log(storage);
return storage[ key ];
},

View File

@ -19,7 +19,7 @@ var Viewport = function ( editor ) {
// helpers
var grid = new THREE.GridHelper( 500, 25 );
var grid = new THREE.GridHelper( 200, 10 );
sceneHelpers.add( grid );
//
@ -236,11 +236,11 @@ var Viewport = function ( editor ) {
switch ( value ) {
case 'css/light.css':
case '../three.js-master/editor/css/light.css':
grid.setColors( 0x444444, 0x888888 );
clearColor = 0xaaaaaa;
break;
case 'css/dark.css':
case '../three.js-master/editor/css/dark.css':
grid.setColors( 0xbbbbbb, 0x888888 );
clearColor = 0x333333;
break;