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