11#include "COLLADABUUtils.h"
12#include "COLLADASWPrimitves.h"
13#include "COLLADASWSource.h"
14#include "COLLADASWVertices.h"
38 Scene *sce = blender_context.get_scene();
43 sce, *
this, this->export_settings.get_export_set());
50 bool use_instantiation = this->export_settings.get_use_object_instantiation();
53 this->export_settings.get_export_mesh_type(),
54 this->export_settings.get_apply_modifiers(),
55 this->export_settings.get_triangulate());
58 std::vector<Normal>
nor;
59 std::vector<BCPolygonNormalsIndices> norind;
62 if (use_instantiation && exportedGeometry.find(geom_id) != exportedGeometry.end()) {
69 exportedGeometry.insert(geom_id);
76 openMesh(geom_id, geom_name);
96 COLLADASW::Vertices
verts(mSW);
98 COLLADASW::InputList &input_list =
verts.getInputList();
99 COLLADASW::Input input(COLLADASW::InputSemantic::POSITION,
101 input_list.push_back(input);
107 if (mesh->totface_legacy > 0) {
110 for (
int a = 0; a < ob->
totcol; a++) {
123 if (this->export_settings.get_include_shapekeys()) {
130 for (; kb; kb = kb->
next) {
132 kb,
reinterpret_cast<float(*)[3]
>(positions.data()), mesh->verts_num);
144 std::vector<Normal>
nor;
145 std::vector<BCPolygonNormalsIndices> norind;
147 if (exportedGeometry.find(geom_id) != exportedGeometry.end()) {
151 std::string geom_name = kb->
name;
153 exportedGeometry.insert(geom_id);
160 openMesh(geom_id, geom_name);
181 COLLADASW::Vertices
verts(mSW);
183 COLLADASW::InputList &input_list =
verts.getInputList();
184 COLLADASW::Input input(COLLADASW::InputSemantic::POSITION,
186 input_list.push_back(input);
193 for (
int a = 0; a < ob->
totcol; a++) {
210 int edges_in_linelist = 0;
211 std::vector<uint> edge_list;
217 if (loose_edges.
count > 0) {
218 for (
const int64_t i : edges.index_range()) {
220 const int2 &edge = edges[i];
221 edges_in_linelist += 1;
222 edge_list.push_back(edge[0]);
223 edge_list.push_back(edge[1]);
228 if (edges_in_linelist > 0) {
230 COLLADASW::Lines lines(mSW);
232 lines.setCount(edges_in_linelist);
234 COLLADASW::InputList &til = lines.getInputList();
237 COLLADASW::Input input1(COLLADASW::InputSemantic::VERTEX,
240 til.push_back(input1);
242 lines.prepareToAppendValues();
244 for (index = 0; index < edges_in_linelist; index++) {
245 lines.appendValues(edge_list[2 * index + 1]);
246 lines.appendValues(edge_list[2 * index]);
253 COLLADASW::PrimitivesBase &primitive_list,
254 std::vector<ulong> &vcount_list)
257 if (is_triangulated) {
258 ((COLLADASW::Triangles &)primitive_list).prepareToAppendValues();
262 primitive_list.setVCountList(vcount_list);
263 ((COLLADASW::Polylist &)primitive_list).prepareToAppendValues();
268 COLLADASW::PrimitivesBase *primitive_list)
270 if (is_triangulated) {
271 ((COLLADASW::Triangles *)primitive_list)->finish();
274 ((COLLADASW::Polylist *)primitive_list)->finish();
276 delete primitive_list;
280 COLLADASW::StreamWriter *mSW)
282 COLLADASW::PrimitivesBase *primitive_list;
284 if (is_triangulated) {
285 primitive_list =
new COLLADASW::Triangles(mSW);
288 primitive_list =
new COLLADASW::Polylist(mSW);
290 return primitive_list;
295 std::vector<ulong> &vcount_list)
301 "material_index", bke::AttrDomain::Face, 0);
302 bool is_triangulated =
true;
305 for (
const int i : faces.index_range()) {
306 if (material_indices[i] == material_index) {
307 const int vertex_count = faces[i].
size();
308 vcount_list.push_back(vertex_count);
309 if (vertex_count != 3) {
310 is_triangulated =
false;
314 return is_triangulated;
319 std::string result =
getIdBySemantics(geom_id, COLLADASW::InputSemantic::COLOR) +
"-" +
329 std::string &geom_id,
330 std::vector<BCPolygonNormalsIndices> &norind)
334 const Span<int> corner_verts = mesh->corner_verts();
336 std::vector<ulong> vcount_list;
339 int polygon_count = vcount_list.size();
342 if (polygon_count == 0) {
344 stderr,
"%s: material with index %d is not used.\n",
id_name(ob).c_str(), material_index);
352 primitive_list->setCount(polygon_count);
357 std::ostringstream ostr;
359 primitive_list->setMaterial(ostr.str());
362 COLLADASW::Input vertex_input(COLLADASW::InputSemantic::VERTEX,
365 COLLADASW::Input normals_input(COLLADASW::InputSemantic::NORMAL,
369 COLLADASW::InputList &til = primitive_list->getInputList();
370 til.push_back(vertex_input);
371 til.push_back(normals_input);
376 for (
int i = 0; i < num_layers; i++) {
377 if (!this->export_settings.get_active_uv_only() || i == active_uv) {
380 COLLADASW::Input texcoord_input(
381 COLLADASW::InputSemantic::TEXCOORD,
384 this->export_settings.get_active_uv_only() ? 0 : i
386 til.push_back(texcoord_input);
391 if (totlayer_mcol > 0) {
394 for (
int a = 0; a < totlayer_mcol; a++) {
397 COLLADASW::Input input4(COLLADASW::InputSemantic::COLOR,
402 til.push_back(input4);
412 "material_index", bke::AttrDomain::Face, 0);
416 for (
const int i : faces.index_range()) {
418 int loop_count = poly.
size();
420 if (material_indices[i] == material_index) {
423 for (
int j = 0; j < loop_count; j++) {
424 const int vert = corner_verts[poly[j]];
425 primitive_list->appendValues(vert);
426 primitive_list->appendValues(normal_indices[j]);
428 primitive_list->appendValues(texindex + j);
432 primitive_list->appendValues(texindex + j);
437 texindex += loop_count;
447 COLLADASW::FloatSourceF source(mSW);
448 source.setId(
getIdBySemantics(geom_id, COLLADASW::InputSemantic::POSITION));
449 source.setArrayId(
getIdBySemantics(geom_id, COLLADASW::InputSemantic::POSITION) +
451 source.setAccessorCount(positions.size());
452 source.setAccessorStride(3);
454 COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList();
455 param.push_back(
"X");
456 param.push_back(
"Y");
457 param.push_back(
"Z");
460 source.prepareToAppendValues();
462 for (
const int i : positions.index_range()) {
464 if (export_settings.get_apply_global_orientation()) {
472 source.appendValues(co[0], co[1], co[2]);
482 if (totlayer_mcol == 0) {
487 for (
int a = 0; a < totlayer_mcol; a++) {
493 COLLADASW::FloatSourceF source(mSW);
498 source.setId(layer_id);
500 source.setNodeName(layer_name);
502 source.setArrayId(layer_id + ARRAY_ID_SUFFIX);
503 source.setAccessorCount(mesh->corners_num);
504 source.setAccessorStride(4);
506 COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList();
507 param.push_back(
"R");
508 param.push_back(
"G");
509 param.push_back(
"B");
510 param.push_back(
"A");
512 source.prepareToAppendValues();
515 for (
const int i : faces.index_range()) {
516 for (
const int corner : faces[i]) {
517 const MLoopCol *mlc = &mloopcol[corner];
518 source.appendValues(mlc->
r / 255.0f, mlc->
g / 255.0f, mlc->
b / 255.0f, mlc->
a / 255.0f);
528 bool is_single_layer)
531 if (is_single_layer) {
535 SNPRINTF(suffix,
"-%d", layer_index);
537 return getIdBySemantics(geom_id, COLLADASW::InputSemantic::TEXCOORD) + suffix;
542 int totuv = mesh->corners_num;
550 for (
int a = 0; a < num_layers; a++) {
552 if (!this->export_settings.get_active_uv_only() || layer_index == active_uv_index) {
556 COLLADASW::FloatSourceF source(mSW);
558 geom_id, a, this->export_settings.get_active_uv_only());
559 source.setId(layer_id);
560 source.setArrayId(layer_id + ARRAY_ID_SUFFIX);
562 source.setAccessorCount(totuv);
563 source.setAccessorStride(2);
564 COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList();
565 param.push_back(
"S");
566 param.push_back(
"T");
568 source.prepareToAppendValues();
570 for (
const int i : faces.index_range()) {
571 for (
const int corner : faces[i]) {
572 source.appendValues(uv_map[corner][0], uv_map[corner][1]);
584 return a.x <
b.x || (a.x ==
b.x && (a.y <
b.y || (a.y ==
b.y && a.z <
b.z)));
589 std::vector<Normal> &
nor)
591 COLLADASW::FloatSourceF source(mSW);
593 source.setArrayId(
getIdBySemantics(geom_id, COLLADASW::InputSemantic::NORMAL) + ARRAY_ID_SUFFIX);
594 source.setAccessorCount(
ulong(
nor.size()));
595 source.setAccessorStride(3);
596 COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList();
597 param.push_back(
"X");
598 param.push_back(
"Y");
599 param.push_back(
"Z");
601 source.prepareToAppendValues();
603 std::vector<Normal>::iterator it;
604 for (it =
nor.begin(); it !=
nor.end(); it++) {
607 Vector no{n.
x, n.
y, n.
z};
608 if (export_settings.get_apply_global_orientation()) {
611 source.appendValues(no[0], no[1], no[2]);
618 std::vector<BCPolygonNormalsIndices> &polygons_normals,
622 std::map<Normal, uint> shared_normal_indices;
623 int last_normal_index = -1;
628 const Span<int> corner_verts = mesh->corner_verts();
631 const VArray<bool> sharp_faces = *attributes.lookup_or_default<
bool>(
632 "sharp_face", bke::AttrDomain::Face,
false);
636 corner_normals = mesh->corner_normals();
639 for (
const int face_index : faces.index_range()) {
641 bool use_vert_normals = !corner_normals.
is_empty() || !sharp_faces[face_index];
643 if (!use_vert_normals) {
647 corner_verts.
slice(face));
650 normals.push_back(n);
655 for (
const int corner : face) {
656 if (use_vert_normals) {
659 if (!corner_normals.is_empty()) {
668 if (shared_normal_indices.find(n) != shared_normal_indices.end()) {
669 poly_indices.
add_index(shared_normal_indices[n]);
673 poly_indices.
add_index(last_normal_index);
674 shared_normal_indices[n] = last_normal_index;
675 normals.push_back(n);
679 poly_indices.
add_index(last_normal_index);
683 polygons_normals.push_back(poly_indices);
688 COLLADASW::InputSemantic::Semantics type,
689 std::string other_suffix)
691 return geom_id + getSuffixBySemantic(type) + other_suffix;
695 COLLADASW::InputSemantic::Semantics type,
696 std::string other_suffix)
700 return COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING,
id);
705 return COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING,
id);
CustomData interface, see also DNA_customdata_types.h.
int CustomData_get_layer_index_n(const CustomData *data, eCustomDataType type, int n)
const void * CustomData_get_layer_n(const CustomData *data, eCustomDataType type, int n)
int CustomData_get_active_layer(const CustomData *data, eCustomDataType type)
bool CustomData_has_layer(const CustomData *data, eCustomDataType type)
int CustomData_get_active_layer_index(const CustomData *data, eCustomDataType type)
int CustomData_number_of_layers(const CustomData *data, eCustomDataType type)
void BKE_keyblock_convert_to_mesh(const KeyBlock *kb, float(*vert_positions)[3], int totvert)
Key * BKE_key_from_object(Object *ob)
void BKE_id_free(Main *bmain, void *idv)
General operations, lookup, etc. for materials.
struct Material * BKE_object_material_get(struct Object *ob, short act)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE float normalize_v3_v3(float r[3], const float a[3])
MINLINE float normalize_v3(float n[3])
#define SNPRINTF(dst, format,...)
static void prepareToAppendValues(bool is_triangulated, COLLADASW::PrimitivesBase &primitive_list, std::vector< ulong > &vcount_list)
static void finish_and_delete_primitive_List(bool is_triangulated, COLLADASW::PrimitivesBase *primitive_list)
static bool collect_vertex_counts_per_poly(Mesh *mesh, int material_index, std::vector< ulong > &vcount_list)
bool operator<(const Normal &a, const Normal &b)
static COLLADASW::PrimitivesBase * create_primitive_list(bool is_triangulated, COLLADASW::StreamWriter *mSW)
SIMD_FORCE_INLINE btVector3 normalized() const
Return a normalized version of this vector.
void add_index(unsigned int index)
void createVertsSource(std::string geom_id, Mesh *mesh)
void createLooseEdgeList(Object *ob, Mesh *mesh, std::string &geom_id)
void createTexcoordsSource(std::string geom_id, Mesh *mesh)
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)
void createNormalsSource(std::string geom_id, Mesh *mesh, std::vector< Normal > &nor)
void operator()(Object *ob)
void create_mesh_primitive_list(short material_index, bool has_uvs, bool has_color, Object *ob, Mesh *mesh, std::string &geom_id, std::vector< BCPolygonNormalsIndices > &norind)
std::string getIdBySemantics(std::string geom_id, COLLADASW::InputSemantic::Semantics type, std::string other_suffix="")
void create_normals(std::vector< Normal > &nor, std::vector< BCPolygonNormalsIndices > &polygons_normals, Mesh *mesh)
std::string makeVertexColorSourceId(std::string &geom_id, const char *layer_name)
void export_key_mesh(Object *ob, Mesh *mesh, KeyBlock *kb)
void createVertexColorSource(std::string geom_id, Mesh *mesh)
constexpr int64_t size() const
constexpr bool is_empty() const
constexpr Span slice(int64_t start, int64_t size) const
std::string encode_xml(const std::string &xml)
std::string translate_id(const char *idString)
std::string get_geometry_id(Object *ob)
std::string get_material_id(Material *mat)
std::string id_name(void *id)
void bc_add_global_transform(Matrix &to_mat, const Matrix &from_mat, const BCMatrix &global_transform, const bool invert)
Mesh * bc_get_mesh_copy(BlenderContext &blender_context, Object *ob, BC_export_mesh_type export_mesh_type, bool apply_modifiers, bool triangulate)
const char * bc_CustomData_get_layer_name(const CustomData *data, eCustomDataType type, int n)
local_group_size(16, 16) .push_constant(Type b
float3 face_normal_calc(Span< float3 > vert_positions, Span< int > face_verts)
Frequency::GEOMETRY nor[]
void forEachMeshObjectInExportSet(Scene *sce, Functor &f, LinkNode *export_set)
blender::BitVector is_loose_bits