[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