1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2020 Blender Foundation.
17  * All rights reserved.
18  */
19 
20 /** \file
21  * \ingroup edsculpt
22  */
23 
24 #include "MEM_guardedalloc.h"
25 
26 #include "BLI_blenlib.h"
27 #include "BLI_hash.h"
28 #include "BLI_math.h"
29 #include "BLI_task.h"
30 
31 #include "BLT_translation.h"
32 
33 #include "DNA_mesh_types.h"
34 #include "DNA_meshdata_types.h"
35 
36 #include "BKE_brush.h"
37 #include "BKE_context.h"
38 #include "BKE_mesh.h"
39 #include "BKE_mesh_mapping.h"
40 #include "BKE_object.h"
41 #include "BKE_paint.h"
42 #include "BKE_pbvh.h"
43 #include "BKE_scene.h"
44 #include "BKE_screen.h"
45 
46 #include "DEG_depsgraph.h"
47 
48 #include "WM_api.h"
49 #include "WM_message.h"
50 #include "WM_toolsystem.h"
51 #include "WM_types.h"
52 
53 #include "ED_object.h"
54 #include "ED_screen.h"
55 #include "ED_sculpt.h"
56 #include "ED_view3d.h"
57 #include "paint_intern.h"
58 #include "sculpt_intern.h"
59 
60 #include "RNA_access.h"
61 #include "RNA_define.h"
62 
63 #include "UI_interface.h"
64 
65 #include "bmesh.h"
66 
67 #include <math.h>
68 #include <stdlib.h>
69 
70 typedef struct {
71   const float *ray_start;
72   bool hit;
73   float depth;
74   float edge_length;
75 
76   struct IsectRayPrecalc isect_precalc;
77 } SculptDetailRaycastData;
78 
sculpt_and_constant_or_manual_detail_poll(bContext * C)79 static bool sculpt_and_constant_or_manual_detail_poll(bContext *C)
80 {
81   Object *ob = CTX_data_active_object(C);
82   Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
83 
84   return SCULPT_mode_poll(C) && ob->sculpt->bm &&
85          (sd->flags & (SCULPT_DYNTOPO_DETAIL_CONSTANT | SCULPT_DYNTOPO_DETAIL_MANUAL));
86 }
87 
sculpt_and_dynamic_topology_poll(bContext * C)88 static bool sculpt_and_dynamic_topology_poll(bContext *C)
89 {
90   Object *ob = CTX_data_active_object(C);
91 
92   return SCULPT_mode_poll(C) && ob->sculpt->bm;
93 }
94 
sculpt_detail_flood_fill_exec(bContext * C,wmOperator * UNUSED (op))95 static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *UNUSED(op))
96 {
97   Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
98   Object *ob = CTX_data_active_object(C);
99   SculptSession *ss = ob->sculpt;
100   float size;
101   float bb_min[3], bb_max[3], center[3], dim[3];
102   int totnodes;
103   PBVHNode **nodes;
104 
105   BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnodes);
106 
107   if (!totnodes) {
108     return OPERATOR_CANCELLED;
109   }
110 
111   for (int i = 0; i < totnodes; i++) {
112     BKE_pbvh_node_mark_topology_update(nodes[i]);
113   }
114   /* Get the bounding box, its center and size. */
115   BKE_pbvh_bounding_box(ob->sculpt->pbvh, bb_min, bb_max);
116   add_v3_v3v3(center, bb_min, bb_max);
117   mul_v3_fl(center, 0.5f);
118   sub_v3_v3v3(dim, bb_max, bb_min);
119   size = max_fff(dim[0], dim[1], dim[2]);
120 
121   /* Update topology size. */
122   float object_space_constant_detail = 1.0f / (sd->constant_detail * mat4_to_scale(ob->obmat));
123   BKE_pbvh_bmesh_detail_size_set(ss->pbvh, object_space_constant_detail);
124 
125   SCULPT_undo_push_begin("Dynamic topology flood fill");
126   SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_COORDS);
127 
128   while (BKE_pbvh_bmesh_update_topology(
129       ss->pbvh, PBVH_Collapse | PBVH_Subdivide, center, NULL, size, false, false)) {
130     for (int i = 0; i < totnodes; i++) {
131       BKE_pbvh_node_mark_topology_update(nodes[i]);
132     }
133   }
134 
135   MEM_SAFE_FREE(nodes);
136   SCULPT_undo_push_end();
137 
138   /* Force rebuild of pbvh for better BB placement. */
139   SCULPT_pbvh_clear(ob);
140   /* Redraw. */
141   WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
142 
143   return OPERATOR_FINISHED;
144 }
145 
SCULPT_OT_detail_flood_fill(wmOperatorType * ot)146 void SCULPT_OT_detail_flood_fill(wmOperatorType *ot)
147 {
148   /* Identifiers. */
149   ot->name = "Detail Flood Fill";
150   ot->idname = "SCULPT_OT_detail_flood_fill";
151   ot->description = "Flood fill the mesh with the selected detail setting";
152 
153   /* API callbacks. */
154   ot->exec = sculpt_detail_flood_fill_exec;
155   ot->poll = sculpt_and_constant_or_manual_detail_poll;
156 
157   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
158 }
159 
160 typedef enum eSculptSampleDetailModeTypes {
161   SAMPLE_DETAIL_DYNTOPO = 0,
162   SAMPLE_DETAIL_VOXEL = 1,
163 } eSculptSampleDetailModeTypes;
164 
165 static EnumPropertyItem prop_sculpt_sample_detail_mode_types[] = {
166     {SAMPLE_DETAIL_DYNTOPO, "DYNTOPO", 0, "Dyntopo", "Sample dyntopo detail"},
167     {SAMPLE_DETAIL_VOXEL, "VOXEL", 0, "Voxel", "Sample mesh voxel size"},
168     {0, NULL, 0, NULL, NULL},
169 };
170 
sample_detail_voxel(bContext * C,ViewContext * vc,int mx,int my)171 static void sample_detail_voxel(bContext *C, ViewContext *vc, int mx, int my)
172 {
173   Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
174   Object *ob = vc->obact;
175   Mesh *mesh = ob->data;
176 
177   SculptSession *ss = ob->sculpt;
178   SculptCursorGeometryInfo sgi;
179   SCULPT_vertex_random_access_ensure(ss);
180 
181   /* Update the active vertex. */
182   const float mouse[2] = {mx, my};
183   SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false);
184   BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, false);
185 
186   /* Average the edge length of the connected edges to the active vertex. */
187   int active_vertex = SCULPT_active_vertex_get(ss);
188   const float *active_vertex_co = SCULPT_active_vertex_co_get(ss);
189   float edge_length = 0.0f;
190   int tot = 0;
191   SculptVertexNeighborIter ni;
192   SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, active_vertex, ni) {
193     edge_length += len_v3v3(active_vertex_co, SCULPT_vertex_co_get(ss, ni.index));
194     tot += 1;
195   }
196   SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
197   if (tot > 0) {
198     mesh->remesh_voxel_size = edge_length / (float)tot;
199   }
200 }
201 
sculpt_raycast_detail_cb(PBVHNode * node,void * data_v,float * tmin)202 static void sculpt_raycast_detail_cb(PBVHNode *node, void *data_v, float *tmin)
203 {
204   if (BKE_pbvh_node_get_tmin(node) < *tmin) {
205     SculptDetailRaycastData *srd = data_v;
206     if (BKE_pbvh_bmesh_node_raycast_detail(
207             node, srd->ray_start, &srd->isect_precalc, &srd->depth, &srd->edge_length)) {
208       srd->hit = true;
209       *tmin = srd->depth;
210     }
211   }
212 }
213 
sample_detail_dyntopo(bContext * C,ViewContext * vc,ARegion * region,int mx,int my)214 static void sample_detail_dyntopo(bContext *C, ViewContext *vc, ARegion *region, int mx, int my)
215 {
216   Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
217   Object *ob = vc->obact;
218   Brush *brush = BKE_paint_brush(&sd->paint);
219 
220   SCULPT_stroke_modifiers_check(C, ob, brush);
221 
222   const float mouse[2] = {mx - region->winrct.xmin, my - region->winrct.ymin};
223   float ray_start[3], ray_end[3], ray_normal[3];
224   float depth = SCULPT_raycast_init(vc, mouse, ray_start, ray_end, ray_normal, false);
225 
226   SculptDetailRaycastData srd;
227   srd.hit = 0;
228   srd.ray_start = ray_start;
229   srd.depth = depth;
230   srd.edge_length = 0.0f;
231   isect_ray_tri_watertight_v3_precalc(&srd.isect_precalc, ray_normal);
232 
233   BKE_pbvh_raycast(ob->sculpt->pbvh, sculpt_raycast_detail_cb, &srd, ray_start, ray_normal, false);
234 
235   if (srd.hit && srd.edge_length > 0.0f) {
236     /* Convert edge length to world space detail resolution. */
237     sd->constant_detail = 1 / (srd.edge_length * mat4_to_scale(ob->obmat));
238   }
239 }
240 
sample_detail(bContext * C,int mx,int my,int mode)241 static int sample_detail(bContext *C, int mx, int my, int mode)
242 {
243   /* Find 3D view to pick from. */
244   bScreen *screen = CTX_wm_screen(C);
245   ScrArea *area = BKE_screen_find_area_xy(screen, SPACE_VIEW3D, mx, my);
246   ARegion *region = (area) ? BKE_area_find_region_xy(area, RGN_TYPE_WINDOW, mx, my) : NULL;
247   if (region == NULL) {
248     return OPERATOR_CANCELLED;
249   }
250 
251   /* Set context to 3D view. */
252   ScrArea *prev_area = CTX_wm_area(C);
253   ARegion *prev_region = CTX_wm_region(C);
254   CTX_wm_area_set(C, area);
255   CTX_wm_region_set(C, region);
256 
257   Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
258   ViewContext vc;
259   ED_view3d_viewcontext_init(C, &vc, depsgraph);
260 
261   Object *ob = vc.obact;
262   if (ob == NULL) {
263     return OPERATOR_CANCELLED;
264   }
265 
266   SculptSession *ss = ob->sculpt;
267   if (!ss->pbvh) {
268     return OPERATOR_CANCELLED;
269   }
270 
271   /* Pick sample detail. */
272   switch (mode) {
273     case SAMPLE_DETAIL_DYNTOPO:
274       if (BKE_pbvh_type(ss->pbvh) != PBVH_BMESH) {
275         CTX_wm_area_set(C, prev_area);
276         CTX_wm_region_set(C, prev_region);
277         return OPERATOR_CANCELLED;
278       }
279       sample_detail_dyntopo(C, &vc, region, mx, my);
280       break;
281     case SAMPLE_DETAIL_VOXEL:
282       if (BKE_pbvh_type(ss->pbvh) != PBVH_FACES) {
283         CTX_wm_area_set(C, prev_area);
284         CTX_wm_region_set(C, prev_region);
285         return OPERATOR_CANCELLED;
286       }
287       sample_detail_voxel(C, &vc, mx, my);
288       break;
289   }
290 
291   /* Restore context. */
292   CTX_wm_area_set(C, prev_area);
293   CTX_wm_region_set(C, prev_region);
294 
295   return OPERATOR_FINISHED;
296 }
297 
sculpt_sample_detail_size_exec(bContext * C,wmOperator * op)298 static int sculpt_sample_detail_size_exec(bContext *C, wmOperator *op)
299 {
300   int ss_co[2];
301   RNA_int_get_array(op->ptr, "location", ss_co);
302   int mode = RNA_enum_get(op->ptr, "mode");
303   return sample_detail(C, ss_co[0], ss_co[1], mode);
304 }
305 
sculpt_sample_detail_size_invoke(bContext * C,wmOperator * op,const wmEvent * UNUSED (e))306 static int sculpt_sample_detail_size_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(e))
307 {
308   ED_workspace_status_text(C, TIP_("Click on the mesh to set the detail"));
309   WM_cursor_modal_set(CTX_wm_window(C), WM_CURSOR_EYEDROPPER);
310   WM_event_add_modal_handler(C, op);
311   return OPERATOR_RUNNING_MODAL;
312 }
313 
sculpt_sample_detail_size_modal(bContext * C,wmOperator * op,const wmEvent * event)314 static int sculpt_sample_detail_size_modal(bContext *C, wmOperator *op, const wmEvent *event)
315 {
316   switch (event->type) {
317     case LEFTMOUSE:
318       if (event->val == KM_PRESS) {
319         const int ss_co[2] = {event->x, event->y};
320 
321         int mode = RNA_enum_get(op->ptr, "mode");
322         sample_detail(C, ss_co[0], ss_co[1], mode);
323 
324         RNA_int_set_array(op->ptr, "location", ss_co);
325         WM_cursor_modal_restore(CTX_wm_window(C));
326         ED_workspace_status_text(C, NULL);
327         WM_main_add_notifier(NC_SCENE | ND_TOOLSETTINGS, NULL);
328 
329         return OPERATOR_FINISHED;
330       }
331       break;
332     case EVT_ESCKEY:
333     case RIGHTMOUSE: {
334       WM_cursor_modal_restore(CTX_wm_window(C));
335       ED_workspace_status_text(C, NULL);
336 
337       return OPERATOR_CANCELLED;
338     }
339   }
340 
341   return OPERATOR_RUNNING_MODAL;
342 }
343 
SCULPT_OT_sample_detail_size(wmOperatorType * ot)344 void SCULPT_OT_sample_detail_size(wmOperatorType *ot)
345 {
346   /* Identifiers. */
347   ot->name = "Sample Detail Size";
348   ot->idname = "SCULPT_OT_sample_detail_size";
349   ot->description = "Sample the mesh detail on clicked point";
350 
351   /* API callbacks. */
352   ot->invoke = sculpt_sample_detail_size_invoke;
353   ot->exec = sculpt_sample_detail_size_exec;
354   ot->modal = sculpt_sample_detail_size_modal;
355   ot->poll = SCULPT_mode_poll;
356 
357   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
358 
359   RNA_def_int_array(ot->srna,
360                     "location",
361                     2,
362                     NULL,
363                     0,
364                     SHRT_MAX,
365                     "Location",
366                     "Screen Coordinates of sampling",
367                     0,
368                     SHRT_MAX);
369   RNA_def_enum(ot->srna,
370                "mode",
371                prop_sculpt_sample_detail_mode_types,
372                SAMPLE_DETAIL_DYNTOPO,
373                "Detail Mode",
374                "Target sculpting workflow that is going to use the sampled size");
375 }
376 
377 /* Dynamic-topology detail size.
378  *
379  * This should be improved further, perhaps by showing a triangle
380  * grid rather than brush alpha. */
set_brush_rc_props(PointerRNA * ptr,const char * prop)381 static void set_brush_rc_props(PointerRNA *ptr, const char *prop)
382 {
383   char *path = BLI_sprintfN("tool_settings.sculpt.brush.%s", prop);
384   RNA_string_set(ptr, "data_path_primary", path);
385   MEM_freeN(path);
386 }
387 
sculpt_set_detail_size_exec(bContext * C,wmOperator * UNUSED (op))388 static int sculpt_set_detail_size_exec(bContext *C, wmOperator *UNUSED(op))
389 {
390   Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
391 
392   PointerRNA props_ptr;
393   wmOperatorType *ot = WM_operatortype_find("WM_OT_radial_control", true);
394 
395   WM_operator_properties_create_ptr(&props_ptr, ot);
396 
397   if (sd->flags & (SCULPT_DYNTOPO_DETAIL_CONSTANT | SCULPT_DYNTOPO_DETAIL_MANUAL)) {
398     set_brush_rc_props(&props_ptr, "constant_detail_resolution");
399     RNA_string_set(
400         &props_ptr, "data_path_primary", "tool_settings.sculpt.constant_detail_resolution");
401   }
402   else if (sd->flags & SCULPT_DYNTOPO_DETAIL_BRUSH) {
403     set_brush_rc_props(&props_ptr, "constant_detail_resolution");
404     RNA_string_set(&props_ptr, "data_path_primary", "tool_settings.sculpt.detail_percent");
405   }
406   else {
407     set_brush_rc_props(&props_ptr, "detail_size");
408     RNA_string_set(&props_ptr, "data_path_primary", "tool_settings.sculpt.detail_size");
409   }
410 
411   WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &props_ptr);
412 
413   WM_operator_properties_free(&props_ptr);
414 
415   return OPERATOR_FINISHED;
416 }
417 
SCULPT_OT_set_detail_size(wmOperatorType * ot)418 void SCULPT_OT_set_detail_size(wmOperatorType *ot)
419 {
420   /* Identifiers. */
421   ot->name = "Set Detail Size";
422   ot->idname = "SCULPT_OT_set_detail_size";
423   ot->description =
424       "Set the mesh detail (either relative or constant one, depending on current dyntopo mode)";
425 
426   /* API callbacks. */
427   ot->exec = sculpt_set_detail_size_exec;
428   ot->poll = sculpt_and_dynamic_topology_poll;
429 
430   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
431 }
432