[Bf-blender-cvs] [4f616c93f7c] master: Vertex/Weight Paint: Use PBVH for painting

Campbell Barton noreply at git.blender.org
Wed Sep 27 17:35:42 CEST 2017


Commit: 4f616c93f7cb8c8c8e038bc0c949c931242971c2
Author: Campbell Barton
Date:   Thu Sep 28 01:38:17 2017 +1000
Branches: master
https://developer.blender.org/rB4f616c93f7cb8c8c8e038bc0c949c931242971c2

Vertex/Weight Paint: Use PBVH for painting

2016 GSOC project by @nathanvollmer, see D2150

- Mirrored painting and radial symmetry, like in sculpt mode.
- Volume based splash prevention,
  which avoids painting vertices far away from the 3D brush location.
- Normal based splash prevention,
  which avoids painting vertices with normals opposite the normal
  at the 3D brush location.
- Blur mode now uses a nearest neighbor average.
- Average mode, which averages the color/weight
  of the vertices within the brush
- Smudge mode, which pulls the colors/weights
  along the direction of the brush
- RGB^2 color blending, which gives a more accurate
  blend between two colors
- multithreading support. (PBVH leaves are painted in parallel.)
- Foreground/background color picker in vertex paint

===================================================================

M	release/scripts/startup/bl_ui/space_view3d_toolbar.py
M	source/blender/blenkernel/BKE_paint.h
M	source/blender/blenkernel/BKE_pbvh.h
M	source/blender/blenkernel/intern/DerivedMesh.c
M	source/blender/blenkernel/intern/cdderivedmesh.c
M	source/blender/blenkernel/intern/object.c
M	source/blender/blenkernel/intern/paint.c
M	source/blender/blenkernel/intern/pbvh.c
M	source/blender/blenkernel/intern/pbvh_intern.h
M	source/blender/blenkernel/intern/scene.c
M	source/blender/blenkernel/intern/subsurf_ccg.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/blenloader/intern/versioning_270.c
M	source/blender/blenloader/intern/versioning_defaults.c
M	source/blender/editors/sculpt_paint/paint_image.c
M	source/blender/editors/sculpt_paint/paint_intern.h
M	source/blender/editors/sculpt_paint/paint_ops.c
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
M	source/blender/makesdna/DNA_brush_types.h
M	source/blender/makesdna/DNA_object_types.h
M	source/blender/makesdna/DNA_scene_types.h
M	source/blender/makesrna/intern/rna_brush.c
M	source/blender/makesrna/intern/rna_sculpt_paint.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index eb1b2e5971d..8562cb419b4 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -51,6 +51,19 @@ def draw_keyframing_tools(context, layout):
     row.operator("anim.keyframe_delete_v3d", text="Remove")
 
 
+# Used by vertex & weight paint
+def draw_vpaint_symmetry(layout, vpaint):
+    col = layout.column(align=True)
+    col.label(text="Mirror:")
+    row = col.row(align=True)
+
+    row.prop(vpaint, "use_symmetry_x", text="X", toggle=True)
+    row.prop(vpaint, "use_symmetry_y", text="Y", toggle=True)
+    row.prop(vpaint, "use_symmetry_z", text="Z", toggle=True)
+
+    col = layout.column()
+    col.prop(vpaint, "radial_symmetry", text="Radial")
+
 # ********** default tools for object-mode ****************
 
 
@@ -1134,7 +1147,11 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
             self.prop_unified_color_picker(col, context, brush, "color", value_slider=True)
             if settings.palette:
                 col.template_palette(settings, "palette", color=True)
-            self.prop_unified_color(col, context, brush, "color", text="")
+            row = col.row(align=True)
+            self.prop_unified_color(row, context, brush, "color", text="")
+            self.prop_unified_color(row, context, brush, "secondary_color", text="")
+            row.separator()
+            row.operator("paint.brush_colors_flip", icon='FILE_REFRESH', text="")
 
             col.separator()
             row = col.row(align=True)
@@ -1717,6 +1734,19 @@ class VIEW3D_PT_tools_weightpaint(View3DPanel, Panel):
         props.data_type = 'VGROUP_WEIGHTS'
 
 
+class VIEW3D_PT_tools_weightpaint_symmetry(Panel, View3DPaintPanel):
+    bl_category = "Tools"
+    bl_context = "weightpaint"
+    bl_options = {'DEFAULT_CLOSED'}
+    bl_label = "Symmetry"
+
+    def draw(self, context):
+        layout = self.layout
+        toolsettings = context.tool_settings
+        wpaint = toolsettings.weight_paint
+        draw_vpaint_symmetry(layout, wpaint)
+
+
 class VIEW3D_PT_tools_weightpaint_options(Panel, View3DPaintPanel):
     bl_category = "Options"
     bl_context = "weightpaint"
@@ -1779,6 +1809,20 @@ class VIEW3D_PT_tools_vertexpaint(Panel, View3DPaintPanel):
 #~         col.label(text="Multiply:")
 #~         col.prop(vpaint, "mul", text="")
 
+
+class VIEW3D_PT_tools_vertexpaint_symmetry(Panel, View3DPaintPanel):
+    bl_category = "Tools"
+    bl_context = "vertexpaint"
+    bl_options = {'DEFAULT_CLOSED'}
+    bl_label = "Symmetry"
+
+    def draw(self, context):
+        layout = self.layout
+        toolsettings = context.tool_settings
+        vpaint = toolsettings.vertex_paint
+        draw_vpaint_symmetry(layout, vpaint)
+
+
 # ********** default tools for texture-paint ****************
 
 
@@ -2058,8 +2102,10 @@ classes = (
     VIEW3D_PT_sculpt_symmetry,
     VIEW3D_PT_tools_brush_appearance,
     VIEW3D_PT_tools_weightpaint,
+    VIEW3D_PT_tools_weightpaint_symmetry,
     VIEW3D_PT_tools_weightpaint_options,
     VIEW3D_PT_tools_vertexpaint,
+    VIEW3D_PT_tools_vertexpaint_symmetry,
     VIEW3D_PT_tools_imagepaint_external,
     VIEW3D_PT_tools_imagepaint_symmetry,
     VIEW3D_PT_tools_projectpaint,
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index f7e6ab59d20..88693600653 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -160,6 +160,14 @@ void paint_update_brush_rake_rotation(struct UnifiedPaintSettings *ups, struct B
 
 void BKE_paint_stroke_get_average(struct Scene *scene, struct Object *ob, float stroke[3]);
 
+/* Used for both vertex color and weight paint */
+struct SculptVertexPaintGeomMap {
+	int *vert_map_mem;
+	struct MeshElemMap *vert_to_loop;
+	int *poly_map_mem;
+	struct MeshElemMap *vert_to_poly;
+};
+
 /* Session data (mode-specific) */
 
 typedef struct SculptSession {
@@ -205,10 +213,38 @@ typedef struct SculptSession {
 
 	struct SculptStroke *stroke;
 	struct StrokeCache *cache;
+
+	union {
+		struct {
+			struct SculptVertexPaintGeomMap gmap;
+
+			/* For non-airbrush painting to re-apply from the original (MLoop aligned). */
+			unsigned int *previous_color;
+		} vpaint;
+
+		struct {
+			struct SculptVertexPaintGeomMap gmap;
+
+			/* Vertex aligned arrays of weights. */
+			/* For non-airbrush painting to re-apply from the original. */
+			float *previous_weight;
+			/* Keep track of how much each vertex has been painted (non-airbrush only). */
+			float *alpha_weight;
+		} wpaint;
+
+		//struct {
+		//ToDo: identify sculpt-only fields
+		//} sculpt;
+	} mode;
+	int mode_type;
+
+	/* This flag prevents PBVH from being freed when creating the vp_handle for texture paint. */
+	bool building_vp_handle;
 } SculptSession;
 
 void BKE_sculptsession_free(struct Object *ob);
 void BKE_sculptsession_free_deformMats(struct SculptSession *ss);
+void BKE_sculptsession_free_vwpaint_data(struct SculptSession *ss);
 void BKE_sculptsession_bm_to_me(struct Object *ob, bool reorder);
 void BKE_sculptsession_bm_to_me_for_render(struct Object *object);
 void BKE_sculpt_update_mesh_elements(struct Scene *scene, struct Sculpt *sd, struct Object *ob,
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 927303f8b3c..cc84be6e2c1 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -32,6 +32,7 @@
 
 struct CCGElem;
 struct CCGKey;
+struct CCGDerivedMesh;
 struct CustomData;
 struct DMFlagMat;
 struct MPoly;
@@ -71,7 +72,7 @@ void BKE_pbvh_build_grids(PBVH *bvh, struct CCGElem **grid_elems,
                           struct CCGKey *key, void **gridfaces, struct DMFlagMat *flagmats,
                           unsigned int **grid_hidden);
 void BKE_pbvh_build_bmesh(PBVH *bvh, struct BMesh *bm, bool smooth_shading, struct BMLog *log, const int cd_vert_node_offset, const int cd_face_node_offset);
-
+void BKE_pbvh_set_ccgdm(PBVH *bvh, struct CCGDerivedMesh *ccgdm);
 void BKE_pbvh_free(PBVH *bvh);
 void BKE_pbvh_free_layer_disp(PBVH *bvh);
 
@@ -118,6 +119,7 @@ void BKE_pbvh_raycast_project_ray_root(
 void BKE_pbvh_node_draw(PBVHNode *node, void *data);
 void BKE_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3],
                    int (*setMaterial)(int matnr, void *attribs), bool wireframe, bool fast);
+void BKE_pbvh_draw_BB(PBVH *bvh);
 
 /* PBVH Access */
 typedef enum {
@@ -141,6 +143,7 @@ int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden,
 
 /* multires level, only valid for type == PBVH_GRIDS */
 void BKE_pbvh_get_grid_key(const PBVH *pbvh, struct CCGKey *key);
+struct CCGDerivedMesh *BKE_pbvh_get_ccgdm(const PBVH *bvh);
 
 /* Only valid for type == PBVH_BMESH */
 struct BMesh *BKE_pbvh_get_bmesh(PBVH *pbvh);
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index ace79f4125b..9dae4c5eae7 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -2663,7 +2663,7 @@ static void mesh_build_data(
 	ob->lastDataMask = dataMask;
 	ob->lastNeedMapping = need_mapping;
 
-	if ((ob->mode & OB_MODE_SCULPT) && ob->sculpt) {
+	if ((ob->mode & OB_MODE_ALL_SCULPT) && ob->sculpt) {
 		/* create PBVH immediately (would be created on the fly too,
 		 * but this avoids waiting on first stroke) */
 
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 2c61cf28691..e97de07752e 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -662,6 +662,11 @@ static void cdDM_drawMappedFaces(
 
 	const int *index_mp_to_orig  = dm->getPolyDataArray(dm, CD_ORIGINDEX);
 
+	if (cddm->pbvh) {
+		if (G.debug_value == 14)
+			BKE_pbvh_draw_BB(cddm->pbvh);
+	}
+
 	/* fist, setup common buffers */
 	GPU_vertex_setup(dm);
 	GPU_triangle_setup(dm);
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index d76ef613023..44058c989ff 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -2682,7 +2682,7 @@ void BKE_object_sculpt_modifiers_changed(Object *ob)
 {
 	SculptSession *ss = ob->sculpt;
 
-	if (ss) {
+	if (ss && ss->building_vp_handle == false) {
 		if (!ss->cache) {
 			/* we free pbvh on changes, except during sculpt since it can't deal with
 			 * changing PVBH node organization, we hope topology does not change in
@@ -2693,6 +2693,9 @@ void BKE_object_sculpt_modifiers_changed(Object *ob)
 			}
 
 			BKE_sculptsession_free_deformMats(ob->sculpt);
+
+			/* In vertex/weight paint, force maps to be rebuilt. */
+			BKE_sculptsession_free_vwpaint_data(ob->sculpt);
 		}
 		else {
 			PBVHNode **nodes;
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 9fc2136df86..25ea6ad079f 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -673,6 +673,29 @@ void BKE_sculptsession_free_deformMats(SculptSession *ss)
 	MEM_SAFE_FREE(ss->deform_imats);
 }
 
+void BKE_sculptsession_free_vwpaint_data(struct SculptSession *ss)
+{
+	struct SculptVertexPaintGeomMap *gmap = NULL;
+	if (ss->mode_type == OB_MODE_VERTEX_PAINT) {
+		gmap = &ss->mode.vpaint.gmap;
+
+		MEM_SAFE_FREE(ss->mode.vpaint.previous_color);
+	}
+	else if (ss->mode_type == OB_MODE_WEIGHT_PAINT) {
+		gmap = &ss->mode.wpaint.gmap;
+
+		MEM_SAFE_FREE(ss->mode.wpaint.alpha_weight);
+		MEM_SAFE_FREE(ss->mode.wpaint.previous_weight);
+	}
+	else {
+		return;
+	}
+	MEM_SAFE_FREE(gmap->vert_to_loop);
+	MEM_SAFE_FREE(gmap->vert_map_mem);
+	MEM_SAFE_FREE(gmap->vert_to_poly);
+	MEM_SAFE_FREE(gmap->poly_map_mem);
+}
+
 /* Write out the sculpt dynamic-topology BMesh to the Mesh */
 static void sculptsession_bm_to_me_update_data_only(Object *ob, bool reorder)
 {
@@ -714,10 +737,7 @@ void BKE_sculptsession_bm_to_me_for_render(Object *object)
 			 */
 			BKE_object_free_derived_caches(object);
 
-			if (object->sculpt-

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list