Merge branch 'master' into blender2.8
[blender.git] / source / blender / collada / collada_utils.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Nathan Letwory.
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 /** \file blender/collada/collada_utils.cpp
24  *  \ingroup collada
25  */
26
27
28 /* COLLADABU_ASSERT, may be able to remove later */
29 #include "COLLADABUPlatform.h"
30
31 #include "COLLADAFWGeometry.h"
32 #include "COLLADAFWMeshPrimitive.h"
33 #include "COLLADAFWMeshVertexData.h"
34
35 #include <set>
36 #include <string>
37 extern "C" {
38 #include "DNA_modifier_types.h"
39 #include "DNA_customdata_types.h"
40 #include "DNA_key_types.h"
41 #include "DNA_object_types.h"
42 #include "DNA_constraint_types.h"
43 #include "DNA_mesh_types.h"
44 #include "DNA_scene_types.h"
45 #include "DNA_armature_types.h"
46
47 #include "BLI_math.h"
48 #include "BLI_linklist.h"
49 #include "BLI_listbase.h"
50
51 #include "BKE_action.h"
52 #include "BKE_context.h"
53 #include "BKE_customdata.h"
54 #include "BKE_constraint.h"
55 #include "BKE_key.h"
56 #include "BKE_material.h"
57 #include "BKE_node.h"
58 #include "BKE_object.h"
59 #include "BKE_global.h"
60 #include "BKE_layer.h"
61 #include "BKE_library.h"
62 #include "BKE_mesh.h"
63 #include "BKE_mesh_runtime.h"
64 #include "BKE_object.h"
65 #include "BKE_scene.h"
66
67 #include "ED_armature.h"
68 #include "ED_screen.h"
69 #include "ED_node.h"
70
71 #include "MEM_guardedalloc.h"
72
73 #include "WM_api.h" // XXX hrm, see if we can do without this
74 #include "WM_types.h"
75
76 #include "bmesh.h"
77 #include "bmesh_tools.h"
78
79 #include "DEG_depsgraph.h"
80 #include "DEG_depsgraph_query.h"
81 #if 0
82 #include "NOD_common.h"
83 #endif
84 }
85
86 #include "collada_utils.h"
87 #include "ExportSettings.h"
88 #include "BlenderContext.h"
89
90 float bc_get_float_value(const COLLADAFW::FloatOrDoubleArray& array, unsigned int index)
91 {
92         if (index >= array.getValuesCount())
93                 return 0.0f;
94
95         if (array.getType() == COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT)
96                 return array.getFloatValues()->getData()[index];
97         else
98                 return array.getDoubleValues()->getData()[index];
99 }
100
101 // copied from /editors/object/object_relations.c
102 int bc_test_parent_loop(Object *par, Object *ob)
103 {
104         /* test if 'ob' is a parent somewhere in par's parents */
105
106         if (par == NULL) return 0;
107         if (ob == par) return 1;
108
109         return bc_test_parent_loop(par->parent, ob);
110 }
111
112 void bc_get_children(std::vector<Object *> &child_set, Object *ob, ViewLayer *view_layer)
113 {
114         Base *base;
115         for (base = (Base *)view_layer->object_bases.first; base; base = base->next) {
116                 Object *cob = base->object;
117                 if (cob->parent == ob) {
118                         switch (ob->type) {
119                         case OB_MESH:
120                         case OB_CAMERA:
121                         case OB_LAMP:
122                         case OB_EMPTY:
123                         case OB_ARMATURE:
124                                 child_set.push_back(cob);
125                         default: break;
126                         }
127                 }
128         }
129 }
130
131 bool bc_validateConstraints(bConstraint *con)
132 {
133         const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
134
135         /* these we can skip completely (invalid constraints...) */
136         if (cti == NULL)
137                 return false;
138         if (con->flag & (CONSTRAINT_DISABLE | CONSTRAINT_OFF))
139                 return false;
140
141         /* these constraints can't be evaluated anyway */
142         if (cti->evaluate_constraint == NULL)
143                 return false;
144
145         /* influence == 0 should be ignored */
146         if (con->enforce == 0.0f)
147                 return false;
148
149         /* validation passed */
150         return true;
151 }
152
153 // a shortened version of parent_set_exec()
154 // if is_parent_space is true then ob->obmat will be multiplied by par->obmat before parenting
155 int bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space)
156 {
157         Object workob;
158         Depsgraph *depsgraph = CTX_data_depsgraph(C);
159         Scene *sce = CTX_data_scene(C);
160
161         if (!par || bc_test_parent_loop(par, ob))
162                 return false;
163
164         ob->parent = par;
165         ob->partype = PAROBJECT;
166
167         ob->parsubstr[0] = 0;
168
169         if (is_parent_space) {
170                 float mat[4][4];
171                 // calc par->obmat
172                 BKE_object_where_is_calc(depsgraph, sce, par);
173
174                 // move child obmat into world space
175                 mul_m4_m4m4(mat, par->obmat, ob->obmat);
176                 copy_m4_m4(ob->obmat, mat);
177         }
178
179         // apply child obmat (i.e. decompose it into rot/loc/size)
180         BKE_object_apply_mat4(ob, ob->obmat, 0, 0);
181
182         // compute parentinv
183         BKE_object_workob_calc_parent(depsgraph, sce, ob, &workob);
184         invert_m4_m4(ob->parentinv, workob.obmat);
185
186         DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA);
187         DEG_id_tag_update(&par->id, OB_RECALC_OB);
188
189         return true;
190 }
191
192 std::vector<bAction *> bc_getSceneActions(const bContext *C, Object *ob, bool all_actions)
193 {
194         std::vector<bAction *> actions;
195         if (all_actions) {
196                 Main *bmain = CTX_data_main(C);
197                 ID *id;
198
199                 for (id = (ID *)bmain->action.first; id; id = (ID *)(id->next)) {
200                         bAction *act = (bAction *)id;
201                         /* XXX This currently creates too many actions.
202                            TODO Need to check if the action is compatible to the given object
203                         */
204                         actions.push_back(act);
205                 }
206         }
207         else
208         {
209                 bAction *action = bc_getSceneObjectAction(ob);
210                 actions.push_back(action);
211         }
212
213         return actions;
214 }
215
216 std::string bc_get_action_id(std::string action_name, std::string ob_name, std::string channel_type, std::string axis_name, std::string axis_separator)
217 {
218         std::string result = action_name + "_" + channel_type;
219         if (ob_name.length() > 0)
220                 result = ob_name + "_" + result;
221         if (axis_name.length() > 0)
222                 result += axis_separator + axis_name;
223         return translate_id(result);
224 }
225
226 void bc_update_scene(BlenderContext &blender_context, float ctime)
227 {
228         Main *bmain = blender_context.get_main();
229         Scene *scene = blender_context.get_scene();
230         Depsgraph *depsgraph = blender_context.get_depsgraph();
231
232         /*
233          * See remark in physics_fluid.c lines 395...)
234          * BKE_scene_update_for_newframe(ev_context, bmain, scene, scene->lay);
235         */
236         BKE_scene_frame_set(scene, ctime);
237         ED_update_for_newframe(bmain, depsgraph);
238 }
239
240 Object *bc_add_object(Main *bmain, Scene *scene, ViewLayer *view_layer, int type, const char *name)
241 {
242         Object *ob = BKE_object_add_only_object(bmain, type, name);
243
244         ob->data = BKE_object_obdata_add_from_type(bmain, type, name);
245         ob->lay = scene->lay;
246         DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
247
248         LayerCollection *layer_collection = BKE_layer_collection_get_active(view_layer);
249         BKE_collection_object_add(bmain, layer_collection->collection, ob);
250
251         Base *base = BKE_view_layer_base_find(view_layer, ob);
252         /* TODO: is setting active needed? */
253         BKE_view_layer_base_select_and_set_active(view_layer, base);
254
255         return ob;
256 }
257
258 Mesh *bc_get_mesh_copy(
259     BlenderContext &blender_context,
260         Object *ob,
261         BC_export_mesh_type export_mesh_type,
262         bool apply_modifiers,
263         bool triangulate)
264 {
265         CustomDataMask mask = CD_MASK_MESH;
266         Mesh *mesh = (Mesh *)ob->data;
267         Mesh *tmpmesh = NULL;
268         if (apply_modifiers) {
269 #if 0  /* Not supported by new system currently... */
270                 switch (export_mesh_type) {
271                         case BC_MESH_TYPE_VIEW:
272                         {
273                                 dm = mesh_create_derived_view(depsgraph, scene, ob, mask);
274                                 break;
275                         }
276                         case BC_MESH_TYPE_RENDER:
277                         {
278                                 dm = mesh_create_derived_render(depsgraph, scene, ob, mask);
279                                 break;
280                         }
281                 }
282 #else
283                 Depsgraph *depsgraph = blender_context.get_depsgraph();
284                 Scene *scene = blender_context.get_scene();
285                 tmpmesh = mesh_get_eval_final(depsgraph, scene, ob, mask);
286 #endif
287         }
288         else {
289                 tmpmesh = mesh;
290         }
291
292         BKE_id_copy_ex(NULL, &tmpmesh->id, (ID **)&tmpmesh,
293                        LIB_ID_CREATE_NO_MAIN |
294                        LIB_ID_CREATE_NO_USER_REFCOUNT |
295                        LIB_ID_CREATE_NO_DEG_TAG |
296                        LIB_ID_COPY_NO_PREVIEW,
297                        false);
298
299         if (triangulate) {
300                 bc_triangulate_mesh(tmpmesh);
301         }
302         BKE_mesh_tessface_ensure(tmpmesh);
303         return tmpmesh;
304 }
305
306 Object *bc_get_assigned_armature(Object *ob)
307 {
308         Object *ob_arm = NULL;
309
310         if (ob->parent && ob->partype == PARSKEL && ob->parent->type == OB_ARMATURE) {
311                 ob_arm = ob->parent;
312         }
313         else {
314                 ModifierData *mod;
315                 for (mod = (ModifierData *)ob->modifiers.first; mod; mod = mod->next) {
316                         if (mod->type == eModifierType_Armature) {
317                                 ob_arm = ((ArmatureModifierData *)mod)->object;
318                         }
319                 }
320         }
321
322         return ob_arm;
323 }
324
325 /*
326 * Returns the highest selected ancestor
327 * returns NULL if no ancestor is selected
328 * IMPORTANT: This function expects that all exported objects have set:
329 * ob->id.tag & LIB_TAG_DOIT
330 */
331 Object *bc_get_highest_selected_ancestor_or_self(LinkNode *export_set, Object *ob)
332
333 {
334         Object *ancestor = ob;
335         while (ob->parent && bc_is_marked(ob->parent)) {
336                 ob = ob->parent;
337                 ancestor = ob;
338         }
339         return ancestor;
340 }
341
342 bool bc_is_base_node(LinkNode *export_set, Object *ob)
343 {
344         Object *root = bc_get_highest_selected_ancestor_or_self(export_set, ob);
345         return (root == ob);
346 }
347
348 bool bc_is_in_Export_set(LinkNode *export_set, Object *ob, ViewLayer *view_layer)
349 {
350         bool to_export = (BLI_linklist_index(export_set, ob) != -1);
351
352         if (!to_export)
353         {
354                 /* Mark this object as to_export even if it is not in the
355                 export list, but it contains children to export */
356
357                 std::vector<Object *> children;
358                 bc_get_children(children, ob, view_layer);
359                 for (int i = 0; i < children.size(); i++) {
360                         if (bc_is_in_Export_set(export_set, children[i], view_layer)) {
361                                 to_export = true;
362                                 break;
363                         }
364                 }
365         }
366         return to_export;
367 }
368
369 bool bc_has_object_type(LinkNode *export_set, short obtype)
370 {
371         LinkNode *node;
372
373         for (node = export_set; node; node = node->next) {
374                 Object *ob = (Object *)node->link;
375                 /* XXX - why is this checking for ob->data? - we could be looking for empties */
376                 if (ob->type == obtype && ob->data) {
377                         return true;
378                 }
379         }
380         return false;
381 }
382
383 int bc_is_marked(Object *ob)
384 {
385         return ob && (ob->id.tag & LIB_TAG_DOIT);
386 }
387
388 void bc_remove_mark(Object *ob)
389 {
390         ob->id.tag &= ~LIB_TAG_DOIT;
391 }
392
393 void bc_set_mark(Object *ob)
394 {
395         ob->id.tag |= LIB_TAG_DOIT;
396 }
397
398 // Use bubble sort algorithm for sorting the export set
399 void bc_bubble_sort_by_Object_name(LinkNode *export_set)
400 {
401         bool sorted = false;
402         LinkNode *node;
403         for (node = export_set; node->next && !sorted; node = node->next) {
404
405                 sorted = true;
406
407                 LinkNode *current;
408                 for (current = export_set; current->next; current = current->next) {
409                         Object *a = (Object *)current->link;
410                         Object *b = (Object *)current->next->link;
411
412                         if (strcmp(a->id.name, b->id.name) > 0) {
413                                 current->link       = b;
414                                 current->next->link = a;
415                                 sorted = false;
416                         }
417
418                 }
419         }
420 }
421
422 /* Check if a bone is the top most exportable bone in the bone hierarchy.
423  * When deform_bones_only == false, then only bones with NO parent
424  * can be root bones. Otherwise the top most deform bones in the hierarchy
425  * are root bones.
426  */
427 bool bc_is_root_bone(Bone *aBone, bool deform_bones_only)
428 {
429         if (deform_bones_only) {
430                 Bone *root = NULL;
431                 Bone *bone = aBone;
432                 while (bone) {
433                         if (!(bone->flag & BONE_NO_DEFORM))
434                                 root = bone;
435                         bone = bone->parent;
436                 }
437                 return (aBone == root);
438         }
439         else
440                 return !(aBone->parent);
441 }
442
443 int bc_get_active_UVLayer(Object *ob)
444 {
445         Mesh *me = (Mesh *)ob->data;
446         return CustomData_get_active_layer_index(&me->fdata, CD_MTFACE);
447 }
448
449 std::string bc_url_encode(std::string data)
450 {
451         /* XXX We probably do not need to do a full encoding.
452          * But in case that is necessary,then it can be added here.
453          */
454         return bc_replace_string(data,"#", "%23");
455 }
456
457 std::string bc_replace_string(std::string data, const std::string& pattern,
458                               const std::string& replacement)
459 {
460         size_t pos = 0;
461         while ((pos = data.find(pattern, pos)) != std::string::npos) {
462                 data.replace(pos, pattern.length(), replacement);
463                 pos += replacement.length();
464         }
465         return data;
466 }
467
468 /**
469  * Calculate a rescale factor such that the imported scene's scale
470  * is preserved. I.e. 1 meter in the import will also be
471  * 1 meter in the current scene.
472  */
473
474 void bc_match_scale(Object *ob, UnitConverter &bc_unit, bool scale_to_scene)
475 {
476         if (scale_to_scene) {
477                 mul_m4_m4m4(ob->obmat, bc_unit.get_scale(), ob->obmat);
478         }
479         mul_m4_m4m4(ob->obmat, bc_unit.get_rotation(), ob->obmat);
480         BKE_object_apply_mat4(ob, ob->obmat, 0, 0);
481 }
482
483 void bc_match_scale(std::vector<Object *> *objects_done,
484                         UnitConverter &bc_unit,
485                         bool scale_to_scene)
486 {
487         for (std::vector<Object *>::iterator it = objects_done->begin();
488                         it != objects_done->end();
489                         ++it)
490         {
491                 Object *ob = *it;
492                 if (ob -> parent == NULL) {
493                         bc_match_scale(*it, bc_unit, scale_to_scene);
494                 }
495         }
496 }
497
498 /*
499  * Convenience function to get only the needed components of a matrix
500  */
501 void bc_decompose(float mat[4][4], float *loc, float eul[3], float quat[4], float *size)
502 {
503         if (size) {
504                 mat4_to_size(size, mat);
505         }
506
507         if (eul) {
508                 mat4_to_eul(eul, mat);
509         }
510
511         if (quat) {
512                 mat4_to_quat(quat, mat);
513         }
514
515         if (loc) {
516                 copy_v3_v3(loc, mat[3]);
517         }
518 }
519
520 /*
521  * Create rotation_quaternion from a delta rotation and a reference quat
522  *
523  * Input:
524  * mat_from: The rotation matrix before rotation
525  * mat_to  : The rotation matrix after rotation
526  * qref    : the quat corresponding to mat_from
527  *
528  * Output:
529  * rot     : the calculated result (quaternion)
530  *
531  */
532 void bc_rotate_from_reference_quat(float quat_to[4], float quat_from[4], float mat_to[4][4])
533 {
534         float qd[4];
535         float matd[4][4];
536         float mati[4][4];
537         float mat_from[4][4];
538         quat_to_mat4(mat_from, quat_from);
539
540         // Calculate the difference matrix matd between mat_from and mat_to
541         invert_m4_m4(mati, mat_from);
542         mul_m4_m4m4(matd, mati, mat_to);
543
544         mat4_to_quat(qd, matd);
545
546         mul_qt_qtqt(quat_to, qd, quat_from); // rot is the final rotation corresponding to mat_to
547 }
548
549 void bc_triangulate_mesh(Mesh *me)
550 {
551         bool use_beauty  = false;
552         bool tag_only    = false;
553         int  quad_method = MOD_TRIANGULATE_QUAD_SHORTEDGE; /* XXX: The triangulation method selection could be offered in the UI */
554
555         const struct BMeshCreateParams bm_create_params = {0};
556         BMesh *bm = BM_mesh_create(
557                 &bm_mesh_allocsize_default,
558                 &bm_create_params);
559         BMeshFromMeshParams bm_from_me_params = {0};
560         bm_from_me_params.calc_face_normal = true;
561         BM_mesh_bm_from_me(bm, me, &bm_from_me_params);
562         BM_mesh_triangulate(bm, quad_method, use_beauty, tag_only, NULL, NULL, NULL);
563
564         BMeshToMeshParams bm_to_me_params = {0};
565         bm_to_me_params.calc_object_remap = false;
566         BM_mesh_bm_to_me(NULL, bm, me, &bm_to_me_params);
567         BM_mesh_free(bm);
568 }
569
570 /*
571  * A bone is a leaf when it has no children or all children are not connected.
572  */
573 bool bc_is_leaf_bone(Bone *bone)
574 {
575         for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) {
576                 if (child->flag & BONE_CONNECTED)
577                         return false;
578         }
579         return true;
580 }
581
582 EditBone *bc_get_edit_bone(bArmature * armature, char *name) {
583         EditBone  *eBone;
584
585         for (eBone = (EditBone *)armature->edbo->first; eBone; eBone = eBone->next) {
586                 if (STREQ(name, eBone->name))
587                         return eBone;
588         }
589
590         return NULL;
591
592 }
593 int bc_set_layer(int bitfield, int layer)
594 {
595         return bc_set_layer(bitfield, layer, true); /* enable */
596 }
597
598 int bc_set_layer(int bitfield, int layer, bool enable)
599 {
600         int bit = 1u << layer;
601
602         if (enable)
603                 bitfield |= bit;
604         else
605                 bitfield &= ~bit;
606
607         return bitfield;
608 }
609
610 /**
611  * This method creates a new extension map when needed.
612  * \note The ~BoneExtensionManager destructor takes care
613  * to delete the created maps when the manager is removed.
614  */
615 BoneExtensionMap &BoneExtensionManager::getExtensionMap(bArmature *armature)
616 {
617         std::string key = armature->id.name;
618         BoneExtensionMap *result = extended_bone_maps[key];
619         if (result == NULL)
620         {
621                 result = new BoneExtensionMap();
622                 extended_bone_maps[key] = result;
623         }
624         return *result;
625 }
626
627 BoneExtensionManager::~BoneExtensionManager()
628 {
629         std::map<std::string, BoneExtensionMap *>::iterator map_it;
630         for (map_it = extended_bone_maps.begin(); map_it != extended_bone_maps.end(); ++map_it)
631         {
632                 BoneExtensionMap *extended_bones = map_it->second;
633                 for (BoneExtensionMap::iterator ext_it = extended_bones->begin(); ext_it != extended_bones->end(); ++ext_it) {
634                         if (ext_it->second != NULL)
635                                 delete ext_it->second;
636                 }
637                 extended_bones->clear();
638                 delete extended_bones;
639         }
640 }
641
642 /**
643  * BoneExtended is a helper class needed for the Bone chain finder
644  * See ArmatureImporter::fix_leaf_bones()
645  * and ArmatureImporter::connect_bone_chains()
646  */
647
648 BoneExtended::BoneExtended(EditBone *aBone)
649 {
650         this->set_name(aBone->name);
651         this->chain_length = 0;
652         this->is_leaf = false;
653         this->tail[0] = 0.0f;
654         this->tail[1] = 0.5f;
655         this->tail[2] = 0.0f;
656         this->use_connect = -1;
657         this->roll = 0;
658         this->bone_layers = 0;
659
660         this->has_custom_tail = false;
661         this->has_custom_roll = false;
662 }
663
664 char *BoneExtended::get_name()
665 {
666         return name;
667 }
668
669 void BoneExtended::set_name(char *aName)
670 {
671         BLI_strncpy(name, aName, MAXBONENAME);
672 }
673
674 int BoneExtended::get_chain_length()
675 {
676         return chain_length;
677 }
678
679 void BoneExtended::set_chain_length(const int aLength)
680 {
681         chain_length = aLength;
682 }
683
684 void BoneExtended::set_leaf_bone(bool state)
685 {
686         is_leaf = state;
687 }
688
689 bool BoneExtended::is_leaf_bone()
690 {
691         return is_leaf;
692 }
693
694 void BoneExtended::set_roll(float roll)
695 {
696         this->roll = roll;
697         this->has_custom_roll = true;
698 }
699
700 bool BoneExtended::has_roll()
701 {
702         return this->has_custom_roll;
703 }
704
705 float BoneExtended::get_roll()
706 {
707         return this->roll;
708 }
709
710 void BoneExtended::set_tail(float vec[])
711 {
712         this->tail[0] = vec[0];
713         this->tail[1] = vec[1];
714         this->tail[2] = vec[2];
715         this->has_custom_tail = true;
716 }
717
718 bool BoneExtended::has_tail()
719 {
720         return this->has_custom_tail;
721 }
722
723 float *BoneExtended::get_tail()
724 {
725         return this->tail;
726 }
727
728 inline bool isInteger(const std::string & s)
729 {
730         if (s.empty() || ((!isdigit(s[0])) && (s[0] != '-') && (s[0] != '+'))) return false;
731
732         char *p;
733         strtol(s.c_str(), &p, 10);
734
735         return (*p == 0);
736 }
737
738 void BoneExtended::set_bone_layers(std::string layerString, std::vector<std::string> &layer_labels)
739 {
740         std::stringstream ss(layerString);
741         std::string layer;
742         int pos;
743
744         while (ss >> layer) {
745
746                 /* Blender uses numbers to specify layers*/
747                 if (isInteger(layer))
748                 {
749                         pos = atoi(layer.c_str());
750                         if (pos >= 0 && pos < 32) {
751                                 this->bone_layers = bc_set_layer(this->bone_layers, pos);
752                                 continue;
753                         }
754                 }
755
756                 /* layer uses labels (not supported by blender). Map to layer numbers:*/
757                 pos = find(layer_labels.begin(), layer_labels.end(), layer) - layer_labels.begin();
758                 if (pos >= layer_labels.size()) {
759                         layer_labels.push_back(layer); /* remember layer number for future usage*/
760                 }
761
762                 if (pos > 31)
763                 {
764                         fprintf(stderr, "Too many layers in Import. Layer %s mapped to Blender layer 31\n", layer.c_str());
765                         pos = 31;
766                 }
767
768                 /* If numeric layers and labeled layers are used in parallel (unlikely),
769                  * we get a potential mixup. Just leave as is for now.
770                  */
771                 this->bone_layers = bc_set_layer(this->bone_layers, pos);
772
773         }
774 }
775
776 std::string BoneExtended::get_bone_layers(int bitfield)
777 {
778         std::string result = "";
779         std::string sep = "";
780         int bit = 1u;
781
782         std::ostringstream ss;
783         for (int i = 0; i < 32; i++)
784         {
785                 if (bit & bitfield)
786                 {
787                         ss << sep << i;
788                         sep = " ";
789                 }
790                 bit = bit << 1;
791         }
792         return ss.str();
793 }
794
795 int BoneExtended::get_bone_layers()
796 {
797         return (bone_layers == 0) ? 1 : bone_layers; // ensure that the bone is in at least one bone layer!
798 }
799
800
801 void BoneExtended::set_use_connect(int use_connect)
802 {
803         this->use_connect = use_connect;
804 }
805
806 int BoneExtended::get_use_connect()
807 {
808         return this->use_connect;
809 }
810
811 /**
812  * Stores a 4*4 matrix as a custom bone property array of size 16
813  */
814 void bc_set_IDPropertyMatrix(EditBone *ebone, const char *key, float mat[4][4])
815 {
816         IDProperty *idgroup = (IDProperty *)ebone->prop;
817         if (idgroup == NULL)
818         {
819                 IDPropertyTemplate val = { 0 };
820                 idgroup = IDP_New(IDP_GROUP, &val, "RNA_EditBone ID properties");
821                 ebone->prop = idgroup;
822         }
823
824         IDPropertyTemplate val = { 0 };
825         val.array.len = 16;
826         val.array.type = IDP_FLOAT;
827
828         IDProperty *data = IDP_New(IDP_ARRAY, &val, key);
829         float *array = (float *)IDP_Array(data);
830         for (int i = 0; i < 4; i++)
831                 for (int j = 0; j < 4; j++)
832                         array[4 * i + j] = mat[i][j];
833
834         IDP_AddToGroup(idgroup, data);
835 }
836
837 #if 0
838 /**
839  * Stores a Float value as a custom bone property
840  *
841  * Note: This function is currently not needed. Keep for future usage
842  */
843 static void bc_set_IDProperty(EditBone *ebone, const char *key, float value)
844 {
845         if (ebone->prop == NULL)
846         {
847                 IDPropertyTemplate val = { 0 };
848                 ebone->prop = IDP_New(IDP_GROUP, &val, "RNA_EditBone ID properties");
849         }
850
851         IDProperty *pgroup = (IDProperty *)ebone->prop;
852         IDPropertyTemplate val = { 0 };
853         IDProperty *prop = IDP_New(IDP_FLOAT, &val, key);
854         IDP_Float(prop) = value;
855         IDP_AddToGroup(pgroup, prop);
856
857 }
858 #endif
859
860 /**
861  * Get a custom property when it exists.
862  * This function is also used to check if a property exists.
863  */
864 IDProperty *bc_get_IDProperty(Bone *bone, std::string key)
865 {
866         return (bone->prop == NULL) ? NULL : IDP_GetPropertyFromGroup(bone->prop, key.c_str());
867 }
868
869 /**
870  * Read a custom bone property and convert to float
871  * Return def if the property does not exist.
872  */
873 float bc_get_property(Bone *bone, std::string key, float def)
874 {
875         float result = def;
876         IDProperty *property = bc_get_IDProperty(bone, key);
877         if (property) {
878                 switch (property->type) {
879                         case IDP_INT:
880                                 result = (float)(IDP_Int(property));
881                                 break;
882                         case IDP_FLOAT:
883                                 result = (float)(IDP_Float(property));
884                                 break;
885                         case IDP_DOUBLE:
886                                 result = (float)(IDP_Double(property));
887                                 break;
888                         default:
889                                 result = def;
890                 }
891         }
892         return result;
893 }
894
895 /**
896  * Read a custom bone property and convert to matrix
897  * Return true if conversion was successful
898  *
899  * Return false if:
900  * - the property does not exist
901  * - is not an array of size 16
902  */
903 bool bc_get_property_matrix(Bone *bone, std::string key, float mat[4][4])
904 {
905         IDProperty *property = bc_get_IDProperty(bone, key);
906         if (property && property->type == IDP_ARRAY && property->len == 16) {
907                 float *array = (float *)IDP_Array(property);
908                 for (int i = 0; i < 4; i++)
909                         for (int j = 0; j < 4; j++)
910                                 mat[i][j] = array[4 * i + j];
911                 return true;
912         }
913         return false;
914 }
915
916 /**
917  * get a vector that is stored in 3 custom properties (used in Blender <= 2.78)
918  */
919 void bc_get_property_vector(Bone *bone, std::string key, float val[3], const float def[3])
920 {
921         val[0] = bc_get_property(bone, key + "_x", def[0]);
922         val[1] = bc_get_property(bone, key + "_y", def[1]);
923         val[2] = bc_get_property(bone, key + "_z", def[2]);
924 }
925
926 /**
927  * Check if vector exist stored in 3 custom properties (used in Blender <= 2.78)
928  */
929 static bool has_custom_props(Bone *bone, bool enabled, std::string key)
930 {
931         if (!enabled)
932                 return false;
933
934         return (bc_get_IDProperty(bone, key + "_x")
935                 ||      bc_get_IDProperty(bone, key + "_y")
936                 ||      bc_get_IDProperty(bone, key + "_z"));
937
938 }
939
940 void bc_enable_fcurves(bAction *act, char *bone_name)
941 {
942         FCurve *fcu;
943         char prefix[200];
944
945         if (bone_name)
946                 BLI_snprintf(prefix, sizeof(prefix), "pose.bones[\"%s\"]", bone_name);
947
948         for (fcu = (FCurve *)act->curves.first; fcu; fcu = fcu->next) {
949                 if (bone_name) {
950                         if (STREQLEN(fcu->rna_path, prefix, strlen(prefix)))
951                                 fcu->flag &= ~FCURVE_DISABLED;
952                         else
953                                 fcu->flag |= FCURVE_DISABLED;
954                 }
955                 else {
956                         fcu->flag &= ~FCURVE_DISABLED;
957                 }
958         }
959 }
960
961 bool bc_bone_matrix_local_get(Object *ob, Bone *bone, Matrix &mat, bool for_opensim)
962 {
963
964         /* Ok, lets be super cautious and check if the bone exists */
965         bPose *pose = ob->pose;
966         bPoseChannel *pchan = BKE_pose_channel_find_name(pose, bone->name);
967         if (!pchan) {
968                 return false;
969         }
970
971         bAction *action = bc_getSceneObjectAction(ob);
972         bPoseChannel *parchan = pchan->parent;
973
974         bc_enable_fcurves(action, bone->name);
975         float ipar[4][4];
976
977         if (bone->parent) {
978                 invert_m4_m4(ipar, parchan->pose_mat);
979                 mul_m4_m4m4(mat, ipar, pchan->pose_mat);
980         }
981         else
982                 copy_m4_m4(mat, pchan->pose_mat);
983
984         /* OPEN_SIM_COMPATIBILITY
985         * AFAIK animation to second life is via BVH, but no
986         * reason to not have the collada-animation be correct
987         */
988         if (for_opensim) {
989                 float temp[4][4];
990                 copy_m4_m4(temp, bone->arm_mat);
991                 temp[3][0] = temp[3][1] = temp[3][2] = 0.0f;
992                 invert_m4(temp);
993
994                 mul_m4_m4m4(mat, mat, temp);
995
996                 if (bone->parent) {
997                         copy_m4_m4(temp, bone->parent->arm_mat);
998                         temp[3][0] = temp[3][1] = temp[3][2] = 0.0f;
999
1000                         mul_m4_m4m4(mat, temp, mat);
1001                 }
1002         }
1003         bc_enable_fcurves(action, NULL);
1004         return true;
1005 }
1006
1007 bool bc_is_animated(BCMatrixSampleMap &values)
1008 {
1009         static float MIN_DISTANCE = 0.00001;
1010
1011         if (values.size() < 2)
1012                 return false; // need at least 2 entries to be not flat
1013
1014         BCMatrixSampleMap::iterator it;
1015         const BCMatrix *refmat = NULL;
1016         for (it = values.begin(); it != values.end(); ++it) {
1017                 const BCMatrix *matrix = it->second;
1018
1019                 if (refmat == NULL) {
1020                         refmat = matrix;
1021                         continue;
1022                 }
1023
1024                 if (!matrix->in_range(*refmat, MIN_DISTANCE))
1025                         return true;
1026         }
1027         return false;
1028 }
1029
1030 bool bc_has_animations(Object *ob)
1031 {
1032         /* Check for object,lamp and camera transform animations */
1033         if ((bc_getSceneObjectAction(ob) && bc_getSceneObjectAction(ob)->curves.first) ||
1034                 (bc_getSceneLampAction(ob) && bc_getSceneLampAction(ob)->curves.first) ||
1035                 (bc_getSceneCameraAction(ob) && bc_getSceneCameraAction(ob)->curves.first))
1036                 return true;
1037
1038         //Check Material Effect parameter animations.
1039         for (int a = 0; a < ob->totcol; a++) {
1040                 Material *ma = give_current_material(ob, a + 1);
1041                 if (!ma) continue;
1042                 if (ma->adt && ma->adt->action && ma->adt->action->curves.first)
1043                         return true;
1044         }
1045
1046         Key *key = BKE_key_from_object(ob);
1047         if ((key && key->adt && key->adt->action) && key->adt->action->curves.first)
1048                 return true;
1049
1050         return false;
1051 }
1052
1053
1054 bool bc_has_animations(Scene *sce, LinkNode &export_set)
1055 {
1056         LinkNode *node;
1057
1058         for (node = &export_set; node; node = node->next) {
1059                 Object *ob = (Object *)node->link;
1060
1061                 if (bc_has_animations(ob))
1062                         return true;
1063         }
1064         return false;
1065 }
1066
1067 /**
1068  * Check if custom information about bind matrix exists and modify the from_mat
1069  * accordingly.
1070  *
1071  * Note: This is old style for Blender <= 2.78 only kept for compatibility
1072  */
1073 void bc_create_restpose_mat(const ExportSettings *export_settings, Bone *bone, float to_mat[4][4], float from_mat[4][4], bool use_local_space)
1074 {
1075         float loc[3];
1076         float rot[3];
1077         float scale[3];
1078         static const float V0[3] = { 0, 0, 0 };
1079
1080         if (!has_custom_props(bone, export_settings->keep_bind_info, "restpose_loc") &&
1081                 !has_custom_props(bone, export_settings->keep_bind_info, "restpose_rot") &&
1082                 !has_custom_props(bone, export_settings->keep_bind_info, "restpose_scale"))
1083         {
1084                 /* No need */
1085                 copy_m4_m4(to_mat, from_mat);
1086                 return;
1087         }
1088
1089         bc_decompose(from_mat, loc, rot, NULL, scale);
1090         loc_eulO_size_to_mat4(to_mat, loc, rot, scale, 6);
1091
1092         if (export_settings->keep_bind_info) {
1093                 bc_get_property_vector(bone, "restpose_loc", loc, loc);
1094
1095                 if (use_local_space && bone->parent) {
1096                         Bone *b = bone;
1097                         while (b->parent) {
1098                                 b = b->parent;
1099                                 float ploc[3];
1100                                 bc_get_property_vector(b, "restpose_loc", ploc, V0);
1101                                 loc[0] += ploc[0];
1102                                 loc[1] += ploc[1];
1103                                 loc[2] += ploc[2];
1104                         }
1105                 }
1106         }
1107
1108         if (export_settings->keep_bind_info) {
1109                 if (bc_get_IDProperty(bone, "restpose_rot_x"))
1110                     rot[0] = DEG2RADF(bc_get_property(bone, "restpose_rot_x", 0));
1111                 if (bc_get_IDProperty(bone, "restpose_rot_y"))
1112                         rot[1] = DEG2RADF(bc_get_property(bone, "restpose_rot_y", 0));
1113                 if (bc_get_IDProperty(bone, "restpose_rot_z"))
1114                         rot[2] = DEG2RADF(bc_get_property(bone, "restpose_rot_z", 0));
1115         }
1116
1117         if (export_settings->keep_bind_info) {
1118                 bc_get_property_vector(bone, "restpose_scale", scale, scale);
1119         }
1120
1121         loc_eulO_size_to_mat4(to_mat, loc, rot, scale, 6);
1122
1123 }
1124
1125 /*
1126  * Make 4*4 matrices better readable
1127  */
1128 void bc_sanitize_mat(float mat[4][4], int precision)
1129 {
1130         for (int i = 0; i < 4; i++)
1131                 for (int j = 0; j < 4; j++) {
1132                         double val = (double)mat[i][j];
1133                         val = double_round(val, precision);
1134                         mat[i][j] = (float)val;
1135                 }
1136 }
1137
1138 void bc_sanitize_mat(double mat[4][4], int precision)
1139 {
1140         for (int i = 0; i < 4; i++)
1141                 for (int j = 0; j < 4; j++)
1142                         mat[i][j] = double_round(mat[i][j], precision);
1143 }
1144
1145 void bc_copy_m4_farray(float r[4][4], float *a)
1146 {
1147         for (int i = 0; i < 4; i++)
1148                 for (int j = 0; j < 4; j++)
1149                         r[i][j] = *a++;
1150 }
1151
1152 void bc_copy_farray_m4(float *r, float a[4][4])
1153 {
1154         for (int i = 0; i < 4; i++)
1155                 for (int j = 0; j < 4; j++)
1156                         *r++ = a[i][j];
1157 }
1158
1159 void bc_copy_darray_m4d(double *r, double a[4][4])
1160 {
1161         for (int i = 0; i < 4; i++)
1162                 for (int j = 0; j < 4; j++)
1163                         *r++ = a[i][j];
1164 }
1165
1166 void bc_copy_v44_m4d(std::vector<std::vector<double>> &r, double(&a)[4][4])
1167 {
1168         for (int i = 0; i < 4; i++) {
1169                 for (int j = 0; j < 4; j++) {
1170                         r[i][j] = a[i][j];
1171                 }
1172         }
1173 }
1174
1175 void bc_copy_m4d_v44(double (&r)[4][4], std::vector<std::vector<double>> &a)
1176 {
1177         for (int i = 0; i < 4; i++) {
1178                 for (int j = 0; j < 4; j++) {
1179                         r[i][j] = a[i][j];
1180                 }
1181         }
1182 }
1183
1184 /**
1185  * Returns name of Active UV Layer or empty String if no active UV Layer defined
1186  */
1187 std::string bc_get_active_uvlayer_name(Mesh *me)
1188 {
1189         int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
1190         if (num_layers) {
1191                 char *layer_name = bc_CustomData_get_active_layer_name(&me->fdata, CD_MTFACE);
1192                 if (layer_name) {
1193                         return std::string(layer_name);
1194                 }
1195         }
1196         return "";
1197 }
1198
1199 /**
1200  * Returns name of Active UV Layer or empty String if no active UV Layer defined.
1201  * Assuming the Object is of type MESH
1202  */
1203 std::string bc_get_active_uvlayer_name(Object *ob)
1204 {
1205         Mesh *me = (Mesh *)ob->data;
1206         return bc_get_active_uvlayer_name(me);
1207 }
1208
1209 /**
1210  * Returns UV Layer name or empty string if layer index is out of range
1211  */
1212 std::string bc_get_uvlayer_name(Mesh *me, int layer)
1213 {
1214         int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
1215         if (num_layers && layer < num_layers) {
1216                 char *layer_name = bc_CustomData_get_layer_name(&me->fdata, CD_MTFACE, layer);
1217                 if (layer_name) {
1218                         return std::string(layer_name);
1219                 }
1220         }
1221         return "";
1222 }
1223
1224 std::string bc_find_bonename_in_path(std::string path, std::string probe)
1225 {
1226         std::string result;
1227         char *boneName = BLI_str_quoted_substrN(path.c_str(), probe.c_str());
1228         if (boneName) {
1229                 result = std::string(boneName);
1230                 MEM_freeN(boneName);
1231         }
1232         return result;
1233 }
1234
1235 static bNodeTree *prepare_material_nodetree(Material *ma)
1236 {
1237         if (ma->nodetree == NULL) {
1238                 ma->nodetree = ntreeAddTree(NULL, "Shader Nodetree", "ShaderNodeTree");
1239                 ma->use_nodes = true;
1240         }
1241         return ma->nodetree;
1242 }
1243
1244 bNode *bc_add_node(bContext *C, bNodeTree *ntree, int node_type, int locx, int locy, std::string label)
1245 {
1246         bNode *node = nodeAddStaticNode(C, ntree, node_type);
1247         if (node) {
1248                 if (label.length() > 0) {
1249                         strcpy(node->label, label.c_str());
1250                 }
1251                 node->locx = locx;
1252                 node->locy = locy;
1253                 node->flag |= NODE_SELECT;
1254         }
1255         return node;
1256 }
1257
1258
1259 bNode *bc_add_node(bContext *C, bNodeTree *ntree, int node_type, int locx, int locy)
1260 {
1261         return bc_add_node(C, ntree, node_type, locx, locy, "");
1262 }
1263
1264 #if 0
1265 // experimental, probably not used
1266 static bNodeSocket *bc_group_add_input_socket(bNodeTree *ntree, bNode *to_node, int to_index, std::string label)
1267 {
1268         bNodeSocket *to_socket = (bNodeSocket *)BLI_findlink(&to_node->inputs, to_index);
1269
1270         //bNodeSocket *socket = ntreeAddSocketInterfaceFromSocket(ntree, to_node, to_socket);
1271         //return socket;
1272
1273         bNodeSocket *gsock = ntreeAddSocketInterfaceFromSocket(ntree, to_node, to_socket);
1274         bNode *inputGroup = ntreeFindType(ntree, NODE_GROUP_INPUT);
1275         node_group_input_verify(ntree, inputGroup, (ID *)ntree);
1276         bNodeSocket *newsock = node_group_input_find_socket(inputGroup, gsock->identifier);
1277         nodeAddLink(ntree, inputGroup, newsock, to_node, to_socket);
1278         strcpy(newsock->name, label.c_str());
1279         return newsock;
1280 }
1281
1282 static bNodeSocket *bc_group_add_output_socket(bNodeTree *ntree, bNode *from_node, int from_index, std::string label)
1283 {
1284         bNodeSocket *from_socket = (bNodeSocket *)BLI_findlink(&from_node->outputs, from_index);
1285
1286         //bNodeSocket *socket = ntreeAddSocketInterfaceFromSocket(ntree, to_node, to_socket);
1287         //return socket;
1288
1289         bNodeSocket *gsock = ntreeAddSocketInterfaceFromSocket(ntree, from_node, from_socket);
1290         bNode *outputGroup = ntreeFindType(ntree, NODE_GROUP_OUTPUT);
1291         node_group_output_verify(ntree, outputGroup, (ID *)ntree);
1292         bNodeSocket *newsock = node_group_output_find_socket(outputGroup, gsock->identifier);
1293         nodeAddLink(ntree, from_node, from_socket, outputGroup, newsock);
1294         strcpy(newsock->name, label.c_str());
1295         return newsock;
1296 }
1297
1298
1299 void bc_make_group(bContext *C, bNodeTree *ntree, std::map<std::string, bNode *> nmap)
1300 {
1301         bNode * gnode = node_group_make_from_selected(C, ntree, "ShaderNodeGroup", "ShaderNodeTree");
1302         bNodeTree *gtree = (bNodeTree *)gnode->id;
1303
1304         bc_group_add_input_socket(gtree, nmap["main"], 0, "Diffuse");
1305         bc_group_add_input_socket(gtree, nmap["emission"], 0, "Emission");
1306         bc_group_add_input_socket(gtree, nmap["mix"], 0, "Transparency");
1307         bc_group_add_input_socket(gtree, nmap["emission"], 1, "Emission");
1308         bc_group_add_input_socket(gtree, nmap["main"], 4, "Metallic");
1309         bc_group_add_input_socket(gtree, nmap["main"], 5, "Specular");
1310
1311         bc_group_add_output_socket(gtree, nmap["mix"], 0, "Shader");
1312 }
1313 #endif
1314
1315 static void bc_node_add_link(bNodeTree *ntree, bNode *from_node, int from_index, bNode *to_node, int to_index)
1316 {
1317         bNodeSocket *from_socket = (bNodeSocket *)BLI_findlink(&from_node->outputs, from_index);
1318         bNodeSocket *to_socket = (bNodeSocket *)BLI_findlink(&to_node->inputs, to_index);
1319
1320         nodeAddLink(ntree, from_node, from_socket, to_node, to_socket);
1321 }
1322
1323 void bc_add_default_shader(bContext *C, Material *ma)
1324 {
1325         bNodeTree *ntree = prepare_material_nodetree(ma);
1326         std::map<std::string, bNode *> nmap;
1327 #if 0
1328         nmap["main"] = bc_add_node(C, ntree, SH_NODE_BSDF_PRINCIPLED, -300, 300);
1329         nmap["emission"] = bc_add_node(C, ntree, SH_NODE_EMISSION, -300, 500, "emission");
1330         nmap["add"] = bc_add_node(C, ntree, SH_NODE_ADD_SHADER, 100, 400);
1331         nmap["transparent"] = bc_add_node(C, ntree, SH_NODE_BSDF_TRANSPARENT, 100, 200);
1332         nmap["mix"] = bc_add_node(C, ntree, SH_NODE_MIX_SHADER, 400, 300, "transparency");
1333         nmap["out"] = bc_add_node(C, ntree, SH_NODE_OUTPUT_MATERIAL, 600, 300);
1334         nmap["out"]->flag &= ~NODE_SELECT;
1335
1336         bc_node_add_link(ntree, nmap["emission"], 0, nmap["add"], 0);
1337         bc_node_add_link(ntree, nmap["main"], 0, nmap["add"], 1);
1338         bc_node_add_link(ntree, nmap["add"], 0, nmap["mix"], 1);
1339         bc_node_add_link(ntree, nmap["transparent"], 0, nmap["mix"], 2);
1340
1341         bc_node_add_link(ntree, nmap["mix"], 0, nmap["out"], 0);
1342         // experimental, probably not used.
1343         bc_make_group(C, ntree, nmap);
1344 #else
1345 nmap["main"] = bc_add_node(C, ntree, SH_NODE_BSDF_PRINCIPLED,  0, 300);
1346 nmap["out"] = bc_add_node(C, ntree, SH_NODE_OUTPUT_MATERIAL, 300, 300);
1347 bc_node_add_link(ntree, nmap["main"], 0, nmap["out"], 0);
1348 #endif
1349 }
1350
1351 COLLADASW::ColorOrTexture bc_get_base_color(Material *ma)
1352 {
1353         bNode *master_shader = bc_get_master_shader(ma);
1354         if (master_shader) {
1355                 return bc_get_base_color(master_shader);
1356         }
1357         else {
1358                 return bc_get_cot(ma->r, ma->g, ma->b, ma->alpha);
1359         }
1360 }
1361
1362 COLLADASW::ColorOrTexture bc_get_specular_color(Material *ma, bool use_fallback)
1363 {
1364         bNode *master_shader = bc_get_master_shader(ma);
1365         if (master_shader) {
1366                 return bc_get_specular_color(master_shader);
1367         }
1368         else if (use_fallback) {
1369                 return bc_get_cot(ma->specr * ma->spec, ma->specg * ma->spec, ma->specb * ma->spec, 1.0f);
1370         }
1371         else {
1372                 return bc_get_cot(0.0, 0.0, 0.0, 1.0); // no specular
1373         }
1374 }
1375
1376 COLLADASW::ColorOrTexture bc_get_base_color(bNode *shader)
1377 {
1378         bNodeSocket *socket = nodeFindSocket(shader, SOCK_IN, "Base Color");
1379         if (socket)
1380         {
1381                 bNodeSocketValueRGBA *dcol = (bNodeSocketValueRGBA *)socket->default_value;
1382                 float* col = dcol->value;
1383                 return bc_get_cot(col[0], col[1], col[2], col[3]);
1384         }
1385         else {
1386                 return bc_get_cot(0.8, 0.8, 0.8, 1.0); //default white
1387         }
1388 }
1389
1390 COLLADASW::ColorOrTexture bc_get_specular_color(bNode *shader)
1391 {
1392         bNodeSocket *socket = nodeFindSocket(shader, SOCK_IN, "Specular");
1393         if (socket)
1394         {
1395                 bNodeSocketValueRGBA *dcol = (bNodeSocketValueRGBA *)socket->default_value;
1396                 float* col = dcol->value;
1397                 return bc_get_cot(col[0], col[1], col[2], col[3]);
1398         }
1399         else {
1400                 return bc_get_cot(0.8, 0.8, 0.8, 1.0); //default white
1401         }
1402 }
1403
1404 bNode *bc_get_master_shader(Material *ma)
1405 {
1406         bNodeTree *nodetree = ma->nodetree;
1407         if (nodetree) {
1408                 for (bNode *node = (bNode *)nodetree->nodes.first; node; node = node->next) {
1409                         if (node->typeinfo->type == SH_NODE_BSDF_PRINCIPLED) {
1410                                 return node;
1411                         }
1412                 }
1413         }
1414         return NULL;
1415 }
1416
1417 COLLADASW::ColorOrTexture bc_get_cot(float r, float g, float b, float a)
1418 {
1419         COLLADASW::Color color(r, g, b, a);
1420         COLLADASW::ColorOrTexture cot(color);
1421         return cot;
1422 }