changes to ruler

- click-drag adds a ruler if there are none.
- pressing enter stores the ruler for re-use when activating again (saves as a grease-pencil layer).
- add to toolbar.
This commit is contained in:
Campbell Barton 2013-03-08 18:17:12 +00:00
parent b16f24c944
commit 743f464f75
2 changed files with 127 additions and 6 deletions

View File

@ -64,6 +64,8 @@ def draw_gpencil_tools(context, layout):
row = col.row()
row.prop(context.tool_settings, "use_grease_pencil_sessions")
col.operator("view3d.ruler")
# ********** default tools for object-mode ****************
@ -102,8 +104,9 @@ class VIEW3D_PT_tools_objectmode(View3DPanel, Panel):
col = layout.column(align=True)
col.label(text="Motion Paths:")
col.operator("object.paths_calculate", text="Calculate Paths")
col.operator("object.paths_clear", text="Clear Paths")
row = col.row(align=True)
row.operator("object.paths_calculate", text="Calculate")
row.operator("object.paths_clear", text="Clear")
draw_repeat_tools(context, layout)

View File

@ -27,6 +27,7 @@
/* defines VIEW3D_OT_ruler modal operator */
#include "DNA_scene_types.h"
#include "DNA_gpencil_types.h"
#include "MEM_guardedalloc.h"
@ -35,6 +36,7 @@
#include "BKE_context.h"
#include "BKE_unit.h"
#include "BKE_gpencil.h"
#include "BIF_gl.h"
@ -246,6 +248,105 @@ static bool view3d_ruler_pick(RulerInfo *ruler_info, const float mval[2],
}
}
#define RULER_ID "RulerData3D"
static bool view3d_ruler_to_gpencil(bContext *C, RulerInfo *ruler_info)
{
Scene *scene = CTX_data_scene(C);
bGPDlayer *gpl;
bGPDframe *gpf;
bGPDstroke *gps;
RulerItem *ruler_item;
const char *ruler_name = RULER_ID;
bool change = false;
if (scene->gpd == NULL) {
scene->gpd = gpencil_data_addnew("GPencil");
}
gpl = BLI_findstring(&scene->gpd->layers, ruler_name, offsetof(bGPDlayer, info));
if (gpl == NULL) {
gpl = gpencil_layer_addnew(scene->gpd, ruler_name, false);
gpl->thickness = 1;
gpl->flag |= GP_LAYER_HIDE;
}
gpf = gpencil_layer_getframe(gpl, CFRA, true);
free_gpencil_strokes(gpf);
for (ruler_item = ruler_info->items.first; ruler_item; ruler_item = ruler_item->next) {
bGPDspoint *pt;
int j;
/* allocate memory for a new stroke */
gps = MEM_callocN(sizeof(bGPDstroke), "gp_stroke");
if (ruler_item->flag & RULERITEM_USE_ANGLE) {
gps->totpoints = 3;
pt = gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
for (j = 0; j < 3; j++) {
copy_v3_v3(&pt->x, ruler_item->co[j]);
pt->pressure = 1.0f;
pt++;
}
}
else {
gps->totpoints = 2;
pt = gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
for (j = 0; j < 3; j += 2) {
copy_v3_v3(&pt->x, ruler_item->co[j]);
pt->pressure = 1.0f;
pt++;
}
}
gps->flag = GP_STROKE_3DSPACE;
BLI_addtail(&gpf->strokes, gps);
change = true;
}
return change;
}
static bool view3d_ruler_from_gpencil(bContext *C, RulerInfo *ruler_info)
{
Scene *scene = CTX_data_scene(C);
bool change = false;
if (scene->gpd) {
bGPDlayer *gpl;
const char *ruler_name = RULER_ID;
gpl = BLI_findstring(&scene->gpd->layers, ruler_name, offsetof(bGPDlayer, info));
if (gpl) {
bGPDframe *gpf;
gpf = gpencil_layer_getframe(gpl, CFRA, false);
if (gpf) {
bGPDstroke *gps;
for (gps = gpf->strokes.first; gps; gps = gps->next) {
bGPDspoint *pt = gps->points;
int j;
if (gps->totpoints == 3) {
RulerItem *ruler_item = ruler_item_add(ruler_info);
for (j = 0; j < 3; j++) {
copy_v3_v3(ruler_item->co[j], &pt->x);
pt++;
}
ruler_item->flag |= RULERITEM_USE_ANGLE;
change = true;
}
else if (gps->totpoints == 2) {
RulerItem *ruler_item = ruler_item_add(ruler_info);
for (j = 0; j < 3; j++) {
copy_v3_v3(ruler_item->co[j], &pt->x);
pt++;
}
change = true;
}
}
}
}
}
return change;
}
/* -------------------------------------------------------------------- */
/* local callbacks */
@ -593,6 +694,10 @@ static int view3d_ruler_invoke(bContext *C, wmOperator *op, wmEvent *event)
ruler_info = MEM_callocN(sizeof(RulerInfo), "RulerInfo");
if (view3d_ruler_from_gpencil(C, ruler_info)) {
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
}
op->customdata = ruler_info;
ruler_info->ar = ar;
@ -642,7 +747,10 @@ static int view3d_ruler_modal(bContext *C, wmOperator *op, wmEvent *event)
else {
if (ruler_info->state == RULER_STATE_NORMAL) {
if (event->ctrl) {
if (event->ctrl ||
/* weak - but user friendly */
(ruler_info->items.first == NULL))
{
/* Create new line */
RulerItem *ruler_item;
/* check if we want to drag an existing point or add a new one */
@ -730,6 +838,13 @@ static int view3d_ruler_modal(bContext *C, wmOperator *op, wmEvent *event)
exit_code = OPERATOR_CANCELLED;
break;
}
case RETKEY:
{
view3d_ruler_to_gpencil(C, ruler_info);
do_draw = true;
exit_code = OPERATOR_FINISHED;
break;
}
case DELKEY:
{
if (event->val == KM_PRESS) {
@ -751,7 +866,10 @@ static int view3d_ruler_modal(bContext *C, wmOperator *op, wmEvent *event)
}
if (do_draw) {
ED_region_tag_redraw(ar);
// ED_region_tag_redraw(ar);
/* all 3d views draw rulers */
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
}
if (ELEM(exit_code, OPERATOR_FINISHED, OPERATOR_CANCELLED)) {
@ -766,7 +884,7 @@ static int view3d_ruler_modal(bContext *C, wmOperator *op, wmEvent *event)
void VIEW3D_OT_ruler(wmOperatorType *ot)
{
/* identifiers */
ot->name = "3D Ruler";
ot->name = "3D Ruler & Protractor";
ot->description = "Interactive ruler";
ot->idname = "VIEW3D_OT_ruler";
@ -777,5 +895,5 @@ void VIEW3D_OT_ruler(wmOperatorType *ot)
ot->poll = ED_operator_view3d_active;
/* flags */
ot->flag = OPTYPE_BLOCKING;
ot->flag = 0;
}