Blender  V2.93
collada_internal.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
21 /* COLLADABU_ASSERT, may be able to remove later */
22 #include "COLLADABUPlatform.h"
23 #include "collada_utils.h"
24 
25 #include "BLI_linklist.h"
26 
27 #include "BKE_armature.h"
28 
29 UnitConverter::UnitConverter() : up_axis(COLLADAFW::FileInfo::Z_UP)
30 {
31  axis_angle_to_mat4_single(x_up_mat4, 'Y', -0.5 * M_PI);
32  axis_angle_to_mat4_single(y_up_mat4, 'X', 0.5 * M_PI);
33 
34  unit_m4(z_up_mat4);
35  unit_m4(scale_mat4);
36 }
37 
38 void UnitConverter::read_asset(const COLLADAFW::FileInfo *asset)
39 {
40  unit = asset->getUnit();
41  up_axis = asset->getUpAxisType();
42 }
43 
45 {
46  switch (unit.getLinearUnitUnit()) {
47  case COLLADAFW::FileInfo::Unit::MILLIMETER:
48  case COLLADAFW::FileInfo::Unit::CENTIMETER:
49  case COLLADAFW::FileInfo::Unit::DECIMETER:
50  case COLLADAFW::FileInfo::Unit::METER:
51  case COLLADAFW::FileInfo::Unit::KILOMETER:
52  return UnitConverter::Metric;
53  case COLLADAFW::FileInfo::Unit::INCH:
54  case COLLADAFW::FileInfo::Unit::FOOT:
55  case COLLADAFW::FileInfo::Unit::YARD:
57  default:
58  return UnitConverter::None;
59  }
60 }
61 
63 {
64  return (float)unit.getLinearUnitMeter();
65 }
66 
68 {
69  v[0] = vec.x;
70  v[1] = vec.y;
71  v[2] = vec.z;
72 }
73 
74 /* TODO need also for angle conversion, time conversion... */
75 
76 void UnitConverter::dae_matrix_to_mat4_(float out[4][4], const COLLADABU::Math::Matrix4 &in)
77 {
78  /* in DAE, matrices use columns vectors, (see comments in COLLADABUMathMatrix4.h)
79  * so here, to make a blender matrix, we swap columns and rows. */
80  for (int i = 0; i < 4; i++) {
81  for (int j = 0; j < 4; j++) {
82  out[i][j] = in[j][i];
83  }
84  }
85 }
86 
87 void UnitConverter::mat4_to_dae(float out[4][4], float in[4][4])
88 {
89  transpose_m4_m4(out, in);
90 }
91 
92 void UnitConverter::mat4_to_dae_double(double out[4][4], float in[4][4])
93 {
94  float mat[4][4];
95 
96  mat4_to_dae(mat, in);
97 
98  for (int i = 0; i < 4; i++) {
99  for (int j = 0; j < 4; j++) {
100  out[i][j] = mat[i][j];
101  }
102  }
103 }
104 
106 {
107  switch (up_axis) {
108  case COLLADAFW::FileInfo::X_UP:
109  return x_up_mat4;
110  break;
111  case COLLADAFW::FileInfo::Y_UP:
112  return y_up_mat4;
113  break;
114  default:
115  return z_up_mat4;
116  break;
117  }
118 }
119 
121 {
122  return scale_mat4;
123 }
124 
126 {
127  PointerRNA scene_ptr, unit_settings;
128  PropertyRNA *system_ptr, *scale_ptr;
129  RNA_id_pointer_create(&sce.id, &scene_ptr);
130 
131  unit_settings = RNA_pointer_get(&scene_ptr, "unit_settings");
132  system_ptr = RNA_struct_find_property(&unit_settings, "system");
133  scale_ptr = RNA_struct_find_property(&unit_settings, "scale_length");
134 
135  int type = RNA_property_enum_get(&unit_settings, system_ptr);
136 
137  float bl_scale;
138 
139  switch (type) {
140  case USER_UNIT_NONE:
141  bl_scale = 1.0; /* map 1 Blender unit to 1 Meter. */
142  break;
143 
144  case USER_UNIT_METRIC:
145  bl_scale = RNA_property_float_get(&unit_settings, scale_ptr);
146  break;
147 
148  default:
149  bl_scale = RNA_property_float_get(&unit_settings, scale_ptr);
150  /* It looks like the conversion to Imperial is done implicitly.
151  * So nothing to do here. */
152  break;
153  }
154 
155  float rescale[3];
156  rescale[0] = rescale[1] = rescale[2] = getLinearMeter() / bl_scale;
157 
158  size_to_mat4(scale_mat4, rescale);
159 }
160 
170 const unsigned char translate_start_name_map[256] = {
171 
172  95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
173  95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
174  95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
175  95, 95, 95, 95, 95, 95, 95, 95, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
176  76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 95, 95, 95, 95,
177  95, 95, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
178  114, 115, 116, 117, 118, 119, 120, 121, 122, 95, 95, 95, 95, 95,
179 
180  128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146,
181  147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165,
182  166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184,
183  185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203,
184  204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222,
185  223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241,
186  242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255,
187 };
188 
189 const unsigned char translate_name_map[256] = {
190 
191  95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
192  95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
193  95, 95, 95, 95, 95, 95, 95, 45, 95, 95, 48, 49, 50, 51, 52, 53, 54, 55, 56,
194  57, 95, 95, 95, 95, 95, 95, 95, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
195  76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 95, 95, 95, 95,
196  95, 95, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
197  114, 115, 116, 117, 118, 119, 120, 121, 122, 95, 95, 95, 95, 95,
198 
199  128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146,
200  147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165,
201  166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184,
202  185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203,
203  204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222,
204  223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241,
205  242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255,
206 };
207 
208 using map_string_list = std::map<std::string, std::vector<std::string>>;
210 
212 {
213  global_id_map.clear();
214 }
215 
217 std::string translate_id(const char *idString)
218 {
219  std::string id = std::string(idString);
220  return translate_id(id);
221 }
222 
223 std::string translate_id(const std::string &id)
224 {
225  if (id.empty()) {
226  return id;
227  }
228 
229  std::string id_translated = id;
230  id_translated[0] = translate_start_name_map[(unsigned int)id_translated[0]];
231  for (unsigned int i = 1; i < id_translated.size(); i++) {
232  id_translated[i] = translate_name_map[(unsigned int)id_translated[i]];
233  }
234  /* It's so much workload now, the if () should speed up things. */
235  if (id_translated != id) {
236  /* Search duplicates. */
237  map_string_list::iterator iter = global_id_map.find(id_translated);
238  if (iter != global_id_map.end()) {
239  unsigned int i = 0;
240  bool found = false;
241  for (i = 0; i < iter->second.size(); i++) {
242  if (id == iter->second[i]) {
243  found = true;
244  break;
245  }
246  }
247  bool convert = false;
248  if (found) {
249  if (i > 0) {
250  convert = true;
251  }
252  }
253  else {
254  convert = true;
255  global_id_map[id_translated].push_back(id);
256  }
257  if (convert) {
258  std::stringstream out;
259  out << ++i;
260  id_translated += out.str();
261  }
262  }
263  else {
264  global_id_map[id_translated].push_back(id);
265  }
266  }
267  return id_translated;
268 }
269 
270 std::string id_name(void *id)
271 {
272  return ((ID *)id)->name + 2;
273 }
274 
275 std::string encode_xml(std::string xml)
276 {
277  const std::map<char, std::string> escape{
278  {'<', "&lt;"}, {'>', "&gt;"}, {'"', "&quot;"}, {'\'', "&apos;"}, {'&', "&amp;"}};
279 
280  std::map<char, std::string>::const_iterator it;
281  std::string encoded_xml;
282 
283  for (char c : xml) {
284  it = escape.find(c);
285 
286  if (it == escape.end()) {
287  encoded_xml += c;
288  }
289  else {
290  encoded_xml += it->second;
291  }
292  }
293  return encoded_xml;
294 }
295 
296 std::string get_geometry_id(Object *ob)
297 {
298  return translate_id(id_name(ob->data)) + "-mesh";
299 }
300 
301 std::string get_geometry_id(Object *ob, bool use_instantiation)
302 {
303  std::string geom_name = (use_instantiation) ? id_name(ob->data) : id_name(ob);
304 
305  return translate_id(geom_name) + "-mesh";
306 }
307 
308 std::string get_light_id(Object *ob)
309 {
310  return translate_id(id_name(ob)) + "-light";
311 }
312 
313 std::string get_joint_sid(Bone *bone)
314 {
315  return translate_id(bone->name);
316 }
317 static std::string get_joint_sid(EditBone *bone)
318 {
319  return translate_id(bone->name);
320 }
321 
322 std::string get_camera_id(Object *ob)
323 {
324  return translate_id(id_name(ob)) + "-camera";
325 }
326 
327 std::string get_effect_id(Material *mat)
328 {
329  return translate_id(id_name(mat)) + "-effect";
330 }
331 
332 std::string get_material_id(Material *mat)
333 {
334  return translate_id(id_name(mat)) + "-material";
335 }
336 
337 std::string get_morph_id(Object *ob)
338 {
339  return translate_id(id_name(ob)) + "-morph";
340 }
typedef float(TangentPoint)[2]
#define M_PI
Definition: BLI_math_base.h:38
void transpose_m4_m4(float R[4][4], const float M[4][4])
Definition: math_matrix.c:1384
void unit_m4(float m[4][4])
Definition: rct.c:1140
void size_to_mat4(float R[4][4], const float size[3])
Definition: math_matrix.c:2118
void axis_angle_to_mat4_single(float R[4][4], const char axis, const 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:97
uint convert(uint c, uint inbits, uint outbits)
Definition: PixelFormat.h:59
float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2941
PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6562
void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
Definition: rna_access.c:122
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:866
int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:3543
char name[64]
char name[64]
Definition: BKE_armature.h:57
Definition: DNA_ID.h:273
void * data