Browse Source

Support for blender linked groups in blender exporter.

This is a typical blender asset usage approach.  Linked
content can be included in a new blend file but it cannot be edited in
the file that links it.

Upgraded the blender exporter to understand linked groups and add them
to an exported scene.

Added "webgl_loader_scenegroup_blender.html".  This example shows
blender linked groups to demonstrate changes made to the
blender exporter.  The table.blend links an object group (cup and
silverware) from the dinnerset.blend file.  This example does not
incorporate the location offsets in the group definition which it really
should.  Being a new threejs user I did not know how best to do it.
druidhawk 13 years ago
parent
commit
0daa79d512

BIN
examples/obj/blendergroups/dinnerset.blend


BIN
examples/obj/blendergroups/table.blend


File diff suppressed because it is too large
+ 236 - 0
examples/obj/blendergroups/table.js


+ 448 - 0
examples/webgl_loader_scenegroup_blender.html

@@ -0,0 +1,448 @@
+<!doctype html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - io - scene group loader [blender]</title>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+		<style>
+			body {
+				background:#000;
+				color:#fff;
+				padding:0;
+				margin:0;
+				overflow:hidden;
+				font-family:georgia;
+				text-align:center;
+			}
+
+			#info {
+				position: absolute;
+				top: 0px; width: 100%;
+				padding: 5px;
+				font-family: Monospace;
+				font-size: 13px;
+				text-align: center;
+				z-index:100;
+			}
+
+			#progress {
+				color:red;
+				top:7em;
+				width: 100%;
+				font-size:3em;
+				font-variant:small-caps;
+				font-weight:bold;
+				position:absolute;
+				z-index:100;
+				text-align: center;
+				text-shadow: #000 0px 0px 10px;
+				display:none;
+			}
+
+			#start {
+				color:#fff;
+				text-shadow: #000 0px 0px 2px;
+				padding:0.1em 0.3em;
+				width:3em;
+				text-align: center;
+				display:none;
+			}
+
+			.shadow {
+				-moz-box-shadow: 0px 0px 5px #000;
+				-webkit-box-shadow: 0px 0px 5px #000;
+				box-shadow: 0px 0px 5px #000;
+			}
+
+			#progressbar {
+				text-align: center;
+				background: white;
+				width: 250px;
+				height: 10px;
+			}
+
+			#bar {
+				background:#d00;
+				width:50px;
+				height:10px;
+			}
+
+			.enabled {
+				color: lime!important;
+				cursor:pointer;
+			}
+
+			.enabled:hover {
+				text-shadow: #0f0 0px 0px 5px !important;
+			}
+
+			.disabled {
+				background:gray;
+				cursor:default;
+			}
+
+			a { color:red }
+			canvas { pointer-events:none; z-index:10; }
+
+			#scene_explorer {
+				background:transparent;
+				color:#fff;
+				width:200px;
+				position:absolute;
+				text-align:left;
+				top:0px;
+				z-index:200;
+				overflow:auto;
+			}
+
+			#section_exp {
+				background:rgba(0,0,50,0.5);
+				padding:0.5em 0;
+				display:none;
+			}
+
+			#scene_explorer h3 {
+				font-size:1em;
+				padding:0;
+				margin:0;
+				color:orange;
+			}
+
+			#scene_explorer a {
+				color:#555;
+				font-weight:bold;
+				text-decoration:none;
+				font-size:1.2em;
+				font-family:Monospace;
+			}
+			#scene_explorer a:hover {
+				background:#555;
+				color:rgba(0,0,50,1);
+			}
+
+			.part {
+				display:none;
+				padding:0 0 0.5em 2em;
+			}
+
+		</style>
+	</head>
+
+	<body>
+		<div id="info">
+			<a href="http://github.com/mrdoob/three.js">three.js</a> - scene group loader test [blender]
+		</div>
+
+		<div id="scene_explorer">
+			<a id="plus_exp" href="#">[+]</a>
+			<div id="section_exp"></div>
+		</div>
+
+		<div id="progress">
+			<span id="message">Loading ...</span>
+
+			<center>
+				<div id="progressbar" class="shadow"><div id="bar" class="shadow"></div></div>
+				<div id="start" class="disabled"></div>
+			</center>
+		</div>
+
+		<script src="../build/Three.js"></script>
+
+		<script src="js/Detector.js"></script>
+		<script src="js/Stats.js"></script>
+
+		<script>
+
+			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
+
+			var SCREEN_WIDTH = window.innerWidth;
+			var SCREEN_HEIGHT = window.innerHeight;
+
+			var container,stats;
+
+			var camera, scene, loaded;
+			var renderer;
+
+			var mesh, zmesh, geometry;
+
+			var mouseX = 0, mouseY = 0;
+
+			var windowHalfX = window.innerWidth / 2;
+			var windowHalfY = window.innerHeight / 2;
+
+			document.addEventListener( 'mousemove', onDocumentMouseMove, false );
+
+			init();
+			animate();
+
+			function $( id ) {
+
+				return document.getElementById( id );
+
+			}
+
+			function handle_update( result, pieces ) {
+
+				refreshSceneView( result );
+				//renderer.initWebGLObjects( result.scene );
+
+				var m, material, count = 0;
+
+				for ( m in result.materials ) {
+
+					material = result.materials[ m ];
+					if ( ! ( material instanceof THREE.MeshFaceMaterial ) ) {
+
+						if( !material.program ) {
+
+							console.log(m);
+							renderer.initMaterial( material, result.scene.__lights, result.scene.fog );
+
+							count += 1;
+							if( count > pieces ) {
+
+								//console.log("xxxxxxxxx");
+								break;
+
+							}
+
+						}
+
+					}
+
+				}
+
+			}
+
+			function init() {
+
+				container = document.createElement( 'div' );
+				document.body.appendChild( container );
+
+				var loadScene = createLoadScene();
+				scene  = loadScene.scene;
+				camera = loadScene.camera;
+
+				renderer = new THREE.WebGLRenderer();
+				renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
+				renderer.domElement.style.position = "relative";
+				container.appendChild( renderer.domElement );
+
+				stats = new Stats();
+				stats.domElement.style.position = 'absolute';
+				stats.domElement.style.top = '0px';
+				stats.domElement.style.right = '0px';
+				stats.domElement.style.zIndex = 100;
+				container.appendChild( stats.domElement );
+
+				$( "start" ).addEventListener( 'click', onStartClick, false );
+
+				var callbackProgress = function( progress, result ) {
+
+					var bar = 250,
+						total = progress.total_models + progress.total_textures,
+						loaded = progress.loaded_models + progress.loaded_textures;
+
+					if ( total )
+						bar = Math.floor( bar * loaded / total );
+
+					$( "bar" ).style.width = bar + "px";
+
+					count = 0;
+					for ( var m in result.materials ) count++;
+
+					handle_update( result, Math.floor( count/total ) );
+
+				}
+
+				var callbackFinished = function( result ) {
+
+					loaded = result;
+					scene = loaded.scene;
+					//camera = loaded.currentCamera;
+
+					camera.aspect = window.innerWidth / window.innerHeight;
+					camera.updateProjectionMatrix();
+
+					renderer.setClearColor( loaded.bgColor, loaded.bgAlpha );
+					$( "message" ).style.display = "none";
+					$( "progressbar" ).style.display = "none";
+					$( "start" ).style.display = "block";
+					$( "start" ).className = "enabled";
+
+					handle_update( result, 1 );
+
+				}
+
+				$( "progress" ).style.display = "block";
+
+				var loader = new THREE.SceneLoader();
+				loader.callbackProgress = callbackProgress;
+
+				loader.load( "obj/blendergroups/table.js", callbackFinished );
+
+				$( "plus_exp" ).addEventListener( 'click', createToggle( "exp" ), false );
+
+			}
+
+			function setButtonActive( id ) {
+
+				$( "start" ).style.backgroundColor = "green";
+
+			}
+
+			function onStartClick() {
+
+				$( "progress" ).style.display = "none";
+
+				scene = loaded.scene;
+				camera = loaded.currentCamera;
+
+				camera.aspect = window.innerWidth / window.innerHeight;
+				camera.updateProjectionMatrix();
+
+				renderer.setClearColor( loaded.bgColor, loaded.bgAlpha );
+
+			}
+
+			function onDocumentMouseMove(event) {
+
+				mouseX = ( event.clientX - windowHalfX );
+				mouseY = ( event.clientY - windowHalfY );
+
+			}
+
+			function createLoadScene() {
+
+				var result = {
+
+					scene:  new THREE.Scene(),
+					camera: new THREE.PerspectiveCamera( 65, window.innerWidth / window.innerHeight, 1, 1000 )
+
+				};
+
+			 
+				result.camera.position.x = 10;
+				result.camera.position.y = 10;
+				result.camera.position.z = 10;
+
+				var object, geometry, material, light, count = 500, range = 200;
+
+				material = new THREE.MeshLambertMaterial( { color:0xffffff } );
+				geometry = new THREE.CubeGeometry( 5, 5, 5 );
+
+
+
+				result.scene.matrixAutoUpdate = false;
+
+				light = new THREE.PointLight( 0xffffff );
+				result.scene.add( light );
+
+				light = new THREE.DirectionalLight( 0x111111 );
+				light.position.x = 1;
+				result.scene.add( light );
+
+				return result;
+
+			}
+
+			//
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+
+				render();
+				stats.update();
+
+			}
+
+			function render() {
+
+				camera.position.x += ( mouseX - camera.position.x ) * .0001;
+				camera.position.y += ( - mouseY - camera.position.y ) * .0001;
+
+				camera.lookAt( scene.position );
+
+				renderer.render( scene, camera );
+
+			}
+
+			// Scene explorer user interface
+
+			function toggle( id ) {
+
+				var scn = $( "section_" + id ).style,
+					btn = $( "plus_" + id );
+
+				if ( scn.display == "block" ) {
+
+					scn.display = "none";
+					btn.innerHTML = "[+]";
+
+				}
+				else {
+
+					scn.display = "block";
+					btn.innerHTML = "[-]";
+
+				}
+
+			}
+
+			function createToggle( label ) { return function() { toggle( label ) } };
+
+			function refreshSceneView( result ) {
+
+				$( "section_exp" ).innerHTML = generateSceneView( result );
+
+				var config = [ "obj", "geo", "mat", "tex", "lit", "cam" ];
+
+				for ( var i = 0; i < config.length; i++ )
+					$( "plus_" + config[i] ).addEventListener( 'click', createToggle( config[i] ), false );
+
+			}
+
+			function generateSection( label, id, objects ) {
+
+				var html = "";
+
+				html += "<h3><a id='plus_" + id + "' href='#'>[+]</a> " + label + "</h3>";
+				html += "<div id='section_" + id + "' class='part'>";
+
+				for( var o in objects ) {
+
+					html += o + "<br/>";
+
+				}
+				html += "</div>";
+
+				return html;
+
+			}
+
+			function generateSceneView( result ) {
+
+				var config = [
+				[ "Objects",    "obj", result.objects ],
+				[ "Geometries", "geo", result.geometries ],
+				[ "Materials",  "mat", result.materials ],
+				[ "Textures",   "tex", result.textures ],
+				[ "Lights",     "lit", result.lights ],
+				[ "Cameras",    "cam", result.cameras ]
+				];
+
+				var html = "";
+
+				for ( var i = 0; i < config.length; i++ )
+					html += generateSection( config[i][0], config[i][1], config[i][2] );
+
+				return html;
+
+			}
+
+		</script>
+
+	</body>
+</html>

+ 29 - 4
utils/exporters/blender/2.62/scripts/addons/io_mesh_threejs/export_threejs.py

@@ -1754,11 +1754,24 @@ def generate_ascii_scene(data):
 def export_scene(scene, filepath, flipyz, option_colors, option_lights, option_cameras, option_embed_meshes, embeds, option_url_base_html, option_copy_textures):
 def export_scene(scene, filepath, flipyz, option_colors, option_lights, option_cameras, option_embed_meshes, embeds, option_url_base_html, option_copy_textures):
 
 
     source_file = os.path.basename(bpy.data.filepath)
     source_file = os.path.basename(bpy.data.filepath)
-
+    
+    # objects are contained in scene and linked groups
+    objects = []
+    
+    # get scene objects
+    sceneobjects = scene.objects
+    for obj in sceneobjects:
+      objects.append(obj)
+      
+    # get linked group objcts  
+    for group in bpy.data.groups:
+       for object in group.objects:
+          objects.append(object)
+          
     scene_text = ""
     scene_text = ""
     data = {
     data = {
     "scene"        : scene,
     "scene"        : scene,
-    "objects"      : scene.objects,
+    "objects"      : objects,
     "embeds"       : embeds,
     "embeds"       : embeds,
     "source_file"  : source_file,
     "source_file"  : source_file,
     "filepath"     : filepath,
     "filepath"     : filepath,
@@ -1809,9 +1822,21 @@ def save(operator, context, filepath = "",
         bpy.ops.object.mode_set(mode='OBJECT')
         bpy.ops.object.mode_set(mode='OBJECT')
 
 
     if option_all_meshes:
     if option_all_meshes:
-        objects = scene.objects
+        sceneobjects = scene.objects
     else:
     else:
-        objects = context.selected_objects
+        sceneobjects = context.selected_objects
+
+    # objects are contained in scene and linked groups
+    objects = []
+    
+    # get scene objects
+    for obj in sceneobjects:
+      objects.append(obj)
+      
+    # get objects in linked groups  
+    for group in bpy.data.groups:
+       for object in group.objects:
+          objects.append(object) 
 
 
     if option_export_scene:
     if option_export_scene:
 
 

Some files were not shown because too many files changed in this diff