[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [26630] branches/soc-2009-chingachgook/ source/blender/collada/DocumentExporter.cpp: COLLADA branch: exporter takes face smoothness flag into account.
Arystanbek Dyussenov
arystan.d at gmail.com
Fri Feb 5 18:37:22 CET 2010
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 ¶m = 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;
More information about the Bf-blender-cvs
mailing list