Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTon Roosendaal <ton@blender.org>2009-02-07 18:44:16 +0300
committerTon Roosendaal <ton@blender.org>2009-02-07 18:44:16 +0300
commitd28a05080c10046bc480088a91296077f9d8165b (patch)
tree1a8eaa50936bdd7a937aeb15a6ca91b8edbb84d6 /source/blender/editors/mesh/editmesh_loop.c
parent875a08884ba670387299a0baef19ace90170d271 (diff)
2.5
Edit Mesh: Knife Cut back. I've put it for now under ALT+CTRL+LMB, modeless direct cutting. Options for polyline input and snapping is for later. At least this works cool :)
Diffstat (limited to 'source/blender/editors/mesh/editmesh_loop.c')
-rw-r--r--source/blender/editors/mesh/editmesh_loop.c238
1 files changed, 127 insertions, 111 deletions
diff --git a/source/blender/editors/mesh/editmesh_loop.c b/source/blender/editors/mesh/editmesh_loop.c
index bb41accc10d..d93ceaf07b8 100644
--- a/source/blender/editors/mesh/editmesh_loop.c
+++ b/source/blender/editors/mesh/editmesh_loop.c
@@ -52,6 +52,7 @@ editmesh_loop: tools with own drawing subloops, select, knife, subdiv
#include "BLI_editVert.h"
#include "BLI_ghash.h"
+#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_displist.h"
#include "BKE_global.h"
@@ -64,9 +65,14 @@ editmesh_loop: tools with own drawing subloops, select, knife, subdiv
#include "BIF_gl.h"
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "WM_api.h"
#include "WM_types.h"
#include "ED_mesh.h"
+#include "ED_screen.h"
#include "ED_view3d.h"
#include "mesh_intern.h"
@@ -75,7 +81,6 @@ editmesh_loop: tools with own drawing subloops, select, knife, subdiv
static void BIF_undo_push() {}
static void BIF_undo() {}
static void error() {}
-static int pupmenu() {return 0;}
static int qtest() {return 0;}
/* **** XXX ******** */
@@ -427,11 +432,6 @@ typedef struct CutCurve {
float y;
} CutCurve;
-static CutCurve *get_mouse_trail(int *len, char mode, char cutmode, struct GHash *gh)
-{
- return NULL; // XXX
-}
-
/* ******************************************************************** */
/* Knife Subdivide Tool. Subdivides edges intersected by a mouse trail
@@ -444,94 +444,24 @@ static CutCurve *get_mouse_trail(int *len, char mode, char cutmode, struct GHash
ESC cancels as expected.
Contributed by Robert Wenzlaff (Det. Thorn).
-*/
-/* prototype */
-static float seg_intersect(struct EditEdge * e, CutCurve *c, int len, char mode, struct GHash *gh);
+ 2.5 revamp:
+ - non modal (no menu before cutting)
+ - exit on mouse release
+ - polygon/segment drawing can become handled by WM cb later
-void KnifeSubdivide(Object *obedit, EditMesh *em, char mode)
-{
- EditEdge *eed;
- EditVert *eve;
- CutCurve *curve;
-
- struct GHash *gh;
- int len=0;
- float isect=0.0;
- short numcuts=1;
- float *scr, co[4];
-
- if (em==NULL) return;
-
- if (EM_nvertices_selected(em) < 2) {
- error("No edges are selected to operate on");
- return;
- }
-
- if (mode==KNIFE_PROMPT) {
- short val= pupmenu("Cut Type %t|Exact Line%x1|Midpoints%x2|Multicut%x3");
- if(val<1) return;
- mode = val; // warning, mode is char, pupmenu returns -1 with ESC
- }
-
- if(mode == KNIFE_MULTICUT) {
-// XXX if(button(&numcuts, 2, 128, "Number of Cuts:")==0) return;
- }
-
- /* XXX Set a knife cursor here */
-
- for(eed=em->edges.first; eed; eed= eed->next) eed->tmp.fp = 0.0; /*store percentage of edge cut for KNIFE_EXACT here.*/
-
- /*the floating point coordinates of verts in screen space will be stored in a hash table according to the vertices pointer*/
- gh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
- for(eve=em->verts.first; eve; eve=eve->next){
- scr = MEM_mallocN(sizeof(float)*2, "Vertex Screen Coordinates");
- VECCOPY(co, eve->co);
- co[3]= 1.0;
-// Mat4MulVec4fl(obedit->obmat, co);
-// XXX project_float(co,scr);
- BLI_ghash_insert(gh, eve, scr);
- eve->f1 = 0; /*store vertex intersection flag here*/
-
- }
-
- curve=get_mouse_trail(&len, TRAIL_MIXED, mode, gh);
-
- if (curve && len && mode){
- eed= em->edges.first;
- while(eed) {
- if( eed->v1->f & eed->v2->f & SELECT ){ // NOTE: uses vertex select, subdiv doesnt do edges yet
- isect=seg_intersect(eed, curve, len, mode, gh);
- if (isect) eed->f2= 1;
- else eed->f2=0;
- eed->tmp.fp= isect;
- //printf("isect=%i\n", isect);
- }
- else {
- eed->f2=0;
- eed->f1=0;
- }
- eed= eed->next;
- }
-
- if(mode==KNIFE_EXACT) esubdivideflag(obedit, em, SELECT, 0, B_KNIFE|B_PERCENTSUBD,1,SUBDIV_SELECT_ORIG);
- else if (mode==KNIFE_MIDPOINT) esubdivideflag(obedit, em, SELECT, 0, B_KNIFE,1,SUBDIV_SELECT_ORIG);
- else if (mode==KNIFE_MULTICUT) esubdivideflag(obedit, em, SELECT, 0, B_KNIFE,numcuts,SUBDIV_SELECT_ORIG);
+*/
- eed=em->edges.first;
- while(eed){
- eed->f2=0;
- eed->f1=0;
- eed=eed->next;
- }
- }
- /* Return to old cursor and flags...*/
-
- BLI_ghash_free(gh, NULL, (GHashValFreeFP)MEM_freeN);
- if (curve) MEM_freeN(curve);
+#define KNIFE_EXACT 1
+#define KNIFE_MIDPOINT 2
+#define KNIFE_MULTICUT 3
- BIF_undo_push("Knife");
-}
+static EnumPropertyItem knife_items[]= {
+ {KNIFE_EXACT, "EXACT", "Exact", ""},
+ {KNIFE_MIDPOINT, "MIDPOINTS", "Midpoints", ""},
+ {KNIFE_MULTICUT, "MULTICUT", "Multicut", ""},
+ {0, NULL, NULL}
+};
/* seg_intersect() Determines if and where a mouse trail intersects an EditEdge */
@@ -547,7 +477,7 @@ static float seg_intersect(EditEdge *e, CutCurve *c, int len, char mode, struct
int i;
//threshold = 0.000001; /*tolerance for vertex intersection*/
-// XXX threshold = scene->toolsettings->select_thresh / 100;
+ // XXX threshold = scene->toolsettings->select_thresh / 100;
/* Get screen coords of verts */
scr = BLI_ghash_lookup(gh, e->v1);
@@ -612,7 +542,7 @@ static float seg_intersect(EditEdge *e, CutCurve *c, int len, char mode, struct
/* Perp. Distance from point to line */
if (m2!=MAXSLOPE) dist=(y12-m2*x12-b2);/* /sqrt(m2*m2+1); Only looking for */
- /* change in sign. Skip extra math */
+ /* change in sign. Skip extra math */
else dist=x22-x12;
if (i==0) lastdist=dist;
@@ -635,7 +565,7 @@ static float seg_intersect(EditEdge *e, CutCurve *c, int len, char mode, struct
/* Found an intersect, calc intersect point */
if (m1==m2){ /* co-incident lines */
- /* cut at 50% of overlap area*/
+ /* cut at 50% of overlap area*/
x1max=MAX2(x11, x12);
x1min=MIN2(x11, x12);
xi= (MIN2(x2max,x1max)+MAX2(x2min,x1min))/2.0;
@@ -679,6 +609,7 @@ static float seg_intersect(EditEdge *e, CutCurve *c, int len, char mode, struct
if ((m2<=1.0)&&(m2>=-1.0)) perc = (xi-x21)/(x22-x21);
else perc=(yi-y21)/(y22-y21); /*lower slope more accurate*/
//isect=32768.0*(perc+0.0000153); /* Percentage in 1/32768ths */
+
break;
}
}
@@ -687,27 +618,112 @@ static float seg_intersect(EditEdge *e, CutCurve *c, int len, char mode, struct
return(perc);
}
-void LoopMenu(Object *obedit, EditMesh *em) /* Called by KKey */
+
+#define MAX_CUTS 256
+
+static int knife_cut_exec(bContext *C, wmOperator *op)
{
- short ret;
+ Object *obedit= CTX_data_edit_object(C);
+ EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ ARegion *ar= CTX_wm_region(C);
+ EditEdge *eed;
+ EditVert *eve;
+ CutCurve curve[MAX_CUTS];
+ struct GHash *gh;
+ float isect=0.0;
+ float *scr, co[4];
+ int len=0;
+ short numcuts=1, mode= RNA_int_get(op->ptr, "type");
- ret=pupmenu("Loop/Cut Menu %t|Loop Cut (CTRL-R)%x2|"
- "Knife (Exact) %x3|Knife (Midpoints)%x4|Knife (Multicut)%x5");
-
- switch (ret){
- case 2:
- CutEdgeloop(obedit, em, 1);
- break;
- case 3:
- KnifeSubdivide(obedit, em, KNIFE_EXACT);
- break;
- case 4:
- KnifeSubdivide(obedit, em, KNIFE_MIDPOINT);
- break;
- case 5:
- KnifeSubdivide(obedit, em, KNIFE_MULTICUT);
- break;
+ if (EM_nvertices_selected(em) < 2) {
+ error("No edges are selected to operate on");
+ return OPERATOR_CANCELLED;;
}
+ /* get the cut curve */
+ RNA_BEGIN(op->ptr, itemptr, "path") {
+
+ RNA_float_get_array(&itemptr, "loc", (float *)&curve[len]);
+ len++;
+ if(len>= MAX_CUTS) break;
+ }
+ RNA_END;
+
+ if(len<2) return OPERATOR_CANCELLED;
+
+ /*store percentage of edge cut for KNIFE_EXACT here.*/
+ for(eed=em->edges.first; eed; eed= eed->next)
+ eed->tmp.fp = 0.0;
+
+ /*the floating point coordinates of verts in screen space will be stored in a hash table according to the vertices pointer*/
+ gh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+ for(eve=em->verts.first; eve; eve=eve->next){
+ scr = MEM_mallocN(sizeof(float)*2, "Vertex Screen Coordinates");
+ VECCOPY(co, eve->co);
+ co[3]= 1.0;
+ Mat4MulVec4fl(obedit->obmat, co);
+ project_float(ar, co, scr);
+ BLI_ghash_insert(gh, eve, scr);
+ eve->f1 = 0; /*store vertex intersection flag here*/
+
+ }
+
+ eed= em->edges.first;
+ while(eed) {
+ if( eed->v1->f & eed->v2->f & SELECT ){ // NOTE: uses vertex select, subdiv doesnt do edges yet
+ isect= seg_intersect(eed, curve, len, mode, gh);
+ if (isect!=0.0f) eed->f2= 1;
+ else eed->f2=0;
+ eed->tmp.fp= isect;
+ //printf("isect=%i\n", isect);
+ }
+ else {
+ eed->f2=0;
+ eed->f1=0;
+ }
+ eed= eed->next;
+ }
+
+ if (mode==KNIFE_MIDPOINT) esubdivideflag(obedit, em, SELECT, 0, B_KNIFE, 1, SUBDIV_SELECT_ORIG);
+ else if (mode==KNIFE_MULTICUT) esubdivideflag(obedit, em, SELECT, 0, B_KNIFE, numcuts, SUBDIV_SELECT_ORIG);
+ else esubdivideflag(obedit, em, SELECT, 0, B_KNIFE|B_PERCENTSUBD, 1, SUBDIV_SELECT_ORIG);
+
+ eed=em->edges.first;
+ while(eed){
+ eed->f2=0;
+ eed->f1=0;
+ eed=eed->next;
+ }
+
+ BLI_ghash_free(gh, NULL, (GHashValFreeFP)MEM_freeN);
+
+ return OPERATOR_FINISHED;
+}
+
+
+void MESH_OT_knife_cut(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ ot->name= "Knife Cut";
+ ot->idname= "MESH_OT_knife_cut";
+
+ ot->invoke= WM_gesture_lines_invoke;
+ ot->modal= WM_gesture_lines_modal;
+ ot->exec= knife_cut_exec;
+
+ ot->poll= ED_operator_editmesh;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ RNA_def_enum(ot->srna, "type", knife_items, KNIFE_EXACT, "Type", "");
+ prop= RNA_def_property(ot->srna, "path", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_struct_runtime(prop, &RNA_OperatorMousePath);
+
+ /* internal */
+ RNA_def_int(ot->srna, "cursor", BC_KNIFECURSOR, 0, INT_MAX, "Cursor", "", 0, INT_MAX);
}
+/* ******************************************************* */
+