Replaced unified extrude edges/faces code (the stuff specificaly for
edges/faces,extrudeflag_edgess, not the entire extrude system) with a bmesh version. This stress-tested the operator api, and I had to code some new stuff,including: * An api to iterate over Mapping slots and array slots. It's modeled after the normal iterator api. * The ability to copy mapping slots. * More mapping functions. * In addition to being able to flag elements in a buffer, you can now unflag them (much clearer then passing in ~flag I think). The extrude edge/faces code has multiple layers. At the top level is a funtion in editmesh_lib.c, which takes care of selection, handles mirror modifiers, etc. It calls the extrude operator, which in turns calls split, which calls dupe/del. Note that split needed a slot to exclude things from being deleting (e.g. when extruding a single isolated face). The basic idea (reflected in original design of split/dupe/del by Briggs) is to use the split function to do the heavy work of extrude. split spits out new geometry and mappings from boundary edges, for extrude (it should also spit out other mappings, but that's for later). Briggs: you may want to look over this, hopefully I didn't do anything too evil. I probably should spend some time going over the 2.5 mesh operators and cleaning them up, splitting ones that need splitting, etc, and in general getting them to work properly.
This commit is contained in:
@@ -80,6 +80,7 @@ int BMO_TestFlag(struct BMesh *bm, void *element, int flag);
|
||||
int BMO_CountFlag(struct BMesh *bm, int flag, int type);
|
||||
void BMO_Flag_To_Slot(struct BMesh *bm, struct BMOperator *op, int slotcode, int flag, int type);
|
||||
void BMO_Flag_Buffer(struct BMesh *bm, struct BMOperator *op, int slotcode, int flag);
|
||||
void BMO_Unflag_Buffer(struct BMesh *bm, struct BMOperator *op, int slotcode, int flag);
|
||||
void BMO_HeaderFlag_To_Slot(struct BMesh *bm, struct BMOperator *op, int slotcode, int flag, int type);
|
||||
int BMO_CountSlotBuf(struct BMesh *bm, struct BMOperator *op, int slotcode);
|
||||
|
||||
@@ -88,6 +89,9 @@ void BMO_Insert_Mapping(BMesh *bm, BMOperator *op, int slotcode,
|
||||
void *element, void *data, int len);
|
||||
void BMO_Insert_MapFloat(BMesh *bm, BMOperator *op, int slotcode,
|
||||
void *element, float val);
|
||||
|
||||
//returns 1 if the specified element is in the map.
|
||||
int BMO_InMap(BMesh *bm, BMOperator *op, int slotcode, void *element);
|
||||
void *BMO_Get_MapData(BMesh *bm, BMOperator *op, int slotcode,
|
||||
void *element);
|
||||
float BMO_Get_MapFloat(BMesh *bm, BMOperator *op, int slotcode,
|
||||
@@ -102,6 +106,22 @@ void BMO_Insert_MapPointer(BMesh *bm, BMOperator *op, int slotcode,
|
||||
void *BMO_Get_MapPointer(BMesh *bm, BMOperator *op, int slotcode,
|
||||
void *element);
|
||||
|
||||
struct GHashIterator;
|
||||
typedef struct BMOIter {
|
||||
BMOpSlot *slot;
|
||||
int cur; //for arrays
|
||||
struct GHashIterator giter;
|
||||
void *val;
|
||||
} BMOIter;
|
||||
|
||||
void *BMO_IterNew(BMOIter *iter, BMesh *bm, BMOperator *op,
|
||||
int slotcode);
|
||||
void *BMO_IterStep(BMOIter *iter);
|
||||
|
||||
/*returns a pointer to the key value when iterating over mappings.
|
||||
remember for pointer maps this will be a pointer to a pointer.*/
|
||||
void *BMO_IterMapVal(BMOIter *iter);
|
||||
|
||||
/*if msg is null, then the default message for the errorcode is used*/
|
||||
void BMOP_RaiseError(BMesh *bm, int errcode, char *msg);
|
||||
/*returns error code or 0 if no error*/
|
||||
@@ -126,8 +146,9 @@ static char *bmop_error_messages[] = {
|
||||
|
||||
enum {
|
||||
BMOP_SPLIT_MULTIN,
|
||||
BMOP_SPLIT_KEEPIN, //input list of geometry to keep
|
||||
BMOP_SPLIT_MULTOUT,
|
||||
BMOP_SPLIT_BOUNDS_EDGEMAP,
|
||||
BMOP_SPLIT_BOUNDS_EDGEMAP, //bounding edges of split faces
|
||||
BMOP_SPLIT_TOTSLOT,
|
||||
};
|
||||
|
||||
@@ -236,8 +257,16 @@ enum {
|
||||
#define BMOP_MAKE_FGONS 9
|
||||
#define BMOP_MAKE_FGONS_TOTSLOT 0
|
||||
|
||||
#define BMOP_EXTRUDE_EDGECONTEXT 10
|
||||
enum {
|
||||
BMOP_EXFACE_EDGEFACEIN,
|
||||
BMOP_EXFACE_EXCLUDEMAP, //exclude edges from skirt connecting
|
||||
BMOP_EXFACE_MULTOUT, //new geometry
|
||||
BMOP_EXFACE_TOTSLOT,
|
||||
};
|
||||
|
||||
/*keep this updated!*/
|
||||
#define BMOP_TOTAL_OPS 10
|
||||
#define BMOP_TOTAL_OPS 11
|
||||
/*-------------------------------end operator defines-------------------------------*/
|
||||
|
||||
extern BMOpDefine *opdefines[];
|
||||
@@ -253,5 +282,7 @@ struct Object;
|
||||
|
||||
void BMOP_DupeFromFlag(struct BMesh *bm, int etypeflag, int flag);
|
||||
void BM_esubdivideflag(struct Object *obedit, struct BMesh *bm, int selflag, float rad,
|
||||
int flag, int numcuts, int seltype);
|
||||
int flag, int numcuts, int seltype);
|
||||
void BM_extrudefaceflag(BMesh *bm, int flag);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,6 +3,15 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
BMOpDefine def_extrudefaceregion = {
|
||||
{BMOP_OPSLOT_PNT_BUF,
|
||||
BMOP_OPSLOT_MAPPING,
|
||||
BMOP_OPSLOT_PNT_BUF},
|
||||
extrude_edge_context_exec,
|
||||
BMOP_EXFACE_TOTSLOT,
|
||||
0
|
||||
};
|
||||
|
||||
BMOpDefine def_makefgonsop = {
|
||||
{0},
|
||||
bmesh_make_fgons_exec,
|
||||
@@ -79,7 +88,7 @@ BMOpDefine def_dupeop = {
|
||||
|
||||
BMOpDefine def_splitop = {
|
||||
{BMOP_OPSLOT_PNT_BUF, BMOP_OPSLOT_PNT_BUF,
|
||||
BMOP_OPSLOT_MAPPING},
|
||||
BMOP_OPSLOT_PNT_BUF, BMOP_OPSLOT_MAPPING},
|
||||
splitop_exec,
|
||||
BMOP_SPLIT_TOTSLOT,
|
||||
0
|
||||
@@ -96,6 +105,7 @@ BMOpDefine *opdefines[] = {
|
||||
&def_dissolvefacesop,
|
||||
&def_dissolvevertsop,
|
||||
&def_makefgonsop,
|
||||
&def_extrudefaceregion,
|
||||
};
|
||||
|
||||
int bmesh_total_ops = (sizeof(opdefines) / sizeof(void*));
|
||||
|
||||
@@ -436,6 +436,17 @@ void BMO_Insert_MapPointer(BMesh *bm, BMOperator *op, int slotcode,
|
||||
BMO_Insert_Mapping(bm, op, slotcode, element, &val, sizeof(void*));
|
||||
}
|
||||
|
||||
int BMO_InMap(BMesh *bm, BMOperator *op, int slotcode, void *element)
|
||||
{
|
||||
BMOpSlot *slot = &op->slots[slotcode];
|
||||
|
||||
/*sanity check*/
|
||||
if (slot->slottype != BMOP_OPSLOT_MAPPING) return 0;
|
||||
if (!slot->data.ghash) return 0;
|
||||
|
||||
return BLI_ghash_haskey(slot->data.ghash, element);
|
||||
}
|
||||
|
||||
void *BMO_Get_MapData(BMesh *bm, BMOperator *op, int slotcode,
|
||||
void *element)
|
||||
{
|
||||
@@ -448,6 +459,8 @@ void *BMO_Get_MapData(BMesh *bm, BMOperator *op, int slotcode,
|
||||
|
||||
mapping = BLI_ghash_lookup(slot->data.ghash, element);
|
||||
|
||||
if (!mapping) return NULL;
|
||||
|
||||
return mapping + 1;
|
||||
}
|
||||
|
||||
@@ -596,6 +609,24 @@ void BMO_Flag_Buffer(BMesh *bm, BMOperator *op, int slotcode, int flag)
|
||||
BMO_SetFlag(bm, data[i], flag);
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* BMO_FLAG_BUFFER
|
||||
*
|
||||
* Removes flags from elements in a slots buffer
|
||||
*
|
||||
*/
|
||||
|
||||
void BMO_Unflag_Buffer(BMesh *bm, BMOperator *op, int slotcode, int flag)
|
||||
{
|
||||
BMOpSlot *slot = BMO_GetSlot(op, slotcode);
|
||||
BMHeader **data = slot->data.p;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < slot->len; i++)
|
||||
BMO_ClearFlag(bm, data[i], flag);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
@@ -706,3 +737,45 @@ static void clear_flag_layer(BMesh *bm)
|
||||
memset(f->head.flags, 0, sizeof(BMFlagLayer)*bm->totflags);
|
||||
}
|
||||
}
|
||||
|
||||
void *BMO_IterNew(BMOIter *iter, BMesh *bm, BMOperator *op,
|
||||
int slotcode)
|
||||
{
|
||||
BMOpSlot *slot = &op->slots[slotcode];
|
||||
|
||||
iter->slot = slot;
|
||||
iter->cur = 0;
|
||||
|
||||
if (iter->slot->slottype == BMOP_OPSLOT_MAPPING)
|
||||
if (iter->slot->data.ghash)
|
||||
BLI_ghashIterator_init(&iter->giter, slot->data.ghash);
|
||||
|
||||
return BMO_IterStep(iter);
|
||||
}
|
||||
|
||||
void *BMO_IterStep(BMOIter *iter)
|
||||
{
|
||||
if (iter->slot->slottype == BMOP_OPSLOT_PNT_BUF) {
|
||||
if (iter->cur >= iter->slot->len) return NULL;
|
||||
|
||||
return ((void**)iter->slot->data.buf)[iter->cur++];
|
||||
} else if (iter->slot->slottype == BMOP_OPSLOT_MAPPING) {
|
||||
struct element_mapping *map;
|
||||
void *ret = BLI_ghashIterator_getKey(&iter->giter);
|
||||
map = BLI_ghashIterator_getValue(&iter->giter);
|
||||
|
||||
iter->val = map + 1;
|
||||
|
||||
BLI_ghashIterator_step(&iter->giter);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*used for iterating over mappings*/
|
||||
void *BMO_IterMapVal(BMOIter *iter)
|
||||
{
|
||||
return iter->val;
|
||||
}
|
||||
|
||||
@@ -17,5 +17,6 @@ void triangulate_exec(BMesh *bmesh, BMOperator *op);
|
||||
void dissolvefaces_exec(BMesh *bmesh, BMOperator *op);
|
||||
void dissolveverts_exec(BMesh *bmesh, BMOperator *op);
|
||||
void bmesh_make_fgons_exec(BMesh *bmesh, BMOperator *op);
|
||||
void extrude_edge_context_exec(BMesh *bm, BMOperator *op);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -55,19 +55,17 @@ static BMEdge *copy_edge(BMOperator *op, BMesh *source_mesh,
|
||||
BMVert *target_vert1, *target_vert2;
|
||||
BMFace *face;
|
||||
BMIter fiter;
|
||||
int found, rlen;
|
||||
int rlen;
|
||||
|
||||
/*see if any of the neighboring faces are
|
||||
not being duplicated. in that case,
|
||||
add it to the new/old map.*/
|
||||
found = rlen = 0;
|
||||
rlen = 0;
|
||||
for (face=BMIter_New(&fiter,source_mesh, BM_FACES_OF_EDGE,source_edge);
|
||||
face; face=BMIter_Step(&fiter)) {
|
||||
if (!BMO_TestFlag(source_mesh, face, DUPE_INPUT)) {
|
||||
found = 1;
|
||||
break;
|
||||
if (BMO_TestFlag(source_mesh, face, DUPE_INPUT)) {
|
||||
rlen++;
|
||||
}
|
||||
rlen++;
|
||||
}
|
||||
|
||||
/*Lookup v1 and v2*/
|
||||
@@ -78,7 +76,7 @@ static BMEdge *copy_edge(BMOperator *op, BMesh *source_mesh,
|
||||
target_edge = BM_Make_Edge(target_mesh, target_vert1, target_vert2, NULL, 0);
|
||||
|
||||
/*add to new/old edge map if necassary*/
|
||||
if (rlen > 0 && rlen <= 2 && found) {
|
||||
if (rlen < 2) {
|
||||
/*not sure what non-manifold cases of greater then three
|
||||
radial should do.*/
|
||||
BMO_Insert_MapPointer(source_mesh,op,BMOP_DUPE_BOUNDS_EDGEMAP,
|
||||
@@ -335,6 +333,7 @@ void BMOP_DupeFromFlag(BMesh *bm, int etypeflag, int flag)
|
||||
*
|
||||
*/
|
||||
|
||||
#define SPLIT_INPUT 1
|
||||
void splitop_exec(BMesh *bm, BMOperator *op)
|
||||
{
|
||||
BMOperator *splitop = op;
|
||||
@@ -350,9 +349,12 @@ void splitop_exec(BMesh *bm, BMOperator *op)
|
||||
BMO_CopySlot(splitop, &dupeop, BMOP_SPLIT_MULTIN, BMOP_DUPE_MULTIN);
|
||||
BMO_Exec_Op(bm, &dupeop);
|
||||
|
||||
/*connect outputs of dupe to delete*/
|
||||
BMO_CopySlot(&dupeop, &delop, BMOP_DUPE_ORIG, BMOP_DEL_MULTIN);
|
||||
BMO_Exec_Op(bm, &delop);
|
||||
/*connect outputs of dupe to delete, exluding keep geometry*/
|
||||
BMO_Flag_Buffer(bm, splitop, BMOP_SPLIT_MULTIN, SPLIT_INPUT);
|
||||
BMO_Unflag_Buffer(bm, splitop, BMOP_SPLIT_KEEPIN, SPLIT_INPUT);
|
||||
BMO_Flag_To_Slot(bm, &delop, BMOP_DEL_MULTIN, SPLIT_INPUT, BM_ALL);
|
||||
|
||||
//BMO_Exec_Op(bm, &delop);
|
||||
|
||||
/*now we make our outputs by copying the dupe outputs*/
|
||||
BMO_CopySlot(&dupeop, splitop, BMOP_DUPE_NEW, BMOP_SPLIT_MULTOUT);
|
||||
|
||||
65
source/blender/bmesh/operators/extrudeops.c
Normal file
65
source/blender/bmesh/operators/extrudeops.c
Normal file
@@ -0,0 +1,65 @@
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_memarena.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_arithb.h"
|
||||
|
||||
#include "bmesh.h"
|
||||
#include "bmesh_operators_private.h"
|
||||
|
||||
#define EXT_INPUT 1
|
||||
#define EXT_KEEP 2
|
||||
|
||||
void extrude_edge_context_exec(BMesh *bm, BMOperator *op)
|
||||
{
|
||||
BMOperator splitop;
|
||||
BMOIter siter;
|
||||
BMIter iter, fiter;
|
||||
BMEdge *edge, *newedge;
|
||||
BMVert *verts[4];
|
||||
BMFace *f;
|
||||
int totflagged, rlen;
|
||||
|
||||
/*initialize our sub-operators*/
|
||||
BMO_Init_Op(&splitop, BMOP_SPLIT);
|
||||
|
||||
BMO_Flag_To_Slot(bm, op, BMOP_EXFACE_EDGEFACEIN, EXT_INPUT, BM_ALL);
|
||||
|
||||
/*calculate geometry to keep*/
|
||||
for (edge = BMIter_New(&iter, bm, BM_EDGES, NULL); edge; edge=BMIter_Step(&iter)) {
|
||||
f = BMIter_New(&fiter, bm, BM_FACES_OF_EDGE, edge);
|
||||
rlen = 0;
|
||||
for (; f; f=BMIter_Step(&fiter)) {
|
||||
if (BMO_TestFlag(bm, f, EXT_INPUT)) rlen++;
|
||||
}
|
||||
|
||||
if (rlen < 2) BMO_SetFlag(bm, edge, EXT_KEEP);
|
||||
}
|
||||
|
||||
BMO_CopySlot(op, &splitop, BMOP_EXFACE_EDGEFACEIN, BMOP_SPLIT_MULTIN);
|
||||
BMO_Flag_To_Slot(bm, &splitop, BMOP_SPLIT_KEEPIN, EXT_KEEP, BM_ALL);
|
||||
|
||||
BMO_Exec_Op(bm, &splitop);
|
||||
|
||||
BMO_CopySlot(&splitop, op, BMOP_SPLIT_MULTOUT, BMOP_EXFACE_MULTOUT);
|
||||
|
||||
edge = BMO_IterNew(&siter, bm, &splitop, BMOP_SPLIT_BOUNDS_EDGEMAP);
|
||||
for (; edge; edge=BMO_IterStep(&siter)) {
|
||||
if (BMO_InMap(bm, op, BMOP_EXFACE_EXCLUDEMAP, edge)) continue;
|
||||
|
||||
newedge = *(BMEdge**)BMO_IterMapVal(&siter);
|
||||
verts[0] = edge->v1;
|
||||
verts[1] = edge->v2;
|
||||
verts[2] = newedge->v2;
|
||||
verts[3] = newedge->v1;
|
||||
|
||||
//not sure what to do about example face, pass NULL for now.
|
||||
f = BM_Make_Quadtriangle(bm, verts, NULL, 4, NULL, 0);
|
||||
}
|
||||
|
||||
/*cleanup*/
|
||||
BMO_Finish_Op(bm, &splitop);
|
||||
}
|
||||
@@ -518,6 +518,12 @@ static void end_editmesh_fastmalloc(void)
|
||||
callocface= calloc_em;
|
||||
}
|
||||
|
||||
void set_editMesh(EditMesh *dst, EditMesh *src)
|
||||
{
|
||||
free_editMesh(dst);
|
||||
*dst = *src;
|
||||
}
|
||||
|
||||
/* do not free editmesh itself here */
|
||||
void free_editMesh(EditMesh *em)
|
||||
{
|
||||
|
||||
@@ -58,6 +58,7 @@ editmesh_lib: generic (no UI, no menus) operations/evaluators for editmesh data
|
||||
#include "ED_view3d.h"
|
||||
|
||||
#include "mesh_intern.h"
|
||||
#include "bmesh.h"
|
||||
|
||||
/* ****************** stats *************** */
|
||||
|
||||
@@ -1135,10 +1136,127 @@ short extrudeflag_verts_indiv(EditMesh *em, short flag, float *nor)
|
||||
return 'g'; // g is grab
|
||||
}
|
||||
|
||||
short BM_extrude_edgeflag(Object *obedit, BMesh *bm, int eflag, float *nor)
|
||||
{
|
||||
BMIter iter;
|
||||
BMOIter siter;
|
||||
BMOperator extop;
|
||||
BMEdge *edge;
|
||||
BMFace *f;
|
||||
void *el;
|
||||
ModifierData *md;
|
||||
int flag;
|
||||
|
||||
switch (eflag) {
|
||||
case SELECT:
|
||||
flag = BM_SELECT;
|
||||
break;
|
||||
default:
|
||||
flag = BM_SELECT;
|
||||
break;
|
||||
}
|
||||
|
||||
for (f=BMIter_New(&iter, bm, BM_FACES, NULL);f;f=BMIter_Step(&iter)) {
|
||||
add_normal_aligned(nor, f->no);
|
||||
}
|
||||
Normalize(nor);
|
||||
|
||||
BMO_Init_Op(&extop, BMOP_EXTRUDE_EDGECONTEXT);
|
||||
BMO_HeaderFlag_To_Slot(bm, &extop, BMOP_EXFACE_EDGEFACEIN,
|
||||
flag, BM_EDGE|BM_FACE);
|
||||
|
||||
for (edge=BMIter_New(&iter, bm, BM_EDGES, NULL); edge; edge=BMIter_Step(&iter)) {
|
||||
BM_Select_Edge(bm, edge, 0);
|
||||
}
|
||||
|
||||
for (f=BMIter_New(&iter, bm, BM_FACES, NULL); f; f=BMIter_Step(&iter)) {
|
||||
BM_Select_Face(bm, f, 0);
|
||||
}
|
||||
|
||||
/* If a mirror modifier with clipping is on, we need to adjust some
|
||||
* of the cases above to handle edges on the line of symmetry.
|
||||
*/
|
||||
for (; md; md=md->next) {
|
||||
if (md->type==eModifierType_Mirror) {
|
||||
MirrorModifierData *mmd = (MirrorModifierData*) md;
|
||||
|
||||
if(mmd->flag & MOD_MIR_CLIPPING) {
|
||||
float mtx[4][4];
|
||||
if (mmd->mirror_ob) {
|
||||
float imtx[4][4];
|
||||
Mat4Invert(imtx, mmd->mirror_ob->obmat);
|
||||
Mat4MulMat4(mtx, obedit->obmat, imtx);
|
||||
}
|
||||
|
||||
for (edge=BMIter_New(&iter,bm,BM_EDGES,NULL);
|
||||
edge; edge=BMIter_Step(&iter))
|
||||
{
|
||||
if(edge->head.flag & flag) {
|
||||
float co1[3], co2[3];
|
||||
|
||||
VecCopyf(co1, edge->v1->co);
|
||||
VecCopyf(co2, edge->v2->co);
|
||||
|
||||
if (mmd->mirror_ob) {
|
||||
VecMat4MulVecfl(co1, mtx, co1);
|
||||
VecMat4MulVecfl(co2, mtx, co2);
|
||||
}
|
||||
|
||||
if (mmd->flag & MOD_MIR_AXIS_X)
|
||||
if ( (fabs(co1[0]) < mmd->tolerance) &&
|
||||
(fabs(co2[0]) < mmd->tolerance) )
|
||||
BMO_Insert_MapPointer(bm, &extop, BMOP_EXFACE_EXCLUDEMAP, edge, NULL);
|
||||
|
||||
if (mmd->flag & MOD_MIR_AXIS_Y)
|
||||
if ( (fabs(co1[1]) < mmd->tolerance) &&
|
||||
(fabs(co2[1]) < mmd->tolerance) )
|
||||
BMO_Insert_MapPointer(bm, &extop, BMOP_EXFACE_EXCLUDEMAP, edge, NULL);
|
||||
|
||||
if (mmd->flag & MOD_MIR_AXIS_Z)
|
||||
if ( (fabs(co1[2]) < mmd->tolerance) &&
|
||||
(fabs(co2[2]) < mmd->tolerance) )
|
||||
BMO_Insert_MapPointer(bm, &extop, BMOP_EXFACE_EXCLUDEMAP, edge, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BMO_Exec_Op(bm, &extop);
|
||||
|
||||
el = BMO_IterNew(&siter, bm, &extop, BMOP_EXFACE_MULTOUT);
|
||||
for (; el; el=BMO_IterStep(&siter)) {
|
||||
BM_Select(bm, el, 1);
|
||||
}
|
||||
|
||||
BMO_Finish_Op(bm, &extop);
|
||||
|
||||
if(nor[0]==0.0 && nor[1]==0.0 && nor[2]==0.0) return 'g'; // grab
|
||||
return 'n'; // normal constraint
|
||||
|
||||
}
|
||||
|
||||
|
||||
static short extrudeflag_edge(Object *obedit, EditMesh *em, short flag, float *nor) {
|
||||
short ret;
|
||||
EditMesh *em2;
|
||||
BMesh *bm = editmesh_to_bmesh(em);
|
||||
|
||||
ret = BM_extrude_edgeflag(obedit, bm, flag, nor);
|
||||
em2 = bmesh_to_editmesh(bm);
|
||||
|
||||
set_editMesh(em, em2);
|
||||
MEM_freeN(em2);
|
||||
|
||||
EM_select_flush(em);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* this is actually a recode of extrudeflag(), using proper edge/face select */
|
||||
/* hurms, doesnt use 'flag' yet, but its not called by primitive making stuff anyway */
|
||||
static short extrudeflag_edge(Object *obedit, EditMesh *em, short flag, float *nor)
|
||||
static short extrudeflag_edge_old(Object *obedit, EditMesh *em, short flag, float *nor)
|
||||
{
|
||||
/* all select edges/faces: extrude */
|
||||
/* old select is cleared, in new ones it is set */
|
||||
|
||||
@@ -634,18 +634,21 @@ void extrude_mesh(Object *obedit, EditMesh *em)
|
||||
}
|
||||
else if(em->selectmode & SCE_SELECT_EDGE) {
|
||||
if (em->totedgesel==0) nr = 0;
|
||||
else if (em->totedgesel==1) nr = 3;
|
||||
|
||||
nr = 1;
|
||||
/*else if (em->totedgesel==1) nr = 3;
|
||||
else if(em->totfacesel==0) nr = 3;
|
||||
else if(em->totfacesel==1)
|
||||
nr= pupmenu("Extrude %t|Region %x1|Only Edges%x3");
|
||||
else
|
||||
nr= pupmenu("Extrude %t|Region %x1||Individual Faces %x2|Only Edges%x3");
|
||||
*/
|
||||
}
|
||||
else {
|
||||
if (em->totfacesel == 0) nr = 0;
|
||||
else if (em->totfacesel == 1) nr = 1;
|
||||
else
|
||||
nr= pupmenu("Extrude %t|Region %x1||Individual Faces %x2");
|
||||
else nr = 1; //if (em->totfacesel == 1) nr = 1;
|
||||
//else
|
||||
// nr= pupmenu("Extrude %t|Region %x1||Individual Faces %x2");
|
||||
}
|
||||
|
||||
if(nr<1) return;
|
||||
|
||||
@@ -80,6 +80,10 @@ extern void free_editedge(EditMesh *em, EditEdge *eed);
|
||||
extern void free_editface(EditMesh *em, EditFace *efa);
|
||||
void free_editMesh(EditMesh *em);
|
||||
|
||||
/*frees dst mesh, then copies the contents of
|
||||
*src (the struct) to dst. */
|
||||
void set_editMesh(EditMesh *dst, EditMesh *src);
|
||||
|
||||
extern void free_vertlist(EditMesh *em, ListBase *edve);
|
||||
extern void free_edgelist(EditMesh *em, ListBase *lb);
|
||||
extern void free_facelist(EditMesh *em, ListBase *lb);
|
||||
|
||||
Reference in New Issue
Block a user