Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntony Riakiotakis <kalast@gmail.com>2013-12-19 16:39:54 +0400
committerAntony Riakiotakis <kalast@gmail.com>2013-12-19 16:40:19 +0400
commita102d3397f69e84b11d57ac15a5206a60cf41614 (patch)
tree95eb6f2ecf960be784604d7ae58cb569469878aa /source/blender/editors/sculpt_paint
parent70ef1f20043425d0b721cbb03eebaa26ec013af9 (diff)
Sculpting:
* Support for symmetry in lasso masking * Optimize away symmetry multiplication of gravity vector if no gravity active * Move flip_v3_v3 to paint_utils (used in masking as well) * Use OpenMP for mask flood fill too.
Diffstat (limited to 'source/blender/editors/sculpt_paint')
-rw-r--r--source/blender/editors/sculpt_paint/paint_intern.h1
-rw-r--r--source/blender/editors/sculpt_paint/paint_mask.c77
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c17
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c20
4 files changed, 70 insertions, 45 deletions
diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h
index 01f5d53594e..57eaa454621 100644
--- a/source/blender/editors/sculpt_paint/paint_intern.h
+++ b/source/blender/editors/sculpt_paint/paint_intern.h
@@ -219,6 +219,7 @@ int vert_paint_poll(struct bContext *C);
int mask_paint_poll(struct bContext *C);
int facemask_paint_poll(struct bContext *C);
+void flip_v3_v3(float out[3], const float in[3], const char symm);
/* stroke operator */
typedef enum BrushStrokeMode {
diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c
index 320bf4f0f5e..acc138afcb8 100644
--- a/source/blender/editors/sculpt_paint/paint_mask.c
+++ b/source/blender/editors/sculpt_paint/paint_mask.c
@@ -94,6 +94,9 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op)
PBVH *pbvh;
PBVHNode **nodes;
int totnode, i;
+#ifdef _OPENMP
+ Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+#endif
mode = RNA_enum_get(op->ptr, "mode");
value = RNA_float_get(op->ptr, "value");
@@ -108,6 +111,7 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op)
sculpt_undo_push_begin("Mask flood fill");
+ #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
for (i = 0; i < totnode; i++) {
PBVHVertexIter vi;
@@ -231,7 +235,7 @@ int do_sculpt_mask_box_select(ViewContext *vc, rcti *rect, bool select, bool UNU
BKE_pbvh_search_gather(pbvh, BKE_pbvh_node_planes_contain_AABB, clip_planes_final, &nodes, &totnode);
-#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
+ #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
for (i = 0; i < totnode; i++) {
PBVHVertexIter vi;
bool any_masked = false;
@@ -270,6 +274,7 @@ typedef struct LassoMaskData {
bool *px;
int width;
rcti rect; /* bounding box for scanfilling */
+ int symmpass;
} LassoMaskData;
@@ -280,9 +285,11 @@ static bool is_effected_lasso(LassoMaskData *data, float co[3])
{
float scr_co_f[2];
short scr_co_s[2];
+ float co_final[3];
+ flip_v3_v3(co_final, co, data->symmpass);
/* first project point to 2d space */
- ED_view3d_project_float_v2_m4(data->vc->ar, co, scr_co_f, data->projviewobjmat);
+ ED_view3d_project_float_v2_m4(data->vc->ar, co_final, scr_co_f, data->projviewobjmat);
scr_co_s[0] = scr_co_f[0];
scr_co_s[1] = scr_co_f[1];
@@ -309,20 +316,19 @@ static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op)
int (*mcords)[2] = (int (*)[2])WM_gesture_lasso_path_to_array(C, op, &mcords_tot);
if (mcords) {
- float clip_planes[4][4];
+ float clip_planes[4][4], clip_planes_final[4][4];
BoundBox bb;
bglMats mats = {{0}};
Object *ob;
ViewContext vc;
LassoMaskData data;
-#ifdef _OPENMP
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
-#endif
+ int symm = sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL;
struct MultiresModifierData *mmd;
DerivedMesh *dm;
PBVH *pbvh;
PBVHNode **nodes;
- int totnode, i;
+ int totnode, i, symmpass;
PaintMaskFloodMode mode = PAINT_MASK_FLOOD_VALUE;
bool select = true; /* TODO: see how to implement deselection */
float value = select ? 1.0 : 0.0;
@@ -356,38 +362,55 @@ static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op)
pbvh = dm->getPBVH(ob, dm);
ob->sculpt->pbvh = pbvh;
- /* gather nodes inside lasso's enclosing rectangle (should greatly help with bigger meshes) */
- BKE_pbvh_search_gather(pbvh, BKE_pbvh_node_planes_contain_AABB, clip_planes, &nodes, &totnode);
-
sculpt_undo_push_begin("Mask lasso fill");
-#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
- for (i = 0; i < totnode; i++) {
- PBVHVertexIter vi;
- bool any_masked = false;
+ for (symmpass = 0; symmpass <= symm; ++symmpass) {
+ if (symmpass == 0 ||
+ (symm & symmpass &&
+ (symm != 5 || symmpass != 3) &&
+ (symm != 6 || (symmpass != 3 && symmpass != 5))))
+ {
+ int j = 0;
+
+ /* flip the planes symmetrically as needed */
+ for (; j < 4; j++) {
+ flip_plane(clip_planes_final[j], clip_planes[j], symmpass);
+ }
- BKE_pbvh_vertex_iter_begin(pbvh, nodes[i], vi, PBVH_ITER_UNIQUE) {
- if (is_effected_lasso(&data, vi.co)) {
- if (!any_masked) {
- any_masked = true;
+ data.symmpass = symmpass;
- sculpt_undo_push_node(ob, nodes[i], SCULPT_UNDO_MASK);
+ /* gather nodes inside lasso's enclosing rectangle (should greatly help with bigger meshes) */
+ BKE_pbvh_search_gather(pbvh, BKE_pbvh_node_planes_contain_AABB, clip_planes_final, &nodes, &totnode);
- BKE_pbvh_node_mark_redraw(nodes[i]);
- if (BKE_pbvh_type(pbvh) == PBVH_GRIDS)
- multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED);
- }
+ #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
+ for (i = 0; i < totnode; i++) {
+ PBVHVertexIter vi;
+ bool any_masked = false;
- mask_flood_fill_set_elem(vi.mask, mode, value);
+ BKE_pbvh_vertex_iter_begin(pbvh, nodes[i], vi, PBVH_ITER_UNIQUE) {
+ if (is_effected_lasso(&data, vi.co)) {
+ if (!any_masked) {
+ any_masked = true;
+
+ sculpt_undo_push_node(ob, nodes[i], SCULPT_UNDO_MASK);
+
+ BKE_pbvh_node_mark_redraw(nodes[i]);
+ if (BKE_pbvh_type(pbvh) == PBVH_GRIDS)
+ multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED);
+ }
+
+ mask_flood_fill_set_elem(vi.mask, mode, value);
+ }
+ } BKE_pbvh_vertex_iter_end;
}
- } BKE_pbvh_vertex_iter_end;
+
+ if (nodes)
+ MEM_freeN(nodes);
+ }
}
sculpt_undo_push_end();
- if (nodes)
- MEM_freeN(nodes);
-
ED_region_tag_redraw(vc.ar);
MEM_freeN((void *)mcords);
MEM_freeN(data.px);
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index bfc431baea5..dd414a7b2b2 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -342,6 +342,23 @@ int imapaint_pick_face(ViewContext *vc, const int mval[2], unsigned int *index,
return 1;
}
+/* Uses symm to selectively flip any axis of a coordinate. */
+void flip_v3_v3(float out[3], const float in[3], const char symm)
+{
+ if (symm & PAINT_SYMM_X)
+ out[0] = -in[0];
+ else
+ out[0] = in[0];
+ if (symm & PAINT_SYMM_Y)
+ out[1] = -in[1];
+ else
+ out[1] = in[1];
+ if (symm & PAINT_SYMM_Z)
+ out[2] = -in[2];
+ else
+ out[2] = in[2];
+}
+
/* used for both 3d view and image window */
void paint_sample_color(const bContext *C, ARegion *ar, int x, int y) /* frontbuf */
{
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 4a1859c15f8..975aa28166e 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -759,23 +759,6 @@ static float integrate_overlap(Brush *br)
return max;
}
-/* Uses symm to selectively flip any axis of a coordinate. */
-static void flip_v3_v3(float out[3], const float in[3], const char symm)
-{
- if (symm & PAINT_SYMM_X)
- out[0] = -in[0];
- else
- out[0] = in[0];
- if (symm & PAINT_SYMM_Y)
- out[1] = -in[1];
- else
- out[1] = in[1];
- if (symm & PAINT_SYMM_Z)
- out[2] = -in[2];
- else
- out[2] = in[2];
-}
-
static void flip_v3(float v[3], const char symm)
{
flip_v3_v3(v, v, symm);
@@ -3478,9 +3461,10 @@ static void calc_brushdata_symm(Sculpt *sd, StrokeCache *cache, const char symm,
mul_m4_v3(cache->symm_rot_mat, cache->location);
mul_m4_v3(cache->symm_rot_mat, cache->grab_delta_symmetry);
- if (cache->supports_gravity)
+ 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);
+ }
}
typedef void (*BrushActionFunc)(Sculpt *sd, Object *ob, Brush *brush);