From 01ba073f4654c7ee9e02721d451f9d028431820c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 25 Aug 2008 10:11:43 +0000 Subject: svn merge -r 16239:HEAD https://svn.blender.org/svnroot/bf-blender/trunk/blender --- source/blender/include/BIF_editview.h | 1 + source/blender/include/transform.h | 2 +- source/blender/makesdna/DNA_gpencil_types.h | 2 +- source/blender/src/drawgpencil.c | 167 ++++++++++++++------- source/blender/src/editmesh_tools.c | 162 +++++++++++++------- source/blender/src/editnode.c | 1 + source/blender/src/editview.c | 2 +- source/blender/src/gpencil.c | 121 ++++++++------- source/blender/src/transform_generics.c | 47 +----- source/blender/src/transform_numinput.c | 14 ++ .../gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp | 5 +- 11 files changed, 314 insertions(+), 210 deletions(-) diff --git a/source/blender/include/BIF_editview.h b/source/blender/include/BIF_editview.h index d2c6c56d01a..204733a19d6 100644 --- a/source/blender/include/BIF_editview.h +++ b/source/blender/include/BIF_editview.h @@ -40,6 +40,7 @@ void arrows_move_cursor(unsigned short event); void lasso_select_boundbox(struct rcti *rect, short mcords[][2], short moves); int lasso_inside(short mcords[][2], short moves, short sx, short sy); int lasso_inside_edge(short mcords[][2], short moves, int x0, int y0, int x1, int y1); +int edge_inside_circle(short centx, short centy, short rad, short x1, short y1, short x2, short y2); void borderselect(void); void circle_select(void); void deselectall(void); diff --git a/source/blender/include/transform.h b/source/blender/include/transform.h index 720b856a149..51fa39ff9d6 100644 --- a/source/blender/include/transform.h +++ b/source/blender/include/transform.h @@ -466,7 +466,6 @@ int validSnappingNormal(TransInfo *t); /*********************** Generics ********************************/ void initTrans(TransInfo *t); -void initTransModeFlags(TransInfo *t, int mode); void postTrans (TransInfo *t); void drawLine(float *center, float *dir, char axis, short options); @@ -498,6 +497,7 @@ TransInfo * BIF_GetTransInfo(void); /*********************** NumInput ********************************/ +void initNumInput(NumInput *n); void outputNumInput(NumInput *n, char *str); short hasNumInput(NumInput *n); void applyNumInput(NumInput *n, float *vec); diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h index 13d412c2c42..cc0c9912057 100644 --- a/source/blender/makesdna/DNA_gpencil_types.h +++ b/source/blender/makesdna/DNA_gpencil_types.h @@ -61,7 +61,7 @@ typedef struct bGPDstroke { #define GP_STROKE_2DSPACE (1<<1) /* stroke is in 2d-space (but with special 'image' scaling) */ #define GP_STROKE_2DIMAGE (1<<2) - /* stroke is an "eraser" stroke */ + /* only for use with stroke-buffer (while drawing eraser) */ #define GP_STROKE_ERASER (1<<15) diff --git a/source/blender/src/drawgpencil.c b/source/blender/src/drawgpencil.c index 22f7fdc32f0..dc9a880086f 100644 --- a/source/blender/src/drawgpencil.c +++ b/source/blender/src/drawgpencil.c @@ -323,6 +323,9 @@ enum { GP_DRAWDATA_ONLYI2D = (1<<3), /* only draw 'image' strokes */ }; +/* thickness above which we should use special drawing */ +#define GP_DRAWTHICKNESS_SPECIAL 3 + /* ----- Tool Buffer Drawing ------ */ /* draw stroke defined in buffer (simple ogl lines/points for now, as dotted lines) */ @@ -347,23 +350,13 @@ static void gp_draw_stroke_buffer (tGPspoint *points, int totpoints, short thick glEnd(); } else if (sflag & GP_STROKE_ERASER) { - /* draw stroke curve - just standard thickness */ - setlinestyle(4); - glLineWidth(1.0f); - - glBegin(GL_LINE_STRIP); - for (i=0, pt=points; i < totpoints && pt; i++, pt++) { - glVertex2f(pt->x, pt->y); - } - glEnd(); - - setlinestyle(0); + /* don't draw stroke at all! */ } else { float oldpressure = 0.0f; /* draw stroke curve */ - setlinestyle(2); + if (G.f & G_DEBUG) setlinestyle(2); glBegin(GL_LINE_STRIP); for (i=0, pt=points; i < totpoints && pt; i++, pt++) { @@ -381,14 +374,14 @@ static void gp_draw_stroke_buffer (tGPspoint *points, int totpoints, short thick } glEnd(); - setlinestyle(0); + if (G.f & G_DEBUG) setlinestyle(0); } } /* ----- Existing Strokes Drawing (3D and Point) ------ */ /* draw a given stroke - just a single dot (only one point) */ -static void gp_draw_stroke_point (bGPDspoint *points, short sflag, int winx, int winy) +static void gp_draw_stroke_point (bGPDspoint *points, short thickness, short sflag, int winx, int winy) { /* draw point */ if (sflag & GP_STROKE_3DSPACE) { @@ -396,18 +389,38 @@ static void gp_draw_stroke_point (bGPDspoint *points, short sflag, int winx, int glVertex3f(points->x, points->y, points->z); glEnd(); } - else if (sflag & GP_STROKE_2DSPACE) { - glBegin(GL_POINTS); - glVertex2f(points->x, points->y); - glEnd(); - } else { - const float x= (points->x / 1000 * winx); - const float y= (points->y / 1000 * winy); + float co[2]; - glBegin(GL_POINTS); - glVertex2f(x, y); - glEnd(); + /* get coordinates of point */ + if (sflag & GP_STROKE_2DSPACE) { + co[0]= points->x; + co[1]= points->y; + } + else { + co[0]= (points->x / 1000 * winx); + co[1]= (points->y / 1000 * winy); + } + + /* if thickness is less than GP_DRAWTHICKNESS_SPECIAL, simple opengl point will do */ + if (thickness < GP_DRAWTHICKNESS_SPECIAL) { + glBegin(GL_POINTS); + glVertex2fv(co); + glEnd(); + } + else { + /* draw filled circle as is done in circf (but without the matrix push/pops which screwed things up) */ + GLUquadricObj *qobj = gluNewQuadric(); + + gluQuadricDrawStyle(qobj, GLU_FILL); + + /* need to translate drawing position, but must reset after too! */ + glTranslatef(co[0], co[1], 0.); + gluDisk( qobj, 0.0, thickness, 32, 1); + glTranslatef(-co[0], -co[1], 0.); + + gluDeleteQuadric(qobj); + } } } @@ -449,8 +462,8 @@ static void gp_draw_stroke_3d (bGPDspoint *points, int totpoints, short thicknes /* draw a given stroke in 2d */ static void gp_draw_stroke (bGPDspoint *points, int totpoints, short thickness, short dflag, short sflag, short debug, int winx, int winy) { - /* if thickness is less than 3, 'smooth' opengl lines look better */ - if ((thickness < 3) || (G.rt==0)) { + /* if thickness is less than GP_DRAWTHICKNESS_SPECIAL, 'smooth' opengl lines look better */ + if (thickness < GP_DRAWTHICKNESS_SPECIAL) { bGPDspoint *pt; int i; @@ -472,19 +485,15 @@ static void gp_draw_stroke (bGPDspoint *points, int totpoints, short thickness, bGPDspoint *pt1, *pt2; float pm[2]; int i; - short n; glShadeModel(GL_FLAT); - - glPointSize(3.0f); // temp - - for (n= 0; n < 2; n++) { // temp - glBegin((n)?GL_POINTS:GL_QUADS); + glBegin(GL_QUADS); for (i=0, pt1=points, pt2=points+1; i < (totpoints-1); i++, pt1++, pt2++) { float s0[2], s1[2]; /* segment 'center' points */ float t0[2], t1[2]; /* tesselated coordinates */ float m1[2], m2[2]; /* gradient and normal */ + float mt[2], sc[2]; /* gradient for thickness, point for end-cap */ float pthick; /* thickness at segment point */ /* get x and y coordinates from points */ @@ -502,42 +511,75 @@ static void gp_draw_stroke (bGPDspoint *points, int totpoints, short thickness, /* calculate gradient and normal - 'angle'=(ny/nx) */ m1[1]= s1[1] - s0[1]; m1[0]= s1[0] - s0[0]; + Normalize2(m1); m2[1]= -m1[0]; m2[0]= m1[1]; - Normalize2(m2); /* always use pressure from first point here */ pthick= (pt1->pressure * thickness); /* if the first segment, start of segment is segment's normal */ if (i == 0) { - // TODO: also draw/do a round end-cap first + /* draw start cap first + * - make points slightly closer to center (about halfway across) + */ + mt[0]= m2[0] * pthick * 0.5; + mt[1]= m2[1] * pthick * 0.5; + sc[0]= s0[0] - (m1[0] * pthick * 0.75); + sc[1]= s0[1] - (m1[1] * pthick * 0.75); + + t0[0]= sc[0] - mt[0]; + t0[1]= sc[1] - mt[1]; + t1[0]= sc[0] + mt[0]; + t1[1]= sc[1] + mt[1]; + + glVertex2fv(t0); + glVertex2fv(t1); /* calculate points for start of segment */ - t0[0]= s0[0] - (pthick * m2[0]); - t0[1]= s0[1] - (pthick * m2[1]); - t1[0]= s0[0] + (pthick * m2[0]); - t1[1]= s0[1] + (pthick * m2[1]); + mt[0]= m2[0] * pthick; + mt[1]= m2[1] * pthick; + + t0[0]= s0[0] - mt[0]; + t0[1]= s0[1] - mt[1]; + t1[0]= s0[0] + mt[0]; + t1[1]= s0[1] + mt[1]; - /* draw this line only once */ + /* draw this line twice (first to finish off start cap, then for stroke) */ + glVertex2fv(t1); + glVertex2fv(t0); glVertex2fv(t0); glVertex2fv(t1); } /* if not the first segment, use bisector of angle between segments */ else { - float mb[2]; /* bisector normal */ + float mb[2]; /* bisector normal */ + float athick, dfac; /* actual thickness, difference between thicknesses */ /* calculate gradient of bisector (as average of normals) */ mb[0]= (pm[0] + m2[0]) / 2; mb[1]= (pm[1] + m2[1]) / 2; Normalize2(mb); + /* calculate gradient to apply + * - as basis, use just pthick * bisector gradient + * - if cross-section not as thick as it should be, add extra padding to fix it + */ + mt[0]= mb[0] * pthick; + mt[1]= mb[1] * pthick; + athick= Vec2Length(mt); + dfac= pthick - (athick * 2); + if ( ((athick * 2) < pthick) && (IS_EQ(athick, pthick)==0) ) + { + mt[0] += (mb[0] * dfac); + mt[1] += (mb[1] * dfac); + } + /* calculate points for start of segment */ - // FIXME: do we need extra padding for acute angles? - t0[0]= s0[0] - (pthick * mb[0]); - t0[1]= s0[1] - (pthick * mb[1]); - t1[0]= s0[0] + (pthick * mb[0]); - t1[1]= s0[1] + (pthick * mb[1]); + t0[0]= s0[0] - mt[0]; + t0[1]= s0[1] - mt[1]; + t1[0]= s0[0] + mt[0]; + t1[1]= s0[1] + mt[1]; /* draw this line twice (once for end of current segment, and once for start of next) */ glVertex2fv(t1); @@ -552,16 +594,36 @@ static void gp_draw_stroke (bGPDspoint *points, int totpoints, short thickness, pthick= (pt2->pressure * thickness); /* calculate points for end of segment */ - t0[0]= s1[0] - (pthick * m2[0]); - t0[1]= s1[1] - (pthick * m2[1]); - t1[0]= s1[0] + (pthick * m2[0]); - t1[1]= s1[1] + (pthick * m2[1]); + mt[0]= m2[0] * pthick; + mt[1]= m2[1] * pthick; + + t0[0]= s1[0] - mt[0]; + t0[1]= s1[1] - mt[1]; + t1[0]= s1[0] + mt[0]; + t1[1]= s1[1] + mt[1]; - /* draw this line only once */ + /* draw this line twice (once for end of stroke, and once for endcap)*/ glVertex2fv(t1); glVertex2fv(t0); + glVertex2fv(t0); + glVertex2fv(t1); + - // TODO: draw end cap as last step + /* draw end cap as last step + * - make points slightly closer to center (about halfway across) + */ + mt[0]= m2[0] * pthick * 0.5; + mt[1]= m2[1] * pthick * 0.5; + sc[0]= s1[0] + (m1[0] * pthick * 0.75); + sc[1]= s1[1] + (m1[1] * pthick * 0.75); + + t0[0]= sc[0] - mt[0]; + t0[1]= sc[1] - mt[1]; + t1[0]= sc[0] + mt[0]; + t1[1]= sc[1] + mt[1]; + + glVertex2fv(t1); + glVertex2fv(t0); } /* store stroke's 'natural' normal for next stroke to use */ @@ -569,7 +631,6 @@ static void gp_draw_stroke (bGPDspoint *points, int totpoints, short thickness, } glEnd(); - } } /* draw debug points of curve on top? (original stroke points) */ @@ -623,7 +684,7 @@ static void gp_draw_strokes (bGPDframe *gpf, int winx, int winy, int dflag, shor /* check which stroke-drawer to use */ if (gps->totpoints == 1) - gp_draw_stroke_point(gps->points, gps->flag, winx, winy); + gp_draw_stroke_point(gps->points, lthick, gps->flag, winx, winy); else if (dflag & GP_DRAWDATA_ONLY3D) gp_draw_stroke_3d(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, winx, winy); else if (gps->totpoints > 1) diff --git a/source/blender/src/editmesh_tools.c b/source/blender/src/editmesh_tools.c index acabac11a2a..aa56d0a7cdb 100644 --- a/source/blender/src/editmesh_tools.c +++ b/source/blender/src/editmesh_tools.c @@ -4683,6 +4683,7 @@ int EdgeLoopDelete(void) { int EdgeSlide(short immediate, float imperc) { + NumInput num; EditMesh *em = G.editMesh; EditFace *efa; EditEdge *eed,*first=NULL,*last=NULL, *temp = NULL; @@ -4709,6 +4710,8 @@ int EdgeSlide(short immediate, float imperc) char str[128]; float labda = 0.0f; + initNumInput(&num); + view3d_get_object_project_mat(curarea, G.obedit, projectMat, viewMat); mvalo[0] = -1; mvalo[1] = -1; @@ -5113,17 +5116,84 @@ int EdgeSlide(short immediate, float imperc) float v2[2], v3[2]; EditVert *centerVert, *upVert, *downVert; - - getmouseco_areawin(mval); if (!immediate && (mval[0] == mvalo[0] && mval[1] == mvalo[1])) { PIL_sleep_ms(10); } else { + char *p = str;; mvalo[0] = mval[0]; mvalo[1] = mval[1]; + + tempsv = BLI_ghash_lookup(vertgh,nearest); + + centerVert = editedge_getSharedVert(tempsv->up, tempsv->down); + upVert = editedge_getOtherVert(tempsv->up, centerVert); + downVert = editedge_getOtherVert(tempsv->down, centerVert); + + view3d_project_float(curarea, upVert->co, v2, projectMat); + view3d_project_float(curarea, downVert->co, v3, projectMat); + + /* Determine the % on which the loop should be cut */ + + rc[0]= v3[0]-v2[0]; + rc[1]= v3[1]-v2[1]; + len= rc[0]*rc[0]+ rc[1]*rc[1]; + if (len==0) {len = 0.0001;} + + if ((G.qual & LR_SHIFTKEY)==0) { + wasshift = 0; + labda= ( rc[0]*((mval[0]-v2[0])) + rc[1]*((mval[1]-v2[1])) )/len; + } + else { + if (wasshift==0) { + wasshift = 1; + shiftlabda = labda; + } + labda= ( rc[0]*((mval[0]-v2[0])) + rc[1]*((mval[1]-v2[1])) )/len / 10.0 + shiftlabda; + } + + + if(labda<=0.0) labda=0.0; + else if(labda>=1.0)labda=1.0; + + perc=((1-labda)*2)-1; + + if(G.qual == 0) { + perc *= 100; + perc = floor(perc); + perc /= 100; + } else if (G.qual == LR_CTRLKEY) { + perc *= 10; + perc = floor(perc); + perc /= 10; + } + + if(prop == 0) { + len = VecLenf(upVert->co,downVert->co)*((perc+1)/2); + if(flip == 1) { + len = VecLenf(upVert->co,downVert->co) - len; + } + } + + if (hasNumInput(&num)) + { + applyNumInput(&num, &perc); + + if (prop) + { + perc = MIN2(perc, 1); + perc = MAX2(perc, -1); + } + else + { + len = MIN2(perc, VecLenf(upVert->co,downVert->co)); + len = MAX2(len, 0); + } + } + //Adjust Edgeloop if(immediate) { perc = imperc; @@ -5205,13 +5275,7 @@ int EdgeSlide(short immediate, float imperc) } - tempsv = BLI_ghash_lookup(vertgh,nearest); - - centerVert = editedge_getSharedVert(tempsv->up, tempsv->down); - upVert = editedge_getOtherVert(tempsv->up, centerVert); - downVert = editedge_getOtherVert(tempsv->down, centerVert); // Highlight the Control Edges - scrarea_do_windraw(curarea); persp(PERSP_VIEW); glPushMatrix(); @@ -5239,55 +5303,36 @@ int EdgeSlide(short immediate, float imperc) glPopMatrix(); - view3d_project_float(curarea, upVert->co, v2, projectMat); - view3d_project_float(curarea, downVert->co, v3, projectMat); - - /* Determine the % on which the loop should be cut */ - - rc[0]= v3[0]-v2[0]; - rc[1]= v3[1]-v2[1]; - len= rc[0]*rc[0]+ rc[1]*rc[1]; - if (len==0) {len = 0.0001;} - - if ((G.qual & LR_SHIFTKEY)==0) { - wasshift = 0; - labda= ( rc[0]*((mval[0]-v2[0])) + rc[1]*((mval[1]-v2[1])) )/len; + if(prop) { + p += sprintf(str, "(P)ercentage: "); + } else { + p += sprintf(str, "Non (P)rop Length: "); } - else { - if (wasshift==0) { - wasshift = 1; - shiftlabda = labda; - } - labda= ( rc[0]*((mval[0]-v2[0])) + rc[1]*((mval[1]-v2[1])) )/len / 10.0 + shiftlabda; + + if (hasNumInput(&num)) + { + char num_str[20]; + + outputNumInput(&num, num_str); + p += sprintf(p, "%s", num_str); + } + else + { + if (prop) + { + p += sprintf(p, "%f", perc); + } + else + { + p += sprintf(p, "%f", len); + } } - - if(labda<=0.0) labda=0.0; - else if(labda>=1.0)labda=1.0; - - perc=((1-labda)*2)-1; - if(G.qual == 0) { - perc *= 100; - perc = floor(perc); - perc /= 100; - } else if (G.qual == LR_CTRLKEY) { - perc *= 10; - perc = floor(perc); - perc /= 10; - } - if(prop) { - sprintf(str, "(P)ercentage: %f", perc); - } else { - len = VecLenf(upVert->co,downVert->co)*((perc+1)/2); - if(flip == 1) { - len = VecLenf(upVert->co,downVert->co) - len; - } - sprintf(str, "Non (P)rop Length: %f, Press (F) to flip control side", len); + if (prop == 0) { + p += sprintf(p, ", Press (F) to flip control side"); } - - headerprint(str); screen_swapbuffers(); } @@ -5310,7 +5355,14 @@ int EdgeSlide(short immediate, float imperc) perc = 0; immediate = 1; } else if(event==PKEY) { - (prop == 1) ? (prop = 0):(prop = 1); + initNumInput(&num); /* reset num input */ + if (prop) { + prop = 0; + num.flag |= NUM_NO_NEGATIVE; + } + else { + prop = 1; + } mvalo[0] = -1; } else if(event==FKEY) { (flip == 1) ? (flip = 0):(flip = 1); @@ -5348,7 +5400,13 @@ int EdgeSlide(short immediate, float imperc) look = look->next; } } + + if (handleNumInput(&num, event)) + { + mvalo[0] = -1; /* NEED A BETTER WAY TO TRIGGER REDRAW */ + } } + } } else { draw = 0; diff --git a/source/blender/src/editnode.c b/source/blender/src/editnode.c index 98f4f1bb46f..eba6c5b4488 100644 --- a/source/blender/src/editnode.c +++ b/source/blender/src/editnode.c @@ -2110,6 +2110,7 @@ static void node_border_link_delete(SpaceNode *snode) mval[1]= rect.ymax; areamouseco_to_ipoco(&snode->v2d, mval, &rectf.xmax, &rectf.ymax); + glLoadIdentity(); myortho2(rectf.xmin, rectf.xmax, rectf.ymin, rectf.ymax); glSelectBuffer(256, buffer); diff --git a/source/blender/src/editview.c b/source/blender/src/editview.c index 8110714e327..2133a92a54e 100644 --- a/source/blender/src/editview.c +++ b/source/blender/src/editview.c @@ -1631,7 +1631,7 @@ void mouse_select(void) /* ------------------------------------------------------------------------- */ -static int edge_inside_circle(short centx, short centy, short rad, short x1, short y1, short x2, short y2) +int edge_inside_circle(short centx, short centy, short rad, short x1, short y1, short x2, short y2) { int radsq= rad*rad; float v1[2], v2[2], v3[2]; diff --git a/source/blender/src/gpencil.c b/source/blender/src/gpencil.c index 9b250fc3ec0..2ea806cf0f9 100644 --- a/source/blender/src/gpencil.c +++ b/source/blender/src/gpencil.c @@ -707,6 +707,10 @@ typedef struct tGPsdata { short status; /* current status of painting */ short paintmode; /* mode for painting */ + + short mval[2]; /* current mouse-position */ + short mvalo[2]; /* previous recorded mouse-position */ + short radius; /* radius of influence for eraser */ } tGPsdata; /* values for tGPsdata->status */ @@ -1037,30 +1041,6 @@ static void gp_stroke_newfrombuffer (tGPsdata *p) } /* --- 'Eraser' for 'Paint' Tool ------ */ -/* User should draw 'circles' around the parts of the sketches they wish to - * delete instead of drawing squiggles over existing lines. This should be - * easier to manage than if it was done otherwise. - */ - -/* convert gp-buffer stroke into mouse-coordinates array */ -static short (*gp_stroke_eraser_2mco (bGPdata *gpd))[2] -{ - tGPspoint *pt; - short (*mcoords)[2]; - int i; - - /* allocate memory for coordinates array */ - mcoords= MEM_mallocN(sizeof(*mcoords)*gpd->sbuffer_size,"gp_buf_mcords"); - - /* copy coordinates */ - for (pt=gpd->sbuffer, i=0; i < gpd->sbuffer_size; i++, pt++) { - mcoords[i][0]= pt->x; - mcoords[i][1]= pt->y; - } - - /* return */ - return mcoords; -} /* eraser tool - remove segment from stroke/split stroke (after lasso inside) */ static short gp_stroke_eraser_splitdel (bGPDframe *gpf, bGPDstroke *gps, int i) @@ -1130,8 +1110,20 @@ static short gp_stroke_eraser_splitdel (bGPDframe *gpf, bGPDstroke *gps, int i) } } +/* eraser tool - check if part of stroke occurs within last segment drawn by eraser */ +static short gp_stroke_eraser_strokeinside (short mval[], short mvalo[], short rad, short x0, short y0, short x1, short y1) +{ + /* step 1: check if within the radius for the new one */ + /* simple within-radius check */ + if (edge_inside_circle(mval[0], mval[1], rad, x0, y0, x1, y1)) + return 1; + + /* step 2: check if within the quad formed between the two eraser coords */ + return 0; +} + /* eraser tool - evaluation per stroke */ -static void gp_stroke_eraser_dostroke (tGPsdata *p, short mcoords[][2], short moves, rcti *rect, bGPDframe *gpf, bGPDstroke *gps) +static void gp_stroke_eraser_dostroke (tGPsdata *p, short mval[], short mvalo[], short rad, rcti *rect, bGPDframe *gpf, bGPDstroke *gps) { bGPDspoint *pt1, *pt2; short x0=0, y0=0, x1=0, y1=0; @@ -1147,10 +1139,9 @@ static void gp_stroke_eraser_dostroke (tGPsdata *p, short mcoords[][2], short mo else if (gps->totpoints == 1) { /* get coordinates */ if (gps->flag & GP_STROKE_3DSPACE) { - // FIXME: this may not be the correct correction project_short(&gps->points->x, xyval); x0= xyval[0]; - x1= xyval[1]; + y0= xyval[1]; } else if (gps->flag & GP_STROKE_2DSPACE) { ipoco_to_areaco_noclip(p->v2d, &gps->points->x, xyval); @@ -1165,7 +1156,7 @@ static void gp_stroke_eraser_dostroke (tGPsdata *p, short mcoords[][2], short mo /* do boundbox check first */ if (BLI_in_rcti(rect, x0, y0)) { /* only check if point is inside */ - if (lasso_inside(mcoords, moves, x0, y0)) { + if ( ((x0-mval[0])*(x0-mval[0]) + (y0-mval[1])*(y0-mval[1])) <= rad*rad ) { /* free stroke */ MEM_freeN(gps->points); BLI_freelinkN(&gpf->strokes, gps); @@ -1183,10 +1174,9 @@ static void gp_stroke_eraser_dostroke (tGPsdata *p, short mcoords[][2], short mo /* get coordinates */ if (gps->flag & GP_STROKE_3DSPACE) { - // FIXME: may not be correct correction project_short(&gps->points->x, xyval); x0= xyval[0]; - x1= xyval[1]; + y0= xyval[1]; } else if (gps->flag & GP_STROKE_2DSPACE) { ipoco_to_areaco_noclip(p->v2d, &pt1->x, xyval); @@ -1211,7 +1201,7 @@ static void gp_stroke_eraser_dostroke (tGPsdata *p, short mcoords[][2], short mo * - this assumes that linewidth is irrelevant * - handled using the lasso-select checking code */ - if (lasso_inside_edge(mcoords, moves, x0, y0, x1, x1)) { + if (gp_stroke_eraser_strokeinside(mval, mvalo, rad, x0, y0, x1, y1)) { /* if function returns true, break this loop (as no more point to check) */ if (gp_stroke_eraser_splitdel(gpf, gps, i)) break; @@ -1226,24 +1216,21 @@ static void gp_stroke_eraser_dostroke (tGPsdata *p, short mcoords[][2], short mo /* erase strokes which fall under the eraser strokes */ static void gp_stroke_doeraser (tGPsdata *p) { - bGPdata *gpd= p->gpd; bGPDframe *gpf= p->gpf; bGPDstroke *gps, *gpn; - short (*mcoords)[2]; rcti rect; - /* get buffer-stroke coordinates as shorts array, and then get bounding box */ - mcoords= gp_stroke_eraser_2mco(gpd); - lasso_select_boundbox(&rect, mcoords, gpd->sbuffer_size); + /* rect is rectangle of eraser */ + rect.xmin= p->mval[0] - p->radius; + rect.ymin= p->mval[1] - p->radius; + rect.xmax= p->mval[0] + p->radius; + rect.ymax= p->mval[1] + p->radius; /* loop over strokes, checking segments for intersections */ for (gps= gpf->strokes.first; gps; gps= gpn) { gpn= gps->next; - gp_stroke_eraser_dostroke(p, mcoords, gpd->sbuffer_size, &rect, gpf, gps); + gp_stroke_eraser_dostroke(p, p->mval, p->mvalo, p->radius, &rect, gpf, gps); } - - /* free mcoords array */ - MEM_freeN(mcoords); } /* ---------- 'Paint' Tool ------------ */ @@ -1308,8 +1295,7 @@ static void gp_paint_strokeend (tGPsdata *p) { /* check if doing eraser or not */ if (p->gpd->sbuffer_sflag & GP_STROKE_ERASER) { - /* get rid of relevant sections of strokes */ - gp_stroke_doeraser(p); + /* don't do anything */ } else { /* transfer stroke to frame */ @@ -1345,7 +1331,6 @@ static void gp_paint_cleanup (tGPsdata *p) short gpencil_paint (short mousebutton, short paintmode) { tGPsdata p; - short prevmval[2], mval[2]; float opressure, pressure; short ok = GP_STROKEADD_NORMAL; @@ -1365,31 +1350,51 @@ short gpencil_paint (short mousebutton, short paintmode) setcursor_space(p.sa->spacetype, CURSOR_VPAINT); /* init drawing-device settings */ - getmouseco_areawin(mval); + getmouseco_areawin(p.mval); pressure = get_pressure(); - prevmval[0]= mval[0]; - prevmval[1]= mval[1]; + p.mvalo[0]= p.mval[0]; + p.mvalo[1]= p.mval[1]; opressure= pressure; + /* radius for eraser circle is thickness^2 */ + p.radius= p.gpl->thickness * p.gpl->thickness; + + /* start drawing eraser-circle (if applicable) */ + if (paintmode == GP_PAINTMODE_ERASER) + draw_sel_circle(p.mval, NULL, p.radius, p.radius, 0); // draws frontbuffer, but sets backbuf again + /* only allow painting of single 'dots' if: * - pressure is not excessive (as it can be on some windows tablets) * - draw-mode for active datablock is turned on + * - not erasing */ - if (!(pressure >= 0.99f) || (p.gpd->flag & GP_DATA_EDITPAINT)) { - gp_stroke_addpoint(&p, mval, pressure); + if (paintmode != GP_PAINTMODE_ERASER) { + if (!(pressure >= 0.99f) || (p.gpd->flag & GP_DATA_EDITPAINT)) { + gp_stroke_addpoint(&p, p.mval, pressure); + } } /* paint loop */ do { /* get current user input */ - getmouseco_areawin(mval); + getmouseco_areawin(p.mval); pressure = get_pressure(); /* only add current point to buffer if mouse moved (otherwise wait until it does) */ - if (gp_stroke_filtermval(&p, mval, prevmval)) { + if (paintmode == GP_PAINTMODE_ERASER) { + /* do 'live' erasing now */ + gp_stroke_doeraser(&p); + + draw_sel_circle(p.mval, p.mvalo, p.radius, p.radius, 0); + force_draw(0); + + p.mvalo[0]= p.mval[0]; + p.mvalo[1]= p.mval[1]; + } + else if (gp_stroke_filtermval(&p, p.mval, p.mvalo)) { /* try to add point */ - ok= gp_stroke_addpoint(&p, mval, pressure); + ok= gp_stroke_addpoint(&p, p.mval, pressure); /* handle errors while adding point */ if ((ok == GP_STROKEADD_FULL) || (ok == GP_STROKEADD_OVERFLOW)) { @@ -1397,8 +1402,8 @@ short gpencil_paint (short mousebutton, short paintmode) gp_paint_strokeend(&p); /* start a new stroke, starting from previous point */ - gp_stroke_addpoint(&p, prevmval, opressure); - ok= gp_stroke_addpoint(&p, mval, pressure); + gp_stroke_addpoint(&p, p.mvalo, opressure); + ok= gp_stroke_addpoint(&p, p.mval, pressure); } else if (ok == GP_STROKEADD_INVALID) { /* the painting operation cannot continue... */ @@ -1411,8 +1416,8 @@ short gpencil_paint (short mousebutton, short paintmode) } force_draw(0); - prevmval[0]= mval[0]; - prevmval[1]= mval[1]; + p.mvalo[0]= p.mval[0]; + p.mvalo[1]= p.mval[1]; opressure= pressure; } else @@ -1430,8 +1435,10 @@ short gpencil_paint (short mousebutton, short paintmode) setcursor_space(p.sa->spacetype, CURSOR_STD); /* check size of buffer before cleanup, to determine if anything happened here */ - if (paintmode == GP_PAINTMODE_ERASER) - ok= (p.gpd->sbuffer_size > 1); + if (paintmode == GP_PAINTMODE_ERASER) { + ok= 1; // fixme + draw_sel_circle(NULL, p.mvalo, 0, p.radius, 0); + } else ok= p.gpd->sbuffer_size; diff --git a/source/blender/src/transform_generics.c b/source/blender/src/transform_generics.c index ead666564a0..86eb1571069 100644 --- a/source/blender/src/transform_generics.c +++ b/source/blender/src/transform_generics.c @@ -616,39 +616,6 @@ void recalcData(TransInfo *t) reshadeall_displist(); } -void initTransModeFlags(TransInfo *t, int mode) -{ - t->mode = mode; - t->num.flag = 0; - - /* REMOVING RESTRICTIONS FLAGS */ - t->flag &= ~T_ALL_RESTRICTIONS; - - switch (mode) { - case TFM_RESIZE: - t->flag |= T_NULL_ONE; - t->num.flag |= NUM_NULL_ONE; - t->num.flag |= NUM_AFFECT_ALL; - if (!G.obedit) { - t->flag |= T_NO_ZERO; - t->num.flag |= NUM_NO_ZERO; - } - break; - case TFM_TOSPHERE: - t->num.flag |= NUM_NULL_ONE; - t->num.flag |= NUM_NO_NEGATIVE; - t->flag |= T_NO_CONSTRAINT; - break; - case TFM_SHEAR: - case TFM_CREASE: - case TFM_BONE_ENVELOPE: - case TFM_CURVE_SHRINKFATTEN: - case TFM_BONE_ROLL: - t->flag |= T_NO_CONSTRAINT; - break; - } -} - void drawLine(float *center, float *dir, char axis, short options) { extern void make_axis_color(char *col, char *col2, char axis); // drawview.c @@ -706,19 +673,10 @@ void initTrans (TransInfo *t) t->transform = NULL; t->handleEvent = NULL; - t->total = - t->num.idx = - t->num.idx_max = - t->num.ctrl[0] = - t->num.ctrl[1] = - t->num.ctrl[2] = 0; + t->total = 0; t->val = 0.0f; - t->num.val[0] = - t->num.val[1] = - t->num.val[2] = 0.0f; - t->vec[0] = t->vec[1] = t->vec[2] = 0.0f; @@ -740,7 +698,8 @@ void initTrans (TransInfo *t) t->around = V3D_CENTER; setTransformViewMatrices(t); - initNDofInput(&(t->ndof)); + initNumInput(&t->num); + initNDofInput(&t->ndof); } /* Here I would suggest only TransInfo related issues, like free data & reset vars. Not redraws */ diff --git a/source/blender/src/transform_numinput.c b/source/blender/src/transform_numinput.c index 9b811595a9a..89a76c097e0 100644 --- a/source/blender/src/transform_numinput.c +++ b/source/blender/src/transform_numinput.c @@ -41,6 +41,20 @@ /* ************************** NUMINPUT **************************** */ +void initNumInput(NumInput *n) +{ + n->flag = + n->idx = + n->idx_max = + n->ctrl[0] = + n->ctrl[1] = + n->ctrl[2] = 0; + + n->val[0] = + n->val[1] = + n->val[2] = 0.0f; +} + void outputNumInput(NumInput *n, char *str) { char cur; diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp index ca0106d64d9..7e0d0df1ab7 100644 --- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp @@ -377,7 +377,10 @@ PyObject* KX_SCA_AddObjectActuator::PyGetLastCreatedObject(PyObject* self, PyObject* kwds) { SCA_IObject* result = this->GetLastCreatedObject(); - if (result) + + // if result->GetSGNode() is NULL + // it means the object has ended, The BGE python api crashes in many places if the object is returned. + if (result && (static_cast(result))->GetSGNode()) { result->AddRef(); return result; -- cgit v1.2.3