adjust strokes by redrawing over them

(has to be turned on in the panel because it can give unexpected results sometimes right now)

http://vimeo.com/2753749

http://blenderartists.org/~theeth/bf/etch-a-ton/adjust.ogv
This commit is contained in:
Martin Poirier 2009-01-07 21:46:10 +00:00
parent 9b3727b5e0
commit 1240b0272d
3 changed files with 169 additions and 10 deletions

View File

@ -881,6 +881,7 @@ typedef struct Scene {
/* toolsettings->bone_sketching */
#define BONE_SKETCHING 1
#define BONE_SKETCHING_QUICK 2
#define BONE_SKETCHING_ADJUST 4
/* toolsettings->bone_sketching_convert */
#define SK_CONVERT_CUT_FIXED 1

View File

@ -2312,7 +2312,8 @@ static void view3d_panel_bonesketch_spaces(short cntrl)
uiBlockBeginAlign(block);
/* use real flag instead of 1 */
uiDefButBitC(block, TOG, BONE_SKETCHING, B_REDR, "Use Bone Sketching", 10, yco, 180, 20, &G.scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Use sketching to create and edit bones");
uiDefButBitC(block, TOG, BONE_SKETCHING, B_REDR, "Use Bone Sketching", 10, yco, 160, 20, &G.scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Use sketching to create and edit bones");
uiDefButBitC(block, TOG, BONE_SKETCHING_ADJUST, B_REDR, "A", 170, yco, 20, 20, &G.scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Adjust strokes by drawing near them");
uiDefButBitC(block, TOG, BONE_SKETCHING_QUICK, B_REDR, "Q", 190, yco, 20, 20, &G.scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Automatically convert and delete on stroke end");
yco -= 20;

View File

@ -92,6 +92,12 @@ typedef struct SK_Stroke
int selected;
} SK_Stroke;
typedef struct SK_Adjustment
{
SK_Stroke *target;
int start, end;
} SK_Adjustment;
#define SK_Stroke_BUFFER_INIT_SIZE 20
typedef struct SK_DrawData
@ -118,6 +124,7 @@ typedef struct SK_Sketch
SK_Stroke *active_stroke;
SK_Stroke *gesture;
SK_Point next_point;
SK_Adjustment adj;
} SK_Sketch;
typedef struct SK_StrokeIterator {
@ -836,6 +843,26 @@ void sk_growStrokeBuffer(SK_Stroke *stk)
}
}
void sk_growStrokeBufferN(SK_Stroke *stk, int n)
{
if (stk->nb_points + n > stk->buf_size)
{
SK_Point *old_points = stk->points;
while (stk->nb_points + n > stk->buf_size)
{
stk->buf_size *= 2;
}
sk_allocStrokeBuffer(stk);
memcpy(stk->points, old_points, sizeof(SK_Point) * stk->nb_points);
MEM_freeN(old_points);
}
}
void sk_replaceStrokePoint(SK_Stroke *stk, SK_Point *pt, int n)
{
memcpy(stk->points + n, pt, sizeof(SK_Point));
@ -863,6 +890,24 @@ void sk_appendStrokePoint(SK_Stroke *stk, SK_Point *pt)
stk->nb_points++;
}
void sk_inserStrokePoints(SK_Stroke *stk, SK_Point *pts, int len, int start, int end)
{
int size = end - start + 1;
sk_growStrokeBufferN(stk, len - size);
if (len != size)
{
int tail_size = stk->nb_points - end + 1;
memmove(stk->points + start + len, stk->points + end + 1, tail_size * sizeof(SK_Point));
}
memcpy(stk->points + start, pts, len * sizeof(SK_Point));
stk->nb_points += len - size;
}
void sk_trimStroke(SK_Stroke *stk, int start, int end)
{
int size = end - start + 1;
@ -1221,14 +1266,14 @@ void sk_drawStrokeSubdivision(SK_Stroke *stk)
}
}
SK_Point *sk_snapPointStroke(SK_Stroke *stk, short mval[2], int *dist)
SK_Point *sk_snapPointStroke(SK_Stroke *stk, short mval[2], int *dist, int *index)
{
SK_Point *pt = NULL;
int i;
for (i = 0; i < stk->nb_points; i++)
{
if (stk->points[i].type == PT_EXACT)
if (1) // stk->points[i].type == PT_EXACT)
{
short pval[2];
int pdist;
@ -1241,6 +1286,11 @@ SK_Point *sk_snapPointStroke(SK_Stroke *stk, short mval[2], int *dist)
{
*dist = pdist;
pt = stk->points + i;
if (index != NULL)
{
*index = i;
}
}
}
}
@ -1295,17 +1345,121 @@ SK_Point *sk_snapPointArmature(Object *ob, ListBase *ebones, short mval[2], int
return pt;
}
void sk_updateAdjust(SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
{
if (sketch->adj.target == NULL)
{
SK_Stroke *target;
int closest_index = 0;
int dist = SNAP_MIN_DISTANCE * 2;
for (target = sketch->strokes.first; target; target = target->next)
{
if (target != stk)
{
int index;
SK_Point *spt = sk_snapPointStroke(target, dd->mval, &dist, &index);
if (spt != NULL)
{
sketch->adj.target = target;
closest_index = index;
}
}
}
if (sketch->adj.target != NULL)
{
if (stk->nb_points == 1)
{
sketch->adj.start = closest_index;
}
else
{
sketch->adj.end = closest_index;
}
sketch->adj.target->selected = 1;
}
}
else if (sketch->adj.target != NULL)
{
SK_Point *closest_pt = NULL;
int dist = SNAP_MIN_DISTANCE * 2;
int index;
closest_pt = sk_snapPointStroke(sketch->adj.target, dd->mval, &dist, &index);
if (closest_pt != NULL)
{
sketch->adj.end = index;
}
else
{
sketch->adj.end = 0;
}
}
}
void sk_endAdjust(SK_Sketch *sketch)
{
SK_Stroke *stk = sketch->active_stroke;
if (sketch->adj.target)
{
int start = sketch->adj.start;
int end = sketch->adj.end;
if (end == 0)
{
end = sketch->adj.target->nb_points - 1;
}
else
{
sk_lastStrokePoint(stk)->type = PT_CONTINUOUS;
}
if (start != 0)
{
stk->points->type = PT_CONTINUOUS;
}
if (end < start)
{
int tmp = start;
start = end;
end = tmp;
sk_reverseStroke(stk);
}
sk_inserStrokePoints(sketch->adj.target, stk->points, stk->nb_points, start, end);
sk_removeStroke(sketch, stk);
}
}
void sk_startStroke(SK_Sketch *sketch)
{
SK_Stroke *stk = sk_createStroke();
BLI_addtail(&sketch->strokes, stk);
sketch->active_stroke = stk;
sketch->adj.target = NULL;
sketch->adj.start = 0;
sketch->adj.end = 0;
}
void sk_endStroke(SK_Sketch *sketch)
{
sk_shrinkStrokeBuffer(sketch->active_stroke);
if (G.scene->toolsettings->bone_sketching & BONE_SKETCHING_ADJUST)
{
sk_endAdjust(sketch);
}
sketch->active_stroke = NULL;
}
@ -1412,7 +1566,7 @@ int sk_getStrokeSnapPoint(SK_Point *pt, SK_Sketch *sketch, SK_Stroke *source_stk
for (stk = sketch->strokes.first; stk; stk = stk->next)
{
SK_Point *spt = sk_snapPointStroke(stk, dd->mval, &dist);
SK_Point *spt = sk_snapPointStroke(stk, dd->mval, &dist, NULL);
if (spt != NULL)
{
@ -1648,7 +1802,12 @@ void sk_addStrokePoint(SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd, short
if (point_added == 0)
{
point_added = sk_addStrokeDrawPoint(sketch, stk, dd);
}
}
if (G.scene->toolsettings->bone_sketching & BONE_SKETCHING_ADJUST)
{
sk_updateAdjust(sketch, stk, dd);
}
}
void sk_getStrokePoint(SK_Point *pt, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd, short qual)
@ -2749,6 +2908,9 @@ int sk_paint(SK_Sketch *sketch, short mbut)
if (sketch->active_stroke == NULL)
{
sk_startStroke(sketch);
sk_selectAllSketch(sketch, -1);
sketch->active_stroke->selected = 1;
}
sk_initDrawData(&dd);
@ -2806,11 +2968,6 @@ int sk_paint(SK_Sketch *sketch, short mbut)
sk_removeStroke(sketch, stk);
allqueue(REDRAWBUTSEDIT, 0);
}
else
{
sk_selectAllSketch(sketch, -1);
stk->selected = 1;
}
allqueue(REDRAWVIEW3D, 0);
}