16#include "COLLADAFWArrayPrimitiveType.h"
17#include "COLLADAFWCamera.h"
18#include "COLLADAFWLibraryNodes.h"
19#include "COLLADAFWLight.h"
20#include "COLLADAFWRoot.h"
21#include "COLLADAFWVisualScene.h"
23#include "COLLADASaxFWLLoader.h"
67 : import_settings(import_settings),
71 armature_importer(&unit_converter,
77 mesh_importer(&unit_converter,
78 import_settings->custom_normals,
89 TagsMap::iterator etit;
90 etit = uid_tags_map.begin();
91 while (etit != uid_tags_map.end()) {
100 COLLADASaxFWL::Loader loader(&errorHandler);
101 COLLADAFW::Root root(&loader,
this);
104 loader.registerExtraDataCallbackHandler(ehandler);
109 std::string mFilename = std::string(this->import_settings->filepath);
110 const std::string encodedFilename =
bc_url_encode(mFilename);
111 if (!root.loadDocument(encodedFilename)) {
112 fprintf(stderr,
"COLLADAFW::Root::loadDocument() returned false on 1st pass\n");
124 COLLADASaxFWL::Loader loader2;
125 COLLADAFW::Root root2(&loader2,
this);
127 if (!root2.loadDocument(encodedFilename)) {
128 fprintf(stderr,
"COLLADAFW::Root::loadDocument() returned false on 2nd pass\n");
160 unit_converter.calculate_scale(*sce);
162 std::vector<Object *> *objects_to_scale =
new std::vector<Object *>();
165 std::vector<const COLLADAFW::VisualScene *>::iterator sit;
166 for (sit = vscenes.begin(); sit != vscenes.end(); sit++) {
177 if (this->import_settings->import_units) {
179 switch (unit_converter.isMetricSystem()) {
190 float unit_factor = unit_converter.getLinearMeter();
192 fprintf(stdout,
"Collada: Adjusting Blender units to Importset units: %f.\n", unit_factor);
196 fprintf(stderr,
"+-- Import Scene --------\n");
197 const COLLADAFW::NodePointerArray &roots = (*sit)->getRootNodes();
198 for (
uint i = 0;
i < roots.getCount();
i++) {
199 std::vector<Object *> *objects_done =
write_node(roots[
i],
nullptr, sce,
nullptr,
false);
200 objects_to_scale->insert(
201 objects_to_scale->end(), objects_done->begin(), objects_done->end());
206 mesh_importer.optimize_material_assignements();
208 armature_importer.set_tags_map(this->uid_tags_map);
209 armature_importer.make_armatures(mContext, *objects_to_scale);
210 armature_importer.make_shape_keys(mContext);
213 armature_importer.fix_animation();
216 for (
const COLLADAFW::VisualScene *vscene : vscenes) {
217 const COLLADAFW::NodePointerArray &roots = vscene->getRootNodes();
219 for (
uint i = 0;
i < roots.getCount();
i++) {
224 if (!libnode_ob.empty()) {
226 fprintf(stderr,
"| Cleanup: free %d library nodes\n",
int(libnode_ob.size()));
228 std::vector<Object *>::iterator it;
229 for (it = libnode_ob.begin(); it != libnode_ob.end(); it++) {
236 bc_match_scale(objects_to_scale, unit_converter, !this->import_settings->import_units);
238 delete objects_to_scale;
247 COLLADAFW::Node *par =
nullptr,
259 if (root_map.find(par->getUniqueId()) == root_map.end()) {
260 root_map[node->getUniqueId()] = node;
263 root_map[node->getUniqueId()] = root_map[par->getUniqueId()];
268 COLLADAFW::Transformation::TransformationType
types[] = {
269 COLLADAFW::Transformation::ROTATE,
270 COLLADAFW::Transformation::SCALE,
271 COLLADAFW::Transformation::TRANSLATE,
272 COLLADAFW::Transformation::MATRIX,
279 if (node->getType() == COLLADAFW::Node::JOINT && par ==
nullptr) {
286 anim_importer.translate_Animations(
287 node, root_map, object_map, FW_object_map, uid_material_map);
288 COLLADAFW::NodePointerArray &children = node->getChildNodes();
289 for (
i = 0;
i < children.getCount();
i++) {
297 const char AUTORING_TOOL[] =
"authoring_tool";
298 const std::string BLENDER(
"Blender ");
299 const COLLADAFW::FileInfo::ValuePairPointerArray &valuePairs = asset->getValuePairArray();
300 for (
size_t i = 0,
count = valuePairs.getCount();
i <
count;
i++) {
301 const COLLADAFW::FileInfo::ValuePair *valuePair = valuePairs[
i];
302 const COLLADAFW::String &key = valuePair->first;
303 const COLLADAFW::String &value = valuePair->second;
304 if (key == AUTORING_TOOL) {
305 if (value.compare(0, BLENDER.length(), BLENDER) == 0) {
307 std::string
v = value.substr(BLENDER.length());
308 std::string::size_type n =
v.find(
" ");
310 return v.substr(0, n);
320 unit_converter.read_asset(asset);
322 anim_importer.set_import_from_version(import_from_version);
333 const COLLADAFW::UniqueId &cam_uid = camera->getInstanciatedObjectId();
334 if (uid_camera_map.find(cam_uid) == uid_camera_map.end()) {
341 Camera *cam = uid_camera_map[cam_uid];
350 const COLLADAFW::UniqueId &lamp_uid = lamp->getInstanciatedObjectId();
351 if (uid_light_map.find(lamp_uid) == uid_light_map.end()) {
352 fprintf(stderr,
"Couldn't find light by UID.\n");
358 Light *la = uid_light_map[lamp_uid];
366 COLLADAFW::Node *source_node,
367 COLLADAFW::Node *instance_node,
369 bool is_library_node)
382 anim_importer.read_node_transform(instance_node, obn);
387 COLLADABU::Math::Matrix4 mat4 = source_node->getTransformationMatrix();
388 COLLADABU::Math::Matrix4 bmat4 =
391 for (
int i = 0;
i < 4;
i++) {
392 for (
int j = 0; j < 4; j++) {
393 mat[
i][j] = bmat4[
i][j];
402 anim_importer.read_node_transform(source_node, obn);
407 COLLADAFW::NodePointerArray &children = source_node->getChildNodes();
408 if (children.getCount()) {
409 for (
uint i = 0;
i < children.getCount();
i++) {
410 COLLADAFW::Node *child_node = children[
i];
411 const COLLADAFW::UniqueId &child_id = child_node->getUniqueId();
412 if (object_map.find(child_id) == object_map.end()) {
415 COLLADAFW::InstanceNodePointerArray &inodes = child_node->getInstanceNodes();
416 Object *new_child =
nullptr;
417 if (inodes.getCount()) {
418 const COLLADAFW::UniqueId &
id = inodes[0]->getInstanciatedObjectId();
419 fprintf(stderr,
"Doing %d child nodes\n",
int(node_map.count(
id)));
421 object_map.find(
id)->second, node_map[
id], child_node, sce, is_library_node);
425 object_map.find(child_id)->second, child_node,
nullptr, sce, is_library_node);
429 if (is_library_node) {
430 libnode_ob.push_back(new_child);
447void DocumentImporter::report_unknown_reference(
const COLLADAFW::Node &node,
448 const std::string object_type)
450 std::string
id = node.getOriginalId();
451 std::string name = node.getName();
453 "error: node id=\"%s\", name=\"%s\" refers to an undefined %s.\n",
456 object_type.c_str());
460 COLLADAFW::Node *parent_node,
463 bool is_library_node)
467 bool is_joint = node->getType() == COLLADAFW::Node::JOINT;
468 bool read_transform =
true;
469 std::string
id = node->getOriginalId();
470 std::string name = node->getName();
473 COLLADAFW::NodePointerArray &child_nodes = node->getChildNodes();
475 std::vector<Object *> *objects_done =
new std::vector<Object *>();
476 std::vector<Object *> *root_objects =
new std::vector<Object *>();
479 stderr,
"| %s id='%s', name='%s'\n", is_joint ?
"JOINT" :
"NODE ",
id.c_str(), name.c_str());
482 if (parent_node ==
nullptr && !is_library_node) {
486 objects_done->push_back(par);
487 root_objects->push_back(par);
488 object_map.insert(std::pair<COLLADAFW::UniqueId, Object *>(node->getUniqueId(), par));
489 node_map[node->getUniqueId()] = node;
491 if (parent_node ==
nullptr || parent_node->getType() != COLLADAFW::Node::JOINT) {
492 armature_importer.add_root_joint(node, par);
495 if (parent_node ==
nullptr) {
502 COLLADAFW::InstanceGeometryPointerArray &geom = node->getInstanceGeometries();
503 COLLADAFW::InstanceCameraPointerArray &camera = node->getInstanceCameras();
504 COLLADAFW::InstanceLightPointerArray &lamp = node->getInstanceLights();
505 COLLADAFW::InstanceControllerPointerArray &
controller = node->getInstanceControllers();
506 COLLADAFW::InstanceNodePointerArray &inst_node = node->getInstanceNodes();
507 size_t geom_done = 0;
508 size_t camera_done = 0;
509 size_t lamp_done = 0;
510 size_t controller_done = 0;
511 size_t inst_done = 0;
516 while (geom_done < geom.getCount()) {
517 ob = mesh_importer.create_mesh_object(node, geom[geom_done],
false, uid_material_map);
519 report_unknown_reference(*node,
"instance_mesh");
522 objects_done->push_back(ob);
523 if (parent_node ==
nullptr) {
524 root_objects->push_back(ob);
529 while (camera_done < camera.getCount()) {
532 report_unknown_reference(*node,
"instance_camera");
535 objects_done->push_back(ob);
536 if (parent_node ==
nullptr) {
537 root_objects->push_back(ob);
542 while (lamp_done < lamp.getCount()) {
545 report_unknown_reference(*node,
"instance_light");
548 objects_done->push_back(ob);
549 if (parent_node ==
nullptr) {
550 root_objects->push_back(ob);
555 while (controller_done <
controller.getCount()) {
556 COLLADAFW::InstanceGeometry *geometry = (COLLADAFW::InstanceGeometry *)
558 ob = mesh_importer.create_mesh_object(node, geometry,
true, uid_material_map);
560 report_unknown_reference(*node,
"instance_controller");
563 objects_done->push_back(ob);
564 if (parent_node ==
nullptr) {
565 root_objects->push_back(ob);
571 while (inst_done < inst_node.getCount()) {
572 const COLLADAFW::UniqueId &node_id = inst_node[inst_done]->getInstanciatedObjectId();
573 if (object_map.find(node_id) == object_map.end()) {
575 "Cannot find object for node referenced by <instance_node name=\"%s\">.\n",
576 inst_node[inst_done]->
getName().c_str());
580 std::pair<std::multimap<COLLADAFW::UniqueId, Object *>::iterator,
581 std::multimap<COLLADAFW::UniqueId, Object *>::iterator>
582 pair_iter = object_map.equal_range(node_id);
583 for (std::multimap<COLLADAFW::UniqueId, Object *>::iterator it2 = pair_iter.first;
584 it2 != pair_iter.second;
588 COLLADAFW::Node *source_node = node_map[node_id];
590 objects_done->push_back(ob);
591 if (parent_node ==
nullptr) {
592 root_objects->push_back(ob);
598 read_transform =
false;
603 if ((geom_done + camera_done + lamp_done + controller_done + inst_done) < 1) {
612 objects_done->push_back(ob);
613 if (parent_node ==
nullptr) {
614 root_objects->push_back(ob);
624 for (
Object *ob : *objects_done) {
625 std::string nodename = node->getName().empty() ? node->getOriginalId() : node->getName();
627 object_map.insert(std::pair<COLLADAFW::UniqueId, Object *>(node->getUniqueId(), ob));
628 node_map[node->getUniqueId()] = node;
630 if (is_library_node) {
631 libnode_ob.push_back(ob);
638 for (
Object *ob : *objects_done) {
639 if (read_transform) {
640 anim_importer.read_node_transform(node, ob);
654 if (objects_done->empty()) {
658 ob = *objects_done->begin();
661 for (
uint i = 0;
i < child_nodes.getCount();
i++) {
662 std::vector<Object *> *child_objects;
663 child_objects =
write_node(child_nodes[
i], node, sce, ob, is_library_node);
664 delete child_objects;
690 vscenes.push_back(visualScene);
703 const COLLADAFW::NodePointerArray &nodes = libraryNodes->getNodes();
705 fprintf(stderr,
"+-- Read Library nodes ----------\n");
706 for (
uint i = 0;
i < nodes.getCount();
i++) {
707 std::vector<Object *> *child_objects;
708 child_objects =
write_node(nodes[
i],
nullptr, sce,
nullptr,
true);
709 delete child_objects;
720 return mesh_importer.write_geometry(geom);
730 const std::string &str_mat_id = cmat->getName().empty() ? cmat->getOriginalId() :
735 this->uid_effect_map[cmat->getInstantiatedEffect()] = ma;
736 this->uid_material_map[cmat->getUniqueId()] = ma;
748 matNode.
set_ior(ef->getIndexOfRefraction());
749 matNode.
set_alpha(ef->getOpaqueMode(), ef->getTransparent(), ef->getTransparency());
772 const COLLADAFW::UniqueId &uid = effect->getUniqueId();
774 if (uid_effect_map.find(uid) == uid_effect_map.end()) {
775 fprintf(stderr,
"Couldn't find a material by UID.\n");
780 std::map<COLLADAFW::UniqueId, Material *>::iterator iter;
781 for (iter = uid_material_map.begin(); iter != uid_material_map.end(); iter++) {
782 if (iter->second == ma) {
783 this->FW_object_map[iter->first] = effect;
787 COLLADAFW::CommonEffectPointerArray common_efs = effect->getCommonEffects();
788 if (common_efs.getCount() < 1) {
789 fprintf(stderr,
"Couldn't find <profile_COMMON>.\n");
794 COLLADAFW::EffectCommon *ef = common_efs[0];
796 this->FW_object_map[effect->getUniqueId()] = effect;
809 std::string cam_id, cam_name;
812 cam_id = camera->getOriginalId();
813 cam_name = camera->getName();
814 if (cam_name.empty()) {
822 fprintf(stderr,
"Cannot create camera.\n");
831 cam->
clip_start = camera->getNearClippingPlane().getValue();
832 cam->
clip_end = camera->getFarClippingPlane().getValue();
834 COLLADAFW::Camera::CameraType type = camera->getCameraType();
836 case COLLADAFW::Camera::ORTHOGRAPHIC: {
840 case COLLADAFW::Camera::PERSPECTIVE: {
844 case COLLADAFW::Camera::UNDEFINED_CAMERATYPE: {
845 fprintf(stderr,
"Current camera type is not supported.\n");
851 switch (camera->getDescriptionType()) {
852 case COLLADAFW::Camera::ASPECTRATIO_AND_Y: {
855 double ymag = 2 * camera->getYMag().getValue();
856 double aspect = camera->getAspectRatio().getValue();
857 double xmag = aspect * ymag;
863 double yfov = camera->getYFov().getValue();
864 double aspect = camera->getAspectRatio().getValue();
877 case COLLADAFW::Camera::ASPECTRATIO_AND_X:
878 case COLLADAFW::Camera::SINGLE_X:
879 case COLLADAFW::Camera::X_AND_Y: {
882 cam->
ortho_scale = float(camera->getXMag().getValue() * 2.0);
886 double x = camera->getXFov().getValue();
894 case COLLADAFW::Camera::SINGLE_Y: {
897 cam->
ortho_scale = float(camera->getYMag().getValue());
901 double yfov = camera->getYFov().getValue();
909 case COLLADAFW::Camera::UNDEFINED:
914 this->uid_camera_map[camera->getUniqueId()] = cam;
915 this->FW_object_map[camera->getUniqueId()] = camera;
926 const std::string &imagepath = image->getImageURI().toNativePath();
930 const char *workpath;
933 BLI_path_join(absolute_path,
sizeof(absolute_path), dir, imagepath.c_str());
935 workpath = absolute_path;
940 fprintf(stderr,
"|! Image not found: %s\n", imagepath.c_str());
943 workpath = imagepath.c_str();
948 fprintf(stderr,
"|! Cannot create image: %s\n", workpath);
951 this->uid_image_map[image->getUniqueId()] = ima;
952 fprintf(stderr,
"| import Image: %s\n", workpath);
963 Light *lamp =
nullptr;
964 std::string la_id, la_name;
968 TagsMap::iterator etit;
970 etit = uid_tags_map.find(light->getUniqueId().toAscii());
971 if (etit != uid_tags_map.end()) {
976 la_id = light->getOriginalId();
977 la_name = light->getName();
978 if (la_name.empty()) {
986 fprintf(stderr,
"Cannot create light.\n");
1014 if (light->getColor().isValid()) {
1015 COLLADAFW::Color
col = light->getColor();
1016 lamp->
r =
col.getRed();
1017 lamp->
g =
col.getGreen();
1018 lamp->
b =
col.getBlue();
1023 switch (light->getLightType()) {
1024 case COLLADAFW::Light::AMBIENT_LIGHT: {
1028 case COLLADAFW::Light::SPOT_LIGHT: {
1031 lamp->
spotblend = light->getFallOffExponent().getValue();
1034 case COLLADAFW::Light::DIRECTIONAL_LIGHT: {
1039 case COLLADAFW::Light::POINT_LIGHT: {
1043 case COLLADAFW::Light::UNDEFINED: {
1044 fprintf(stderr,
"Current light type is not supported.\n");
1051 this->uid_light_map[light->getUniqueId()] = lamp;
1052 this->FW_object_map[light->getUniqueId()] = light;
1062 return anim_importer.write_animation(anim);
1072 return anim_importer.write_animation_list(animationList);
1075#if WITH_OPENCOLLADA_ANIMATION_CLIP
1076bool DocumentImporter::writeAnimationClip(
const COLLADAFW::AnimationClip *animationClip)
1092 return armature_importer.write_skin_controller_data(skin);
1101 return armature_importer.write_controller(
controller);
1116 if (uid_tags_map.find(uid.toAscii()) == uid_tags_map.end()) {
1119 return uid_tags_map[uid.toAscii()];
1124 uid_tags_map[uid.toAscii()] = extra_tags;
1130 COLLADAFW::NodePointerArray &child_nodes = node->getChildNodes();
1131 for (
uint i = 0;
i < child_nodes.getCount();
i++) {
1132 if (child_nodes[
i]->getType() == COLLADAFW::Node::JOINT) {
Camera data-block and utility functions.
struct Camera * BKE_camera_add(struct Main *bmain, const char *name)
bool BKE_scene_collections_object_remove(Main *bmain, Scene *scene, Object *ob, bool free_us)
void BKE_collection_object_add_from(Main *bmain, Scene *scene, Object *ob_src, Object *ob_dst)
struct bConstraint * BKE_constraint_add_for_object(struct Object *ob, const char *name, short type)
Scene * CTX_data_scene(const bContext *C)
Main * CTX_data_main(const bContext *C)
ViewLayer * CTX_data_view_layer(const bContext *C)
Image * BKE_image_load_exists(Main *bmain, const char *filepath, bool *r_exists=nullptr)
void BKE_view_layer_base_deselect_all(const Scene *scene, ViewLayer *view_layer)
void BKE_id_free_us(Main *bmain, void *idv) ATTR_NONNULL()
IDNewNameResult BKE_libblock_rename(Main &bmain, ID &id, blender::StringRefNull name, const IDNewNameMode mode=IDNewNameMode::RenameExistingNever)
ID * BKE_id_copy(Main *bmain, const ID *id)
General operations, lookup, etc. for blender lights.
Light * BKE_light_add(Main *bmain, const char *name) ATTR_WARN_UNUSED_RESULT
General operations, lookup, etc. for materials.
Material * BKE_material_add(Main *bmain, const char *name)
void BKE_object_apply_mat4(Object *ob, const float mat[4][4], bool use_compat, bool use_parent)
File and directory operations.
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
float fov_to_focallength(float hfov, float sensor)
#define BLI_path_join(...)
void void BLI_path_split_dir_part(const char *filepath, char *dir, size_t dir_maxncpy) ATTR_NONNULL(1
void DEG_id_tag_update(ID *id, unsigned int flags)
void DEG_relations_tag_update(Main *bmain)
static Controller * controller
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
virtual const char * getName() const
bool writeScene(const COLLADAFW::Scene *) override
void write_profile_COMMON(COLLADAFW::EffectCommon *, Material *)
std::vector< Object * > * write_node(COLLADAFW::Node *, COLLADAFW::Node *, Scene *, Object *, bool)
std::string get_import_version(const COLLADAFW::FileInfo *asset)
bool addExtraTags(const COLLADAFW::UniqueId &uid, ExtraTags *extra_tags)
@ Fetching_Controller_data
Object * create_light_object(COLLADAFW::InstanceLight *, Scene *)
bool writeVisualScene(const COLLADAFW::VisualScene *) override
bool writeSkinControllerData(const COLLADAFW::SkinControllerData *) override
bool writeImage(const COLLADAFW::Image *) override
bool writeGlobalAsset(const COLLADAFW::FileInfo *) override
~DocumentImporter() override
bool writeMaterial(const COLLADAFW::Material *) override
void translate_anim_recursive(COLLADAFW::Node *, COLLADAFW::Node *, Object *)
void cancel(const COLLADAFW::String &errorMessage) override
bool writeAnimationList(const COLLADAFW::AnimationList *) override
Object * create_instance_node(Object *, COLLADAFW::Node *, COLLADAFW::Node *, Scene *, bool)
bool writeLight(const COLLADAFW::Light *) override
bool writeGeometry(const COLLADAFW::Geometry *) override
bool writeLibraryNodes(const COLLADAFW::LibraryNodes *) override
bool writeController(const COLLADAFW::Controller *) override
bool writeKinematicsScene(const COLLADAFW::KinematicsScene *) override
bool writeCamera(const COLLADAFW::Camera *) override
void create_constraints(ExtraTags *et, Object *ob)
DocumentImporter(bContext *C, const ImportSettings *import_settings)
ExtraTags * getExtraTags(const COLLADAFW::UniqueId &uid)
bool writeEffect(const COLLADAFW::Effect *) override
Object * create_camera_object(COLLADAFW::InstanceCamera *, Scene *)
bool writeFormulas(const COLLADAFW::Formulas *) override
bool is_armature(COLLADAFW::Node *node)
bool writeAnimation(const COLLADAFW::Animation *) override
Handler class for parser errors.
Handler class for <extra> data, through which different profiles can be handled.
void set_reflectivity(COLLADAFW::FloatOrParam &val)
void set_shininess(COLLADAFW::FloatOrParam &val)
void set_specular(COLLADAFW::ColorOrTexture &cot)
void update_material_nodetree()
void set_ior(COLLADAFW::FloatOrParam &val)
void set_reflective(COLLADAFW::ColorOrTexture &cot)
void set_emission(COLLADAFW::ColorOrTexture &cot)
void set_alpha(COLLADAFW::EffectCommon::OpaqueMode mode, COLLADAFW::ColorOrTexture &cot, COLLADAFW::FloatOrParam &val)
void set_diffuse(COLLADAFW::ColorOrTexture &cot)
void set_ambient(COLLADAFW::ColorOrTexture &cot)
Object * bc_add_object(Main *bmain, Scene *scene, ViewLayer *view_layer, int type, const char *name)
bool bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space)
std::string bc_url_encode(const std::string &data)
void bc_match_scale(Object *ob, UnitConverter &bc_unit, bool scale_to_scene)
Object * bc_add_armature(COLLADAFW::Node *node, ExtraTags *node_extra_tags, Main *bmain, Scene *scene, ViewLayer *view_layer, int type, const char *name)
PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
PointerRNA RNA_id_pointer_create(ID *id)
struct CameraDOFSettings dof
ObjectRuntimeHandle * runtime
void WM_event_add_notifier(const bContext *C, uint type, void *reference)