Select Grouped editdata- minor fix in the menu.

Updated Python Mesh API to support UV and Color layers with names.
Similar to vertex group's

renamed a function in customdata.c CustomData_free_layers -> CustomData_free_layers_active and made CustomData_free_layers accept an index, this is needed so python could free layers that arnt active.
This commit is contained in:
2006-12-23 17:07:02 +00:00
parent d66f828c9b
commit bef18061ec
13 changed files with 221 additions and 105 deletions

View File

@@ -89,7 +89,14 @@ void *CustomData_add_layer(struct CustomData *data, int type, int alloctype,
*
* in editmode, use EM_free_data_layer instead of this function
*/
int CustomData_free_layer(struct CustomData *data, int type, int totelem);
int CustomData_free_layer(struct CustomData *data, int type, int totelem, int index);
/* frees the layer index with the give type.
* returns 1 on succes, 0 if no layer with the given type is found
*
* in editmode, use EM_free_data_layer instead of this function
*/
int CustomData_free_layer_active(struct CustomData *data, int type, int totelem);
/* same as above, but free all layers with type */
void CustomData_free_layers(struct CustomData *data, int type, int totelem);

View File

@@ -2118,7 +2118,7 @@ static void mesh_build_data(Object *ob, CustomDataMask dataMask)
&ob->derivedFinal, 0, 1,
needMapping, dataMask);
CustomData_free_layer(&me->fdata, CD_MCOL, me->totface);
CustomData_free_layer_active(&me->fdata, CD_MCOL, me->totface);
} else {
mesh_calc_modifiers(ob, NULL, &ob->derivedDeform,
&ob->derivedFinal, 0, 1,
@@ -2629,7 +2629,7 @@ Mesh* readBobjgz(char *filename, Mesh *orgmesh, float* bbstart, float *bbsize) /
gotBytes = gzread(gzf, &wri, sizeof(wri));
if(wri != newmesh->totvert) {
// complain #vertices has to be equal to #normals, reset&abort
CustomData_free_layer(&newmesh->vdata, CD_MVERT, newmesh->totvert);
CustomData_free_layer_active(&newmesh->vdata, CD_MVERT, newmesh->totvert);
MEM_freeN(newmesh);
snprintf(debugStrBuffer,256,"Reading GZ_BOBJ, #normals=%d, #vertices=%d, aborting...\n", wri,newmesh->totvert );
return NULL;

View File

@@ -628,12 +628,11 @@ void *CustomData_add_layer(CustomData *data, int type, int alloctype,
return NULL;
}
int CustomData_free_layer(CustomData *data, int type, int totelem)
int CustomData_free_layer(CustomData *data, int type, int totelem, int index)
{
int index = 0, i;
int i;
CustomDataLayer *layer;
index = CustomData_get_active_layer_index(data, type);
if (index < 0) return 0;
layer = &data->layers[index];
@@ -662,10 +661,19 @@ int CustomData_free_layer(CustomData *data, int type, int totelem)
return 1;
}
int CustomData_free_layer_active(CustomData *data, int type, int totelem)
{
int index = 0;
index = CustomData_get_active_layer_index(data, type);
if (index < 0) return 0;
return CustomData_free_layer(data, type, totelem, index);
}
void CustomData_free_layers(CustomData *data, int type, int totelem)
{
while (CustomData_has_layer(data, type))
CustomData_free_layer(data, type, totelem);
CustomData_free_layer_active(data, type, totelem);
}
int CustomData_has_layer(const CustomData *data, int type)

View File

@@ -6211,6 +6211,45 @@ static PyObject *Mesh_renameVertGroup( BPy_Mesh * self, PyObject * args )
return EXPP_incr_ret( Py_None );
}
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; i<data->totlayer; 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 )
{
bDeformGroup *defGroup;
@@ -6244,6 +6283,37 @@ 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; i<data->totlayer; 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;
@@ -6341,59 +6411,80 @@ static PyObject *Mesh_insertKey( BPy_Mesh * self, PyObject * args )
}
void Mesh_addCustomLayer_internal(Mesh *me, int type)
static PyObject * Mesh_addCustomLayer_internal(Mesh *me, PyObject * args, int type)
{
int layernum = CustomData_number_of_layers(&me->fdata, type);
int i;
char *name = NULL;
void *layer_data;
CustomData *data = &me->fdata;
if( !PyArg_ParseTuple( args, "|s", &name ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected a string or nothing" );
CustomData_add_layer(&me->fdata, type, CD_DEFAULT,
layer_data = CustomData_add_layer(data, type, CD_DEFAULT,
NULL, me->totface);
CustomData_set_layer_active(&me->fdata, type, layernum);
if (name) {
for(i = 0; i < data->totlayer; i++) {
if (data->layers[i].data == layer_data ) {
BLI_strncpy(data->layers[i].name, name, 32);
CustomData_set_layer_unique_name(&me->fdata, i);
}
}
}
mesh_update_customdata_pointers(me);
Py_RETURN_NONE;
}
/* custom data layers */
static PyObject *Mesh_addUVLayer( BPy_Mesh * self )
static PyObject *Mesh_addUVLayer( BPy_Mesh * self, PyObject * args )
{
Mesh_addCustomLayer_internal(self->mesh, CD_MTFACE);
Py_RETURN_NONE;
return Mesh_addCustomLayer_internal(self->mesh, args, CD_MTFACE);
}
static PyObject *Mesh_addColorLayer( BPy_Mesh * self, PyObject * args )
{
Mesh_addCustomLayer_internal(self->mesh, CD_MCOL);
Py_RETURN_NONE;
return Mesh_addCustomLayer_internal(self->mesh, args, CD_MCOL);
}
static PyObject *Mesh_removeUVLayer( BPy_Mesh * self )
static PyObject *Mesh_removeLayer_internal( BPy_Mesh * self, PyObject * args, int type )
{
Mesh *me = self->mesh;
if (CustomData_number_of_layers(&me->fdata, CD_MTFACE)) {
CustomData_free_layer(&me->fdata, CD_MTFACE, me->totface);
me->mtface= CustomData_get_layer(&me->fdata, CD_MTFACE);
} else
return EXPP_ReturnPyObjError(PyExc_RuntimeError,
"No more UV layers to remove" );
CustomData *data = &me->fdata;
CustomDataLayer *layer;
char *name;
int i;
if( !PyArg_ParseTuple( args, "s", &name ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected string argument" );
for(i=0; i<data->totlayer; 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;
}
}
}
static PyObject *Mesh_removeColorLayer( BPy_Mesh * self )
{
Mesh *me = self->mesh;
if (CustomData_number_of_layers(&me->fdata, CD_MCOL)) {
CustomData_free_layer(&me->fdata, CD_MCOL, me->totface);
me->mcol= CustomData_get_layer(&me->fdata, CD_MCOL);
} else
return EXPP_ReturnPyObjError(PyExc_RuntimeError,
"No more color layers to remove" );
mesh_update_customdata_pointers(me);
Py_RETURN_NONE;
return EXPP_ReturnPyObjError(PyExc_ValueError,
"No matching layers to remove" );
}
static PyObject *Mesh_removeUVLayer( BPy_Mesh * self, PyObject * args )
{
return Mesh_removeLayer_internal(self, args, CD_MTFACE);
}
static PyObject *Mesh_removeColorLayer( BPy_Mesh * self, PyObject * args )
{
return Mesh_removeLayer_internal(self, args, CD_MCOL);
}
static PyObject *Mesh_Tools( BPy_Mesh * self, int type, void **args )
{
@@ -6651,8 +6742,16 @@ 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 */
@@ -6681,13 +6780,13 @@ static struct PyMethodDef BPy_Mesh_methods[] = {
"Recalculates inside or outside normals (experimental)"},
/* mesh custom data layers */
{"addUVLayer", (PyCFunction)Mesh_addUVLayer, METH_NOARGS,
{"addUVLayer", (PyCFunction)Mesh_addUVLayer, METH_VARARGS,
"adds a UV layer to this mesh"},
{"addColorLayer", (PyCFunction)Mesh_addColorLayer, METH_NOARGS,
{"addColorLayer", (PyCFunction)Mesh_addColorLayer, METH_VARARGS,
"adds a color layer to this mesh "},
{"removeUVLayer", (PyCFunction)Mesh_removeUVLayer, METH_NOARGS,
{"removeUVLayer", (PyCFunction)Mesh_removeUVLayer, METH_VARARGS,
"removes a UV layer to this mesh"},
{"removeColorLayer", (PyCFunction)Mesh_removeColorLayer, METH_NOARGS,
{"removeColorLayer", (PyCFunction)Mesh_removeColorLayer, METH_VARARGS,
"removes a color layer to this mesh"},
/* python standard class functions */
@@ -7029,7 +7128,7 @@ static int Mesh_setFlag( BPy_Mesh * self, PyObject *value, void *type )
case MESH_HASVERTUV:
if( !param ) {
if( mesh->msticky ) {
CustomData_free_layer( &mesh->vdata, CD_MSTICKY, mesh->totvert );
CustomData_free_layer_active( &mesh->vdata, CD_MSTICKY, mesh->totvert );
mesh->msticky = NULL;
}
} else {
@@ -7197,47 +7296,50 @@ static int Mesh_setActiveGroup( BPy_Mesh * self, PyObject * arg )
return 0;
}
static PyObject *Mesh_getActiveLayer( BPy_Mesh * self, void *type )
{
int i = CustomData_get_active_layer_index(&self->mesh->fdata, (int)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 */
return PyInt_FromLong(i);
Py_RETURN_NONE;
else {
i--;
return PyInt_FromLong( self->mesh->fdata.layers[i-1].active );
return PyString_FromString( data->layers[i].name);
}
}
static int Mesh_setActiveLayer( BPy_Mesh * self, PyObject * arg, void *type )
static int Mesh_setActiveLayer( BPy_Mesh * self, PyObject * value, void *type )
{
int i, totlayers;
CustomData *data = &self->mesh->fdata;
char *name;
int i,ok,n;
if( !PyInt_Check( arg ) )
if( !PyString_Check( value ) )
return EXPP_ReturnIntError( PyExc_AttributeError,
"expected an int argument" );
"expected a string argument" );
totlayers = CustomData_number_of_layers(&self->mesh->fdata, (int)type );
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++;
}
}
i = PyInt_AsLong( arg );
if (i >= totlayers)
if (!ok)
return EXPP_ReturnIntError( PyExc_ValueError,
"index out of range" );
"layer name does not exist" );
if (i<0)
i = totlayers+i;
CustomData_set_layer_active(data, (int)type, n);
CustomData_set_layer_active(&self->mesh->fdata, (int)type, i);
mesh_update_customdata_pointers(self->mesh);
return 0;
}
static PyObject *Mesh_getTotLayers( BPy_Mesh * self, void *type )
{
return PyInt_FromLong( CustomData_number_of_layers(&self->mesh->fdata, (int)type ) );
}
static PyObject *Mesh_getTexMesh( BPy_Mesh * self )
{
Mesh *texme= self->mesh->texcomesh;
@@ -7438,20 +7540,11 @@ static PyGetSetDef BPy_Mesh_getseters[] = {
{"activeColorLayer",
(getter)Mesh_getActiveLayer, (setter)Mesh_setActiveLayer,
"Index of the active UV layer",
"Name of the active UV layer",
(void *)CD_MCOL},
{"activeUVLayer",
(getter)Mesh_getActiveLayer, (setter)Mesh_setActiveLayer,
"Index of the active vertex color layer",
(void *)CD_MTFACE},
{"totalColorLayers",
(getter)Mesh_getTotLayers, (setter)NULL,
"Index of the active vertex color layer",
(void *)CD_MCOL},
{"totalUVLayers",
(getter)Mesh_getTotLayers, (setter)NULL,
"Index of the active vertex color layer",
"Name of the active vertex color layer",
(void *)CD_MTFACE},
{"texMesh",

View File

@@ -2914,7 +2914,7 @@ static void fill_medge_from_nmesh(Mesh * mesh, BPy_NMesh * nmesh)
tot_valid_faces_edges=tot_faces_edges;
mesh->medge= CustomData_set_layer(&mesh->edata, CD_MEDGE, NULL);
CustomData_free_layer(&mesh->edata, CD_MEDGE, mesh->totedge);
CustomData_free_layer_active(&mesh->edata, CD_MEDGE, mesh->totedge);
mesh->totedge = 0;
/* Flag each edge in faces_edges that is already in nmesh->edges list.
@@ -3004,7 +3004,7 @@ static void check_dverts(Mesh *me, int old_totvert)
if ((totvert == old_totvert) || (!me->dvert)) return;
/* if all verts have been deleted, free old dverts */
else if (totvert == 0) {
CustomData_free_layer( &me->vdata, CD_MDEFORMVERT, old_totvert );
CustomData_free_layer_active( &me->vdata, CD_MDEFORMVERT, old_totvert );
me->dvert= NULL;
}
else {

View File

@@ -1027,24 +1027,32 @@ class Mesh:
Blender itself later).
"""
def addUVLayer():
def addUVLayer(name):
"""
Adds a new UV/Image layer to this mesh, it will always be the last layer and made active.
Adds a new UV/Image layer to this mesh, it will always be the last layer but not made active.
@type name: string
@param name: The name of the new UV layer, 31 characters max.
"""
def addColorLayer():
def addColorLayer(name):
"""
Adds a new Vertex Color layer to this mesh, it will always be the last layer and made active.
Adds a new Vertex Color layer to this mesh, it will always be the last layer but not made active.
@type name: string
@param name: The name of the new Color layer, 31 characters max.
"""
def removeUVLayer():
def removeUVLayer(name):
"""
Removes the active UV/Image layer.
@type name: string
@param name: The name of the UV layer to remove.
"""
def removeColorLayer():
def removeColorLayer(name):
"""
Removes the active Vertex Color layer.
@type name: string
@param name: The name of the Color layer to remove.
"""
def smooth():

View File

@@ -4081,7 +4081,7 @@ void RE_make_sticky(void)
me= ob->data;
mvert= me->mvert;
if(me->msticky)
CustomData_free_layer(&me->vdata, CD_MSTICKY, me->totvert);
CustomData_free_layer_active(&me->vdata, CD_MSTICKY, me->totvert);
me->msticky= CustomData_add_layer(&me->vdata, CD_MSTICKY,
CD_CALLOC, NULL, me->totvert);

View File

@@ -693,7 +693,7 @@ static void delete_customdata_layer(void *data1, void *data2)
EM_free_data_layer(data, type);
}
else if(me) {
CustomData_free_layer(data, type, me->totface);
CustomData_free_layer_active(data, type, me->totface);
mesh_update_customdata_pointers(me);
}
@@ -3669,7 +3669,7 @@ void do_meshbuts(unsigned short event)
switch(event) {
case B_DELSTICKY:
if(me->msticky) {
CustomData_free_layer(&me->vdata, CD_MSTICKY, me->totvert);
CustomData_free_layer_active(&me->vdata, CD_MSTICKY, me->totvert);
me->msticky= NULL;
BIF_undo_push("Delete Sticky");
}

View File

@@ -255,7 +255,7 @@ void del_defgroup (Object *ob)
/* remove all dverts */
if(ob->actdef==0) {
Mesh *me= ob->data;
CustomData_free_layer(&me->vdata, CD_MDEFORMVERT, me->totvert);
CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert);
me->dvert= NULL;
}
}

View File

@@ -810,7 +810,7 @@ void EM_free_data_layer(CustomData *data, int type)
olddata= *data;
olddata.layers= (olddata.layers)? MEM_dupallocN(olddata.layers): NULL;
CustomData_free_layer(data, type, 0);
CustomData_free_layer_active(data, type, 0);
update_data_blocks(&olddata, data);
if (olddata.layers) MEM_freeN(olddata.layers);

View File

@@ -1210,23 +1210,23 @@ void select_mesh_group_menu()
{
short ret;
int selcount, first_item=1;
char str[512] = "Select Grouped%t"; /* total max length is 392 at the moment */
char str[512] = "Select Grouped%t"; /* total max length is 404 at the moment */
if(G.scene->selectmode & SCE_SELECT_VERTEX) {
first_item=0;
strcat(str, "|Verts...| Similar Normal %x1| Same Face Users %x2| Shared Vertex Groups%x3");
strcat(str, "|Verts...%x-1| Similar Normal %x1| Same Face Users %x2| Shared Vertex Groups%x3");
}
if(G.scene->selectmode & SCE_SELECT_EDGE) {
if (!first_item) strcat(str, "|%l");
else first_item=1;
strcat(str, "|Edges...| Similar Length %x10| Similar Direction %x20| Same Face Users%x30| Similar Face Angle%x40| Similar Crease%x50");
strcat(str, "|Edges...%x-1| Similar Length %x10| Similar Direction %x20| Same Face Users%x30| Similar Face Angle%x40| Similar Crease%x50");
}
if(G.scene->selectmode & SCE_SELECT_FACE) {
if (!first_item) strcat(str, "|%l");
strcat(str, "|Faces...| Same Material %x100| Same Image %x200| Similar Area %x300| Similar Perimeter %x400| Similar Normal %x500| Similar Co-Planer %x600");
strcat(str, "|Faces...%x-1| Same Material %x100| Same Image %x200| Similar Area %x300| Similar Perimeter %x400| Similar Normal %x500| Similar Co-Planer %x600");
}

View File

@@ -1066,10 +1066,10 @@ void multires_level_to_mesh(Object *ob, Mesh *me)
eves= MEM_callocN(sizeof(EditVert)*lvl->totvert, "editvert pointers");
} else {
CustomData_free_layer(&me->vdata, CD_MVERT, me->totvert);
CustomData_free_layer(&me->edata, CD_MEDGE, me->totedge);
CustomData_free_layer(&me->fdata, CD_MFACE, me->totface);
CustomData_free_layer(&me->vdata, CD_MDEFORMVERT, me->totvert);
CustomData_free_layer_active(&me->vdata, CD_MVERT, me->totvert);
CustomData_free_layer_active(&me->edata, CD_MEDGE, me->totedge);
CustomData_free_layer_active(&me->fdata, CD_MFACE, me->totface);
CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert);
CustomData_free_layers(&me->fdata, CD_MTFACE, me->totface);
CustomData_free_layers(&me->fdata, CD_MCOL, me->totface);

View File

@@ -395,7 +395,7 @@ void sculptmode_undo_update(SculptUndoStep *newcur)
/* Verts */
if(newcur->verts) {
CustomData_free_layer(&me->vdata, CD_MVERT, me->totvert);
CustomData_free_layer_active(&me->vdata, CD_MVERT, me->totvert);
me->mvert= MEM_dupallocN(newcur->verts);
CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, me->mvert, newcur->totvert);
}
@@ -426,8 +426,8 @@ void sculptmode_undo_update(SculptUndoStep *newcur)
if(type & SUNDO_TOPO)
for(sus= newcur; sus; sus= sus->prev) {
if(sus->type & SUNDO_TOPO) {
CustomData_free_layer(&me->edata, CD_MEDGE, me->totedge);
CustomData_free_layer(&me->fdata, CD_MFACE, me->totface);
CustomData_free_layer_active(&me->edata, CD_MEDGE, me->totedge);
CustomData_free_layer_active(&me->fdata, CD_MFACE, me->totface);
me->medge= MEM_dupallocN(sus->edges);
me->mface= MEM_dupallocN(sus->faces);
@@ -1850,9 +1850,9 @@ void sculptmode_revert_pmv(Mesh *me)
old_verts[i]= nve[me->pv->vert_map[i]];
/* Restore verts, edges and faces */
CustomData_free_layer(&me->vdata, CD_MVERT, me->totvert);
CustomData_free_layer(&me->edata, CD_MEDGE, me->totedge);
CustomData_free_layer(&me->fdata, CD_MFACE, me->totface);
CustomData_free_layer_active(&me->vdata, CD_MVERT, me->totvert);
CustomData_free_layer_active(&me->edata, CD_MEDGE, me->totedge);
CustomData_free_layer_active(&me->fdata, CD_MFACE, me->totface);
CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, old_verts, me->pv->totvert);
CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, me->pv->old_edges, me->pv->totedge);
@@ -1988,7 +1988,7 @@ void sculptmode_do_pmv(Object *ob, rcti *hb_2d, int mode)
++ndx_show;
}
}
CustomData_free_layer(&me->vdata, CD_MVERT, me->pv->totvert);
CustomData_free_layer_active(&me->vdata, CD_MVERT, me->pv->totvert);
me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, nve, me->totvert);
/* Create new face array */