Blender  V2.93
GeometryExporter.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 #include <sstream>
22 
23 #include "COLLADABUUtils.h"
24 #include "COLLADASWPrimitves.h"
25 #include "COLLADASWSource.h"
26 #include "COLLADASWVertices.h"
27 
28 #include "GeometryExporter.h"
29 
30 #include "DNA_meshdata_types.h"
31 
32 #include "BLI_utildefines.h"
33 
34 #include "BKE_customdata.h"
35 #include "BKE_global.h"
36 #include "BKE_lib_id.h"
37 #include "BKE_material.h"
38 #include "BKE_mesh.h"
39 
40 #include "collada_internal.h"
41 #include "collada_utils.h"
42 
44 {
45  Scene *sce = blender_context.get_scene();
46  openLibrary();
47 
48  GeometryFunctor gf;
50  sce, *this, this->export_settings.get_export_set());
51 
52  closeLibrary();
53 }
54 
56 {
57  bool use_instantiation = this->export_settings.get_use_object_instantiation();
58  Mesh *me = bc_get_mesh_copy(blender_context,
59  ob,
60  this->export_settings.get_export_mesh_type(),
61  this->export_settings.get_apply_modifiers(),
62  this->export_settings.get_triangulate());
63 
64  std::string geom_id = get_geometry_id(ob, use_instantiation);
65  std::vector<Normal> nor;
66  std::vector<BCPolygonNormalsIndices> norind;
67 
68  /* Skip if linked geometry was already exported from another reference */
69  if (use_instantiation && exportedGeometry.find(geom_id) != exportedGeometry.end()) {
70  return;
71  }
72 
73  std::string geom_name = (use_instantiation) ? id_name(ob->data) : id_name(ob);
74  geom_name = encode_xml(geom_name);
75 
76  exportedGeometry.insert(geom_id);
77 
78  bool has_color = (bool)CustomData_has_layer(&me->fdata, CD_MCOL);
79 
80  create_normals(nor, norind, me);
81 
82  /* openMesh(geoId, geoName, meshId) */
83  openMesh(geom_id, geom_name);
84 
85  /* writes <source> for vertex coords */
86  createVertsSource(geom_id, me);
87 
88  /* writes <source> for normal coords */
89  createNormalsSource(geom_id, me, nor);
90 
91  bool has_uvs = (bool)CustomData_has_layer(&me->ldata, CD_MLOOPUV);
92 
93  /* writes <source> for uv coords if mesh has uv coords */
94  if (has_uvs) {
95  createTexcoordsSource(geom_id, me);
96  }
97 
98  if (has_color) {
99  createVertexColorSource(geom_id, me);
100  }
101  /* <vertices> */
102 
103  COLLADASW::Vertices verts(mSW);
104  verts.setId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::VERTEX));
105  COLLADASW::InputList &input_list = verts.getInputList();
106  COLLADASW::Input input(COLLADASW::InputSemantic::POSITION,
107  getUrlBySemantics(geom_id, COLLADASW::InputSemantic::POSITION));
108  input_list.push_back(input);
109  verts.add();
110 
111  createLooseEdgeList(ob, me, geom_id);
112 
113  /* Only create Polylists if number of faces > 0 */
114  if (me->totface > 0) {
115  /* XXX slow */
116  if (ob->totcol) {
117  for (int a = 0; a < ob->totcol; a++) {
118  create_mesh_primitive_list(a, has_uvs, has_color, ob, me, geom_id, norind);
119  }
120  }
121  else {
122  create_mesh_primitive_list(0, has_uvs, has_color, ob, me, geom_id, norind);
123  }
124  }
125 
126  closeMesh();
127 
128  closeGeometry();
129 
130  if (this->export_settings.get_include_shapekeys()) {
131  Key *key = BKE_key_from_object(ob);
132  if (key) {
133  KeyBlock *kb = (KeyBlock *)key->block.first;
134  /* skip the basis */
135  kb = kb->next;
136  for (; kb; kb = kb->next) {
138  export_key_mesh(ob, me, kb);
139  }
140  }
141  }
142 
143  BKE_id_free(nullptr, me);
144 }
145 
147 {
148  std::string geom_id = get_geometry_id(ob, false) + "_morph_" + translate_id(kb->name);
149  std::vector<Normal> nor;
150  std::vector<BCPolygonNormalsIndices> norind;
151 
152  if (exportedGeometry.find(geom_id) != exportedGeometry.end()) {
153  return;
154  }
155 
156  std::string geom_name = kb->name;
157 
158  exportedGeometry.insert(geom_id);
159 
160  bool has_color = (bool)CustomData_has_layer(&me->fdata, CD_MCOL);
161 
162  create_normals(nor, norind, me);
163 
164  // openMesh(geoId, geoName, meshId)
165  openMesh(geom_id, geom_name);
166 
167  /* writes <source> for vertex coords */
168  createVertsSource(geom_id, me);
169 
170  /* writes <source> for normal coords */
171  createNormalsSource(geom_id, me, nor);
172 
173  bool has_uvs = (bool)CustomData_has_layer(&me->ldata, CD_MLOOPUV);
174 
175  /* writes <source> for uv coords if mesh has uv coords */
176  if (has_uvs) {
177  createTexcoordsSource(geom_id, me);
178  }
179 
180  if (has_color) {
181  createVertexColorSource(geom_id, me);
182  }
183 
184  /* <vertices> */
185 
186  COLLADASW::Vertices verts(mSW);
187  verts.setId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::VERTEX));
188  COLLADASW::InputList &input_list = verts.getInputList();
189  COLLADASW::Input input(COLLADASW::InputSemantic::POSITION,
190  getUrlBySemantics(geom_id, COLLADASW::InputSemantic::POSITION));
191  input_list.push_back(input);
192  verts.add();
193 
194  // createLooseEdgeList(ob, me, geom_id, norind);
195 
196  /* XXX slow */
197  if (ob->totcol) {
198  for (int a = 0; a < ob->totcol; a++) {
199  create_mesh_primitive_list(a, has_uvs, has_color, ob, me, geom_id, norind);
200  }
201  }
202  else {
203  create_mesh_primitive_list(0, has_uvs, has_color, ob, me, geom_id, norind);
204  }
205 
206  closeMesh();
207 
208  closeGeometry();
209 }
210 
211 void GeometryExporter::createLooseEdgeList(Object *ob, Mesh *me, std::string &geom_id)
212 {
213 
214  MEdge *medges = me->medge;
215  int totedges = me->totedge;
216  int edges_in_linelist = 0;
217  std::vector<unsigned int> edge_list;
218  int index;
219 
220  /* Find all loose edges in Mesh
221  * and save vertex indices in edge_list */
222  for (index = 0; index < totedges; index++) {
223  MEdge *edge = &medges[index];
224 
225  if (edge->flag & ME_LOOSEEDGE) {
226  edges_in_linelist += 1;
227  edge_list.push_back(edge->v1);
228  edge_list.push_back(edge->v2);
229  }
230  }
231 
232  if (edges_in_linelist > 0) {
233  /* Create the list of loose edges */
234  COLLADASW::Lines lines(mSW);
235 
236  lines.setCount(edges_in_linelist);
237 
238  COLLADASW::InputList &til = lines.getInputList();
239 
240  /* creates <input> in <lines> for vertices */
241  COLLADASW::Input input1(COLLADASW::InputSemantic::VERTEX,
242  getUrlBySemantics(geom_id, COLLADASW::InputSemantic::VERTEX),
243  0);
244  til.push_back(input1);
245 
246  lines.prepareToAppendValues();
247 
248  for (index = 0; index < edges_in_linelist; index++) {
249  lines.appendValues(edge_list[2 * index + 1]);
250  lines.appendValues(edge_list[2 * index]);
251  }
252  lines.finish();
253  }
254 }
255 
256 static void prepareToAppendValues(bool is_triangulated,
257  COLLADASW::PrimitivesBase &primitive_list,
258  std::vector<unsigned long> &vcount_list)
259 {
260  /* performs the actual writing */
261  if (is_triangulated) {
262  ((COLLADASW::Triangles &)primitive_list).prepareToAppendValues();
263  }
264  else {
265  /* sets <vcount> */
266  primitive_list.setVCountList(vcount_list);
267  ((COLLADASW::Polylist &)primitive_list).prepareToAppendValues();
268  }
269 }
270 
271 static void finish_and_delete_primitive_List(bool is_triangulated,
272  COLLADASW::PrimitivesBase *primitive_list)
273 {
274  if (is_triangulated) {
275  ((COLLADASW::Triangles *)primitive_list)->finish();
276  }
277  else {
278  ((COLLADASW::Polylist *)primitive_list)->finish();
279  }
280  delete primitive_list;
281 }
282 
283 static COLLADASW::PrimitivesBase *create_primitive_list(bool is_triangulated,
284  COLLADASW::StreamWriter *mSW)
285 {
286  COLLADASW::PrimitivesBase *primitive_list;
287 
288  if (is_triangulated) {
289  primitive_list = new COLLADASW::Triangles(mSW);
290  }
291  else {
292  primitive_list = new COLLADASW::Polylist(mSW);
293  }
294  return primitive_list;
295 }
296 
298  int material_index,
299  std::vector<unsigned long> &vcount_list)
300 {
301  MPoly *mpolys = me->mpoly;
302  int totpolys = me->totpoly;
303  bool is_triangulated = true;
304 
305  int i;
306  /* Expecting that p->mat_nr is always 0 if the mesh has no materials assigned */
307  for (i = 0; i < totpolys; i++) {
308  MPoly *p = &mpolys[i];
309  if (p->mat_nr == material_index) {
310  int vertex_count = p->totloop;
311  vcount_list.push_back(vertex_count);
312  if (vertex_count != 3) {
313  is_triangulated = false;
314  }
315  }
316  }
317  return is_triangulated;
318 }
319 
320 std::string GeometryExporter::makeVertexColorSourceId(std::string &geom_id, char *layer_name)
321 {
322  std::string result = getIdBySemantics(geom_id, COLLADASW::InputSemantic::COLOR) + "-" +
323  layer_name;
324  return result;
325 }
326 
327 /* powerful because it handles both cases when there is material and when there's not */
329  bool has_uvs,
330  bool has_color,
331  Object *ob,
332  Mesh *me,
333  std::string &geom_id,
334  std::vector<BCPolygonNormalsIndices> &norind)
335 {
336 
337  MPoly *mpolys = me->mpoly;
338  MLoop *mloops = me->mloop;
339  int totpolys = me->totpoly;
340 
341  std::vector<unsigned long> vcount_list;
342 
343  bool is_triangulated = collect_vertex_counts_per_poly(me, material_index, vcount_list);
344  int polygon_count = vcount_list.size();
345 
346  /* no faces using this material */
347  if (polygon_count == 0) {
348  fprintf(
349  stderr, "%s: material with index %d is not used.\n", id_name(ob).c_str(), material_index);
350  return;
351  }
352 
353  Material *ma = ob->totcol ? BKE_object_material_get(ob, material_index + 1) : nullptr;
354  COLLADASW::PrimitivesBase *primitive_list = create_primitive_list(is_triangulated, mSW);
355 
356  /* sets count attribute in <polylist> */
357  primitive_list->setCount(polygon_count);
358 
359  /* sets material name */
360  if (ma) {
361  std::string material_id = get_material_id(ma);
362  std::ostringstream ostr;
363  ostr << translate_id(material_id);
364  primitive_list->setMaterial(ostr.str());
365  }
366 
367  COLLADASW::Input vertex_input(COLLADASW::InputSemantic::VERTEX,
368  getUrlBySemantics(geom_id, COLLADASW::InputSemantic::VERTEX),
369  0);
370  COLLADASW::Input normals_input(COLLADASW::InputSemantic::NORMAL,
372  1);
373 
374  COLLADASW::InputList &til = primitive_list->getInputList();
375  til.push_back(vertex_input);
376  til.push_back(normals_input);
377 
378  /* if mesh has uv coords writes <input> for TEXCOORD */
379  int num_layers = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV);
380  int active_uv_index = CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV);
381  for (int i = 0; i < num_layers; i++) {
382  int layer_index = CustomData_get_layer_index_n(&me->ldata, CD_MLOOPUV, i);
383  if (!this->export_settings.get_active_uv_only() || layer_index == active_uv_index) {
384 
385  // char *name = CustomData_get_layer_name(&me->ldata, CD_MLOOPUV, i);
386  COLLADASW::Input texcoord_input(
387  COLLADASW::InputSemantic::TEXCOORD,
388  makeUrl(makeTexcoordSourceId(geom_id, i, this->export_settings.get_active_uv_only())),
389  2, /* this is only until we have optimized UV sets */
390  (this->export_settings.get_active_uv_only()) ? 0 : layer_index - 1 /* set (0,1,2,...) */
391  );
392  til.push_back(texcoord_input);
393  }
394  }
395 
396  int totlayer_mcol = CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL);
397  if (totlayer_mcol > 0) {
398  int map_index = 0;
399 
400  for (int a = 0; a < totlayer_mcol; a++) {
401  char *layer_name = bc_CustomData_get_layer_name(&me->ldata, CD_MLOOPCOL, a);
402  COLLADASW::Input input4(COLLADASW::InputSemantic::COLOR,
403  makeUrl(makeVertexColorSourceId(geom_id, layer_name)),
404  (has_uvs) ? 3 : 2, /* all color layers have same index order */
405  map_index /* set number equals color map index */
406  );
407  til.push_back(input4);
408  map_index++;
409  }
410  }
411 
412  /* performs the actual writing */
413  prepareToAppendValues(is_triangulated, *primitive_list, vcount_list);
414 
415  /* <p> */
416  int texindex = 0;
417  for (int i = 0; i < totpolys; i++) {
418  MPoly *p = &mpolys[i];
419  int loop_count = p->totloop;
420 
421  if (p->mat_nr == material_index) {
422  MLoop *l = &mloops[p->loopstart];
423  BCPolygonNormalsIndices normal_indices = norind[i];
424 
425  for (int j = 0; j < loop_count; j++) {
426  primitive_list->appendValues(l[j].v);
427  primitive_list->appendValues(normal_indices[j]);
428  if (has_uvs) {
429  primitive_list->appendValues(texindex + j);
430  }
431 
432  if (has_color) {
433  primitive_list->appendValues(texindex + j);
434  }
435  }
436  }
437 
438  texindex += loop_count;
439  }
440 
441  finish_and_delete_primitive_List(is_triangulated, primitive_list);
442 }
443 
444 /* creates <source> for positions */
445 void GeometryExporter::createVertsSource(std::string geom_id, Mesh *me)
446 {
447 #if 0
448  int totverts = dm->getNumVerts(dm);
449  MVert *verts = dm->getVertArray(dm);
450 #endif
451  int totverts = me->totvert;
452  MVert *verts = me->mvert;
453 
454  COLLADASW::FloatSourceF source(mSW);
455  source.setId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::POSITION));
456  source.setArrayId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::POSITION) +
457  ARRAY_ID_SUFFIX);
458  source.setAccessorCount(totverts);
459  source.setAccessorStride(3);
460 
461  COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
462  param.push_back("X");
463  param.push_back("Y");
464  param.push_back("Z");
465  /* main function, it creates <source id = "">, <float_array id = ""
466  * count = ""> */
467  source.prepareToAppendValues();
468  /* appends data to <float_array> */
469  int i = 0;
470  for (i = 0; i < totverts; i++) {
471  Vector co;
472  if (export_settings.get_apply_global_orientation()) {
473  bc_add_global_transform(co, verts[i].co, export_settings.get_global_transform());
474  }
475  else {
476  copy_v3_v3(co, verts[i].co);
477  }
478  source.appendValues(co[0], co[1], co[2]);
479  }
480 
481  source.finish();
482 }
483 
484 void GeometryExporter::createVertexColorSource(std::string geom_id, Mesh *me)
485 {
486  /* Find number of vertex color layers */
487  int totlayer_mcol = CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL);
488  if (totlayer_mcol == 0) {
489  return;
490  }
491 
492  int map_index = 0;
493  for (int a = 0; a < totlayer_mcol; a++) {
494 
495  map_index++;
497 
498  COLLADASW::FloatSourceF source(mSW);
499 
500  char *layer_name = bc_CustomData_get_layer_name(&me->ldata, CD_MLOOPCOL, a);
501  std::string layer_id = makeVertexColorSourceId(geom_id, layer_name);
502  source.setId(layer_id);
503 
504  source.setNodeName(layer_name);
505 
506  source.setArrayId(layer_id + ARRAY_ID_SUFFIX);
507  source.setAccessorCount(me->totloop);
508  source.setAccessorStride(4);
509 
510  COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
511  param.push_back("R");
512  param.push_back("G");
513  param.push_back("B");
514  param.push_back("A");
515 
516  source.prepareToAppendValues();
517 
518  MPoly *mpoly;
519  int i;
520  for (i = 0, mpoly = me->mpoly; i < me->totpoly; i++, mpoly++) {
521  MLoopCol *mlc = mloopcol + mpoly->loopstart;
522  for (int j = 0; j < mpoly->totloop; j++, mlc++) {
523  source.appendValues(mlc->r / 255.0f, mlc->g / 255.0f, mlc->b / 255.0f, mlc->a / 255.0f);
524  }
525  }
526 
527  source.finish();
528  }
529 }
530 
531 std::string GeometryExporter::makeTexcoordSourceId(std::string &geom_id,
532  int layer_index,
533  bool is_single_layer)
534 {
535  char suffix[20];
536  if (is_single_layer) {
537  suffix[0] = '\0';
538  }
539  else {
540  sprintf(suffix, "-%d", layer_index);
541  }
542  return getIdBySemantics(geom_id, COLLADASW::InputSemantic::TEXCOORD) + suffix;
543 }
544 
545 /* creates <source> for texcoords */
546 void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me)
547 {
548 
549  int totpoly = me->totpoly;
550  int totuv = me->totloop;
551  MPoly *mpolys = me->mpoly;
552 
553  int num_layers = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV);
554 
555  /* write <source> for each layer
556  * each <source> will get id like meshName + "map-channel-1" */
557  int active_uv_index = CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV);
558  for (int a = 0; a < num_layers; a++) {
559  int layer_index = CustomData_get_layer_index_n(&me->ldata, CD_MLOOPUV, a);
560  if (!this->export_settings.get_active_uv_only() || layer_index == active_uv_index) {
562 
563  COLLADASW::FloatSourceF source(mSW);
564  std::string layer_id = makeTexcoordSourceId(
565  geom_id, a, this->export_settings.get_active_uv_only());
566  source.setId(layer_id);
567  source.setArrayId(layer_id + ARRAY_ID_SUFFIX);
568 
569  source.setAccessorCount(totuv);
570  source.setAccessorStride(2);
571  COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
572  param.push_back("S");
573  param.push_back("T");
574 
575  source.prepareToAppendValues();
576 
577  for (int index = 0; index < totpoly; index++) {
578  MPoly *mpoly = mpolys + index;
579  MLoopUV *mloop = mloops + mpoly->loopstart;
580  for (int j = 0; j < mpoly->totloop; j++) {
581  source.appendValues(mloop[j].uv[0], mloop[j].uv[1]);
582  }
583  }
584 
585  source.finish();
586  }
587  }
588 }
589 
590 bool operator<(const Normal &a, const Normal &b)
591 {
592  /* only needed to sort normal vectors and find() them later in a map.*/
593  return a.x < b.x || (a.x == b.x && (a.y < b.y || (a.y == b.y && a.z < b.z)));
594 }
595 
596 /* creates <source> for normals */
597 void GeometryExporter::createNormalsSource(std::string geom_id, Mesh *me, std::vector<Normal> &nor)
598 {
599 #if 0
600  int totverts = dm->getNumVerts(dm);
601  MVert *verts = dm->getVertArray(dm);
602 #endif
603 
604  COLLADASW::FloatSourceF source(mSW);
605  source.setId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::NORMAL));
606  source.setArrayId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::NORMAL) + ARRAY_ID_SUFFIX);
607  source.setAccessorCount((unsigned long)nor.size());
608  source.setAccessorStride(3);
609  COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
610  param.push_back("X");
611  param.push_back("Y");
612  param.push_back("Z");
613 
614  source.prepareToAppendValues();
615 
616  std::vector<Normal>::iterator it;
617  for (it = nor.begin(); it != nor.end(); it++) {
618  Normal &n = *it;
619 
620  Vector no{n.x, n.y, n.z};
621  if (export_settings.get_apply_global_orientation()) {
622  bc_add_global_transform(no, export_settings.get_global_transform());
623  }
624  source.appendValues(no[0], no[1], no[2]);
625  }
626 
627  source.finish();
628 }
629 
630 void GeometryExporter::create_normals(std::vector<Normal> &normals,
631  std::vector<BCPolygonNormalsIndices> &polygons_normals,
632  Mesh *me)
633 {
634  std::map<Normal, unsigned int> shared_normal_indices;
635  int last_normal_index = -1;
636 
637  MVert *verts = me->mvert;
638  MLoop *mloops = me->mloop;
639  float(*lnors)[3] = nullptr;
640  bool use_custom_normals = false;
641 
643  if (CustomData_has_layer(&me->ldata, CD_NORMAL)) {
644  lnors = (float(*)[3])CustomData_get_layer(&me->ldata, CD_NORMAL);
645  use_custom_normals = true;
646  }
647 
648  for (int poly_index = 0; poly_index < me->totpoly; poly_index++) {
649  MPoly *mpoly = &me->mpoly[poly_index];
650  bool use_vertex_normals = use_custom_normals || mpoly->flag & ME_SMOOTH;
651 
652  if (!use_vertex_normals) {
653  /* For flat faces use face normal as vertex normal: */
654 
655  float vector[3];
656  BKE_mesh_calc_poly_normal(mpoly, mloops + mpoly->loopstart, verts, vector);
657 
658  Normal n = {vector[0], vector[1], vector[2]};
659  normals.push_back(n);
660  last_normal_index++;
661  }
662 
663  BCPolygonNormalsIndices poly_indices;
664  for (int loop_index = 0; loop_index < mpoly->totloop; loop_index++) {
665  unsigned int loop_idx = mpoly->loopstart + loop_index;
666  if (use_vertex_normals) {
667  float normalized[3];
668 
669  if (use_custom_normals) {
670  normalize_v3_v3(normalized, lnors[loop_idx]);
671  }
672  else {
673  normal_short_to_float_v3(normalized, verts[mloops[loop_index].v].no);
675  }
676  Normal n = {normalized[0], normalized[1], normalized[2]};
677 
678  if (shared_normal_indices.find(n) != shared_normal_indices.end()) {
679  poly_indices.add_index(shared_normal_indices[n]);
680  }
681  else {
682  last_normal_index++;
683  poly_indices.add_index(last_normal_index);
684  shared_normal_indices[n] = last_normal_index;
685  normals.push_back(n);
686  }
687  }
688  else {
689  poly_indices.add_index(last_normal_index);
690  }
691  }
692 
693  polygons_normals.push_back(poly_indices);
694  }
695 }
696 
697 std::string GeometryExporter::getIdBySemantics(std::string geom_id,
698  COLLADASW::InputSemantic::Semantics type,
699  std::string other_suffix)
700 {
701  return geom_id + getSuffixBySemantic(type) + other_suffix;
702 }
703 
704 COLLADASW::URI GeometryExporter::getUrlBySemantics(std::string geom_id,
705  COLLADASW::InputSemantic::Semantics type,
706  std::string other_suffix)
707 {
708 
709  std::string id(getIdBySemantics(geom_id, type, other_suffix));
710  return COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, id);
711 }
712 
713 COLLADASW::URI GeometryExporter::makeUrl(std::string id)
714 {
715  return COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, id);
716 }
std::string EMPTY_STRING
typedef float(TangentPoint)[2]
CustomData interface, see also DNA_customdata_types.h.
int CustomData_get_active_layer_index(const struct CustomData *data, int type)
int CustomData_number_of_layers(const struct CustomData *data, int type)
bool CustomData_has_layer(const struct CustomData *data, int type)
int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n)
Definition: customdata.c:2308
void * CustomData_get_layer_n(const struct CustomData *data, int type, int n)
void * CustomData_get_layer(const struct CustomData *data, int type)
struct Key * BKE_key_from_object(const struct Object *ob)
void BKE_keyblock_convert_to_mesh(struct KeyBlock *kb, struct Mesh *me)
Definition: key.c:2224
void BKE_id_free(struct Main *bmain, void *idv)
General operations, lookup, etc. for materials.
struct Material * BKE_object_material_get(struct Object *ob, short act)
Definition: material.c:697
void BKE_mesh_calc_poly_normal(const struct MPoly *mpoly, const struct MLoop *loopstart, const struct MVert *mvarray, float r_no[3])
void BKE_mesh_calc_normals_split(struct Mesh *mesh)
Definition: mesh.c:1865
MINLINE float normalize_v3(float r[3])
MINLINE void normal_short_to_float_v3(float r[3], const short n[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE float normalize_v3_v3(float r[3], const float a[3])
@ CD_MLOOPCOL
@ CD_MLOOPUV
@ ME_LOOSEEDGE
@ ME_SMOOTH
_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
static COLLADASW::PrimitivesBase * create_primitive_list(bool is_triangulated, COLLADASW::StreamWriter *mSW)
static void finish_and_delete_primitive_List(bool is_triangulated, COLLADASW::PrimitivesBase *primitive_list)
static bool collect_vertex_counts_per_poly(Mesh *me, int material_index, std::vector< unsigned long > &vcount_list)
bool operator<(const Normal &a, const Normal &b)
static void prepareToAppendValues(bool is_triangulated, COLLADASW::PrimitivesBase &primitive_list, std::vector< unsigned long > &vcount_list)
Group RGB to NORMAL
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE btVector3 normalized() const
Return a normalized version of this vector.
void add_index(unsigned int index)
void create_normals(std::vector< Normal > &nor, std::vector< BCPolygonNormalsIndices > &polygons_normals, Mesh *me)
COLLADASW::URI getUrlBySemantics(std::string geom_id, COLLADASW::InputSemantic::Semantics type, std::string other_suffix="")
COLLADASW::URI makeUrl(std::string id)
std::string makeTexcoordSourceId(std::string &geom_id, int layer_index, bool is_single_layer)
std::string makeVertexColorSourceId(std::string &geom_id, char *layer_name)
void export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb)
void operator()(Object *ob)
void create_mesh_primitive_list(short material_index, bool has_uvs, bool has_color, Object *ob, Mesh *me, std::string &geom_id, std::vector< BCPolygonNormalsIndices > &norind)
void createVertexColorSource(std::string geom_id, Mesh *me)
std::string getIdBySemantics(std::string geom_id, COLLADASW::InputSemantic::Semantics type, std::string other_suffix="")
void createLooseEdgeList(Object *ob, Mesh *me, std::string &geom_id)
void createTexcoordsSource(std::string geom_id, Mesh *me)
void createVertsSource(std::string geom_id, Mesh *me)
void createNormalsSource(std::string geom_id, Mesh *me, std::vector< Normal > &nor)
std::string translate_id(const char *idString)
std::string get_geometry_id(Object *ob)
std::string get_material_id(Material *mat)
std::string encode_xml(std::string xml)
std::string id_name(void *id)
Mesh * bc_get_mesh_copy(BlenderContext &blender_context, Object *ob, BC_export_mesh_type export_mesh_type, bool apply_modifiers, bool triangulate)
void bc_add_global_transform(Matrix &to_mat, const Matrix &from_mat, const BCMatrix &global_transform, const bool invert)
char * bc_CustomData_get_layer_name(const CustomData *data, int type, int n)
static float verts[][3]
static float normals[][3]
uint nor
static unsigned a[3]
Definition: RandGen.cpp:92
void forEachMeshObjectInExportSet(Scene *sce, Functor &f, LinkNode *export_set)
char name[64]
Definition: DNA_key_types.h:68
struct KeyBlock * next
Definition: DNA_key_types.h:41
ListBase block
void * first
Definition: DNA_listBase.h:47
unsigned int v1
unsigned int v2
unsigned char a
unsigned char b
unsigned char r
unsigned char g
short mat_nr
struct MEdge * medge
struct CustomData pdata ldata
struct MVert * mvert
int totedge
int totvert
struct MLoop * mloop
int totface
struct CustomData vdata edata fdata
int totpoly
int totloop
struct MPoly * mpoly
void * data