Revision: 26630
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=26630
Author:   kazanbas
Date:     2010-02-05 18:36:41 +0100 (Fri, 05 Feb 2010)

Log Message:
-----------
COLLADA branch: exporter takes face smoothness flag into account.

Previously only smooth normals were written for each mesh. Now proper normals 
are written for flat faces too. Since smooth faces may share normals, writing 
of duplicate normals is avoided.

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  
2010-02-05 15:55:45 UTC (rev 26629)
+++ branches/soc-2009-chingachgook/source/blender/collada/DocumentExporter.cpp  
2010-02-05 17:36:41 UTC (rev 26630)
@@ -322,7 +322,18 @@
 // TODO: optimize UV sets by making indexed list with duplicates removed
 class GeometryExporter : COLLADASW::LibraryGeometries
 {
+       struct Face
+       {
+               unsigned int v1, v2, v3, v4;
+       };
+
+       struct Normal
+       {
+               float x, y, z;
+       };
+
        Scene *mScene;
+
 public:
        GeometryExporter(COLLADASW::StreamWriter *sw) : 
COLLADASW::LibraryGeometries(sw) {}
 
@@ -345,7 +356,11 @@
 #endif
                Mesh *me = (Mesh*)ob->data;
                std::string geom_id = get_geometry_id(ob);
-               
+               std::vector<Normal> nor;
+               std::vector<Face> norind;
+
+               create_normals(nor, norind, me);
+
                // openMesh(geoId, geoName, meshId)
                openMesh(geom_id);
                
@@ -353,7 +368,7 @@
                createVertsSource(geom_id, me);
                
                // writes <source> for normal coords
-               createNormalsSource(geom_id, me);
+               createNormalsSource(geom_id, me, nor);
 
                int has_uvs = CustomData_has_layer(&me->fdata, CD_MTFACE);
                
@@ -374,11 +389,11 @@
                        for(int a = 0; a < ob->totcol; a++)     {
                                // account for NULL materials, this should not 
normally happen?
                                Material *ma = give_current_material(ob, a + 1);
-                               createPolylist(ma != NULL, a, has_uvs, ob, 
geom_id);
+                               createPolylist(ma != NULL, a, has_uvs, ob, 
geom_id, norind);
                        }
                }
                else {
-                       createPolylist(false, 0, has_uvs, ob, geom_id);
+                       createPolylist(false, 0, has_uvs, ob, geom_id, norind);
                }
                
                closeMesh();
@@ -394,7 +409,8 @@
                                                int material_index,
                                                bool has_uvs,
                                                Object *ob,
-                                               std::string& geom_id)
+                                               std::string& geom_id,
+                                               std::vector<Face>& norind)
        {
 #if 0
                MFace *mfaces = dm->getFaceArray(dm);
@@ -443,12 +459,10 @@
                COLLADASW::InputList &til = polylist.getInputList();
                        
                // creates <input> in <polylist> for vertices 
-               COLLADASW::Input input1(COLLADASW::VERTEX, getUrlBySemantics
-                                                               (geom_id, 
COLLADASW::VERTEX), 0);
+               COLLADASW::Input input1(COLLADASW::VERTEX, 
getUrlBySemantics(geom_id, COLLADASW::VERTEX), 0);
                        
                // creates <input> in <polylist> for normals
-               COLLADASW::Input input2(COLLADASW::NORMAL, getUrlBySemantics
-                                                               (geom_id, 
COLLADASW::NORMAL), 0);
+               COLLADASW::Input input2(COLLADASW::NORMAL, 
getUrlBySemantics(geom_id, COLLADASW::NORMAL), 1);
                        
                til.push_back(input1);
                til.push_back(input2);
@@ -460,7 +474,7 @@
                        char *name = CustomData_get_layer_name(&me->fdata, 
CD_MTFACE, i);
                        COLLADASW::Input input3(COLLADASW::TEXCOORD,
                                                                        
makeUrl(makeTexcoordSourceId(geom_id, i)),
-                                                                       1, // 
offset always 1, this is only until we have optimized UV sets
+                                                                       2, // 
offset always 2, this is only until we have optimized UV sets
                                                                        i  // 
set number equals UV layer index
                                                                        );
                        til.push_back(input3);
@@ -480,8 +494,10 @@
                        if ((has_material && f->mat_nr == material_index) || 
!has_material) {
 
                                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 (has_uvs)
                                                polylist.appendValues(texindex 
+ j);
@@ -596,21 +612,18 @@
 
 
        //creates <source> for normals
-       void createNormalsSource(std::string geom_id, Mesh *me)
+       void createNormalsSource(std::string geom_id, Mesh *me, 
std::vector<Normal>& nor)
        {
 #if 0
                int totverts = dm->getNumVerts(dm);
                MVert *verts = dm->getVertArray(dm);
 #endif
 
-               int totverts = me->totvert;
-               MVert *verts = me->mvert;
-
                COLLADASW::FloatSourceF source(mSW);
                source.setId(getIdBySemantics(geom_id, COLLADASW::NORMAL));
                source.setArrayId(getIdBySemantics(geom_id, COLLADASW::NORMAL) +
                                                  ARRAY_ID_SUFFIX);
-               source.setAccessorCount(totverts);
+               source.setAccessorCount(nor.size());
                source.setAccessorStride(3);
                COLLADASW::SourceBase::ParameterNameList &param = 
source.getParameterNameList();
                param.push_back("X");
@@ -618,18 +631,65 @@
                param.push_back("Z");
                
                source.prepareToAppendValues();
-               
-               int i = 0;
-               
-               for( i = 0; i < totverts; ++i ){
-                       
-                       source.appendValues(float(verts[i].no[0]/32767.0),
-                                                               
float(verts[i].no[1]/32767.0),
-                                                               
float(verts[i].no[2]/32767.0));
-                               
+
+               std::vector<Normal>::iterator it;
+               for (it = nor.begin(); it != nor.end(); it++) {
+                       Normal& n = *it;
+                       source.appendValues(n.x, n.y, n.z);
                }
+
                source.finish();
        }
+
+       void create_normals(std::vector<Normal> &nor, std::vector<Face> &ind, 
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;
+                       Normal n;
+                       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)) {
+                               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);
+                       }
+
+                       for (j = 0; j < v; j++) {
+                               if (fa->flag & ME_SMOOTH) {
+                                       if (nshar.find(*vv) != nshar.end())
+                                               *nn = nshar[*vv];
+                                       else {
+                                               Normal n = {
+                                                       vert[*vv].no[0]/32767.0,
+                                                       vert[*vv].no[1]/32767.0,
+                                                       vert[*vv].no[2]/32767.0
+                                               };
+                                               nor.push_back(n);
+                                               *nn = nor.size() - 1;
+                                               nshar[*vv] = *nn;
+                                       }
+                                       vv++;
+                               }
+                               else {
+                                       nor.push_back(n);
+                                       *nn = nor.size() - 1;
+                               }
+                               nn++;
+                       }
+
+                       ind.push_back(f);
+               }
+       }
        
        std::string getIdBySemantics(std::string geom_id, COLLADASW::Semantics 
type, std::string other_suffix = "") {
                return geom_id + getSuffixBySemantic(type) + other_suffix;


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

Reply via email to