Blender  V3.3
collada_internal.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
7 /* COLLADABU_ASSERT, may be able to remove later */
8 #include "COLLADABUPlatform.h"
9 #include "collada_utils.h"
10 
11 #include "BLI_linklist.h"
12 
13 #include "BKE_armature.h"
14 
15 UnitConverter::UnitConverter() : up_axis(COLLADAFW::FileInfo::Z_UP)
16 {
17  axis_angle_to_mat4_single(x_up_mat4, 'Y', -M_PI_2);
18  axis_angle_to_mat4_single(y_up_mat4, 'X', M_PI_2);
19 
20  unit_m4(z_up_mat4);
21  unit_m4(scale_mat4);
22 }
23 
24 void UnitConverter::read_asset(const COLLADAFW::FileInfo *asset)
25 {
26  unit = asset->getUnit();
27  up_axis = asset->getUpAxisType();
28 }
29 
31 {
32  switch (unit.getLinearUnitUnit()) {
33  case COLLADAFW::FileInfo::Unit::MILLIMETER:
34  case COLLADAFW::FileInfo::Unit::CENTIMETER:
35  case COLLADAFW::FileInfo::Unit::DECIMETER:
36  case COLLADAFW::FileInfo::Unit::METER:
37  case COLLADAFW::FileInfo::Unit::KILOMETER:
38  return UnitConverter::Metric;
39  case COLLADAFW::FileInfo::Unit::INCH:
40  case COLLADAFW::FileInfo::Unit::FOOT:
41  case COLLADAFW::FileInfo::Unit::YARD:
43  default:
44  return UnitConverter::None;
45  }
46 }
47 
49 {
50  return (float)unit.getLinearUnitMeter();
51 }
52 
54 {
55  v[0] = vec.x;
56  v[1] = vec.y;
57  v[2] = vec.z;
58 }
59 
60 /* TODO: need also for angle conversion, time conversion... */
61 
62 void UnitConverter::dae_matrix_to_mat4_(float out[4][4], const COLLADABU::Math::Matrix4 &in)
63 {
64  /* in DAE, matrices use columns vectors, (see comments in COLLADABUMathMatrix4.h)
65  * so here, to make a blender matrix, we swap columns and rows. */
66  for (int i = 0; i < 4; i++) {
67  for (int j = 0; j < 4; j++) {
68  out[i][j] = in[j][i];
69  }
70  }
71 }
72 
73 void UnitConverter::mat4_to_dae(float out[4][4], float in[4][4])
74 {
75  transpose_m4_m4(out, in);
76 }
77 
78 void UnitConverter::mat4_to_dae_double(double out[4][4], float in[4][4])
79 {
80  float mat[4][4];
81 
82  mat4_to_dae(mat, in);
83 
84  for (int i = 0; i < 4; i++) {
85  for (int j = 0; j < 4; j++) {
86  out[i][j] = mat[i][j];
87  }
88  }
89 }
90 
92 {
93  switch (up_axis) {
94  case COLLADAFW::FileInfo::X_UP:
95  return x_up_mat4;
96  break;
97  case COLLADAFW::FileInfo::Y_UP:
98  return y_up_mat4;
99  break;
100  default:
101  return z_up_mat4;
102  break;
103  }
104 }
105 
107 {
108  return scale_mat4;
109 }
110 
112 {
113  PointerRNA scene_ptr, unit_settings;
114  PropertyRNA *system_ptr, *scale_ptr;
115  RNA_id_pointer_create(&sce.id, &scene_ptr);
116 
117  unit_settings = RNA_pointer_get(&scene_ptr, "unit_settings");
118  system_ptr = RNA_struct_find_property(&unit_settings, "system");
119  scale_ptr = RNA_struct_find_property(&unit_settings, "scale_length");
120 
121  int type = RNA_property_enum_get(&unit_settings, system_ptr);
122 
123  float bl_scale;
124 
125  switch (type) {
126  case USER_UNIT_NONE:
127  bl_scale = 1.0; /* map 1 Blender unit to 1 Meter. */
128  break;
129 
130  case USER_UNIT_METRIC:
131  bl_scale = RNA_property_float_get(&unit_settings, scale_ptr);
132  break;
133 
134  default:
135  bl_scale = RNA_property_float_get(&unit_settings, scale_ptr);
136  /* It looks like the conversion to Imperial is done implicitly.
137  * So nothing to do here. */
138  break;
139  }
140 
141  float rescale[3];
142  rescale[0] = rescale[1] = rescale[2] = getLinearMeter() / bl_scale;
143 
144  size_to_mat4(scale_mat4, rescale);
145 }
146 
156 const unsigned char translate_start_name_map[256] = {
157 
158  95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
159  95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
160  95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
161  95, 95, 95, 95, 95, 95, 95, 95, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
162  76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 95, 95, 95, 95,
163  95, 95, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
164  114, 115, 116, 117, 118, 119, 120, 121, 122, 95, 95, 95, 95, 95,
165 
166  128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146,
167  147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165,
168  166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184,
169  185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203,
170  204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222,
171  223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241,
172  242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255,
173 };
174 
175 const unsigned char translate_name_map[256] = {
176 
177  95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
178  95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
179  95, 95, 95, 95, 95, 95, 95, 45, 95, 95, 48, 49, 50, 51, 52, 53, 54, 55, 56,
180  57, 95, 95, 95, 95, 95, 95, 95, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
181  76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 95, 95, 95, 95,
182  95, 95, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
183  114, 115, 116, 117, 118, 119, 120, 121, 122, 95, 95, 95, 95, 95,
184 
185  128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146,
186  147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165,
187  166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184,
188  185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203,
189  204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222,
190  223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241,
191  242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255,
192 };
193 
194 using map_string_list = std::map<std::string, std::vector<std::string>>;
196 
198 {
199  global_id_map.clear();
200 }
201 
202 std::string translate_id(const char *idString)
203 {
204  std::string id = std::string(idString);
205  return translate_id(id);
206 }
207 
208 std::string translate_id(const std::string &id)
209 {
210  if (id.empty()) {
211  return id;
212  }
213 
214  std::string id_translated = id;
215  id_translated[0] = translate_start_name_map[(unsigned int)id_translated[0]];
216  for (unsigned int i = 1; i < id_translated.size(); i++) {
217  id_translated[i] = translate_name_map[(unsigned int)id_translated[i]];
218  }
219  /* It's so much workload now, the if () should speed up things. */
220  if (id_translated != id) {
221  /* Search duplicates. */
222  map_string_list::iterator iter = global_id_map.find(id_translated);
223  if (iter != global_id_map.end()) {
224  unsigned int i = 0;
225  bool found = false;
226  for (i = 0; i < iter->second.size(); i++) {
227  if (id == iter->second[i]) {
228  found = true;
229  break;
230  }
231  }
232  bool convert = false;
233  if (found) {
234  if (i > 0) {
235  convert = true;
236  }
237  }
238  else {
239  convert = true;
240  global_id_map[id_translated].push_back(id);
241  }
242  if (convert) {
243  std::stringstream out;
244  out << ++i;
245  id_translated += out.str();
246  }
247  }
248  else {
249  global_id_map[id_translated].push_back(id);
250  }
251  }
252  return id_translated;
253 }
254 
255 std::string id_name(void *id)
256 {
257  return ((ID *)id)->name + 2;
258 }
259 
260 std::string encode_xml(std::string xml)
261 {
262  const std::map<char, std::string> escape{
263  {'<', "&lt;"}, {'>', "&gt;"}, {'"', "&quot;"}, {'\'', "&apos;"}, {'&', "&amp;"}};
264 
265  std::map<char, std::string>::const_iterator it;
266  std::string encoded_xml;
267 
268  for (char c : xml) {
269  it = escape.find(c);
270 
271  if (it == escape.end()) {
272  encoded_xml += c;
273  }
274  else {
275  encoded_xml += it->second;
276  }
277  }
278  return encoded_xml;
279 }
280 
281 std::string get_geometry_id(Object *ob)
282 {
283  return translate_id(id_name(ob->data)) + "-mesh";
284 }
285 
286 std::string get_geometry_id(Object *ob, bool use_instantiation)
287 {
288  std::string geom_name = (use_instantiation) ? id_name(ob->data) : id_name(ob);
289 
290  return translate_id(geom_name) + "-mesh";
291 }
292 
293 std::string get_light_id(Object *ob)
294 {
295  return translate_id(id_name(ob)) + "-light";
296 }
297 
298 std::string get_joint_sid(Bone *bone)
299 {
300  return translate_id(bone->name);
301 }
302 static std::string get_joint_sid(EditBone *bone)
303 {
304  return translate_id(bone->name);
305 }
306 
307 std::string get_camera_id(Object *ob)
308 {
309  return translate_id(id_name(ob)) + "-camera";
310 }
311 
312 std::string get_effect_id(Material *mat)
313 {
314  return translate_id(id_name(mat)) + "-effect";
315 }
316 
317 std::string get_material_id(Material *mat)
318 {
319  return translate_id(id_name(mat)) + "-material";
320 }
321 
322 std::string get_morph_id(Object *ob)
323 {
324  return translate_id(id_name(ob)) + "-morph";
325 }
typedef float(TangentPoint)[2]
#define M_PI_2
Definition: BLI_math_base.h:23
void transpose_m4_m4(float R[4][4], const float M[4][4])
Definition: math_matrix.c:1403
void unit_m4(float m[4][4])
Definition: rct.c:1090
void size_to_mat4(float R[4][4], const float size[3])
Definition: math_matrix.c:2111
void axis_angle_to_mat4_single(float R[4][4], char axis, float angle)
#define USER_UNIT_METRIC
#define USER_UNIT_NONE
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
ATTR_WARN_UNUSED_RESULT const BMVert * v
void read_asset(const COLLADAFW::FileInfo *asset)
float(& get_scale())[4]
static void mat4_to_dae(float out[4][4], float in[4][4])
void convertVector3(COLLADABU::Math::Vector3 &vec, float *v)
void calculate_scale(Scene &sce)
UnitConverter::UnitSystem isMetricSystem(void)
static void mat4_to_dae_double(double out[4][4], float in[4][4])
float(& get_rotation())[4]
float getLinearMeter(void)
static void dae_matrix_to_mat4_(float out[4][4], const COLLADABU::Math::Matrix4 &in)
std::string get_camera_id(Object *ob)
std::string get_morph_id(Object *ob)
const unsigned char translate_name_map[256]
std::string get_joint_sid(Bone *bone)
std::map< std::string, std::vector< std::string > > map_string_list
std::string translate_id(const char *idString)
const unsigned char translate_start_name_map[256]
std::string get_geometry_id(Object *ob)
std::string get_material_id(Material *mat)
std::string encode_xml(std::string xml)
std::string get_light_id(Object *ob)
std::string get_effect_id(Material *mat)
void clear_global_id_map()
map_string_list global_id_map
std::string id_name(void *id)
float[3] Vector3
static unsigned c
Definition: RandGen.cpp:83
uint convert(uint c, uint inbits, uint outbits)
Definition: PixelFormat.h:45
static const pxr::TfToken out("out", pxr::TfToken::Immortal)
float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2767
PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:5167
void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
Definition: rna_access.c:112
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:717
int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:3402
char name[64]
char name[64]
Definition: BKE_armature.h:43
Definition: DNA_ID.h:368
void * data