diff options
-rw-r--r-- | source/blender/editors/gpencil/gpencil_buttons.c | 8 | ||||
-rw-r--r-- | source/blender/editors/gpencil/gpencil_paint.c | 110 | ||||
-rw-r--r-- | source/blender/editors/include/ED_view3d.h | 3 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_edit.c | 34 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_gpencil_types.h | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_gpencil.c | 13 |
6 files changed, 143 insertions, 27 deletions
diff --git a/source/blender/editors/gpencil/gpencil_buttons.c b/source/blender/editors/gpencil/gpencil_buttons.c index 5deffbabb77..54dd43160a6 100644 --- a/source/blender/editors/gpencil/gpencil_buttons.c +++ b/source/blender/editors/gpencil/gpencil_buttons.c @@ -229,7 +229,7 @@ static void draw_gpencil_panel (bContext *C, uiLayout *layout, bGPdata *gpd, Poi { PointerRNA gpd_ptr; bGPDlayer *gpl; - uiLayout *col; + uiLayout *col, *row; /* make new PointerRNA for Grease Pencil block */ RNA_id_pointer_create((ID *)gpd, &gpd_ptr); @@ -259,7 +259,11 @@ static void draw_gpencil_panel (bContext *C, uiLayout *layout, bGPdata *gpd, Poi uiItemL(col, "Drawing Settings:", 0); /* 'stick to view' option */ - uiItemR(col, NULL, 0, &gpd_ptr, "view_space_draw", 0); + //uiItemR(col, NULL, 0, &gpd_ptr, "draw_mode", 0); + row= uiLayoutRow(layout, 1); + uiItemEnumR_string(row, NULL, 0, &gpd_ptr, "draw_mode", "VIEW"); + uiItemEnumR_string(row, NULL, 0, &gpd_ptr, "draw_mode", "CURSOR"); + uiItemEnumR_string(row, NULL, 0, &gpd_ptr, "draw_mode", "DEPTH"); } diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 3f9e3e04411..86ca69f6cf6 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -155,15 +155,7 @@ static int gpencil_draw_poll (bContext *C) static int gpencil_project_check (tGPsdata *p) { bGPdata *gpd= p->gpd; - - if( (gpd->sbuffer_sflag & GP_STROKE_3DSPACE) && - (p->scene->toolsettings->snap_mode==SCE_SNAP_MODE_FACE) && - (p->scene->toolsettings->snap_flag & SCE_SNAP_PROJECT) ) - { - return 1; - } - - return 0; + return ((gpd->sbuffer_sflag & GP_STROKE_3DSPACE) && (p->gpd->flag & GP_DATA_VIEWDEPTH)) ? 1:0; } /* ******************************************* */ @@ -220,13 +212,13 @@ static short gp_stroke_filtermval (tGPsdata *p, int mval[2], int pmval[2]) /* convert screen-coordinates to buffer-coordinates */ // XXX this method needs a total overhaul! -static void gp_stroke_convertcoords (tGPsdata *p, short mval[], float out[]) +static void gp_stroke_convertcoords (tGPsdata *p, short mval[], float out[], float *depth) { bGPdata *gpd= p->gpd; /* in 3d-space - pt->x/y/z are 3 side-by-side floats */ if (gpd->sbuffer_sflag & GP_STROKE_3DSPACE) { - if(gpencil_project_check(p) && (view_autodist_simple(p->ar, mval, out))) { + if(gpencil_project_check(p) && (view_autodist_simple(p->ar, mval, out, depth))) { /* projecting onto 3D-Geometry * - nothing more needs to be done here, since view_autodist_simple() has already done it */ @@ -501,7 +493,7 @@ static void gp_stroke_newfrombuffer (tGPsdata *p) ptc= gpd->sbuffer; /* convert screen-coordinates to appropriate coordinates (and store them) */ - gp_stroke_convertcoords(p, &ptc->x, &pt->x); + gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL); /* copy pressure */ pt->pressure= ptc->pressure; @@ -514,23 +506,107 @@ static void gp_stroke_newfrombuffer (tGPsdata *p) ptc= ((tGPspoint *)gpd->sbuffer) + (gpd->sbuffer_size - 1); /* convert screen-coordinates to appropriate coordinates (and store them) */ - gp_stroke_convertcoords(p, &ptc->x, &pt->x); + gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL); /* copy pressure */ pt->pressure= ptc->pressure; } } else { + float *depth_arr= NULL; + + /* get an array of depths, far depths are blended */ + if(gpencil_project_check(p)) { + short mval[2]; + int interp_depth = 0; + int found_depth = 0; + + depth_arr= MEM_mallocN(sizeof(float) * gpd->sbuffer_size, "depth_points"); + + for (i=0, ptc=gpd->sbuffer; i < gpd->sbuffer_size; i++, ptc++, pt++) { + mval[0]= ptc->x; mval[1]= ptc->y; + if(view_autodist_depth(p->ar, mval, depth_arr+i) == 0) + interp_depth= TRUE; + else + found_depth= TRUE; + } + + if(found_depth==FALSE) { + /* eeh... not much we can do.. :/, ignore depth in this case, use the 3D cursor */ + for (i=gpd->sbuffer_size-1; i >= 0; i--) + depth_arr[i] = 0.9999f; + } + else if(interp_depth) { + /* found invalid depths, interpolate */ + float valid_last= FLT_MAX; + int valid_ofs= 0; + + float *depth_arr_up= MEM_callocN(sizeof(float) * gpd->sbuffer_size, "depth_points_up"); + float *depth_arr_down= MEM_callocN(sizeof(float) * gpd->sbuffer_size, "depth_points_down"); + + int *depth_tot_up= MEM_callocN(sizeof(int) * gpd->sbuffer_size, "depth_tot_up"); + int *depth_tot_down= MEM_callocN(sizeof(int) * gpd->sbuffer_size, "depth_tot_down"); + + for (i=0; i < gpd->sbuffer_size; i++) { + if(depth_arr[i] == FLT_MAX) { + depth_arr_up[i]= valid_last; + depth_tot_up[i]= ++valid_ofs; + } + else { + valid_last= depth_arr[i]; + valid_ofs= 0; + } + } + + valid_last= FLT_MAX; + valid_ofs= 0; + + for (i=gpd->sbuffer_size-1; i >= 0; i--) { + if(depth_arr[i] == FLT_MAX) { + depth_arr_down[i]= valid_last; + depth_tot_down[i]= ++valid_ofs; + } + else { + valid_last= depth_arr[i]; + valid_ofs= 0; + } + } + + /* now blend */ + for (i=0; i < gpd->sbuffer_size; i++) { + if(depth_arr[i] == FLT_MAX) { + if(depth_arr_up[i] != FLT_MAX && depth_arr_down[i] != FLT_MAX) { + depth_arr[i]= ((depth_arr_up[i] * depth_tot_down[i]) + (depth_arr_down[i] * depth_tot_up[i])) / (float)(depth_tot_down[i] + depth_tot_up[i]); + } else if (depth_arr_up[i] != FLT_MAX) { + depth_arr[i]= depth_arr_up[i]; + } else if (depth_arr_down[i] != FLT_MAX) { + depth_arr[i]= depth_arr_down[i]; + } + } + } + + MEM_freeN(depth_arr_up); + MEM_freeN(depth_arr_down); + + MEM_freeN(depth_tot_up); + MEM_freeN(depth_tot_down); + } + } + + + pt= gps->points; + /* convert all points (normal behaviour) */ - for (i=0, ptc=gpd->sbuffer; i < gpd->sbuffer_size && ptc; i++, ptc++) { + for (i=0, ptc=gpd->sbuffer; i < gpd->sbuffer_size && ptc; i++, ptc++, pt++) { /* convert screen-coordinates to appropriate coordinates (and store them) */ - gp_stroke_convertcoords(p, &ptc->x, &pt->x); + gp_stroke_convertcoords(p, &ptc->x, &pt->x, depth_arr ? depth_arr+i:NULL); /* copy pressure */ pt->pressure= ptc->pressure; - - pt++; } + + if(depth_arr) + MEM_freeN(depth_arr); } /* add stroke to frame */ diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index de5a9fe4e07..2e439f8fdef 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -128,7 +128,8 @@ int view_autodist(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, s /* only draw so view_autodist_simple can be called many times after */ int view_autodist_init(struct Scene *scene, struct ARegion *ar, struct View3D *v3d); -int view_autodist_simple(struct ARegion *ar, short *mval, float mouse_worldloc[3]); +int view_autodist_simple(struct ARegion *ar, short *mval, float mouse_worldloc[3], float *force_depth); +int view_autodist_depth(struct ARegion *ar, short *mval, float *depth); /* select */ #define MAXPICKBUF 10000 diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 9b0712ac255..bfd2ecb4939 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -2282,7 +2282,7 @@ int view_autodist_init(Scene *scene, ARegion *ar, View3D *v3d) //, float *autodi } // no 4x4 sampling, run view_autodist_init first -int view_autodist_simple(ARegion *ar, short *mval, float mouse_worldloc[3] ) //, float *autodist ) +int view_autodist_simple(ARegion *ar, short *mval, float mouse_worldloc[3], float *force_depth) //, float *autodist ) { RegionView3D *rv3d= ar->regiondata; bglMats mats; /* ZBuffer depth vars, could cache? */ @@ -2295,15 +2295,18 @@ int view_autodist_simple(ARegion *ar, short *mval, float mouse_worldloc[3] ) //, if (mval[1] >= rv3d->depths->h) return 0; /* Get Z Depths, needed for perspective, nice for ortho */ - bgl_get_mats(&mats); - depth= rv3d->depths->depths[mval[1]*rv3d->depths->w+mval[0]]; + if(force_depth) + depth= *force_depth; + else + depth= rv3d->depths->depths[mval[1]*rv3d->depths->w+mval[0]]; - if (depth==MAXFLOAT) + if (depth==FLT_MAX) return 0; cent[0] = (double)mval[0]; cent[1] = (double)mval[1]; + bgl_get_mats(&mats); if (!gluUnProject(cent[0], cent[1], depth, mats.modelview, mats.projection, (GLint *)mats.viewport, &p[0], &p[1], &p[2])) return 0; @@ -2313,6 +2316,29 @@ int view_autodist_simple(ARegion *ar, short *mval, float mouse_worldloc[3] ) //, return 1; } +int view_autodist_depth(struct ARegion *ar, short *mval, float *depth) +{ + RegionView3D *rv3d= ar->regiondata; + *depth= FLT_MAX; + + if (mval[0] < 0) return 0; + if (mval[1] < 0) return 0; + if (mval[0] >= rv3d->depths->w) return 0; + if (mval[1] >= rv3d->depths->h) return 0; + + /* Get Z Depths, needed for perspective, nice for ortho */ + *depth= rv3d->depths->depths[mval[1]*rv3d->depths->w+mval[0]]; + + /* float error means we need to shave off some */ + + if(*depth >= 1.0) { + *depth= FLT_MAX; + } + + return (*depth==FLT_MAX) ? 0:1; + return 0; +} + /* ********************* NDOF ************************ */ /* note: this code is confusing and unclear... (ton) */ /* **************************************************** */ diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h index 4bae9935ea7..9ba3c243d20 100644 --- a/source/blender/makesdna/DNA_gpencil_types.h +++ b/source/blender/makesdna/DNA_gpencil_types.h @@ -146,5 +146,7 @@ typedef struct bGPdata { #define GP_DATA_EDITPAINT (1<<3) /* new strokes are added in viewport space */ #define GP_DATA_VIEWALIGN (1<<4) + /* Project into the screens Z values */ +#define GP_DATA_VIEWDEPTH (1<<5) #endif /* DNA_GPENCIL_TYPES_H */ diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c index 129fad4e98c..d55f5f21e72 100644 --- a/source/blender/makesrna/intern/rna_gpencil.c +++ b/source/blender/makesrna/intern/rna_gpencil.c @@ -220,6 +220,12 @@ static void rna_def_gpencil_data(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; + static EnumPropertyItem draw_mode_items[] = { + {GP_DATA_VIEWALIGN, "CURSOR", 0, "Cursor", ""}, + {0, "VIEW", 0, "View", ""}, /* weired, GP_DATA_VIEWALIGN is inverted */ + {GP_DATA_VIEWALIGN|GP_DATA_VIEWDEPTH, "DEPTH", 0, "Depth", ""}, + {0, NULL, 0, NULL, NULL}}; + srna= RNA_def_struct(brna, "GreasePencil", "ID"); RNA_def_struct_sdna(srna, "bGPdata"); RNA_def_struct_ui_text(srna, "Grease Pencil", "Freehand annotation sketchbook."); @@ -232,9 +238,10 @@ static void rna_def_gpencil_data(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Layers", "Similar to layers in Photoshop."); /* Flags */ - prop= RNA_def_property(srna, "view_space_draw", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", GP_DATA_VIEWALIGN); - RNA_def_property_ui_text(prop, "Stick to View", "Newly drawn strokes get added in view space (i.e. sketches stick to data when view is manipulated)."); + prop= RNA_def_property(srna, "draw_mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); + RNA_def_property_enum_items(prop, draw_mode_items); + RNA_def_property_ui_text(prop, "Draw Mode", ""); } /* --- */ |