Revision: 21079
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=21079
Author:   chingachgook
Date:     2009-06-22 18:21:59 +0200 (Mon, 22 Jun 2009)

Log Message:
-----------
COLLADA exporter:
* removed code duplication for object and material traversing
* removed geometry, material, image duplication in produced DAE

TODO:
* UVs export still needs fixing/improvments
* Material/texcoord binding is not done

Modified Paths:
--------------
    branches/soc-2009-chingachgook/source/blender/collada/DocumentExporter.cpp

Modified: 
branches/soc-2009-chingachgook/source/blender/collada/DocumentExporter.cpp
===================================================================
--- branches/soc-2009-chingachgook/source/blender/collada/DocumentExporter.cpp  
2009-06-22 13:45:18 UTC (rev 21078)
+++ branches/soc-2009-chingachgook/source/blender/collada/DocumentExporter.cpp  
2009-06-22 16:21:59 UTC (rev 21079)
@@ -42,164 +42,208 @@
 #include <COLLADASWLibraryMaterials.h>
 #include <COLLADASWBindMaterial.h>
 
+#include <vector>
+#include <algorithm> // std::find
 
-// not good idea - there are for example blender Scene and COLLADASW::Scene
-//using namespace COLLADASW;
+// utilities to avoid code duplication
+// definition of these is difficult to read, but they should be useful
 
+// f should have
+// void operator()(Object* ob)
+template<class Functor>
+void forEachMeshObjectInScene(Scene *sce, Functor &f)
+{
+       Base *base= (Base*) sce->base.first;
+       while(base) {
+               Object *ob = base->object;
+                       
+               if (ob->type == OB_MESH && ob->data) {
+                       f(ob);
+               }
+               base= base->next;
+       }
+}
 
+// used in forEachMaterialInScene
+template <class MaterialFunctor>
+class ForEachMaterialFunctor
+{
+       std::vector<std::string> mMat; // contains list of material names, to 
avoid duplicate calling of f
+       MaterialFunctor *f;
+public:
+       ForEachMaterialFunctor(MaterialFunctor *f) : f(f) { }
+       void operator ()(Object *ob)
+       {
+               int a;
+               for(a = 0; a < ob->totcol; a++) {
+
+                       Material *ma = give_current_material(ob, a+1);
+
+                       if (find(mMat.begin(), mMat.end(), 
std::string(ma->id.name)) == mMat.end()) {
+                               (*this->f)(ma);
+
+                               mMat.push_back(ma->id.name);
+                       }
+               }
+       }
+};
+
+// calls f for each unique material linked to each object in sce
+// f should have
+// void operator()(Material* ma)
+template<class Functor>
+void forEachMaterialInScene(Scene *sce, Functor &f)
+{
+       ForEachMaterialFunctor<Functor> matfunc(&f);
+       forEachMeshObjectInScene(sce, matfunc);
+}
+
 class GeometryExporter : COLLADASW::LibraryGeometries
 {
+       Scene *mScene;
 public:
        GeometryExporter(COLLADASW::StreamWriter *sw) : 
COLLADASW::LibraryGeometries(sw) {}
-       
-       
+
        void exportGeom(Scene *sce)
        {
-               //opens <library_geometries>
                openLibrary();
-               
-               // iterate over objects in scene
-               Base *base= (Base*) sce->base.first;
-               while(base) {
-                       
-                       Object *ob = base->object;
-                       
-                       // only meshes
-                       if (ob->type == OB_MESH && ob->data) {
-                               
-                               DerivedMesh *dm = mesh_get_derived_final(sce, 
ob, CD_MASK_BAREMESH);
-                               MVert *mverts = dm->getVertArray(dm);
-                               MFace *mfaces = dm->getFaceArray(dm);
-                               int totfaces = dm->getNumFaces(dm);
-                               int totverts = dm->getNumVerts(dm);
-                               bool checkTexcoords = false;
 
-                               std::string geom_name(ob->id.name);
+               mScene = sce;
+               forEachMeshObjectInScene(sce, *this);
 
-                               //openMesh(geoId, geoName, meshId)
-                               openMesh(geom_name, "", "");
+               closeLibrary();
+       }
 
-                               //writes <source> for vertex coords
-                               createVertsSource(sce, mSW, geom_name, dm);
-                               //writes <source> for normal coords
-                               createNormalsSource(sce, mSW, geom_name, dm);
-                               //writes <source> for uv coords
-                               //if mesh has uv coords
-                               checkTexcoords = createTexcoordsSource(sce, 
mSW, geom_name, dm, (Mesh*)ob->data);
+       void operator()(Object *ob)
+       {
+               // XXX don't use DerivedMesh, Mesh instead?
 
-                               //<vertices>
-                               COLLADASW::Vertices verts(mSW);
-                               verts.setId(getIdBySemantics(geom_name, 
COLLADASW::VERTEX));
-                               COLLADASW::InputList &input_list = 
verts.getInputList();
-                               COLLADASW::Input input(COLLADASW::POSITION,
-                                                                          
getUrlBySemantics(geom_name, COLLADASW::POSITION));
-                               input_list.push_back(input);
-                               verts.add();
+               DerivedMesh *dm = mesh_get_derived_final(mScene, ob, 
CD_MASK_BAREMESH);
+               MVert *mverts = dm->getVertArray(dm);
+               MFace *mfaces = dm->getFaceArray(dm);
+               int totfaces = dm->getNumFaces(dm);
+               int totverts = dm->getNumVerts(dm);
+               bool checkTexcoords = false;
+
+               std::string geom_name(ob->id.name);
+
+               //openMesh(geoId, geoName, meshId)
+               openMesh(geom_name, "", "");
+
+               //writes <source> for vertex coords
+               createVertsSource(geom_name, dm);
+               //writes <source> for normal coords
+               createNormalsSource(geom_name, dm);
+               //writes <source> for uv coords
+               //if mesh has uv coords
+               checkTexcoords = createTexcoordsSource(geom_name, dm, 
(Mesh*)ob->data);
+
+               //<vertices>
+               COLLADASW::Vertices verts(mSW);
+               verts.setId(getIdBySemantics(geom_name, COLLADASW::VERTEX));
+               COLLADASW::InputList &input_list = verts.getInputList();
+               COLLADASW::Input input(COLLADASW::POSITION,
+                                                          
getUrlBySemantics(geom_name, COLLADASW::POSITION));
+               input_list.push_back(input);
+               verts.add();
                                
-                               //<triangles>
-                               COLLADASW::Triangles tris(mSW);
-                               //sets count attribute in <triangles>
-                               tris.setCount(getTriCount(mfaces, totfaces));
+               //<triangles>
+               COLLADASW::Triangles tris(mSW);
+               //sets count attribute in <triangles>
+               tris.setCount(getTriCount(mfaces, totfaces));
                                
-                               COLLADASW::InputList &til = tris.getInputList();
-                               /*added semantic, source, offset attributes to 
<input> */
+               COLLADASW::InputList &til = tris.getInputList();
+               /*added semantic, source, offset attributes to <input> */
                                
-                          //creates list of attributes in <triangles> <input> 
for vertices 
-                               COLLADASW::Input input2(COLLADASW::VERTEX,
-                                                                               
getUrlBySemantics(geom_name, COLLADASW::VERTEX), 0);
-                               //creates list of attributes in <triangles> 
<input> for normals
-                               COLLADASW::Input input3(COLLADASW::NORMAL,
-                                                                               
getUrlBySemantics(geom_name, COLLADASW::NORMAL), 0);
+               //creates list of attributes in <triangles> <input> for 
vertices 
+               COLLADASW::Input input2(COLLADASW::VERTEX,
+                                                               
getUrlBySemantics(geom_name, COLLADASW::VERTEX), 0);
+               //creates list of attributes in <triangles> <input> for normals
+               COLLADASW::Input input3(COLLADASW::NORMAL,
+                                                               
getUrlBySemantics(geom_name, COLLADASW::NORMAL), 0);
                                
-                               til.push_back(input2);
-                               til.push_back(input3);
+               til.push_back(input2);
+               til.push_back(input3);
                                
-                               //if mesh has uv coords writes <input> 
attributes for TEXCOORD
-                               if (checkTexcoords == true)
-                                       {
-                                               COLLADASW::Input 
input4(COLLADASW::TEXCOORD,
-                                                                               
                getUrlBySemantics(geom_name, COLLADASW::TEXCOORD), 1, 1);
-                                               til.push_back(input4);
-                                               //XXX
-                                               
tris.setMaterial("material-symbol");
-                                       }
-                               //performs the actual writing
-                               tris.prepareToAppendValues();
+               //if mesh has uv coords writes <input> attributes for TEXCOORD
+               if (checkTexcoords == true)
+                       {
+                               COLLADASW::Input input4(COLLADASW::TEXCOORD,
+                                                                               
getUrlBySemantics(geom_name, COLLADASW::TEXCOORD), 1, 1);
+                               til.push_back(input4);
+                               //XXX
+                               tris.setMaterial("material-symbol");
+                       }
+               //performs the actual writing
+               tris.prepareToAppendValues();
                                
-                               int i;
-                               int texindex = 0;
-                               //writes data to <p>
-                               for (i = 0; i < totfaces; i++) {
-                                       MFace *f = &mfaces[i];
-                                       //if mesh has uv coords writes uv and
-                                       //vertex indexes
-                                       if (checkTexcoords == true)     {
-                                               // if triangle
-                                               if (f->v4 == 0) {
-                                                       
tris.appendValues(f->v1);
-                                                       
tris.appendValues(texindex++);
-                                                       
tris.appendValues(f->v2);
-                                                       
tris.appendValues(texindex++);
-                                                       
tris.appendValues(f->v3);
-                                                       
tris.appendValues(texindex++);
-                                               }
-                                               // quad
-                                               else {
-                                                       
tris.appendValues(f->v1);
-                                                       
tris.appendValues(texindex++);
-                                                       
tris.appendValues(f->v2);
-                                                       
tris.appendValues(texindex++);
-                                                       
tris.appendValues(f->v3);
-                                                       
tris.appendValues(texindex++);
-                                                       
tris.appendValues(f->v3);
-                                                       
tris.appendValues(texindex++);
-                                                       
tris.appendValues(f->v4);
-                                                       
tris.appendValues(texindex++);
-                                                       
tris.appendValues(f->v1);
-                                                       
tris.appendValues(texindex++);
-                                               }
-                                       }
-                                       //if mesh has no uv coords writes only 
-                                       //vertex indexes
-                                       else {
-                                               // if triangle
-                                               if (f->v4 == 0) {
-                                                       
tris.appendValues(f->v1, f->v2, f->v3); 
-                                               }
-                                               // quad
-                                               else {
-                                                       
tris.appendValues(f->v1, f->v2, f->v3);
-                                                       
tris.appendValues(f->v3, f->v4, f->v1);
-                                               }
+               int i;
+               int texindex = 0;
+               //writes data to <p>
+               for (i = 0; i < totfaces; i++) {
+                       MFace *f = &mfaces[i];
+                       //if mesh has uv coords writes uv and
+                       //vertex indexes
+                       if (checkTexcoords == true)     {
+                               // if triangle
+                               if (f->v4 == 0) {
+                                       tris.appendValues(f->v1);
+                                       tris.appendValues(texindex++);
+                                       tris.appendValues(f->v2);
+                                       tris.appendValues(texindex++);
+                                       tris.appendValues(f->v3);
+                                       tris.appendValues(texindex++);
+                               }
+                               // quad
+                               else {
+                                       tris.appendValues(f->v1);
+                                       tris.appendValues(texindex++);
+                                       tris.appendValues(f->v2);
+                                       tris.appendValues(texindex++);
+                                       tris.appendValues(f->v3);
+                                       tris.appendValues(texindex++);
+                                       tris.appendValues(f->v3);
+                                       tris.appendValues(texindex++);
+                                       tris.appendValues(f->v4);
+                                       tris.appendValues(texindex++);
+                                       tris.appendValues(f->v1);
+                                       tris.appendValues(texindex++);
+                               }
+                       }
+                       //if mesh has no uv coords writes only 
+                       //vertex indexes
+                       else {
+                               // if triangle
+                               if (f->v4 == 0) {
+                                       tris.appendValues(f->v1, f->v2, f->v3); 
+                               }
+                               // quad
+                               else {
+                                       tris.appendValues(f->v1, f->v2, f->v3);
+                                       tris.appendValues(f->v3, f->v4, f->v1);
+                               }
                                                
-                                       } 
-                               }
+                       } 
+               }
 
-                               tris.closeElement();
-                               tris.finish();
+               tris.closeElement();
+               tris.finish();
                                        
-                               closeMesh();
-                               closeGeometry();
+               closeMesh();
+               closeGeometry();
                                        
-                               dm->release(dm);
+               dm->release(dm);
                                                
-                                  
-                       }
-                       base= base->next;
-               }
-
-               closeLibrary();
        }
-
+       
        //creates <source> for positions
-       void createVertsSource(Scene *sce, COLLADASW::StreamWriter *sw,
-                                         std::string geom_name, DerivedMesh 
*dm)
+       void createVertsSource(std::string geom_name, DerivedMesh *dm)
        {
                int totverts = dm->getNumVerts(dm);
                MVert *verts = dm->getVertArray(dm);
                
                
-               COLLADASW::FloatSourceF source(sw);
+               COLLADASW::FloatSourceF source(mSW);
                source.setId(getIdBySemantics(geom_name, COLLADASW::POSITION));
                source.setArrayId(getIdBySemantics(geom_name, 
COLLADASW::POSITION) +
                                                  ARRAY_ID_SUFFIX);
@@ -228,90 +272,87 @@
 
        //creates <source> for texcoords
        // returns true if mesh has uv data
-       bool createTexcoordsSource(Scene *sce, COLLADASW::StreamWriter *sw,
-                                                          std::string 
geom_name, DerivedMesh *dm, Mesh *me)
+       bool createTexcoordsSource(std::string geom_name, DerivedMesh *dm, Mesh 
*me)
        {
                

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to