Index: NMesh.c =================================================================== RCS file: /cvsroot/bf-blender/blender/source/blender/python/api2_2x/NMesh.c,v retrieving revision 1.52 diff -r1.52 NMesh.c 89c89,98 < static int convert_NMeshToMesh( Mesh * mesh, BPy_NMesh * nmesh ); --- > static int convert_NMeshToMesh( Mesh * mesh, BPy_NMesh * nmesh, int store_edges ); > /* */ > static PyObject *NMesh_printDebug( PyObject * self, PyObject * args ); > /* */ > static PyObject *NMesh_addEdge( PyObject * self, PyObject * args ); > static PyObject *NMesh_findEdge( PyObject * self, PyObject * args ); > static PyObject *NMesh_removeEdge( PyObject * self, PyObject * args ); > static PyObject *NMesh_addEdgesData( PyObject * self, PyObject * args ); > static PyObject *NMesh_addFace( PyObject * self, PyObject * args ); > static PyObject *NMesh_removeFace( PyObject * self, PyObject * args ); 98a108,136 > /* */ > > static char NMesh_printDebug_doc[] = > "print debug info about the mesh."; > > /* */ > > static char NMesh_addEdge_doc[] = > "create an edge between two vertices.\n\ > If an edge already exists between those vertices, it is returned. (in blender, only zero \ > or one edge can link two vertices.\n\ > Created edge is automatically added to edges list."; > > static char NMesh_findEdge_doc[] = > "find an edge between two vertices."; > > static char NMesh_removeEdge_doc[] = > "remove an edge between two vertices.\n\ > All faces using this edge are removed from faces list."; > > static char NMesh_addEdgesData_doc[] = > "add edges data to the mesh."; > > static char NMesh_addFace_doc[] = > "add a face to face list and add to edge list (if edge data exists) necessary edges."; > > static char NMesh_removeFace_doc[] = > "remove a face for face list and remove edges no more used by any other face (if \ > edge data exists)."; 205,206c243,245 < static char NMesh_update_doc[] = "(recalc_normals = 0) - updates the Mesh.\n\ < if recalc_normals is given and is equal to 1, normal vectors are recalculated."; --- > static char NMesh_update_doc[] = "(recalc_normals = 0, store_edges = 0) - updates the Mesh.\n\ > if recalc_normals is given and is equal to 1, normal vectors are recalculated.\n\ > if store_edges is given qnd is equal to 1, egdes data are stored."; 245c284 < "(mesh, [name, renormal]) - Return a raw mesh to Blender\n\n\ --- > "(mesh, [name, renormal, store_edges]) - Return a raw mesh to Blender\n\n\ 248c287,288 < [renormal=1] Flag to control vertex normal recalculation\n\n\ --- > [renormal=1] Flag to control vertex normal recalculation\n\ > [store_edges=0] Store edges data in the blender mesh\n\ 842a883,985 > > /***************************** > * NMEdge > *****************************/ > > static PyObject *new_NMEdge( PyObject * v1, PyObject * v2, char crease, short flag) > { > BPy_NMEdge *edge=NULL; > > if (!v1 || !v2) return NULL; > if (!BPy_NMVert_Check(v1) || !BPy_NMVert_Check(v2)) return NULL; > > edge = PyObject_NEW( BPy_NMEdge, &NMEdge_Type ); > > edge->v1=EXPP_incr_ret(v1); > edge->v2=EXPP_incr_ret(v2); > edge->flag=flag; > edge->crease=crease; > > return ( PyObject * )edge; > } > > static void NMEdge_dealloc( PyObject * self ) > { > BPy_NMEdge *edge=(BPy_NMEdge *)self; > > Py_DECREF(edge->v1); > Py_DECREF(edge->v2); > > PyObject_DEL(self); > } > > static PyObject *NMEdge_getattr( PyObject * self, char *name ) > { > BPy_NMEdge *edge=(BPy_NMEdge *)self; > > if ( strcmp( name, "v1" ) == 0 ) > return EXPP_incr_ret( edge->v1 ); > else if ( strcmp( name, "v2" ) == 0 ) > return EXPP_incr_ret( edge->v2 ); > else if ( strcmp( name, "flag" ) == 0 ) > return PyInt_FromLong( edge->flag ); > else if ( strcmp( name, "crease" ) == 0 ) > return PyInt_FromLong( edge->crease ); > else if( strcmp( name, "__members__" ) == 0 ) > return Py_BuildValue( "[s,s,s,s]", > "v1", "v2", "flag", "crease" ); > > return EXPP_ReturnPyObjError( PyExc_AttributeError, name ); > } > > static int NMEdge_setattr( PyObject * self, char *name, PyObject * v ) > { > BPy_NMEdge *edge=(BPy_NMEdge *)self; > > if ( strcmp( name, "flag" ) == 0 ) > { > short flag=0; > if( !PyInt_Check( v ) ) > return EXPP_ReturnIntError( PyExc_TypeError, > "expected int argument" ); > > flag = ( short ) PyInt_AsLong( v ); > > edge->flag = flag; > > return 0; > } > else if ( strcmp( name, "crease" ) == 0 ) > { > char crease=0; > if( !PyInt_Check( v ) ) > return EXPP_ReturnIntError( PyExc_TypeError, > "expected int argument" ); > > crease = ( char ) PyInt_AsLong( v ); > > edge->crease = crease; > > return 0; > } > > return EXPP_ReturnIntError( PyExc_AttributeError, name ); > } > > PyTypeObject NMEdge_Type = { > PyObject_HEAD_INIT( NULL ) > 0, /*ob_size */ > "Blender NMEdge", /*tp_name */ > sizeof( BPy_NMEdge ), /*tp_basicsize */ > 0, /*tp_itemsize */ > /* methods */ > ( destructor ) NMEdge_dealloc, /*tp_dealloc */ > ( printfunc ) 0, /*tp_print */ > ( getattrfunc ) NMEdge_getattr, /*tp_getattr */ > ( setattrfunc ) NMEdge_setattr, /*tp_setattr */ > }; > > > > > > 850a994 > Py_XDECREF( me->edges ); 1111c1255 < int recalc_normals = 0; --- > int recalc_normals = 0, store_edges = 0; 1115c1259 < if( !PyArg_ParseTuple( args, "|i", &recalc_normals ) ) --- > if( !PyArg_ParseTuple( args, "|ii", &recalc_normals, &store_edges ) ) 1117c1261 < "expected nothing or an int (0 or 1) as argument" ); --- > "expected nothing, one or two int(s) (0 or 1) as argument" ); 1125c1269 < convert_NMeshToMesh( mesh, nmesh ); --- > convert_NMeshToMesh( mesh, nmesh, store_edges ); 1127c1271 < nmesh->mesh = Mesh_fromNMesh( nmesh ); --- > nmesh->mesh = Mesh_fromNMesh( nmesh, store_edges ); 1218c1362 < Mesh *Mesh_fromNMesh( BPy_NMesh * nmesh ) --- > Mesh *Mesh_fromNMesh( BPy_NMesh * nmesh , int store_edges ) 1229c1373 < convert_NMeshToMesh( mesh, nmesh ); --- > convert_NMeshToMesh( mesh, nmesh, store_edges ); 1359a1504,1512 > /* */ > MethodDef( printDebug ), > /* */ > MethodDef( addEdge ), > MethodDef( findEdge ), > MethodDef( removeEdge ), > MethodDef( addEdgesData ), > MethodDef( addFace ), > MethodDef( removeFace ), 1427a1581,1587 > else if( strcmp( name, "edges" ) == 0 ) > { > if (me->edges) > return EXPP_incr_ret( me->edges ); > else > return EXPP_incr_ret( Py_None ); > } 1429c1589 < return Py_BuildValue( "[s,s,s,s,s,s,s]", --- > return Py_BuildValue( "[s,s,s,s,s,s,s,s]", 1432c1592 < "subdivLevels" ); --- > "subdivLevels", "edges" ); 1532c1692,1705 < --- > else if( strcmp( name, "edges" ) == 0 ) > { > if (me->edges) > { > if (PySequence_Check(v)) > { > Py_DECREF(me->edges); > me->edges = EXPP_incr_ret( v ); > } > } > else > return EXPP_ReturnIntError( PyExc_RuntimeError, > "mesh has no edge information" ); > } 1613a1787,1793 > static BPy_NMEdge *nmedge_from_data( BPy_NMesh * mesh, MEdge *edge ) > { > PyObject *v1=PyList_GetItem( mesh->verts, edge->v1 ); > PyObject *v2=PyList_GetItem( mesh->verts, edge->v2 ); > return new_NMEdge(v1, v2, edge->crease, edge->flag); > } > 1669a1850 > me->edges = NULL; /* no edge data by default */ 1685c1866,1867 < int i, totvert, totface; --- > MEdge *medges; > int i, totvert, totface, totedge; 1696a1879 > medges = dlm->medge; 1699a1883 > totedge = dlm->totedge; 1712a1897 > medges = oldmesh->medge; 1715a1901 > totedge = oldmesh->totedge; 1764a1951,1961 > > if (medges) > { > me->edges = PyList_New( totedge ); > for( i = 0; i < totedge; i++ ) > { > MEdge *edge = &medges[i]; > PyList_SetItem( me->edges, i, nmedge_from_data ( me, edge ) ); > } > } > 2173c2370,2456 < static int convert_NMeshToMesh( Mesh * mesh, BPy_NMesh * nmesh ) --- > static void fill_medge_from_nmesh(Mesh * mesh, BPy_NMesh * nmesh) > { > int i,j; > MEdge *faces_edges=NULL; > int tot_faces_edges=0; > int tot_valid_faces_edges=0; > int nmeshtotedges=PyList_Size(nmesh->edges); > int tot_valid_nmedges=0; > BPy_NMEdge **valid_nmedges=NULL; > > valid_nmedges=MEM_callocN(nmeshtotedges*sizeof(BPy_NMEdge *), "make BPy_NMEdge"); > > /* First compute the list of edges that exists because faces exists */ > make_edges(mesh); > > faces_edges=mesh->medge; > tot_faces_edges=mesh->totedge; > tot_valid_faces_edges=tot_faces_edges; > > mesh->medge=NULL; > mesh->totedge = 0; > > /* Flag each edge in faces_edges that is already in nmesh->edges list. > * Flaging an edge means MEdge v1=v2=0. > * Each time an edge is flagged, tot_valid_faces_edges is decremented. > * > * Also store in valid_nmedges pointers to each valid NMEdge in nmesh->edges. > * An invalid NMEdge is an edge that has a vertex that is not in the vertices > * list. Ie its index is -1. > * Each time an valid NMEdge is flagged, tot_valid_nmedges is incremented. > */ > for( i = 0; i < nmeshtotedges; ++i ) > { > int v1idx,v2idx; > BPy_NMEdge *edge=( BPy_NMEdge *) PyList_GetItem(nmesh->edges, i); > BPy_NMVert *v=(BPy_NMVert *)edge->v1; > v1idx=v->index; > v=(BPy_NMVert *)edge->v2; > v2idx=v->index; > if (-1 == v1idx || -1 == v2idx) continue; > valid_nmedges[tot_valid_nmedges]=edge; > ++tot_valid_nmedges; > for( j = 0; j < tot_faces_edges; j++ ) > { > MEdge *me=faces_edges+j; > if ( (me->v1==v1idx && me->v2==v2idx) || > (me->v1==v2idx && me->v2==v1idx) ) > { > me->v1=0; me->v2=0; > --tot_valid_faces_edges; > } > } > } > > /* Now we have the total count of valid edges */ > mesh->totedge=tot_valid_nmedges+tot_valid_faces_edges; > mesh->medge=MEM_callocN(mesh->totedge*sizeof(MEdge), "make mesh edges"); > for ( i = 0; i < tot_valid_nmedges; ++i ) > { > BPy_NMEdge *edge=valid_nmedges[i]; > MEdge *medge=mesh->medge+i; > int v1=((BPy_NMVert *)edge->v1)->index; > int v2=((BPy_NMVert *)edge->v2)->index; > medge->v1=v1; > medge->v2=v2; > medge->flag=edge->flag; > medge->crease=edge->crease; > } > for ( i = 0, j = tot_valid_nmedges; i < tot_faces_edges; ++i ) > { > MEdge *edge=faces_edges+i; > if (edge->v1!=0 || edge->v2!=0) // valid edge > { > MEdge *medge=mesh->medge+j; > medge->v1=edge->v1; > medge->v2=edge->v2; > medge->flag=ME_EDGEDRAW; > medge->crease=0; > ++j; > } > } > > MEM_freeN( valid_nmedges ); > MEM_freeN( faces_edges ); > } > > static int convert_NMeshToMesh( Mesh * mesh, BPy_NMesh * nmesh, int store_edges) 2179a2463 > MEdge *newedge; 2189a2474 > mesh->medge = NULL; 2259a2545,2557 > /* do the same for edges if there is edge data */ > if (nmesh->edges) > { > int nmeshtotedges=PyList_Size(nmesh->edges); > for( i = 0; i < nmeshtotedges; ++i ) > { > BPy_NMEdge *edge=( BPy_NMEdge *) PyList_GetItem(nmesh->edges, i); > BPy_NMVert *v=(BPy_NMVert *)edge->v1; > v->index=-1; > v=(BPy_NMVert *)edge->v2; > v->index=-1; > } > } 2319a2618,2626 > /* After face data has been written, write edge data. > * Edge data are not stored before face ones since we need > * mesh->mface to be correctly initialized. > */ > if (nmesh->edges && store_edges) > { > fill_medge_from_nmesh(mesh, nmesh); > } > 2329a2637 > int store_edges = 0; 2331,2332c2639,2640 < if( !PyArg_ParseTuple( args, "O!|si", < &NMesh_Type, &nmesh, &name, &recalc_normals ) ) --- > if( !PyArg_ParseTuple( args, "O!|sii", > &NMesh_Type, &nmesh, &name, &recalc_normals, &store_edges ) ) 2334c2642 < "expected an NMesh object and optionally also a string and an int" ); --- > "expected an NMesh object and optionally also a string and two ints" ); 2379c2687 < convert_NMeshToMesh( mesh, nmesh ); --- > convert_NMeshToMesh( mesh, nmesh, store_edges ); 2526a2835,2850 > static PyObject *M_NMesh_EdgeFlagsDict( void ) > { > PyObject *EF = M_constant_New( ); > > if( EF ) { > BPy_constant *d = ( BPy_constant * ) EF; > > constant_insert(d, "SELECT", PyInt_FromLong(1)); > constant_insert(d, "EDGEDRAW", PyInt_FromLong(ME_EDGEDRAW)); > constant_insert(d, "SEAM", PyInt_FromLong(ME_SEAM)); > constant_insert(d, "FGON", PyInt_FromLong(ME_FGON)); > } > > return EF; > } > 2534a2859 > PyObject *EdgeFlags = M_NMesh_EdgeFlagsDict( ); 2553a2879,2880 > if( EdgeFlags ) > PyModule_AddObject( submodule, "EdgeFlags", EdgeFlags ); 2584,2585d2910 < unlink_existingMeshData( mesh ); < convert_NMeshToMesh( mesh, nmesh ); 2587c2912 < nmesh->mesh = Mesh_fromNMesh( nmesh ); --- > nmesh->mesh = Mesh_fromNMesh( nmesh, 1 ); 2589d2913 < } 2591c2915 < nmesh->object = ob; /* linking for vgrouping methods */ --- > nmesh->object = ob; /* linking for vgrouping methods */ 2593,2595c2917,2919 < if( nmesh->name && nmesh->name != Py_None ) < new_id( &( G.main->mesh ), &mesh->id, < PyString_AsString( nmesh->name ) ); --- > if( nmesh->name && nmesh->name != Py_None ) > new_id( &( G.main->mesh ), &mesh->id, > PyString_AsString( nmesh->name ) ); 2597,2599c2921 < mesh_update( mesh ); < < nmesh_updateMaterials( nmesh ); --- > mesh_update( mesh ); 2600a2923,2924 > nmesh_updateMaterials( nmesh ); > } 2606a2931,3283 > #define POINTER_CROSS_EQ(a1, a2, b1, b2) (((a1)==(b1) && (a2)==(b2)) || ((a1)==(b2) && (a2)==(b1))) > > static PyObject *findEdge( BPy_NMesh *nmesh, BPy_NMVert *v1, BPy_NMVert *v2, int create) > { > int i; > > for ( i = 0; i < PyList_Size(nmesh->edges); ++i ) > { > BPy_NMEdge *edge=PyList_GetItem( nmesh->edges, i ); > if (!BPy_NMEdge_Check(edge)) continue; > if ( POINTER_CROSS_EQ(edge->v1, edge->v2, v1, v2) ) > { > return EXPP_incr_ret(edge); > } > } > > /* if this line is reached, edge has not been found */ > if (create) > { > BPy_NMEdge *newEdge=new_NMEdge(v1, v2, 0, ME_EDGEDRAW); > PyList_Append(nmesh->edges, newEdge); > return newEdge; > } > else > return EXPP_incr_ret( Py_None ); > } > > static void removeEdge( BPy_NMesh *nmesh, BPy_NMVert *v1, BPy_NMVert *v2, int ununsedOnly) > { > int i,j; > BPy_NMEdge *edge=NULL; > int edgeUsedByFace=0; > int totedge=PyList_Size(nmesh->edges); > > /* find the edge in the edge list */ > for ( i = 0; i < totedge; ++i ) > { > edge=PyList_GetItem( nmesh->edges, i ); > if (!BPy_NMEdge_Check(edge)) continue; > if ( POINTER_CROSS_EQ(edge->v1, edge->v2, v1, v2) ) > { > break; > } > } > > if (i==totedge || !edge) // edge not found > return; > > for ( j = PyList_Size(nmesh->faces)-1; j >= 0 ; --j ) > { > BPy_NMFace *face=PyList_GetItem(nmesh->faces, j); > int k, del_face=0; > int totv; > if (!BPy_NMFace_Check(face)) continue; > totv=PyList_Size(face->v); > if (totv<2) continue; > for ( k = 0; k < totv && !del_face; ++k ) > { > BPy_NMVert *fe_v1=PyList_GetItem(face->v, k ? k-1 : totv-1); > BPy_NMVert *fe_v2=PyList_GetItem(face->v, k); > if ( POINTER_CROSS_EQ(v1, v2, fe_v1, fe_v2) ) > { > edgeUsedByFace=1; > del_face=1; > } > } > if (del_face && !ununsedOnly) > { > PySequence_DelItem(nmesh->faces, j); > } > } > > if (!ununsedOnly || (ununsedOnly && !edgeUsedByFace) ) > PySequence_DelItem(nmesh->edges, PySequence_Index(nmesh->edges, edge)); > } > > > static PyObject *NMesh_addEdge( PyObject * self, PyObject * args ) > { > BPy_NMesh *bmesh=self; > BPy_NMVert *v1=NULL, *v2=NULL; > int i; > > if (!bmesh->edges) > return EXPP_ReturnPyObjError( PyExc_RuntimeError, > "NMesh has no edge data." ); > > if (!PyArg_ParseTuple > ( args, "O!O!", &NMVert_Type, &v1, &NMVert_Type, &v2 ) ) { > return EXPP_ReturnPyObjError( PyExc_TypeError, > "expected NMVert, NMVert" ); > } > > if (v1==v2) > return EXPP_ReturnPyObjError( PyExc_AttributeError, > "vertices must be different" ); > > return findEdge(bmesh, v1, v2, 1); > } > > static PyObject *NMesh_findEdge( PyObject * self, PyObject * args ) > { > BPy_NMesh *bmesh=self; > BPy_NMVert *v1=NULL, *v2=NULL; > int i; > > if (!bmesh->edges) > return EXPP_ReturnPyObjError( PyExc_RuntimeError, > "NMesh has no edge data." ); > > if (!PyArg_ParseTuple > ( args, "O!O!", &NMVert_Type, &v1, &NMVert_Type, &v2 ) ) { > return EXPP_ReturnPyObjError( PyExc_TypeError, > "expected NMVert, NMVert" ); > } > > if (v1==v2) > return EXPP_ReturnPyObjError( PyExc_AttributeError, > "vertices must be different" ); > > return findEdge(bmesh, v1, v2, 0); > } > > static PyObject *NMesh_removeEdge( PyObject * self, PyObject * args ) > { > BPy_NMesh *bmesh=self; > BPy_NMVert *v1=NULL, *v2=NULL; > int i; > > if (!bmesh->edges) > return EXPP_ReturnPyObjError( PyExc_RuntimeError, > "NMesh has no edge data." ); > > if (!PyArg_ParseTuple > ( args, "O!O!", &NMVert_Type, &v1, &NMVert_Type, &v2 ) ) { > return EXPP_ReturnPyObjError( PyExc_TypeError, > "expected NMVert, NMVert" ); > } > > if (v1==v2) > return EXPP_ReturnPyObjError( PyExc_AttributeError, > "vertices must be different" ); > removeEdge(bmesh, v1, v2, 0); > > return EXPP_incr_ret( Py_None ); > } > > > static PyObject *NMesh_addEdgesData( PyObject * self, PyObject * args ) > { > /* Here we uses make_edges to create edges data. > * Since Mesh corresponding to NMesh may not content the same data as > * the NMesh and since maybe the NMesh has been created from scratch, > * we creates a temporary Mesh to use to call make_edges > */ > BPy_NMesh *nmesh=self; > Mesh *tempMesh=NULL; > int i; > > if (nmesh->edges) > return EXPP_ReturnPyObjError( PyExc_RuntimeError, > "NMesh has already edge data." ); > > tempMesh=MEM_callocN(sizeof(Mesh), "temp mesh"); > convert_NMeshToMesh(tempMesh, nmesh, 0); > > make_edges(tempMesh); > > nmesh->edges = PyList_New( tempMesh->totedge ); > for( i = 0; i < tempMesh->totedge; ++i ) > { > MEdge *edge = (tempMesh->medge) + i; > /* By using nmedge_from_data, an important assumption is made: > * every vertex in nmesh has been written in tempMesh in the same order > * than in nmesh->verts. > * Actually this assumption is needed since nmedge_from_data get the > * two NMVert for the newly created edge by using a PyList_GetItem with > * the indices stored in edge. Those indices are valid for nmesh only if > * nmesh->verts and tempMesh->mvert are identical (same number of vertices > * in same order). > */ > PyList_SetItem( nmesh->edges, i, nmedge_from_data ( nmesh, edge ) ); > } > > unlink_existingMeshData(tempMesh); > MEM_freeN(tempMesh); > > return EXPP_incr_ret( Py_None ); > } > > static PyObject *NMesh_addFace( PyObject * self, PyObject * args ) > { > BPy_NMesh *nmesh=self; > > BPy_NMFace *face; > int totv=0; > > if (!PyArg_ParseTuple > ( args, "O!", &NMFace_Type, &face ) ) { > return EXPP_ReturnPyObjError( PyExc_TypeError, > "expected NMFace argument" ); > } > > totv=PyList_Size(face->v); > > /* > * Before edges data exists, having faces with two vertices was > * the only way of storing edges not attached to any face. > */ > if (totv!=2 || !nmesh->edges) > PyList_Append(nmesh->faces, face); > > if (nmesh->edges) > { > > if (totv>=2) > { > /* when totv==2, there is only one edge, when totv==3 there is three edges > * and when totv==4 there is four edges. > * that's why in the following line totv==2 is a special case */ > PyObject *edges = PyList_New((totv==2) ? 1 : totv); > if (totv==2) > { > BPy_NMVert *fe_v1=PyList_GetItem(face->v, 0); > BPy_NMVert *fe_v2=PyList_GetItem(face->v, 1); > BPy_NMEdge *edge=findEdge(nmesh, fe_v1, fe_v2, 1); > PyList_SetItem(edges, 0, edge); // PyList_SetItem steals the reference > } > else > { > int k; > for ( k = 0; k < totv; ++k ) > { > BPy_NMVert *fe_v1=PyList_GetItem(face->v, k ? k-1 : totv-1); > BPy_NMVert *fe_v2=PyList_GetItem(face->v, k); > BPy_NMEdge *edge=findEdge(nmesh, fe_v1, fe_v2, 1); > PyList_SetItem(edges, k, edge); // PyList_SetItem steals the reference > } > } > return edges; > } > } > > return EXPP_incr_ret( Py_None ); > } > > static PyObject *NMesh_removeFace( PyObject * self, PyObject * args ) > { > BPy_NMesh *nmesh=self; > > BPy_NMFace *face; > int totv=0; > > if (!PyArg_ParseTuple > ( args, "O!", &NMFace_Type, &face ) ) { > return EXPP_ReturnPyObjError( PyExc_TypeError, > "expected NMFace argument" ); > } > > totv=PyList_Size(face->v); > > { > int index=PySequence_Index(nmesh->faces, face); > if (index>=0) > PySequence_DelItem(nmesh->faces, index); > } > > if (nmesh->edges) > { > > if (totv>=2) > { > /* when totv==2, there is only one edge, when totv==3 there is three edges > * and when totv==4 there is four edges. > * that's why in the following line totv==2 is a special case */ > if (totv==2) > { > BPy_NMVert *fe_v1=PyList_GetItem(face->v, 0); > BPy_NMVert *fe_v2=PyList_GetItem(face->v, 1); > removeEdge(nmesh, fe_v1, fe_v2, 1); > } > else > { > int k; > for ( k = 0; k < totv; ++k ) > { > BPy_NMVert *fe_v1=PyList_GetItem(face->v, k ? k-1 : totv-1); > BPy_NMVert *fe_v2=PyList_GetItem(face->v, k); > removeEdge(nmesh, fe_v1, fe_v2, 1); > } > } > } > } > > return EXPP_incr_ret( Py_None ); > } > > > /* */ > > static PyObject *NMesh_printDebug( PyObject * self, PyObject * args ) > { > BPy_NMesh *bmesh=self; > > Mesh *mesh=bmesh->mesh; > > printf("**Vertices\n"); > { > int i; > for (i=0; itotvert; ++i) > { > MVert *v=mesh->mvert+i; > double x=v->co[0]; > double y=v->co[1]; > double z=v->co[2]; > printf(" %2d : %.3f %.3f %.3f\n", i, x, y, z); > } > } > > printf("**Edges\n"); > if (mesh->medge) > { > int i; > for (i=0; itotedge; ++i) > { > MEdge *e=mesh->medge+i; > int v1 = e->v1; > int v2 = e->v2; > int flag = e->flag; > printf(" %2d : %2d %2d flag=%d\n", i, v1, v2, flag); > } > } > else > printf(" No edge informations\n"); > > printf("**Faces\n"); > { > int i; > for (i=0; itotface; ++i) > { > MFace *e=((MFace*)(mesh->mface))+i; > int v1 = e->v1; > int v2 = e->v2; > int v3 = e->v3; > int v4 = e->v4; > printf(" %2d : %2d %2d %2d %2d\n", i, v1, v2, v3, v4); > } > } > > return EXPP_incr_ret( Py_None ); > } > > /* */ Index: NMesh.h =================================================================== RCS file: /cvsroot/bf-blender/blender/source/blender/python/api2_2x/NMesh.h,v retrieving revision 1.29 diff -r1.29 NMesh.h 54a55 > extern PyTypeObject NMEdge_Type; 73a75 > #define BPy_NMEdge_Check(v) ((v)->ob_type == &NMEdge_Type) 106a109,116 > PyObject_HEAD /* required python macro */ > PyObject *v1; > PyObject *v2; > char crease; > short flag; > } BPy_NMEdge; /* an NMesh edge */ > > typedef struct { 113a124 > PyObject *edges; 137c148 < Mesh *Mesh_fromNMesh( BPy_NMesh * nmesh ); --- > Mesh *Mesh_fromNMesh( BPy_NMesh * nmesh , int store_edges ); Index: doc/NMesh.py =================================================================== RCS file: /cvsroot/bf-blender/blender/source/blender/python/api2_2x/doc/NMesh.py,v retrieving revision 1.24 diff -r1.24 NMesh.py 68a69,73 > @var EdgeFlags: The available edge flags. > - SELECT - selected. > - EDGEDRAW - edge is drawn out of edition mode. > - SEAM - edge is a seam for LSCM UV unwrapping > - FGON - edge is part of a F-Gon. 142c147 < def PutRaw(nmesh, name = None, recalculate_normals = 1): --- > def PutRaw(nmesh, name = None, recalculate_normals = 1, store_edges = 0): 147a153 > @type store_edges: int 151a158 > @param store_edges: if non-zero, the edges data are stored 195a203,217 > class NMEdge: > """ > The NMEdge object > ================= > This object holds mesh edge data. > @type v1: NMVert > @cvar v1: The first vertex of the edge. > @type v2: NMVert > @cvar v2: The second vertex of the edge. > @type crease: int > @cvar crease: The crease value of the edge. It is in the range [0,255]. > @type flag: int > @cvar flag: The bitmask describing edge properties. See L{NMesh.EdgeFlags}. > """ > 266a289 > @cvar edges: None if mesh has no edge data, else a list of L{NMEdge} edges. Use L{addEdgesData} to create edge data if it do not exist. 271a295,353 > def addEdge(v1, v2): > """ > Create an edge between two vertices. > If an edge already exists between those vertices, it is returned. (in blender, only zero or one edge can link two vertices). > Created edge is automatically added to edges list. > You can only call this method if mesh has edge data. > @type v1: NMVert > @param v1: the first vertex of the edge. > @type v2: NMVert > @param v2: the second vertex of the edge. > @rtype: NMEdge > @return: The created or already existing edge. > """ > > def findEdge(v1, v2): > """ > Try to find an edge between two vertices. > If no edge exists between v1 and v2, None is returned. > You can only call this method if mesh has edge data. > @type v1: NMVert > @param v1: the first vertex of the edge. > @type v2: NMVert > @param v2: the second vertex of the edge. > @rtype: NMEdge > @return: The found edge. None if no edge was found. > """ > > def removeEdge(): > """ > remove an edge between two vertices. > All faces using this edge are removed from faces list. > You can only call this method if mesh has edge data. > @type v1: NMVert > @param v1: the first vertex of the edge. > @type v2: NMVert > @param v2: the second vertex of the edge. > """ > > def addFace(face): > """ > Add a face to face list and add to edge list (if edge data exists) necessary edges. > @type face: NMFace > @param face: the face to add to the mesh. > @rtype: list of NMEdge > @return: If mesh has edge data, return the list of face edges. > """ > > def removeFace(): > """ > Remove a face for face list and remove edges no more used by any other face (if edge data exists). > @type face: NMFace > @param face: the face to add to the mesh. > """ > > def addEdgesData(): > """ > If edge data does not exist for the mesh (ie L{edges}==None), then create them. > """ > 415c497 < def update(recalc_normals = 0): --- > def update(recalc_normals = 0, store_edges = 0): 422a505,506 > @type store_edges: int > @param store_edges: if not 0, then edge data are stored.