[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [21317] branches/soc-2009-chingachgook/ source/blender/collada: Import per-face materials.

Chingiz Dyussenov chingiz.ds at gmail.com
Thu Jul 2 14:35:46 CEST 2009


Revision: 21317
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=21317
Author:   chingachgook
Date:     2009-07-02 14:35:46 +0200 (Thu, 02 Jul 2009)

Log Message:
-----------
Import per-face materials. 

Modified Paths:
--------------
    branches/soc-2009-chingachgook/source/blender/collada/DocumentExporter.cpp
    branches/soc-2009-chingachgook/source/blender/collada/DocumentImporter.cpp

Modified: branches/soc-2009-chingachgook/source/blender/collada/DocumentExporter.cpp
===================================================================
--- branches/soc-2009-chingachgook/source/blender/collada/DocumentExporter.cpp	2009-07-02 12:11:20 UTC (rev 21316)
+++ branches/soc-2009-chingachgook/source/blender/collada/DocumentExporter.cpp	2009-07-02 12:35:46 UTC (rev 21317)
@@ -281,7 +281,7 @@
 		// 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) {

Modified: branches/soc-2009-chingachgook/source/blender/collada/DocumentImporter.cpp
===================================================================
--- branches/soc-2009-chingachgook/source/blender/collada/DocumentImporter.cpp	2009-07-02 12:11:20 UTC (rev 21316)
+++ branches/soc-2009-chingachgook/source/blender/collada/DocumentImporter.cpp	2009-07-02 12:35:46 UTC (rev 21317)
@@ -101,6 +101,17 @@
 	std::map<COLLADAFW::UniqueId, Mesh*> uid_mesh_map; // geometry unique id-to-mesh map
 	std::map<COLLADAFW::UniqueId, Material*> uid_material_map;
 	std::map<COLLADAFW::UniqueId, Material*> uid_effect_map;
+
+	// this structure is used to assign material indices to faces
+	// when materials are assigned to an object
+	struct Primitive {
+		MFace *mface;
+		int totface;
+	};
+	typedef std::map<COLLADAFW::MaterialId, std::vector<Primitive> > MaterialIdPrimitiveArrayMap;
+	// amazing name!
+	std::map<COLLADAFW::UniqueId, MaterialIdPrimitiveArrayMap> geom_uid_mat_mapping_map;
+
 	class UnitConverter
 	{
 	private:
@@ -249,8 +260,8 @@
 				continue;
 			}
 			
-			const COLLADAFW::UniqueId& uid = geom[0]->getInstanciatedObjectId();
-			if (uid_mesh_map.find(uid) == uid_mesh_map.end()) {
+			const COLLADAFW::UniqueId& geom_uid = geom[0]->getInstanciatedObjectId();
+			if (uid_mesh_map.find(geom_uid) == uid_mesh_map.end()) {
 				// XXX report to user
 				// this could happen if a mesh was not created
 				// (e.g. if it contains unsupported geometry)
@@ -258,7 +269,7 @@
 				continue;
 			}
 			
-			set_mesh(ob, uid_mesh_map[uid]);
+			set_mesh(ob, uid_mesh_map[geom_uid]);
 			
 			float rot[3][3];
 			Mat3One(rot);
@@ -316,15 +327,42 @@
 				}
 			}
 			Mat3ToEul(rot, ob->rot);
-			
+
+			// assign materials to object
+			// assign material indices to mesh faces
 			for (k = 0; k < geom[0]->getMaterialBindings().getCount(); k++) {
-				const COLLADAFW::UniqueId& mat_uid = geom[0]->getMaterialBindings()[k].getReferencedMaterial();
+				
+				const COLLADAFW::UniqueId& mat_uid =
+					geom[0]->getMaterialBindings()[k].getReferencedMaterial();
+
 				if (uid_material_map.find(mat_uid) == uid_material_map.end()) {
 					// This should not happen
-					fprintf(stderr, "This mesh has no materials.\n");
+					fprintf(stderr, "Cannot find material by UID.\n");
 					continue;
 				}
+
 				assign_material(ob, uid_material_map[mat_uid], ob->totcol + 1);
+
+				MaterialIdPrimitiveArrayMap& mat_prim_map = geom_uid_mat_mapping_map[geom_uid];
+				COLLADAFW::MaterialId mat_id = geom[0]->getMaterialBindings()[k].getMaterialId();
+				
+				// if there's geometry that uses this material,
+				// set mface->mat_nr=k for each face in that geometry
+				if (mat_prim_map.find(mat_id) != mat_prim_map.end()) {
+
+					std::vector<Primitive>& prims = mat_prim_map[mat_id];
+
+					std::vector<Primitive>::iterator it;
+
+					for (it = prims.begin(); it != prims.end(); it++) {
+						Primitive& prim = *it;
+
+						int l = 0;
+						while (l++ < prim.totface) {
+							prim.mface->mat_nr = k;
+						}
+					}
+				}
 			}
 		}
 		
@@ -360,7 +398,7 @@
 			fprintf(stderr, "Mesh type %s is not supported\n", geomTypeToStr(cgeom->getType()));
 			return true;
 		}
-
+		
 		COLLADAFW::Mesh *cmesh = (COLLADAFW::Mesh*)cgeom;
 		
 		// first check if we can import this mesh
@@ -451,6 +489,9 @@
 
 		// read faces
 		MFace *mface = me->mface;
+
+		MaterialIdPrimitiveArrayMap mat_prim_map;
+		
 		for (i = 0; i < prim_arr.getCount(); i++){
 			
  			COLLADAFW::MeshPrimitive *mp = prim_arr[i];
@@ -460,14 +501,20 @@
 			unsigned int *indices = mp->getPositionIndices().getData();
 			int k;
 			int type = mp->getPrimitiveType();
+
+			// since we cannot set mface->mat_nr here, we store part of me->mface in Primitive
+			Primitive prim = {mface, 0};
 			
 			if (type == COLLADAFW::MeshPrimitive::TRIANGLES) {
 				for (k = 0; k < prim_totface; k++){
 					mface->v1 = indices[0];
 					mface->v2 = indices[1];
 					mface->v3 = indices[2];
+					
 					indices += 3;
 					mface++;
+					
+					prim.totface++;
 				}
 			}
 			else if (type == COLLADAFW::MeshPrimitive::POLYLIST || type == COLLADAFW::MeshPrimitive::POLYGONS) {
@@ -492,10 +539,60 @@
 						
 					}
 					mface++;
+
+					prim.totface++;
 				}
 			}
+			// XXX primitive could have no materials
+			// check if primitive has material
+			mat_prim_map[mp->getMaterialId()].push_back(prim);
 		}
+
+		geom_uid_mat_mapping_map[cgeom->getUniqueId()] = mat_prim_map;
+
+		/*
+		// UVs
+		MeshVertexData& uvcoord = cmesh->getUVCoords();
 		
+		// get number of UV sets
+		int totuvset = uvcoord.getNumInputInfos();
+		
+		// for each uv set 
+		for (i = 0; i < totuvset; i++) {
+			
+			std::string uv_name = uvcoord.getName(i);
+			me->mtface = CustomData_add_layer_named(&me->fdata, CD_MTFACE, CD_DEFAULT, NULL, me->totface, uv_name);
+			
+			size_t stride = uvcoord.getStride(i);
+			size_t totindex = uvcoord.getLength(i);
+			size_t totuv = (totindex/stride);
+			size_t start = i * stride;
+			
+			// for each uv coord in this set 
+			for (int j = start; j < totindex; j += stride) {
+				
+				switch(uvcoord.getType()) {
+				case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT:
+					COLLADAFW::ArrayPrimitiveType<float>* values = uvcoord.getFloatValues();
+					
+					float u = (*values)[j];
+					float v = (*values)[j + 1];
+					
+					break;
+				case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE:
+					COLLADAFW::ArrayPrimitiveType<double>* values = uvcoord.getDoubleValues();
+					
+					float u = (float)(*values)[j];
+					float v = (float)(*values)[j + 1];
+					
+					break;
+				}
+				
+			}
+		}
+		*/
+		
+		// normals
 		mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
 		return true;
 	}





More information about the Bf-blender-cvs mailing list