1c241671c812fbc0cb28c65cbed37cba79f0a939
[blender.git] / source / blender / collada / DocumentImporter.cpp
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16
17 /** \file
18  * \ingroup collada
19  */
20
21 /* TODO:
22  * * name imported objects
23  * * import object rotation as euler */
24
25 #include <string>
26 #include <map>
27 #include <algorithm>  // sort()
28
29 #include "COLLADAFWRoot.h"
30 #include "COLLADAFWStableHeaders.h"
31 #include "COLLADAFWColorOrTexture.h"
32 #include "COLLADAFWIndexList.h"
33 #include "COLLADAFWMeshPrimitiveWithFaceVertexCount.h"
34 #include "COLLADAFWPolygons.h"
35 #include "COLLADAFWSampler.h"
36 #include "COLLADAFWTypes.h"
37 #include "COLLADAFWVisualScene.h"
38 #include "COLLADAFWArrayPrimitiveType.h"
39 #include "COLLADAFWLibraryNodes.h"
40 #include "COLLADAFWCamera.h"
41 #include "COLLADAFWLight.h"
42
43 #include "COLLADASaxFWLLoader.h"
44 #include "COLLADASaxFWLIExtraDataCallbackHandler.h"
45
46 extern "C" {
47 #include "BLI_listbase.h"
48 #include "BLI_math.h"
49 #include "BLI_string.h"
50 #include "BLI_utildefines.h"
51 #include "BLI_fileops.h"
52
53 #include "BKE_camera.h"
54 #include "BKE_collection.h"
55 #include "BKE_fcurve.h"
56 #include "BKE_global.h"
57 #include "BKE_image.h"
58 #include "BKE_layer.h"
59 #include "BKE_light.h"
60 #include "BKE_library.h"
61 #include "BKE_material.h"
62 #include "BKE_scene.h"
63
64 #include "BLI_path_util.h"
65
66 #include "DNA_camera_types.h"
67 #include "DNA_light_types.h"
68
69 #include "RNA_access.h"
70
71 #include "MEM_guardedalloc.h"
72
73 #include "WM_api.h"
74 #include "WM_types.h"
75 }
76
77 #include "DEG_depsgraph.h"
78 #include "DEG_depsgraph_build.h"
79
80 #include "ExtraHandler.h"
81 #include "ErrorHandler.h"
82 #include "DocumentImporter.h"
83 #include "TransformReader.h"
84
85 #include "collada_internal.h"
86 #include "collada_utils.h"
87 #include "Materials.h"
88
89 /*
90  * COLLADA Importer limitations:
91  * - no multiple scene import, all objects are added to active scene
92  */
93
94 // #define COLLADA_DEBUG
95 // creates empties for each imported bone on layer 2, for debugging
96 // #define ARMATURE_TEST
97
98 DocumentImporter::DocumentImporter(bContext *C, const ImportSettings *import_settings)
99     : import_settings(import_settings),
100       mImportStage(Fetching_Scene_data),
101       mContext(C),
102       view_layer(CTX_data_view_layer(mContext)),
103       armature_importer(&unit_converter,
104                         &mesh_importer,
105                         CTX_data_main(C),
106                         CTX_data_scene(C),
107                         view_layer,
108                         import_settings),
109       mesh_importer(
110           &unit_converter, &armature_importer, CTX_data_main(C), CTX_data_scene(C), view_layer),
111       anim_importer(C, &unit_converter, &armature_importer, CTX_data_scene(C))
112 {
113 }
114
115 DocumentImporter::~DocumentImporter()
116 {
117   TagsMap::iterator etit;
118   etit = uid_tags_map.begin();
119   while (etit != uid_tags_map.end()) {
120     delete etit->second;
121     etit++;
122   }
123 }
124
125 bool DocumentImporter::import()
126 {
127   ErrorHandler errorHandler;
128   COLLADASaxFWL::Loader loader(&errorHandler);
129   COLLADAFW::Root root(&loader, this);
130   ExtraHandler *ehandler = new ExtraHandler(this, &(this->anim_importer));
131
132   loader.registerExtraDataCallbackHandler(ehandler);
133
134   /* deselect all to select new objects */
135   BKE_view_layer_base_deselect_all(view_layer);
136
137   std::string mFilename = std::string(this->import_settings->filepath);
138   const std::string encodedFilename = bc_url_encode(mFilename);
139   if (!root.loadDocument(encodedFilename)) {
140     fprintf(stderr, "COLLADAFW::Root::loadDocument() returned false on 1st pass\n");
141     delete ehandler;
142     return false;
143   }
144
145   if (errorHandler.hasError()) {
146     delete ehandler;
147     return false;
148   }
149
150   /** TODO set up scene graph and such here */
151   mImportStage = Fetching_Controller_data;
152   COLLADASaxFWL::Loader loader2;
153   COLLADAFW::Root root2(&loader2, this);
154
155   if (!root2.loadDocument(encodedFilename)) {
156     fprintf(stderr, "COLLADAFW::Root::loadDocument() returned false on 2nd pass\n");
157     delete ehandler;
158     return false;
159   }
160
161   delete ehandler;
162
163   return true;
164 }
165
166 void DocumentImporter::cancel(const COLLADAFW::String &errorMessage)
167 {
168   /* TODO: if possible show error info
169    *
170    * Should we get rid of invisible Meshes that were created so far
171    * or maybe create objects at coordinate space origin?
172    *
173    * The latter sounds better. */
174 }
175
176 void DocumentImporter::start()
177 {
178 }
179
180 void DocumentImporter::finish()
181 {
182   if (mImportStage == Fetching_Controller_data) {
183     return;
184   }
185
186   Main *bmain = CTX_data_main(mContext);
187   /* TODO: create a new scene except the selected <visual_scene> -
188    * use current blender scene for it */
189   Scene *sce = CTX_data_scene(mContext);
190   unit_converter.calculate_scale(*sce);
191
192   std::vector<Object *> *objects_to_scale = new std::vector<Object *>();
193
194   /** TODO Break up and put into 2-pass parsing of DAE */
195   std::vector<const COLLADAFW::VisualScene *>::iterator sit;
196   for (sit = vscenes.begin(); sit != vscenes.end(); sit++) {
197     PointerRNA sceneptr, unit_settings;
198     PropertyRNA *system, *scale;
199
200     /* for scene unit settings: system, scale_length */
201
202     RNA_id_pointer_create(&sce->id, &sceneptr);
203     unit_settings = RNA_pointer_get(&sceneptr, "unit_settings");
204     system = RNA_struct_find_property(&unit_settings, "system");
205     scale = RNA_struct_find_property(&unit_settings, "scale_length");
206
207     if (this->import_settings->import_units) {
208
209       switch (unit_converter.isMetricSystem()) {
210         case UnitConverter::Metric:
211           RNA_property_enum_set(&unit_settings, system, USER_UNIT_METRIC);
212           break;
213         case UnitConverter::Imperial:
214           RNA_property_enum_set(&unit_settings, system, USER_UNIT_IMPERIAL);
215           break;
216         default:
217           RNA_property_enum_set(&unit_settings, system, USER_UNIT_NONE);
218           break;
219       }
220       float unit_factor = unit_converter.getLinearMeter();
221       RNA_property_float_set(&unit_settings, scale, unit_factor);
222       fprintf(stdout, "Collada: Adjusting Blender units to Importset units: %f.\n", unit_factor);
223     }
224
225     /* Write nodes to scene */
226     fprintf(stderr, "+-- Import Scene --------\n");
227     const COLLADAFW::NodePointerArray &roots = (*sit)->getRootNodes();
228     for (unsigned int i = 0; i < roots.getCount(); i++) {
229       std::vector<Object *> *objects_done = write_node(roots[i], NULL, sce, NULL, false);
230       objects_to_scale->insert(
231           objects_to_scale->end(), objects_done->begin(), objects_done->end());
232       delete objects_done;
233     }
234   }
235
236   mesh_importer.optimize_material_assignements();
237
238   armature_importer.set_tags_map(this->uid_tags_map);
239   armature_importer.make_armatures(mContext, *objects_to_scale);
240   armature_importer.make_shape_keys(mContext);
241
242 #if 0
243   armature_importer.fix_animation();
244 #endif
245
246   for (std::vector<const COLLADAFW::VisualScene *>::iterator vsit = vscenes.begin();
247        vsit != vscenes.end();
248        vsit++) {
249     const COLLADAFW::NodePointerArray &roots = (*vsit)->getRootNodes();
250
251     for (unsigned int i = 0; i < roots.getCount(); i++) {
252       translate_anim_recursive(roots[i], NULL, NULL);
253     }
254   }
255
256   if (libnode_ob.size()) {
257
258     fprintf(stderr, "| Cleanup: free %d library nodes\n", (int)libnode_ob.size());
259     /* free all library_nodes */
260     std::vector<Object *>::iterator it;
261     for (it = libnode_ob.begin(); it != libnode_ob.end(); it++) {
262       Object *ob = *it;
263       BKE_scene_collections_object_remove(bmain, sce, ob, true);
264     }
265     libnode_ob.clear();
266   }
267
268   bc_match_scale(objects_to_scale, unit_converter, !this->import_settings->import_units);
269
270   delete objects_to_scale;
271
272   /* update scene */
273   DEG_id_tag_update(&sce->id, ID_RECALC_COPY_ON_WRITE);
274   DEG_relations_tag_update(bmain);
275   WM_event_add_notifier(mContext, NC_OBJECT | ND_TRANSFORM, NULL);
276 }
277
278 void DocumentImporter::translate_anim_recursive(COLLADAFW::Node *node,
279                                                 COLLADAFW::Node *par = NULL,
280                                                 Object *parob = NULL)
281 {
282   /* The split in #29246, rootmap must point at actual root when
283    * calculating bones in apply_curves_as_matrix. - actual root is the root node.
284    * This has to do with inverse bind poses being world space
285    * (the sources for skinned bones' restposes) and the way
286    * non-skinning nodes have their "restpose" recursively calculated.
287    * XXX TODO: design issue, how to support unrelated joints taking
288    * part in skinning. */
289   if (par) {  // && par->getType() == COLLADAFW::Node::JOINT) {
290     /* par is root if there's no corresp. key in root_map */
291     if (root_map.find(par->getUniqueId()) == root_map.end()) {
292       root_map[node->getUniqueId()] = node;
293     }
294     else {
295       root_map[node->getUniqueId()] = root_map[par->getUniqueId()];
296     }
297   }
298
299 #if 0
300   COLLADAFW::Transformation::TransformationType types[] = {
301       COLLADAFW::Transformation::ROTATE,
302       COLLADAFW::Transformation::SCALE,
303       COLLADAFW::Transformation::TRANSLATE,
304       COLLADAFW::Transformation::MATRIX,
305   };
306
307   Object *ob;
308 #endif
309   unsigned int i;
310
311   if (node->getType() == COLLADAFW::Node::JOINT && par == NULL) {
312     /* For Skeletons without root node we have to simulate the
313      * root node here and recursively enter the same function
314      * XXX: maybe this can be made more elegant. */
315     translate_anim_recursive(node, node, parob);
316   }
317   else {
318     anim_importer.translate_Animations(
319         node, root_map, object_map, FW_object_map, uid_material_map);
320     COLLADAFW::NodePointerArray &children = node->getChildNodes();
321     for (i = 0; i < children.getCount(); i++) {
322       translate_anim_recursive(children[i], node, NULL);
323     }
324   }
325 }
326
327 /**
328  * If the imported file was made with Blender, return the Blender version used,
329  * otherwise return an empty std::string
330  */
331 std::string DocumentImporter::get_import_version(const COLLADAFW::FileInfo *asset)
332 {
333   const char AUTORING_TOOL[] = "authoring_tool";
334   const std::string BLENDER("Blender ");
335   const COLLADAFW::FileInfo::ValuePairPointerArray &valuePairs = asset->getValuePairArray();
336   for (size_t i = 0, count = valuePairs.getCount(); i < count; ++i) {
337     const COLLADAFW::FileInfo::ValuePair *valuePair = valuePairs[i];
338     const COLLADAFW::String &key = valuePair->first;
339     const COLLADAFW::String &value = valuePair->second;
340     if (key == AUTORING_TOOL) {
341       if (value.compare(0, BLENDER.length(), BLENDER) == 0) {
342         /* Was made with Blender, now get version string */
343         std::string v = value.substr(BLENDER.length());
344         std::string::size_type n = v.find(" ");
345         if (n > 0) {
346           return v.substr(0, n);
347         }
348       }
349     }
350   }
351   return "";
352 }
353
354 /** When this method is called, the writer must write the global document asset.
355  * \return The writer should return true, if writing succeeded, false otherwise.*/
356 bool DocumentImporter::writeGlobalAsset(const COLLADAFW::FileInfo *asset)
357 {
358   unit_converter.read_asset(asset);
359   import_from_version = get_import_version(asset);
360   anim_importer.set_import_from_version(import_from_version);
361   return true;
362 }
363
364 /** When this method is called, the writer must write the scene.
365  * \return The writer should return true, if writing succeeded, false otherwise.*/
366 bool DocumentImporter::writeScene(const COLLADAFW::Scene *scene)
367 {
368   /* XXX could store the scene id, but do nothing for now */
369   return true;
370 }
371 Object *DocumentImporter::create_camera_object(COLLADAFW::InstanceCamera *camera, Scene *sce)
372 {
373   const COLLADAFW::UniqueId &cam_uid = camera->getInstanciatedObjectId();
374   if (uid_camera_map.find(cam_uid) == uid_camera_map.end()) {
375     // fprintf(stderr, "Couldn't find camera by UID.\n");
376     return NULL;
377   }
378
379   Main *bmain = CTX_data_main(mContext);
380   Object *ob = bc_add_object(bmain, sce, view_layer, OB_CAMERA, NULL);
381   Camera *cam = uid_camera_map[cam_uid];
382   Camera *old_cam = (Camera *)ob->data;
383   ob->data = cam;
384   BKE_id_free_us(bmain, old_cam);
385   return ob;
386 }
387
388 Object *DocumentImporter::create_light_object(COLLADAFW::InstanceLight *lamp, Scene *sce)
389 {
390   const COLLADAFW::UniqueId &lamp_uid = lamp->getInstanciatedObjectId();
391   if (uid_light_map.find(lamp_uid) == uid_light_map.end()) {
392     fprintf(stderr, "Couldn't find light by UID.\n");
393     return NULL;
394   }
395
396   Main *bmain = CTX_data_main(mContext);
397   Object *ob = bc_add_object(bmain, sce, view_layer, OB_LAMP, NULL);
398   Light *la = uid_light_map[lamp_uid];
399   Light *old_light = (Light *)ob->data;
400   ob->data = la;
401   BKE_id_free_us(bmain, old_light);
402   return ob;
403 }
404
405 Object *DocumentImporter::create_instance_node(Object *source_ob,
406                                                COLLADAFW::Node *source_node,
407                                                COLLADAFW::Node *instance_node,
408                                                Scene *sce,
409                                                bool is_library_node)
410 {
411   // fprintf(stderr, "create <instance_node> under node id=%s from node id=%s\n", instance_node ?
412   // instance_node->getOriginalId().c_str() : NULL, source_node ?
413   // source_node->getOriginalId().c_str() : NULL);
414
415   Main *bmain = CTX_data_main(mContext);
416   Object *obn = BKE_object_copy(bmain, source_ob);
417   DEG_id_tag_update(&obn->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
418   BKE_collection_object_add_from(bmain, sce, source_ob, obn);
419
420   if (instance_node) {
421     anim_importer.read_node_transform(instance_node, obn);
422     /* if we also have a source_node (always ;), take its
423      * transformation matrix and apply it to the newly instantiated
424      * object to account for node hierarchy transforms in
425      * .dae */
426     if (source_node) {
427       COLLADABU::Math::Matrix4 mat4 = source_node->getTransformationMatrix();
428       COLLADABU::Math::Matrix4 bmat4 =
429           mat4.transpose();  // transpose to get blender row-major order
430       float mat[4][4];
431       for (int i = 0; i < 4; i++) {
432         for (int j = 0; j < 4; j++) {
433           mat[i][j] = bmat4[i][j];
434         }
435       }
436       /* calc new matrix and apply */
437       mul_m4_m4m4(obn->obmat, obn->obmat, mat);
438       BKE_object_apply_mat4(obn, obn->obmat, 0, 0);
439     }
440   }
441   else {
442     anim_importer.read_node_transform(source_node, obn);
443   }
444
445   /*DAG_relations_tag_update(CTX_data_main(mContext));*/
446
447   COLLADAFW::NodePointerArray &children = source_node->getChildNodes();
448   if (children.getCount()) {
449     for (unsigned int i = 0; i < children.getCount(); i++) {
450       COLLADAFW::Node *child_node = children[i];
451       const COLLADAFW::UniqueId &child_id = child_node->getUniqueId();
452       if (object_map.find(child_id) == object_map.end()) {
453         continue;
454       }
455       COLLADAFW::InstanceNodePointerArray &inodes = child_node->getInstanceNodes();
456       Object *new_child = NULL;
457       if (inodes.getCount()) {  // \todo loop through instance nodes
458         const COLLADAFW::UniqueId &id = inodes[0]->getInstanciatedObjectId();
459         fprintf(stderr, "Doing %d child nodes\n", (int)node_map.count(id));
460         new_child = create_instance_node(
461             object_map.find(id)->second, node_map[id], child_node, sce, is_library_node);
462       }
463       else {
464         new_child = create_instance_node(
465             object_map.find(child_id)->second, child_node, NULL, sce, is_library_node);
466       }
467       bc_set_parent(new_child, obn, mContext, true);
468
469       if (is_library_node) {
470         libnode_ob.push_back(new_child);
471       }
472     }
473   }
474
475   return obn;
476 }
477
478 /* to create constraints off node <extra> tags. Assumes only constraint data in
479  * current <extra> with blender profile. */
480 void DocumentImporter::create_constraints(ExtraTags *et, Object *ob)
481 {
482   if (et && et->isProfile("blender")) {
483     std::string name;
484     short type = 0;
485     et->setData("type", &type);
486     BKE_constraint_add_for_object(ob, "Test_con", type);
487   }
488 }
489
490 void DocumentImporter::report_unknown_reference(const COLLADAFW::Node &node,
491                                                 const std::string object_type)
492 {
493   std::string id = node.getOriginalId();
494   std::string name = node.getName();
495   fprintf(stderr,
496           "error: node id=\"%s\", name=\"%s\" refers to an undefined %s.\n",
497           id.c_str(),
498           name.c_str(),
499           object_type.c_str());
500 }
501
502 std::vector<Object *> *DocumentImporter::write_node(COLLADAFW::Node *node,
503                                                     COLLADAFW::Node *parent_node,
504                                                     Scene *sce,
505                                                     Object *par,
506                                                     bool is_library_node)
507 {
508   Main *bmain = CTX_data_main(mContext);
509   Object *ob = NULL;
510   bool is_joint = node->getType() == COLLADAFW::Node::JOINT;
511   bool read_transform = true;
512   std::string id = node->getOriginalId();
513   std::string name = node->getName();
514
515   /* if node has child nodes write them */
516   COLLADAFW::NodePointerArray &child_nodes = node->getChildNodes();
517
518   std::vector<Object *> *objects_done = new std::vector<Object *>();
519   std::vector<Object *> *root_objects = new std::vector<Object *>();
520
521   fprintf(
522       stderr, "| %s id='%s', name='%s'\n", is_joint ? "JOINT" : "NODE ", id.c_str(), name.c_str());
523
524   if (is_joint) {
525     if (parent_node == NULL && !is_library_node) {
526       /* A Joint on root level is a skeleton without root node.
527        * Here we add the armature "on the fly": */
528       par = bc_add_object(bmain, sce, view_layer, OB_ARMATURE, std::string("Armature").c_str());
529       objects_done->push_back(par);
530       root_objects->push_back(par);
531       object_map.insert(std::pair<COLLADAFW::UniqueId, Object *>(node->getUniqueId(), par));
532       node_map[node->getUniqueId()] = node;
533     }
534     if (parent_node == NULL || parent_node->getType() != COLLADAFW::Node::JOINT) {
535       armature_importer.add_root_joint(node, par);
536     }
537
538     if (parent_node == NULL) {
539       /* for skeletons without root node all has been done above.
540        * Skeletons with root node are handled further down. */
541       goto finally;
542     }
543   }
544   else {
545     COLLADAFW::InstanceGeometryPointerArray &geom = node->getInstanceGeometries();
546     COLLADAFW::InstanceCameraPointerArray &camera = node->getInstanceCameras();
547     COLLADAFW::InstanceLightPointerArray &lamp = node->getInstanceLights();
548     COLLADAFW::InstanceControllerPointerArray &controller = node->getInstanceControllers();
549     COLLADAFW::InstanceNodePointerArray &inst_node = node->getInstanceNodes();
550     size_t geom_done = 0;
551     size_t camera_done = 0;
552     size_t lamp_done = 0;
553     size_t controller_done = 0;
554     size_t inst_done = 0;
555
556     /* XXX linking object with the first <instance_geometry>, though a node may have more of
557      * them... maybe join multiple <instance_...> meshes into 1, and link object with it? not
558      * sure... <instance_geometry> */
559     while (geom_done < geom.getCount()) {
560       ob = mesh_importer.create_mesh_object(node, geom[geom_done], false, uid_material_map);
561       if (ob == NULL) {
562         report_unknown_reference(*node, "instance_mesh");
563       }
564       else {
565         objects_done->push_back(ob);
566         if (parent_node == NULL) {
567           root_objects->push_back(ob);
568         }
569       }
570       ++geom_done;
571     }
572     while (camera_done < camera.getCount()) {
573       ob = create_camera_object(camera[camera_done], sce);
574       if (ob == NULL) {
575         report_unknown_reference(*node, "instance_camera");
576       }
577       else {
578         objects_done->push_back(ob);
579         if (parent_node == NULL) {
580           root_objects->push_back(ob);
581         }
582       }
583       ++camera_done;
584     }
585     while (lamp_done < lamp.getCount()) {
586       ob = create_light_object(lamp[lamp_done], sce);
587       if (ob == NULL) {
588         report_unknown_reference(*node, "instance_light");
589       }
590       else {
591         objects_done->push_back(ob);
592         if (parent_node == NULL) {
593           root_objects->push_back(ob);
594         }
595       }
596       ++lamp_done;
597     }
598     while (controller_done < controller.getCount()) {
599       COLLADAFW::InstanceGeometry *geometry = (COLLADAFW::InstanceGeometry *)
600           controller[controller_done];
601       ob = mesh_importer.create_mesh_object(node, geometry, true, uid_material_map);
602       if (ob == NULL) {
603         report_unknown_reference(*node, "instance_controller");
604       }
605       else {
606         objects_done->push_back(ob);
607         if (parent_node == NULL) {
608           root_objects->push_back(ob);
609         }
610       }
611       ++controller_done;
612     }
613     /* XXX instance_node is not supported yet */
614     while (inst_done < inst_node.getCount()) {
615       const COLLADAFW::UniqueId &node_id = inst_node[inst_done]->getInstanciatedObjectId();
616       if (object_map.find(node_id) == object_map.end()) {
617         fprintf(stderr,
618                 "Cannot find object for node referenced by <instance_node name=\"%s\">.\n",
619                 inst_node[inst_done]->getName().c_str());
620         ob = NULL;
621       }
622       else {
623         std::pair<std::multimap<COLLADAFW::UniqueId, Object *>::iterator,
624                   std::multimap<COLLADAFW::UniqueId, Object *>::iterator>
625             pair_iter = object_map.equal_range(node_id);
626         for (std::multimap<COLLADAFW::UniqueId, Object *>::iterator it2 = pair_iter.first;
627              it2 != pair_iter.second;
628              it2++) {
629           Object *source_ob = (Object *)it2->second;
630           COLLADAFW::Node *source_node = node_map[node_id];
631           ob = create_instance_node(source_ob, source_node, node, sce, is_library_node);
632           objects_done->push_back(ob);
633           if (parent_node == NULL) {
634             root_objects->push_back(ob);
635           }
636         }
637       }
638       ++inst_done;
639
640       read_transform = false;
641     }
642
643     /* if node is empty - create empty object
644      * XXX empty node may not mean it is empty object, not sure about this */
645     if ((geom_done + camera_done + lamp_done + controller_done + inst_done) < 1) {
646       /* Check if Object is armature, by checking if immediate child is a JOINT node. */
647       if (is_armature(node)) {
648         ob = bc_add_object(bmain, sce, view_layer, OB_ARMATURE, name.c_str());
649       }
650       else {
651         ob = bc_add_object(bmain, sce, view_layer, OB_EMPTY, NULL);
652       }
653       objects_done->push_back(ob);
654       if (parent_node == NULL) {
655         root_objects->push_back(ob);
656       }
657     }
658
659     /* XXX: if there're multiple instances, only one is stored */
660
661     if (!ob) {
662       goto finally;
663     }
664
665     for (std::vector<Object *>::iterator it = objects_done->begin(); it != objects_done->end();
666          ++it) {
667       ob = *it;
668       std::string nodename = node->getName().size() ? node->getName() : node->getOriginalId();
669       BKE_libblock_rename(bmain, &ob->id, (char *)nodename.c_str());
670       object_map.insert(std::pair<COLLADAFW::UniqueId, Object *>(node->getUniqueId(), ob));
671       node_map[node->getUniqueId()] = node;
672
673       if (is_library_node) {
674         libnode_ob.push_back(ob);
675       }
676     }
677
678     // create_constraints(et,ob);
679   }
680
681   for (std::vector<Object *>::iterator it = objects_done->begin(); it != objects_done->end();
682        ++it) {
683     ob = *it;
684
685     if (read_transform) {
686       anim_importer.read_node_transform(node, ob);  // overwrites location set earlier
687     }
688
689     if (!is_joint) {
690       if (par && ob) {
691         ob->parent = par;
692         ob->partype = PAROBJECT;
693         ob->parsubstr[0] = 0;
694
695         // bc_set_parent(ob, par, mContext, false);
696       }
697     }
698   }
699
700   if (objects_done->size() > 0) {
701     ob = *objects_done->begin();
702   }
703   else {
704     ob = NULL;
705   }
706
707   for (unsigned int i = 0; i < child_nodes.getCount(); i++) {
708     std::vector<Object *> *child_objects;
709     child_objects = write_node(child_nodes[i], node, sce, ob, is_library_node);
710     delete child_objects;
711   }
712
713 finally:
714   delete objects_done;
715
716   return root_objects;
717 }
718
719 /**
720  * When this method is called, the writer must write the entire visual scene.
721  * Return The writer should return true, if writing succeeded, false otherwise.
722  */
723 bool DocumentImporter::writeVisualScene(const COLLADAFW::VisualScene *visualScene)
724 {
725   if (mImportStage == Fetching_Controller_data) {
726     return true;
727   }
728
729   /* This method called on post process after writeGeometry, writeMaterial, etc. */
730
731   /* For each <node> in <visual_scene>:
732    * create an Object
733    * if Mesh (previously created in writeGeometry) to which <node> corresponds exists,
734    * link Object with that mesh.
735    *
736    * Update: since we cannot link a Mesh with Object in
737    * writeGeometry because <geometry> does not reference <node>,
738    * we link Objects with Meshes here.
739    */
740   vscenes.push_back(visualScene);
741
742   return true;
743 }
744
745 /** When this method is called, the writer must handle all nodes contained in the
746  * library nodes.
747  * \return The writer should return true, if writing succeeded, false otherwise.*/
748 bool DocumentImporter::writeLibraryNodes(const COLLADAFW::LibraryNodes *libraryNodes)
749 {
750   if (mImportStage == Fetching_Controller_data) {
751     return true;
752   }
753
754   Scene *sce = CTX_data_scene(mContext);
755
756   const COLLADAFW::NodePointerArray &nodes = libraryNodes->getNodes();
757
758   fprintf(stderr, "+-- Read Library nodes ----------\n");
759   for (unsigned int i = 0; i < nodes.getCount(); i++) {
760     std::vector<Object *> *child_objects;
761     child_objects = write_node(nodes[i], NULL, sce, NULL, true);
762     delete child_objects;
763   }
764   return true;
765 }
766
767 /** When this method is called, the writer must write the geometry.
768  * \return The writer should return true, if writing succeeded, false otherwise.*/
769 bool DocumentImporter::writeGeometry(const COLLADAFW::Geometry *geom)
770 {
771   if (mImportStage == Fetching_Controller_data) {
772     return true;
773   }
774
775   return mesh_importer.write_geometry(geom);
776 }
777
778 /** When this method is called, the writer must write the material.
779  * \return The writer should return true, if writing succeeded, false otherwise.*/
780 bool DocumentImporter::writeMaterial(const COLLADAFW::Material *cmat)
781 {
782   if (mImportStage == Fetching_Controller_data) {
783     return true;
784   }
785
786   Main *bmain = CTX_data_main(mContext);
787   const std::string &str_mat_id = cmat->getName().size() ? cmat->getName() : cmat->getOriginalId();
788   Material *ma = BKE_material_add(bmain, (char *)str_mat_id.c_str());
789
790   this->uid_effect_map[cmat->getInstantiatedEffect()] = ma;
791   this->uid_material_map[cmat->getUniqueId()] = ma;
792
793   return true;
794 }
795
796 void DocumentImporter::write_profile_COMMON(COLLADAFW::EffectCommon *ef, Material *ma)
797 {
798   MaterialNode matNode = MaterialNode(mContext, ef, ma, uid_image_map);
799   matNode.set_reflectivity(ef->getReflectivity().getFloatValue());
800   matNode.set_ior(ef->getIndexOfRefraction().getFloatValue());
801   matNode.set_diffuse(ef->getDiffuse(), "Diffuse");
802   matNode.set_ambient(ef->getAmbient(), "Ambient");
803   matNode.set_specular(ef->getSpecular(), "Specular");
804   matNode.set_reflective(ef->getReflective(), "Reflective");
805   matNode.set_emission(ef->getEmission(), "Emission");
806   matNode.set_opacity(ef->getOpacity(), "Opacity");
807 }
808
809 /** When this method is called, the writer must write the effect.
810  * \return The writer should return true, if writing succeeded, false otherwise.*/
811
812 bool DocumentImporter::writeEffect(const COLLADAFW::Effect *effect)
813 {
814   if (mImportStage == Fetching_Controller_data) {
815     return true;
816   }
817
818   const COLLADAFW::UniqueId &uid = effect->getUniqueId();
819
820   if (uid_effect_map.find(uid) == uid_effect_map.end()) {
821     fprintf(stderr, "Couldn't find a material by UID.\n");
822     return true;
823   }
824
825   Material *ma = uid_effect_map[uid];
826   std::map<COLLADAFW::UniqueId, Material *>::iterator iter;
827   for (iter = uid_material_map.begin(); iter != uid_material_map.end(); iter++) {
828     if (iter->second == ma) {
829       this->FW_object_map[iter->first] = effect;
830       break;
831     }
832   }
833   COLLADAFW::CommonEffectPointerArray common_efs = effect->getCommonEffects();
834   if (common_efs.getCount() < 1) {
835     fprintf(stderr, "Couldn't find <profile_COMMON>.\n");
836     return true;
837   }
838   /* XXX TODO: Take all <profile_common>s
839    * Currently only first <profile_common> is supported */
840   COLLADAFW::EffectCommon *ef = common_efs[0];
841   write_profile_COMMON(ef, ma);
842   this->FW_object_map[effect->getUniqueId()] = effect;
843
844   return true;
845 }
846
847 /** When this method is called, the writer must write the camera.
848  * \return The writer should return true, if writing succeeded, false otherwise.*/
849 bool DocumentImporter::writeCamera(const COLLADAFW::Camera *camera)
850 {
851   if (mImportStage == Fetching_Controller_data) {
852     return true;
853   }
854
855   Main *bmain = CTX_data_main(mContext);
856   Camera *cam = NULL;
857   std::string cam_id, cam_name;
858
859   ExtraTags *et = getExtraTags(camera->getUniqueId());
860   cam_id = camera->getOriginalId();
861   cam_name = camera->getName();
862   if (cam_name.size()) {
863     cam = (Camera *)BKE_camera_add(bmain, (char *)cam_name.c_str());
864   }
865   else {
866     cam = (Camera *)BKE_camera_add(bmain, (char *)cam_id.c_str());
867   }
868
869   if (!cam) {
870     fprintf(stderr, "Cannot create camera.\n");
871     return true;
872   }
873
874   if (et && et->isProfile("blender")) {
875     et->setData("shiftx", &(cam->shiftx));
876     et->setData("shifty", &(cam->shifty));
877     et->setData("dof_distance", &(cam->dof.focus_distance));
878   }
879   cam->clip_start = camera->getNearClippingPlane().getValue();
880   cam->clip_end = camera->getFarClippingPlane().getValue();
881
882   COLLADAFW::Camera::CameraType type = camera->getCameraType();
883   switch (type) {
884     case COLLADAFW::Camera::ORTHOGRAPHIC: {
885       cam->type = CAM_ORTHO;
886     } break;
887     case COLLADAFW::Camera::PERSPECTIVE: {
888       cam->type = CAM_PERSP;
889     } break;
890     case COLLADAFW::Camera::UNDEFINED_CAMERATYPE: {
891       fprintf(stderr, "Current camera type is not supported.\n");
892       cam->type = CAM_PERSP;
893     } break;
894   }
895
896   switch (camera->getDescriptionType()) {
897     case COLLADAFW::Camera::ASPECTRATIO_AND_Y: {
898       switch (cam->type) {
899         case CAM_ORTHO: {
900           double ymag = 2 * camera->getYMag().getValue();
901           double aspect = camera->getAspectRatio().getValue();
902           double xmag = aspect * ymag;
903           cam->ortho_scale = (float)xmag;
904         } break;
905         case CAM_PERSP:
906         default: {
907           double yfov = camera->getYFov().getValue();
908           double aspect = camera->getAspectRatio().getValue();
909
910           /* NOTE: Needs more testing (As we curretnly have no official test data for this) */
911
912           double xfov = 2.0f * atanf(aspect * tanf(DEG2RADF(yfov) * 0.5f));
913           cam->lens = fov_to_focallength(xfov, cam->sensor_x);
914         } break;
915       }
916     } break;
917     /* XXX correct way to do following four is probably to get also render
918      * size and determine proper settings from that somehow */
919     case COLLADAFW::Camera::ASPECTRATIO_AND_X:
920     case COLLADAFW::Camera::SINGLE_X:
921     case COLLADAFW::Camera::X_AND_Y: {
922       switch (cam->type) {
923         case CAM_ORTHO:
924           cam->ortho_scale = (float)camera->getXMag().getValue() * 2;
925           break;
926         case CAM_PERSP:
927         default: {
928           double x = camera->getXFov().getValue();
929           /* x is in degrees, cam->lens is in millimiters */
930           cam->lens = fov_to_focallength(DEG2RADF(x), cam->sensor_x);
931         } break;
932       }
933     } break;
934     case COLLADAFW::Camera::SINGLE_Y: {
935       switch (cam->type) {
936         case CAM_ORTHO:
937           cam->ortho_scale = (float)camera->getYMag().getValue();
938           break;
939         case CAM_PERSP:
940         default: {
941           double yfov = camera->getYFov().getValue();
942           /* yfov is in degrees, cam->lens is in millimiters */
943           cam->lens = fov_to_focallength(DEG2RADF(yfov), cam->sensor_x);
944         } break;
945       }
946     } break;
947     case COLLADAFW::Camera::UNDEFINED:
948       /* read nothing, use blender defaults. */
949       break;
950   }
951
952   this->uid_camera_map[camera->getUniqueId()] = cam;
953   this->FW_object_map[camera->getUniqueId()] = camera;
954   /* XXX import camera options */
955   return true;
956 }
957
958 /** When this method is called, the writer must write the image.
959  * \return The writer should return true, if writing succeeded, false otherwise.*/
960 bool DocumentImporter::writeImage(const COLLADAFW::Image *image)
961 {
962   if (mImportStage == Fetching_Controller_data) {
963     return true;
964   }
965
966   const std::string &imagepath = image->getImageURI().toNativePath();
967
968   char dir[FILE_MAX];
969   char absolute_path[FILE_MAX];
970   const char *workpath;
971
972   BLI_split_dir_part(this->import_settings->filepath, dir, sizeof(dir));
973   BLI_join_dirfile(absolute_path, sizeof(absolute_path), dir, imagepath.c_str());
974   if (BLI_exists(absolute_path)) {
975     workpath = absolute_path;
976   }
977   else {
978     /* Maybe imagepath was already absolute ? */
979     if (!BLI_exists(imagepath.c_str())) {
980       fprintf(stderr, "|! Image not found: %s\n", imagepath.c_str());
981       return true;
982     }
983     workpath = imagepath.c_str();
984   }
985
986   Image *ima = BKE_image_load_exists(CTX_data_main(mContext), workpath);
987   if (!ima) {
988     fprintf(stderr, "|! Cannot create image: %s\n", workpath);
989     return true;
990   }
991   this->uid_image_map[image->getUniqueId()] = ima;
992   fprintf(stderr, "| import Image: %s\n", workpath);
993   return true;
994 }
995
996 /** When this method is called, the writer must write the light.
997  * \return The writer should return true, if writing succeeded, false otherwise.*/
998 bool DocumentImporter::writeLight(const COLLADAFW::Light *light)
999 {
1000   if (mImportStage == Fetching_Controller_data) {
1001     return true;
1002   }
1003
1004   Main *bmain = CTX_data_main(mContext);
1005   Light *lamp = NULL;
1006   std::string la_id, la_name;
1007
1008   ExtraTags *et = getExtraTags(light->getUniqueId());
1009 #if 0
1010   TagsMap::iterator etit;
1011   ExtraTags *et = 0;
1012   etit = uid_tags_map.find(light->getUniqueId().toAscii());
1013   if (etit != uid_tags_map.end()) {
1014     et = etit->second;
1015   }
1016 #endif
1017
1018   la_id = light->getOriginalId();
1019   la_name = light->getName();
1020   if (la_name.size()) {
1021     lamp = (Light *)BKE_light_add(bmain, (char *)la_name.c_str());
1022   }
1023   else {
1024     lamp = (Light *)BKE_light_add(bmain, (char *)la_id.c_str());
1025   }
1026
1027   if (!lamp) {
1028     fprintf(stderr, "Cannot create light.\n");
1029     return true;
1030   }
1031
1032   /* if we find an ExtraTags for this, use that instead. */
1033   if (et && et->isProfile("blender")) {
1034     et->setData("type", &(lamp->type));
1035     et->setData("flag", &(lamp->flag));
1036     et->setData("mode", &(lamp->mode));
1037     et->setData("gamma", &(lamp->k));
1038     et->setData("red", &(lamp->r));
1039     et->setData("green", &(lamp->g));
1040     et->setData("blue", &(lamp->b));
1041     et->setData("shadow_r", &(lamp->shdwr));
1042     et->setData("shadow_g", &(lamp->shdwg));
1043     et->setData("shadow_b", &(lamp->shdwb));
1044     et->setData("energy", &(lamp->energy));
1045     et->setData("dist", &(lamp->dist));
1046     et->setData("spotsize", &(lamp->spotsize));
1047     lamp->spotsize = DEG2RADF(lamp->spotsize);
1048     et->setData("spotblend", &(lamp->spotblend));
1049     et->setData("att1", &(lamp->att1));
1050     et->setData("att2", &(lamp->att2));
1051     et->setData("falloff_type", &(lamp->falloff_type));
1052     et->setData("clipsta", &(lamp->clipsta));
1053     et->setData("clipend", &(lamp->clipend));
1054     et->setData("bias", &(lamp->bias));
1055     et->setData("soft", &(lamp->soft));
1056     et->setData("bufsize", &(lamp->bufsize));
1057     et->setData("buffers", &(lamp->buffers));
1058     et->setData("area_shape", &(lamp->area_shape));
1059     et->setData("area_size", &(lamp->area_size));
1060     et->setData("area_sizey", &(lamp->area_sizey));
1061     et->setData("area_sizez", &(lamp->area_sizez));
1062   }
1063   else {
1064     float constatt = light->getConstantAttenuation().getValue();
1065     float linatt = light->getLinearAttenuation().getValue();
1066     float quadatt = light->getQuadraticAttenuation().getValue();
1067     float d = 25.0f;
1068     float att1 = 0.0f;
1069     float att2 = 0.0f;
1070     float e = 1.0f;
1071
1072     if (light->getColor().isValid()) {
1073       COLLADAFW::Color col = light->getColor();
1074       lamp->r = col.getRed();
1075       lamp->g = col.getGreen();
1076       lamp->b = col.getBlue();
1077     }
1078
1079     if (IS_EQ(linatt, 0.0f) && quadatt > 0.0f) {
1080       att2 = quadatt;
1081       d = sqrt(1.0f / quadatt);
1082     }
1083     /* linear light */
1084     else if (IS_EQ(quadatt, 0.0f) && linatt > 0.0f) {
1085       att1 = linatt;
1086       d = (1.0f / linatt);
1087     }
1088     else if (IS_EQ(constatt, 1.0f)) {
1089       att1 = 1.0f;
1090     }
1091     else {
1092       /* assuming point light (const att = 1.0); */
1093       att1 = 1.0f;
1094     }
1095
1096     d *= (1.0f / unit_converter.getLinearMeter());
1097
1098     lamp->energy = e;
1099     lamp->dist = d;
1100
1101     switch (light->getLightType()) {
1102       case COLLADAFW::Light::AMBIENT_LIGHT: {
1103         lamp->type = LA_SUN;  // TODO needs more thoughts
1104       } break;
1105       case COLLADAFW::Light::SPOT_LIGHT: {
1106         lamp->type = LA_SPOT;
1107         lamp->att1 = att1;
1108         lamp->att2 = att2;
1109         if (IS_EQ(att1, 0.0f) && att2 > 0) {
1110           lamp->falloff_type = LA_FALLOFF_INVSQUARE;
1111         }
1112         if (IS_EQ(att2, 0.0f) && att1 > 0) {
1113           lamp->falloff_type = LA_FALLOFF_INVLINEAR;
1114         }
1115         lamp->spotsize = DEG2RADF(light->getFallOffAngle().getValue());
1116         lamp->spotblend = light->getFallOffExponent().getValue();
1117       } break;
1118       case COLLADAFW::Light::DIRECTIONAL_LIGHT: {
1119         /* our sun is very strong, so pick a smaller energy level */
1120         lamp->type = LA_SUN;
1121       } break;
1122       case COLLADAFW::Light::POINT_LIGHT: {
1123         lamp->type = LA_LOCAL;
1124         lamp->att1 = att1;
1125         lamp->att2 = att2;
1126         if (IS_EQ(att1, 0.0f) && att2 > 0) {
1127           lamp->falloff_type = LA_FALLOFF_INVSQUARE;
1128         }
1129         if (IS_EQ(att2, 0.0f) && att1 > 0) {
1130           lamp->falloff_type = LA_FALLOFF_INVLINEAR;
1131         }
1132       } break;
1133       case COLLADAFW::Light::UNDEFINED: {
1134         fprintf(stderr, "Current light type is not supported.\n");
1135         lamp->type = LA_LOCAL;
1136       } break;
1137     }
1138   }
1139
1140   this->uid_light_map[light->getUniqueId()] = lamp;
1141   this->FW_object_map[light->getUniqueId()] = light;
1142   return true;
1143 }
1144
1145 /* this function is called only for animations that pass COLLADAFW::validate */
1146 bool DocumentImporter::writeAnimation(const COLLADAFW::Animation *anim)
1147 {
1148   if (mImportStage == Fetching_Controller_data) {
1149     return true;
1150   }
1151
1152   return anim_importer.write_animation(anim);
1153 }
1154
1155 /* called on post-process stage after writeVisualScenes */
1156 bool DocumentImporter::writeAnimationList(const COLLADAFW::AnimationList *animationList)
1157 {
1158   if (mImportStage == Fetching_Controller_data) {
1159     return true;
1160   }
1161
1162   /* return true; */
1163   return anim_importer.write_animation_list(animationList);
1164 }
1165
1166 #if WITH_OPENCOLLADA_ANIMATION_CLIP
1167 /* Since opencollada 1.6.68
1168  * called on post-process stage after writeVisualScenes */
1169 bool DocumentImporter::writeAnimationClip(const COLLADAFW::AnimationClip *animationClip)
1170 {
1171   if (mImportStage == Fetching_Controller_data) {
1172     return true;
1173   }
1174
1175   return true;
1176   /* TODO: implement import of AnimationClips */
1177   // return animation_clip_importer.write_animation_clip(animationClip);
1178 }
1179 #endif
1180
1181 /** When this method is called, the writer must write the skin controller data.
1182  * \return The writer should return true, if writing succeeded, false otherwise.*/
1183 bool DocumentImporter::writeSkinControllerData(const COLLADAFW::SkinControllerData *skin)
1184 {
1185   return armature_importer.write_skin_controller_data(skin);
1186 }
1187
1188 /* this is called on postprocess, before writeVisualScenes */
1189 bool DocumentImporter::writeController(const COLLADAFW::Controller *controller)
1190 {
1191   if (mImportStage == Fetching_Controller_data) {
1192     return true;
1193   }
1194
1195   return armature_importer.write_controller(controller);
1196 }
1197
1198 bool DocumentImporter::writeFormulas(const COLLADAFW::Formulas *formulas)
1199 {
1200   return true;
1201 }
1202
1203 bool DocumentImporter::writeKinematicsScene(const COLLADAFW::KinematicsScene *kinematicsScene)
1204 {
1205   return true;
1206 }
1207
1208 ExtraTags *DocumentImporter::getExtraTags(const COLLADAFW::UniqueId &uid)
1209 {
1210   if (uid_tags_map.find(uid.toAscii()) == uid_tags_map.end()) {
1211     return NULL;
1212   }
1213   return uid_tags_map[uid.toAscii()];
1214 }
1215
1216 bool DocumentImporter::addExtraTags(const COLLADAFW::UniqueId &uid, ExtraTags *extra_tags)
1217 {
1218   uid_tags_map[uid.toAscii()] = extra_tags;
1219   return true;
1220 }
1221
1222 bool DocumentImporter::is_armature(COLLADAFW::Node *node)
1223 {
1224   COLLADAFW::NodePointerArray &child_nodes = node->getChildNodes();
1225   for (unsigned int i = 0; i < child_nodes.getCount(); i++) {
1226     if (child_nodes[i]->getType() == COLLADAFW::Node::JOINT) {
1227       return true;
1228     }
1229     else {
1230       continue;
1231     }
1232   }
1233
1234   /* no child is JOINT */
1235   return false;
1236 }