[Bf-blender-cvs] [4e623b3] soc-2016-pbvh-painting: Added mirror painting and radial symmetry.

Nathan Vollmer noreply at git.blender.org
Sat Jul 2 02:17:58 CEST 2016


Commit: 4e623b380e5be02219a545729bc090fa965a1419
Author: Nathan Vollmer
Date:   Fri Jul 1 17:17:52 2016 -0700
Branches: soc-2016-pbvh-painting
https://developer.blender.org/rB4e623b380e5be02219a545729bc090fa965a1419

Added mirror painting and radial symmetry.

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

M	release/scripts/startup/bl_ui/space_view3d_toolbar.py
M	source/blender/editors/sculpt_paint/paint_vertex.c
M	source/blender/editors/sculpt_paint/sculpt.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 49c7600..0c2791f 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -1739,7 +1739,6 @@ class VIEW3D_PT_tools_weightpaint_options(Panel, View3DPaintPanel):
 
 # ********** default tools for vertex-paint ****************
 
-
 class VIEW3D_PT_tools_vertexpaint(Panel, View3DPaintPanel):
     bl_category = "Options"
     bl_context = "vertexpaint"
@@ -1758,7 +1757,27 @@ class VIEW3D_PT_tools_vertexpaint(Panel, View3DPaintPanel):
         col.prop(vpaint, "use_spray")
 
         self.unified_paint_settings(col, context)
+        
+class VIEW3D_PT_vertexpaint_symmetry(Panel, View3DPaintPanel):
+    bl_category = "Tools"
+    bl_context = "vertexpaint"
+    bl_options = {'DEFAULT_CLOSED'}
+    bl_label = "Symmetry / Lock"
+    
+    def draw(self, context):
+        layout = self.layout
+        toolsettings = context.tool_settings
+        vpaint = toolsettings.vertex_paint
 
+        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)
+        
+        layout.column().prop(vpaint, "radial_symmetry", text="Radial")
 # Commented out because the Apply button isn't an operator yet, making these settings useless
 #~         col.label(text="Gamma:")
 #~         col.prop(vpaint, "gamma", text="")
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 08af851..2bb4e34 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -2816,7 +2816,7 @@ static int vpaint_mode_toggle_exec(bContext *C, wmOperator *op)
 
 		if (vp == NULL)
 			vp = scene->toolsettings->vpaint = new_vpaint(0);
-		
+    vp->radial_symm[0] = vp->radial_symm[1] = vp->radial_symm[2] = 1;
 		paint_cursor_start(C, vertex_paint_poll);
 
 		BKE_paint_init(scene, ePaintVertex, PAINT_CURSOR_VERTEX_PAINT);
@@ -3235,6 +3235,107 @@ static void vpaint_paint_leaves(Sculpt *sd, VPaint *vp, VPaintData *vpd, Object
 
 }
 
+/* Flip all the editdata across the axis/axes specified by symm. Used to
+* calculate multiple modifications to the mesh when symmetry is enabled. */
+static void calc_brushdata_symm(VPaint *vd, StrokeCache *cache, const char symm,
+  const char axis, const float angle)
+{
+  (void)vd; /* unused */
+
+  flip_v3_v3(cache->location, cache->true_location, symm);
+  flip_v3_v3(cache->grab_delta_symmetry, cache->grab_delta, symm);
+  flip_v3_v3(cache->view_normal, cache->true_view_normal, symm);
+
+  /* XXX This reduces the length of the grab delta if it approaches the line of symmetry
+  * XXX However, a different approach appears to be needed */
+#if 0
+  if (sd->paint.symmetry_flags & SCULPT_SYMMETRY_FEATHER) {
+    float frac = 1.0f / max_overlap_count(sd);
+    float reduce = (feather - frac) / (1 - frac);
+
+    printf("feather: %f frac: %f reduce: %f\n", feather, frac, reduce);
+
+    if (frac < 1)
+      mul_v3_fl(cache->grab_delta_symmetry, reduce);
+  }
+#endif
+
+  unit_m4(cache->symm_rot_mat);
+  unit_m4(cache->symm_rot_mat_inv);
+  zero_v3(cache->plane_offset);
+
+  if (axis) { /* expects XYZ */
+    rotate_m4(cache->symm_rot_mat, axis, angle);
+    rotate_m4(cache->symm_rot_mat_inv, axis, -angle);
+  }
+  
+  mul_m4_v3(cache->symm_rot_mat, cache->location);
+  mul_m4_v3(cache->symm_rot_mat, cache->grab_delta_symmetry);
+
+  if (cache->supports_gravity) {
+    flip_v3_v3(cache->gravity_direction, cache->true_gravity_direction, symm);
+    mul_m4_v3(cache->symm_rot_mat, cache->gravity_direction);
+  }
+
+  if (cache->is_rake_rotation_valid) {
+    flip_qt_qt(cache->rake_rotation_symmetry, cache->rake_rotation, symm);
+  }
+}
+
+static void do_radial_symmetry(Sculpt *sd, VPaint *vd, VPaintData *vpd, Object *ob, Mesh *me, Brush *brush, const char symm, const int axis)
+{
+  SculptSession *ss = ob->sculpt;
+  int i;
+
+  for (i = 1; i < vd->radial_symm[axis - 'X']; ++i) {
+    const float angle = (2.0 * M_PI) * i / vd->radial_symm[axis - 'X'];
+    ss->cache->radial_symmetry_pass = i;
+    calc_brushdata_symm(vd, ss->cache, symm, axis, angle);
+//    do_tiled(sd, ob, brush, ups, action);
+    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;
+    BKE_pbvh_search_gather(ss->pbvh, sculpt_search_sphere_cb, &data, &nodes, &totnode);
+
+    //Paint those leaves.
+    vpaint_paint_leaves(sd, vd, vpd, ob, me, nodes, totnode);
+
+    if (nodes)
+      MEM_freeN(nodes);
+  }
+}
+
+static void do_symmetrical_brush_actions(Sculpt *sd, VPaint *vd, VPaintData *vpd, Object *ob)
+{
+  Brush *brush = BKE_paint_brush(&vd->paint);
+  Mesh *me = ob->data;
+  SculptSession *ss = ob->sculpt;
+  StrokeCache *cache = ss->cache;
+  const char symm = vd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL;
+  int i;
+
+  cache->symmetry = symm;
+
+  /* symm is a bit combination of XYZ - 1 is mirror X; 2 is Y; 3 is XY; 4 is Z; 5 is XZ; 6 is YZ; 7 is XYZ */
+  for (i = 0; i <= symm; ++i) {
+    if (i == 0 || (symm & i && (symm != 5 || i != 3) && (symm != 6 || (i != 3 && i != 5)))) {
+      cache->mirror_symmetry_pass = i;
+      cache->radial_symmetry_pass = 0;
+
+      calc_brushdata_symm(vd, cache, i, 0, 0);
+
+      do_radial_symmetry(sd, vd, vpd, ob, me, brush, i, 'X');
+      do_radial_symmetry(sd, vd, vpd, ob, me, brush, i, 'Y');
+      do_radial_symmetry(sd, vd, vpd, ob, me, brush, i, 'Z');
+    }
+  }
+}
 static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, PointerRNA *itemptr)
 {
 	Scene *scene = CTX_data_scene(C);
@@ -3292,33 +3393,34 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
 	if (vpd->mlooptag)
 		memset(vpd->mlooptag, 0, sizeof(bool) * me->totloop);
 
-	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;
-	BKE_pbvh_search_gather(ss->pbvh, sculpt_search_sphere_cb, &data, &nodes, &totnode);
-	//Paint those leaves.
-	//ss->cache->brush = brush;
-	vpaint_paint_leaves(sd, vp, vpd, ob, me, nodes, totnode);
+	// Paint happens here.
+  SculptSession *ss = ob->sculpt;
+  copy_v3_v3(ss->cache->location, ss->cache->true_location);
+  SculptSearchSphereData data;
+  PBVHNode **nodes = NULL;
+  int totnode;
 
-	swap_m4m4(vc->rv3d->persmat, mat);
+  /* 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;
+  BKE_pbvh_search_gather(ss->pbvh, sculpt_search_sphere_cb, &data, &nodes, &totnode);
 
-	/* was disabled because it is slow, but necessary for blur */
-	/*if (brush->vertexpaint_tool == PAINT_BLEND_BLUR) {
-		do_shared_vertexcol(me, vpd->mlooptag);
-	}*/
+  //Paint those leaves.
+  vpaint_paint_leaves(sd, vp, vpd, ob, me, nodes, totnode);
 
-	/* calculate pivot for rotation around seletion if needed */
-	if (U.uiflag & USER_ORBIT_SELECTION) {
-		paint_last_stroke_update(scene, vc->ar, mval);
-	}
+  if (nodes)
+    MEM_freeN(nodes);
 
+  do_symmetrical_brush_actions(sd, vp, vpd, ob);
+
+	swap_m4m4(vc->rv3d->persmat, mat);
+
+	///* calculate pivot for rotation around seletion if needed */
+	//if (U.uiflag & USER_ORBIT_SELECTION) {
+	//	paint_last_stroke_update(scene, vc->ar, mval);
+	//}
 
 	ED_region_tag_redraw(vc->ar);
 
@@ -3331,8 +3433,6 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
 		/* If using new VBO drawing, mark mcol as dirty to force colors gpu buffer refresh! */
 		ob->derivedFinal->dirty |= DM_DIRTY_MCOL_UPDATE_DRAW;
 	}
-	if (nodes)
-		MEM_freeN(nodes);
 
 }
 
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 8b06430..a2fa8c9 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -4360,7 +4360,7 @@ bool sculpt_stroke_get_location(bContext *C, float out[3], const float mouse[2])
 
 	//used in vwpaint
 	if (cache && srd.hit){
-		copy_v3_v3(cache->location, out);
+		copy_v3_v3(cache->true_location, out);
 	}
 
 	return srd.hit;
diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c
index 55c73b7..22c9eab 100644
--- a/source/blender/makesrna/intern/rna_sculpt_paint.c
+++ b/source/blender/makesrna/intern/rna_sculpt_paint.c
@@ -674,7 +674,7 @@ static void rna_def_vertex_paint(BlenderRNA *brna)
   RNA_def_property_int_sdna(prop, NULL, "radial_symm");
   RNA_def_property_int_default(prop, 1);
   RNA_def_property_range(prop, 1, 64);
-  RNA_def_property_ui_range(prop, 0, 32, 1, 1);
+  RNA_def_property_ui_range(prop, 1, 32, 1, 1);
   RNA_def_property_ui_text(prop, "Radial Symmetry Count X Axis",
     "Number of times to copy strokes across the surface");
 }




More information about the Bf-blender-cvs mailing list