[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