[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [21235] branches/soc-2009-chingachgook/ source/blender/collada/DocumentExporter.cpp: Added multiple UV layers export.

Chingiz Dyussenov chingiz.ds at gmail.com
Mon Jun 29 14:53:49 CEST 2009


Revision: 21235
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=21235
Author:   chingachgook
Date:     2009-06-29 14:53:49 +0200 (Mon, 29 Jun 2009)

Log Message:
-----------
Added multiple UV layers export.
Next: texture/UV binding.

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-29 12:06:46 UTC (rev 21234)
+++ branches/soc-2009-chingachgook/source/blender/collada/DocumentExporter.cpp	2009-06-29 12:53:49 UTC (rev 21235)
@@ -71,6 +71,14 @@
 	}
 }
 
+char *CustomData_get_layer_name(const struct CustomData *data, int type, int n)
+{
+	int layer_index = CustomData_get_layer_index(data, type);
+	if(layer_index < 0) return NULL;
+
+	return data->layers[layer_index+n].name;
+}
+
 /*
   Utilities to avoid code duplication.
   Definition can take some time to understand, but they should be useful.
@@ -126,6 +134,7 @@
 	forEachMeshObjectInScene(sce, matfunc);
 }
 
+// TODO: optimize UV sets by making indexed list with duplicates removed
 class GeometryExporter : COLLADASW::LibraryGeometries
 {
 	Scene *mScene;
@@ -147,12 +156,7 @@
 		// XXX don't use DerivedMesh, Mesh instead?
 		
 		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;
-
+		Mesh *me = (Mesh*)ob->data;
 		std::string geom_name(ob->id.name);
 
 		// openMesh(geoId, geoName, meshId)
@@ -163,10 +167,13 @@
 		
 		// writes <source> for normal coords
 		createNormalsSource(geom_name, dm);
+
+		int has_uvs = CustomData_has_layer(&me->fdata, CD_MTFACE);
 		
 		// writes <source> for uv coords if mesh has uv coords
-		checkTexcoords = createTexcoordsSource(geom_name, dm, (Mesh*)ob->data);
-		
+		if (has_uvs) {
+			createTexcoordsSource(geom_name, dm, (Mesh*)ob->data);
+		}
 		// <vertices>
 		COLLADASW::Vertices verts(mSW);
 		verts.setId(getIdBySemantics(geom_name, COLLADASW::VERTEX));
@@ -175,216 +182,124 @@
 							   getUrlBySemantics(geom_name, COLLADASW::POSITION));
 		input_list.push_back(input);
 		verts.add();
-		
-		// if mesh has per-face materials
-		for(int a = 0; a < ob->totcol; a++)	{
-			// <vcount>
-			int i;
-			int faces_in_polylist = 0;
-			std::vector<unsigned long> VCountList;
-			
-			for (i = 0; i < totfaces; i++) {
-				MFace *f = &mfaces[i];
-				if (f->mat_nr == a) {
-					faces_in_polylist += 1;
-					if (f->v4 == 0) {
-						VCountList.push_back(3);
-					}
-					else {
-						VCountList.push_back(4);
-					}
-				}
+
+		// XXX slow		
+		if (ob->totcol) {
+			for(int a = 0; a < ob->totcol; a++)	{
+				createPolylist(true, a, has_uvs, ob, dm, geom_name);
 			}
-			
-			if (faces_in_polylist == 0) {
-				continue;
-			}
-			
-			Material *ma = give_current_material(ob, a+1);
-			COLLADASW::Polylist polylist(mSW);
-			
-			// sets count attribute in <polylist>
-			polylist.setCount(faces_in_polylist);
-			
-			// sets material name
-			polylist.setMaterial(ma->id.name);
-				
-			COLLADASW::InputList &til = polylist.getInputList();
-			
-			// creates <input> in <polylist> for vertices 
-			COLLADASW::Input input1(COLLADASW::VERTEX, getUrlBySemantics
-									(geom_name, COLLADASW::VERTEX), 0);
-			
-			// creates <input> in <polylist> for normals
-			COLLADASW::Input input2(COLLADASW::NORMAL, getUrlBySemantics
-									(geom_name, COLLADASW::NORMAL), 0);
-			
-			til.push_back(input1);
-			til.push_back(input2);
-			
-			// if mesh has uv coords writes <input> for TEXCOORD
-			if (checkTexcoords == true)
-				{
-					COLLADASW::Input input3(COLLADASW::TEXCOORD,
-											getUrlBySemantics(geom_name, COLLADASW::TEXCOORD), 1, 0);
-					til.push_back(input3);
-				}
-			
-			// sets <vcount>
-			polylist.setVCountList(VCountList);
-			
-			// performs the actual writing
-			polylist.prepareToAppendValues();
-			
-			// <p>
-			int texindex = 0;
-			for (i = 0; i < totfaces; i++) {
-				MFace *f = &mfaces[i];
-				
-				// if mesh has uv coords writes uv and vertex indices
-				if (checkTexcoords == true && f->mat_nr == a)	{
-					// if triangle
-					if (f->v4 == 0) {
-						polylist.appendValues(f->v1);
-						polylist.appendValues(texindex++);
-						polylist.appendValues(f->v2);
-						polylist.appendValues(texindex++);
-						polylist.appendValues(f->v3);
-						polylist.appendValues(texindex++);
-					}
-					// quad
-					else {
-						polylist.appendValues(f->v1);
-						polylist.appendValues(texindex++);
-						polylist.appendValues(f->v2);
-						polylist.appendValues(texindex++);
-						polylist.appendValues(f->v3);
-						polylist.appendValues(texindex++);
-						polylist.appendValues(f->v4);
-						polylist.appendValues(texindex++);
-					}
-				}
-				// if mesh has no uv coords writes only vertex indices
-				else if(f->mat_nr == a){
-					// if triangle
-					if (f->v4 == 0) {
-						polylist.appendValues(f->v1, f->v2, f->v3);	
-					}
-					// quad
-					else {
-						polylist.appendValues(f->v1, f->v2, f->v3, f->v4);
-					}
-				}
-				
-				else if(f->mat_nr != a) {
-					if (f->v4 == 0) {
-						texindex += 3;
-					}
-					else {
-						texindex += 4;
-					}
-				}
-			}
-			
-			polylist.finish();
 		}
+		else {
+			createPolylist(false, 0, has_uvs, ob, dm, geom_name);
+		}
 		
-		// writes <polylist> if mesh has no materials
-		if (ob->totcol == 0) {
-			// <vcount>
-			int i;
-			std::vector<unsigned long> VCountList;
-			for (i = 0; i < totfaces; i++) {
-				MFace *f = &mfaces[i];
+		closeMesh();
+		closeGeometry();
+		
+		dm->release(dm);
+		
+	}
+
+	// powerful because it handles both cases when there is material and when there's not
+	void createPolylist(bool has_material,
+						int material_index,
+						bool has_uvs,
+						Object *ob,
+						DerivedMesh *dm,
+						std::string& geom_name)
+	{
+		MFace *mfaces = dm->getFaceArray(dm);
+		int totfaces = dm->getNumFaces(dm);
+		Mesh *me = (Mesh*)ob->data;
+
+		// <vcount>
+		int i;
+		int faces_in_polylist = 0;
+		std::vector<unsigned long> vcount_list;
+
+		// count faces with this material
+		for (i = 0; i < totfaces; i++) {
+			MFace *f = &mfaces[i];
+
+			if ((has_material && f->mat_nr == material_index) || !has_material) {
+				faces_in_polylist++;
 				if (f->v4 == 0) {
-					VCountList.push_back(3);
+					vcount_list.push_back(3);
 				}
 				else {
-					VCountList.push_back(4);
+					vcount_list.push_back(4);
 				}
 			}
+		}
+
+		// no faces using this material
+		if (faces_in_polylist == 0) {
+			return;
+		}
 			
+		Material *ma = has_material ? give_current_material(ob, material_index + 1) : NULL;
+		COLLADASW::Polylist polylist(mSW);
 			
-			COLLADASW::Polylist polylist(mSW);
+		// sets count attribute in <polylist>
+		polylist.setCount(faces_in_polylist);
 			
-			// sets count attribute in <polylist>
-			polylist.setCount(totfaces);
+		// sets material name
+		if (has_material)
+			polylist.setMaterial(ma->id.name);
+				
+		COLLADASW::InputList &til = polylist.getInputList();
 			
-			COLLADASW::InputList &til = polylist.getInputList();
+		// creates <input> in <polylist> for vertices 
+		COLLADASW::Input input1(COLLADASW::VERTEX, getUrlBySemantics
+								(geom_name, COLLADASW::VERTEX), 0);
 			
-			// creates <input> in <polylist> for vertices 
-			COLLADASW::Input input1(COLLADASW::VERTEX, getUrlBySemantics
-									(geom_name, COLLADASW::VERTEX), 0);
-			// creates <input> in <polylist> for normals
-			COLLADASW::Input input2(COLLADASW::NORMAL, getUrlBySemantics
-									(geom_name, COLLADASW::NORMAL), 0);
+		// creates <input> in <polylist> for normals
+		COLLADASW::Input input2(COLLADASW::NORMAL, getUrlBySemantics
+								(geom_name, COLLADASW::NORMAL), 0);
 			
-			til.push_back(input1);
-			til.push_back(input2);
+		til.push_back(input1);
+		til.push_back(input2);
 			
-			// if mesh has uv coords writes <input> for TEXCOORD
-			if (checkTexcoords == true)
-				{
-					COLLADASW::Input input3(COLLADASW::TEXCOORD,
-											getUrlBySemantics(geom_name, COLLADASW::TEXCOORD), 1, 0);
-					til.push_back(input3);
-				}
-			// <vcount>
-			polylist.setVCountList(VCountList);
+		// if mesh has uv coords writes <input> for TEXCOORD
+		int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
+
+		for (i = 0; i < num_layers; i++) {
+			char *name = CustomData_get_layer_name(&me->fdata, CD_MTFACE, i);
+			COLLADASW::Input input3(COLLADASW::TEXCOORD,
+									makeUrl(makeTexcoordSourceId(geom_name, i)),
+									1, // offset always 1, this is only until we have optimized UV sets
+									0);
+			til.push_back(input3);
+		}
 			
-			// performs the actual writing
-			polylist.prepareToAppendValues();
+		// sets <vcount>
+		polylist.setVCountList(vcount_list);
 			
-			// <p>
-			int texindex = 0;
-			for (i = 0; i < totfaces; i++) {
-				MFace *f = &mfaces[i];
-				
-				//if mesh has uv coords writes uv and vertex indices
-				if (checkTexcoords == true)	{
-					// if triangle
-					if (f->v4 == 0) {
-						polylist.appendValues(f->v1);
-						polylist.appendValues(texindex++);
-						polylist.appendValues(f->v2);
-						polylist.appendValues(texindex++);
-						polylist.appendValues(f->v3);
-						polylist.appendValues(texindex++);
-					}
-					// quad
-					else {
-						polylist.appendValues(f->v1);
-						polylist.appendValues(texindex++);
-						polylist.appendValues(f->v2);
-						polylist.appendValues(texindex++);
-						polylist.appendValues(f->v3);
-						polylist.appendValues(texindex++);
-						polylist.appendValues(f->v4);
-						polylist.appendValues(texindex++);
-					}
+		// performs the actual writing
+		polylist.prepareToAppendValues();
+			
+		// <p>
+		int texindex = 0;
+		for (i = 0; i < totfaces; i++) {
+			MFace *f = &mfaces[i];
+
+			if ((has_material && f->mat_nr == material_index) || !has_material) {
+
+				unsigned int *v = &f->v1;
+				for (int j = 0; j < (f->v4 == 0 ? 3 : 4); j++) {
+					polylist.appendValues(v[j]);
+
+					if (has_uvs)
+						polylist.appendValues(texindex + j);
 				}
-				
-				// if mesh has no uv coords writes only vertex indices 
-				else {
-					// if triangle
-					if (f->v4 == 0) {
-						polylist.appendValues(f->v1, f->v2, f->v3);	
-					}
-					// quad
-					else {
-						polylist.appendValues(f->v1, f->v2, f->v3, f->v4);
-					}
-				}
 			}
-			polylist.finish();
-			
+
+			texindex += 3;
+			if (f->v4 != 0)
+				texindex++;
 		}
-		
-		closeMesh();
-		closeGeometry();
-		
-		dm->release(dm);
-		
+			
+		polylist.finish();
 	}
 	
 	// creates <source> for positions
@@ -413,99 +328,70 @@
 			source.appendValues(verts[i].co[0], verts[i].co[1], verts[i].co[2]);
 			
 		}

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list