[Bf-blender-cvs] [a9500e1] soc-2016-pbvh-painting: Added support for painting multiple leaves at the same time. Also added brush strength and curve fade support. I need to optimize how maps for vert->loops are generated and destroyed.
Nathan Vollmer
noreply at git.blender.org
Sun Jun 12 06:59:13 CEST 2016
Commit: a9500e1a4c0948bfbc00df3c01d3975567cb5a47
Author: Nathan Vollmer
Date: Sat Jun 11 22:59:07 2016 -0600
Branches: soc-2016-pbvh-painting
https://developer.blender.org/rBa9500e1a4c0948bfbc00df3c01d3975567cb5a47
Added support for painting multiple leaves at the same time. Also added brush strength and curve fade support. I need to optimize how maps for vert->loops are generated and destroyed.
===================================================================
M source/blender/editors/sculpt_paint/paint_intern.h
M source/blender/editors/sculpt_paint/paint_vertex.c
M source/blender/editors/sculpt_paint/sculpt.c
M source/blender/editors/sculpt_paint/sculpt_intern.h
===================================================================
diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h
index b6a7d67..5483b43 100644
--- a/source/blender/editors/sculpt_paint/paint_intern.h
+++ b/source/blender/editors/sculpt_paint/paint_intern.h
@@ -28,6 +28,8 @@
* \ingroup edsculpt
*/
+#include "ED_view3d.h"
+#include "BKE_DerivedMesh.h"
#ifndef __PAINT_INTERN_H__
#define __PAINT_INTERN_H__
@@ -91,6 +93,27 @@ void paint_cursor_start_explicit(struct Paint *p, struct wmWindowManager *wm, in
void paint_cursor_delete_textures(void);
/* paint_vertex.c */
+typedef struct VPaintData {
+ ViewContext vc;
+ unsigned int paintcol;
+ int *indexar;
+
+ struct VertProjHandle *vp_handle;
+ DMCoNo *vertexcosnos;
+
+ float vpimat[3][3];
+
+ /* modify 'me->mcol' directly, since the derived mesh is drawing from this
+ * array, otherwise we need to refresh the modifier stack */
+ bool use_fast_update;
+
+ /* loops tagged as having been painted, to apply shared vertex color
+ * blending only to modified loops */
+ bool *mlooptag;
+
+ bool is_texbrush;
+} VPaintData;
+
int weight_paint_poll(struct bContext *C);
int weight_paint_mode_poll(struct bContext *C);
int vertex_paint_poll(struct bContext *C);
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index c974987..7272144 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -2013,8 +2013,12 @@ static void vwpaint_update_cache_invariants(bContext *C, VPaint *vd, SculptSessi
// /* Truly temporary data that isn't stored in properties */
cache->vc = vc;
+ //brush = br;
+ //cache->saved_smooth_size = BKE_brush_size_get(scene, brush);
+ //BKE_brush_size_set(scene, brush, size);
cache->brush = brush;
-
+ curvemapping_initialize(cache->brush->curve);
+ //BKE_paint_brush_set(p, br);
cache->first_time = 1;
/* cache projection matrix */
@@ -2026,6 +2030,10 @@ static void vwpaint_update_cache_invariants(bContext *C, VPaint *vd, SculptSessi
copy_m3_m4(mat, ob->imat);
mul_m3_v3(mat, viewDir);
normalize_v3_v3(cache->true_view_normal, viewDir);
+
+ //TEMPORARY. needs to be changed once we add mirroring.
+ copy_v3_v3(cache->view_normal, cache->true_view_normal);
+ cache->bstrength = BKE_brush_alpha_get(scene, brush);
cache->nodes = MEM_callocN(sizeof(PBVHNode*), "PBVH node ptr");
}
@@ -2054,14 +2062,14 @@ static void vwpaint_update_cache_variants(bContext *C, VPaint *vd, Object *ob,
//cache->pen_flip = RNA_boolean_get(ptr, "pen_flip");
RNA_float_get_array(ptr, "mouse", cache->mouse);
- ///* XXX: Use pressure value from first brush step for brushes which don't
- //* support strokes (grab, thumb). They depends on initial state and
- //* brush coord/pressure/etc.
- //* It's more an events design issue, which doesn't split coordinate/pressure/angle
- //* changing events. We should avoid this after events system re-design */
- //if (paint_supports_dynamic_size(brush, ePaintSculpt) || cache->first_time) {
- // cache->pressure = RNA_float_get(ptr, "pressure");
- //}
+ /* XXX: Use pressure value from first brush step for brushes which don't
+ * support strokes (grab, thumb). They depends on initial state and
+ * brush coord/pressure/etc.
+ * It's more an events design issue, which doesn't split coordinate/pressure/angle
+ * changing events. We should avoid this after events system re-design */
+ if (paint_supports_dynamic_size(brush, ePaintSculpt) || cache->first_time) {
+ cache->pressure = RNA_float_get(ptr, "pressure");
+ }
/* Truly temporary data that isn't stored in properties */
if (cache->first_time) {
@@ -2808,27 +2816,6 @@ typedef struct PolyFaceMap {
int facenr;
} PolyFaceMap;
-typedef struct VPaintData {
- ViewContext vc;
- unsigned int paintcol;
- int *indexar;
-
- struct VertProjHandle *vp_handle;
- DMCoNo *vertexcosnos;
-
- float vpimat[3][3];
-
- /* modify 'me->mcol' directly, since the derived mesh is drawing from this
- * array, otherwise we need to refresh the modifier stack */
- bool use_fast_update;
-
- /* loops tagged as having been painted, to apply shared vertex color
- * blending only to modified loops */
- bool *mlooptag;
-
- bool is_texbrush;
-} VPaintData;
-
static bool vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const float mouse[2])
{
Scene *scene = CTX_data_scene(C);
@@ -3036,6 +3023,70 @@ static void vpaint_paint_loop(VPaint *vp, VPaintData *vpd, Mesh *me,
}
}
+static void do_mask_brush_draw_task_cb_ex(
+ void *userdata, void *UNUSED(userdata_chunk), const int n, const int thread_id)
+{
+ SculptThreadedTaskData *data = userdata;
+ SculptSession *ss = data->ob->sculpt;
+ Brush *brush = data->brush;
+ const float bstrength = ss->cache->bstrength;
+
+ //This should probably be put in the STTD struct.
+ Mesh *me = data->ob->data;
+ int r_unique = 0;
+ int r_total = 0;
+ int* r_vert_indices;
+ int *r_mem = NULL;
+ MeshElemMap *vert_to_loop = NULL;
+ MVert* r_verts;
+ BKE_pbvh_node_num_verts(ss->pbvh, data->nodes[n], &r_unique, &r_total);
+ BKE_pbvh_node_get_verts(ss->pbvh, data->nodes[n], &r_vert_indices, &r_verts);
+ BKE_mesh_vert_loop_map_create(&vert_to_loop, &r_mem, me->mpoly, me->mloop, me->totvert, me->totpoly, me->totloop);
+
+ unsigned int *lcol = data->lcol;
+ unsigned int *lcolorig = data->vp->vpaint_prev;
+
+ PBVHVertexIter vd;
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
+ {
+ SculptBrushTest test;
+ sculpt_brush_test_init(ss, &test);
+ if (sculpt_brush_test(&test, vd.co)) {
+ const float fade = tex_strength(ss, brush, vd.co, test.dist, vd.no, vd.fno, 0.0f, thread_id);
+
+ int vertexIndex = vd.vert_indices[vd.i];
+ MVert vert = me->mvert[vertexIndex];
+ //Test to see if the vertex coordinates are within the spherical brush region.
+ if (sculpt_brush_test(&test, vert.co)) {
+ unsigned int original[4] = { 0 };
+ //if a vertex is within the brush region, then paint each loop that vertex owns.
+ for (int j = 0; j < vert_to_loop[vertexIndex].count; ++j) {
+ int loopIndex = vert_to_loop[vertexIndex].indices[j];
+ //Mix the new color with the original based on the brush strength and the curve.
+ lcol[loopIndex] = vpaint_blend(data->vp, data->lcol[loopIndex], data->vp->vpaint_prev[loopIndex], data->vpd->paintcol, fade*255.0, bstrength*255);
+ }
+ }
+ }
+ BKE_pbvh_vertex_iter_end;
+ }
+}
+
+static void vpaint_paint_leaves(Sculpt *sd, VPaint *vp, VPaintData *vpd, Object *ob, Mesh *me, PBVHNode **nodes, int totnode)
+{
+ Brush *brush = ob->sculpt->cache->brush;//BKE_paint_brush(&sd->paint);
+ /* threaded loop over nodes */
+ SculptThreadedTaskData data = {
+ .sd = sd, .ob = ob, .brush = brush, .nodes = nodes,
+ };
+ data.vp = vp;
+ data.vpd = vpd;
+ data.lcol = (unsigned int*)me->mloopcol;
+
+ BLI_task_parallel_range_ex(
+ 0, totnode, &data, NULL, 0, do_mask_brush_draw_task_cb_ex,
+ ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT), false);
+}
+
static void vpaint_paint_leaf(bContext *C, Mesh *me, VPaintData *vpd, SculptSession *ss, PointerRNA *itemptr) {
StrokeCache* cache = ss->cache;
@@ -3085,7 +3136,7 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
{
Scene *scene = CTX_data_scene(C);
ToolSettings *ts = CTX_data_tool_settings(C);
- struct VPaintData *vpd = paint_stroke_mode_data(stroke);
+ VPaintData *vpd = paint_stroke_mode_data(stroke);
VPaint *vp = ts->vpaint;
Brush *brush = BKE_paint_brush(&vp->paint);
ViewContext *vc = &vpd->vc;
@@ -3140,7 +3191,20 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
//Logic will change to "for each leaf within the brush region".
- vpaint_paint_leaf(C, me, vpd, ob->sculpt, itemptr);
+ SculptSession *ss = ob->sculpt;
+ SculptSearchSphereData data;
+ PBVHNode **nodes = NULL;
+ int totnode;
+
+ /* Build a list of all nodes that are potentially within the brush's area of influence */
+ data.ss = ss;
+ data.sd = sd;
+ data.radius_squared = ss->cache->radius_squared;
+ data.original = true;// sculpt_tool_needs_original(brush->sculpt_tool) ? true : ss->cache->original;
+ BKE_pbvh_search_gather(ss->pbvh, sculpt_search_sphere_cb, &data, &nodes, &totnode);
+
+ vpaint_paint_leaves(sd, vp, vpd, ob, me, nodes, totnode);
+ //vpaint_paint_leaf(C, me, vpd, ob->sculpt, itemptr);
//for (index = 0; index < totindex; index++) {
//if (indexar[index] && indexar[index] <= me->totpoly) {
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 8cbd45a..0ee37c6 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -37,8 +37,6 @@
#include "BLI_math.h"
#include "BLI_blenlib.h"
-#include "BLI_task.h"
-#include "BLI_threads.h"
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
@@ -304,21 +302,6 @@ static void sculpt_project_v3_normal_align(SculptSession *ss, const float normal
madd_v3_v3fl(grab_delta, ss->cache->sculpt_normal_symm, (len_signed * normal_weight) * len_view_scale);
}
-
-/** \name SculptProjectVector
- *
- * Fast-path for #project_plane_v3_v3v3
- *
- * \{ */
-
-typedef struct SculptProjectVector {
- float plane[3];
- float len_sq;
- float len_sq_inv_neg;
- bool is_valid;
-
-} SculptProjectVector;
-
/**
* \param plane Direction, can be any length.
*/
@@ -374,41 +357,6 @@ static bool sculpt_stroke_is_dynamic_topology(
/*** paint mesh ***/
-/* Single struct used by all BLI_task threaded callbacks, let's avoid adding 10's of those... */
-typedef struct SculptThreadedTaskData {
- Sculpt *sd;
- Object *ob;
- Brush *brush;
- PBVHNode **nodes;
- int totnode;
-
- /* Data specific to some callbacks. */
- /* Note: even if only one or two of those are used at a time, keeping them separated, names help figuring out
- * what it is, and memory overhead is ridiculous anyway... */
- float flippedbstrength;
- float angle;
- float strength;
- bool smooth_mask;
- bool has_bm_orco;
-
- SculptProjectVector *spvc;
- float *offset;
- float *grab_delta;
- float *cono;
- float *area_no;
- float *area_no
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list