Commit: 8bdac4d0bc21143bafbdbb9b45ab521dfedfa369
Author: gaiaclary
Date:   Thu May 1 14:52:10 2014 +0200
https://developer.blender.org/rB8bdac4d0bc21143bafbdbb9b45ab521dfedfa369

fix T39967: Added support for Import/export of vertex color layers

===================================================================

M       source/blender/collada/GeometryExporter.cpp
M       source/blender/collada/GeometryExporter.h
M       source/blender/collada/MeshImporter.cpp
M       source/blender/collada/MeshImporter.h

===================================================================

diff --git a/source/blender/collada/GeometryExporter.cpp 
b/source/blender/collada/GeometryExporter.cpp
index 3d5d79f..d54fc71 100644
--- a/source/blender/collada/GeometryExporter.cpp
+++ b/source/blender/collada/GeometryExporter.cpp
@@ -289,6 +289,12 @@ void GeometryExporter::createLooseEdgeList(Object *ob,
 
 }
 
+std::string GeometryExporter::makeVertexColorSourceId(std::string& geom_id, 
char *layer_name)
+{
+       std::string result = getIdBySemantics(geom_id, 
COLLADASW::InputSemantic::COLOR) + "-" + layer_name;
+       return result;
+}
+
 // powerful because it handles both cases when there is material and when 
there's not
 void GeometryExporter::createPolylist(short material_index,
                                       bool has_uvs,
@@ -365,9 +371,20 @@ void GeometryExporter::createPolylist(short material_index,
                }
        }
 
-       if (has_color) {
-               COLLADASW::Input input4(COLLADASW::InputSemantic::COLOR, 
getUrlBySemantics(geom_id, COLLADASW::InputSemantic::COLOR), has_uvs ? 3 : 2);
-               til.push_back(input4);
+       int totlayer_mcol = CustomData_number_of_layers(&me->ldata, 
CD_MLOOPCOL);
+       if (totlayer_mcol > 0) {
+               int map_index = 0;
+
+               for (int a = 0; a < totlayer_mcol; a++) {
+                       char *layer_name = 
bc_CustomData_get_layer_name(&me->ldata, CD_MLOOPCOL, a);
+                       COLLADASW::Input input4(COLLADASW::InputSemantic::COLOR,
+                                               
makeUrl(makeVertexColorSourceId(geom_id, layer_name)),
+                                               (has_uvs) ? 3 : 2,  // all 
color layers have same index order
+                                               map_index           // set 
number equals color map index
+                                               );
+                       til.push_back(input4);
+                       map_index++;
+               }
        }
                
        // sets <vcount>
@@ -420,6 +437,7 @@ void GeometryExporter::createVertsSource(std::string 
geom_id, Mesh *me)
                          ARRAY_ID_SUFFIX);
        source.setAccessorCount(totverts);
        source.setAccessorStride(3);
+
        COLLADASW::SourceBase::ParameterNameList &param = 
source.getParameterNameList();
        param.push_back("X");
        param.push_back("Y");
@@ -437,40 +455,56 @@ void GeometryExporter::createVertsSource(std::string 
geom_id, Mesh *me)
 
 }
 
+
 void GeometryExporter::createVertexColorSource(std::string geom_id, Mesh *me)
 {
-       MLoopCol *mloopcol = (MLoopCol *)CustomData_get_layer(&me->ldata, 
CD_MLOOPCOL);
-       if (mloopcol == NULL)
+       /* Find number of vertex color layers */
+       int totlayer_mcol = CustomData_number_of_layers(&me->ldata, 
CD_MLOOPCOL);
+       if (totlayer_mcol == 0)
                return;
 
+       int active_vcolor_index = CustomData_get_active_layer_index(&me->ldata, 
CD_MLOOPCOL);
 
-       COLLADASW::FloatSourceF source(mSW);
-       source.setId(getIdBySemantics(geom_id, 
COLLADASW::InputSemantic::COLOR));
-       source.setArrayId(getIdBySemantics(geom_id, 
COLLADASW::InputSemantic::COLOR) + ARRAY_ID_SUFFIX);
-       source.setAccessorCount(me->totloop);
-       source.setAccessorStride(3);
+       int map_index = 0;
+       for (int a = 0; a < totlayer_mcol; a++) {
 
-       COLLADASW::SourceBase::ParameterNameList &param = 
source.getParameterNameList();
-       param.push_back("R");
-       param.push_back("G");
-       param.push_back("B");
+               map_index++;
+               MLoopCol *mloopcol = (MLoopCol 
*)CustomData_get_layer_n(&me->ldata, CD_MLOOPCOL, a);
 
-       source.prepareToAppendValues();
+               COLLADASW::FloatSourceF source(mSW);
 
-       MPoly *mpoly;
-       int i;
-       for (i = 0, mpoly = me->mpoly; i < me->totpoly; i++, mpoly++) {
-               MLoopCol *mlc = mloopcol + mpoly->loopstart;
-               for (int j = 0; j < mpoly->totloop; j++, mlc++) {
-                       source.appendValues(
-                                       mlc->r / 255.0f,
-                                       mlc->g / 255.0f,
-                                       mlc->b / 255.0f
-                       );
+               char *layer_name = bc_CustomData_get_layer_name(&me->ldata, 
CD_MLOOPCOL, a);
+               std::string layer_id = makeVertexColorSourceId(geom_id, 
layer_name);
+               source.setId(layer_id);
+
+               source.setNodeName(layer_name);
+
+               source.setArrayId(layer_id + ARRAY_ID_SUFFIX);
+               source.setAccessorCount(me->totloop);
+               source.setAccessorStride(3);
+
+               COLLADASW::SourceBase::ParameterNameList &param = 
source.getParameterNameList();
+               param.push_back("R");
+               param.push_back("G");
+               param.push_back("B");
+
+               source.prepareToAppendValues();
+
+               MPoly *mpoly;
+               int i;
+               for (i = 0, mpoly = me->mpoly; i < me->totpoly; i++, mpoly++) {
+                       MLoopCol *mlc = mloopcol + mpoly->loopstart;
+                       for (int j = 0; j < mpoly->totloop; j++, mlc++) {
+                               source.appendValues(
+                                               mlc->r / 255.0f,
+                                               mlc->g / 255.0f,
+                                               mlc->b / 255.0f
+                               );
+                       }
                }
-       }
        
-       source.finish();
+               source.finish();
+       }
 }
 
 
diff --git a/source/blender/collada/GeometryExporter.h 
b/source/blender/collada/GeometryExporter.h
index 5b67f80..4d54e79 100644
--- a/source/blender/collada/GeometryExporter.h
+++ b/source/blender/collada/GeometryExporter.h
@@ -100,7 +100,8 @@ public:
        void create_normals(std::vector<Normal> &nor, 
std::vector<BCPolygonNormalsIndices> &ind, Mesh *me);
        
        std::string getIdBySemantics(std::string geom_id, 
COLLADASW::InputSemantic::Semantics type, std::string other_suffix = "");
-       
+       std::string makeVertexColorSourceId(std::string& geom_id, char 
*layer_name);
+
        COLLADASW::URI getUrlBySemantics(std::string geom_id, 
COLLADASW::InputSemantic::Semantics type, std::string other_suffix = "");
 
        COLLADASW::URI makeUrl(std::string id);
diff --git a/source/blender/collada/MeshImporter.cpp 
b/source/blender/collada/MeshImporter.cpp
index d631a43..8840e11 100644
--- a/source/blender/collada/MeshImporter.cpp
+++ b/source/blender/collada/MeshImporter.cpp
@@ -173,6 +173,42 @@ void UVDataWrapper::getUV(int uv_index, float *uv)
        }
 }
 
+VCOLDataWrapper::VCOLDataWrapper(COLLADAFW::MeshVertexData& vdata) : 
mVData(&vdata){
+}
+
+void VCOLDataWrapper::get_vcol(int v_index, MLoopCol *mloopcol)
+{
+       int stride = mVData->getStride(0);
+       if(stride == 0) stride =3;
+
+       switch (mVData->getType()) {
+               case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT:
+               {
+                       COLLADAFW::ArrayPrimitiveType<float> *values = 
mVData->getFloatValues();
+                       if (values->empty()) return;
+
+                       mloopcol->r = FTOCHAR((*values)[v_index * stride]);
+                       mloopcol->g = FTOCHAR((*values)[v_index * stride + 1]);
+                       mloopcol->b = FTOCHAR((*values)[v_index * stride + 2]);
+               }
+               break;
+
+               case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE:
+               {
+                       COLLADAFW::ArrayPrimitiveType<double> *values = 
mVData->getDoubleValues();
+                       if (values->empty()) return;
+
+                       mloopcol->r = FTOCHAR((*values)[v_index * stride]);
+                       mloopcol->g = FTOCHAR((*values)[v_index * stride + 1]);
+                       mloopcol->b = FTOCHAR((*values)[v_index * stride + 2]);
+               }
+               break;
+               default:
+                       fprintf(stderr, "VCOLDataWrapper.getvcol(): unknown 
data type\n");
+       }
+
+}
+
 MeshImporter::MeshImporter(UnitConverter *unitconv, ArmatureImporter *arm, 
Scene *sce) : unitconverter(unitconv), scene(sce), armature_importer(arm) {
 }
 
@@ -187,6 +223,17 @@ void MeshImporter::set_poly_indices(MPoly *mpoly, MLoop 
*mloop, int loop_index,
        }
 }
 
+void MeshImporter::set_vcol(MLoopCol *mlc, VCOLDataWrapper &vob, int 
loop_index, COLLADAFW::IndexList &index_list, int count)
+{
+       COLLADAFW::UIntValuesArray& indices =index_list.getIndices();
+       int index;
+       for(index = 0; index < count; index++,mlc++)
+       {
+               int v_index = indices[index+loop_index];
+               vob.get_vcol(v_index,mlc);
+       }
+}
+
 void MeshImporter::set_face_uv(MLoopUV *mloopuv, UVDataWrapper &uvs,
                                int start_index, COLLADAFW::IndexList& 
index_list, int count)
 {
@@ -328,6 +375,17 @@ bool 
MeshImporter::primitive_has_faces(COLLADAFW::MeshPrimitive *mp) {
        return has_faces;
 }
 
+
+static std::string extract_vcolname(const COLLADAFW::String &collada_id) {
+       std::string colname =  collada_id;
+       int spos = colname.find("-mesh-colors-");
+       if (spos != std::string::npos) {
+               colname = colname.substr(spos+13);
+       }
+       return colname;
+}
+
+
 // =================================================================
 // Return the number of faces by summing up
 // the facecounts of the parts.
@@ -337,8 +395,9 @@ bool 
MeshImporter::primitive_has_faces(COLLADAFW::MeshPrimitive *mp) {
 void MeshImporter::allocate_poly_data(COLLADAFW::Mesh *collada_mesh, Mesh *me)
 {
        COLLADAFW::MeshPrimitiveArray& prim_arr = 
collada_mesh->getMeshPrimitives();
-       int total_poly_count = 0;
-       int total_loop_count = 0;
+       int total_poly_count  = 0;
+       int total_loop_count  = 0;
+       int total_color_count = 0;
 
        // collect edge_count and face_count from all parts
        for (int i = 0; i < prim_arr.getCount(); i++) {
@@ -360,6 +419,7 @@ void MeshImporter::allocate_poly_data(COLLADAFW::Mesh 
*collada_mesh, Mesh *me)
 
                                total_poly_count += prim_poly_count;
                                total_loop_count += prim_loop_count;
+
                                break;
                        }
                        default:
@@ -394,6 +454,17 @@ void MeshImporter::allocate_poly_data(COLLADAFW::Mesh 
*collada_mesh, Mesh *me)
                        me->mtpoly  = (MTexPoly 
*)CustomData_get_layer_n(&me->pdata, CD_MTEXPOLY, 0);
                        me->mloopuv = (MLoopUV *) 
CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, 0);
                }
+
+               int totcolset = 
collada_mesh->getColors().getInputInfosArray().getCount();
+               if (totcolset > 0) {
+                       for (int i = 0; i < totcolset; i++) {
+                               COLLADAFW::MeshVertexData::InputInfos *info = 
collada_mesh->getColors().getInputInfosArray()[i];
+                               COLLADAFW::String colname = 
extract_vcolname(info->mName);
+                               
CustomData_add_layer_named(&me->ldata,CD_MLOOPCOL,CD_DEFAULT,NULL,me->totloop, 
colname.c_str());
+                       }
+                       me->mloopcol = (MLoopCol *) 
CustomData_get_layer_n(&me->ldata, CD_MLOOPCOL, 0);
+               }
+
        }
 }
 
@@ -538,6 +609,7 @@ void MeshImporter::read_polys(COLLADAFW::Mesh 
*collada_mesh, Mesh *me)
        allocate_poly_data(collada_mesh, me);
 
        UVDataWrapper uvs(collada_mesh->getUVCoords());
+       VCOLDataWrapper vcol(collada_mesh->getColors());
 
        MPoly *mpoly = me->mpoly;
        MLoop *mloop = me->mloop;
@@ -553,9 +625,9 @@ void MeshImporter::read_polys(COLLADAFW::Mesh 
*collada_mesh, Mesh *me)
                COLLADAFW::MeshPrimitive *mp = prim_arr[i];
 
                // faces
-               size_t prim_totpoly            = mp->getFaceCount();
-               unsigned int *position_indices = 
mp->getPositionIndices().getData();
-               unsigned int *normal_indices   = 
mp->getNormalIndices().getData();
+               size_t prim_totpoly                           = 
mp->getFaceCount();
+               unsigned int *position_indices                = 
mp->getPositionIndices().getData();
+               unsigned int *normal_indices                  = mp->get

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to