diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index ced210df984..73b1e02eb51 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -174,6 +174,7 @@ void *CustomData_get_layer(const struct CustomData *data, int type); void *CustomData_get_layer_n(const struct CustomData *data, int type, int n); int CustomData_get_layer_index(const struct CustomData *data, int type); +int CustomData_get_named_layer_index(const struct CustomData *data, int type, char *name); int CustomData_get_active_layer_index(const struct CustomData *data, int type); /* copies the data from source to the data element at index in the first diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 3237b7d2d4f..6b763490be9 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -504,6 +504,17 @@ int CustomData_get_layer_index(const CustomData *data, int type) return -1; } +int CustomData_get_named_layer_index(const CustomData *data, int type, char *name) +{ + int i; + + for(i=0; i < data->totlayer; ++i) + if(data->layers[i].type == type && strcmp(data->layers[i].name, name)==0) + return i; + + return -1; +} + int CustomData_get_active_layer_index(const CustomData *data, int type) { int i; diff --git a/source/blender/python/api2_2x/Mesh.c b/source/blender/python/api2_2x/Mesh.c index d7d7c7edb52..04823c62248 100644 --- a/source/blender/python/api2_2x/Mesh.c +++ b/source/blender/python/api2_2x/Mesh.c @@ -6212,42 +6212,6 @@ static PyObject *Mesh_renameVertGroup( BPy_Mesh * self, PyObject * args ) } -static PyObject *Mesh_renameLayer_internal( BPy_Mesh * self, PyObject * args, int type ) -{ - CustomData *data; - CustomDataLayer *layer; - Mesh *mesh = self->mesh; - int i; - char *name_from, *name_to; - - data = &mesh->fdata; - - if( !PyArg_ParseTuple( args, "ss", &name_from, &name_to ) ) - return EXPP_ReturnPyObjError( PyExc_TypeError, - "expected 2 strings" ); - - for(i=0; itotlayer; i++) { - layer = &data->layers[i]; - if(layer->type == type && strcmp(layer->name, name_from)==0) { - BLI_strncpy(layer->name, name_to, 32); - CustomData_set_layer_unique_name(data, i); - return EXPP_incr_ret( Py_None ); - } - } - return EXPP_ReturnPyObjError( PyExc_ValueError, - "layer name was not found" ); -} - -static PyObject *Mesh_renameUVLayer( BPy_Mesh * self, PyObject * args ) -{ - return Mesh_renameLayer_internal( self, args, CD_MTFACE ); -} - -static PyObject *Mesh_renameColorLayer( BPy_Mesh * self, PyObject * args ) -{ - return Mesh_renameLayer_internal( self, args, CD_MCOL ); -} - static PyObject *Mesh_getVertGroupNames( BPy_Mesh * self ) @@ -6283,37 +6247,6 @@ static PyObject *Mesh_getVertGroupNames( BPy_Mesh * self ) return list; } - -static PyObject *Mesh_getLayerNames_internal( BPy_Mesh * self, int type ) -{ - CustomData *data; - CustomDataLayer *layer; - PyObject *list = PyList_New( 0 ); - Mesh *mesh = self->mesh; - int i; - data = &mesh->fdata; - - /* see if there is a duplicate */ - for(i=0; itotlayer; i++) { - layer = &data->layers[i]; - if(layer->type == type) { - PyList_Append( list, PyString_FromString(layer->name) ); - } - } - return list; -} - - -static PyObject *Mesh_getUVLayerNames( BPy_Mesh * self ) -{ - return Mesh_getLayerNames_internal(self, CD_MTFACE); -} - -static PyObject *Mesh_getColorLayerNames( BPy_Mesh * self ) -{ - return Mesh_getLayerNames_internal(self, CD_MCOL); -} - static PyObject *Mesh_getVertexInfluences( BPy_Mesh * self, PyObject * args ) { int index; @@ -6411,6 +6344,10 @@ static PyObject *Mesh_insertKey( BPy_Mesh * self, PyObject * args ) } + + +/* Custom Data Layers */ + static PyObject * Mesh_addCustomLayer_internal(Mesh *me, PyObject * args, int type) { int i; @@ -6424,10 +6361,15 @@ static PyObject * Mesh_addCustomLayer_internal(Mesh *me, PyObject * args, int ty layer_data = CustomData_add_layer(data, type, CD_DEFAULT, NULL, me->totface); - if (name) { + if (name && layer_data) { + + if (strlen(name)>31) + return EXPP_ReturnPyObjError( PyExc_ValueError, + "error, maximum name length is 31" ); + for(i = 0; i < data->totlayer; i++) { if (data->layers[i].data == layer_data ) { - BLI_strncpy(data->layers[i].name, name, 32); + BLI_strncpy(data->layers[i].name, name, 31); CustomData_set_layer_unique_name(&me->fdata, i); } } @@ -6436,7 +6378,6 @@ static PyObject * Mesh_addCustomLayer_internal(Mesh *me, PyObject * args, int ty Py_RETURN_NONE; } -/* custom data layers */ static PyObject *Mesh_addUVLayer( BPy_Mesh * self, PyObject * args ) { return Mesh_addCustomLayer_internal(self->mesh, args, CD_MTFACE); @@ -6459,20 +6400,19 @@ static PyObject *Mesh_removeLayer_internal( BPy_Mesh * self, PyObject * args, in return EXPP_ReturnPyObjError( PyExc_TypeError, "expected string argument" ); - for(i=0; itotlayer; i++) { - layer = &data->layers[i]; - if(layer->type == type) { - if (strcmp(layer->name, name)==0) { - - CustomData_free_layer(data, type, me->totface, i); - mesh_update_customdata_pointers(me); - Py_RETURN_NONE; - } - } - } + if (strlen(name)>31) + return EXPP_ReturnPyObjError( PyExc_ValueError, + "error, maximum name length is 31" ); - return EXPP_ReturnPyObjError(PyExc_ValueError, - "No matching layers to remove" ); + i = CustomData_get_named_layer_index(data, type, name); + + if (i==-1) + return EXPP_ReturnPyObjError(PyExc_ValueError, + "No matching layers to remove" ); + + CustomData_free_layer(data, type, me->totface, i); + mesh_update_customdata_pointers(me); + Py_RETURN_NONE; } @@ -6486,6 +6426,120 @@ static PyObject *Mesh_removeColorLayer( BPy_Mesh * self, PyObject * args ) return Mesh_removeLayer_internal(self, args, CD_MCOL); } + +static PyObject *Mesh_renameLayer_internal( BPy_Mesh * self, PyObject * args, int type ) +{ + CustomData *data; + CustomDataLayer *layer; + Mesh *mesh = self->mesh; + int i; + char *name_from, *name_to; + + data = &mesh->fdata; + + if( !PyArg_ParseTuple( args, "ss", &name_from, &name_to ) ) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "expected 2 strings" ); + + if (strlen(name_from)>31 || strlen(name_to)>31) + return EXPP_ReturnPyObjError( PyExc_ValueError, + "error, maximum name length is 31" ); + + i = CustomData_get_named_layer_index(data, type, name_from); + + if (i==-1) + return EXPP_ReturnPyObjError( PyExc_ValueError, + "layer name was not found" ); + + layer = &data->layers[i]; + BLI_strncpy(layer->name, name_to, 31); + CustomData_set_layer_unique_name(data, i); + return EXPP_incr_ret( Py_None ); +} + +static PyObject *Mesh_renameUVLayer( BPy_Mesh * self, PyObject * args ) +{ + return Mesh_renameLayer_internal( self, args, CD_MTFACE ); +} + +static PyObject *Mesh_renameColorLayer( BPy_Mesh * self, PyObject * args ) +{ + return Mesh_renameLayer_internal( self, args, CD_MCOL ); +} + + +static PyObject *Mesh_getLayerNames_internal( BPy_Mesh * self, int type ) +{ + CustomData *data; + CustomDataLayer *layer; + PyObject *list = PyList_New( 0 ); + Mesh *mesh = self->mesh; + int i; + data = &mesh->fdata; + + /* see if there is a duplicate */ + for(i=0; itotlayer; i++) { + layer = &data->layers[i]; + if(layer->type == type) { + PyList_Append( list, PyString_FromString(layer->name) ); + } + } + return list; +} + +static PyObject *Mesh_getUVLayerNames( BPy_Mesh * self ) +{ + return Mesh_getLayerNames_internal(self, CD_MTFACE); +} + +static PyObject *Mesh_getColorLayerNames( BPy_Mesh * self ) +{ + return Mesh_getLayerNames_internal(self, CD_MCOL); +} +/* used by activeUVLayer and activeColorLayer attrs */ +static PyObject *Mesh_getActiveLayer( BPy_Mesh * self, void *type ) +{ + CustomData *data = &self->mesh->fdata; + int i = CustomData_get_active_layer_index(data, (int)type); + if (i == -1) /* so -1 is for no active layer 0+ for an active layer */ + Py_RETURN_NONE; + else { + return PyString_FromString( data->layers[i].name); + } +} + +static int Mesh_setActiveLayer( BPy_Mesh * self, PyObject * value, void *type ) +{ + CustomData *data = &self->mesh->fdata; + char *name; + int i,ok,n; + + if( !PyString_Check( value ) ) + return EXPP_ReturnIntError( PyExc_ValueError, + "expected a string argument" ); + + name = PyString_AsString( value ); + ok = 0; + n = 0; + for(i=0; i < data->totlayer; ++i) { + if(data->layers[i].type == (int) type) { + if (strcmp(data->layers[i].name, name)==0) { + ok = 1; + break; + } + n++; + } + } + + if (!ok) + return EXPP_ReturnIntError( PyExc_ValueError, + "layer name does not exist" ); + + CustomData_set_layer_active(data, (int)type, n); + mesh_update_customdata_pointers(self->mesh); + return 0; +} + static PyObject *Mesh_Tools( BPy_Mesh * self, int type, void **args ) { Base *base; @@ -6742,16 +6796,8 @@ static struct PyMethodDef BPy_Mesh_methods[] = { "Get index and optional weight for vertices in vertex group"}, {"renameVertGroup", (PyCFunction)Mesh_renameVertGroup, METH_VARARGS, "Rename an existing vertex group"}, - {"renameUVLayer", (PyCFunction)Mesh_renameUVLayer, METH_VARARGS, - "Rename a UV Layer"}, - {"renameColorLayer", (PyCFunction)Mesh_renameColorLayer, METH_VARARGS, - "Rename a Color Layer"}, {"getVertGroupNames", (PyCFunction)Mesh_getVertGroupNames, METH_NOARGS, "Get names of vertex groups"}, - {"getUVLayerNames", (PyCFunction)Mesh_getUVLayerNames, METH_NOARGS, - "Get names of UV layers"}, - {"getColorLayerNames", (PyCFunction)Mesh_getColorLayerNames, METH_NOARGS, - "Get names of Color layers"}, {"getVertexInfluences", (PyCFunction)Mesh_getVertexInfluences, METH_VARARGS, "Get list of the influences of bones for a given mesh vertex"}, /* Shape Keys */ @@ -6788,7 +6834,15 @@ static struct PyMethodDef BPy_Mesh_methods[] = { "removes a UV layer to this mesh"}, {"removeColorLayer", (PyCFunction)Mesh_removeColorLayer, METH_VARARGS, "removes a color layer to this mesh"}, - + {"getUVLayerNames", (PyCFunction)Mesh_getUVLayerNames, METH_NOARGS, + "Get names of UV layers"}, + {"getColorLayerNames", (PyCFunction)Mesh_getColorLayerNames, METH_NOARGS, + "Get names of Color layers"}, + {"renameUVLayer", (PyCFunction)Mesh_renameUVLayer, METH_VARARGS, + "Rename a UV Layer"}, + {"renameColorLayer", (PyCFunction)Mesh_renameColorLayer, METH_VARARGS, + "Rename a Color Layer"}, + /* python standard class functions */ {"__copy__", (PyCFunction)Mesh_copy, METH_NOARGS, "Return a copy of the mesh"}, @@ -7296,50 +7350,6 @@ static int Mesh_setActiveGroup( BPy_Mesh * self, PyObject * arg ) return 0; } -static PyObject *Mesh_getActiveLayer( BPy_Mesh * self, void *type ) -{ - CustomData *data = &self->mesh->fdata; - int i = CustomData_get_active_layer_index(data, (int)type); - if (i == -1) /* so -1 is for no active layer 0+ for an active layer */ - Py_RETURN_NONE; - else { - return PyString_FromString( data->layers[i].name); - } -} - -static int Mesh_setActiveLayer( BPy_Mesh * self, PyObject * value, void *type ) -{ - CustomData *data = &self->mesh->fdata; - char *name; - int i,ok,n; - - if( !PyString_Check( value ) ) - return EXPP_ReturnIntError( PyExc_AttributeError, - "expected a string argument" ); - - name = PyString_AsString( value ); - ok = 0; - n = 0; - for(i=0; i < data->totlayer; ++i) { - if(data->layers[i].type == (int) type) { - if (strcmp(data->layers[i].name, name)==0) { - ok = 1; - break; - } - n++; - } - } - - if (!ok) - return EXPP_ReturnIntError( PyExc_ValueError, - "layer name does not exist" ); - - CustomData_set_layer_active(data, (int)type, n); - - mesh_update_customdata_pointers(self->mesh); - return 0; -} - static PyObject *Mesh_getTexMesh( BPy_Mesh * self ) { Mesh *texme= self->mesh->texcomesh; diff --git a/source/blender/python/api2_2x/doc/Mesh.py b/source/blender/python/api2_2x/doc/Mesh.py index 3bc8ca885f0..a5541fb81ba 100644 --- a/source/blender/python/api2_2x/doc/Mesh.py +++ b/source/blender/python/api2_2x/doc/Mesh.py @@ -776,16 +776,10 @@ class Mesh: mesh can be used for rendering textures. @type texMesh: Mesh or None - @ivar activeUVLayer: The mesh's active UV/Image layer index. -1 if there is no UV/Image layers. - @type activeUVLayer: int - @ivar activeColorLayer: The mesh's active Vertex Color layer index. -1 if there is no UV/Image layers. - @type activeColorLayer: int - - @ivar totalUVLayers: The mesh's total number of UV/Image layers. - @type totalUVLayers: int - @ivar totalColorLayers: The mesh's total number of Vertex Color layers. - @type totalColorLayers: int - + @ivar activeUVLayer: The mesh's active UV/Image layer. None if there is no UV/Image layers. + @type activeUVLayer: string + @ivar activeColorLayer: The mesh's active Vertex Color layer. None if there is no UV/Image layers. + @type activeColorLayer: string """ def getFromObject(object, cage=0, render=0): @@ -1055,6 +1049,24 @@ class Mesh: @param name: The name of the Color layer to remove. """ + def renameUVLayer(name, newname): + """ + Removes the active UV/Image layer. + @type name: string + @param name: The UV layer to rename. + @type newname: string + @param newname: The new name of the UV layer, will be made unique. + """ + + def renameColorLayer(name, newname): + """ + Removes the active Vertex Color layer. + @type name: string + @param name: The Color layer to rename. + @type newname: string + @param newname: The new name of the Color layer, will be made unique. + """ + def smooth(): """ Flattens angle of selected faces. Experimental mesh tool.