[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [21153] branches/soc-2009-chingachgook/ source/blender/collada/DocumentImporter.cpp: Added very basic geometry import.

Chingiz Dyussenov chingiz.ds at gmail.com
Thu Jun 25 14:13:32 CEST 2009


Revision: 21153
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=21153
Author:   chingachgook
Date:     2009-06-25 14:13:32 +0200 (Thu, 25 Jun 2009)

Log Message:
-----------
Added very basic geometry import. Only <triangles> is supported.
Found a bug in OpenCollada - <polylist> is treated as <polygon>.

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

Modified: branches/soc-2009-chingachgook/source/blender/collada/DocumentImporter.cpp
===================================================================
--- branches/soc-2009-chingachgook/source/blender/collada/DocumentImporter.cpp	2009-06-25 11:57:19 UTC (rev 21152)
+++ branches/soc-2009-chingachgook/source/blender/collada/DocumentImporter.cpp	2009-06-25 12:13:32 UTC (rev 21153)
@@ -13,6 +13,8 @@
 #include "COLLADAFWMesh.h"
 #include "COLLADAFWFloatOrDoubleArray.h"
 #include "COLLADAFWArrayPrimitiveType.h"
+#include "COLLADAFWMeshPrimitiveWithFaceVertexCount.h"
+#include "COLLADAFWPolygons.h"
 
 #include "COLLADASaxFWLLoader.h"
 
@@ -21,6 +23,7 @@
 {
 #include "BKE_main.h"
 #include "BKE_mesh.h"
+#include "BKE_customdata.h"
 #include "BKE_context.h"
 #include "BKE_object.h"
 #include "BKE_image.h"
@@ -28,11 +31,52 @@
 }
 
 #include "DNA_object_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_mesh_types.h"
 
 #include "DocumentImporter.h"
 
 
+const char *primTypeToStr(COLLADAFW::MeshPrimitive::PrimitiveType type)
+{
+	using namespace COLLADAFW;
+	
+	switch (type) {
+	case MeshPrimitive::LINES:
+		return "LINES";
+	case MeshPrimitive::LINE_STRIPS:
+		return "LINESTRIPS";
+	case MeshPrimitive::POLYGONS:
+		return "POLYGONS";
+	case MeshPrimitive::POLYLIST:
+		return "POLYLIST";
+	case MeshPrimitive::TRIANGLES:
+		return "TRIANGLES";
+	case MeshPrimitive::TRIANGLE_FANS:
+		return "TRIANGLE_FANS";
+	case MeshPrimitive::TRIANGLE_STRIPS:
+		return "TRIANGLE_FANS";
+	case MeshPrimitive::POINTS:
+		return "POINTS";
+	case MeshPrimitive::UNDEFINED_PRIMITIVE_TYPE:
+		return "UNDEFINED_PRIMITIVE_TYPE";
+	}
+	return "UNKNOWN";
+}
 
+const char *geomTypeToStr(COLLADAFW::Geometry::GeometryType type)
+{
+	switch (type) {
+	case COLLADAFW::Geometry::GEO_TYPE_MESH:
+		return "MESH";
+	case COLLADAFW::Geometry::GEO_TYPE_SPLINE:
+		return "SPLINE";
+	case COLLADAFW::Geometry::GEO_TYPE_CONVEX_MESH:
+		return "CONVEX_MESH";
+	}
+	return "UNKNOWN";
+}
+
 /** Class that needs to be implemented by a writer. 
 	IMPORTANT: The write functions are called in arbitrary order.*/
 class Writer: public COLLADAFW::IWriter
@@ -80,6 +124,8 @@
 		// XXX report error
 		if (!root.loadDocument(mFilename))
 			return false;
+
+		return true;
 	}
 
 	/** This method will be called if an error in the loading process occurred and the loader cannot
@@ -167,7 +213,7 @@
 
 	/** When this method is called, the writer must write the geometry.
 		@return The writer should return true, if writing succeeded, false otherwise.*/
-	virtual bool writeGeometry ( const COLLADAFW::Geometry* cgeometry ) 
+	virtual bool writeGeometry ( const COLLADAFW::Geometry* cgeom ) 
 	{
 		// - create a mesh object
 		// - enter editmode getting editmesh
@@ -177,13 +223,157 @@
 		// - unlink mesh from object
 		// - remove object
 
+		// - ignore usupported primitive types
+
 		// TODO: import also uvs, normals
+		// XXX what to do with normal indices?
+		// XXX num_normals may be != num verts, then what to do?
 
-
 		// check geometry->getType() first
-		COLLADAFW::Mesh *cmesh = (COLLADAFW::Mesh*)cgeometry;
-		Scene *sce = CTX_data_scene(mContext);
+		if (cgeom->getType() != COLLADAFW::Geometry::GEO_TYPE_MESH) {
+			// TODO: report warning
+			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
+		COLLADAFW::MeshPrimitiveArray& prim_arr = cmesh->getMeshPrimitives();
+
+		int i;
+		
+		for (i = 0; i < prim_arr.getCount(); i++) {
+			
+			COLLADAFW::MeshPrimitive *mp = prim_arr.getData()[i];
+			COLLADAFW::MeshPrimitive::PrimitiveType type = mp->getPrimitiveType();
+
+			const char *type_str = primTypeToStr(type);
+
+			if (type == COLLADAFW::MeshPrimitive::POLYLIST) {
+
+				COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons*)mp;
+				COLLADAFW::Polygons::VertexCountArray& vca = mpvc->getGroupedVerticesVertexCountArray();
+				
+				bool ok = true;
+				for(int j = 0; j < vca.getCount(); j++){
+					int count = vca.getData()[j];
+					if (count != 3 && count != 4) {
+						fprintf(stderr, "%s has at least one face with vertex count > 4 or < 3\n",
+								type_str);
+						return true;
+					}
+				}
+					
+			}
+			else if(type != COLLADAFW::MeshPrimitive::TRIANGLES) {
+				fprintf(stderr, "Primitive type %s is not supported.\n", type_str);
+				return true;
+			}
+		}
+		
+		size_t totvert = cmesh->getPositions().getFloatValues()->getCount() / 3;
+		size_t totnorm = cmesh->getNormals().getFloatValues()->getCount() / 3;
+		
+		if (cmesh->hasNormals() && totnorm != totvert) {
+			fprintf(stderr, "Per-face normals are not supported.\n");
+			return true;
+		}
+		
+		Mesh *me = add_mesh((char*)cgeom->getOriginalId().c_str());
+		
+		// vertices	
+		me->mvert = (MVert*)CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
+		me->totvert = totvert;
+		
+		float *pos_float_array = cmesh->getPositions().getFloatValues()->getData();
+		float *normals_float_array = NULL;
+
+		if (cmesh->hasNormals())
+			normals_float_array = cmesh->getNormals().getFloatValues()->getData();
+		
+		MVert *mvert = me->mvert;
+		i = 0;
+		while (i < totvert) {
+			// fill mvert
+			mvert->co[0] = pos_float_array[0];
+			mvert->co[1] = pos_float_array[1];
+			mvert->co[2] = pos_float_array[2];
+
+			if (normals_float_array) {
+				mvert->no[0] = (short)(32767.0 * normals_float_array[0]);
+				mvert->no[1] = (short)(32767.0 * normals_float_array[1]);
+				mvert->no[2] = (short)(32767.0 * normals_float_array[2]);
+				normals_float_array += 3;
+			}
+			
+			pos_float_array += 3;
+			mvert++;
+			i++;
+		}
+
+		// count totface
+		int totface = 0;
+
+		for (i = 0; i < prim_arr.getCount(); i++) {
+			COLLADAFW::MeshPrimitive *mp = prim_arr.getData()[i];
+			totface += mp->getFaceCount();
+		}
+
+		// allocate faces
+		me->mface = (MFace*)CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, totface);
+		me->totface = totface;
+
+		// read faces
+		MFace *mface = me->mface;
+		for (i = 0; i < prim_arr.getCount(); i++){
+			
+ 			COLLADAFW::MeshPrimitive *mp = prim_arr.getData()[i];
+			
+			// faces
+			size_t prim_totface = mp->getFaceCount();
+			unsigned int *indices = mp->getPositionIndices().getData();
+			int k;
+			int type = mp->getPrimitiveType();
+			
+			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++;
+				}
+			}
+			else if (type == COLLADAFW::MeshPrimitive::POLYLIST) {
+				COLLADAFW::Polygons *mpvc =	(COLLADAFW::Polygons*)mp;
+				COLLADAFW::Polygons::VertexCountArray& vca =
+					mpvc->getGroupedVerticesVertexCountArray();
+				for (k = 0; k < prim_totface; k++) {
+					
+					if (vca.getData()[k] == 3){
+						mface->v1 = indices[0];
+						mface->v2 = indices[1];
+						mface->v3 = indices[2];
+						indices += 3;
+						
+					}
+					else {
+						mface->v1 = indices[0];
+						mface->v2 = indices[1];
+						mface->v3 = indices[2];
+						mface->v4 = indices[3];
+						indices +=4;
+						
+					}
+					mface++;
+				}
+			}
+		}
+		
+		Object *ob = add_object(CTX_data_scene(mContext), OB_MESH);
+		set_mesh(ob, me);
+
 		// XXX: don't use editors module
 
 





More information about the Bf-blender-cvs mailing list