Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/sculpt_paint/sculpt.c
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
| Show First 20 Lines • Show All 1,510 Lines • ▼ Show 20 Lines | if (br->automasking_flags & BRUSH_AUTOMASKING_TOPOLOGY) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| if (br->automasking_flags & BRUSH_AUTOMASKING_FACE_SETS) { | if (br->automasking_flags & BRUSH_AUTOMASKING_FACE_SETS) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| if (br->automasking_flags & BRUSH_AUTOMASKING_BOUNDARY_EDGES) { | if (br->automasking_flags & BRUSH_AUTOMASKING_BOUNDARY_EDGES) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| if (br->automasking_flags & BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS) { | |||||
| return true; | |||||
| } | |||||
| return false; | return false; | ||||
| } | } | ||||
| float SCULPT_automasking_factor_get(SculptSession *ss, int vert) | float SCULPT_automasking_factor_get(SculptSession *ss, int vert) | ||||
| { | { | ||||
| if (ss->cache->automask) { | if (ss->cache->automask) { | ||||
| return ss->cache->automask[vert]; | return ss->cache->automask[vert]; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 102 Lines • ▼ Show 20 Lines | for (int i = 0; i < tot_vert; i++) { | ||||
| } | } | ||||
| } | } | ||||
| return automask_factor; | return automask_factor; | ||||
| } | } | ||||
| #define EDGE_DISTANCE_INF -1 | #define EDGE_DISTANCE_INF -1 | ||||
| static float *sculpt_boundary_edges_automasking_init(Object *ob, | typedef enum eBoundaryAutomaskMode { | ||||
| AUTOMASK_INIT_BOUNDARY_EDGES = 1, | |||||
| AUTOMASK_INIT_BOUNDARY_FACE_SETS = 2, | |||||
| } eBoundaryAutomaskMode; | |||||
| static float *sculpt_boundary_automasking_init(Object *ob, | |||||
| eBoundaryAutomaskMode mode, | |||||
| int propagation_steps, | int propagation_steps, | ||||
| float *automask_factor) | float *automask_factor) | ||||
| { | { | ||||
| SculptSession *ss = ob->sculpt; | SculptSession *ss = ob->sculpt; | ||||
| if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES && !ss->pmap) { | if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES && !ss->pmap) { | ||||
| BLI_assert(!"Boundary Edges masking: pmap missing"); | BLI_assert(!"Boundary Edges masking: pmap missing"); | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| const int totvert = SCULPT_vertex_count_get(ss); | const int totvert = SCULPT_vertex_count_get(ss); | ||||
| int *edge_distance = MEM_callocN(sizeof(int) * totvert, "automask_factor"); | int *edge_distance = MEM_callocN(sizeof(int) * totvert, "automask_factor"); | ||||
| for (int i = 0; i < totvert; i++) { | for (int i = 0; i < totvert; i++) { | ||||
| edge_distance[i] = EDGE_DISTANCE_INF; | edge_distance[i] = EDGE_DISTANCE_INF; | ||||
| switch (mode) { | |||||
| case AUTOMASK_INIT_BOUNDARY_EDGES: | |||||
| if (!sculpt_vertex_is_boundary(ss, i)) { | if (!sculpt_vertex_is_boundary(ss, i)) { | ||||
| edge_distance[i] = 0; | edge_distance[i] = 0; | ||||
| } | } | ||||
| break; | |||||
| case AUTOMASK_INIT_BOUNDARY_FACE_SETS: | |||||
| if (!sculpt_vertex_has_unique_face_set(ss, i)) { | |||||
| edge_distance[i] = 0; | |||||
| } | |||||
| break; | |||||
| } | |||||
| } | } | ||||
| for (int propagation_it = 0; propagation_it < propagation_steps; propagation_it++) { | for (int propagation_it = 0; propagation_it < propagation_steps; propagation_it++) { | ||||
| for (int i = 0; i < totvert; i++) { | for (int i = 0; i < totvert; i++) { | ||||
| if (edge_distance[i] == EDGE_DISTANCE_INF) { | if (edge_distance[i] == EDGE_DISTANCE_INF) { | ||||
| SculptVertexNeighborIter ni; | SculptVertexNeighborIter ni; | ||||
| sculpt_vertex_neighbors_iter_begin(ss, i, ni) | sculpt_vertex_neighbors_iter_begin(ss, i, ni) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | static void sculpt_automasking_init(Sculpt *sd, Object *ob) | ||||
| } | } | ||||
| if (brush->automasking_flags & BRUSH_AUTOMASKING_FACE_SETS) { | if (brush->automasking_flags & BRUSH_AUTOMASKING_FACE_SETS) { | ||||
| SCULPT_vertex_random_access_init(ss); | SCULPT_vertex_random_access_init(ss); | ||||
| sculpt_face_sets_automasking_init(sd, ob, ss->cache->automask); | sculpt_face_sets_automasking_init(sd, ob, ss->cache->automask); | ||||
| } | } | ||||
| if (brush->automasking_flags & BRUSH_AUTOMASKING_BOUNDARY_EDGES) { | if (brush->automasking_flags & BRUSH_AUTOMASKING_BOUNDARY_EDGES) { | ||||
| SCULPT_vertex_random_access_init(ss); | SCULPT_vertex_random_access_init(ss); | ||||
| sculpt_boundary_edges_automasking_init( | sculpt_boundary_automasking_init(ob, | ||||
| ob, brush->automasking_boundary_edges_propagation_steps, ss->cache->automask); | AUTOMASK_INIT_BOUNDARY_EDGES, | ||||
| brush->automasking_boundary_edges_propagation_steps, | |||||
| ss->cache->automask); | |||||
| } | |||||
| if (brush->automasking_flags & BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS) { | |||||
jbakker: isn't this mutual exclusive? | |||||
pablodp606AuthorUnsubmitted Done Inline ActionsNo, you can enable any combination of automasking operations and the result is the combination of the masks generated in each one of them. In the future we could probably expose this better in the UI, as each one of this operations can have different parameters and their order can also be changed. pablodp606: No, you can enable any combination of automasking operations and the result is the combination… | |||||
| SCULPT_vertex_random_access_init(ss); | |||||
| sculpt_boundary_automasking_init(ob, | |||||
| AUTOMASK_INIT_BOUNDARY_FACE_SETS, | |||||
| brush->automasking_boundary_edges_propagation_steps, | |||||
| ss->cache->automask); | |||||
| } | } | ||||
| } | } | ||||
| /* ===== Sculpting ===== | /* ===== Sculpting ===== | ||||
| */ | */ | ||||
| static void flip_v3(float v[3], const ePaintSymmetryFlags symm) | static void flip_v3(float v[3], const ePaintSymmetryFlags symm) | ||||
| { | { | ||||
| flip_v3_v3(v, v, symm); | flip_v3_v3(v, v, symm); | ||||
| ▲ Show 20 Lines • Show All 7,736 Lines • ▼ Show 20 Lines | static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent *event) | ||||
| if (RNA_enum_get(op->ptr, "type") == MESH_FILTER_RELAX) { | if (RNA_enum_get(op->ptr, "type") == MESH_FILTER_RELAX) { | ||||
| const int totvert = SCULPT_vertex_count_get(ss); | const int totvert = SCULPT_vertex_count_get(ss); | ||||
| ss->filter_cache->automask = MEM_mallocN(totvert * sizeof(float), | ss->filter_cache->automask = MEM_mallocN(totvert * sizeof(float), | ||||
| "Relax filter edge automask"); | "Relax filter edge automask"); | ||||
| for (int i = 0; i < totvert; i++) { | for (int i = 0; i < totvert; i++) { | ||||
| ss->filter_cache->automask[i] = 1.0f; | ss->filter_cache->automask[i] = 1.0f; | ||||
| } | } | ||||
| sculpt_boundary_edges_automasking_init(ob, 1, ss->filter_cache->automask); | sculpt_boundary_automasking_init( | ||||
| ob, AUTOMASK_INIT_BOUNDARY_EDGES, 1, ss->filter_cache->automask); | |||||
| } | } | ||||
| WM_event_add_modal_handler(C, op); | WM_event_add_modal_handler(C, op); | ||||
| return OPERATOR_RUNNING_MODAL; | return OPERATOR_RUNNING_MODAL; | ||||
| } | } | ||||
| static void SCULPT_OT_mesh_filter(struct wmOperatorType *ot) | static void SCULPT_OT_mesh_filter(struct wmOperatorType *ot) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 1,707 Lines • Show Last 20 Lines | |||||
isn't this mutual exclusive?