Added a matrix slot type for bmops. Coded a simple transform
bmop, that just multiplies input verts with a matrix. Also made a derivative translate bmop. BMO_CallOpf now has a %s format code, which is used to copy data from another slot. Also cleaned the extrude code up some more, and restored extrude-repeat (which is bound to ctrl-alt-4), though this doesn't work right yet (the view matrix it uses is incorrect, or something like that).
This commit is contained in:
@@ -872,7 +872,7 @@ void Mat4MulVec( float mat[][4], int *vec)
|
||||
vec[2]=(int)(x*mat[0][2] + y*mat[1][2] + mat[2][2]*vec[2] + mat[3][2]);
|
||||
}
|
||||
|
||||
void Mat4MulVecfl( float mat[][4], float *vec)
|
||||
void Mat4MulVecfl(float mat[][4], float *vec)
|
||||
{
|
||||
float x,y;
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ struct GHashIterator;
|
||||
#define BMOP_OPSLOT_INT 1
|
||||
#define BMOP_OPSLOT_FLT 2
|
||||
#define BMOP_OPSLOT_PNT 3
|
||||
#define BMOP_OPSLOT_MAT 4
|
||||
#define BMOP_OPSLOT_VEC 7
|
||||
|
||||
/*after BMOP_OPSLOT_VEC, everything is
|
||||
@@ -159,6 +160,13 @@ int BMO_CountFlag(struct BMesh *bm, int flag, int type);
|
||||
%hv will do verts, etc. must pass in at least one
|
||||
element type letter.
|
||||
%f[f/e/v] - same as %h.
|
||||
%v - pointer to a float vector of length 3.
|
||||
%m[3/4] - matrix, 3/4 refers to the matrix size, 3 or 4. the
|
||||
corrusponding argument must be a pointer to
|
||||
a float matrix.
|
||||
%s - copy a slot from another op, instead of mapping to one
|
||||
argument, it maps to two, a pointer to an operator and
|
||||
a slot name.
|
||||
*/
|
||||
/*executes an operator*/
|
||||
int BMO_CallOpf(BMesh *bm, char *fmt, ...);
|
||||
@@ -196,6 +204,13 @@ void *BMO_Get_Pnt(BMOperator *op, char *slotname);
|
||||
void BMO_Set_Vec(struct BMOperator *op, char *slotname, float *vec);
|
||||
void BMO_Get_Vec(BMOperator *op, char *slotname, float *vec_out);
|
||||
|
||||
/*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_Set_Mat(struct BMOperator *op, char *slotname, float *mat, int size);
|
||||
void BMO_Get_Mat4(struct BMOperator *op, char *slotname, float mat[4][4]);
|
||||
void BMO_Get_Mat3(struct BMOperator *op, char *slotname, float mat[3][3]);
|
||||
|
||||
/*puts every element of type type (which is a bitmask) with tool flag flag,
|
||||
into a slot.*/
|
||||
|
||||
@@ -3,15 +3,35 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/*applies a transform to vertices*/
|
||||
|
||||
BMOpDefine def_translate= {
|
||||
"translate",
|
||||
{{BMOP_OPSLOT_VEC, "vec"},
|
||||
{BMOP_OPSLOT_ELEMENT_BUF, "verts"},
|
||||
{0, /*null-terminating sentinel*/}},
|
||||
bmesh_translate_exec,
|
||||
0,
|
||||
};
|
||||
|
||||
|
||||
BMOpDefine def_transform = {
|
||||
"transform",
|
||||
{{BMOP_OPSLOT_MAT, "mat"},
|
||||
{BMOP_OPSLOT_ELEMENT_BUF, "verts"},
|
||||
{0, /*null-terminating sentinel*/}},
|
||||
bmesh_transform_exec,
|
||||
0,
|
||||
};
|
||||
|
||||
/*loads a bmesh into an object*/
|
||||
BMOpDefine def_object_load_bmesh = {
|
||||
"object_load_bmesh",
|
||||
/*pointer to a mesh struct*/
|
||||
{{BMOP_OPSLOT_PNT, "scene"},
|
||||
{BMOP_OPSLOT_PNT, "object"},
|
||||
{0, /*null-terminating sentinel*/}},
|
||||
bmesh_to_mesh_exec,
|
||||
0
|
||||
0,
|
||||
};
|
||||
|
||||
|
||||
@@ -191,6 +211,8 @@ BMOpDefine *opdefines[] = {
|
||||
&def_extrudeverts_indiv,
|
||||
&def_mesh_to_bmesh,
|
||||
&def_object_load_bmesh,
|
||||
&def_transform,
|
||||
&def_translate,
|
||||
};
|
||||
|
||||
int bmesh_total_ops = (sizeof(opdefines) / sizeof(void*));
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_arithb.h"
|
||||
#include "BLI_memarena.h"
|
||||
#include "BLI_mempool.h"
|
||||
#include "BLI_blenlib.h"
|
||||
@@ -259,6 +260,45 @@ void BMO_Set_Int(BMOperator *op, char *slotname, int i)
|
||||
slot->data.i = i;
|
||||
}
|
||||
|
||||
/*only supports square mats*/
|
||||
void BMO_Set_Mat(struct BMOperator *op, char *slotname, float *mat, int size)
|
||||
{
|
||||
BMOpSlot *slot = BMO_GetSlot(op, slotname);
|
||||
if( !(slot->slottype == BMOP_OPSLOT_MAT) )
|
||||
return 0;
|
||||
|
||||
slot->len = 4;
|
||||
slot->data.p = BLI_memarena_alloc(op->arena, sizeof(float)*4*4);
|
||||
|
||||
if (size == 4) {
|
||||
memcpy(slot->data.p, mat, sizeof(float)*4*4);
|
||||
} else if (size == 3) {
|
||||
Mat4CpyMat3(slot->data.p, mat);
|
||||
} else {
|
||||
printf("yeek! invalid size in BMO_Set_Mat!\n");
|
||||
|
||||
memset(slot->data.p, 0, sizeof(float)*4*4);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void BMO_Get_Mat4(struct BMOperator *op, char *slotname, float mat[4][4])
|
||||
{
|
||||
BMOpSlot *slot = BMO_GetSlot(op, slotname);
|
||||
if( !(slot->slottype == BMOP_OPSLOT_MAT) )
|
||||
return;
|
||||
|
||||
memcpy(mat, slot->data.p, sizeof(float)*4*4);
|
||||
}
|
||||
|
||||
void BMO_Get_Mat3(struct BMOperator *op, char *slotname, float mat[3][3])
|
||||
{
|
||||
BMOpSlot *slot = BMO_GetSlot(op, slotname);
|
||||
if( !(slot->slottype == BMOP_OPSLOT_MAT) )
|
||||
return;
|
||||
|
||||
Mat3CpyMat4(mat, slot->data.p);
|
||||
}
|
||||
|
||||
void BMO_Set_Pnt(BMOperator *op, char *slotname, void *p)
|
||||
{
|
||||
@@ -1028,6 +1068,33 @@ int BMO_VInitOpf(BMesh *bm, BMOperator *op, char *fmt, va_list vlist)
|
||||
case '=':
|
||||
case '%':
|
||||
break;
|
||||
case 'm': {
|
||||
int size, c;
|
||||
|
||||
c = nextc(fmt);
|
||||
fmt++;
|
||||
|
||||
if (c == '3') size = 3;
|
||||
else if (c == '4') size = 4;
|
||||
else goto error;
|
||||
|
||||
BMO_Set_Mat(op, slotname, va_arg(vlist, void*), size);
|
||||
state = 1;
|
||||
break;
|
||||
}
|
||||
case 'v': {
|
||||
BMO_Set_Vec(op, slotname, va_arg(vlist, float*));
|
||||
state = 1;
|
||||
break;
|
||||
}
|
||||
case 's': {
|
||||
BMOperator *op2 = va_arg(vlist, void*);
|
||||
char *slotname2 = va_arg(vlist, char*);
|
||||
|
||||
BMO_CopySlot(op2, op, slotname2, slotname);
|
||||
state = 1;
|
||||
break;
|
||||
}
|
||||
case 'i':
|
||||
case 'd':
|
||||
BMO_Set_Int(op, slotname, va_arg(vlist, int));
|
||||
|
||||
@@ -23,5 +23,7 @@ void makeprim_exec(BMesh *bm, BMOperator *op);
|
||||
void extrude_vert_indiv_exec(BMesh *bm, BMOperator *op);
|
||||
void mesh_to_bmesh_exec(BMesh *bm, BMOperator *op);
|
||||
void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op);
|
||||
void bmesh_translate_exec(BMesh *bm, BMOperator *op);
|
||||
void bmesh_transform_exec(BMesh *bm, BMOperator *op);
|
||||
|
||||
#endif
|
||||
|
||||
63
source/blender/bmesh/operators/utils.c
Normal file
63
source/blender/bmesh/operators/utils.c
Normal file
@@ -0,0 +1,63 @@
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
#include "BKE_customdata.h"
|
||||
#include "DNA_listBase.h"
|
||||
#include "DNA_customdata_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include <string.h>
|
||||
#include "BKE_utildefines.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_DerivedMesh.h"
|
||||
#include "BKE_cdderivedmesh.h"
|
||||
|
||||
#include "BLI_editVert.h"
|
||||
#include "mesh_intern.h"
|
||||
#include "ED_mesh.h"
|
||||
|
||||
#include "BLI_arithb.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_edgehash.h"
|
||||
|
||||
#include "bmesh.h"
|
||||
|
||||
/*
|
||||
* UTILS.C
|
||||
*
|
||||
* utility bmesh operators, e.g. transform,
|
||||
* translate, rotate, scale, etc.
|
||||
*
|
||||
*/
|
||||
|
||||
void bmesh_transform_exec(BMesh *bm, BMOperator *op) {
|
||||
BMOIter iter;
|
||||
BMVert *v;
|
||||
float mat[4][4];
|
||||
|
||||
BMO_Get_Mat4(op, "mat", mat);
|
||||
|
||||
BMO_ITER(v, &iter, bm, op, "verts") {
|
||||
Mat4MulVecfl(mat, v->co);
|
||||
}
|
||||
}
|
||||
|
||||
/*this operator calls the transform operator, which
|
||||
is a little complex, but makes it easier to make
|
||||
sure the transform op is working, since initially
|
||||
only this one will be used.*/
|
||||
void bmesh_translate_exec(BMesh *bm, BMOperator *op) {
|
||||
BMOIter iter;
|
||||
BMVert *v;
|
||||
float mat[4][4], vec[3];
|
||||
|
||||
BMO_Get_Vec(op, "offset", vec);
|
||||
|
||||
Mat4One(mat);
|
||||
VECCOPY(mat[3], vec);
|
||||
|
||||
BMO_CallOpf(bm, "transform mat=%m4 verts=%s", mat, op, "verts");
|
||||
}
|
||||
|
||||
@@ -466,7 +466,7 @@ short EDBM_Extrude_verts_indiv(BMEditMesh *em, wmOperator *op, short flag, float
|
||||
return 'g'; // g is grab
|
||||
}
|
||||
|
||||
short EDBM_Extrude_edge(Object *obedit, BMEditMesh *em, int eflag, float *nor)
|
||||
short EDBM_Extrude_edge(Object *obedit, BMEditMesh *em, int flag, float *nor)
|
||||
{
|
||||
BMesh *bm = em->bm;
|
||||
BMIter iter;
|
||||
@@ -475,24 +475,9 @@ short EDBM_Extrude_edge(Object *obedit, BMEditMesh *em, int eflag, float *nor)
|
||||
BMVert *vert;
|
||||
BMEdge *edge;
|
||||
BMFace *f;
|
||||
void *el;
|
||||
ModifierData *md;
|
||||
int flag;
|
||||
BMHeader *el;
|
||||
|
||||
switch (eflag) {
|
||||
case SELECT:
|
||||
flag = BM_SELECT;
|
||||
break;
|
||||
default:
|
||||
flag = BM_SELECT;
|
||||
break;
|
||||
}
|
||||
|
||||
for (f=BMIter_New(&iter, bm, BM_FACES_OF_MESH, NULL);f;f=BMIter_Step(&iter)) {
|
||||
add_normal_aligned(nor, f->no);
|
||||
}
|
||||
Normalize(nor);
|
||||
|
||||
BMO_Init_Op(&extop, "extrudefaceregion");
|
||||
BMO_HeaderFlag_To_Slot(bm, &extop, "edgefacein",
|
||||
flag, BM_VERT|BM_EDGE|BM_FACE);
|
||||
@@ -561,10 +546,19 @@ short EDBM_Extrude_edge(Object *obedit, BMEditMesh *em, int eflag, float *nor)
|
||||
|
||||
BMO_Exec_Op(bm, &extop);
|
||||
|
||||
nor[0] = nor[1] = nor[2] = 0.0f;
|
||||
|
||||
BMO_ITER(el, &siter, bm, &extop, "geomout") {
|
||||
BM_Select(bm, el, 1);
|
||||
|
||||
if (el->type == BM_FACE) {
|
||||
f = (BMFace*)el;
|
||||
add_normal_aligned(nor, f->no);
|
||||
};
|
||||
}
|
||||
|
||||
Normalize(nor);
|
||||
|
||||
BMO_Finish_Op(bm, &extop);
|
||||
|
||||
if(nor[0]==0.0 && nor[1]==0.0 && nor[2]==0.0) return 'g'; // grab
|
||||
@@ -576,29 +570,6 @@ short EDBM_Extrude_vert(Object *obedit, BMEditMesh *em, short flag, float *nor)
|
||||
BMIter iter;
|
||||
BMEdge *eed;
|
||||
|
||||
/*ensure vert flags are consistent for edge selections*/
|
||||
eed = BMIter_New(&iter, em->bm, BM_EDGES_OF_MESH, NULL);
|
||||
for ( ; eed; eed=BMIter_Step(&iter)) {
|
||||
if (BM_TestHFlag(eed, flag)) {
|
||||
BM_SetHFlag(eed->v1, flag);
|
||||
BM_SetHFlag(eed->v2, flag);
|
||||
} else {
|
||||
if (BM_TestHFlag(eed->v1, flag) && BM_TestHFlag(eed->v2, flag))
|
||||
BM_SetHFlag(eed, flag);
|
||||
}
|
||||
}
|
||||
|
||||
return EDBM_Extrude_edge(obedit, em, flag, nor);
|
||||
|
||||
}
|
||||
|
||||
/* generic extrude */
|
||||
short EDBM_Extrude(Object *obedit, BMEditMesh *em, short flag, float *nor)
|
||||
{
|
||||
if(em->selectmode & SCE_SELECT_VERTEX) {
|
||||
BMIter iter;
|
||||
BMEdge *eed;
|
||||
|
||||
/*ensure vert flags are consistent for edge selections*/
|
||||
eed = BMIter_New(&iter, em->bm, BM_EDGES_OF_MESH, NULL);
|
||||
for ( ; eed; eed=BMIter_Step(&iter)) {
|
||||
@@ -620,18 +591,13 @@ short EDBM_Extrude(Object *obedit, BMEditMesh *em, short flag, float *nor)
|
||||
}
|
||||
|
||||
return EDBM_Extrude_edge(obedit, em, flag, nor);
|
||||
} else
|
||||
return EDBM_Extrude_edge(obedit, em, flag, nor);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int extrude_repeat_mesh(bContext *C, wmOperator *op)
|
||||
{
|
||||
#if 0
|
||||
Object *obedit= CTX_data_edit_object(C);
|
||||
EditMesh *em= EM_GetEditMesh((Mesh *)obedit->data);
|
||||
|
||||
BMEditMesh *em = ((Mesh *)obedit->data)->edit_btmesh;
|
||||
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
||||
|
||||
int steps = RNA_int_get(op->ptr,"steps");
|
||||
@@ -656,19 +622,18 @@ static int extrude_repeat_mesh(bContext *C, wmOperator *op)
|
||||
Mat3MulVecfl(tmat, dvec);
|
||||
|
||||
for(a=0; a<steps; a++) {
|
||||
extrudeflag(obedit, em, SELECT, nor);
|
||||
translateflag(em, SELECT, dvec);
|
||||
EDBM_Extrude_edge(obedit, em, BM_SELECT, nor);
|
||||
//BMO_CallOpf(em->bm, "extrudefaceregion edgefacein=%hef", BM_SELECT);
|
||||
BMO_CallOpf(em->bm, "translate vec=%v verts=%hv", (float*)dvec, BM_SELECT);
|
||||
//extrudeflag(obedit, em, SELECT, nor);
|
||||
//translateflag(em, SELECT, dvec);
|
||||
}
|
||||
|
||||
recalc_editnormals(em);
|
||||
|
||||
EM_fgon_flags(em);
|
||||
|
||||
EDBM_RecalcNormals(em);
|
||||
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
|
||||
|
||||
// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
|
||||
EM_EndEditMesh(obedit->data, em);
|
||||
#endif
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
@@ -729,7 +694,9 @@ void EDBM_Extrude_Mesh(Object *obedit, BMEditMesh *em, wmOperator *op)
|
||||
|
||||
if(nr<1) return;
|
||||
|
||||
if(nr==1) transmode= EDBM_Extrude(obedit, em, SELECT, nor);
|
||||
if(nr==1 && em->selectmode & SCE_SELECT_VERTEX)
|
||||
transmode= EDBM_Extrude_vert(obedit, em, SELECT, nor);
|
||||
else if (nr == 1) transmode= EDBM_Extrude_edge(obedit, em, SELECT, nor);
|
||||
else if(nr==4) transmode= EDBM_Extrude_verts_indiv(em, op, SELECT, nor);
|
||||
else if(nr==3) transmode= EDBM_Extrude_edges_indiv(em, SELECT, nor);
|
||||
else transmode= EDBM_Extrude_face_indiv(em, SELECT, nor);
|
||||
@@ -850,3 +817,126 @@ void MESH_OT_select_all_toggle(wmOperatorType *ot)
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
/* *************** add-click-mesh (extrude) operator ************** */
|
||||
|
||||
static int dupli_extrude_cursor(bContext *C, wmOperator *op, wmEvent *event)
|
||||
{
|
||||
#if 0 //BMESH_TODO
|
||||
ViewContext vc;
|
||||
EditVert *eve, *v1;
|
||||
float min[3], max[3];
|
||||
int done= 0;
|
||||
|
||||
em_setup_viewcontext(C, &vc);
|
||||
|
||||
INIT_MINMAX(min, max);
|
||||
|
||||
for(v1= vc.em->verts.first;v1; v1=v1->next) {
|
||||
if(v1->f & SELECT) {
|
||||
DO_MINMAX(v1->co, min, max);
|
||||
done= 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* call extrude? */
|
||||
if(done) {
|
||||
EditEdge *eed;
|
||||
float vec[3], cent[3], mat[3][3];
|
||||
float nor[3]= {0.0, 0.0, 0.0};
|
||||
|
||||
/* check for edges that are half selected, use for rotation */
|
||||
done= 0;
|
||||
for(eed= vc.em->edges.first; eed; eed= eed->next) {
|
||||
if( (eed->v1->f & SELECT)+(eed->v2->f & SELECT) == SELECT ) {
|
||||
if(eed->v1->f & SELECT) VecSubf(vec, eed->v1->co, eed->v2->co);
|
||||
else VecSubf(vec, eed->v2->co, eed->v1->co);
|
||||
VecAddf(nor, nor, vec);
|
||||
done= 1;
|
||||
}
|
||||
}
|
||||
if(done) Normalize(nor);
|
||||
|
||||
/* center */
|
||||
VecAddf(cent, min, max);
|
||||
VecMulf(cent, 0.5f);
|
||||
VECCOPY(min, cent);
|
||||
|
||||
Mat4MulVecfl(vc.obedit->obmat, min); // view space
|
||||
view3d_get_view_aligned_coordinate(&vc, min, event->mval);
|
||||
Mat4Invert(vc.obedit->imat, vc.obedit->obmat);
|
||||
Mat4MulVecfl(vc.obedit->imat, min); // back in object space
|
||||
|
||||
VecSubf(min, min, cent);
|
||||
|
||||
/* calculate rotation */
|
||||
Mat3One(mat);
|
||||
if(done) {
|
||||
float dot;
|
||||
|
||||
VECCOPY(vec, min);
|
||||
Normalize(vec);
|
||||
dot= INPR(vec, nor);
|
||||
|
||||
if( fabs(dot)<0.999) {
|
||||
float cross[3], si, q1[4];
|
||||
|
||||
Crossf(cross, nor, vec);
|
||||
Normalize(cross);
|
||||
dot= 0.5f*saacos(dot);
|
||||
si= (float)sin(dot);
|
||||
q1[0]= (float)cos(dot);
|
||||
q1[1]= cross[0]*si;
|
||||
q1[2]= cross[1]*si;
|
||||
q1[3]= cross[2]*si;
|
||||
|
||||
QuatToMat3(q1, mat);
|
||||
}
|
||||
}
|
||||
|
||||
extrudeflag(vc.obedit, vc.em, SELECT, nor);
|
||||
rotateflag(vc.em, SELECT, cent, mat);
|
||||
translateflag(vc.em, SELECT, min);
|
||||
|
||||
recalc_editnormals(vc.em);
|
||||
}
|
||||
else {
|
||||
float mat[3][3],imat[3][3];
|
||||
float *curs= give_cursor(vc.scene, vc.v3d);
|
||||
|
||||
VECCOPY(min, curs);
|
||||
view3d_get_view_aligned_coordinate(&vc, min, event->mval);
|
||||
|
||||
eve= addvertlist(vc.em, 0, NULL);
|
||||
|
||||
Mat3CpyMat4(mat, vc.obedit->obmat);
|
||||
Mat3Inv(imat, mat);
|
||||
|
||||
VECCOPY(eve->co, min);
|
||||
Mat3MulVecfl(imat, eve->co);
|
||||
VecSubf(eve->co, eve->co, vc.obedit->obmat[3]);
|
||||
|
||||
eve->f= SELECT;
|
||||
}
|
||||
|
||||
//retopo_do_all();
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, vc.obedit);
|
||||
DAG_object_flush_update(vc.scene, vc.obedit, OB_RECALC_DATA);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
#endif
|
||||
}
|
||||
|
||||
void MESH_OT_dupli_extrude_cursor(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name= "Duplicate or Extrude at 3D Cursor";
|
||||
ot->idname= "MESH_OT_dupli_extrude_cursor";
|
||||
|
||||
/* api callbacks */
|
||||
ot->invoke= dupli_extrude_cursor;
|
||||
ot->poll= ED_operator_editmesh;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
@@ -119,129 +119,6 @@ static short icoface[20][3] = {
|
||||
{10,9,11}
|
||||
};
|
||||
|
||||
/* *************** add-click-mesh (extrude) operator ************** */
|
||||
|
||||
static int dupli_extrude_cursor(bContext *C, wmOperator *op, wmEvent *event)
|
||||
{
|
||||
#if 0 //BMESH_TODO
|
||||
ViewContext vc;
|
||||
EditVert *eve, *v1;
|
||||
float min[3], max[3];
|
||||
int done= 0;
|
||||
|
||||
em_setup_viewcontext(C, &vc);
|
||||
|
||||
INIT_MINMAX(min, max);
|
||||
|
||||
for(v1= vc.em->verts.first;v1; v1=v1->next) {
|
||||
if(v1->f & SELECT) {
|
||||
DO_MINMAX(v1->co, min, max);
|
||||
done= 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* call extrude? */
|
||||
if(done) {
|
||||
EditEdge *eed;
|
||||
float vec[3], cent[3], mat[3][3];
|
||||
float nor[3]= {0.0, 0.0, 0.0};
|
||||
|
||||
/* check for edges that are half selected, use for rotation */
|
||||
done= 0;
|
||||
for(eed= vc.em->edges.first; eed; eed= eed->next) {
|
||||
if( (eed->v1->f & SELECT)+(eed->v2->f & SELECT) == SELECT ) {
|
||||
if(eed->v1->f & SELECT) VecSubf(vec, eed->v1->co, eed->v2->co);
|
||||
else VecSubf(vec, eed->v2->co, eed->v1->co);
|
||||
VecAddf(nor, nor, vec);
|
||||
done= 1;
|
||||
}
|
||||
}
|
||||
if(done) Normalize(nor);
|
||||
|
||||
/* center */
|
||||
VecAddf(cent, min, max);
|
||||
VecMulf(cent, 0.5f);
|
||||
VECCOPY(min, cent);
|
||||
|
||||
Mat4MulVecfl(vc.obedit->obmat, min); // view space
|
||||
view3d_get_view_aligned_coordinate(&vc, min, event->mval);
|
||||
Mat4Invert(vc.obedit->imat, vc.obedit->obmat);
|
||||
Mat4MulVecfl(vc.obedit->imat, min); // back in object space
|
||||
|
||||
VecSubf(min, min, cent);
|
||||
|
||||
/* calculate rotation */
|
||||
Mat3One(mat);
|
||||
if(done) {
|
||||
float dot;
|
||||
|
||||
VECCOPY(vec, min);
|
||||
Normalize(vec);
|
||||
dot= INPR(vec, nor);
|
||||
|
||||
if( fabs(dot)<0.999) {
|
||||
float cross[3], si, q1[4];
|
||||
|
||||
Crossf(cross, nor, vec);
|
||||
Normalize(cross);
|
||||
dot= 0.5f*saacos(dot);
|
||||
si= (float)sin(dot);
|
||||
q1[0]= (float)cos(dot);
|
||||
q1[1]= cross[0]*si;
|
||||
q1[2]= cross[1]*si;
|
||||
q1[3]= cross[2]*si;
|
||||
|
||||
QuatToMat3(q1, mat);
|
||||
}
|
||||
}
|
||||
|
||||
extrudeflag(vc.obedit, vc.em, SELECT, nor);
|
||||
rotateflag(vc.em, SELECT, cent, mat);
|
||||
translateflag(vc.em, SELECT, min);
|
||||
|
||||
recalc_editnormals(vc.em);
|
||||
}
|
||||
else {
|
||||
float mat[3][3],imat[3][3];
|
||||
float *curs= give_cursor(vc.scene, vc.v3d);
|
||||
|
||||
VECCOPY(min, curs);
|
||||
view3d_get_view_aligned_coordinate(&vc, min, event->mval);
|
||||
|
||||
eve= addvertlist(vc.em, 0, NULL);
|
||||
|
||||
Mat3CpyMat4(mat, vc.obedit->obmat);
|
||||
Mat3Inv(imat, mat);
|
||||
|
||||
VECCOPY(eve->co, min);
|
||||
Mat3MulVecfl(imat, eve->co);
|
||||
VecSubf(eve->co, eve->co, vc.obedit->obmat[3]);
|
||||
|
||||
eve->f= SELECT;
|
||||
}
|
||||
|
||||
//retopo_do_all();
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, vc.obedit);
|
||||
DAG_object_flush_update(vc.scene, vc.obedit, OB_RECALC_DATA);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
#endif
|
||||
}
|
||||
|
||||
void MESH_OT_dupli_extrude_cursor(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name= "Duplicate or Extrude at 3D Cursor";
|
||||
ot->idname= "MESH_OT_dupli_extrude_cursor";
|
||||
|
||||
/* api callbacks */
|
||||
ot->invoke= dupli_extrude_cursor;
|
||||
ot->poll= ED_operator_editmesh;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
|
||||
/* ********************** */
|
||||
|
||||
|
||||
@@ -265,7 +265,7 @@ void ED_keymap_mesh(wmWindowManager *wm)
|
||||
WM_keymap_add_item(keymap, "MESH_OT_tris_convert_to_quads", JKEY, KM_PRESS, KM_ALT, 0);
|
||||
|
||||
WM_keymap_add_item(keymap, "MESH_OT_split", FOURKEY, KM_PRESS, KM_CTRL, 0);
|
||||
WM_keymap_add_item(keymap, "MESH_OT_extrude_repeat", FOURKEY, KM_PRESS, KM_ALT, 0);
|
||||
WM_keymap_add_item(keymap, "MESH_OT_extrude_repeat", FOURKEY, KM_PRESS, KM_ALT|KM_CTRL, 0);
|
||||
WM_keymap_add_item(keymap, "MESH_OT_edge_rotate", FIVEKEY, KM_PRESS, KM_CTRL, 0);
|
||||
|
||||
WM_keymap_add_item(keymap, "MESH_OT_loop_to_region",SIXKEY, KM_PRESS, KM_CTRL, 0);
|
||||
|
||||
@@ -478,6 +478,7 @@ void recalcData(TransInfo *t)
|
||||
|
||||
DAG_object_flush_update(scene, t->obedit, OB_RECALC_DATA); /* sets recalc flags */
|
||||
|
||||
BMEdit_RecalcTesselation(em);
|
||||
EDBM_RecalcNormals(em);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user