[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [54442] trunk/blender/source/blender: Fix #33437 Collada: Added scale matching for Scene imports.

Gaia Clary gaia.clary at machinimatrix.org
Sun Feb 10 23:14:56 CET 2013


Revision: 54442
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=54442
Author:   gaiaclary
Date:     2013-02-10 22:14:56 +0000 (Sun, 10 Feb 2013)
Log Message:
-----------
Fix #33437 Collada: Added scale matching for Scene imports.

Modified Paths:
--------------
    trunk/blender/source/blender/collada/DocumentImporter.cpp
    trunk/blender/source/blender/collada/DocumentImporter.h
    trunk/blender/source/blender/collada/collada_utils.cpp
    trunk/blender/source/blender/collada/collada_utils.h
    trunk/blender/source/blender/editors/io/io_collada.c

Modified: trunk/blender/source/blender/collada/DocumentImporter.cpp
===================================================================
--- trunk/blender/source/blender/collada/DocumentImporter.cpp	2013-02-10 21:01:30 UTC (rev 54441)
+++ trunk/blender/source/blender/collada/DocumentImporter.cpp	2013-02-10 22:14:56 UTC (rev 54442)
@@ -213,15 +213,17 @@
 			fprintf(stdout, "Collada: Adjusting Blender units to Importset units: %f.\n", unit_factor);
 
 		}
-		else {
-			// TODO: add automatic scaling for the case when Blender units 
-			//       and import units are set to different values.
-		}
 
 		// Write nodes to scene
 		const COLLADAFW::NodePointerArray& roots = (*it)->getRootNodes();
 		for (unsigned int i = 0; i < roots.getCount(); i++) {
-			write_node(roots[i], NULL, sce, NULL, false);
+			std::vector<Object *> *objects_done;
+			objects_done = write_node(roots[i], NULL, sce, NULL, false);
+			
+			if (!this->import_settings->import_units) {
+				// Match incoming scene with current unit settings
+				bc_match_scale(objects_done, *sce, unit_converter);
+			}
 		}
 
 		// update scene
@@ -443,7 +445,7 @@
 	}
 }
 
-void DocumentImporter::write_node(COLLADAFW::Node *node, COLLADAFW::Node *parent_node, Scene *sce, Object *par, bool is_library_node)
+std::vector<Object *> *DocumentImporter::write_node(COLLADAFW::Node *node, COLLADAFW::Node *parent_node, Scene *sce, Object *par, bool is_library_node)
 {
 	Object *ob = NULL;
 	bool is_joint = node->getType() == COLLADAFW::Node::JOINT;
@@ -549,7 +551,8 @@
 		
 		// XXX: if there're multiple instances, only one is stored
 
-		if (!ob) return;
+		if (!ob) return objects_done;
+
 		for (std::vector<Object *>::iterator it = objects_done->begin(); it != objects_done->end(); ++it) {
 			ob = *it;
 			std::string nodename = node->getName().size() ? node->getName() : node->getOriginalId();
@@ -561,6 +564,7 @@
 				libnode_ob.push_back(ob);
 		}
 
+
 		//create_constraints(et,ob);
 
 	}
@@ -585,6 +589,8 @@
 			write_node(child_nodes[i], node, sce, ob, is_library_node);
 		}
 	}
+
+	return objects_done;
 }
 
 /** When this method is called, the writer must write the entire visual scene.

Modified: trunk/blender/source/blender/collada/DocumentImporter.h
===================================================================
--- trunk/blender/source/blender/collada/DocumentImporter.h	2013-02-10 21:01:30 UTC (rev 54441)
+++ trunk/blender/source/blender/collada/DocumentImporter.h	2013-02-10 22:14:56 UTC (rev 54442)
@@ -77,7 +77,7 @@
 	Object* create_lamp_object(COLLADAFW::InstanceLight*, Scene*);
 	Object* create_instance_node(Object*, COLLADAFW::Node*, COLLADAFW::Node*, Scene*, bool);
 	void create_constraints(ExtraTags *et, Object *ob);
-	void write_node(COLLADAFW::Node*, COLLADAFW::Node*, Scene*, Object*, bool);
+	std::vector<Object *> *write_node(COLLADAFW::Node*, COLLADAFW::Node*, Scene*, Object*, bool);
 	MTex* create_texture(COLLADAFW::EffectCommon*, COLLADAFW::Texture&, Material*, int, TexIndexTextureArrayMap&);
 	void write_profile_COMMON(COLLADAFW::EffectCommon*, Material*);
 	

Modified: trunk/blender/source/blender/collada/collada_utils.cpp
===================================================================
--- trunk/blender/source/blender/collada/collada_utils.cpp	2013-02-10 21:01:30 UTC (rev 54441)
+++ trunk/blender/source/blender/collada/collada_utils.cpp	2013-02-10 22:14:56 UTC (rev 54442)
@@ -295,11 +295,69 @@
 }
 
 std::string bc_replace_string(std::string data, const std::string& pattern,
-                              const std::string& replacement) {
+							  const std::string& replacement) {
 	size_t pos = 0;
-	while ((pos = data.find(pattern, pos)) != std::string::npos) {
+	while((pos = data.find(pattern, pos)) != std::string::npos) {
 		data.replace(pos, pattern.length(), replacement);
 		pos += replacement.length();
 	}
 	return data;
 }
+
+/**
+	Calculate a rescale factor such that the imported scene's scale
+	is preserved. I.e. 1 meter in the import will also be
+	1 meter in the curretn scene.
+	XXX : I am not sure if it is correct to map 1 Blender Unit
+	to 1 Meter for unit type NONE. But it looks reasonable to me.
+*/
+void bc_match_scale(std::vector<Object *> *objects_done, 
+					Scene &sce, 
+					UnitConverter &unit_converter) {
+
+	Object *ob = NULL;
+
+	PointerRNA scene_ptr, unit_settings;
+	PropertyRNA *system_ptr, *scale_ptr;
+	RNA_id_pointer_create(&sce.id, &scene_ptr);
+
+	unit_settings = RNA_pointer_get(&scene_ptr, "unit_settings");
+	system_ptr = RNA_struct_find_property(&unit_settings, "system");
+	scale_ptr = RNA_struct_find_property(&unit_settings, "scale_length");
+
+	int   type  = RNA_property_enum_get(&unit_settings, system_ptr);
+
+	float bl_scale;
+	
+	switch(type) {
+		case USER_UNIT_NONE :	bl_scale = 1.0; // map 1 Blender unit to 1 Meter
+								break;
+		case USER_UNIT_METRIC : bl_scale = RNA_property_float_get(&unit_settings, scale_ptr);
+								break;
+		default :				bl_scale = RNA_property_float_get(&unit_settings, scale_ptr);
+								// it looks like the conversion to Imperial is done implicitly.
+								// So nothing to do here.
+								break;
+	}
+	
+	float size_mat3[3][3];
+	float size_mat4[4][4];
+
+	float scale_conv = unit_converter.getLinearMeter() / bl_scale;
+
+	float rescale[3];
+	rescale[0] = rescale[1] = rescale[2] = scale_conv;
+
+	size_to_mat3(size_mat3, rescale);
+	copy_m4_m3(size_mat4, size_mat3);
+
+	for (std::vector<Object *>::iterator it = objects_done->begin(); it != objects_done->end(); ++it) {
+		ob = *it;
+		mult_m4_m4m4(ob->obmat, ob->obmat, size_mat4);
+		ob->obmat[3][0] = ob->loc[0] * rescale[0];
+		ob->obmat[3][1] = ob->loc[1] * rescale[1];
+		ob->obmat[3][2] = ob->loc[2] * rescale[2];
+		BKE_object_apply_mat4(ob, ob->obmat, 0, 0);
+	}
+
+}

Modified: trunk/blender/source/blender/collada/collada_utils.h
===================================================================
--- trunk/blender/source/blender/collada/collada_utils.h	2013-02-10 21:01:30 UTC (rev 54441)
+++ trunk/blender/source/blender/collada/collada_utils.h	2013-02-10 22:14:56 UTC (rev 54442)
@@ -42,15 +42,19 @@
 #include "DNA_texture_types.h"
 #include "DNA_scene_types.h"
 
+#include "RNA_access.h"
+
 #include "BLI_linklist.h"
 #include "BLI_utildefines.h"
 
 #include "BKE_context.h"
 #include "BKE_object.h"
 #include "BKE_DerivedMesh.h"
+#include "BKE_scene.h"
 }
 
 #include "ExportSettings.h"
+#include "collada_internal.h"
 
 typedef std::map<COLLADAFW::TextureMapId, std::vector<MTex *> > TexIndexTextureArrayMap;
 
@@ -79,5 +83,5 @@
 
 extern std::string bc_replace_string(std::string data, const std::string& pattern, const std::string& replacement); 
 extern std::string bc_url_encode(std::string data); 
-
+extern void bc_match_scale(std::vector<Object *> *objects_done, Scene &sce, UnitConverter &unit_converter);
 #endif

Modified: trunk/blender/source/blender/editors/io/io_collada.c
===================================================================
--- trunk/blender/source/blender/editors/io/io_collada.c	2013-02-10 21:01:30 UTC (rev 54441)
+++ trunk/blender/source/blender/editors/io/io_collada.c	2013-02-10 22:14:56 UTC (rev 54442)
@@ -319,12 +319,11 @@
 	import_units = RNA_boolean_get(op->ptr, "import_units");
 
 	RNA_string_get(op->ptr, "filepath", filename);
-	if (collada_import(C, filename, import_units)) {
+	if (collada_import( C, filename, import_units)) {
 		return OPERATOR_FINISHED;
 	}
 	else {
-		BKE_report(op->reports, RPT_ERROR,
-		           "Errors found during parsing COLLADA document (see console for details)");
+		BKE_report(op->reports, RPT_ERROR, "Errors found during parsing COLLADA document (see console for details)");
 		return OPERATOR_CANCELLED;
 	}
 }
@@ -367,8 +366,9 @@
 	WM_operator_properties_filesel(ot, FOLDERFILE | COLLADAFILE, FILE_BLENDER, FILE_OPENFILE,
 	                               WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY);
 
-	RNA_def_boolean(ot->srna, "import_units", 0, "Import Units",
-	                "If enabled use Units as defined in Collada Import, else keep Blender's current Units settings");
+	RNA_def_boolean(ot->srna,
+					"import_units", 0, "Import Units",
+					"If disabled match import to Blender's current Unit settings. Otherwise use the settings from the Imported scene.");
 
 }
 #endif




More information about the Bf-blender-cvs mailing list