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