[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