forked from bartvdbraak/blender
Code Cleanup: bmesh
* remove unneeded struct's from headers. * give argument names for return ** pointers r_ prefix.
This commit is contained in:
parent
94f171f2c6
commit
7536bcbe70
@ -345,7 +345,7 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface);
|
||||
* the nl member to a loop in the newly created edge.*/
|
||||
BMFace *BM_face_split(BMesh *bm, BMFace *f,
|
||||
BMVert *v1, BMVert *v2,
|
||||
BMLoop **nl, BMEdge *example);
|
||||
BMLoop **r_l, BMEdge *example);
|
||||
|
||||
/* these 2 functions are very similar */
|
||||
BMEdge* BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac,
|
||||
@ -355,14 +355,14 @@ BMEdge* BM_vert_collapse_edge(BMesh *bm, BMEdge *ke, BMVert *kv,
|
||||
|
||||
|
||||
/* splits an edge. ne is set to the new edge created. */
|
||||
BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **ne, float percent);
|
||||
BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float percent);
|
||||
|
||||
/* split an edge multiple times evenly */
|
||||
BMVert *BM_edge_split_n(BMesh *bm, BMEdge *e, int numcuts);
|
||||
|
||||
/* connect two verts together, through a face they share. this function may
|
||||
* be removed in the future. */
|
||||
BMEdge *BM_verts_connect(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **nf);
|
||||
BMEdge *BM_verts_connect(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **r_f);
|
||||
|
||||
/* rotates an edge topologically, either clockwise (if ccw=0) or counterclockwise
|
||||
* (if ccw is 1). */
|
||||
|
@ -73,7 +73,6 @@ extern "C" {
|
||||
* semantically similar to the iterator api in bmesh_iterators.h).
|
||||
*/
|
||||
|
||||
struct BMesh;
|
||||
struct GHashIterator;
|
||||
|
||||
#define BMO_elem_flag_test( bm, ele, oflag) _bmo_elem_flag_test (bm, (ele)->oflags, oflag)
|
||||
@ -173,19 +172,19 @@ typedef struct BMOpDefine {
|
||||
* have it set directly. and never use BMO_slot_ptr_set to
|
||||
* pass in a list of edges or any arrays, really.*/
|
||||
|
||||
void BMO_op_init(struct BMesh *bm, struct BMOperator *op, const char *opname);
|
||||
void BMO_op_init(BMesh *bm, BMOperator *op, const char *opname);
|
||||
|
||||
/* executes an operator, pushing and popping a new tool flag
|
||||
* layer as appropriate.*/
|
||||
void BMO_op_exec(struct BMesh *bm, struct BMOperator *op);
|
||||
void BMO_op_exec(BMesh *bm, BMOperator *op);
|
||||
|
||||
/* finishes an operator (though note the operator's tool flag is removed
|
||||
* after it finishes executing in BMO_op_exec).*/
|
||||
void BMO_op_finish(struct BMesh *bm, struct BMOperator *op);
|
||||
void BMO_op_finish(BMesh *bm, BMOperator *op);
|
||||
|
||||
/* count the number of elements with a specific flag.
|
||||
* type can be a bitmask of BM_FACE, BM_EDGE, or BM_FACE. */
|
||||
int BMO_mesh_flag_count(struct BMesh *bm, const short oflag, const char htype);
|
||||
int BMO_mesh_flag_count(BMesh *bm, const short oflag, const char htype);
|
||||
|
||||
/*---------formatted operator initialization/execution-----------*/
|
||||
/*
|
||||
@ -239,20 +238,20 @@ int BMO_op_initf(BMesh *bm, BMOperator *op, const char *fmt, ...);
|
||||
int BMO_op_vinitf(BMesh *bm, BMOperator *op, const char *fmt, va_list vlist);
|
||||
|
||||
/* test whether a named slot exists */
|
||||
int BMO_slot_exists(struct BMOperator *op, const char *slotname);
|
||||
int BMO_slot_exists(BMOperator *op, const char *slotname);
|
||||
|
||||
/* get a pointer to a slot. this may be removed layer on from the public API. */
|
||||
BMOpSlot *BMO_slot_get(struct BMOperator *op, const char *slotname);
|
||||
BMOpSlot *BMO_slot_get(BMOperator *op, const char *slotname);
|
||||
|
||||
/* copies the data of a slot from one operator to another. src and dst are the
|
||||
* source/destination slot codes, respectively. */
|
||||
void BMO_slot_copy(struct BMOperator *source_op, struct BMOperator *dest_op,
|
||||
void BMO_slot_copy(BMOperator *source_op, BMOperator *dest_op,
|
||||
const char *src, const char *dst);
|
||||
|
||||
/* remove tool flagged elements */
|
||||
void BMO_remove_tagged_faces(struct BMesh *bm, const short oflag);
|
||||
void BMO_remove_tagged_edges(struct BMesh *bm, const short oflag);
|
||||
void BMO_remove_tagged_verts(struct BMesh *bm, const short oflag);
|
||||
void BMO_remove_tagged_faces(BMesh *bm, const short oflag);
|
||||
void BMO_remove_tagged_edges(BMesh *bm, const short oflag);
|
||||
void BMO_remove_tagged_verts(BMesh *bm, const short oflag);
|
||||
|
||||
/* take care, uses operator flag DEL_WIREVERT */
|
||||
void BMO_remove_tagged_context(BMesh *bm, const short oflag, const int type);
|
||||
@ -268,14 +267,14 @@ enum {
|
||||
DEL_ONLYTAGGED
|
||||
};
|
||||
|
||||
void BMO_op_flag_enable(struct BMesh *bm, struct BMOperator *op, const int op_flag);
|
||||
void BMO_op_flag_disable(struct BMesh *bm, struct BMOperator *op, const int op_flag);
|
||||
void BMO_op_flag_enable(BMesh *bm, BMOperator *op, const int op_flag);
|
||||
void BMO_op_flag_disable(BMesh *bm, BMOperator *op, const int op_flag);
|
||||
|
||||
void BMO_slot_float_set(struct BMOperator *op, const char *slotname, const float f);
|
||||
void BMO_slot_float_set(BMOperator *op, const char *slotname, const float f);
|
||||
float BMO_slot_float_get(BMOperator *op, const char *slotname);
|
||||
void BMO_slot_int_set(struct BMOperator *op, const char *slotname, const int i);
|
||||
void BMO_slot_int_set(BMOperator *op, const char *slotname, const int i);
|
||||
int BMO_slot_int_get(BMOperator *op, const char *slotname);
|
||||
void BMO_slot_bool_set(struct BMOperator *op, const char *slotname, const int i);
|
||||
void BMO_slot_bool_set(BMOperator *op, const char *slotname, const int i);
|
||||
int BMO_slot_bool_get(BMOperator *op, const char *slotname);
|
||||
|
||||
/* don't pass in arrays that are supposed to map to elements this way.
|
||||
@ -283,49 +282,49 @@ int BMO_slot_bool_get(BMOperator *op, const char *slotname);
|
||||
* so, e.g. passing in list of floats per element in another slot is bad.
|
||||
* passing in, e.g. pointer to an editmesh for the conversion operator is fine
|
||||
* though. */
|
||||
void BMO_slot_ptr_set(struct BMOperator *op, const char *slotname, void *p);
|
||||
void BMO_slot_ptr_set(BMOperator *op, const char *slotname, void *p);
|
||||
void *BMO_slot_ptr_get(BMOperator *op, const char *slotname);
|
||||
void BMO_slot_vec_set(struct BMOperator *op, const char *slotname, const float vec[3]);
|
||||
void BMO_slot_vec_set(BMOperator *op, const char *slotname, const float vec[3]);
|
||||
void BMO_slot_vec_get(BMOperator *op, const char *slotname, float r_vec[3]);
|
||||
|
||||
/* only supports square mats */
|
||||
/* size must be 3 or 4; this api is meant only for transformation matrices.
|
||||
* note that internally the matrix is stored in 4x4 form, and it's safe to
|
||||
* call whichever BMO_Get_Mat* function you want. */
|
||||
void BMO_slot_mat_set(struct BMOperator *op, const char *slotname, const float *mat, int size);
|
||||
void BMO_slot_mat4_get(struct BMOperator *op, const char *slotname, float r_mat[4][4]);
|
||||
void BMO_slot_mat3_set(struct BMOperator *op, const char *slotname, float r_mat[3][3]);
|
||||
void BMO_slot_mat_set(BMOperator *op, const char *slotname, const float *mat, int size);
|
||||
void BMO_slot_mat4_get(BMOperator *op, const char *slotname, float r_mat[4][4]);
|
||||
void BMO_slot_mat3_set(BMOperator *op, const char *slotname, float r_mat[3][3]);
|
||||
|
||||
void BMO_mesh_flag_disable_all(BMesh *bm, BMOperator *op, const char htype, const short oflag);
|
||||
|
||||
/* puts every element of type type (which is a bitmask) with tool flag flag,
|
||||
* into a slot. */
|
||||
void BMO_slot_from_flag(struct BMesh *bm, struct BMOperator *op, const char *slotname,
|
||||
void BMO_slot_from_flag(BMesh *bm, BMOperator *op, const char *slotname,
|
||||
const short oflag, const char htype);
|
||||
|
||||
/* tool-flags all elements inside an element slot array with flag flag. */
|
||||
void BMO_slot_buffer_flag_enable(struct BMesh *bm, struct BMOperator *op, const char *slotname,
|
||||
void BMO_slot_buffer_flag_enable(BMesh *bm, BMOperator *op, const char *slotname,
|
||||
const short oflag, const char htype);
|
||||
/* clears tool-flag flag from all elements inside a slot array. */
|
||||
void BMO_slot_buffer_flag_disable(struct BMesh *bm, struct BMOperator *op, const char *slotname,
|
||||
void BMO_slot_buffer_flag_disable(BMesh *bm, BMOperator *op, const char *slotname,
|
||||
const short oflag, const char htype);
|
||||
|
||||
/* tool-flags all elements inside an element slot array with flag flag. */
|
||||
void BMO_slot_buffer_hflag_enable(struct BMesh *bm, struct BMOperator *op, const char *slotname,
|
||||
void BMO_slot_buffer_hflag_enable(BMesh *bm, BMOperator *op, const char *slotname,
|
||||
const char hflag, const char htype, char do_flush_select);
|
||||
/* clears tool-flag flag from all elements inside a slot array. */
|
||||
void BMO_slot_buffer_hflag_disable(struct BMesh *bm, struct BMOperator *op, const char *slotname,
|
||||
void BMO_slot_buffer_hflag_disable(BMesh *bm, BMOperator *op, const char *slotname,
|
||||
const char hflag, const char htype, char do_flush_select);
|
||||
|
||||
/* puts every element of type type (which is a bitmask) with header flag
|
||||
* flag, into a slot. note: ignores hidden elements (e.g. elements with
|
||||
* header flag BM_ELEM_HIDDEN set).*/
|
||||
void BMO_slot_from_hflag(struct BMesh *bm, struct BMOperator *op, const char *slotname,
|
||||
void BMO_slot_from_hflag(BMesh *bm, BMOperator *op, const char *slotname,
|
||||
const char hflag, const char htype);
|
||||
|
||||
/* counts number of elements inside a slot array. */
|
||||
int BMO_slot_buf_count(struct BMesh *bm, struct BMOperator *op, const char *slotname);
|
||||
int BMO_slot_map_count(struct BMesh *bm, struct BMOperator *op, const char *slotname);
|
||||
int BMO_slot_buf_count(BMesh *bm, BMOperator *op, const char *slotname);
|
||||
int BMO_slot_map_count(BMesh *bm, BMOperator *op, const char *slotname);
|
||||
|
||||
void BMO_slot_map_insert(BMesh *UNUSED(bm), BMOperator *op, const char *slotname,
|
||||
void *element, void *data, int len);
|
||||
@ -336,7 +335,7 @@ int BMO_vert_edge_flags_count(BMesh *bm, BMVert *v, const short oflag);
|
||||
|
||||
/* flags all elements in a mapping. note that the mapping must only have
|
||||
* bmesh elements in it.*/
|
||||
void BMO_slot_map_to_flag(struct BMesh *bm, struct BMOperator *op,
|
||||
void BMO_slot_map_to_flag(BMesh *bm, BMOperator *op,
|
||||
const char *slotname, const short oflag);
|
||||
|
||||
/* this part of the API is used to iterate over element buffer or
|
||||
@ -375,7 +374,7 @@ void BMO_slot_map_to_flag(struct BMesh *bm, struct BMOperator *op,
|
||||
typedef struct BMOIter {
|
||||
BMOpSlot *slot;
|
||||
int cur; //for arrays
|
||||
struct GHashIterator giter;
|
||||
GHashIterator giter;
|
||||
void *val;
|
||||
char restrictmask; /* bitwise '&' with BMHeader.htype */
|
||||
} BMOIter;
|
||||
@ -404,7 +403,7 @@ float BMO_iter_map_value_f(BMOIter *iter);
|
||||
for ( ; ele; ele=BMO_iter_step(iter))
|
||||
|
||||
/******************* Inlined Functions********************/
|
||||
typedef void (*opexec)(struct BMesh *bm, struct BMOperator *op);
|
||||
typedef void (*opexec)(BMesh *bm, BMOperator *op);
|
||||
|
||||
/* mappings map elements to data, which
|
||||
* follows the mapping struct in memory. */
|
||||
|
@ -32,93 +32,93 @@
|
||||
/* Queries */
|
||||
|
||||
/* counts number of elements of type type are in the mesh. */
|
||||
int BM_mesh_elem_count(struct BMesh *bm, const char htype);
|
||||
int BM_mesh_elem_count(BMesh *bm, const char htype);
|
||||
|
||||
/*returns true if v is in f*/
|
||||
int BM_vert_in_face(struct BMFace *f, struct BMVert *v);
|
||||
int BM_vert_in_face(BMFace *f, BMVert *v);
|
||||
|
||||
// int BM_verts_in_face(struct BMFace *f, struct BMVert **varr, int len);
|
||||
int BM_verts_in_face(struct BMesh *bm, struct BMFace *f, struct BMVert **varr, int len);
|
||||
// int BM_verts_in_face(BMFace *f, BMVert **varr, int len);
|
||||
int BM_verts_in_face(BMesh *bm, BMFace *f, BMVert **varr, int len);
|
||||
|
||||
int BM_edge_in_face(struct BMFace *f, struct BMEdge *e);
|
||||
int BM_edge_in_face(BMFace *f, BMEdge *e);
|
||||
|
||||
int BM_vert_in_edge(struct BMEdge *e, struct BMVert *v);
|
||||
int BM_vert_in_edge(BMEdge *e, BMVert *v);
|
||||
|
||||
int BM_verts_in_edge(struct BMVert *v1, struct BMVert *v2, struct BMEdge *e);
|
||||
int BM_verts_in_edge(BMVert *v1, BMVert *v2, BMEdge *e);
|
||||
|
||||
/*get opposing vert from v in edge e.*/
|
||||
struct BMVert *BM_edge_other_vert(struct BMEdge *e, struct BMVert *v);
|
||||
BMVert *BM_edge_other_vert(BMEdge *e, BMVert *v);
|
||||
|
||||
/*finds other loop that shares v with e's loop in f.*/
|
||||
struct BMLoop *BM_face_other_loop(BMEdge *e, BMFace *f, BMVert *v);
|
||||
BMLoop *BM_face_other_loop(BMEdge *e, BMFace *f, BMVert *v);
|
||||
|
||||
/*returns the edge existing between v1 and v2, or NULL if there isn't one.*/
|
||||
struct BMEdge *BM_edge_exists(struct BMVert *v1, struct BMVert *v2);
|
||||
BMEdge *BM_edge_exists(BMVert *v1, BMVert *v2);
|
||||
|
||||
|
||||
/*returns number of edges aroudn a vert*/
|
||||
int BM_vert_edge_count(struct BMVert *v);
|
||||
int BM_vert_edge_count(BMVert *v);
|
||||
|
||||
/*returns number of faces around an edge*/
|
||||
int BM_edge_face_count(struct BMEdge *e);
|
||||
int BM_edge_face_count(BMEdge *e);
|
||||
|
||||
/*returns number of faces around a vert.*/
|
||||
int BM_vert_face_count(struct BMVert *v);
|
||||
int BM_vert_face_count(BMVert *v);
|
||||
|
||||
|
||||
/*returns true if v is a wire vert*/
|
||||
int BM_vert_is_wire(struct BMesh *bm, struct BMVert *v);
|
||||
int BM_vert_is_wire(BMesh *bm, BMVert *v);
|
||||
|
||||
/*returns true if e is a wire edge*/
|
||||
int BM_edge_is_wire(struct BMesh *bm, struct BMEdge *e);
|
||||
int BM_edge_is_wire(BMesh *bm, BMEdge *e);
|
||||
|
||||
/* returns FALSE if v is part of a non-manifold edge in the mesh,
|
||||
* I believe this includes if it's part of both a wire edge and
|
||||
* a face.*/
|
||||
int BM_vert_is_manifold(struct BMesh *bm, struct BMVert *v);
|
||||
int BM_vert_is_manifold(BMesh *bm, BMVert *v);
|
||||
|
||||
/* returns FALSE if e is shared by more then two faces. */
|
||||
int BM_edge_is_manifold(struct BMesh *bm, struct BMEdge *e);
|
||||
int BM_edge_is_manifold(BMesh *bm, BMEdge *e);
|
||||
|
||||
/* returns true if e is a boundary edge, e.g. has only 1 face bordering it. */
|
||||
int BM_edge_is_boundary(struct BMEdge *e);
|
||||
int BM_edge_is_boundary(BMEdge *e);
|
||||
|
||||
/* returns the face corner angle */
|
||||
float BM_loop_face_angle(struct BMesh *bm, struct BMLoop *l);
|
||||
float BM_loop_face_angle(BMesh *bm, BMLoop *l);
|
||||
|
||||
/* returns angle of two faces surrounding an edge. note there must be
|
||||
* exactly two faces sharing the edge.*/
|
||||
float BM_edge_face_angle(struct BMesh *bm, struct BMEdge *e);
|
||||
float BM_edge_face_angle(BMesh *bm, BMEdge *e);
|
||||
|
||||
/* returns angle of two faces surrounding edges. note there must be
|
||||
* exactly two edges sharing the vertex.*/
|
||||
float BM_vert_edge_angle(struct BMesh *bm, struct BMVert *v);
|
||||
float BM_vert_edge_angle(BMesh *bm, BMVert *v);
|
||||
|
||||
/* checks overlapping of existing faces with the verts in varr. */
|
||||
int BM_face_exists_overlap(struct BMesh *bm, struct BMVert **varr, int len, struct BMFace **r_existface,
|
||||
int BM_face_exists_overlap(BMesh *bm, BMVert **varr, int len, BMFace **r_existface,
|
||||
const short do_partial);
|
||||
|
||||
/* checks if many existing faces overlap the faces defined by varr */
|
||||
int BM_face_exists_multi(BMesh *bm, struct BMVert **varr, struct BMEdge **earr, int len);
|
||||
int BM_face_exists_multi(BMesh *bm, BMVert **varr, BMEdge **earr, int len);
|
||||
int BM_face_exists_multi_edge(BMesh *bm, BMEdge **earr, int len);
|
||||
|
||||
/* checks if a face defined by varr already exists. */
|
||||
int BM_face_exists(BMesh *bm, BMVert **varr, int len, BMFace **existface);
|
||||
int BM_face_exists(BMesh *bm, BMVert **varr, int len, BMFace **r_existface);
|
||||
|
||||
|
||||
/* returns number of edges f1 and f2 share. */
|
||||
int BM_face_share_edge_count(struct BMFace *f1, struct BMFace *f2);
|
||||
int BM_face_share_edge_count(BMFace *f1, BMFace *f2);
|
||||
|
||||
/* returns number of faces e1 and e2 share. */
|
||||
int BM_edge_share_face_count(struct BMEdge *e1, struct BMEdge *e2);
|
||||
int BM_edge_share_face_count(BMEdge *e1, BMEdge *e2);
|
||||
|
||||
/* returns bool 1/0 if the edges share a vertex */
|
||||
int BM_edge_share_vert_count(struct BMEdge *e1, struct BMEdge *e2);
|
||||
int BM_edge_share_vert_count(BMEdge *e1, BMEdge *e2);
|
||||
|
||||
BMVert *BM_edge_share_vert(struct BMEdge *e1, struct BMEdge *e2);
|
||||
BMVert *BM_edge_share_vert(BMEdge *e1, BMEdge *e2);
|
||||
|
||||
/* edge verts in winding order from face */
|
||||
void BM_edge_ordered_verts(struct BMEdge *edge, struct BMVert **r_v1, struct BMVert **r_v2);
|
||||
void BM_edge_ordered_verts(BMEdge *edge, BMVert **r_v1, BMVert **r_v2);
|
||||
|
||||
/* checks if a face is valid in the data structure */
|
||||
int BM_face_validate(BMesh *bm, BMFace *face, FILE *err);
|
||||
|
@ -147,8 +147,8 @@ void BM_face_copy_shared(BMesh *bm, BMFace *f)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* BMESH MAKE NGON
|
||||
/**
|
||||
* \brief BMESH MAKE NGON
|
||||
*
|
||||
* Attempts to make a new Ngon from a list of edges.
|
||||
* If nodouble equals one, a check for overlaps or existing
|
||||
@ -165,11 +165,11 @@ BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, i
|
||||
{
|
||||
BMEdge **edges2 = NULL;
|
||||
BLI_array_staticdeclare(edges2, BM_NGON_STACK_SIZE);
|
||||
BMVert **verts = NULL, *v;
|
||||
BMVert **verts = NULL;
|
||||
BLI_array_staticdeclare(verts, BM_NGON_STACK_SIZE);
|
||||
BMFace *f = NULL;
|
||||
BMEdge *e;
|
||||
BMVert *ev1, *ev2;
|
||||
BMVert *v, *ev1, *ev2;
|
||||
int i, /* j, */ v1found, reverse;
|
||||
|
||||
/* this code is hideous, yeek. I'll have to think about ways of
|
||||
|
@ -257,7 +257,8 @@ BMFace *BM_faces_join_pair(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e)
|
||||
return f1;
|
||||
}
|
||||
|
||||
/* connects two verts together, automatically (if very naively) finding the
|
||||
/**
|
||||
* connects two verts together, automatically (if very naively) finding the
|
||||
* face they both share (if there is one) and splittling it. use this at your
|
||||
* own risk, as it doesn't handle the many complex cases it should (like zero-area faces,
|
||||
* multiple faces, etc).
|
||||
@ -266,47 +267,43 @@ BMFace *BM_faces_join_pair(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e)
|
||||
* the two verts belong to for splitting (e.g. the subdivision operator).
|
||||
*/
|
||||
|
||||
BMEdge *BM_verts_connect(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **nf)
|
||||
BMEdge *BM_verts_connect(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **r_f)
|
||||
{
|
||||
BMIter iter, iter2;
|
||||
BMVert *v;
|
||||
BMLoop *nl;
|
||||
BMFace *face;
|
||||
BMFace *f;
|
||||
|
||||
/* be warned: this can do weird things in some ngon situation, see BM_face_legal_splits */
|
||||
for (face = BM_iter_new(&iter, bm, BM_FACES_OF_VERT, v1); face; face = BM_iter_step(&iter)) {
|
||||
for (v = BM_iter_new(&iter2, bm, BM_VERTS_OF_FACE, face); v; v = BM_iter_step(&iter2)) {
|
||||
for (f = BM_iter_new(&iter, bm, BM_FACES_OF_VERT, v1); f; f = BM_iter_step(&iter)) {
|
||||
for (v = BM_iter_new(&iter2, bm, BM_VERTS_OF_FACE, f); v; v = BM_iter_step(&iter2)) {
|
||||
if (v == v2) {
|
||||
face = BM_face_split(bm, face, v1, v2, &nl, NULL);
|
||||
f = BM_face_split(bm, f, v1, v2, &nl, NULL);
|
||||
|
||||
if (nf) *nf = face;
|
||||
if (r_f) *r_f = f;
|
||||
return nl->e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (r_f) *r_f = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* BM_face_split
|
||||
* Splits a single face into two.
|
||||
*
|
||||
* Splits a single face into two.
|
||||
* \param the original face
|
||||
* \param v1,v2 vertices which define the split edge, must be different
|
||||
* \param r_l pointer which will receive the BMLoop for the split edge in the new face
|
||||
*
|
||||
* f - the original face
|
||||
* v1 & v2 - vertices which define the split edge, must be different
|
||||
* nl - pointer which will receive the BMLoop for the split edge in the new face
|
||||
*
|
||||
* Notes: the
|
||||
|
||||
* Returns -
|
||||
* Pointer to the newly created face representing one side of the split
|
||||
* if the split is successful (and the original original face will be the
|
||||
* other side). NULL if the split fails.
|
||||
*
|
||||
* \return Pointer to the newly created face representing one side of the split
|
||||
* if the split is successful (and the original original face will be the
|
||||
* other side). NULL if the split fails.
|
||||
*/
|
||||
|
||||
BMFace *BM_face_split(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMLoop **nl, BMEdge *example)
|
||||
BMFace *BM_face_split(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMLoop **r_l, BMEdge *example)
|
||||
{
|
||||
const int has_mdisp = CustomData_has_layer(&bm->ldata, CD_MDISPS);
|
||||
BMFace *nf, *of;
|
||||
@ -319,9 +316,9 @@ BMFace *BM_face_split(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMLoop **nl,
|
||||
}
|
||||
|
||||
#ifdef USE_BMESH_HOLES
|
||||
nf = bmesh_sfme(bm, f, v1, v2, nl, NULL, example);
|
||||
nf = bmesh_sfme(bm, f, v1, v2, r_l, NULL, example);
|
||||
#else
|
||||
nf = bmesh_sfme(bm, f, v1, v2, nl, example);
|
||||
nf = bmesh_sfme(bm, f, v1, v2, r_l, example);
|
||||
#endif
|
||||
|
||||
if (nf) {
|
||||
@ -357,26 +354,24 @@ BMFace *BM_face_split(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMLoop **nl,
|
||||
}
|
||||
|
||||
/**
|
||||
* BM_vert_collapse_faces
|
||||
* Collapses a vertex that has only two manifold edges
|
||||
* onto a vertex it shares an edge with. Fac defines
|
||||
* the amount of interpolation for Custom Data.
|
||||
*
|
||||
* Collapses a vertex that has only two manifold edges
|
||||
* onto a vertex it shares an edge with. Fac defines
|
||||
* the amount of interpolation for Custom Data.
|
||||
* \note that this is not a general edge collapse function.
|
||||
*
|
||||
* Note that this is not a general edge collapse function.
|
||||
*
|
||||
* Note this function is very close to 'BM_vert_collapse_edge', both collapse
|
||||
* \note this function is very close to #BM_vert_collapse_edge, both collapse
|
||||
* a vertex and return a new edge. Except this takes a factor and merges
|
||||
* custom data.
|
||||
*
|
||||
* BMESH_TODO:
|
||||
* Insert error checking for KV valance.
|
||||
*
|
||||
* @param fac The factor along the edge
|
||||
* @param join_faces When true the faces around the vertex will be joined
|
||||
* \param fac The factor along the edge
|
||||
* \param join_faces When true the faces around the vertex will be joined
|
||||
* otherwise collapse the vertex by merging the 2 edges this vert touches into one.
|
||||
* @param kill_degenerate_faces Removes faces with less than 3 verts after collapsing.
|
||||
* @returns The New Edge
|
||||
* \param kill_degenerate_faces Removes faces with less than 3 verts after collapsing.
|
||||
* \returns The New Edge
|
||||
*/
|
||||
|
||||
BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac,
|
||||
@ -423,7 +418,8 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac,
|
||||
tv2 = BM_edge_other_vert(e2, kv);
|
||||
|
||||
if (join_faces) {
|
||||
BMFace **faces = NULL, *f;
|
||||
BMFace **faces = NULL;
|
||||
BMFace *f;
|
||||
BLI_array_staticdeclare(faces, 8);
|
||||
|
||||
BM_ITER(f, &iter, bm, BM_FACES_OF_VERT, kv) {
|
||||
@ -524,17 +520,18 @@ BMEdge *BM_vert_collapse_edge(BMesh *bm, BMEdge *ke, BMVert *kv,
|
||||
* the new vert
|
||||
*/
|
||||
|
||||
BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **ne, float percent)
|
||||
BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float percent)
|
||||
{
|
||||
BMVert *nv, *v2;
|
||||
BMFace **oldfaces = NULL;
|
||||
BMEdge *dummy;
|
||||
BMEdge *e_dummy;
|
||||
BLI_array_staticdeclare(oldfaces, 32);
|
||||
SmallHash hash;
|
||||
|
||||
/* we need this for handling multire */
|
||||
if (!ne)
|
||||
ne = &dummy;
|
||||
if (!r_e) {
|
||||
r_e = &e_dummy;
|
||||
}
|
||||
|
||||
/* do we have a multires layer */
|
||||
if (CustomData_has_layer(&bm->ldata, CD_MDISPS) && e->l) {
|
||||
@ -557,7 +554,7 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **ne, float percen
|
||||
}
|
||||
|
||||
v2 = bmesh_edge_other_vert_get(e, v);
|
||||
nv = bmesh_semv(bm, v, e, ne);
|
||||
nv = bmesh_semv(bm, v, e, r_e);
|
||||
if (nv == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@ -565,9 +562,9 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **ne, float percen
|
||||
sub_v3_v3v3(nv->co, v2->co, v->co);
|
||||
madd_v3_v3v3fl(nv->co, v->co, nv->co, percent);
|
||||
|
||||
if (ne) {
|
||||
(*ne)->head.hflag = e->head.hflag;
|
||||
BM_elem_attrs_copy(bm, bm, e, *ne);
|
||||
if (r_e) {
|
||||
(*r_e)->head.hflag = e->head.hflag;
|
||||
BM_elem_attrs_copy(bm, bm, e, *r_e);
|
||||
}
|
||||
|
||||
/* v->nv->v2 */
|
||||
@ -580,7 +577,7 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **ne, float percen
|
||||
/* interpolate new/changed loop data from copied old face */
|
||||
for (j = 0; j < 2; j++) {
|
||||
for (i = 0; i < BLI_array_count(oldfaces); i++) {
|
||||
BMEdge *e1 = j ? *ne : e;
|
||||
BMEdge *e1 = j ? *r_e : e;
|
||||
BMLoop *l, *l2;
|
||||
|
||||
l = e1->l;
|
||||
@ -612,7 +609,7 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **ne, float percen
|
||||
/* fix boundaries a bit, doesn't work too well quite ye */
|
||||
#if 0
|
||||
for (j = 0; j < 2; j++) {
|
||||
BMEdge *e1 = j ? *ne : e;
|
||||
BMEdge *e1 = j ? *r_e : e;
|
||||
BMLoop *l, *l2;
|
||||
|
||||
l = e1->l;
|
||||
|
@ -36,9 +36,6 @@
|
||||
* parts of the bmesh internals.
|
||||
*/
|
||||
|
||||
struct Link;
|
||||
struct BMLoop;
|
||||
|
||||
/* returns positive nonzero on error */
|
||||
int bmesh_elem_check(BMesh *bm, void *element, const char htype);
|
||||
|
||||
@ -56,11 +53,11 @@ int bmesh_elem_check(BMesh *bm, void *element, const char htype);
|
||||
&((e)->v2_disk_link) \
|
||||
)
|
||||
|
||||
int bmesh_radial_length(struct BMLoop *l);
|
||||
int bmesh_radial_length(BMLoop *l);
|
||||
int bmesh_disk_count(BMVert *v);
|
||||
|
||||
/* internal selection flushing */
|
||||
void bmesh_selectmode_flush(struct BMesh *bm);
|
||||
void bmesh_selectmode_flush(BMesh *bm);
|
||||
|
||||
/*internal filter API*/
|
||||
void *bmesh_get_filter_callback(int type);
|
||||
@ -79,14 +76,14 @@ int bmesh_get_filter_argtype(int type);
|
||||
/* newedgeflag sets a flag layer flag, obviously not the header flag. */
|
||||
void BM_face_triangulate(BMesh *bm, BMFace *f, float (*projectverts)[3],
|
||||
const short newedge_oflag, const short newface_oflag, BMFace **newfaces);
|
||||
void bmesh_face_normal_update(struct BMesh *bm, struct BMFace *f, float no[3],
|
||||
void bmesh_face_normal_update(BMesh *bm, BMFace *f, float no[3],
|
||||
float (*projectverts)[3]);
|
||||
void bmesh_face_normal_update_vertex_cos(struct BMesh *bm, struct BMFace *f, float no[3],
|
||||
void bmesh_face_normal_update_vertex_cos(BMesh *bm, BMFace *f, float no[3],
|
||||
float (*projectverts)[3], float (*vertexCos)[3]);
|
||||
|
||||
void compute_poly_plane(float (*verts)[3], int nverts);
|
||||
void poly_rotate_plane(const float normal[3], float (*verts)[3], const int nverts);
|
||||
void bmesh_flip_normal(struct BMesh *bm, struct BMFace *f);
|
||||
void bmesh_flip_normal(BMesh *bm, BMFace *f);
|
||||
|
||||
BMEdge *bmesh_disk_next(BMEdge *e, BMVert *v);
|
||||
BMEdge *bmesh_disk_prev(BMEdge *e, BMVert *v);
|
||||
|
@ -600,13 +600,12 @@ float BM_edge_face_angle(BMesh *UNUSED(bm), BMEdge *e)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* BMESH FACE ANGLE
|
||||
/**
|
||||
* BMESH FACE ANGLE
|
||||
*
|
||||
* Calculates the angle a verts 2 edges.
|
||||
*
|
||||
* Returns -
|
||||
* Float.
|
||||
* \returns the angle in radians
|
||||
*/
|
||||
float BM_vert_edge_angle(BMesh *UNUSED(bm), BMVert *v)
|
||||
{
|
||||
@ -630,16 +629,15 @@ float BM_vert_edge_angle(BMesh *UNUSED(bm), BMVert *v)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* BMESH EXIST FACE OVERLAPS
|
||||
*
|
||||
* Given a set of vertices (varr), find out if
|
||||
* all those vertices overlap an existing face.
|
||||
*
|
||||
* Returns:
|
||||
* 0 for no overlap
|
||||
* 1 for overlap
|
||||
*
|
||||
* \param do_partial When TRUE the overlapping face
|
||||
* can be a different length to the one given
|
||||
* \returns TRUE for overlap
|
||||
*
|
||||
*/
|
||||
int BM_face_exists_overlap(BMesh *bm, BMVert **varr, int len, BMFace **r_overlapface,
|
||||
@ -654,9 +652,7 @@ int BM_face_exists_overlap(BMesh *bm, BMVert **varr, int len, BMFace **r_overlap
|
||||
while (f) {
|
||||
amount = BM_verts_in_face(bm, f, varr, len);
|
||||
if ((amount >= len) && (do_partial == TRUE || len == f->len)) {
|
||||
if (r_overlapface) {
|
||||
*r_overlapface = f;
|
||||
}
|
||||
if (r_overlapface) *r_overlapface = f;
|
||||
return TRUE;
|
||||
}
|
||||
f = BM_iter_step(&vertfaces);
|
||||
@ -839,24 +835,28 @@ int BM_face_exists_multi_edge(BMesh *bm, BMEdge **earr, int len)
|
||||
* 1 for face found
|
||||
*/
|
||||
|
||||
int BM_face_exists(BMesh *bm, BMVert **varr, int len, BMFace **existface)
|
||||
int BM_face_exists(BMesh *bm, BMVert **varr, int len, BMFace **r_existface)
|
||||
{
|
||||
BMIter vertfaces;
|
||||
BMFace *f;
|
||||
int i, amount;
|
||||
|
||||
if (existface) *existface = NULL;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
f = BM_iter_new(&vertfaces, bm, BM_FACES_OF_VERT, varr[i]);
|
||||
while (f) {
|
||||
amount = BM_verts_in_face(bm, f, varr, len);
|
||||
if (amount == len && amount == f->len) {
|
||||
if (existface) *existface = f;
|
||||
if (r_existface) {
|
||||
*r_existface = f;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
f = BM_iter_step(&vertfaces);
|
||||
}
|
||||
}
|
||||
|
||||
if (r_existface) {
|
||||
*r_existface = NULL;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -187,7 +187,7 @@ void EDBM_free_data_layer(struct BMEditMesh *em, struct CustomData *data, int t
|
||||
void EDBM_select_swap(struct BMEditMesh *em); /* exported for UV */
|
||||
|
||||
int EDBM_texFaceCheck(struct BMEditMesh *em);
|
||||
struct MTexPoly *EDBM_get_active_mtexpoly(struct BMEditMesh *em, struct BMFace **act_efa, int sloppy);
|
||||
struct MTexPoly *EDBM_get_active_mtexpoly(struct BMEditMesh *em, struct BMFace **r_act_efa, int sloppy);
|
||||
|
||||
void EDBM_free_uv_vert_map(struct UvVertMap *vmap);
|
||||
struct UvMapVert *EDBM_get_uv_map_vert(struct UvVertMap *vmap, unsigned int v);
|
||||
|
@ -630,36 +630,36 @@ BMFace *EDBM_findnearestface(ViewContext *vc, int *dist)
|
||||
selected vertices and edges get disadvantage
|
||||
return 1 if found one
|
||||
*/
|
||||
static int unified_findnearest(ViewContext *vc, BMVert **eve, BMEdge **eed, BMFace **efa)
|
||||
static int unified_findnearest(ViewContext *vc, BMVert **r_eve, BMEdge **r_eed, BMFace **r_efa)
|
||||
{
|
||||
BMEditMesh *em = vc->em;
|
||||
int dist = 75;
|
||||
|
||||
*eve = NULL;
|
||||
*eed = NULL;
|
||||
*efa = NULL;
|
||||
*r_eve = NULL;
|
||||
*r_eed = NULL;
|
||||
*r_efa = NULL;
|
||||
|
||||
/* no afterqueue (yet), so we check it now, otherwise the em_xxxofs indices are bad */
|
||||
view3d_validate_backbuf(vc);
|
||||
|
||||
if (em->selectmode & SCE_SELECT_VERTEX)
|
||||
*eve = EDBM_findnearestvert(vc, &dist, BM_ELEM_SELECT, 0);
|
||||
*r_eve = EDBM_findnearestvert(vc, &dist, BM_ELEM_SELECT, 0);
|
||||
if (em->selectmode & SCE_SELECT_FACE)
|
||||
*efa = EDBM_findnearestface(vc, &dist);
|
||||
*r_efa = EDBM_findnearestface(vc, &dist);
|
||||
|
||||
dist-= 20; /* since edges select lines, we give dots advantage of 20 pix */
|
||||
if (em->selectmode & SCE_SELECT_EDGE)
|
||||
*eed = EDBM_findnearestedge(vc, &dist);
|
||||
*r_eed = EDBM_findnearestedge(vc, &dist);
|
||||
|
||||
/* return only one of 3 pointers, for frontbuffer redraws */
|
||||
if (*eed) {
|
||||
*efa = NULL; *eve = NULL;
|
||||
if (*r_eed) {
|
||||
*r_efa = NULL; *r_eve = NULL;
|
||||
}
|
||||
else if (*efa) {
|
||||
*eve = NULL;
|
||||
else if (*r_efa) {
|
||||
*r_eve = NULL;
|
||||
}
|
||||
|
||||
return (*eve || *eed || *efa);
|
||||
return (*r_eve || *r_eed || *r_efa);
|
||||
}
|
||||
|
||||
/* **************** SIMILAR "group" SELECTS. FACE, EDGE AND VERTEX ************** */
|
||||
@ -2064,7 +2064,7 @@ static void walker_deselect_nth(BMEditMesh *em, int nth, int offset, BMHeader *h
|
||||
EDBM_selectmode_flush_ex(em, flushtype);
|
||||
}
|
||||
|
||||
static void deselect_nth_active(BMEditMesh *em, BMVert **v_p, BMEdge **e_p, BMFace **f_p)
|
||||
static void deselect_nth_active(BMEditMesh *em, BMVert **r_eve, BMEdge **r_eed, BMFace **r_efa)
|
||||
{
|
||||
BMVert *v;
|
||||
BMEdge *e;
|
||||
@ -2072,9 +2072,9 @@ static void deselect_nth_active(BMEditMesh *em, BMVert **v_p, BMEdge **e_p, BMFa
|
||||
BMIter iter;
|
||||
BMEditSelection *ese;
|
||||
|
||||
*v_p = NULL;
|
||||
*e_p = NULL;
|
||||
*f_p = NULL;
|
||||
*r_eve = NULL;
|
||||
*r_eed = NULL;
|
||||
*r_efa = NULL;
|
||||
|
||||
EDBM_selectmode_flush(em);
|
||||
ese = (BMEditSelection *)em->bm->selected.last;
|
||||
@ -2082,13 +2082,13 @@ static void deselect_nth_active(BMEditMesh *em, BMVert **v_p, BMEdge **e_p, BMFa
|
||||
if (ese) {
|
||||
switch(ese->htype) {
|
||||
case BM_VERT:
|
||||
*v_p = (BMVert *)ese->ele;
|
||||
*r_eve = (BMVert *)ese->ele;
|
||||
return;
|
||||
case BM_EDGE:
|
||||
*e_p = (BMEdge *)ese->ele;
|
||||
*r_eed = (BMEdge *)ese->ele;
|
||||
return;
|
||||
case BM_FACE:
|
||||
*f_p = (BMFace *)ese->ele;
|
||||
*r_efa = (BMFace *)ese->ele;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -2096,7 +2096,7 @@ static void deselect_nth_active(BMEditMesh *em, BMVert **v_p, BMEdge **e_p, BMFa
|
||||
if (em->selectmode & SCE_SELECT_VERTEX) {
|
||||
BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
|
||||
if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
|
||||
*v_p = v;
|
||||
*r_eve = v;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -2104,7 +2104,7 @@ static void deselect_nth_active(BMEditMesh *em, BMVert **v_p, BMEdge **e_p, BMFa
|
||||
else if (em->selectmode & SCE_SELECT_EDGE) {
|
||||
BM_ITER(e, &iter, em->bm, BM_EDGES_OF_MESH, NULL) {
|
||||
if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
|
||||
*e_p = e;
|
||||
*r_eed = e;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -2112,7 +2112,7 @@ static void deselect_nth_active(BMEditMesh *em, BMVert **v_p, BMEdge **e_p, BMFa
|
||||
else if (em->selectmode & SCE_SELECT_FACE) {
|
||||
f = BM_active_face_get(em->bm, TRUE);
|
||||
if (f) {
|
||||
*f_p = f;
|
||||
*r_efa = f;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -2570,12 +2570,13 @@ void MESH_OT_region_to_loop(wmOperatorType *ot)
|
||||
}
|
||||
|
||||
static int loop_find_region(BMEditMesh *em, BMLoop *l, int flag,
|
||||
SmallHash *fhash, BMFace ***region_out)
|
||||
SmallHash *fhash, BMFace ***region_out)
|
||||
{
|
||||
BLI_array_declare(region);
|
||||
BLI_array_declare(stack);
|
||||
BMFace **region = NULL, *f;
|
||||
BMFace **region = NULL;
|
||||
BMFace **stack = NULL;
|
||||
BMFace *f;
|
||||
|
||||
BLI_array_append(stack, l->f);
|
||||
BLI_smallhash_insert(fhash, (uintptr_t)l->f, NULL);
|
||||
@ -2654,7 +2655,7 @@ static int loop_find_regions(BMEditMesh *em, int selbigger)
|
||||
for (i = 0; i < BLI_array_count(edges); i++) {
|
||||
BMIter liter;
|
||||
BMLoop *l;
|
||||
BMFace **region = NULL, **r;
|
||||
BMFace **region = NULL, **region_out;
|
||||
int c, tot = 0;
|
||||
|
||||
e = edges[i];
|
||||
@ -2666,7 +2667,7 @@ static int loop_find_regions(BMEditMesh *em, int selbigger)
|
||||
if (BLI_smallhash_haskey(&visithash, (uintptr_t)l->f))
|
||||
continue;
|
||||
|
||||
c = loop_find_region(em, l, BM_ELEM_SELECT, &visithash, &r);
|
||||
c = loop_find_region(em, l, BM_ELEM_SELECT, &visithash, ®ion_out);
|
||||
|
||||
if (!region || (selbigger ? c >= tot : c < tot)) {
|
||||
/* this region is the best seen so far */
|
||||
@ -2676,11 +2677,11 @@ static int loop_find_regions(BMEditMesh *em, int selbigger)
|
||||
MEM_freeN(region);
|
||||
}
|
||||
/* track the current region as the new best */
|
||||
region = r;
|
||||
region = region_out;
|
||||
}
|
||||
else {
|
||||
/* this region is not as good as best so far, just free it */
|
||||
MEM_freeN(r);
|
||||
MEM_freeN(region_out);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include "ED_mesh.h"
|
||||
#include "ED_util.h"
|
||||
|
||||
#include "bmesh.h"
|
||||
|
||||
void EDBM_RecalcNormals(BMEditMesh *em)
|
||||
{
|
||||
@ -960,7 +961,7 @@ void EDBM_free_uv_element_map(UvElementMap *element_map)
|
||||
|
||||
/* last_sel, use em->act_face otherwise get the last selected face in the editselections
|
||||
* at the moment, last_sel is mainly useful for gaking sure the space image dosnt flicker */
|
||||
MTexPoly *EDBM_get_active_mtexpoly(BMEditMesh *em, BMFace **act_efa, int sloppy)
|
||||
MTexPoly *EDBM_get_active_mtexpoly(BMEditMesh *em, BMFace **r_act_efa, int sloppy)
|
||||
{
|
||||
BMFace *efa = NULL;
|
||||
|
||||
@ -970,11 +971,11 @@ MTexPoly *EDBM_get_active_mtexpoly(BMEditMesh *em, BMFace **act_efa, int sloppy)
|
||||
efa = BM_active_face_get(em->bm, sloppy);
|
||||
|
||||
if (efa) {
|
||||
if (act_efa) *act_efa = efa;
|
||||
if (r_act_efa) *r_act_efa = efa;
|
||||
return CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
|
||||
}
|
||||
|
||||
if (act_efa) *act_efa = NULL;
|
||||
if (r_act_efa) *r_act_efa = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user