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:
authorCampbell Barton <ideasman42@gmail.com>2008-08-25 14:11:43 +0400
committerCampbell Barton <ideasman42@gmail.com>2008-08-25 14:11:43 +0400
commit01ba073f4654c7ee9e02721d451f9d028431820c (patch)
treea09af56e4b1e05494b6e8ee57218287397198b0e
parentb766ff4a0067a86855bdea600436ec1647599fda (diff)
svn merge -r 16239:HEAD https://svn.blender.org/svnroot/bf-blender/trunk/blender
-rw-r--r--source/blender/include/BIF_editview.h1
-rw-r--r--source/blender/include/transform.h2
-rw-r--r--source/blender/makesdna/DNA_gpencil_types.h2
-rw-r--r--source/blender/src/drawgpencil.c167
-rw-r--r--source/blender/src/editmesh_tools.c162
-rw-r--r--source/blender/src/editnode.c1
-rw-r--r--source/blender/src/editview.c2
-rw-r--r--source/blender/src/gpencil.c121
-rw-r--r--source/blender/src/transform_generics.c47
-rw-r--r--source/blender/src/transform_numinput.c14
-rw-r--r--source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp5
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<KX_GameObject *>(result))->GetSGNode())
{
result->AddRef();
return result;