update Collada Importer: reworked export and import of Materials
[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
800   /* Direct mapping to principled BSDF Shader */
801   matNode.set_diffuse(ef->getDiffuse());
802   matNode.set_emission(ef->getEmission());
803   matNode.set_ior(ef->getIndexOfRefraction());
804   matNode.set_alpha(ef->getOpaqueMode(), ef->getTransparent(), ef->getTransparency());
805
806   /* following mapping still needs to be verified */
807   matNode.set_shininess(ef->getShininess());
808   matNode.set_reflectivity(ef->getReflectivity());
809
810   /* not supported by principled BSDF */
811   matNode.set_ambient(ef->getAmbient());
812   matNode.set_specular(ef->getSpecular());
813   matNode.set_reflective(ef->getReflective());
814 }
815
816 /** When this method is called, the writer must write the effect.
817  * \return The writer should return true, if writing succeeded, false otherwise.*/
818
819 bool DocumentImporter::writeEffect(const COLLADAFW::Effect *effect)
820 {
821   if (mImportStage == Fetching_Controller_data) {
822     return true;
823   }
824
825   const COLLADAFW::UniqueId &uid = effect->getUniqueId();
826
827   if (uid_effect_map.find(uid) == uid_effect_map.end()) {
828     fprintf(stderr, "Couldn't find a material by UID.\n");
829     return true;
830   }
831
832   Material *ma = uid_effect_map[uid];
833   std::map<COLLADAFW::UniqueId, Material *>::iterator iter;
834   for (iter = uid_material_map.begin(); iter != uid_material_map.end(); iter++) {
835     if (iter->second == ma) {
836       this->FW_object_map[iter->first] = effect;
837       break;
838     }
839   }
840   COLLADAFW::CommonEffectPointerArray common_efs = effect->getCommonEffects();
841   if (common_efs.getCount() < 1) {
842     fprintf(stderr, "Couldn't find <profile_COMMON>.\n");
843     return true;
844   }
845   /* XXX TODO: Take all <profile_common>s
846    * Currently only first <profile_common> is supported */
847   COLLADAFW::EffectCommon *ef = common_efs[0];
848   write_profile_COMMON(ef, ma);
849   this->FW_object_map[effect->getUniqueId()] = effect;
850
851   return true;
852 }
853
854 /** When this method is called, the writer must write the camera.
855  * \return The writer should return true, if writing succeeded, false otherwise.*/
856 bool DocumentImporter::writeCamera(const COLLADAFW::Camera *camera)
857 {
858   if (mImportStage == Fetching_Controller_data) {
859     return true;
860   }
861
862   Main *bmain = CTX_data_main(mContext);
863   Camera *cam = NULL;
864   std::string cam_id, cam_name;
865
866   ExtraTags *et = getExtraTags(camera->getUniqueId());
867   cam_id = camera->getOriginalId();
868   cam_name = camera->getName();
869   if (cam_name.size()) {
870     cam = (Camera *)BKE_camera_add(bmain, (char *)cam_name.c_str());
871   }
872   else {
873     cam = (Camera *)BKE_camera_add(bmain, (char *)cam_id.c_str());
874   }
875
876   if (!cam) {
877     fprintf(stderr, "Cannot create camera.\n");
878     return true;
879   }
880
881   if (et && et->isProfile("blender")) {
882     et->setData("shiftx", &(cam->shiftx));
883     et->setData("shifty", &(cam->shifty));
884     et->setData("dof_distance", &(cam->dof.focus_distance));
885   }
886   cam->clip_start = camera->getNearClippingPlane().getValue();
887   cam->clip_end = camera->getFarClippingPlane().getValue();
888
889   COLLADAFW::Camera::CameraType type = camera->getCameraType();
890   switch (type) {
891     case COLLADAFW::Camera::ORTHOGRAPHIC: {
892       cam->type = CAM_ORTHO;
893     } break;
894     case COLLADAFW::Camera::PERSPECTIVE: {
895       cam->type = CAM_PERSP;
896     } break;
897     case COLLADAFW::Camera::UNDEFINED_CAMERATYPE: {
898       fprintf(stderr, "Current camera type is not supported.\n");
899       cam->type = CAM_PERSP;
900     } break;
901   }
902
903   switch (camera->getDescriptionType()) {
904     case COLLADAFW::Camera::ASPECTRATIO_AND_Y: {
905       switch (cam->type) {
906         case CAM_ORTHO: {
907           double ymag = 2 * camera->getYMag().getValue();
908           double aspect = camera->getAspectRatio().getValue();
909           double xmag = aspect * ymag;
910           cam->ortho_scale = (float)xmag;
911         } break;
912         case CAM_PERSP:
913         default: {
914           double yfov = camera->getYFov().getValue();
915           double aspect = camera->getAspectRatio().getValue();
916
917           /* NOTE: Needs more testing (As we curretnly have no official test data for this) */
918
919           double xfov = 2.0f * atanf(aspect * tanf(DEG2RADF(yfov) * 0.5f));
920           cam->lens = fov_to_focallength(xfov, cam->sensor_x);
921         } break;
922       }
923     } break;
924     /* XXX correct way to do following four is probably to get also render
925      * size and determine proper settings from that somehow */
926     case COLLADAFW::Camera::ASPECTRATIO_AND_X:
927     case COLLADAFW::Camera::SINGLE_X:
928     case COLLADAFW::Camera::X_AND_Y: {
929       switch (cam->type) {
930         case CAM_ORTHO:
931           cam->ortho_scale = (float)camera->getXMag().getValue() * 2;
932           break;
933         case CAM_PERSP:
934         default: {
935           double x = camera->getXFov().getValue();
936           /* x is in degrees, cam->lens is in millimiters */
937           cam->lens = fov_to_focallength(DEG2RADF(x), cam->sensor_x);
938         } break;
939       }
940     } break;
941     case COLLADAFW::Camera::SINGLE_Y: {
942       switch (cam->type) {
943         case CAM_ORTHO:
944           cam->ortho_scale = (float)camera->getYMag().getValue();
945           break;
946         case CAM_PERSP:
947         default: {
948           double yfov = camera->getYFov().getValue();
949           /* yfov is in degrees, cam->lens is in millimiters */
950           cam->lens = fov_to_focallength(DEG2RADF(yfov), cam->sensor_x);
951         } break;
952       }
953     } break;
954     case COLLADAFW::Camera::UNDEFINED:
955       /* read nothing, use blender defaults. */
956       break;
957   }
958
959   this->uid_camera_map[camera->getUniqueId()] = cam;
960   this->FW_object_map[camera->getUniqueId()] = camera;
961   /* XXX import camera options */
962   return true;
963 }
964
965 /** When this method is called, the writer must write the image.
966  * \return The writer should return true, if writing succeeded, false otherwise.*/
967 bool DocumentImporter::writeImage(const COLLADAFW::Image *image)
968 {
969   if (mImportStage == Fetching_Controller_data) {
970     return true;
971   }
972
973   const std::string &imagepath = image->getImageURI().toNativePath();
974
975   char dir[FILE_MAX];
976   char absolute_path[FILE_MAX];
977   const char *workpath;
978
979   BLI_split_dir_part(this->import_settings->filepath, dir, sizeof(dir));
980   BLI_join_dirfile(absolute_path, sizeof(absolute_path), dir, imagepath.c_str());
981   if (BLI_exists(absolute_path)) {
982     workpath = absolute_path;
983   }
984   else {
985     /* Maybe imagepath was already absolute ? */
986     if (!BLI_exists(imagepath.c_str())) {
987       fprintf(stderr, "|! Image not found: %s\n", imagepath.c_str());
988       return true;
989     }
990     workpath = imagepath.c_str();
991   }
992
993   Image *ima = BKE_image_load_exists(CTX_data_main(mContext), workpath);
994   if (!ima) {
995     fprintf(stderr, "|! Cannot create image: %s\n", workpath);
996     return true;
997   }
998   this->uid_image_map[image->getUniqueId()] = ima;
999   fprintf(stderr, "| import Image: %s\n", workpath);
1000   return true;
1001 }
1002
1003 /** When this method is called, the writer must write the light.
1004  * \return The writer should return true, if writing succeeded, false otherwise.*/
1005 bool DocumentImporter::writeLight(const COLLADAFW::Light *light)
1006 {
1007   if (mImportStage == Fetching_Controller_data) {
1008     return true;
1009   }
1010
1011   Main *bmain = CTX_data_main(mContext);
1012   Light *lamp = NULL;
1013   std::string la_id, la_name;
1014
1015   ExtraTags *et = getExtraTags(light->getUniqueId());
1016 #if 0
1017   TagsMap::iterator etit;
1018   ExtraTags *et = 0;
1019   etit = uid_tags_map.find(light->getUniqueId().toAscii());
1020   if (etit != uid_tags_map.end()) {
1021     et = etit->second;
1022   }
1023 #endif
1024
1025   la_id = light->getOriginalId();
1026   la_name = light->getName();
1027   if (la_name.size()) {
1028     lamp = (Light *)BKE_light_add(bmain, (char *)la_name.c_str());
1029   }
1030   else {
1031     lamp = (Light *)BKE_light_add(bmain, (char *)la_id.c_str());
1032   }
1033
1034   if (!lamp) {
1035     fprintf(stderr, "Cannot create light.\n");
1036     return true;
1037   }
1038
1039   /* if we find an ExtraTags for this, use that instead. */
1040   if (et && et->isProfile("blender")) {
1041     et->setData("type", &(lamp->type));
1042     et->setData("flag", &(lamp->flag));
1043     et->setData("mode", &(lamp->mode));
1044     et->setData("gamma", &(lamp->k));
1045     et->setData("red", &(lamp->r));
1046     et->setData("green", &(lamp->g));
1047     et->setData("blue", &(lamp->b));
1048     et->setData("shadow_r", &(lamp->shdwr));
1049     et->setData("shadow_g", &(lamp->shdwg));
1050     et->setData("shadow_b", &(lamp->shdwb));
1051     et->setData("energy", &(lamp->energy));
1052     et->setData("dist", &(lamp->dist));
1053     et->setData("spotsize", &(lamp->spotsize));
1054     lamp->spotsize = DEG2RADF(lamp->spotsize);
1055     et->setData("spotblend", &(lamp->spotblend));
1056     et->setData("att1", &(lamp->att1));
1057     et->setData("att2", &(lamp->att2));
1058     et->setData("falloff_type", &(lamp->falloff_type));
1059     et->setData("clipsta", &(lamp->clipsta));
1060     et->setData("clipend", &(lamp->clipend));
1061     et->setData("bias", &(lamp->bias));
1062     et->setData("soft", &(lamp->soft));
1063     et->setData("bufsize", &(lamp->bufsize));
1064     et->setData("buffers", &(lamp->buffers));
1065     et->setData("area_shape", &(lamp->area_shape));
1066     et->setData("area_size", &(lamp->area_size));
1067     et->setData("area_sizey", &(lamp->area_sizey));
1068     et->setData("area_sizez", &(lamp->area_sizez));
1069   }
1070   else {
1071     float constatt = light->getConstantAttenuation().getValue();
1072     float linatt = light->getLinearAttenuation().getValue();
1073     float quadatt = light->getQuadraticAttenuation().getValue();
1074     float d = 25.0f;
1075     float att1 = 0.0f;
1076     float att2 = 0.0f;
1077     float e = 1.0f;
1078
1079     if (light->getColor().isValid()) {
1080       COLLADAFW::Color col = light->getColor();
1081       lamp->r = col.getRed();
1082       lamp->g = col.getGreen();
1083       lamp->b = col.getBlue();
1084     }
1085
1086     if (IS_EQ(linatt, 0.0f) && quadatt > 0.0f) {
1087       att2 = quadatt;
1088       d = sqrt(1.0f / quadatt);
1089     }
1090     /* linear light */
1091     else if (IS_EQ(quadatt, 0.0f) && linatt > 0.0f) {
1092       att1 = linatt;
1093       d = (1.0f / linatt);
1094     }
1095     else if (IS_EQ(constatt, 1.0f)) {
1096       att1 = 1.0f;
1097     }
1098     else {
1099       /* assuming point light (const att = 1.0); */
1100       att1 = 1.0f;
1101     }
1102
1103     d *= (1.0f / unit_converter.getLinearMeter());
1104
1105     lamp->energy = e;
1106     lamp->dist = d;
1107
1108     switch (light->getLightType()) {
1109       case COLLADAFW::Light::AMBIENT_LIGHT: {
1110         lamp->type = LA_SUN;  // TODO needs more thoughts
1111       } break;
1112       case COLLADAFW::Light::SPOT_LIGHT: {
1113         lamp->type = LA_SPOT;
1114         lamp->att1 = att1;
1115         lamp->att2 = att2;
1116         if (IS_EQ(att1, 0.0f) && att2 > 0) {
1117           lamp->falloff_type = LA_FALLOFF_INVSQUARE;
1118         }
1119         if (IS_EQ(att2, 0.0f) && att1 > 0) {
1120           lamp->falloff_type = LA_FALLOFF_INVLINEAR;
1121         }
1122         lamp->spotsize = DEG2RADF(light->getFallOffAngle().getValue());
1123         lamp->spotblend = light->getFallOffExponent().getValue();
1124       } break;
1125       case COLLADAFW::Light::DIRECTIONAL_LIGHT: {
1126         /* our sun is very strong, so pick a smaller energy level */
1127         lamp->type = LA_SUN;
1128       } break;
1129       case COLLADAFW::Light::POINT_LIGHT: {
1130         lamp->type = LA_LOCAL;
1131         lamp->att1 = att1;
1132         lamp->att2 = att2;
1133         if (IS_EQ(att1, 0.0f) && att2 > 0) {
1134           lamp->falloff_type = LA_FALLOFF_INVSQUARE;
1135         }
1136         if (IS_EQ(att2, 0.0f) && att1 > 0) {
1137           lamp->falloff_type = LA_FALLOFF_INVLINEAR;
1138         }
1139       } break;
1140       case COLLADAFW::Light::UNDEFINED: {
1141         fprintf(stderr, "Current light type is not supported.\n");
1142         lamp->type = LA_LOCAL;
1143       } break;
1144     }
1145   }
1146
1147   this->uid_light_map[light->getUniqueId()] = lamp;
1148   this->FW_object_map[light->getUniqueId()] = light;
1149   return true;
1150 }
1151
1152 /* this function is called only for animations that pass COLLADAFW::validate */
1153 bool DocumentImporter::writeAnimation(const COLLADAFW::Animation *anim)
1154 {
1155   if (mImportStage == Fetching_Controller_data) {
1156     return true;
1157   }
1158
1159   return anim_importer.write_animation(anim);
1160 }
1161
1162 /* called on post-process stage after writeVisualScenes */
1163 bool DocumentImporter::writeAnimationList(const COLLADAFW::AnimationList *animationList)
1164 {
1165   if (mImportStage == Fetching_Controller_data) {
1166     return true;
1167   }
1168
1169   /* return true; */
1170   return anim_importer.write_animation_list(animationList);
1171 }
1172
1173 #if WITH_OPENCOLLADA_ANIMATION_CLIP
1174 /* Since opencollada 1.6.68
1175  * called on post-process stage after writeVisualScenes */
1176 bool DocumentImporter::writeAnimationClip(const COLLADAFW::AnimationClip *animationClip)
1177 {
1178   if (mImportStage == Fetching_Controller_data) {
1179     return true;
1180   }
1181
1182   return true;
1183   /* TODO: implement import of AnimationClips */
1184   // return animation_clip_importer.write_animation_clip(animationClip);
1185 }
1186 #endif
1187
1188 /** When this method is called, the writer must write the skin controller data.
1189  * \return The writer should return true, if writing succeeded, false otherwise.*/
1190 bool DocumentImporter::writeSkinControllerData(const COLLADAFW::SkinControllerData *skin)
1191 {
1192   return armature_importer.write_skin_controller_data(skin);
1193 }
1194
1195 /* this is called on postprocess, before writeVisualScenes */
1196 bool DocumentImporter::writeController(const COLLADAFW::Controller *controller)
1197 {
1198   if (mImportStage == Fetching_Controller_data) {
1199     return true;
1200   }
1201
1202   return armature_importer.write_controller(controller);
1203 }
1204
1205 bool DocumentImporter::writeFormulas(const COLLADAFW::Formulas *formulas)
1206 {
1207   return true;
1208 }
1209
1210 bool DocumentImporter::writeKinematicsScene(const COLLADAFW::KinematicsScene *kinematicsScene)
1211 {
1212   return true;
1213 }
1214
1215 ExtraTags *DocumentImporter::getExtraTags(const COLLADAFW::UniqueId &uid)
1216 {
1217   if (uid_tags_map.find(uid.toAscii()) == uid_tags_map.end()) {
1218     return NULL;
1219   }
1220   return uid_tags_map[uid.toAscii()];
1221 }
1222
1223 bool DocumentImporter::addExtraTags(const COLLADAFW::UniqueId &uid, ExtraTags *extra_tags)
1224 {
1225   uid_tags_map[uid.toAscii()] = extra_tags;
1226   return true;
1227 }
1228
1229 bool DocumentImporter::is_armature(COLLADAFW::Node *node)
1230 {
1231   COLLADAFW::NodePointerArray &child_nodes = node->getChildNodes();
1232   for (unsigned int i = 0; i < child_nodes.getCount(); i++) {
1233     if (child_nodes[i]->getType() == COLLADAFW::Node::JOINT) {
1234       return true;
1235     }
1236     else {
1237       continue;
1238     }
1239   }
1240
1241   /* no child is JOINT */
1242   return false;
1243 }