Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/collada/GeometryExporter.cpp')
-rw-r--r--source/blender/collada/GeometryExporter.cpp328
1 files changed, 182 insertions, 146 deletions
diff --git a/source/blender/collada/GeometryExporter.cpp b/source/blender/collada/GeometryExporter.cpp
index f33f0fa110d..669b787062a 100644
--- a/source/blender/collada/GeometryExporter.cpp
+++ b/source/blender/collada/GeometryExporter.cpp
@@ -53,10 +53,10 @@ extern "C" {
#include "collada_utils.h"
// TODO: optimize UV sets by making indexed list with duplicates removed
-GeometryExporter::GeometryExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryGeometries(sw), export_settings(export_settings) {
+GeometryExporter::GeometryExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryGeometries(sw), export_settings(export_settings)
+{
}
-
void GeometryExporter::exportGeom(Scene *sce)
{
openLibrary();
@@ -69,26 +69,22 @@ void GeometryExporter::exportGeom(Scene *sce)
}
void GeometryExporter::operator()(Object *ob)
-{
+{
// XXX don't use DerivedMesh, Mesh instead?
-
#if 0
DerivedMesh *dm = mesh_get_derived_final(mScene, ob, CD_MASK_BAREMESH);
#endif
bool use_instantiation = this->export_settings->use_object_instantiation;
- Mesh *me;
- if (this->export_settings->apply_modifiers) {
- me = bc_to_mesh_apply_modifiers(mScene, ob, this->export_settings->export_mesh_type);
- }
- else {
- me = (Mesh *)ob->data;
- }
- BKE_mesh_tessface_ensure(me);
+ Mesh *me = bc_get_mesh_copy( mScene,
+ ob,
+ this->export_settings->export_mesh_type,
+ this->export_settings->apply_modifiers,
+ this->export_settings->triangulate);
std::string geom_id = get_geometry_id(ob, use_instantiation);
std::vector<Normal> nor;
- std::vector<Face> norind;
+ std::vector<BCPolygonNormalsIndices> norind;
// Skip if linked geometry was already exported from another reference
if (use_instantiation &&
@@ -117,12 +113,13 @@ void GeometryExporter::operator()(Object *ob)
bool has_uvs = (bool)CustomData_has_layer(&me->fdata, CD_MTFACE);
// writes <source> for uv coords if mesh has uv coords
- if (has_uvs)
+ if (has_uvs) {
createTexcoordsSource(geom_id, me);
+ }
- if (has_color)
+ if (has_color) {
createVertexColorSource(geom_id, me);
-
+ }
// <vertices>
COLLADASW::Vertices verts(mSW);
@@ -132,7 +129,7 @@ void GeometryExporter::operator()(Object *ob)
input_list.push_back(input);
verts.add();
- createLooseEdgeList(ob, me, geom_id, norind);
+ createLooseEdgeList(ob, me, geom_id);
// Only create Polylists if number of faces > 0
if (me->totface > 0) {
@@ -155,22 +152,95 @@ void GeometryExporter::operator()(Object *ob)
closeGeometry();
- if (this->export_settings->apply_modifiers)
- {
- BKE_libblock_free_us(&(G.main->mesh), me);
+ if (this->export_settings->include_shapekeys) {
+ Key * key = BKE_key_from_object(ob);
+ if (key) {
+ KeyBlock * kb = (KeyBlock *)key->block.first;
+ //skip the basis
+ kb = kb->next;
+ for (; kb; kb = kb->next) {
+ BKE_key_convert_to_mesh(kb, me);
+ export_key_mesh(ob, me, kb);
+ }
+ }
}
+ BKE_libblock_free_us(&(G.main->mesh), me);
-#if 0
- dm->release(dm);
-#endif
}
+void GeometryExporter::export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb)
+{
+ std::string geom_id = get_geometry_id(ob, false) + "_morph_" + translate_id(kb->name);
+ std::vector<Normal> nor;
+ std::vector<BCPolygonNormalsIndices> norind;
+
+ if (exportedGeometry.find(geom_id) != exportedGeometry.end())
+ {
+ return;
+ }
+
+ std::string geom_name = kb->name;
+
+ exportedGeometry.insert(geom_id);
+
+ bool has_color = (bool)CustomData_has_layer(&me->fdata, CD_MCOL);
+
+ create_normals(nor, norind, me);
+
+ // openMesh(geoId, geoName, meshId)
+ openMesh(geom_id, geom_name);
+
+ // writes <source> for vertex coords
+ createVertsSource(geom_id, me);
+
+ // writes <source> for normal coords
+ createNormalsSource(geom_id, me, nor);
+
+ bool has_uvs = (bool)CustomData_has_layer(&me->fdata, CD_MTFACE);
+
+ // writes <source> for uv coords if mesh has uv coords
+ if (has_uvs) {
+ createTexcoordsSource(geom_id, me);
+ }
+
+ if (has_color) {
+ createVertexColorSource(geom_id, me);
+ }
+
+ // <vertices>
+
+ COLLADASW::Vertices verts(mSW);
+ verts.setId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::VERTEX));
+ COLLADASW::InputList &input_list = verts.getInputList();
+ COLLADASW::Input input(COLLADASW::InputSemantic::POSITION, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::POSITION));
+ input_list.push_back(input);
+ verts.add();
+
+ //createLooseEdgeList(ob, me, geom_id, norind);
+
+ // XXX slow
+ if (ob->totcol) {
+ for (int a = 0; a < ob->totcol; a++) {
+ createPolylist(a, has_uvs, has_color, ob, me, geom_id, norind);
+ }
+ }
+ else {
+ createPolylist(0, has_uvs, has_color, ob, me, geom_id, norind);
+ }
+
+ closeMesh();
+
+ if (me->flag & ME_TWOSIDED) {
+ mSW->appendTextBlock("<extra><technique profile=\"MAYA\"><double_sided>1</double_sided></technique></extra>");
+ }
+
+ closeGeometry();
+}
void GeometryExporter::createLooseEdgeList(Object *ob,
Mesh *me,
- std::string& geom_id,
- std::vector<Face>& norind)
+ std::string& geom_id)
{
MEdge *medges = me->medge;
@@ -226,10 +296,12 @@ void GeometryExporter::createPolylist(short material_index,
Object *ob,
Mesh *me,
std::string& geom_id,
- std::vector<Face>& norind)
+ std::vector<BCPolygonNormalsIndices>& norind)
{
- MFace *mfaces = me->mface;
- int totfaces = me->totface;
+
+ MPoly *mpolys = me->mpoly;
+ MLoop *mloops = me->mloop;
+ int totpolys = me->totpoly;
// <vcount>
int i;
@@ -237,17 +309,12 @@ void GeometryExporter::createPolylist(short material_index,
std::vector<unsigned long> vcount_list;
// count faces with this material
- for (i = 0; i < totfaces; i++) {
- MFace *f = &mfaces[i];
+ for (i = 0; i < totpolys; i++) {
+ MPoly *p = &mpolys[i];
- if (f->mat_nr == material_index) {
+ if (p->mat_nr == material_index) {
faces_in_polylist++;
- if (f->v4 == 0) {
- vcount_list.push_back(3);
- }
- else {
- vcount_list.push_back(4);
- }
+ vcount_list.push_back(p->totloop);
}
}
@@ -309,21 +376,19 @@ void GeometryExporter::createPolylist(short material_index,
// performs the actual writing
polylist.prepareToAppendValues();
-
-
// <p>
int texindex = 0;
- for (i = 0; i < totfaces; i++) {
- MFace *f = &mfaces[i];
+ for (i = 0; i < totpolys; i++) {
+ MPoly *p = &mpolys[i];
+ int loop_count = p->totloop;
- if (f->mat_nr == material_index) {
-
- unsigned int *v = &f->v1;
- unsigned int *n = &norind[i].v1;
- for (int j = 0; j < (f->v4 == 0 ? 3 : 4); j++) {
- polylist.appendValues(v[j]);
- polylist.appendValues(n[j]);
+ if (p->mat_nr == material_index) {
+ MLoop *l = &mloops[p->loopstart];
+ BCPolygonNormalsIndices normal_indices = norind[i];
+ for (int j = 0; j < loop_count; j++) {
+ polylist.appendValues(l[j].v);
+ polylist.appendValues(normal_indices[j]);
if (has_uvs)
polylist.appendValues(texindex + j);
@@ -332,14 +397,13 @@ void GeometryExporter::createPolylist(short material_index,
}
}
- texindex += 3;
- if (f->v4 != 0)
- texindex++;
+ texindex += loop_count;
}
polylist.finish();
}
+
// creates <source> for positions
void GeometryExporter::createVertsSource(std::string geom_id, Mesh *me)
{
@@ -375,19 +439,14 @@ void GeometryExporter::createVertsSource(std::string geom_id, Mesh *me)
void GeometryExporter::createVertexColorSource(std::string geom_id, Mesh *me)
{
- if (!CustomData_has_layer(&me->fdata, CD_MCOL))
+ if (!CustomData_has_layer(&me->ldata, CD_MLOOPCOL))
return;
- MFace *f;
- int totcolor = 0, i, j;
-
- for (i = 0, f = me->mface; i < me->totface; i++, f++)
- totcolor += f->v4 ? 4 : 3;
COLLADASW::FloatSourceF source(mSW);
source.setId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::COLOR));
source.setArrayId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::COLOR) + ARRAY_ID_SUFFIX);
- source.setAccessorCount(totcolor);
+ source.setAccessorCount(me->totloop);
source.setAccessorStride(3);
COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
@@ -397,18 +456,26 @@ void GeometryExporter::createVertexColorSource(std::string geom_id, Mesh *me)
source.prepareToAppendValues();
- int index = CustomData_get_active_layer_index(&me->fdata, CD_MCOL);
-
- MCol *mcol = (MCol *)me->fdata.layers[index].data;
- MCol *c = mcol;
+ int index = CustomData_get_active_layer_index(&me->ldata, CD_MLOOPCOL);
+ MCol *mcol = (MCol *)me->ldata.layers[index].data;
- for (i = 0, f = me->mface; i < me->totface; i++, c += 4, f++)
- for (j = 0; j < (f->v4 ? 4 : 3); j++)
- source.appendValues(c[j].b / 255.0f, c[j].g / 255.0f, c[j].r / 255.0f);
+ MPoly *mpoly;
+ int i;
+ for (i = 0, mpoly = me->mpoly; i < me->totpoly; i++, mpoly++) {
+ MCol *color = mcol + mpoly->loopstart;
+ for (int j = 0; j < mpoly->totloop; j++, color++) {
+ source.appendValues(
+ color->b / 255.0f,
+ color->g / 255.0f,
+ color->r / 255.0f
+ );
+ }
+ }
source.finish();
}
+
std::string GeometryExporter::makeTexcoordSourceId(std::string& geom_id, int layer_index)
{
char suffix[20];
@@ -419,38 +486,21 @@ std::string GeometryExporter::makeTexcoordSourceId(std::string& geom_id, int lay
//creates <source> for texcoords
void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me)
{
-#if 0
- int totfaces = dm->getNumTessFaces(dm);
- MFace *mfaces = dm->getTessFaceArray(dm);
-#endif
- int totfaces = me->totface;
- MFace *mfaces = me->mface;
-
- int totuv = 0;
- int i;
- // count totuv
- for (i = 0; i < totfaces; i++) {
- MFace *f = &mfaces[i];
- if (f->v4 == 0) {
- totuv += 3;
- }
- else {
- totuv += 4;
- }
- }
+ int totpoly = me->totpoly;
+ int totuv = me->totloop;
+ MPoly *mpolys = me->mpoly;
- int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
+ int num_layers = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV);
// write <source> for each layer
// each <source> will get id like meshName + "map-channel-1"
int map_index = 0;
- int active_uv_index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE)-1;
+ int active_uv_index = CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV);
for (int a = 0; a < num_layers; a++) {
if (!this->export_settings->active_uv_only || a == active_uv_index) {
- MTFace *tface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, a);
- // char *name = CustomData_get_layer_name(&me->fdata, CD_MTFACE, a);
+ MLoopUV *mloops = (MLoopUV *)CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, a);
COLLADASW::FloatSourceF source(mSW);
std::string layer_id = makeTexcoordSourceId(geom_id, map_index++);
@@ -465,12 +515,12 @@ void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me)
source.prepareToAppendValues();
- for (i = 0; i < totfaces; i++) {
- MFace *f = &mfaces[i];
-
- for (int j = 0; j < (f->v4 == 0 ? 3 : 4); j++) {
- source.appendValues(tface[i].uv[j][0],
- tface[i].uv[j][1]);
+ for (int index = 0; index < totpoly; index++) {
+ MPoly *mpoly = mpolys+index;
+ MLoopUV *mloop = mloops+mpoly->loopstart;
+ for (int j = 0; j < mpoly->totloop; j++) {
+ source.appendValues(mloop[j].uv[0],
+ mloop[j].uv[1]);
}
}
@@ -510,53 +560,54 @@ void GeometryExporter::createNormalsSource(std::string geom_id, Mesh *me, std::v
source.finish();
}
-void GeometryExporter::create_normals(std::vector<Normal> &nor, std::vector<Face> &ind, Mesh *me)
+void GeometryExporter::create_normals(std::vector<Normal> &normals, std::vector<BCPolygonNormalsIndices> &polygons_normals, Mesh *me)
{
- int i, j, v;
- MVert *vert = me->mvert;
- std::map<unsigned int, unsigned int> nshar;
-
- for (i = 0; i < me->totface; i++) {
- MFace *fa = &me->mface[i];
- Face f;
- unsigned int *nn = &f.v1;
- unsigned int *vv = &fa->v1;
-
- memset(&f, 0, sizeof(f));
- v = fa->v4 == 0 ? 3 : 4;
-
- if (!(fa->flag & ME_SMOOTH)) {
- Normal n;
- if (v == 4)
- normal_quad_v3(&n.x, vert[fa->v1].co, vert[fa->v2].co, vert[fa->v3].co, vert[fa->v4].co);
- else
- normal_tri_v3(&n.x, vert[fa->v1].co, vert[fa->v2].co, vert[fa->v3].co);
- nor.push_back(n);
+ std::map<unsigned int, unsigned int> shared_normal_indices;
+ int last_normal_index = -1;
+
+ MVert *verts = me->mvert;
+ MLoop *mloops = me->mloop;
+ for (int poly_index = 0; poly_index < me->totpoly; poly_index++) {
+ MPoly *mpoly = &me->mpoly[poly_index];
+
+ if (!(mpoly->flag & ME_SMOOTH)) {
+ // For flat faces use face normal as vertex normal:
+
+ float vector[3];
+ BKE_mesh_calc_poly_normal(mpoly, mloops, verts, vector);
+
+ Normal n = { vector[0], vector[1], vector[2] };
+ normals.push_back(n);
+ last_normal_index++;
}
- for (j = 0; j < v; j++) {
- if (fa->flag & ME_SMOOTH) {
- if (nshar.find(*vv) != nshar.end())
- *nn = nshar[*vv];
+
+ MLoop *mloop = mloops + mpoly->loopstart;
+ BCPolygonNormalsIndices poly_indices;
+ for (int loop_index = 0; loop_index < mpoly->totloop; loop_index++) {
+ unsigned int vertex_index = mloop[loop_index].v;
+ if (mpoly->flag & ME_SMOOTH) {
+ if (shared_normal_indices.find(vertex_index) != shared_normal_indices.end())
+ poly_indices.add_index (shared_normal_indices[vertex_index]);
else {
- Normal n = {
- (float)vert[*vv].no[0] / 32767.0f,
- (float)vert[*vv].no[1] / 32767.0f,
- (float)vert[*vv].no[2] / 32767.0f
- };
- nor.push_back(n);
- *nn = (unsigned int)nor.size() - 1;
- nshar[*vv] = *nn;
+
+ float vector[3];
+ normal_short_to_float_v3(vector, verts[vertex_index].no);
+
+ Normal n = { vector[0], vector[1], vector[2] };
+ normals.push_back(n);
+ last_normal_index++;
+
+ poly_indices.add_index(last_normal_index);
+ shared_normal_indices[vertex_index] = last_normal_index;
}
- vv++;
}
else {
- *nn = (unsigned int)nor.size() - 1;
+ poly_indices.add_index(last_normal_index);
}
- nn++;
}
- ind.push_back(f);
+ polygons_normals.push_back(poly_indices);
}
}
@@ -579,19 +630,4 @@ COLLADASW::URI GeometryExporter::makeUrl(std::string id)
return COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, id);
}
-#if 0
-int GeometryExporter::getTriCount(MFace *faces, int totface)
-{
- int i;
- int tris = 0;
- for (i = 0; i < totface; i++) {
- // if quad
- if (faces[i].v4 != 0)
- tris += 2;
- else
- tris++;
- }
- return tris;
-}
-#endif