diff options
author | Campbell Barton <ideasman42@gmail.com> | 2019-04-17 07:17:24 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2019-04-17 07:21:24 +0300 |
commit | e12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch) | |
tree | 8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/collada/DocumentImporter.cpp | |
parent | b3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff) |
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211.
For details on usage and instructions for migrating branches
without conflicts, see:
https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/collada/DocumentImporter.cpp')
-rw-r--r-- | source/blender/collada/DocumentImporter.cpp | 1816 |
1 files changed, 903 insertions, 913 deletions
diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp index f784c811c26..d21e71bb37b 100644 --- a/source/blender/collada/DocumentImporter.cpp +++ b/source/blender/collada/DocumentImporter.cpp @@ -24,7 +24,7 @@ #include <string> #include <map> -#include <algorithm> // sort() +#include <algorithm> // sort() #include "COLLADAFWRoot.h" #include "COLLADAFWStableHeaders.h" @@ -72,7 +72,6 @@ extern "C" { #include "WM_api.h" #include "WM_types.h" - } #include "DEG_depsgraph.h" @@ -96,76 +95,82 @@ extern "C" { // creates empties for each imported bone on layer 2, for debugging // #define ARMATURE_TEST -DocumentImporter::DocumentImporter(bContext *C, const ImportSettings *import_settings) : - import_settings(import_settings), - mImportStage(Fetching_Scene_data), - mContext(C), - view_layer(CTX_data_view_layer(mContext)), - armature_importer(&unit_converter, &mesh_importer, CTX_data_main(C), CTX_data_scene(C), view_layer, import_settings), - mesh_importer(&unit_converter, &armature_importer, CTX_data_main(C), CTX_data_scene(C), view_layer), - anim_importer(C, &unit_converter, &armature_importer, CTX_data_scene(C)) +DocumentImporter::DocumentImporter(bContext *C, const ImportSettings *import_settings) + : import_settings(import_settings), + mImportStage(Fetching_Scene_data), + mContext(C), + view_layer(CTX_data_view_layer(mContext)), + armature_importer(&unit_converter, + &mesh_importer, + CTX_data_main(C), + CTX_data_scene(C), + view_layer, + import_settings), + mesh_importer( + &unit_converter, &armature_importer, CTX_data_main(C), CTX_data_scene(C), view_layer), + anim_importer(C, &unit_converter, &armature_importer, CTX_data_scene(C)) { } DocumentImporter::~DocumentImporter() { - TagsMap::iterator etit; - etit = uid_tags_map.begin(); - while (etit != uid_tags_map.end()) { - delete etit->second; - etit++; - } + TagsMap::iterator etit; + etit = uid_tags_map.begin(); + while (etit != uid_tags_map.end()) { + delete etit->second; + etit++; + } } bool DocumentImporter::import() { - ErrorHandler errorHandler; - COLLADASaxFWL::Loader loader(&errorHandler); - COLLADAFW::Root root(&loader, this); - ExtraHandler *ehandler = new ExtraHandler(this, &(this->anim_importer)); - - loader.registerExtraDataCallbackHandler(ehandler); - - // deselect all to select new objects - BKE_view_layer_base_deselect_all(view_layer); - - std::string mFilename = std::string(this->import_settings->filepath); - const std::string encodedFilename = bc_url_encode(mFilename); - if (!root.loadDocument(encodedFilename)) { - fprintf(stderr, "COLLADAFW::Root::loadDocument() returned false on 1st pass\n"); - delete ehandler; - return false; - } - - if (errorHandler.hasError()) { - delete ehandler; - return false; - } - - /** TODO set up scene graph and such here */ - mImportStage = Fetching_Controller_data; - COLLADASaxFWL::Loader loader2; - COLLADAFW::Root root2(&loader2, this); - - if (!root2.loadDocument(encodedFilename)) { - fprintf(stderr, "COLLADAFW::Root::loadDocument() returned false on 2nd pass\n"); - delete ehandler; - return false; - } - - delete ehandler; - - return true; + ErrorHandler errorHandler; + COLLADASaxFWL::Loader loader(&errorHandler); + COLLADAFW::Root root(&loader, this); + ExtraHandler *ehandler = new ExtraHandler(this, &(this->anim_importer)); + + loader.registerExtraDataCallbackHandler(ehandler); + + // deselect all to select new objects + BKE_view_layer_base_deselect_all(view_layer); + + std::string mFilename = std::string(this->import_settings->filepath); + const std::string encodedFilename = bc_url_encode(mFilename); + if (!root.loadDocument(encodedFilename)) { + fprintf(stderr, "COLLADAFW::Root::loadDocument() returned false on 1st pass\n"); + delete ehandler; + return false; + } + + if (errorHandler.hasError()) { + delete ehandler; + return false; + } + + /** TODO set up scene graph and such here */ + mImportStage = Fetching_Controller_data; + COLLADASaxFWL::Loader loader2; + COLLADAFW::Root root2(&loader2, this); + + if (!root2.loadDocument(encodedFilename)) { + fprintf(stderr, "COLLADAFW::Root::loadDocument() returned false on 2nd pass\n"); + delete ehandler; + return false; + } + + delete ehandler; + + return true; } -void DocumentImporter::cancel(const COLLADAFW::String& errorMessage) +void DocumentImporter::cancel(const COLLADAFW::String &errorMessage) { - // TODO: if possible show error info - // - // Should we get rid of invisible Meshes that were created so far - // or maybe create objects at coordinate space origin? - // - // The latter sounds better. + // TODO: if possible show error info + // + // Should we get rid of invisible Meshes that were created so far + // or maybe create objects at coordinate space origin? + // + // The latter sounds better. } void DocumentImporter::start() @@ -174,143 +179,145 @@ void DocumentImporter::start() void DocumentImporter::finish() { - if (mImportStage == Fetching_Controller_data) - return; - - Main *bmain = CTX_data_main(mContext); - // TODO: create a new scene except the selected <visual_scene> - use current blender scene for it - Scene *sce = CTX_data_scene(mContext); - unit_converter.calculate_scale(*sce); - - std::vector<Object *> *objects_to_scale = new std::vector<Object *>(); - - /** TODO Break up and put into 2-pass parsing of DAE */ - std::vector<const COLLADAFW::VisualScene *>::iterator sit; - for (sit = vscenes.begin(); sit != vscenes.end(); sit++) { - PointerRNA sceneptr, unit_settings; - PropertyRNA *system, *scale; - - // for scene unit settings: system, scale_length - - RNA_id_pointer_create(&sce->id, &sceneptr); - unit_settings = RNA_pointer_get(&sceneptr, "unit_settings"); - system = RNA_struct_find_property(&unit_settings, "system"); - scale = RNA_struct_find_property(&unit_settings, "scale_length"); - - if (this->import_settings->import_units) { - - switch (unit_converter.isMetricSystem()) { - case UnitConverter::Metric: - RNA_property_enum_set(&unit_settings, system, USER_UNIT_METRIC); - break; - case UnitConverter::Imperial: - RNA_property_enum_set(&unit_settings, system, USER_UNIT_IMPERIAL); - break; - default: - RNA_property_enum_set(&unit_settings, system, USER_UNIT_NONE); - break; - } - float unit_factor = unit_converter.getLinearMeter(); - RNA_property_float_set(&unit_settings, scale, unit_factor); - fprintf(stdout, "Collada: Adjusting Blender units to Importset units: %f.\n", unit_factor); - - } - - // Write nodes to scene - fprintf(stderr, "+-- Import Scene --------\n"); - const COLLADAFW::NodePointerArray& roots = (*sit)->getRootNodes(); - for (unsigned int i = 0; i < roots.getCount(); i++) { - std::vector<Object *> *objects_done = write_node(roots[i], NULL, sce, NULL, false); - objects_to_scale->insert(objects_to_scale->end(), objects_done->begin(), objects_done->end()); - delete objects_done; - } - - } - - - mesh_importer.optimize_material_assignements(); - - armature_importer.set_tags_map(this->uid_tags_map); - armature_importer.make_armatures(mContext, *objects_to_scale); - armature_importer.make_shape_keys(mContext); + if (mImportStage == Fetching_Controller_data) + return; + + Main *bmain = CTX_data_main(mContext); + // TODO: create a new scene except the selected <visual_scene> - use current blender scene for it + Scene *sce = CTX_data_scene(mContext); + unit_converter.calculate_scale(*sce); + + std::vector<Object *> *objects_to_scale = new std::vector<Object *>(); + + /** TODO Break up and put into 2-pass parsing of DAE */ + std::vector<const COLLADAFW::VisualScene *>::iterator sit; + for (sit = vscenes.begin(); sit != vscenes.end(); sit++) { + PointerRNA sceneptr, unit_settings; + PropertyRNA *system, *scale; + + // for scene unit settings: system, scale_length + + RNA_id_pointer_create(&sce->id, &sceneptr); + unit_settings = RNA_pointer_get(&sceneptr, "unit_settings"); + system = RNA_struct_find_property(&unit_settings, "system"); + scale = RNA_struct_find_property(&unit_settings, "scale_length"); + + if (this->import_settings->import_units) { + + switch (unit_converter.isMetricSystem()) { + case UnitConverter::Metric: + RNA_property_enum_set(&unit_settings, system, USER_UNIT_METRIC); + break; + case UnitConverter::Imperial: + RNA_property_enum_set(&unit_settings, system, USER_UNIT_IMPERIAL); + break; + default: + RNA_property_enum_set(&unit_settings, system, USER_UNIT_NONE); + break; + } + float unit_factor = unit_converter.getLinearMeter(); + RNA_property_float_set(&unit_settings, scale, unit_factor); + fprintf(stdout, "Collada: Adjusting Blender units to Importset units: %f.\n", unit_factor); + } + + // Write nodes to scene + fprintf(stderr, "+-- Import Scene --------\n"); + const COLLADAFW::NodePointerArray &roots = (*sit)->getRootNodes(); + for (unsigned int i = 0; i < roots.getCount(); i++) { + std::vector<Object *> *objects_done = write_node(roots[i], NULL, sce, NULL, false); + objects_to_scale->insert( + objects_to_scale->end(), objects_done->begin(), objects_done->end()); + delete objects_done; + } + } + + mesh_importer.optimize_material_assignements(); + + armature_importer.set_tags_map(this->uid_tags_map); + armature_importer.make_armatures(mContext, *objects_to_scale); + armature_importer.make_shape_keys(mContext); #if 0 - armature_importer.fix_animation(); + armature_importer.fix_animation(); #endif - for (std::vector<const COLLADAFW::VisualScene *>::iterator vsit = vscenes.begin(); vsit != vscenes.end(); vsit++) { - const COLLADAFW::NodePointerArray& roots = (*vsit)->getRootNodes(); + for (std::vector<const COLLADAFW::VisualScene *>::iterator vsit = vscenes.begin(); + vsit != vscenes.end(); + vsit++) { + const COLLADAFW::NodePointerArray &roots = (*vsit)->getRootNodes(); - for (unsigned int i = 0; i < roots.getCount(); i++) { - translate_anim_recursive(roots[i], NULL, NULL); - } - } + for (unsigned int i = 0; i < roots.getCount(); i++) { + translate_anim_recursive(roots[i], NULL, NULL); + } + } - if (libnode_ob.size()) { + if (libnode_ob.size()) { - fprintf(stderr, "| Cleanup: free %d library nodes\n", (int)libnode_ob.size()); - // free all library_nodes - std::vector<Object *>::iterator it; - for (it = libnode_ob.begin(); it != libnode_ob.end(); it++) { - Object *ob = *it; - BKE_scene_collections_object_remove(bmain, sce, ob, true); - } - libnode_ob.clear(); - } + fprintf(stderr, "| Cleanup: free %d library nodes\n", (int)libnode_ob.size()); + // free all library_nodes + std::vector<Object *>::iterator it; + for (it = libnode_ob.begin(); it != libnode_ob.end(); it++) { + Object *ob = *it; + BKE_scene_collections_object_remove(bmain, sce, ob, true); + } + libnode_ob.clear(); + } - bc_match_scale(objects_to_scale, unit_converter, !this->import_settings->import_units); + bc_match_scale(objects_to_scale, unit_converter, !this->import_settings->import_units); - delete objects_to_scale; + delete objects_to_scale; - // update scene - DEG_id_tag_update(&sce->id, ID_RECALC_COPY_ON_WRITE); - DEG_relations_tag_update(bmain); - WM_event_add_notifier(mContext, NC_OBJECT | ND_TRANSFORM, NULL); + // update scene + DEG_id_tag_update(&sce->id, ID_RECALC_COPY_ON_WRITE); + DEG_relations_tag_update(bmain); + WM_event_add_notifier(mContext, NC_OBJECT | ND_TRANSFORM, NULL); } - -void DocumentImporter::translate_anim_recursive(COLLADAFW::Node *node, COLLADAFW::Node *par = NULL, Object *parob = NULL) +void DocumentImporter::translate_anim_recursive(COLLADAFW::Node *node, + COLLADAFW::Node *par = NULL, + Object *parob = NULL) { - // The split in #29246, rootmap must point at actual root when - // calculating bones in apply_curves_as_matrix. - actual root is the root node. - // This has to do with inverse bind poses being world space - // (the sources for skinned bones' restposes) and the way - // non-skinning nodes have their "restpose" recursively calculated. - // XXX TODO: design issue, how to support unrelated joints taking - // part in skinning. - if (par) { // && par->getType() == COLLADAFW::Node::JOINT) { - // par is root if there's no corresp. key in root_map - if (root_map.find(par->getUniqueId()) == root_map.end()) - root_map[node->getUniqueId()] = node; - else - root_map[node->getUniqueId()] = root_map[par->getUniqueId()]; - } + // The split in #29246, rootmap must point at actual root when + // calculating bones in apply_curves_as_matrix. - actual root is the root node. + // This has to do with inverse bind poses being world space + // (the sources for skinned bones' restposes) and the way + // non-skinning nodes have their "restpose" recursively calculated. + // XXX TODO: design issue, how to support unrelated joints taking + // part in skinning. + if (par) { // && par->getType() == COLLADAFW::Node::JOINT) { + // par is root if there's no corresp. key in root_map + if (root_map.find(par->getUniqueId()) == root_map.end()) + root_map[node->getUniqueId()] = node; + else + root_map[node->getUniqueId()] = root_map[par->getUniqueId()]; + } #if 0 - COLLADAFW::Transformation::TransformationType types[] = { - COLLADAFW::Transformation::ROTATE, - COLLADAFW::Transformation::SCALE, - COLLADAFW::Transformation::TRANSLATE, - COLLADAFW::Transformation::MATRIX, - }; - - Object *ob; + COLLADAFW::Transformation::TransformationType types[] = { + COLLADAFW::Transformation::ROTATE, + COLLADAFW::Transformation::SCALE, + COLLADAFW::Transformation::TRANSLATE, + COLLADAFW::Transformation::MATRIX, + }; + + Object *ob; #endif - unsigned int i; - - if (node->getType() == COLLADAFW::Node::JOINT && par == NULL) { - // For Skeletons without root node we have to simulate the - // root node here and recursively enter the same function - // XXX: maybe this can be made more elegant. - translate_anim_recursive(node, node, parob); - } - else { - anim_importer.translate_Animations(node, root_map, object_map, FW_object_map, uid_material_map); - COLLADAFW::NodePointerArray &children = node->getChildNodes(); - for (i = 0; i < children.getCount(); i++) { - translate_anim_recursive(children[i], node, NULL); - } - } + unsigned int i; + + if (node->getType() == COLLADAFW::Node::JOINT && par == NULL) { + // For Skeletons without root node we have to simulate the + // root node here and recursively enter the same function + // XXX: maybe this can be made more elegant. + translate_anim_recursive(node, node, parob); + } + else { + anim_importer.translate_Animations( + node, root_map, object_map, FW_object_map, uid_material_map); + COLLADAFW::NodePointerArray &children = node->getChildNodes(); + for (i = 0; i < children.getCount(); i++) { + translate_anim_recursive(children[i], node, NULL); + } + } } /** @@ -319,373 +326,384 @@ void DocumentImporter::translate_anim_recursive(COLLADAFW::Node *node, COLLADAFW */ std::string DocumentImporter::get_import_version(const COLLADAFW::FileInfo *asset) { - const char AUTORING_TOOL[] = "authoring_tool"; - const std::string BLENDER("Blender "); - const COLLADAFW::FileInfo::ValuePairPointerArray &valuePairs = asset->getValuePairArray(); - for ( size_t i = 0, count = valuePairs.getCount(); i < count; ++i) - { - const COLLADAFW::FileInfo::ValuePair* valuePair = valuePairs[i]; - const COLLADAFW::String& key = valuePair->first; - const COLLADAFW::String& value = valuePair->second; - if ( key == AUTORING_TOOL ) - { - if (value.compare(0, BLENDER.length(), BLENDER) == 0) - { - // Was made with Blender, now get version string - std::string v = value.substr(BLENDER.length()); - std::string::size_type n = v.find(" "); - if (n > 0) { - return v.substr(0,n); - } - } - } - } - return ""; + const char AUTORING_TOOL[] = "authoring_tool"; + const std::string BLENDER("Blender "); + const COLLADAFW::FileInfo::ValuePairPointerArray &valuePairs = asset->getValuePairArray(); + for (size_t i = 0, count = valuePairs.getCount(); i < count; ++i) { + const COLLADAFW::FileInfo::ValuePair *valuePair = valuePairs[i]; + const COLLADAFW::String &key = valuePair->first; + const COLLADAFW::String &value = valuePair->second; + if (key == AUTORING_TOOL) { + if (value.compare(0, BLENDER.length(), BLENDER) == 0) { + // Was made with Blender, now get version string + std::string v = value.substr(BLENDER.length()); + std::string::size_type n = v.find(" "); + if (n > 0) { + return v.substr(0, n); + } + } + } + } + return ""; } /** When this method is called, the writer must write the global document asset. * \return The writer should return true, if writing succeeded, false otherwise.*/ bool DocumentImporter::writeGlobalAsset(const COLLADAFW::FileInfo *asset) { - unit_converter.read_asset(asset); - import_from_version = get_import_version(asset); - anim_importer.set_import_from_version(import_from_version); - return true; + unit_converter.read_asset(asset); + import_from_version = get_import_version(asset); + anim_importer.set_import_from_version(import_from_version); + return true; } /** When this method is called, the writer must write the scene. * \return The writer should return true, if writing succeeded, false otherwise.*/ bool DocumentImporter::writeScene(const COLLADAFW::Scene *scene) { - // XXX could store the scene id, but do nothing for now - return true; + // XXX could store the scene id, but do nothing for now + return true; } Object *DocumentImporter::create_camera_object(COLLADAFW::InstanceCamera *camera, Scene *sce) { - const COLLADAFW::UniqueId& cam_uid = camera->getInstanciatedObjectId(); - if (uid_camera_map.find(cam_uid) == uid_camera_map.end()) { - // fprintf(stderr, "Couldn't find camera by UID.\n"); - return NULL; - } - - Main *bmain = CTX_data_main(mContext); - Object *ob = bc_add_object(bmain, sce, view_layer, OB_CAMERA, NULL); - Camera *cam = uid_camera_map[cam_uid]; - Camera *old_cam = (Camera *)ob->data; - ob->data = cam; - BKE_id_free_us(bmain, old_cam); - return ob; + const COLLADAFW::UniqueId &cam_uid = camera->getInstanciatedObjectId(); + if (uid_camera_map.find(cam_uid) == uid_camera_map.end()) { + // fprintf(stderr, "Couldn't find camera by UID.\n"); + return NULL; + } + + Main *bmain = CTX_data_main(mContext); + Object *ob = bc_add_object(bmain, sce, view_layer, OB_CAMERA, NULL); + Camera *cam = uid_camera_map[cam_uid]; + Camera *old_cam = (Camera *)ob->data; + ob->data = cam; + BKE_id_free_us(bmain, old_cam); + return ob; } Object *DocumentImporter::create_light_object(COLLADAFW::InstanceLight *lamp, Scene *sce) { - const COLLADAFW::UniqueId& lamp_uid = lamp->getInstanciatedObjectId(); - if (uid_light_map.find(lamp_uid) == uid_light_map.end()) { - fprintf(stderr, "Couldn't find light by UID.\n"); - return NULL; - } - - Main *bmain = CTX_data_main(mContext); - Object *ob = bc_add_object(bmain, sce, view_layer, OB_LAMP, NULL); - Light *la = uid_light_map[lamp_uid]; - Light *old_light = (Light *)ob->data; - ob->data = la; - BKE_id_free_us(bmain, old_light); - return ob; + const COLLADAFW::UniqueId &lamp_uid = lamp->getInstanciatedObjectId(); + if (uid_light_map.find(lamp_uid) == uid_light_map.end()) { + fprintf(stderr, "Couldn't find light by UID.\n"); + return NULL; + } + + Main *bmain = CTX_data_main(mContext); + Object *ob = bc_add_object(bmain, sce, view_layer, OB_LAMP, NULL); + Light *la = uid_light_map[lamp_uid]; + Light *old_light = (Light *)ob->data; + ob->data = la; + BKE_id_free_us(bmain, old_light); + return ob; } -Object *DocumentImporter::create_instance_node(Object *source_ob, COLLADAFW::Node *source_node, COLLADAFW::Node *instance_node, Scene *sce, bool is_library_node) +Object *DocumentImporter::create_instance_node(Object *source_ob, + COLLADAFW::Node *source_node, + COLLADAFW::Node *instance_node, + Scene *sce, + bool is_library_node) { - //fprintf(stderr, "create <instance_node> under node id=%s from node id=%s\n", instance_node ? instance_node->getOriginalId().c_str() : NULL, source_node ? source_node->getOriginalId().c_str() : NULL); - - Main *bmain = CTX_data_main(mContext); - Object *obn = BKE_object_copy(bmain, source_ob); - DEG_id_tag_update(&obn->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION); - BKE_collection_object_add_from(bmain, sce, source_ob, obn); - - if (instance_node) { - anim_importer.read_node_transform(instance_node, obn); - // if we also have a source_node (always ;), take its - // transformation matrix and apply it to the newly instantiated - // object to account for node hierarchy transforms in - // .dae - if (source_node) { - COLLADABU::Math::Matrix4 mat4 = source_node->getTransformationMatrix(); - COLLADABU::Math::Matrix4 bmat4 = mat4.transpose(); // transpose to get blender row-major order - float mat[4][4]; - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - mat[i][j] = bmat4[i][j]; - } - } - // calc new matrix and apply - mul_m4_m4m4(obn->obmat, obn->obmat, mat); - BKE_object_apply_mat4(obn, obn->obmat, 0, 0); - } - } - else { - anim_importer.read_node_transform(source_node, obn); - } - - /*DAG_relations_tag_update(CTX_data_main(mContext));*/ - - COLLADAFW::NodePointerArray &children = source_node->getChildNodes(); - if (children.getCount()) { - for (unsigned int i = 0; i < children.getCount(); i++) { - COLLADAFW::Node *child_node = children[i]; - const COLLADAFW::UniqueId& child_id = child_node->getUniqueId(); - if (object_map.find(child_id) == object_map.end()) - continue; - COLLADAFW::InstanceNodePointerArray &inodes = child_node->getInstanceNodes(); - Object *new_child = NULL; - if (inodes.getCount()) { // \todo loop through instance nodes - const COLLADAFW::UniqueId& id = inodes[0]->getInstanciatedObjectId(); - fprintf(stderr, "Doing %d child nodes\n", (int)node_map.count(id)); - new_child = create_instance_node(object_map.find(id)->second, node_map[id], child_node, sce, is_library_node); - } - else { - new_child = create_instance_node(object_map.find(child_id)->second, child_node, NULL, sce, is_library_node); - } - bc_set_parent(new_child, obn, mContext, true); - - if (is_library_node) - libnode_ob.push_back(new_child); - } - } - - return obn; + //fprintf(stderr, "create <instance_node> under node id=%s from node id=%s\n", instance_node ? instance_node->getOriginalId().c_str() : NULL, source_node ? source_node->getOriginalId().c_str() : NULL); + + Main *bmain = CTX_data_main(mContext); + Object *obn = BKE_object_copy(bmain, source_ob); + DEG_id_tag_update(&obn->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION); + BKE_collection_object_add_from(bmain, sce, source_ob, obn); + + if (instance_node) { + anim_importer.read_node_transform(instance_node, obn); + // if we also have a source_node (always ;), take its + // transformation matrix and apply it to the newly instantiated + // object to account for node hierarchy transforms in + // .dae + if (source_node) { + COLLADABU::Math::Matrix4 mat4 = source_node->getTransformationMatrix(); + COLLADABU::Math::Matrix4 bmat4 = + mat4.transpose(); // transpose to get blender row-major order + float mat[4][4]; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + mat[i][j] = bmat4[i][j]; + } + } + // calc new matrix and apply + mul_m4_m4m4(obn->obmat, obn->obmat, mat); + BKE_object_apply_mat4(obn, obn->obmat, 0, 0); + } + } + else { + anim_importer.read_node_transform(source_node, obn); + } + + /*DAG_relations_tag_update(CTX_data_main(mContext));*/ + + COLLADAFW::NodePointerArray &children = source_node->getChildNodes(); + if (children.getCount()) { + for (unsigned int i = 0; i < children.getCount(); i++) { + COLLADAFW::Node *child_node = children[i]; + const COLLADAFW::UniqueId &child_id = child_node->getUniqueId(); + if (object_map.find(child_id) == object_map.end()) + continue; + COLLADAFW::InstanceNodePointerArray &inodes = child_node->getInstanceNodes(); + Object *new_child = NULL; + if (inodes.getCount()) { // \todo loop through instance nodes + const COLLADAFW::UniqueId &id = inodes[0]->getInstanciatedObjectId(); + fprintf(stderr, "Doing %d child nodes\n", (int)node_map.count(id)); + new_child = create_instance_node( + object_map.find(id)->second, node_map[id], child_node, sce, is_library_node); + } + else { + new_child = create_instance_node( + object_map.find(child_id)->second, child_node, NULL, sce, is_library_node); + } + bc_set_parent(new_child, obn, mContext, true); + + if (is_library_node) + libnode_ob.push_back(new_child); + } + } + + return obn; } // to create constraints off node <extra> tags. Assumes only constraint data in // current <extra> with blender profile. void DocumentImporter::create_constraints(ExtraTags *et, Object *ob) { - if (et && et->isProfile("blender")) { - std::string name; - short type = 0; - et->setData("type", &type); - BKE_constraint_add_for_object(ob, "Test_con", type); - - } + if (et && et->isProfile("blender")) { + std::string name; + short type = 0; + et->setData("type", &type); + BKE_constraint_add_for_object(ob, "Test_con", type); + } } -void DocumentImporter::report_unknown_reference(const COLLADAFW::Node &node, const std::string object_type) +void DocumentImporter::report_unknown_reference(const COLLADAFW::Node &node, + const std::string object_type) { - std::string id = node.getOriginalId(); - std::string name = node.getName(); - fprintf(stderr, - "error: node id=\"%s\", name=\"%s\" refers to an undefined %s.\n", - id.c_str(), - name.c_str(), - object_type.c_str()); + std::string id = node.getOriginalId(); + std::string name = node.getName(); + fprintf(stderr, + "error: node id=\"%s\", name=\"%s\" refers to an undefined %s.\n", + id.c_str(), + name.c_str(), + object_type.c_str()); } -std::vector<Object *> *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) { - Main *bmain = CTX_data_main(mContext); - Object *ob = NULL; - bool is_joint = node->getType() == COLLADAFW::Node::JOINT; - bool read_transform = true; - std::string id = node->getOriginalId(); - std::string name = node->getName(); - - // if node has child nodes write them - COLLADAFW::NodePointerArray &child_nodes = node->getChildNodes(); - - std::vector<Object *> *objects_done = new std::vector<Object *>(); - std::vector<Object *> *root_objects = new std::vector<Object *>(); - - fprintf(stderr, - "| %s id='%s', name='%s'\n", - is_joint ? "JOINT" : "NODE ", - id.c_str(), - name.c_str() ); - - if (is_joint) { - if (parent_node == NULL && !is_library_node) { - // A Joint on root level is a skeleton without root node. - // Here we add the armature "on the fly": - par = bc_add_object(bmain, sce, view_layer, OB_ARMATURE, std::string("Armature").c_str()); - objects_done->push_back(par); - root_objects->push_back(par); - object_map.insert(std::pair<COLLADAFW::UniqueId, Object *>(node->getUniqueId(), par)); - node_map[node->getUniqueId()] = node; - } - if (parent_node == NULL || parent_node->getType() != COLLADAFW::Node::JOINT) { - armature_importer.add_root_joint(node, par); - } - - if (parent_node == NULL) { - // for skeletons without root node all has been done above. - // Skeletons with root node are handled further down. - goto finally; - } - } - else { - COLLADAFW::InstanceGeometryPointerArray &geom = node->getInstanceGeometries(); - COLLADAFW::InstanceCameraPointerArray &camera = node->getInstanceCameras(); - COLLADAFW::InstanceLightPointerArray &lamp = node->getInstanceLights(); - COLLADAFW::InstanceControllerPointerArray &controller = node->getInstanceControllers(); - COLLADAFW::InstanceNodePointerArray &inst_node = node->getInstanceNodes(); - size_t geom_done = 0; - size_t camera_done = 0; - size_t lamp_done = 0; - size_t controller_done = 0; - size_t inst_done = 0; - - // XXX linking object with the first <instance_geometry>, though a node may have more of them... - // maybe join multiple <instance_...> meshes into 1, and link object with it? not sure... - // <instance_geometry> - while (geom_done < geom.getCount()) { - ob = mesh_importer.create_mesh_object(node, geom[geom_done], false, uid_material_map); - if (ob == NULL) { - report_unknown_reference(*node, "instance_mesh"); - } - else { - objects_done->push_back(ob); - if (parent_node == NULL) { - root_objects->push_back(ob); - } - } - ++geom_done; - } - while (camera_done < camera.getCount()) { - ob = create_camera_object(camera[camera_done], sce); - if (ob == NULL) { - report_unknown_reference(*node, "instance_camera"); - } - else { - objects_done->push_back(ob); - if (parent_node == NULL) { - root_objects->push_back(ob); - } - } - ++camera_done; - } - while (lamp_done < lamp.getCount()) { - ob = create_light_object(lamp[lamp_done], sce); - if (ob == NULL) { - report_unknown_reference(*node, "instance_light"); - } - else { - objects_done->push_back(ob); - if (parent_node == NULL) { - root_objects->push_back(ob); - } - } - ++lamp_done; - } - while (controller_done < controller.getCount()) { - COLLADAFW::InstanceGeometry *geometry = (COLLADAFW::InstanceGeometry *)controller[controller_done]; - ob = mesh_importer.create_mesh_object(node, geometry, true, uid_material_map); - if (ob == NULL) { - report_unknown_reference(*node, "instance_controller"); - } - else { - objects_done->push_back(ob); - if (parent_node == NULL) { - root_objects->push_back(ob); - } - } - ++controller_done; - } - // XXX instance_node is not supported yet - while (inst_done < inst_node.getCount()) { - const COLLADAFW::UniqueId& node_id = inst_node[inst_done]->getInstanciatedObjectId(); - if (object_map.find(node_id) == object_map.end()) { - fprintf(stderr, "Cannot find object for node referenced by <instance_node name=\"%s\">.\n", inst_node[inst_done]->getName().c_str()); - ob = NULL; - } - else { - std::pair<std::multimap<COLLADAFW::UniqueId, Object *>::iterator, std::multimap<COLLADAFW::UniqueId, Object *>::iterator> pair_iter = object_map.equal_range(node_id); - for (std::multimap<COLLADAFW::UniqueId, Object *>::iterator it2 = pair_iter.first; it2 != pair_iter.second; it2++) { - Object *source_ob = (Object *)it2->second; - COLLADAFW::Node *source_node = node_map[node_id]; - ob = create_instance_node(source_ob, source_node, node, sce, is_library_node); - objects_done->push_back(ob); - if (parent_node == NULL) { - root_objects->push_back(ob); - } - } - } - ++inst_done; - - read_transform = false; - } - - // if node is empty - create empty object - // XXX empty node may not mean it is empty object, not sure about this - if ( (geom_done + camera_done + lamp_done + controller_done + inst_done) < 1) { - //Check if Object is armature, by checking if immediate child is a JOINT node. - if (is_armature(node)) { - ob = bc_add_object(bmain, sce, view_layer, OB_ARMATURE, name.c_str()); - } - else { - ob = bc_add_object(bmain, sce, view_layer, OB_EMPTY, NULL); - } - objects_done->push_back(ob); - if (parent_node == NULL) { - root_objects->push_back(ob); - } - } - - // XXX: if there're multiple instances, only one is stored - - if (!ob) { - goto finally; - } - - 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(); - BKE_libblock_rename(bmain, &ob->id, (char *)nodename.c_str()); - object_map.insert(std::pair<COLLADAFW::UniqueId, Object *>(node->getUniqueId(), ob)); - node_map[node->getUniqueId()] = node; - - if (is_library_node) - libnode_ob.push_back(ob); - } - - - //create_constraints(et,ob); - - } - - for (std::vector<Object *>::iterator it = objects_done->begin(); it != objects_done->end(); ++it) { - ob = *it; - - if (read_transform) - anim_importer.read_node_transform(node, ob); // overwrites location set earlier - - if (!is_joint) { - if (par && ob) { - ob->parent = par; - ob->partype = PAROBJECT; - ob->parsubstr[0] = 0; - - //bc_set_parent(ob, par, mContext, false); - } - } - } - - if (objects_done->size() > 0) { - ob = *objects_done->begin(); - } - else { - ob = NULL; - } - - for (unsigned int i = 0; i < child_nodes.getCount(); i++) { - std::vector<Object *> *child_objects; - child_objects = write_node(child_nodes[i], node, sce, ob, is_library_node); - delete child_objects; - } - + Main *bmain = CTX_data_main(mContext); + Object *ob = NULL; + bool is_joint = node->getType() == COLLADAFW::Node::JOINT; + bool read_transform = true; + std::string id = node->getOriginalId(); + std::string name = node->getName(); + + // if node has child nodes write them + COLLADAFW::NodePointerArray &child_nodes = node->getChildNodes(); + + std::vector<Object *> *objects_done = new std::vector<Object *>(); + std::vector<Object *> *root_objects = new std::vector<Object *>(); + + fprintf( + stderr, "| %s id='%s', name='%s'\n", is_joint ? "JOINT" : "NODE ", id.c_str(), name.c_str()); + + if (is_joint) { + if (parent_node == NULL && !is_library_node) { + // A Joint on root level is a skeleton without root node. + // Here we add the armature "on the fly": + par = bc_add_object(bmain, sce, view_layer, OB_ARMATURE, std::string("Armature").c_str()); + objects_done->push_back(par); + root_objects->push_back(par); + object_map.insert(std::pair<COLLADAFW::UniqueId, Object *>(node->getUniqueId(), par)); + node_map[node->getUniqueId()] = node; + } + if (parent_node == NULL || parent_node->getType() != COLLADAFW::Node::JOINT) { + armature_importer.add_root_joint(node, par); + } + + if (parent_node == NULL) { + // for skeletons without root node all has been done above. + // Skeletons with root node are handled further down. + goto finally; + } + } + else { + COLLADAFW::InstanceGeometryPointerArray &geom = node->getInstanceGeometries(); + COLLADAFW::InstanceCameraPointerArray &camera = node->getInstanceCameras(); + COLLADAFW::InstanceLightPointerArray &lamp = node->getInstanceLights(); + COLLADAFW::InstanceControllerPointerArray &controller = node->getInstanceControllers(); + COLLADAFW::InstanceNodePointerArray &inst_node = node->getInstanceNodes(); + size_t geom_done = 0; + size_t camera_done = 0; + size_t lamp_done = 0; + size_t controller_done = 0; + size_t inst_done = 0; + + // XXX linking object with the first <instance_geometry>, though a node may have more of them... + // maybe join multiple <instance_...> meshes into 1, and link object with it? not sure... + // <instance_geometry> + while (geom_done < geom.getCount()) { + ob = mesh_importer.create_mesh_object(node, geom[geom_done], false, uid_material_map); + if (ob == NULL) { + report_unknown_reference(*node, "instance_mesh"); + } + else { + objects_done->push_back(ob); + if (parent_node == NULL) { + root_objects->push_back(ob); + } + } + ++geom_done; + } + while (camera_done < camera.getCount()) { + ob = create_camera_object(camera[camera_done], sce); + if (ob == NULL) { + report_unknown_reference(*node, "instance_camera"); + } + else { + objects_done->push_back(ob); + if (parent_node == NULL) { + root_objects->push_back(ob); + } + } + ++camera_done; + } + while (lamp_done < lamp.getCount()) { + ob = create_light_object(lamp[lamp_done], sce); + if (ob == NULL) { + report_unknown_reference(*node, "instance_light"); + } + else { + objects_done->push_back(ob); + if (parent_node == NULL) { + root_objects->push_back(ob); + } + } + ++lamp_done; + } + while (controller_done < controller.getCount()) { + COLLADAFW::InstanceGeometry *geometry = (COLLADAFW::InstanceGeometry *) + controller[controller_done]; + ob = mesh_importer.create_mesh_object(node, geometry, true, uid_material_map); + if (ob == NULL) { + report_unknown_reference(*node, "instance_controller"); + } + else { + objects_done->push_back(ob); + if (parent_node == NULL) { + root_objects->push_back(ob); + } + } + ++controller_done; + } + // XXX instance_node is not supported yet + while (inst_done < inst_node.getCount()) { + const COLLADAFW::UniqueId &node_id = inst_node[inst_done]->getInstanciatedObjectId(); + if (object_map.find(node_id) == object_map.end()) { + fprintf(stderr, + "Cannot find object for node referenced by <instance_node name=\"%s\">.\n", + inst_node[inst_done]->getName().c_str()); + ob = NULL; + } + else { + std::pair<std::multimap<COLLADAFW::UniqueId, Object *>::iterator, + std::multimap<COLLADAFW::UniqueId, Object *>::iterator> + pair_iter = object_map.equal_range(node_id); + for (std::multimap<COLLADAFW::UniqueId, Object *>::iterator it2 = pair_iter.first; + it2 != pair_iter.second; + it2++) { + Object *source_ob = (Object *)it2->second; + COLLADAFW::Node *source_node = node_map[node_id]; + ob = create_instance_node(source_ob, source_node, node, sce, is_library_node); + objects_done->push_back(ob); + if (parent_node == NULL) { + root_objects->push_back(ob); + } + } + } + ++inst_done; + + read_transform = false; + } + + // if node is empty - create empty object + // XXX empty node may not mean it is empty object, not sure about this + if ((geom_done + camera_done + lamp_done + controller_done + inst_done) < 1) { + //Check if Object is armature, by checking if immediate child is a JOINT node. + if (is_armature(node)) { + ob = bc_add_object(bmain, sce, view_layer, OB_ARMATURE, name.c_str()); + } + else { + ob = bc_add_object(bmain, sce, view_layer, OB_EMPTY, NULL); + } + objects_done->push_back(ob); + if (parent_node == NULL) { + root_objects->push_back(ob); + } + } + + // XXX: if there're multiple instances, only one is stored + + if (!ob) { + goto finally; + } + + 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(); + BKE_libblock_rename(bmain, &ob->id, (char *)nodename.c_str()); + object_map.insert(std::pair<COLLADAFW::UniqueId, Object *>(node->getUniqueId(), ob)); + node_map[node->getUniqueId()] = node; + + if (is_library_node) + libnode_ob.push_back(ob); + } + + //create_constraints(et,ob); + } + + for (std::vector<Object *>::iterator it = objects_done->begin(); it != objects_done->end(); + ++it) { + ob = *it; + + if (read_transform) + anim_importer.read_node_transform(node, ob); // overwrites location set earlier + + if (!is_joint) { + if (par && ob) { + ob->parent = par; + ob->partype = PAROBJECT; + ob->parsubstr[0] = 0; + + //bc_set_parent(ob, par, mContext, false); + } + } + } + + if (objects_done->size() > 0) { + ob = *objects_done->begin(); + } + else { + ob = NULL; + } + + for (unsigned int i = 0; i < child_nodes.getCount(); i++) { + std::vector<Object *> *child_objects; + child_objects = write_node(child_nodes[i], node, sce, ob, is_library_node); + delete child_objects; + } finally: - delete objects_done; + delete objects_done; - return root_objects; + return root_objects; } /** @@ -694,22 +712,22 @@ finally: */ bool DocumentImporter::writeVisualScene(const COLLADAFW::VisualScene *visualScene) { - if (mImportStage == Fetching_Controller_data) - return true; + if (mImportStage == Fetching_Controller_data) + return true; - // this method called on post process after writeGeometry, writeMaterial, etc. + // this method called on post process after writeGeometry, writeMaterial, etc. - // for each <node> in <visual_scene>: - // create an Object - // if Mesh (previously created in writeGeometry) to which <node> corresponds exists, link Object with that mesh + // for each <node> in <visual_scene>: + // create an Object + // if Mesh (previously created in writeGeometry) to which <node> corresponds exists, link Object with that mesh - // update: since we cannot link a Mesh with Object in - // writeGeometry because <geometry> does not reference <node>, - // we link Objects with Meshes here + // update: since we cannot link a Mesh with Object in + // writeGeometry because <geometry> does not reference <node>, + // we link Objects with Meshes here - vscenes.push_back(visualScene); + vscenes.push_back(visualScene); - return true; + return true; } /** When this method is called, the writer must handle all nodes contained in the @@ -717,61 +735,60 @@ bool DocumentImporter::writeVisualScene(const COLLADAFW::VisualScene *visualScen * \return The writer should return true, if writing succeeded, false otherwise.*/ bool DocumentImporter::writeLibraryNodes(const COLLADAFW::LibraryNodes *libraryNodes) { - if (mImportStage == Fetching_Controller_data) - return true; + if (mImportStage == Fetching_Controller_data) + return true; - Scene *sce = CTX_data_scene(mContext); + Scene *sce = CTX_data_scene(mContext); - const COLLADAFW::NodePointerArray& nodes = libraryNodes->getNodes(); + const COLLADAFW::NodePointerArray &nodes = libraryNodes->getNodes(); - fprintf(stderr, "+-- Read Library nodes ----------\n"); - for (unsigned int i = 0; i < nodes.getCount(); i++) { - std::vector<Object *> *child_objects; - child_objects = write_node(nodes[i], NULL, sce, NULL, true); - delete child_objects; - } - return true; + fprintf(stderr, "+-- Read Library nodes ----------\n"); + for (unsigned int i = 0; i < nodes.getCount(); i++) { + std::vector<Object *> *child_objects; + child_objects = write_node(nodes[i], NULL, sce, NULL, true); + delete child_objects; + } + return true; } /** When this method is called, the writer must write the geometry. * \return The writer should return true, if writing succeeded, false otherwise.*/ bool DocumentImporter::writeGeometry(const COLLADAFW::Geometry *geom) { - if (mImportStage == Fetching_Controller_data) - return true; + if (mImportStage == Fetching_Controller_data) + return true; - return mesh_importer.write_geometry(geom); + return mesh_importer.write_geometry(geom); } /** When this method is called, the writer must write the material. * \return The writer should return true, if writing succeeded, false otherwise.*/ bool DocumentImporter::writeMaterial(const COLLADAFW::Material *cmat) { - if (mImportStage == Fetching_Controller_data) - return true; + if (mImportStage == Fetching_Controller_data) + return true; - Main *bmain = CTX_data_main(mContext); - const std::string& str_mat_id = cmat->getName().size() ? cmat->getName() : cmat->getOriginalId(); - Material *ma = BKE_material_add(bmain, (char *)str_mat_id.c_str()); + Main *bmain = CTX_data_main(mContext); + const std::string &str_mat_id = cmat->getName().size() ? cmat->getName() : cmat->getOriginalId(); + Material *ma = BKE_material_add(bmain, (char *)str_mat_id.c_str()); - this->uid_effect_map[cmat->getInstantiatedEffect()] = ma; - this->uid_material_map[cmat->getUniqueId()] = ma; + this->uid_effect_map[cmat->getInstantiatedEffect()] = ma; + this->uid_material_map[cmat->getUniqueId()] = ma; - return true; + return true; } - void DocumentImporter::write_profile_COMMON(COLLADAFW::EffectCommon *ef, Material *ma) { - MaterialNode matNode = MaterialNode(mContext, ef, ma, uid_image_map); - matNode.set_reflectivity(ef->getReflectivity().getFloatValue()); - matNode.set_ior(ef->getIndexOfRefraction().getFloatValue()); - matNode.set_diffuse(ef->getDiffuse(), "Diffuse"); - matNode.set_ambient(ef->getAmbient(), "Ambient"); - matNode.set_specular(ef->getSpecular(), "Specular"); - matNode.set_reflective(ef->getReflective(), "Reflective"); - matNode.set_emission(ef->getEmission(), "Emission"); - matNode.set_opacity(ef->getOpacity(), "Opacity"); + MaterialNode matNode = MaterialNode(mContext, ef, ma, uid_image_map); + matNode.set_reflectivity(ef->getReflectivity().getFloatValue()); + matNode.set_ior(ef->getIndexOfRefraction().getFloatValue()); + matNode.set_diffuse(ef->getDiffuse(), "Diffuse"); + matNode.set_ambient(ef->getAmbient(), "Ambient"); + matNode.set_specular(ef->getSpecular(), "Specular"); + matNode.set_reflective(ef->getReflective(), "Reflective"); + matNode.set_emission(ef->getEmission(), "Emission"); + matNode.set_opacity(ef->getOpacity(), "Opacity"); } /** When this method is called, the writer must write the effect. @@ -779,367 +796,340 @@ void DocumentImporter::write_profile_COMMON(COLLADAFW::EffectCommon *ef, Materia bool DocumentImporter::writeEffect(const COLLADAFW::Effect *effect) { - if (mImportStage == Fetching_Controller_data) - return true; - - const COLLADAFW::UniqueId& uid = effect->getUniqueId(); - - if (uid_effect_map.find(uid) == uid_effect_map.end()) { - fprintf(stderr, "Couldn't find a material by UID.\n"); - return true; - } - - Material *ma = uid_effect_map[uid]; - std::map<COLLADAFW::UniqueId, Material *>::iterator iter; - for (iter = uid_material_map.begin(); iter != uid_material_map.end(); iter++) { - if (iter->second == ma) { - this->FW_object_map[iter->first] = effect; - break; - } - } - COLLADAFW::CommonEffectPointerArray common_efs = effect->getCommonEffects(); - if (common_efs.getCount() < 1) { - fprintf(stderr, "Couldn't find <profile_COMMON>.\n"); - return true; - } - // XXX TODO: Take all <profile_common>s - // Currently only first <profile_common> is supported - COLLADAFW::EffectCommon *ef = common_efs[0]; - write_profile_COMMON(ef, ma); - this->FW_object_map[effect->getUniqueId()] = effect; - - return true; + if (mImportStage == Fetching_Controller_data) + return true; + + const COLLADAFW::UniqueId &uid = effect->getUniqueId(); + + if (uid_effect_map.find(uid) == uid_effect_map.end()) { + fprintf(stderr, "Couldn't find a material by UID.\n"); + return true; + } + + Material *ma = uid_effect_map[uid]; + std::map<COLLADAFW::UniqueId, Material *>::iterator iter; + for (iter = uid_material_map.begin(); iter != uid_material_map.end(); iter++) { + if (iter->second == ma) { + this->FW_object_map[iter->first] = effect; + break; + } + } + COLLADAFW::CommonEffectPointerArray common_efs = effect->getCommonEffects(); + if (common_efs.getCount() < 1) { + fprintf(stderr, "Couldn't find <profile_COMMON>.\n"); + return true; + } + // XXX TODO: Take all <profile_common>s + // Currently only first <profile_common> is supported + COLLADAFW::EffectCommon *ef = common_efs[0]; + write_profile_COMMON(ef, ma); + this->FW_object_map[effect->getUniqueId()] = effect; + + return true; } - /** When this method is called, the writer must write the camera. * \return The writer should return true, if writing succeeded, false otherwise.*/ bool DocumentImporter::writeCamera(const COLLADAFW::Camera *camera) { - if (mImportStage == Fetching_Controller_data) - return true; - - Main *bmain = CTX_data_main(mContext); - Camera *cam = NULL; - std::string cam_id, cam_name; - - ExtraTags *et=getExtraTags(camera->getUniqueId()); - cam_id = camera->getOriginalId(); - cam_name = camera->getName(); - if (cam_name.size()) cam = (Camera *)BKE_camera_add(bmain, (char *)cam_name.c_str()); - else cam = (Camera *)BKE_camera_add(bmain, (char *)cam_id.c_str()); - - if (!cam) { - fprintf(stderr, "Cannot create camera.\n"); - return true; - } - - if (et && et->isProfile("blender")) { - et->setData("shiftx",&(cam->shiftx)); - et->setData("shifty",&(cam->shifty)); - et->setData("dof_distance",&(cam->dof_distance)); - } - cam->clip_start = camera->getNearClippingPlane().getValue(); - cam->clip_end = camera->getFarClippingPlane().getValue(); - - COLLADAFW::Camera::CameraType type = camera->getCameraType(); - switch (type) { - case COLLADAFW::Camera::ORTHOGRAPHIC: - { - cam->type = CAM_ORTHO; - } - break; - case COLLADAFW::Camera::PERSPECTIVE: - { - cam->type = CAM_PERSP; - } - break; - case COLLADAFW::Camera::UNDEFINED_CAMERATYPE: - { - fprintf(stderr, "Current camera type is not supported.\n"); - cam->type = CAM_PERSP; - } - break; - } - - switch (camera->getDescriptionType()) { - case COLLADAFW::Camera::ASPECTRATIO_AND_Y: - { - switch (cam->type) { - case CAM_ORTHO: - { - double ymag = 2 * camera->getYMag().getValue(); - double aspect = camera->getAspectRatio().getValue(); - double xmag = aspect * ymag; - cam->ortho_scale = (float)xmag; - } - break; - case CAM_PERSP: - default: - { - double yfov = camera->getYFov().getValue(); - double aspect = camera->getAspectRatio().getValue(); - - // NOTE: Needs more testing (As we curretnly have no official test data for this) - - double xfov = 2.0f * atanf(aspect * tanf(DEG2RADF(yfov) * 0.5f)); - cam->lens = fov_to_focallength(xfov, cam->sensor_x); - } - break; - } - } - break; - /* XXX correct way to do following four is probably to get also render - * size and determine proper settings from that somehow */ - case COLLADAFW::Camera::ASPECTRATIO_AND_X: - case COLLADAFW::Camera::SINGLE_X: - case COLLADAFW::Camera::X_AND_Y: - { - switch (cam->type) { - case CAM_ORTHO: - cam->ortho_scale = (float)camera->getXMag().getValue() * 2; - break; - case CAM_PERSP: - default: - { - double x = camera->getXFov().getValue(); - // x is in degrees, cam->lens is in millimiters - cam->lens = fov_to_focallength(DEG2RADF(x), cam->sensor_x); - } - break; - } - } - break; - case COLLADAFW::Camera::SINGLE_Y: - { - switch (cam->type) { - case CAM_ORTHO: - cam->ortho_scale = (float)camera->getYMag().getValue(); - break; - case CAM_PERSP: - default: - { - double yfov = camera->getYFov().getValue(); - // yfov is in degrees, cam->lens is in millimiters - cam->lens = fov_to_focallength(DEG2RADF(yfov), cam->sensor_x); - } - break; - } - } - break; - case COLLADAFW::Camera::UNDEFINED: - // read nothing, use blender defaults. - break; - } - - this->uid_camera_map[camera->getUniqueId()] = cam; - this->FW_object_map[camera->getUniqueId()] = camera; - // XXX import camera options - return true; + if (mImportStage == Fetching_Controller_data) + return true; + + Main *bmain = CTX_data_main(mContext); + Camera *cam = NULL; + std::string cam_id, cam_name; + + ExtraTags *et = getExtraTags(camera->getUniqueId()); + cam_id = camera->getOriginalId(); + cam_name = camera->getName(); + if (cam_name.size()) + cam = (Camera *)BKE_camera_add(bmain, (char *)cam_name.c_str()); + else + cam = (Camera *)BKE_camera_add(bmain, (char *)cam_id.c_str()); + + if (!cam) { + fprintf(stderr, "Cannot create camera.\n"); + return true; + } + + if (et && et->isProfile("blender")) { + et->setData("shiftx", &(cam->shiftx)); + et->setData("shifty", &(cam->shifty)); + et->setData("dof_distance", &(cam->dof_distance)); + } + cam->clip_start = camera->getNearClippingPlane().getValue(); + cam->clip_end = camera->getFarClippingPlane().getValue(); + + COLLADAFW::Camera::CameraType type = camera->getCameraType(); + switch (type) { + case COLLADAFW::Camera::ORTHOGRAPHIC: { + cam->type = CAM_ORTHO; + } break; + case COLLADAFW::Camera::PERSPECTIVE: { + cam->type = CAM_PERSP; + } break; + case COLLADAFW::Camera::UNDEFINED_CAMERATYPE: { + fprintf(stderr, "Current camera type is not supported.\n"); + cam->type = CAM_PERSP; + } break; + } + + switch (camera->getDescriptionType()) { + case COLLADAFW::Camera::ASPECTRATIO_AND_Y: { + switch (cam->type) { + case CAM_ORTHO: { + double ymag = 2 * camera->getYMag().getValue(); + double aspect = camera->getAspectRatio().getValue(); + double xmag = aspect * ymag; + cam->ortho_scale = (float)xmag; + } break; + case CAM_PERSP: + default: { + double yfov = camera->getYFov().getValue(); + double aspect = camera->getAspectRatio().getValue(); + + // NOTE: Needs more testing (As we curretnly have no official test data for this) + + double xfov = 2.0f * atanf(aspect * tanf(DEG2RADF(yfov) * 0.5f)); + cam->lens = fov_to_focallength(xfov, cam->sensor_x); + } break; + } + } break; + /* XXX correct way to do following four is probably to get also render + * size and determine proper settings from that somehow */ + case COLLADAFW::Camera::ASPECTRATIO_AND_X: + case COLLADAFW::Camera::SINGLE_X: + case COLLADAFW::Camera::X_AND_Y: { + switch (cam->type) { + case CAM_ORTHO: + cam->ortho_scale = (float)camera->getXMag().getValue() * 2; + break; + case CAM_PERSP: + default: { + double x = camera->getXFov().getValue(); + // x is in degrees, cam->lens is in millimiters + cam->lens = fov_to_focallength(DEG2RADF(x), cam->sensor_x); + } break; + } + } break; + case COLLADAFW::Camera::SINGLE_Y: { + switch (cam->type) { + case CAM_ORTHO: + cam->ortho_scale = (float)camera->getYMag().getValue(); + break; + case CAM_PERSP: + default: { + double yfov = camera->getYFov().getValue(); + // yfov is in degrees, cam->lens is in millimiters + cam->lens = fov_to_focallength(DEG2RADF(yfov), cam->sensor_x); + } break; + } + } break; + case COLLADAFW::Camera::UNDEFINED: + // read nothing, use blender defaults. + break; + } + + this->uid_camera_map[camera->getUniqueId()] = cam; + this->FW_object_map[camera->getUniqueId()] = camera; + // XXX import camera options + return true; } /** When this method is called, the writer must write the image. * \return The writer should return true, if writing succeeded, false otherwise.*/ bool DocumentImporter::writeImage(const COLLADAFW::Image *image) { - if (mImportStage == Fetching_Controller_data) - return true; - - const std::string& imagepath = image->getImageURI().toNativePath(); - - char dir[FILE_MAX]; - char absolute_path[FILE_MAX]; - const char *workpath; - - BLI_split_dir_part(this->import_settings->filepath, dir, sizeof(dir)); - BLI_join_dirfile(absolute_path, sizeof(absolute_path), dir, imagepath.c_str()); - if (BLI_exists(absolute_path)) { - workpath = absolute_path; - } - else { - // Maybe imagepath was already absolute ? - if (!BLI_exists(imagepath.c_str())) { - fprintf(stderr, "|! Image not found: %s\n", imagepath.c_str() ); - return true; - } - workpath = imagepath.c_str(); - } - - Image *ima = BKE_image_load_exists(CTX_data_main(mContext), workpath); - if (!ima) { - fprintf(stderr, "|! Cannot create image: %s\n", workpath); - return true; - } - this->uid_image_map[image->getUniqueId()] = ima; - fprintf(stderr, "| import Image: %s\n", workpath); - return true; + if (mImportStage == Fetching_Controller_data) + return true; + + const std::string &imagepath = image->getImageURI().toNativePath(); + + char dir[FILE_MAX]; + char absolute_path[FILE_MAX]; + const char *workpath; + + BLI_split_dir_part(this->import_settings->filepath, dir, sizeof(dir)); + BLI_join_dirfile(absolute_path, sizeof(absolute_path), dir, imagepath.c_str()); + if (BLI_exists(absolute_path)) { + workpath = absolute_path; + } + else { + // Maybe imagepath was already absolute ? + if (!BLI_exists(imagepath.c_str())) { + fprintf(stderr, "|! Image not found: %s\n", imagepath.c_str()); + return true; + } + workpath = imagepath.c_str(); + } + + Image *ima = BKE_image_load_exists(CTX_data_main(mContext), workpath); + if (!ima) { + fprintf(stderr, "|! Cannot create image: %s\n", workpath); + return true; + } + this->uid_image_map[image->getUniqueId()] = ima; + fprintf(stderr, "| import Image: %s\n", workpath); + return true; } /** When this method is called, the writer must write the light. * \return The writer should return true, if writing succeeded, false otherwise.*/ bool DocumentImporter::writeLight(const COLLADAFW::Light *light) { - if (mImportStage == Fetching_Controller_data) - return true; - - Main *bmain = CTX_data_main(mContext); - Light *lamp = NULL; - std::string la_id, la_name; - - ExtraTags *et = getExtraTags(light->getUniqueId()); - /*TagsMap::iterator etit; - ExtraTags *et = 0; - etit = uid_tags_map.find(light->getUniqueId().toAscii()); - if (etit != uid_tags_map.end()) - et = etit->second;*/ - - la_id = light->getOriginalId(); - la_name = light->getName(); - if (la_name.size()) lamp = (Light *)BKE_light_add(bmain, (char *)la_name.c_str()); - else lamp = (Light *)BKE_light_add(bmain, (char *)la_id.c_str()); - - if (!lamp) { - fprintf(stderr, "Cannot create light.\n"); - return true; - } - - // if we find an ExtraTags for this, use that instead. - if (et && et->isProfile("blender")) { - et->setData("type", &(lamp->type)); - et->setData("flag", &(lamp->flag)); - et->setData("mode", &(lamp->mode)); - et->setData("gamma", &(lamp->k)); - et->setData("red", &(lamp->r)); - et->setData("green", &(lamp->g)); - et->setData("blue", &(lamp->b)); - et->setData("shadow_r", &(lamp->shdwr)); - et->setData("shadow_g", &(lamp->shdwg)); - et->setData("shadow_b", &(lamp->shdwb)); - et->setData("energy", &(lamp->energy)); - et->setData("dist", &(lamp->dist)); - et->setData("spotsize", &(lamp->spotsize)); - lamp->spotsize = DEG2RADF(lamp->spotsize); - et->setData("spotblend", &(lamp->spotblend)); - et->setData("att1", &(lamp->att1)); - et->setData("att2", &(lamp->att2)); - et->setData("falloff_type", &(lamp->falloff_type)); - et->setData("clipsta", &(lamp->clipsta)); - et->setData("clipend", &(lamp->clipend)); - et->setData("bias", &(lamp->bias)); - et->setData("soft", &(lamp->soft)); - et->setData("bufsize", &(lamp->bufsize)); - et->setData("buffers", &(lamp->buffers)); - et->setData("area_shape", &(lamp->area_shape)); - et->setData("area_size", &(lamp->area_size)); - et->setData("area_sizey", &(lamp->area_sizey)); - et->setData("area_sizez", &(lamp->area_sizez)); - } - else { - float constatt = light->getConstantAttenuation().getValue(); - float linatt = light->getLinearAttenuation().getValue(); - float quadatt = light->getQuadraticAttenuation().getValue(); - float d = 25.0f; - float att1 = 0.0f; - float att2 = 0.0f; - float e = 1.0f; - - if (light->getColor().isValid()) { - COLLADAFW::Color col = light->getColor(); - lamp->r = col.getRed(); - lamp->g = col.getGreen(); - lamp->b = col.getBlue(); - } - - if (IS_EQ(linatt, 0.0f) && quadatt > 0.0f) { - att2 = quadatt; - d = sqrt(1.0f / quadatt); - } - // linear light - else if (IS_EQ(quadatt, 0.0f) && linatt > 0.0f) { - att1 = linatt; - d = (1.0f / linatt); - } - else if (IS_EQ(constatt, 1.0f)) { - att1 = 1.0f; - } - else { - // assuming point light (const att = 1.0); - att1 = 1.0f; - } - - d *= (1.0f / unit_converter.getLinearMeter()); - - lamp->energy = e; - lamp->dist = d; - - switch (light->getLightType()) { - case COLLADAFW::Light::AMBIENT_LIGHT: - { - lamp->type = LA_SUN; //TODO needs more thoughts - } - break; - case COLLADAFW::Light::SPOT_LIGHT: - { - lamp->type = LA_SPOT; - lamp->att1 = att1; - lamp->att2 = att2; - if (IS_EQ(att1, 0.0f) && att2 > 0) - lamp->falloff_type = LA_FALLOFF_INVSQUARE; - if (IS_EQ(att2, 0.0f) && att1 > 0) - lamp->falloff_type = LA_FALLOFF_INVLINEAR; - lamp->spotsize = DEG2RADF(light->getFallOffAngle().getValue()); - lamp->spotblend = light->getFallOffExponent().getValue(); - } - break; - case COLLADAFW::Light::DIRECTIONAL_LIGHT: - { - /* our sun is very strong, so pick a smaller energy level */ - lamp->type = LA_SUN; - } - break; - case COLLADAFW::Light::POINT_LIGHT: - { - lamp->type = LA_LOCAL; - lamp->att1 = att1; - lamp->att2 = att2; - if (IS_EQ(att1, 0.0f) && att2 > 0) - lamp->falloff_type = LA_FALLOFF_INVSQUARE; - if (IS_EQ(att2, 0.0f) && att1 > 0) - lamp->falloff_type = LA_FALLOFF_INVLINEAR; - } - break; - case COLLADAFW::Light::UNDEFINED: - { - fprintf(stderr, "Current light type is not supported.\n"); - lamp->type = LA_LOCAL; - } - break; - } - } - - this->uid_light_map[light->getUniqueId()] = lamp; - this->FW_object_map[light->getUniqueId()] = light; - return true; + if (mImportStage == Fetching_Controller_data) + return true; + + Main *bmain = CTX_data_main(mContext); + Light *lamp = NULL; + std::string la_id, la_name; + + ExtraTags *et = getExtraTags(light->getUniqueId()); + /*TagsMap::iterator etit; + ExtraTags *et = 0; + etit = uid_tags_map.find(light->getUniqueId().toAscii()); + if (etit != uid_tags_map.end()) + et = etit->second;*/ + + la_id = light->getOriginalId(); + la_name = light->getName(); + if (la_name.size()) + lamp = (Light *)BKE_light_add(bmain, (char *)la_name.c_str()); + else + lamp = (Light *)BKE_light_add(bmain, (char *)la_id.c_str()); + + if (!lamp) { + fprintf(stderr, "Cannot create light.\n"); + return true; + } + + // if we find an ExtraTags for this, use that instead. + if (et && et->isProfile("blender")) { + et->setData("type", &(lamp->type)); + et->setData("flag", &(lamp->flag)); + et->setData("mode", &(lamp->mode)); + et->setData("gamma", &(lamp->k)); + et->setData("red", &(lamp->r)); + et->setData("green", &(lamp->g)); + et->setData("blue", &(lamp->b)); + et->setData("shadow_r", &(lamp->shdwr)); + et->setData("shadow_g", &(lamp->shdwg)); + et->setData("shadow_b", &(lamp->shdwb)); + et->setData("energy", &(lamp->energy)); + et->setData("dist", &(lamp->dist)); + et->setData("spotsize", &(lamp->spotsize)); + lamp->spotsize = DEG2RADF(lamp->spotsize); + et->setData("spotblend", &(lamp->spotblend)); + et->setData("att1", &(lamp->att1)); + et->setData("att2", &(lamp->att2)); + et->setData("falloff_type", &(lamp->falloff_type)); + et->setData("clipsta", &(lamp->clipsta)); + et->setData("clipend", &(lamp->clipend)); + et->setData("bias", &(lamp->bias)); + et->setData("soft", &(lamp->soft)); + et->setData("bufsize", &(lamp->bufsize)); + et->setData("buffers", &(lamp->buffers)); + et->setData("area_shape", &(lamp->area_shape)); + et->setData("area_size", &(lamp->area_size)); + et->setData("area_sizey", &(lamp->area_sizey)); + et->setData("area_sizez", &(lamp->area_sizez)); + } + else { + float constatt = light->getConstantAttenuation().getValue(); + float linatt = light->getLinearAttenuation().getValue(); + float quadatt = light->getQuadraticAttenuation().getValue(); + float d = 25.0f; + float att1 = 0.0f; + float att2 = 0.0f; + float e = 1.0f; + + if (light->getColor().isValid()) { + COLLADAFW::Color col = light->getColor(); + lamp->r = col.getRed(); + lamp->g = col.getGreen(); + lamp->b = col.getBlue(); + } + + if (IS_EQ(linatt, 0.0f) && quadatt > 0.0f) { + att2 = quadatt; + d = sqrt(1.0f / quadatt); + } + // linear light + else if (IS_EQ(quadatt, 0.0f) && linatt > 0.0f) { + att1 = linatt; + d = (1.0f / linatt); + } + else if (IS_EQ(constatt, 1.0f)) { + att1 = 1.0f; + } + else { + // assuming point light (const att = 1.0); + att1 = 1.0f; + } + + d *= (1.0f / unit_converter.getLinearMeter()); + + lamp->energy = e; + lamp->dist = d; + + switch (light->getLightType()) { + case COLLADAFW::Light::AMBIENT_LIGHT: { + lamp->type = LA_SUN; //TODO needs more thoughts + } break; + case COLLADAFW::Light::SPOT_LIGHT: { + lamp->type = LA_SPOT; + lamp->att1 = att1; + lamp->att2 = att2; + if (IS_EQ(att1, 0.0f) && att2 > 0) + lamp->falloff_type = LA_FALLOFF_INVSQUARE; + if (IS_EQ(att2, 0.0f) && att1 > 0) + lamp->falloff_type = LA_FALLOFF_INVLINEAR; + lamp->spotsize = DEG2RADF(light->getFallOffAngle().getValue()); + lamp->spotblend = light->getFallOffExponent().getValue(); + } break; + case COLLADAFW::Light::DIRECTIONAL_LIGHT: { + /* our sun is very strong, so pick a smaller energy level */ + lamp->type = LA_SUN; + } break; + case COLLADAFW::Light::POINT_LIGHT: { + lamp->type = LA_LOCAL; + lamp->att1 = att1; + lamp->att2 = att2; + if (IS_EQ(att1, 0.0f) && att2 > 0) + lamp->falloff_type = LA_FALLOFF_INVSQUARE; + if (IS_EQ(att2, 0.0f) && att1 > 0) + lamp->falloff_type = LA_FALLOFF_INVLINEAR; + } break; + case COLLADAFW::Light::UNDEFINED: { + fprintf(stderr, "Current light type is not supported.\n"); + lamp->type = LA_LOCAL; + } break; + } + } + + this->uid_light_map[light->getUniqueId()] = lamp; + this->FW_object_map[light->getUniqueId()] = light; + return true; } // this function is called only for animations that pass COLLADAFW::validate bool DocumentImporter::writeAnimation(const COLLADAFW::Animation *anim) { - if (mImportStage == Fetching_Controller_data) - return true; + if (mImportStage == Fetching_Controller_data) + return true; - // return true; - return anim_importer.write_animation(anim); + // return true; + return anim_importer.write_animation(anim); } // called on post-process stage after writeVisualScenes bool DocumentImporter::writeAnimationList(const COLLADAFW::AnimationList *animationList) { - if (mImportStage == Fetching_Controller_data) - return true; + if (mImportStage == Fetching_Controller_data) + return true; - // return true; - return anim_importer.write_animation_list(animationList); + // return true; + return anim_importer.write_animation_list(animationList); } #if WITH_OPENCOLLADA_ANIMATION_CLIP @@ -1147,11 +1137,11 @@ bool DocumentImporter::writeAnimationList(const COLLADAFW::AnimationList *animat // called on post-process stage after writeVisualScenes bool DocumentImporter::writeAnimationClip(const COLLADAFW::AnimationClip *animationClip) { - if (mImportStage == Fetching_Controller_data) - return true; + if (mImportStage == Fetching_Controller_data) + return true; - return true; - //return animation_clip_importer.write_animation_clip(animationClip); // TODO: implement import of AnimationClips + return true; + //return animation_clip_importer.write_animation_clip(animationClip); // TODO: implement import of AnimationClips } #endif @@ -1159,54 +1149,54 @@ bool DocumentImporter::writeAnimationClip(const COLLADAFW::AnimationClip *animat * \return The writer should return true, if writing succeeded, false otherwise.*/ bool DocumentImporter::writeSkinControllerData(const COLLADAFW::SkinControllerData *skin) { - return armature_importer.write_skin_controller_data(skin); + return armature_importer.write_skin_controller_data(skin); } // this is called on postprocess, before writeVisualScenes bool DocumentImporter::writeController(const COLLADAFW::Controller *controller) { - if (mImportStage == Fetching_Controller_data) - return true; + if (mImportStage == Fetching_Controller_data) + return true; - return armature_importer.write_controller(controller); + return armature_importer.write_controller(controller); } bool DocumentImporter::writeFormulas(const COLLADAFW::Formulas *formulas) { - return true; + return true; } bool DocumentImporter::writeKinematicsScene(const COLLADAFW::KinematicsScene *kinematicsScene) { - return true; + return true; } ExtraTags *DocumentImporter::getExtraTags(const COLLADAFW::UniqueId &uid) { - if (uid_tags_map.find(uid.toAscii()) == uid_tags_map.end()) { - return NULL; - } - return uid_tags_map[uid.toAscii()]; + if (uid_tags_map.find(uid.toAscii()) == uid_tags_map.end()) { + return NULL; + } + return uid_tags_map[uid.toAscii()]; } bool DocumentImporter::addExtraTags(const COLLADAFW::UniqueId &uid, ExtraTags *extra_tags) { - uid_tags_map[uid.toAscii()] = extra_tags; - return true; + uid_tags_map[uid.toAscii()] = extra_tags; + return true; } bool DocumentImporter::is_armature(COLLADAFW::Node *node) { - COLLADAFW::NodePointerArray &child_nodes = node->getChildNodes(); - for (unsigned int i = 0; i < child_nodes.getCount(); i++) { - if (child_nodes[i]->getType() == COLLADAFW::Node::JOINT) { - return true; - } - else { - continue; - } - } - - //no child is JOINT - return false; + COLLADAFW::NodePointerArray &child_nodes = node->getChildNodes(); + for (unsigned int i = 0; i < child_nodes.getCount(); i++) { + if (child_nodes[i]->getType() == COLLADAFW::Node::JOINT) { + return true; + } + else { + continue; + } + } + + //no child is JOINT + return false; } |