diff options
Diffstat (limited to 'source/blender/collada/GeometryExporter.cpp')
-rw-r--r-- | source/blender/collada/GeometryExporter.cpp | 311 |
1 files changed, 33 insertions, 278 deletions
diff --git a/source/blender/collada/GeometryExporter.cpp b/source/blender/collada/GeometryExporter.cpp index 73b00fd07ec..8dbee607b01 100644 --- a/source/blender/collada/GeometryExporter.cpp +++ b/source/blender/collada/GeometryExporter.cpp @@ -52,16 +52,16 @@ extern "C" { #include "collada_internal.h" #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) { } -void GeometryExporter::exportGeom(Scene *sce) +void GeometryExporter::exportGeom(const struct EvaluationContext *eval_ctx, Scene *sce) { openLibrary(); + mEvalCtx = eval_ctx; mScene = sce; GeometryFunctor gf; gf.forEachMeshObjectInExportSet<GeometryExporter>(sce, *this, this->export_settings->export_set); @@ -77,7 +77,7 @@ void GeometryExporter::operator()(Object *ob) #endif bool use_instantiation = this->export_settings->use_object_instantiation; - Mesh *me = bc_get_mesh_copy( mScene, + Mesh *me = bc_get_mesh_copy(mEvalCtx, mScene, ob, this->export_settings->export_mesh_type, this->export_settings->apply_modifiers, @@ -135,22 +135,13 @@ void GeometryExporter::operator()(Object *ob) // Only create Polylists if number of faces > 0 if (me->totface > 0) { // XXX slow - std::set<Image *> uv_images = bc_getUVImages(ob, !this->export_settings->active_uv_only); - if (this->export_settings->export_texture_type == BC_TEXTURE_TYPE_MAT || uv_images.size() == 0) { - if (ob->totcol) { - for (int a = 0; a < ob->totcol; a++) { - createPolylist(a, has_uvs, has_color, ob, me, geom_id, norind); - } - } - else { - int i = 0; - createPolylist(i, has_uvs, has_color, ob, me, geom_id, norind); + if (ob->totcol) { + for (int a = 0; a < ob->totcol; a++) { + createPolylist(a, has_uvs, has_color, ob, me, geom_id, norind); } } else { - bool all_uv_layers = !this->export_settings->active_uv_only; - std::set<Image *> uv_images = bc_getUVImages(ob, all_uv_layers); - createPolylists(uv_images, has_uvs, has_color, ob, me, geom_id, norind); + createPolylist(0, has_uvs, has_color, ob, me, geom_id, norind); } } @@ -230,15 +221,13 @@ void GeometryExporter::export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb) //createLooseEdgeList(ob, me, geom_id, norind); // XXX slow - if (ob->totcol && this->export_settings->export_texture_type == BC_TEXTURE_TYPE_MAT) { + if (ob->totcol) { for (int a = 0; a < ob->totcol; a++) { createPolylist(a, has_uvs, has_color, ob, me, geom_id, norind); } } else { - bool all_uv_layers = !this->export_settings->active_uv_only; - std::set<Image *> uv_images = bc_getUVImages(ob, all_uv_layers); - createPolylists(uv_images, has_uvs, has_color, ob, me, geom_id, norind); + createPolylist(0, has_uvs, has_color, ob, me, geom_id, norind); } closeMesh(); @@ -307,44 +296,7 @@ std::string GeometryExporter::makeVertexColorSourceId(std::string& geom_id, char return result; } -static void prepareToAppendValues(bool is_triangulated, COLLADASW::PrimitivesBase *facelist, std::vector<unsigned long> &vcount_list) -{ - // performs the actual writing - if (is_triangulated) { - ((COLLADASW::Triangles *)facelist)->prepareToAppendValues(); - } - else { - // sets <vcount> - facelist->setVCountList(vcount_list); - ((COLLADASW::Polylist *)facelist)-> prepareToAppendValues(); - } -} - -static void finishList(bool is_triangulated, COLLADASW::PrimitivesBase *facelist) -{ - if (is_triangulated) { - ((COLLADASW::Triangles *)facelist)->finish(); - } - else { - ((COLLADASW::Polylist *)facelist)->finish(); - } -} - -COLLADASW::PrimitivesBase *getFacelist(bool is_triangulated, COLLADASW::StreamWriter *mSW) -{ - COLLADASW::PrimitivesBase *facelist; - - if (is_triangulated) - { - facelist = new COLLADASW::Triangles(mSW); - } - else { - facelist = new COLLADASW::Polylist(mSW); - } - return facelist; -} - -// Export meshes with Materials +// powerful because it handles both cases when there is material and when there's not void GeometryExporter::createPolylist(short material_index, bool has_uvs, bool has_color, @@ -362,7 +314,7 @@ void GeometryExporter::createPolylist(short material_index, int i; int faces_in_polylist = 0; std::vector<unsigned long> vcount_list; - bool is_triangulated = true; + // count faces with this material for (i = 0; i < totpolys; i++) { MPoly *p = &mpolys[i]; @@ -370,9 +322,6 @@ void GeometryExporter::createPolylist(short material_index, if (p->mat_nr == material_index) { faces_in_polylist++; vcount_list.push_back(p->totloop); - if (p->totloop != 3) { - is_triangulated = false; - } } } @@ -383,21 +332,20 @@ void GeometryExporter::createPolylist(short material_index, } Material *ma = ob->totcol ? give_current_material(ob, material_index + 1) : NULL; - COLLADASW::PrimitivesBase *facelist = getFacelist(is_triangulated, mSW); - + COLLADASW::Polylist polylist(mSW); // sets count attribute in <polylist> - facelist->setCount(faces_in_polylist); + polylist.setCount(faces_in_polylist); // sets material name if (ma) { std::string material_id = get_material_id(ma); std::ostringstream ostr; ostr << translate_id(material_id); - facelist->setMaterial(ostr.str()); + polylist.setMaterial(ostr.str()); } - - COLLADASW::InputList &til = facelist->getInputList(); + + COLLADASW::InputList &til = polylist.getInputList(); // creates <input> in <polylist> for vertices COLLADASW::Input input1(COLLADASW::InputSemantic::VERTEX, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::VERTEX), 0); @@ -413,21 +361,13 @@ void GeometryExporter::createPolylist(short material_index, int active_uv_index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE)-1; for (i = 0; i < num_layers; i++) { if (!this->export_settings->active_uv_only || i == active_uv_index) { - - std::string uv_name(bc_get_uvlayer_name(me, i)); - std::string effective_id = geom_id; // (uv_name == "") ? geom_id : uv_name; - std::string layer_id = makeTexcoordSourceId( - effective_id, - i, this->export_settings->active_uv_only); - - /* Note: the third parameter denotes the offset of TEXCOORD in polylist elements - For now this is always 2 (This may change sometime/maybe) - */ + + // char *name = CustomData_get_layer_name(&me->fdata, CD_MTFACE, i); COLLADASW::Input input3(COLLADASW::InputSemantic::TEXCOORD, - makeUrl(layer_id), - 2, // this is only until we have optimized UV sets - (this->export_settings->active_uv_only) ? 0 : i // only_active_uv exported -> we have only one set - ); + makeUrl(makeTexcoordSourceId(geom_id, i, this->export_settings->active_uv_only)), + 2, // this is only until we have optimized UV sets + (this->export_settings->active_uv_only) ? 0 : i // only_active_uv exported -> we have only one set + ); til.push_back(input3); } } @@ -448,10 +388,12 @@ void GeometryExporter::createPolylist(short material_index, } } + // sets <vcount> + polylist.setVCountList(vcount_list); // performs the actual writing - prepareToAppendValues(is_triangulated, facelist, vcount_list); - + polylist.prepareToAppendValues(); + // <p> int texindex = 0; for (i = 0; i < totpolys; i++) { @@ -463,201 +405,20 @@ void GeometryExporter::createPolylist(short material_index, BCPolygonNormalsIndices normal_indices = norind[i]; for (int j = 0; j < loop_count; j++) { - facelist->appendValues(l[j].v); - facelist->appendValues(normal_indices[j]); - if (has_uvs) - facelist->appendValues(texindex + j); - - if (has_color) - facelist->appendValues(texindex + j); - } - } - - texindex += loop_count; - } - - finishList(is_triangulated, facelist); - delete facelist; -} - -void GeometryExporter::createPolylists(std::set<Image *> uv_images, - bool has_uvs, - bool has_color, - Object *ob, - Mesh *me, - std::string& geom_id, - std::vector<BCPolygonNormalsIndices>& norind) -{ - std::set<Image *>::iterator uv_images_iter; - for (uv_images_iter = uv_images.begin(); - uv_images_iter != uv_images.end(); - uv_images_iter++) { - - Image *ima = *uv_images_iter; - std::string imageid(id_name(ima)); - createPolylist(imageid, has_uvs, - has_color, - ob, - me, - geom_id, - norind); - } - - /* We msut add an additional collector for the case when - * some parts of the object are not textured at all. - * The next call creates a polylist for all untextured polygons - */ - - createPolylist("", has_uvs, - has_color, - ob, - me, - geom_id, - norind); - -} - -/* =========================================================================== - * Export Meshes with UV Textures (export as materials, see also in - * effectExporter and MaterialExporter) - * - * If imageid is the empty string, then collect only untextured polygons - * =========================================================================== */ -void GeometryExporter::createPolylist(std::string imageid, - bool has_uvs, - bool has_color, - Object *ob, - Mesh *me, - std::string& geom_id, - std::vector<BCPolygonNormalsIndices>& norind) -{ - - MPoly *mpolys = me->mpoly; - MLoop *mloops = me->mloop; - MTexPoly *mtpolys = me->mtpoly; - - int totpolys = me->totpoly; - - // <vcount> - int i; - int faces_in_polylist = 0; - std::vector<unsigned long> vcount_list; - bool is_triangulated = true; - // count faces with this material - for (i = 0; i < totpolys; i++) { - MTexPoly *tp = &mtpolys[i]; - MPoly *p = &mpolys[i]; - - std::string tpageid = (mtpolys && tp->tpage) ? id_name(tp->tpage) : ""; - if (tpageid == imageid) { - faces_in_polylist++; - vcount_list.push_back(p->totloop); - if (p->totloop != 3) { - is_triangulated = false; - } - } - } - - // no faces using this imageid - if (faces_in_polylist == 0) { - if (imageid != "") - fprintf(stderr, "%s: Image %s is not used.\n", id_name(ob).c_str(), imageid.c_str()); - return; - } - - COLLADASW::PrimitivesBase *facelist = getFacelist(is_triangulated, mSW); - - // sets count attribute in <polylist> - facelist->setCount(faces_in_polylist); - - if (imageid != "") { - // sets material name - std::string material_id = get_material_id_from_id(imageid); - std::ostringstream ostr; - ostr << translate_id(material_id); - facelist->setMaterial(ostr.str()); - } - COLLADASW::InputList &til = facelist->getInputList(); - - // creates <input> in <polylist> for vertices - COLLADASW::Input input1(COLLADASW::InputSemantic::VERTEX, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::VERTEX), 0); - - // creates <input> in <polylist> for normals - COLLADASW::Input input2(COLLADASW::InputSemantic::NORMAL, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::NORMAL), 1); - - til.push_back(input1); - til.push_back(input2); - - // if mesh has uv coords writes <input> for TEXCOORD - int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE); - int active_uv_index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE) - 1; - for (i = 0; i < num_layers; i++) { - if (!this->export_settings->active_uv_only || i == active_uv_index) { - - std::string uv_name(bc_get_uvlayer_name(me, i)); - std::string effective_id = geom_id; // (uv_name == "") ? geom_id : uv_name; - std::string layer_id = makeTexcoordSourceId( - effective_id, - i, this->export_settings->active_uv_only); - - /* Note: the third parameter denotes the offset of TEXCOORD in polylist elements - For now this is always 2 (This may change sometime/maybe) - */ - COLLADASW::Input input3(COLLADASW::InputSemantic::TEXCOORD, - makeUrl(layer_id), - 2, // this is only until we have optimized UV sets - (this->export_settings->active_uv_only) ? 0 : i // only_active_uv exported -> we have only one set - ); - til.push_back(input3); - } - } - - int totlayer_mcol = CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL); - if (totlayer_mcol > 0) { - int map_index = 0; - - for (int a = 0; a < totlayer_mcol; a++) { - char *layer_name = bc_CustomData_get_layer_name(&me->ldata, CD_MLOOPCOL, a); - COLLADASW::Input input4(COLLADASW::InputSemantic::COLOR, - makeUrl(makeVertexColorSourceId(geom_id, layer_name)), - (has_uvs) ? 3 : 2, // all color layers have same index order - map_index // set number equals color map index - ); - til.push_back(input4); - map_index++; - } - } - - // performs the actual writing - prepareToAppendValues(is_triangulated, facelist, vcount_list); - - // <p> - int texindex = 0; - for (i = 0; i < totpolys; i++) { - MTexPoly *tp = &mtpolys[i]; - MPoly *p = &mpolys[i]; - int loop_count = p->totloop; - std::string tpageid = (mtpolys && tp->tpage) ? id_name(tp->tpage) : ""; - if (tpageid == imageid) { - MLoop *l = &mloops[p->loopstart]; - BCPolygonNormalsIndices normal_indices = norind[i]; - - for (int j = 0; j < loop_count; j++) { - facelist->appendValues(l[j].v); - facelist->appendValues(normal_indices[j]); + polylist.appendValues(l[j].v); + polylist.appendValues(normal_indices[j]); if (has_uvs) - facelist->appendValues(texindex + j); + polylist.appendValues(texindex + j); if (has_color) - facelist->appendValues(texindex + j); + polylist.appendValues(texindex + j); } } texindex += loop_count; } - - finishList(is_triangulated, facelist); - delete facelist; + + polylist.finish(); } // creates <source> for positions @@ -778,13 +539,7 @@ void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me) MLoopUV *mloops = (MLoopUV *)CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, a); COLLADASW::FloatSourceF source(mSW); - std::string active_uv_name(bc_get_active_uvlayer_name(me)); - std::string effective_id = geom_id; // (active_uv_name == "") ? geom_id : active_uv_name; - std::string layer_id = makeTexcoordSourceId( - effective_id, - a, - this->export_settings->active_uv_only ); - + std::string layer_id = makeTexcoordSourceId(geom_id, a, this->export_settings->active_uv_only); source.setId(layer_id); source.setArrayId(layer_id + ARRAY_ID_SUFFIX); |