forked from bartvdbraak/blender
Fix #33437 Collada: Added scale matching for Scene imports.
This commit is contained in:
parent
1ba194aedd
commit
22dbb675c1
@ -213,15 +213,17 @@ void DocumentImporter::finish()
|
|||||||
fprintf(stdout, "Collada: Adjusting Blender units to Importset units: %f.\n", unit_factor);
|
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
|
// Write nodes to scene
|
||||||
const COLLADAFW::NodePointerArray& roots = (*it)->getRootNodes();
|
const COLLADAFW::NodePointerArray& roots = (*it)->getRootNodes();
|
||||||
for (unsigned int i = 0; i < roots.getCount(); i++) {
|
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
|
// update scene
|
||||||
@ -443,7 +445,7 @@ void DocumentImporter::create_constraints(ExtraTags *et, Object *ob)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
Object *ob = NULL;
|
||||||
bool is_joint = node->getType() == COLLADAFW::Node::JOINT;
|
bool is_joint = node->getType() == COLLADAFW::Node::JOINT;
|
||||||
@ -549,7 +551,8 @@ void DocumentImporter::write_node(COLLADAFW::Node *node, COLLADAFW::Node *parent
|
|||||||
|
|
||||||
// XXX: if there're multiple instances, only one is stored
|
// 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) {
|
for (std::vector<Object *>::iterator it = objects_done->begin(); it != objects_done->end(); ++it) {
|
||||||
ob = *it;
|
ob = *it;
|
||||||
std::string nodename = node->getName().size() ? node->getName() : node->getOriginalId();
|
std::string nodename = node->getName().size() ? node->getName() : node->getOriginalId();
|
||||||
@ -561,6 +564,7 @@ void DocumentImporter::write_node(COLLADAFW::Node *node, COLLADAFW::Node *parent
|
|||||||
libnode_ob.push_back(ob);
|
libnode_ob.push_back(ob);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//create_constraints(et,ob);
|
//create_constraints(et,ob);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -585,6 +589,8 @@ void DocumentImporter::write_node(COLLADAFW::Node *node, COLLADAFW::Node *parent
|
|||||||
write_node(child_nodes[i], node, sce, ob, is_library_node);
|
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.
|
/** When this method is called, the writer must write the entire visual scene.
|
||||||
|
@ -77,7 +77,7 @@ public:
|
|||||||
Object* create_lamp_object(COLLADAFW::InstanceLight*, Scene*);
|
Object* create_lamp_object(COLLADAFW::InstanceLight*, Scene*);
|
||||||
Object* create_instance_node(Object*, COLLADAFW::Node*, COLLADAFW::Node*, Scene*, bool);
|
Object* create_instance_node(Object*, COLLADAFW::Node*, COLLADAFW::Node*, Scene*, bool);
|
||||||
void create_constraints(ExtraTags *et, Object *ob);
|
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&);
|
MTex* create_texture(COLLADAFW::EffectCommon*, COLLADAFW::Texture&, Material*, int, TexIndexTextureArrayMap&);
|
||||||
void write_profile_COMMON(COLLADAFW::EffectCommon*, Material*);
|
void write_profile_COMMON(COLLADAFW::EffectCommon*, Material*);
|
||||||
|
|
||||||
|
@ -295,11 +295,69 @@ std::string bc_url_encode(std::string data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string bc_replace_string(std::string data, const std::string& pattern,
|
std::string bc_replace_string(std::string data, const std::string& pattern,
|
||||||
const std::string& replacement) {
|
const std::string& replacement) {
|
||||||
size_t pos = 0;
|
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);
|
data.replace(pos, pattern.length(), replacement);
|
||||||
pos += replacement.length();
|
pos += replacement.length();
|
||||||
}
|
}
|
||||||
return data;
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -42,15 +42,19 @@ extern "C" {
|
|||||||
#include "DNA_texture_types.h"
|
#include "DNA_texture_types.h"
|
||||||
#include "DNA_scene_types.h"
|
#include "DNA_scene_types.h"
|
||||||
|
|
||||||
|
#include "RNA_access.h"
|
||||||
|
|
||||||
#include "BLI_linklist.h"
|
#include "BLI_linklist.h"
|
||||||
#include "BLI_utildefines.h"
|
#include "BLI_utildefines.h"
|
||||||
|
|
||||||
#include "BKE_context.h"
|
#include "BKE_context.h"
|
||||||
#include "BKE_object.h"
|
#include "BKE_object.h"
|
||||||
#include "BKE_DerivedMesh.h"
|
#include "BKE_DerivedMesh.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "ExportSettings.h"
|
#include "ExportSettings.h"
|
||||||
|
#include "collada_internal.h"
|
||||||
|
|
||||||
typedef std::map<COLLADAFW::TextureMapId, std::vector<MTex *> > TexIndexTextureArrayMap;
|
typedef std::map<COLLADAFW::TextureMapId, std::vector<MTex *> > TexIndexTextureArrayMap;
|
||||||
|
|
||||||
@ -79,5 +83,5 @@ extern int bc_get_active_UVLayer(Object *ob);
|
|||||||
|
|
||||||
extern std::string bc_replace_string(std::string data, const std::string& pattern, const std::string& replacement);
|
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 std::string bc_url_encode(std::string data);
|
||||||
|
extern void bc_match_scale(std::vector<Object *> *objects_done, Scene &sce, UnitConverter &unit_converter);
|
||||||
#endif
|
#endif
|
||||||
|
@ -319,12 +319,11 @@ static int wm_collada_import_exec(bContext *C, wmOperator *op)
|
|||||||
import_units = RNA_boolean_get(op->ptr, "import_units");
|
import_units = RNA_boolean_get(op->ptr, "import_units");
|
||||||
|
|
||||||
RNA_string_get(op->ptr, "filepath", filename);
|
RNA_string_get(op->ptr, "filepath", filename);
|
||||||
if (collada_import(C, filename, import_units)) {
|
if (collada_import( C, filename, import_units)) {
|
||||||
return OPERATOR_FINISHED;
|
return OPERATOR_FINISHED;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
BKE_report(op->reports, RPT_ERROR,
|
BKE_report(op->reports, RPT_ERROR, "Errors found during parsing COLLADA document (see console for details)");
|
||||||
"Errors found during parsing COLLADA document (see console for details)");
|
|
||||||
return OPERATOR_CANCELLED;
|
return OPERATOR_CANCELLED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -367,8 +366,9 @@ void WM_OT_collada_import(wmOperatorType *ot)
|
|||||||
WM_operator_properties_filesel(ot, FOLDERFILE | COLLADAFILE, FILE_BLENDER, FILE_OPENFILE,
|
WM_operator_properties_filesel(ot, FOLDERFILE | COLLADAFILE, FILE_BLENDER, FILE_OPENFILE,
|
||||||
WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY);
|
WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY);
|
||||||
|
|
||||||
RNA_def_boolean(ot->srna, "import_units", 0, "Import Units",
|
RNA_def_boolean(ot->srna,
|
||||||
"If enabled use Units as defined in Collada Import, else keep Blender's current Units settings");
|
"import_units", 0, "Import Units",
|
||||||
|
"If disabled match import to Blender's current Unit settings. Otherwise use the settings from the Imported scene.");
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user