[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [21079] branches/soc-2009-chingachgook/ source/blender/collada/DocumentExporter.cpp: COLLADA exporter:
Chingiz Dyussenov
chingiz.ds at gmail.com
Mon Jun 22 18:22:00 CEST 2009
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. @@
More information about the Bf-blender-cvs
mailing list