Merge branch 'master' into blender2.8
[blender.git] / source / blender / collada / GeometryExporter.cpp
index f110f4c3aa0ddf70dd391cccf65b4a6761facd3f..27ff6b5f2b5ff4253926e3f7ff4668f0ab15fe0c 100644 (file)
@@ -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,202 +405,22 @@ 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]);
+                               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;
-}
-
-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);
-
+               
+       polylist.finish();
 }
 
-/* ===========================================================================
- * 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 = (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 = (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]);
-                               if (has_uvs)
-                                       facelist->appendValues(texindex + j);
-
-                               if (has_color)
-                                       facelist->appendValues(texindex + j);
-                       }
-               }
-
-               texindex += loop_count;
-       }
-
-       finishList(is_triangulated, facelist);
-       delete facelist;
-}
 
 // creates <source> for positions
 void GeometryExporter::createVertsSource(std::string geom_id, Mesh *me)
@@ -776,13 +538,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);