[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