Blender V4.5
collada_utils.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2010-2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "COLLADAFWMeshVertexData.h"
10#include "COLLADAFWNode.h"
11
12#include <set>
13#include <string>
14
15#include "DNA_armature_types.h"
18#include "DNA_key_types.h"
19#include "DNA_mesh_types.h"
20#include "DNA_modifier_types.h"
21#include "DNA_object_types.h"
22#include "DNA_scene_types.h"
23
24#include "BLI_linklist.h"
25#include "BLI_listbase.h"
26#include "BLI_math_matrix.h"
27#include "BLI_string.h"
28
29#include "BKE_action.hh"
30#include "BKE_armature.hh"
31#include "BKE_constraint.h"
32#include "BKE_context.hh"
33#include "BKE_customdata.hh"
34#include "BKE_global.hh"
35#include "BKE_idprop.hh"
36#include "BKE_key.hh"
37#include "BKE_layer.hh"
38#include "BKE_lib_id.hh"
39#include "BKE_material.hh"
40#include "BKE_mesh.hh"
42#include "BKE_mesh_runtime.hh"
43#include "BKE_mesh_wrapper.hh"
44#include "BKE_node.hh"
46#include "BKE_node_runtime.hh"
47#include "BKE_object.hh"
48#include "BKE_scene.hh"
49
50#include "ANIM_action.hh"
51#include "ANIM_action_legacy.hh"
53
54#include "ED_node.hh"
55#include "ED_object.hh"
56#include "ED_screen.hh"
57
58#include "WM_api.hh" /* XXX hrm, see if we can do without this */
59#include "WM_types.hh"
60
61#include "bmesh.hh"
62#include "bmesh_tools.hh"
63
64#include "DEG_depsgraph.hh"
66
67#include "BlenderContext.h"
68#include "ExportSettings.h"
69#include "ExtraTags.h"
70#include "collada_utils.h"
71
72float bc_get_float_value(const COLLADAFW::FloatOrDoubleArray &array, uint index)
73{
74 if (index >= array.getValuesCount()) {
75 return 0.0f;
76 }
77
78 if (array.getType() == COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT) {
79 return array.getFloatValues()->getData()[index];
80 }
81
82 return array.getDoubleValues()->getData()[index];
83}
84
86{
87 /* Copied from `editors/object/object_relations.cc`. */
88
89 /* test if 'ob' is a parent somewhere in par's parents */
90
91 if (par == nullptr) {
92 return 0;
93 }
94 if (ob == par) {
95 return 1;
96 }
97
98 return bc_test_parent_loop(par->parent, ob);
99}
100
102{
104
105 /* these we can skip completely (invalid constraints...) */
106 if (cti == nullptr) {
107 return false;
108 }
109 if (con->flag & (CONSTRAINT_DISABLE | CONSTRAINT_OFF)) {
110 return false;
111 }
112
113 /* these constraints can't be evaluated anyway */
114 if (cti->evaluate_constraint == nullptr) {
115 return false;
116 }
117
118 /* influence == 0 should be ignored */
119 if (con->enforce == 0.0f) {
120 return false;
121 }
122
123 /* validation passed */
124 return true;
125}
126
127bool bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space)
128{
129 Scene *scene = CTX_data_scene(C);
131 const bool xmirror = false;
132 const bool keep_transform = false;
133
134 if (par && is_parent_space) {
135 mul_m4_m4m4(ob->runtime->object_to_world.ptr(),
136 par->object_to_world().ptr(),
137 ob->object_to_world().ptr());
138 }
139
141 nullptr, C, scene, ob, par, partype, xmirror, keep_transform, nullptr);
142 return ok;
143}
144
145std::vector<bAction *> bc_getSceneActions(const bContext *C, Object *ob, bool all_actions)
146{
147 std::vector<bAction *> actions;
148 if (all_actions) {
149 Main *bmain = CTX_data_main(C);
150 ID *id;
151
152 for (id = (ID *)bmain->actions.first; id; id = (ID *)(id->next)) {
153 bAction *act = (bAction *)id;
154 /* XXX This currently creates too many actions.
155 * TODO: Need to check if the action is compatible to the given object. */
156 actions.push_back(act);
157 }
158 }
159 else {
160 bAction *action = bc_getSceneObjectAction(ob);
161 actions.push_back(action);
162 }
163
164 return actions;
165}
166
167std::string bc_get_action_id(const std::string &action_name,
168 const std::string &ob_name,
169 const std::string &channel_type,
170 const std::string &axis_name,
171 const std::string &axis_separator)
172{
173 std::string result = action_name + "_" + channel_type;
174 if (ob_name.length() > 0) {
175 result = ob_name + "_" + result;
176 }
177 if (axis_name.length() > 0) {
178 result += axis_separator + axis_name;
179 }
180 return translate_id(result);
181}
182
183void bc_update_scene(BlenderContext &blender_context, float ctime)
184{
185 Main *bmain = blender_context.get_main();
186 Scene *scene = blender_context.get_scene();
187 Depsgraph *depsgraph = blender_context.get_depsgraph();
188
189 /* See remark in `physics_fluid.cc` lines 395...) */
190 // BKE_scene_update_for_newframe(ev_context, bmain, scene, scene->lay);
191 BKE_scene_frame_set(scene, ctime);
193}
194
195Object *bc_add_object(Main *bmain, Scene *scene, ViewLayer *view_layer, int type, const char *name)
196{
197 Object *ob = BKE_object_add_only_object(bmain, type, name);
198
199 ob->data = BKE_object_obdata_add_from_type(bmain, type, name);
201
202 LayerCollection *layer_collection = BKE_layer_collection_get_active(view_layer);
203 BKE_collection_object_add(bmain, layer_collection->collection, ob);
204
205 BKE_view_layer_synced_ensure(scene, view_layer);
206 Base *base = BKE_view_layer_base_find(view_layer, ob);
207 /* TODO: is setting active needed? */
209
210 return ob;
211}
212
213static void bc_add_armature_collections(COLLADAFW::Node *node,
214 ExtraTags *node_extra_tags,
215 bArmature *arm)
216{
217 if (!node_extra_tags) {
218 /* No 'extra' tags means that there are no bone collections. */
219 return;
220 }
221
222 std::vector<std::string> collection_names = node_extra_tags->dataSplitString("collections");
223 std::vector<std::string> visible_names = node_extra_tags->dataSplitString("visible_collections");
224 std::set<std::string> visible_names_set(visible_names.begin(), visible_names.end());
225 for (const std::string &name : collection_names) {
226 BoneCollection *bcoll = ANIM_armature_bonecoll_new(arm, name.c_str());
227 if (visible_names_set.find(name) == visible_names_set.end()) {
228 ANIM_bonecoll_hide(arm, bcoll);
229 }
230 else {
231 ANIM_bonecoll_show(arm, bcoll);
232 }
233 }
234
235 std::string active_name;
236 active_name = node_extra_tags->setData("active_collection", active_name);
237 ANIM_armature_bonecoll_active_name_set(arm, active_name.c_str());
238}
239
240Object *bc_add_armature(COLLADAFW::Node *node,
241 ExtraTags *node_extra_tags,
242 Main *bmain,
243 Scene *scene,
244 ViewLayer *view_layer,
245 int type,
246 const char *name)
247{
248 Object *ob = bc_add_object(bmain, scene, view_layer, type, name);
249 bc_add_armature_collections(node, node_extra_tags, reinterpret_cast<bArmature *>(ob->data));
250 return ob;
251}
252
254 Object *ob,
255 BC_export_mesh_type export_mesh_type,
256 bool apply_modifiers,
257 bool triangulate)
258{
259 const Mesh *tmpmesh = nullptr;
260 if (apply_modifiers) {
261#if 0 /* Not supported by new system currently... */
262 switch (export_mesh_type) {
263 case BC_MESH_TYPE_VIEW: {
264 dm = mesh_create_derived_view(depsgraph, scene, ob, &mask);
265 break;
266 }
267 case BC_MESH_TYPE_RENDER: {
268 dm = mesh_create_derived_render(depsgraph, scene, ob, &mask);
269 break;
270 }
271 }
272#else
273 Depsgraph *depsgraph = blender_context.get_depsgraph();
274 const Object *ob_eval = DEG_get_evaluated(depsgraph, ob);
275 tmpmesh = BKE_object_get_evaluated_mesh(ob_eval);
276#endif
277 }
278 else {
279 tmpmesh = (Mesh *)ob->data;
280 }
281
282 Mesh *mesh = BKE_mesh_copy_for_eval(*tmpmesh);
283
284 /* Ensure data exists if currently in edit mode. */
286
287 if (triangulate) {
289 }
291
292 return mesh;
293}
294
296{
297 Object *ob_arm = nullptr;
298
299 if (ob->parent && ob->partype == PARSKEL && ob->parent->type == OB_ARMATURE) {
300 ob_arm = ob->parent;
301 }
302 else {
304 if (mod->type == eModifierType_Armature) {
305 ob_arm = ((ArmatureModifierData *)mod)->object;
306 }
307 }
308 }
309
310 return ob_arm;
311}
312
313bool bc_has_object_type(LinkNode *export_set, short obtype)
314{
315 LinkNode *node;
316
317 for (node = export_set; node; node = node->next) {
318 Object *ob = (Object *)node->link;
319 /* XXX: why is this checking for ob->data? - we could be looking for empties. */
320 if (ob->type == obtype && ob->data) {
321 return true;
322 }
323 }
324 return false;
325}
326
328{
329 /* Use bubble sort algorithm for sorting the export set. */
330
331 bool sorted = false;
332 LinkNode *node;
333 for (node = export_set; node->next && !sorted; node = node->next) {
334
335 sorted = true;
336
337 LinkNode *current;
338 for (current = export_set; current->next; current = current->next) {
339 Object *a = (Object *)current->link;
340 Object *b = (Object *)current->next->link;
341
342 if (strcmp(a->id.name, b->id.name) > 0) {
343 current->link = b;
344 current->next->link = a;
345 sorted = false;
346 }
347 }
348 }
349}
350
351bool bc_is_root_bone(Bone *aBone, bool deform_bones_only)
352{
353 if (deform_bones_only) {
354 Bone *root = nullptr;
355 Bone *bone = aBone;
356 while (bone) {
357 if (!(bone->flag & BONE_NO_DEFORM)) {
358 root = bone;
359 }
360 bone = bone->parent;
361 }
362 return (aBone == root);
363 }
364
365 return !(aBone->parent);
366}
367
369{
370 Mesh *mesh = (Mesh *)ob->data;
372}
373
374std::string bc_url_encode(const std::string &data)
375{
376 /* XXX We probably do not need to do a full encoding.
377 * But in case that is necessary,then it can be added here.
378 */
379 return bc_replace_string(data, "#", "%23");
380}
381
382std::string bc_replace_string(std::string data,
383 const std::string &pattern,
384 const std::string &replacement)
385{
386 size_t pos = 0;
387 while ((pos = data.find(pattern, pos)) != std::string::npos) {
388 data.replace(pos, pattern.length(), replacement);
389 pos += replacement.length();
390 }
391 return data;
392}
393
394void bc_match_scale(Object *ob, UnitConverter &bc_unit, bool scale_to_scene)
395{
396 if (scale_to_scene) {
398 ob->runtime->object_to_world.ptr(), bc_unit.get_scale(), ob->object_to_world().ptr());
399 }
401 ob->runtime->object_to_world.ptr(), bc_unit.get_rotation(), ob->object_to_world().ptr());
402 BKE_object_apply_mat4(ob, ob->object_to_world().ptr(), false, false);
403}
404
405void bc_match_scale(std::vector<Object *> *objects_done,
406 UnitConverter &bc_unit,
407 bool scale_to_scene)
408{
409 for (Object *ob : *objects_done) {
410 if (ob->parent == nullptr) {
411 bc_match_scale(ob, bc_unit, scale_to_scene);
412 }
413 }
414}
415
416void bc_decompose(float mat[4][4], float *loc, float eul[3], float quat[4], float *size)
417{
418 if (size) {
419 mat4_to_size(size, mat);
420 }
421
422 if (eul) {
423 mat4_to_eul(eul, mat);
424 }
425
426 if (quat) {
427 mat4_to_quat(quat, mat);
428 }
429
430 if (loc) {
431 copy_v3_v3(loc, mat[3]);
432 }
433}
434
435void bc_rotate_from_reference_quat(float quat_to[4], float quat_from[4], float mat_to[4][4])
436{
437 float qd[4];
438 float matd[4][4];
439 float mati[4][4];
440 float mat_from[4][4];
441 quat_to_mat4(mat_from, quat_from);
442
443 /* Calculate the difference matrix matd between mat_from and mat_to */
444 invert_m4_m4(mati, mat_from);
445 mul_m4_m4m4(matd, mati, mat_to);
446
447 mat4_to_quat(qd, matd);
448
449 mul_qt_qtqt(quat_to, qd, quat_from); /* rot is the final rotation corresponding to mat_to */
450}
451
453{
454 bool use_beauty = false;
455 bool tag_only = false;
456
457 /* XXX: The triangulation method selection could be offered in the UI. */
458 int quad_method = MOD_TRIANGULATE_QUAD_SHORTEDGE;
459
460 const BMeshCreateParams bm_create_params{};
461 BMesh *bm = BM_mesh_create(&bm_mesh_allocsize_default, &bm_create_params);
462 BMeshFromMeshParams bm_from_me_params{};
463 bm_from_me_params.calc_face_normal = true;
464 bm_from_me_params.calc_vert_normal = true;
465 BM_mesh_bm_from_me(bm, mesh, &bm_from_me_params);
466 BM_mesh_triangulate(bm, quad_method, use_beauty, 4, tag_only, nullptr, nullptr, nullptr);
467
468 BMeshToMeshParams bm_to_me_params{};
469 bm_to_me_params.calc_object_remap = false;
470 BM_mesh_bm_to_me(nullptr, bm, mesh, &bm_to_me_params);
472}
473
475{
476 LISTBASE_FOREACH (Bone *, child, &bone->childbase) {
477 if (child->flag & BONE_CONNECTED) {
478 return false;
479 }
480 }
481 return true;
482}
483
484EditBone *bc_get_edit_bone(bArmature *armature, const char *name)
485{
486 LISTBASE_FOREACH (EditBone *, eBone, armature->edbo) {
487 if (STREQ(name, eBone->name)) {
488 return eBone;
489 }
490 }
491
492 return nullptr;
493}
494int bc_set_layer(int bitfield, int layer)
495{
496 return bc_set_layer(bitfield, layer, true); /* enable */
497}
498
499int bc_set_layer(int bitfield, int layer, bool enable)
500{
501 int bit = 1u << layer;
502
503 if (enable) {
504 bitfield |= bit;
505 }
506 else {
507 bitfield &= ~bit;
508 }
509
510 return bitfield;
511}
512
514{
515 std::string key = armature->id.name;
516 BoneExtensionMap *result = extended_bone_maps[key];
517 if (result == nullptr) {
518 result = new BoneExtensionMap();
519 extended_bone_maps[key] = result;
520 }
521 return *result;
522}
523
525{
526 std::map<std::string, BoneExtensionMap *>::iterator map_it;
527 for (map_it = extended_bone_maps.begin(); map_it != extended_bone_maps.end(); ++map_it) {
528 BoneExtensionMap *extended_bones = map_it->second;
529 for (auto &extended_bone : *extended_bones) {
530 delete extended_bone.second;
531 }
532 extended_bones->clear();
533 delete extended_bones;
534 }
535}
536
538{
539 this->set_name(aBone->name);
540 this->chain_length = 0;
541 this->is_leaf = false;
542 this->tail[0] = 0.0f;
543 this->tail[1] = 0.5f;
544 this->tail[2] = 0.0f;
545 this->use_connect = -1;
546 this->roll = 0;
547
548 this->has_custom_tail = false;
549 this->has_custom_roll = false;
550}
551
553{
554 return name;
555}
556
557void BoneExtended::set_name(const char *aName)
558{
559 STRNCPY(name, aName);
560}
561
563{
564 return chain_length;
565}
566
567void BoneExtended::set_chain_length(const int aLength)
568{
569 chain_length = aLength;
570}
571
573{
574 is_leaf = state;
575}
576
578{
579 return is_leaf;
580}
581
583{
584 this->roll = roll;
585 this->has_custom_roll = true;
586}
587
589{
590 return this->has_custom_roll;
591}
592
594{
595 return this->roll;
596}
597
598void BoneExtended::set_tail(const float vec[])
599{
600 this->tail[0] = vec[0];
601 this->tail[1] = vec[1];
602 this->tail[2] = vec[2];
603 this->has_custom_tail = true;
604}
605
607{
608 return this->has_custom_tail;
609}
610
612{
613 return this->tail;
614}
615
616inline bool isInteger(const std::string &s)
617{
618 if (s.empty() || (!isdigit(s[0]) && (s[0] != '-') && (s[0] != '+'))) {
619 return false;
620 }
621
622 char *p;
623 strtol(s.c_str(), &p, 10);
624
625 return (*p == 0);
626}
627
628void BoneExtended::set_bone_collections(std::vector<std::string> bone_collections)
629{
630 this->bone_collections = bone_collections;
631}
632const std::vector<std::string> &BoneExtended::get_bone_collections()
633{
634 return this->bone_collections;
635}
636
637void BoneExtended::set_use_connect(int use_connect)
638{
639 this->use_connect = use_connect;
640}
641
643{
644 return this->use_connect;
645}
646
647void bc_set_IDPropertyMatrix(EditBone *ebone, const char *key, float mat[4][4])
648{
649 IDProperty *idgroup = ebone->prop;
650 if (idgroup == nullptr) {
651 idgroup = blender::bke::idprop::create_group("RNA_EditBone ID properties").release();
652 ebone->prop = idgroup;
653 }
654
656 key, blender::Span(reinterpret_cast<float *>(mat), 16))
657 .release();
658
659 IDP_AddToGroup(idgroup, data);
660}
661
662#if 0
668static void bc_set_IDProperty(EditBone *ebone, const char *key, float value)
669{
670 if (ebone->prop == nullptr) {
671 IDPropertyTemplate val = {0};
672 ebone->prop = blender::bke::idprop::create_group( "RNA_EditBone ID properties").release();
673 }
674
675 IDProperty *pgroup = (IDProperty *)ebone->prop;
676 IDP_AddToGroup(pgroup, blender::bke::idprop::create(key, value).release());
677}
678#endif
679
680IDProperty *bc_get_IDProperty(Bone *bone, const std::string &key)
681{
682 return (bone->prop == nullptr) ? nullptr : IDP_GetPropertyFromGroup(bone->prop, key.c_str());
683}
684
685float bc_get_property(Bone *bone, const std::string &key, float def)
686{
687 float result = def;
688 IDProperty *property = bc_get_IDProperty(bone, key);
689 if (property) {
690 switch (property->type) {
691 case IDP_INT:
692 result = float(IDP_Int(property));
693 break;
694 case IDP_FLOAT:
695 result = IDP_Float(property);
696 break;
697 case IDP_DOUBLE:
698 result = float(IDP_Double(property));
699 break;
700 case IDP_BOOLEAN:
701 result = float(IDP_Bool(property));
702 break;
703 default:
704 result = def;
705 }
706 }
707 return result;
708}
709
710bool bc_get_property_matrix(Bone *bone, const std::string &key, float mat[4][4])
711{
712 IDProperty *property = bc_get_IDProperty(bone, key);
713 if (property && property->type == IDP_ARRAY && property->len == 16) {
714 float *array = (float *)IDP_Array(property);
715 for (int i = 0; i < 4; i++) {
716 for (int j = 0; j < 4; j++) {
717 mat[i][j] = array[4 * i + j];
718 }
719 }
720 return true;
721 }
722 return false;
723}
724
725void bc_get_property_vector(Bone *bone, const std::string &key, float val[3], const float def[3])
726{
727 val[0] = bc_get_property(bone, key + "_x", def[0]);
728 val[1] = bc_get_property(bone, key + "_y", def[1]);
729 val[2] = bc_get_property(bone, key + "_z", def[2]);
730}
731
735static bool has_custom_props(Bone *bone, bool enabled, const std::string &key)
736{
737 if (!enabled) {
738 return false;
739 }
740
741 return (bc_get_IDProperty(bone, key + "_x") || bc_get_IDProperty(bone, key + "_y") ||
742 bc_get_IDProperty(bone, key + "_z"));
743}
744
745void bc_enable_fcurves(AnimData *adt, const char *bone_name)
746{
747 if (adt == nullptr) {
748 return;
749 }
750
751 char prefix[200];
752
753 if (bone_name) {
754 char bone_name_esc[sizeof(Bone::name) * 2];
755 BLI_str_escape(bone_name_esc, bone_name, sizeof(bone_name_esc));
756 SNPRINTF(prefix, "pose.bones[\"%s\"]", bone_name_esc);
757 }
758
760 if (bone_name) {
761 if (STREQLEN(fcu->rna_path, prefix, strlen(prefix))) {
762 fcu->flag &= ~FCURVE_DISABLED;
763 }
764 else {
765 fcu->flag |= FCURVE_DISABLED;
766 }
767 }
768 else {
769 fcu->flag &= ~FCURVE_DISABLED;
770 }
771 }
772}
773
774bool bc_bone_matrix_local_get(Object *ob, Bone *bone, Matrix &mat, bool for_opensim)
775{
776
777 /* Ok, lets be super cautious and check if the bone exists */
778 bPose *pose = ob->pose;
779 bPoseChannel *pchan = BKE_pose_channel_find_name(pose, bone->name);
780 if (!pchan) {
781 return false;
782 }
783
784 bPoseChannel *parchan = pchan->parent;
785
786 bc_enable_fcurves(ob->adt, bone->name);
787 float ipar[4][4];
788
789 if (bone->parent) {
790 invert_m4_m4(ipar, parchan->pose_mat);
791 mul_m4_m4m4(mat, ipar, pchan->pose_mat);
792 }
793 else {
794 copy_m4_m4(mat, pchan->pose_mat);
795 }
796
797 /* OPEN_SIM_COMPATIBILITY
798 * AFAIK animation to second life is via BVH, but no
799 * reason to not have the collada-animation be correct */
800 if (for_opensim) {
801 float temp[4][4];
802 copy_m4_m4(temp, bone->arm_mat);
803 temp[3][0] = temp[3][1] = temp[3][2] = 0.0f;
804 invert_m4(temp);
805
806 mul_m4_m4m4(mat, mat, temp);
807
808 if (bone->parent) {
809 copy_m4_m4(temp, bone->parent->arm_mat);
810 temp[3][0] = temp[3][1] = temp[3][2] = 0.0f;
811
812 mul_m4_m4m4(mat, temp, mat);
813 }
814 }
815 bc_enable_fcurves(ob->adt, nullptr);
816 return true;
817}
818
820{
821 static float MIN_DISTANCE = 0.00001;
822
823 if (values.size() < 2) {
824 return false; /* need at least 2 entries to be not flat */
825 }
826
827 BCMatrixSampleMap::iterator it;
828 const BCMatrix *refmat = nullptr;
829 for (it = values.begin(); it != values.end(); ++it) {
830 const BCMatrix *matrix = it->second;
831
832 if (refmat == nullptr) {
833 refmat = matrix;
834 continue;
835 }
836
837 if (!matrix->in_range(*refmat, MIN_DISTANCE)) {
838 return true;
839 }
840 }
841 return false;
842}
843
845{
846 /* Check for object, light and camera transform animations */
850 {
851 return true;
852 }
853
854 /* Check Material Effect parameter animations. */
855 for (int a = 0; a < ob->totcol; a++) {
856 Material *ma = BKE_object_material_get(ob, a + 1);
857 if (!ma) {
858 continue;
859 }
861 return true;
862 }
863 }
864
865 Key *key = BKE_key_from_object(ob);
867 return true;
868 }
869
870 return false;
871}
872
873bool bc_has_animations(Scene *sce, LinkNode *export_set)
874{
875 LinkNode *node;
876 if (export_set) {
877 for (node = export_set; node; node = node->next) {
878 Object *ob = (Object *)node->link;
879
880 if (bc_has_animations(ob)) {
881 return true;
882 }
883 }
884 }
885 return false;
886}
887
889 const Matrix &from_mat,
890 const BCMatrix &global_transform,
891 const bool invert)
892{
893 copy_m4_m4(to_mat, from_mat);
894 bc_add_global_transform(to_mat, global_transform, invert);
895}
896
898 const Vector &from_vec,
899 const BCMatrix &global_transform,
900 const bool invert)
901{
902 copy_v3_v3(to_vec, from_vec);
903 bc_add_global_transform(to_vec, global_transform, invert);
904}
905
906void bc_add_global_transform(Matrix &to_mat, const BCMatrix &global_transform, const bool invert)
907{
908 BCMatrix mat(to_mat);
909 mat.add_transform(global_transform, invert);
910 mat.get_matrix(to_mat);
911}
912
913void bc_add_global_transform(Vector &to_vec, const BCMatrix &global_transform, const bool invert)
914{
915 Matrix mat;
916 Vector from_vec;
917 copy_v3_v3(from_vec, to_vec);
918 global_transform.get_matrix(mat, false, 6, invert);
919 mul_v3_m4v3(to_vec, mat, from_vec);
920}
921
922void bc_apply_global_transform(Matrix &to_mat, const BCMatrix &global_transform, const bool invert)
923{
924 BCMatrix mat(to_mat);
925 mat.apply_transform(global_transform, invert);
926 mat.get_matrix(to_mat);
927}
928
929void bc_apply_global_transform(Vector &to_vec, const BCMatrix &global_transform, const bool invert)
930{
932 global_transform.get_matrix(transform);
933 mul_v3_m4v3(to_vec, transform, to_vec);
934}
935
936void bc_create_restpose_mat(BCExportSettings &export_settings,
937 Bone *bone,
938 float to_mat[4][4],
939 float from_mat[4][4],
940 bool use_local_space)
941{
942 float loc[3];
943 float rot[3];
944 float scale[3];
945 static const float V0[3] = {0, 0, 0};
946
947 if (!has_custom_props(bone, export_settings.get_keep_bind_info(), "restpose_loc") &&
948 !has_custom_props(bone, export_settings.get_keep_bind_info(), "restpose_rot") &&
949 !has_custom_props(bone, export_settings.get_keep_bind_info(), "restpose_scale"))
950 {
951 /* No need */
952 copy_m4_m4(to_mat, from_mat);
953 return;
954 }
955
956 bc_decompose(from_mat, loc, rot, nullptr, scale);
957 loc_eulO_size_to_mat4(to_mat, loc, rot, scale, 6);
958
959 if (export_settings.get_keep_bind_info()) {
960 bc_get_property_vector(bone, "restpose_loc", loc, loc);
961
962 if (use_local_space && bone->parent) {
963 Bone *b = bone;
964 while (b->parent) {
965 b = b->parent;
966 float ploc[3];
967 bc_get_property_vector(b, "restpose_loc", ploc, V0);
968 loc[0] += ploc[0];
969 loc[1] += ploc[1];
970 loc[2] += ploc[2];
971 }
972 }
973 }
974
975 if (export_settings.get_keep_bind_info()) {
976 if (bc_get_IDProperty(bone, "restpose_rot_x")) {
977 rot[0] = DEG2RADF(bc_get_property(bone, "restpose_rot_x", 0));
978 }
979 if (bc_get_IDProperty(bone, "restpose_rot_y")) {
980 rot[1] = DEG2RADF(bc_get_property(bone, "restpose_rot_y", 0));
981 }
982 if (bc_get_IDProperty(bone, "restpose_rot_z")) {
983 rot[2] = DEG2RADF(bc_get_property(bone, "restpose_rot_z", 0));
984 }
985 }
986
987 if (export_settings.get_keep_bind_info()) {
988 bc_get_property_vector(bone, "restpose_scale", scale, scale);
989 }
990
991 loc_eulO_size_to_mat4(to_mat, loc, rot, scale, 6);
992}
993
994void bc_sanitize_v3(float v[3], int precision)
995{
996 for (int i = 0; i < 3; i++) {
997 double val = double(v[i]);
998 val = double_round(val, precision);
999 v[i] = float(val);
1000 }
1001}
1002
1003void bc_sanitize_v3(double v[3], int precision)
1004{
1005 for (int i = 0; i < 3; i++) {
1006 v[i] = double_round(v[i], precision);
1007 }
1008}
1009
1010void bc_copy_m4_farray(float r[4][4], float *a)
1011{
1012 for (int i = 0; i < 4; i++) {
1013 for (int j = 0; j < 4; j++) {
1014 r[i][j] = *a++;
1015 }
1016 }
1017}
1018
1019void bc_copy_farray_m4(float *r, float a[4][4])
1020{
1021 for (int i = 0; i < 4; i++) {
1022 for (int j = 0; j < 4; j++) {
1023 *r++ = a[i][j];
1024 }
1025 }
1026}
1027
1028void bc_copy_darray_m4d(double *r, double a[4][4])
1029{
1030 for (int i = 0; i < 4; i++) {
1031 for (int j = 0; j < 4; j++) {
1032 *r++ = a[i][j];
1033 }
1034 }
1035}
1036
1037void bc_copy_v44_m4d(std::vector<std::vector<double>> &r, double (&a)[4][4])
1038{
1039 for (int i = 0; i < 4; i++) {
1040 for (int j = 0; j < 4; j++) {
1041 r[i][j] = a[i][j];
1042 }
1043 }
1044}
1045
1046void bc_copy_m4d_v44(double (&r)[4][4], std::vector<std::vector<double>> &a)
1047{
1048 for (int i = 0; i < 4; i++) {
1049 for (int j = 0; j < 4; j++) {
1050 r[i][j] = a[i][j];
1051 }
1052 }
1053}
1054
1058static std::string bc_get_active_uvlayer_name(Mesh *mesh)
1059{
1060 int num_layers = CustomData_number_of_layers(&mesh->corner_data, CD_PROP_FLOAT2);
1061 if (num_layers) {
1062 const char *layer_name = bc_CustomData_get_active_layer_name(&mesh->corner_data,
1064 if (layer_name) {
1065 return std::string(layer_name);
1066 }
1067 }
1068 return "";
1069}
1070
1075static std::string bc_get_active_uvlayer_name(Object *ob)
1076{
1077 Mesh *mesh = (Mesh *)ob->data;
1078 return bc_get_active_uvlayer_name(mesh);
1079}
1080
1084static std::string bc_get_uvlayer_name(Mesh *mesh, int layer)
1085{
1086 int num_layers = CustomData_number_of_layers(&mesh->corner_data, CD_PROP_FLOAT2);
1087 if (num_layers && layer < num_layers) {
1088 const char *layer_name = bc_CustomData_get_layer_name(
1089 &mesh->corner_data, CD_PROP_FLOAT2, layer);
1090 if (layer_name) {
1091 return std::string(layer_name);
1092 }
1093 }
1094 return "";
1095}
1096
1098{
1099 if (ma->nodetree == nullptr) {
1101 nullptr, &ma->id, "Shader Nodetree", "ShaderNodeTree");
1102 ma->use_nodes = true;
1103 }
1104 return ma->nodetree;
1105}
1106
1108 bContext *C, bNodeTree *ntree, int node_type, int locx, int locy, const std::string &label)
1109{
1110 bNode *node = blender::bke::node_add_static_node(C, *ntree, node_type);
1111 if (node) {
1112 if (label.length() > 0) {
1113 STRNCPY(node->label, label.c_str());
1114 }
1115 node->location[0] = locx;
1116 node->location[1] = locy;
1117 node->flag |= NODE_SELECT;
1118 }
1119 return node;
1120}
1121
1122static bNode *bc_add_node(bContext *C, bNodeTree *ntree, int node_type, int locx, int locy)
1123{
1124 return bc_add_node(C, ntree, node_type, locx, locy, "");
1125}
1126
1128 bNodeTree *ntree, bNode *from_node, int from_index, bNode *to_node, int to_index)
1129{
1130 bNodeSocket *from_socket = (bNodeSocket *)BLI_findlink(&from_node->outputs, from_index);
1131 bNodeSocket *to_socket = (bNodeSocket *)BLI_findlink(&to_node->inputs, to_index);
1132
1133 blender::bke::node_add_link(*ntree, *from_node, *from_socket, *to_node, *to_socket);
1134}
1135
1137{
1139 std::map<std::string, bNode *> nmap;
1140#if 0
1141 nmap["main"] = bc_add_node(C, ntree, SH_NODE_BSDF_PRINCIPLED, -300, 300);
1142 nmap["emission"] = bc_add_node(C, ntree, SH_NODE_EMISSION, -300, 500, "emission");
1143 nmap["add"] = bc_add_node(C, ntree, SH_NODE_ADD_SHADER, 100, 400);
1144 nmap["transparent"] = bc_add_node(C, ntree, SH_NODE_BSDF_TRANSPARENT, 100, 200);
1145 nmap["mix"] = bc_add_node(C, ntree, SH_NODE_MIX_SHADER, 400, 300, "transparency");
1146 nmap["out"] = bc_add_node(C, ntree, SH_NODE_OUTPUT_MATERIAL, 600, 300);
1147 nmap["out"]->flag &= ~NODE_SELECT;
1148
1149 bc_node_add_link(ntree, nmap["emission"], 0, nmap["add"], 0);
1150 bc_node_add_link(ntree, nmap["main"], 0, nmap["add"], 1);
1151 bc_node_add_link(ntree, nmap["add"], 0, nmap["mix"], 1);
1152 bc_node_add_link(ntree, nmap["transparent"], 0, nmap["mix"], 2);
1153
1154 bc_node_add_link(ntree, nmap["mix"], 0, nmap["out"], 0);
1155 /* experimental, probably not used. */
1156 bc_make_group(C, ntree, nmap);
1157#else
1158 nmap["main"] = bc_add_node(C, ntree, SH_NODE_BSDF_PRINCIPLED, 0, 300);
1159 nmap["out"] = bc_add_node(C, ntree, SH_NODE_OUTPUT_MATERIAL, 300, 300);
1160 bc_node_add_link(ntree, nmap["main"], 0, nmap["out"], 0);
1161#endif
1162}
1163
1164COLLADASW::ColorOrTexture bc_get_base_color(Material *ma)
1165{
1166 /* for alpha see bc_get_alpha() */
1167 Color default_color = {ma->r, ma->g, ma->b, 1.0};
1168 bNode *shader = bc_get_master_shader(ma);
1169 if (ma->use_nodes && shader) {
1170 return bc_get_cot_from_shader(shader, "Base Color", default_color, false);
1171 }
1172
1173 return bc_get_cot(default_color);
1174}
1175
1176COLLADASW::ColorOrTexture bc_get_emission(Material *ma)
1177{
1178 Color default_color = {0, 0, 0, 1}; /* default black */
1179 bNode *shader = bc_get_master_shader(ma);
1180 if (!(ma->use_nodes && shader)) {
1181 return bc_get_cot(default_color);
1182 }
1183
1184 double emission_strength = 0.0;
1185 bc_get_float_from_shader(shader, emission_strength, "Emission Strength");
1186 if (emission_strength == 0.0) {
1187 return bc_get_cot(default_color);
1188 }
1189
1190 COLLADASW::ColorOrTexture cot = bc_get_cot_from_shader(shader, "Emission Color", default_color);
1191
1192 /* If using texture, emission strength is not supported. */
1193 COLLADASW::Color col = cot.getColor();
1194 double final_color[3] = {col.getRed(), col.getGreen(), col.getBlue()};
1195 mul_v3db_db(final_color, emission_strength);
1196
1197 /* Collada does not support HDR colors, so clamp to 1 keeping channels proportional. */
1198 double max_color = fmax(fmax(final_color[0], final_color[1]), final_color[2]);
1199 if (max_color > 1.0) {
1200 mul_v3db_db(final_color, 1.0 / max_color);
1201 }
1202
1203 cot.getColor().set(final_color[0], final_color[1], final_color[2], col.getAlpha());
1204
1205 return cot;
1206}
1207
1208COLLADASW::ColorOrTexture bc_get_ambient(Material *ma)
1209{
1210 Color default_color = {0, 0, 0, 1.0};
1211 return bc_get_cot(default_color);
1212}
1213
1214COLLADASW::ColorOrTexture bc_get_specular(Material *ma)
1215{
1216 Color default_color = {0, 0, 0, 1.0};
1217 return bc_get_cot(default_color);
1218}
1219
1220COLLADASW::ColorOrTexture bc_get_reflective(Material *ma)
1221{
1222 Color default_color = {0, 0, 0, 1.0};
1223 return bc_get_cot(default_color);
1224}
1225
1227{
1228 double alpha = ma->a; /* fallback if no socket found */
1229 bNode *master_shader = bc_get_master_shader(ma);
1230 if (ma->use_nodes && master_shader) {
1231 bc_get_float_from_shader(master_shader, alpha, "Alpha");
1232 }
1233 return alpha;
1234}
1235
1237{
1238 double ior = -1; /* fallback if no socket found */
1239 bNode *master_shader = bc_get_master_shader(ma);
1240 if (ma->use_nodes && master_shader) {
1241 bc_get_float_from_shader(master_shader, ior, "IOR");
1242 }
1243 return ior;
1244}
1245
1247{
1248 double ior = -1; /* fallback if no socket found */
1249 bNode *master_shader = bc_get_master_shader(ma);
1250 if (ma->use_nodes && master_shader) {
1251 bc_get_float_from_shader(master_shader, ior, "Roughness");
1252 }
1253 return ior;
1254}
1255
1257{
1258 double reflectivity = ma->spec; /* fallback if no socket found */
1259 bNode *master_shader = bc_get_master_shader(ma);
1260 if (ma->use_nodes && master_shader) {
1261 bc_get_float_from_shader(master_shader, reflectivity, "Metallic");
1262 }
1263 return reflectivity;
1264}
1265
1266bool bc_get_float_from_shader(bNode *shader, double &val, std::string nodeid)
1267{
1268 bNodeSocket *socket = blender::bke::node_find_socket(*shader, SOCK_IN, nodeid);
1269 if (socket) {
1271 val = double(ref->value);
1272 return true;
1273 }
1274 return false;
1275}
1276
1277COLLADASW::ColorOrTexture bc_get_cot_from_shader(bNode *shader,
1278 std::string nodeid,
1279 const Color &default_color,
1280 bool with_alpha)
1281{
1282 bNodeSocket *socket = blender::bke::node_find_socket(*shader, SOCK_IN, nodeid);
1283 if (socket) {
1285 float *col = dcol->value;
1286 return bc_get_cot(col, with_alpha);
1287 }
1288
1289 return bc_get_cot(default_color, with_alpha);
1290}
1291
1293{
1294 bNodeTree *nodetree = ma->nodetree;
1295 if (nodetree) {
1296 for (bNode *node : nodetree->all_nodes()) {
1297 if (node->typeinfo->type_legacy == SH_NODE_BSDF_PRINCIPLED) {
1298 return node;
1299 }
1300 }
1301 }
1302 return nullptr;
1303}
1304
1305COLLADASW::ColorOrTexture bc_get_cot(float r, float g, float b, float a)
1306{
1307 COLLADASW::Color color(r, g, b, a);
1308 COLLADASW::ColorOrTexture cot(color);
1309 return cot;
1310}
1311
1312COLLADASW::ColorOrTexture bc_get_cot(const Color col, bool with_alpha)
1313{
1314 COLLADASW::Color color(col[0], col[1], col[2], (with_alpha) ? col[3] : 1.0);
1315 COLLADASW::ColorOrTexture cot(color);
1316 return cot;
1317}
Functions and classes to work with Actions.
Functions for backward compatibility with the legacy Action API.
C++ functions to deal with Armature collections (i.e. the successor of bone layers).
void ANIM_bonecoll_hide(bArmature *armature, BoneCollection *bcoll)
void ANIM_armature_bonecoll_active_name_set(bArmature *armature, const char *name)
void ANIM_bonecoll_show(bArmature *armature, BoneCollection *bcoll)
BoneCollection * ANIM_armature_bonecoll_new(bArmature *armature, const char *name, int parent_index=-1)
std::map< int, const BCMatrix * > BCMatrixSampleMap
Blender kernel action and pose functionality.
bPoseChannel * BKE_pose_channel_find_name(const bPose *pose, const char *name)
bool BKE_collection_object_add(Main *bmain, Collection *collection, Object *ob)
const bConstraintTypeInfo * BKE_constraint_typeinfo_get(struct bConstraint *con)
Scene * CTX_data_scene(const bContext *C)
Main * CTX_data_main(const bContext *C)
CustomData interface, see also DNA_customdata_types.h.
int CustomData_get_active_layer_index(const CustomData *data, eCustomDataType type)
int CustomData_number_of_layers(const CustomData *data, eCustomDataType type)
#define IDP_Float(prop)
IDProperty * IDP_GetPropertyFromGroup(const IDProperty *prop, blender::StringRef name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition idprop.cc:766
#define IDP_Int(prop)
#define IDP_Bool(prop)
#define IDP_Double(prop)
bool IDP_AddToGroup(IDProperty *group, IDProperty *prop) ATTR_NONNULL()
Definition idprop.cc:725
#define IDP_Array(prop)
Key * BKE_key_from_object(Object *ob)
Definition key.cc:1824
LayerCollection * BKE_layer_collection_get_active(ViewLayer *view_layer)
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
Base * BKE_view_layer_base_find(ViewLayer *view_layer, Object *ob)
void BKE_view_layer_base_select_and_set_active(ViewLayer *view_layer, Base *selbase)
General operations, lookup, etc. for materials.
Material * BKE_object_material_get(Object *ob, short act)
Mesh * BKE_mesh_copy_for_eval(const Mesh &source)
void BKE_mesh_tessface_ensure(Mesh *mesh)
void BKE_mesh_wrapper_ensure_mdata(Mesh *mesh)
#define SH_NODE_MIX_SHADER
#define SH_NODE_BSDF_PRINCIPLED
#define SH_NODE_EMISSION
#define SH_NODE_ADD_SHADER
#define SH_NODE_BSDF_TRANSPARENT
#define SH_NODE_OUTPUT_MATERIAL
General operations, lookup, etc. for blender objects.
void BKE_object_apply_mat4(Object *ob, const float mat[4][4], bool use_compat, bool use_parent)
void * BKE_object_obdata_add_from_type(Main *bmain, int type, const char *name) ATTR_NONNULL(1)
Mesh * BKE_object_get_evaluated_mesh(const Object *object_eval)
Object * BKE_object_add_only_object(Main *bmain, int type, const char *name) ATTR_RETURNS_NONNULL
void BKE_scene_frame_set(Scene *scene, float frame)
Definition scene.cc:2386
void * BLI_findlink(const ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:534
#define LISTBASE_FOREACH(type, var, list)
double double_round(double x, int ndigits)
Definition math_base.cc:28
#define DEG2RADF(_deg)
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
void loc_eulO_size_to_mat4(float R[4][4], const float loc[3], const float eul[3], const float size[3], short order)
void copy_m4_m4(float m1[4][4], const float m2[4][4])
void mul_v3_m4v3(float r[3], const float mat[4][4], const float vec[3])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
bool invert_m4(float mat[4][4])
void mat4_to_size(float size[3], const float M[4][4])
void mat4_to_eul(float eul[3], const float mat[4][4])
void quat_to_mat4(float m[4][4], const float q[4])
void mul_qt_qtqt(float q[4], const float a[4], const float b[4])
void mat4_to_quat(float q[4], const float mat[4][4])
MINLINE void mul_v3db_db(double r[3], double f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
#define SNPRINTF(dst, format,...)
Definition BLI_string.h:599
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:688
size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
unsigned int uint
#define STREQLEN(a, b, n)
#define STREQ(a, b)
float[3] Vector
float[4][4] Matrix
float[4] Color
void DEG_id_tag_update(ID *id, unsigned int flags)
T * DEG_get_evaluated(const Depsgraph *depsgraph, T *id)
@ ID_RECALC_TRANSFORM
Definition DNA_ID.h:962
@ ID_RECALC_ANIMATION
Definition DNA_ID.h:985
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:982
@ IDP_DOUBLE
@ IDP_FLOAT
@ IDP_BOOLEAN
@ IDP_INT
@ IDP_ARRAY
@ FCURVE_DISABLED
@ BONE_NO_DEFORM
@ BONE_CONNECTED
@ CONSTRAINT_OFF
@ CONSTRAINT_DISABLE
@ CD_PROP_FLOAT2
@ MOD_TRIANGULATE_QUAD_SHORTEDGE
@ eModifierType_Armature
@ NODE_SELECT
@ SOCK_IN
Object is a sort of wrapper for general info.
@ OB_ARMATURE
@ PARSKEL
void ED_update_for_newframe(Main *bmain, Depsgraph *depsgraph)
BC_export_mesh_type
@ BC_MESH_TYPE_RENDER
@ BC_MESH_TYPE_VIEW
#define C
Definition RandGen.cpp:29
BMesh const char void * data
BMesh * bm
const BMAllocTemplate bm_mesh_allocsize_default
Definition bmesh_mesh.cc:30
void BM_mesh_free(BMesh *bm)
BMesh Free Mesh.
BMesh * BM_mesh_create(const BMAllocTemplate *allocsize, const BMeshCreateParams *params)
BMesh Make Mesh.
void BM_mesh_bm_from_me(BMesh *bm, const Mesh *mesh, const BMeshFromMeshParams *params)
void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *mesh, const BMeshToMeshParams *params)
ATTR_WARN_UNUSED_RESULT const BMVert * v
void BM_mesh_triangulate(BMesh *bm, const int quad_method, const int ngon_method, const int min_vertices, const bool tag_only, BMOperator *op, BMOpSlot *slot_facemap_out, BMOpSlot *slot_facemap_double_out)
BPy_StructRNA * depsgraph
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
void add_transform(Matrix &to, const Matrix &transform, const Matrix &from, bool inverted=false)
Definition BCMath.cpp:73
void get_matrix(DMatrix &matrix, bool transposed=false, int precision=-1) const
Definition BCMath.cpp:167
void apply_transform(Matrix &to, const Matrix &transform, const Matrix &from, bool inverse=false)
Definition BCMath.cpp:88
bool in_range(const BCMatrix &other, float distance) const
Definition BCMath.cpp:200
Depsgraph * get_depsgraph()
void set_use_connect(int use_connect)
void set_roll(float roll)
const std::vector< std::string > & get_bone_collections()
void set_bone_collections(std::vector< std::string > bone_collections)
void set_tail(const float vec[])
void set_leaf_bone(bool state)
float * get_tail()
BoneExtended(EditBone *aBone)
void set_chain_length(int aLength)
void set_name(const char *aName)
BoneExtensionMap & getExtensionMap(bArmature *armature)
Class for saving <extra> tags for a specific UniqueId.
Definition ExtraTags.h:17
std::vector< std::string > dataSplitString(const std::string &tag)
bool setData(std::string tag, short *data)
Definition ExtraTags.cpp:66
float(& get_scale())[4]
float(& get_rotation())[4]
std::string translate_id(const char *idString)
Object * bc_add_object(Main *bmain, Scene *scene, ViewLayer *view_layer, int type, const char *name)
COLLADASW::ColorOrTexture bc_get_specular(Material *ma)
COLLADASW::ColorOrTexture bc_get_ambient(Material *ma)
bool bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space)
IDProperty * bc_get_IDProperty(Bone *bone, const std::string &key)
void bc_copy_farray_m4(float *r, float a[4][4])
void bc_enable_fcurves(AnimData *adt, const char *bone_name)
bool bc_is_root_bone(Bone *aBone, bool deform_bones_only)
double bc_get_alpha(Material *ma)
void bc_add_global_transform(Matrix &to_mat, const Matrix &from_mat, const BCMatrix &global_transform, const bool invert)
bNode * bc_get_master_shader(Material *ma)
void bc_sanitize_v3(float v[3], int precision)
std::vector< bAction * > bc_getSceneActions(const bContext *C, Object *ob, bool all_actions)
COLLADASW::ColorOrTexture bc_get_cot(float r, float g, float b, float a)
std::string bc_url_encode(const std::string &data)
bool bc_has_animations(Object *ob)
void bc_apply_global_transform(Matrix &to_mat, const BCMatrix &global_transform, const bool invert)
COLLADASW::ColorOrTexture bc_get_emission(Material *ma)
COLLADASW::ColorOrTexture bc_get_reflective(Material *ma)
static bNode * bc_add_node(bContext *C, bNodeTree *ntree, int node_type, int locx, int locy, const std::string &label)
static std::string bc_get_uvlayer_name(Mesh *mesh, int layer)
bool isInteger(const std::string &s)
static bool has_custom_props(Bone *bone, bool enabled, const std::string &key)
void bc_rotate_from_reference_quat(float quat_to[4], float quat_from[4], float mat_to[4][4])
double bc_get_reflectivity(Material *ma)
static void bc_add_armature_collections(COLLADAFW::Node *node, ExtraTags *node_extra_tags, bArmature *arm)
COLLADASW::ColorOrTexture bc_get_cot_from_shader(bNode *shader, std::string nodeid, const Color &default_color, bool with_alpha)
void bc_copy_m4d_v44(double(&r)[4][4], std::vector< std::vector< double > > &a)
void bc_match_scale(Object *ob, UnitConverter &bc_unit, bool scale_to_scene)
Object * bc_get_assigned_armature(Object *ob)
float bc_get_property(Bone *bone, const std::string &key, float def)
void bc_add_default_shader(bContext *C, Material *ma)
Object * bc_add_armature(COLLADAFW::Node *node, ExtraTags *node_extra_tags, Main *bmain, Scene *scene, ViewLayer *view_layer, int type, const char *name)
static void bc_node_add_link(bNodeTree *ntree, bNode *from_node, int from_index, bNode *to_node, int to_index)
void bc_set_IDPropertyMatrix(EditBone *ebone, const char *key, float mat[4][4])
std::string bc_get_action_id(const std::string &action_name, const std::string &ob_name, const std::string &channel_type, const std::string &axis_name, const std::string &axis_separator)
bool bc_is_animated(BCMatrixSampleMap &values)
void bc_triangulate_mesh(Mesh *mesh)
void bc_create_restpose_mat(BCExportSettings &export_settings, Bone *bone, float to_mat[4][4], float from_mat[4][4], bool use_local_space)
bool bc_get_float_from_shader(bNode *shader, double &val, std::string nodeid)
int bc_get_active_UVLayer(Object *ob)
static std::string bc_get_active_uvlayer_name(Mesh *mesh)
void bc_bubble_sort_by_Object_name(LinkNode *export_set)
EditBone * bc_get_edit_bone(bArmature *armature, const char *name)
bool bc_validateConstraints(bConstraint *con)
Mesh * bc_get_mesh_copy(BlenderContext &blender_context, Object *ob, BC_export_mesh_type export_mesh_type, bool apply_modifiers, bool triangulate)
double bc_get_shininess(Material *ma)
COLLADASW::ColorOrTexture bc_get_base_color(Material *ma)
static bNodeTree * prepare_material_nodetree(Material *ma)
double bc_get_ior(Material *ma)
void bc_get_property_vector(Bone *bone, const std::string &key, float val[3], const float def[3])
int bc_set_layer(int bitfield, int layer)
void bc_copy_v44_m4d(std::vector< std::vector< double > > &r, double(&a)[4][4])
void bc_update_scene(BlenderContext &blender_context, float ctime)
std::string bc_replace_string(std::string data, const std::string &pattern, const std::string &replacement)
bool bc_bone_matrix_local_get(Object *ob, Bone *bone, Matrix &mat, bool for_opensim)
float bc_get_float_value(const COLLADAFW::FloatOrDoubleArray &array, uint index)
void bc_copy_darray_m4d(double *r, double a[4][4])
void bc_decompose(float mat[4][4], float *loc, float eul[3], float quat[4], float *size)
void bc_copy_m4_farray(float r[4][4], float *a)
bool bc_get_property_matrix(Bone *bone, const std::string &key, float mat[4][4])
bool bc_has_object_type(LinkNode *export_set, short obtype)
bool bc_is_leaf_bone(Bone *bone)
int bc_test_parent_loop(Object *par, Object *ob)
const char * bc_CustomData_get_active_layer_name(const CustomData *data, eCustomDataType type)
AnimData * bc_getSceneLightAnimData(Object *ob)
AnimData * bc_getSceneCameraAnimData(Object *ob)
const char * bc_CustomData_get_layer_name(const CustomData *data, eCustomDataType type, int n)
void bc_set_IDProperty(EditBone *ebone, const char *key, float value)
bAction * bc_getSceneObjectAction(Object *ob)
AnimData * bc_getSceneMaterialAnimData(Material *ma)
std::map< std::string, BoneExtended * > BoneExtensionMap
#define rot(x, k)
uint pos
uint col
VecBase< float, D > constexpr mod(VecOp< float, D >, VecOp< float, D >) RET
bool enabled
CCL_NAMESPACE_BEGIN ccl_device float invert(const float color, const float factor)
Definition invert.h:11
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
static ulong state[N]
Vector< FCurve * > fcurves_for_assigned_action(AnimData *adt)
bool assigned_action_has_keyframes(AnimData *adt)
std::unique_ptr< IDProperty, IDPropertyDeleter > create(StringRef prop_name, int32_t value, eIDPropertyFlag flags={})
Allocate a new IDProperty of type IDP_INT, set its name and value.
std::unique_ptr< IDProperty, IDPropertyDeleter > create_group(StringRef prop_name, eIDPropertyFlag flags={})
Allocate a new IDProperty of type IDP_GROUP.
bNodeTree * node_tree_add_tree_embedded(Main *bmain, ID *owner_id, StringRefNull name, StringRefNull idname)
Definition node.cc:4375
bNodeSocket * node_find_socket(bNode &node, eNodeSocketInOut in_out, StringRef identifier)
Definition node.cc:2864
bNode * node_add_static_node(const bContext *C, bNodeTree &ntree, int type)
Definition node.cc:3804
bNodeLink & node_add_link(bNodeTree &ntree, bNode &fromnode, bNodeSocket &fromsock, bNode &tonode, bNodeSocket &tosock)
Definition node.cc:4087
bool parent_set(ReportList *reports, const bContext *C, Scene *scene, Object *const ob, Object *const par, int partype, bool xmirror, bool keep_transform, const int vert_par[3])
struct Bone * parent
char name[64]
IDProperty * prop
float arm_mat[4][4]
ListBase childbase
char name[64]
IDProperty * prop
Definition DNA_ID.h:404
void * next
Definition DNA_ID.h:407
char name[66]
Definition DNA_ID.h:415
struct AnimData * adt
struct Collection * collection
void * link
struct LinkNode * next
void * first
ListBase actions
Definition BKE_main.hh:269
struct bNodeTree * nodetree
CustomData corner_data
struct bPose * pose
ObjectRuntimeHandle * runtime
ListBase modifiers
struct AnimData * adt
struct Object * parent
ListBase * edbo
void(* evaluate_constraint)(struct bConstraint *con, struct bConstraintOb *cob, struct ListBase *targets)
void * default_value
float location[2]
ListBase inputs
char label[64]
ListBase outputs
struct bPoseChannel * parent
float pose_mat[4][4]
i
Definition text_draw.cc:230