define the size of matrix args for both rows/cols.
[blender.git] / source / blender / editors / sculpt_paint / paint_utils.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/editors/sculpt_paint/paint_utils.c
29  *  \ingroup edsculpt
30  */
31
32 #include <math.h>
33 #include <stdlib.h>
34
35 #include "DNA_mesh_types.h"
36 #include "DNA_meshdata_types.h"
37 #include "DNA_object_types.h"
38
39 #include "DNA_scene_types.h"
40 #include "DNA_brush_types.h"
41
42 #include "BLI_math.h"
43 #include "BLI_utildefines.h"
44 #include "BLI_rect.h"
45
46 #include "BKE_brush.h"
47 #include "BKE_context.h"
48 #include "BKE_DerivedMesh.h"
49 #include "BKE_paint.h"
50
51 #include "RNA_access.h"
52 #include "RNA_define.h"
53
54 #include "BIF_gl.h"
55 /* TODO: remove once projectf goes away */
56 #include "BIF_glutil.h"
57
58 #include "RE_shader_ext.h"
59
60 #include "ED_view3d.h"
61 #include "ED_screen.h"
62
63 #include "BLO_sys_types.h"
64 #include "ED_mesh.h" /* for face mask functions */
65
66 #include "WM_api.h"
67 #include "WM_types.h"
68
69 #include "paint_intern.h"
70
71 /* Convert the object-space axis-aligned bounding box (expressed as
72  * its minimum and maximum corners) into a screen-space rectangle,
73  * returns zero if the result is empty */
74 int paint_convert_bb_to_rect(rcti *rect,
75                              const float bb_min[3],
76                              const float bb_max[3],
77                              const ARegion *ar,
78                              RegionView3D *rv3d,
79                              Object *ob)
80 {
81         float projection_mat[4][4];
82         int i, j, k;
83
84         BLI_rcti_init_minmax(rect);
85
86         /* return zero if the bounding box has non-positive volume */
87         if (bb_min[0] > bb_max[0] || bb_min[1] > bb_max[1] || bb_min[2] > bb_max[2])
88                 return 0;
89
90         ED_view3d_ob_project_mat_get(rv3d, ob, projection_mat);
91
92         for (i = 0; i < 2; ++i) {
93                 for (j = 0; j < 2; ++j) {
94                         for (k = 0; k < 2; ++k) {
95                                 float vec[3], proj[2];
96                                 int proj_i[2];
97                                 vec[0] = i ? bb_min[0] : bb_max[0];
98                                 vec[1] = j ? bb_min[1] : bb_max[1];
99                                 vec[2] = k ? bb_min[2] : bb_max[2];
100                                 /* convert corner to screen space */
101                                 ED_view3d_project_float_v2_m4(ar, vec, proj, projection_mat);
102                                 /* expand 2D rectangle */
103
104                                 /* we could project directly to int? */
105                                 proj_i[0] = proj[0];
106                                 proj_i[1] = proj[1];
107
108                                 BLI_rcti_do_minmax_v(rect, proj_i);
109                         }
110                 }
111         }
112
113         /* return false if the rectangle has non-positive area */
114         return rect->xmin < rect->xmax && rect->ymin < rect->ymax;
115 }
116
117 /* Get four planes in object-space that describe the projection of
118  * screen_rect from screen into object-space (essentially converting a
119  * 2D screens-space bounding box into four 3D planes) */
120 void paint_calc_redraw_planes(float planes[4][4],
121                               const ARegion *ar,
122                               RegionView3D *rv3d,
123                               Object *ob,
124                               const rcti *screen_rect)
125 {
126         BoundBox bb;
127         bglMats mats;
128         rcti rect;
129
130         memset(&bb, 0, sizeof(BoundBox));
131         view3d_get_transformation(ar, rv3d, ob, &mats);
132
133         /* use some extra space just in case */
134         rect = *screen_rect;
135         rect.xmin -= 2;
136         rect.xmax += 2;
137         rect.ymin -= 2;
138         rect.ymax += 2;
139
140         ED_view3d_clipping_calc(&bb, planes, &mats, &rect);
141         mul_m4_fl(planes, -1.0f);
142 }
143
144 /* convert a point in model coordinates to 2D screen coordinates */
145 /* TODO: can be deleted once all calls are replaced with
146  * view3d_project_float() */
147 void projectf(bglMats *mats, const float v[3], float p[2])
148 {
149         double ux, uy, uz;
150
151         gluProject(v[0], v[1], v[2], mats->modelview, mats->projection,
152                    (GLint *)mats->viewport, &ux, &uy, &uz);
153         p[0] = ux;
154         p[1] = uy;
155 }
156
157 float paint_calc_object_space_radius(ViewContext *vc, const float center[3],
158                                      float pixel_radius)
159 {
160         Object *ob = vc->obact;
161         float delta[3], scale, loc[3];
162         const float mval_f[2] = {pixel_radius, 0.0f};
163
164         mul_v3_m4v3(loc, ob->obmat, center);
165
166         initgrabz(vc->rv3d, loc[0], loc[1], loc[2]);
167
168         ED_view3d_win_to_delta(vc->ar, mval_f, delta);
169
170         scale = fabsf(mat4_to_scale(ob->obmat));
171         scale = (scale == 0.0f) ? 1.0f : scale;
172
173         return len_v3(delta) / scale;
174 }
175
176 float paint_get_tex_pixel(Brush *br, float u, float v)
177 {
178         TexResult texres = {0};
179         float co[3] = {u, v, 0.0f};
180         int hasrgb;
181
182         hasrgb = multitex_ext(br->mtex.tex, co, NULL, NULL, 0, &texres);
183
184         if (hasrgb & TEX_RGB)
185                 texres.tin = rgb_to_grayscale(&texres.tr) * texres.ta;
186
187         return texres.tin;
188 }
189
190 /* 3D Paint */
191
192 static void imapaint_project(Object *ob, float model[4][4], float proj[4][4], const float co[3], float pco[4])
193 {
194         copy_v3_v3(pco, co);
195         pco[3] = 1.0f;
196
197         mul_m4_v3(ob->obmat, pco);
198         mul_m4_v3(model, pco);
199         mul_m4_v4(proj, pco);
200 }
201
202 static void imapaint_tri_weights(Object *ob,
203                                  const float v1[3], const float v2[3], const float v3[3],
204                                  const float co[2], float w[3])
205 {
206         float pv1[4], pv2[4], pv3[4], h[3], divw;
207         float model[4][4], proj[4][4], wmat[3][3], invwmat[3][3];
208         GLint view[4];
209
210         /* compute barycentric coordinates */
211
212         /* get the needed opengl matrices */
213         glGetIntegerv(GL_VIEWPORT, view);
214         glGetFloatv(GL_MODELVIEW_MATRIX,  (float *)model);
215         glGetFloatv(GL_PROJECTION_MATRIX, (float *)proj);
216         view[0] = view[1] = 0;
217
218         /* project the verts */
219         imapaint_project(ob, model, proj, v1, pv1);
220         imapaint_project(ob, model, proj, v2, pv2);
221         imapaint_project(ob, model, proj, v3, pv3);
222
223         /* do inverse view mapping, see gluProject man page */
224         h[0] = (co[0] - view[0]) * 2.0f / view[2] - 1;
225         h[1] = (co[1] - view[1]) * 2.0f / view[3] - 1;
226         h[2] = 1.0f;
227
228         /* solve for (w1,w2,w3)/perspdiv in:
229          * h * perspdiv = Project * Model * (w1 * v1 + w2 * v2 + w3 * v3) */
230
231         wmat[0][0] = pv1[0];  wmat[1][0] = pv2[0];  wmat[2][0] = pv3[0];
232         wmat[0][1] = pv1[1];  wmat[1][1] = pv2[1];  wmat[2][1] = pv3[1];
233         wmat[0][2] = pv1[3];  wmat[1][2] = pv2[3];  wmat[2][2] = pv3[3];
234
235         invert_m3_m3(invwmat, wmat);
236         mul_m3_v3(invwmat, h);
237
238         copy_v3_v3(w, h);
239
240         /* w is still divided by perspdiv, make it sum to one */
241         divw = w[0] + w[1] + w[2];
242         if (divw != 0.0f) {
243                 mul_v3_fl(w, 1.0f / divw);
244         }
245 }
246
247 /* compute uv coordinates of mouse in face */
248 void imapaint_pick_uv(Scene *scene, Object *ob, unsigned int faceindex, const int xy[2], float uv[2])
249 {
250         DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
251         MTFace *tface = dm->getTessFaceDataArray(dm, CD_MTFACE), *tf;
252         int numfaces = dm->getNumTessFaces(dm), a, findex;
253         float p[2], w[3], absw, minabsw;
254         MFace mf;
255         MVert mv[4];
256
257         /* double lookup */
258         const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
259         const int *index_mp_to_orig  = dm->getPolyDataArray(dm, CD_ORIGINDEX);
260         if (index_mf_to_mpoly == NULL) {
261                 index_mp_to_orig = NULL;
262         }
263
264         minabsw = 1e10;
265         uv[0] = uv[1] = 0.0;
266
267         /* test all faces in the derivedmesh with the original index of the picked face */
268         for (a = 0; a < numfaces; a++) {
269                 findex = index_mf_to_mpoly ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a) : a;
270
271                 if (findex == faceindex) {
272                         dm->getTessFace(dm, a, &mf);
273
274                         dm->getVert(dm, mf.v1, &mv[0]);
275                         dm->getVert(dm, mf.v2, &mv[1]);
276                         dm->getVert(dm, mf.v3, &mv[2]);
277                         if (mf.v4)
278                                 dm->getVert(dm, mf.v4, &mv[3]);
279
280                         tf = &tface[a];
281
282                         p[0] = xy[0];
283                         p[1] = xy[1];
284
285                         if (mf.v4) {
286                                 /* the triangle with the largest absolute values is the one
287                                  * with the most negative weights */
288                                 imapaint_tri_weights(ob, mv[0].co, mv[1].co, mv[3].co, p, w);
289                                 absw = fabsf(w[0]) + fabsf(w[1]) + fabsf(w[2]);
290                                 if (absw < minabsw) {
291                                         uv[0] = tf->uv[0][0] * w[0] + tf->uv[1][0] * w[1] + tf->uv[3][0] * w[2];
292                                         uv[1] = tf->uv[0][1] * w[0] + tf->uv[1][1] * w[1] + tf->uv[3][1] * w[2];
293                                         minabsw = absw;
294                                 }
295
296                                 imapaint_tri_weights(ob, mv[1].co, mv[2].co, mv[3].co, p, w);
297                                 absw = fabsf(w[0]) + fabsf(w[1]) + fabsf(w[2]);
298                                 if (absw < minabsw) {
299                                         uv[0] = tf->uv[1][0] * w[0] + tf->uv[2][0] * w[1] + tf->uv[3][0] * w[2];
300                                         uv[1] = tf->uv[1][1] * w[0] + tf->uv[2][1] * w[1] + tf->uv[3][1] * w[2];
301                                         minabsw = absw;
302                                 }
303                         }
304                         else {
305                                 imapaint_tri_weights(ob, mv[0].co, mv[1].co, mv[2].co, p, w);
306                                 absw = fabsf(w[0]) + fabsf(w[1]) + fabsf(w[2]);
307                                 if (absw < minabsw) {
308                                         uv[0] = tf->uv[0][0] * w[0] + tf->uv[1][0] * w[1] + tf->uv[2][0] * w[2];
309                                         uv[1] = tf->uv[0][1] * w[0] + tf->uv[1][1] * w[1] + tf->uv[2][1] * w[2];
310                                         minabsw = absw;
311                                 }
312                         }
313                 }
314         }
315
316         dm->release(dm);
317 }
318
319 /* returns 0 if not found, otherwise 1 */
320 int imapaint_pick_face(ViewContext *vc, const int mval[2], unsigned int *index, unsigned int totface)
321 {
322         if (totface == 0)
323                 return 0;
324
325         /* sample only on the exact position */
326         *index = view3d_sample_backbuf(vc, mval[0], mval[1]);
327
328         if ((*index) <= 0 || (*index) > (unsigned int)totface) {
329                 return 0;
330         }
331
332         (*index)--;
333         
334         return 1;
335 }
336
337 /* used for both 3d view and image window */
338 void paint_sample_color(const bContext *C, ARegion *ar, int x, int y)    /* frontbuf */
339 {
340         Brush *br = paint_brush(paint_get_active_from_context(C));
341         unsigned int col;
342         char *cp;
343
344         CLAMP(x, 0, ar->winx);
345         CLAMP(y, 0, ar->winy);
346         
347         glReadBuffer(GL_FRONT);
348         glReadPixels(x + ar->winrct.xmin, y + ar->winrct.ymin, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col);
349         glReadBuffer(GL_BACK);
350
351         cp = (char *)&col;
352         
353         if (br) {
354                 br->rgb[0] = cp[0] / 255.0f;
355                 br->rgb[1] = cp[1] / 255.0f;
356                 br->rgb[2] = cp[2] / 255.0f;
357         }
358 }
359
360 static int brush_curve_preset_exec(bContext *C, wmOperator *op)
361 {
362         Brush *br = paint_brush(paint_get_active_from_context(C));
363         BKE_brush_curve_preset(br, RNA_enum_get(op->ptr, "shape"));
364
365         return OPERATOR_FINISHED;
366 }
367
368 static int brush_curve_preset_poll(bContext *C)
369 {
370         Brush *br = paint_brush(paint_get_active_from_context(C));
371
372         return br && br->curve;
373 }
374
375 void BRUSH_OT_curve_preset(wmOperatorType *ot)
376 {
377         static EnumPropertyItem prop_shape_items[] = {
378                 {CURVE_PRESET_SHARP, "SHARP", 0, "Sharp", ""},
379                 {CURVE_PRESET_SMOOTH, "SMOOTH", 0, "Smooth", ""},
380                 {CURVE_PRESET_MAX, "MAX", 0, "Max", ""},
381                 {CURVE_PRESET_LINE, "LINE", 0, "Line", ""},
382                 {CURVE_PRESET_ROUND, "ROUND", 0, "Round", ""},
383                 {CURVE_PRESET_ROOT, "ROOT", 0, "Root", ""},
384                 {0, NULL, 0, NULL, NULL}};
385
386         ot->name = "Preset";
387         ot->description = "Set brush shape";
388         ot->idname = "BRUSH_OT_curve_preset";
389
390         ot->exec = brush_curve_preset_exec;
391         ot->poll = brush_curve_preset_poll;
392
393         RNA_def_enum(ot->srna, "shape", prop_shape_items, CURVE_PRESET_SMOOTH, "Mode", "");
394 }
395
396
397 /* face-select ops */
398 static int paint_select_linked_exec(bContext *C, wmOperator *UNUSED(op))
399 {
400         paintface_select_linked(C, CTX_data_active_object(C), NULL, 2);
401         ED_region_tag_redraw(CTX_wm_region(C));
402         return OPERATOR_FINISHED;
403 }
404
405 void PAINT_OT_face_select_linked(wmOperatorType *ot)
406 {
407         ot->name = "Select Linked";
408         ot->description = "Select linked faces";
409         ot->idname = "PAINT_OT_face_select_linked";
410
411         ot->exec = paint_select_linked_exec;
412         ot->poll = facemask_paint_poll;
413
414         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
415 }
416
417 static int paint_select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *event)
418 {
419         int mode = RNA_boolean_get(op->ptr, "extend") ? 1 : 0;
420         paintface_select_linked(C, CTX_data_active_object(C), event->mval, mode);
421         ED_region_tag_redraw(CTX_wm_region(C));
422         return OPERATOR_FINISHED;
423 }
424
425 void PAINT_OT_face_select_linked_pick(wmOperatorType *ot)
426 {
427         ot->name = "Select Linked Pick";
428         ot->description = "Select linked faces";
429         ot->idname = "PAINT_OT_face_select_linked_pick";
430
431         ot->invoke = paint_select_linked_pick_invoke;
432         ot->poll = facemask_paint_poll;
433
434         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
435
436         RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend the existing selection");
437 }
438
439
440 static int face_select_all_exec(bContext *C, wmOperator *op)
441 {
442         Object *ob = CTX_data_active_object(C);
443         paintface_deselect_all_visible(ob, RNA_enum_get(op->ptr, "action"), TRUE);
444         ED_region_tag_redraw(CTX_wm_region(C));
445         return OPERATOR_FINISHED;
446 }
447
448
449 void PAINT_OT_face_select_all(wmOperatorType *ot)
450 {
451         ot->name = "Face Selection";
452         ot->description = "Change selection for all faces";
453         ot->idname = "PAINT_OT_face_select_all";
454
455         ot->exec = face_select_all_exec;
456         ot->poll = facemask_paint_poll;
457
458         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
459
460         WM_operator_properties_select_all(ot);
461 }
462
463
464 static int vert_select_all_exec(bContext *C, wmOperator *op)
465 {
466         Object *ob = CTX_data_active_object(C);
467         paintvert_deselect_all_visible(ob, RNA_enum_get(op->ptr, "action"), TRUE);
468         ED_region_tag_redraw(CTX_wm_region(C));
469         return OPERATOR_FINISHED;
470 }
471
472
473 void PAINT_OT_vert_select_all(wmOperatorType *ot)
474 {
475         ot->name = "Vertex Selection";
476         ot->description = "Change selection for all vertices";
477         ot->idname = "PAINT_OT_vert_select_all";
478
479         ot->exec = vert_select_all_exec;
480         ot->poll = vert_paint_poll;
481
482         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
483
484         WM_operator_properties_select_all(ot);
485 }
486
487 static int vert_select_inverse_exec(bContext *C, wmOperator *UNUSED(op))
488 {
489         Object *ob = CTX_data_active_object(C);
490         paintvert_deselect_all_visible(ob, SEL_INVERT, TRUE);
491         ED_region_tag_redraw(CTX_wm_region(C));
492         return OPERATOR_FINISHED;
493 }
494
495 void PAINT_OT_vert_select_inverse(wmOperatorType *ot)
496 {
497         ot->name = "Vertex Select Invert";
498         ot->description = "Invert selection of vertices";
499         ot->idname = "PAINT_OT_vert_select_inverse";
500
501         ot->exec = vert_select_inverse_exec;
502         ot->poll = vert_paint_poll;
503
504         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
505 }
506 static int face_select_inverse_exec(bContext *C, wmOperator *UNUSED(op))
507 {
508         Object *ob = CTX_data_active_object(C);
509         paintface_deselect_all_visible(ob, SEL_INVERT, TRUE);
510         ED_region_tag_redraw(CTX_wm_region(C));
511         return OPERATOR_FINISHED;
512 }
513
514
515 void PAINT_OT_face_select_inverse(wmOperatorType *ot)
516 {
517         ot->name = "Face Select Invert";
518         ot->description = "Invert selection of faces";
519         ot->idname = "PAINT_OT_face_select_inverse";
520
521         ot->exec = face_select_inverse_exec;
522         ot->poll = facemask_paint_poll;
523
524         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
525 }
526
527 static int face_select_hide_exec(bContext *C, wmOperator *op)
528 {
529         const int unselected = RNA_boolean_get(op->ptr, "unselected");
530         Object *ob = CTX_data_active_object(C);
531         paintface_hide(ob, unselected);
532         ED_region_tag_redraw(CTX_wm_region(C));
533         return OPERATOR_FINISHED;
534 }
535
536 void PAINT_OT_face_select_hide(wmOperatorType *ot)
537 {
538         ot->name = "Face Select Hide";
539         ot->description = "Hide selected faces";
540         ot->idname = "PAINT_OT_face_select_hide";
541
542         ot->exec = face_select_hide_exec;
543         ot->poll = facemask_paint_poll;
544
545         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
546
547         RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected objects");
548 }
549
550 static int face_select_reveal_exec(bContext *C, wmOperator *UNUSED(op))
551 {
552         Object *ob = CTX_data_active_object(C);
553         paintface_reveal(ob);
554         ED_region_tag_redraw(CTX_wm_region(C));
555         return OPERATOR_FINISHED;
556 }
557
558 void PAINT_OT_face_select_reveal(wmOperatorType *ot)
559 {
560         ot->name = "Face Select Reveal";
561         ot->description = "Reveal hidden faces";
562         ot->idname = "PAINT_OT_face_select_reveal";
563
564         ot->exec = face_select_reveal_exec;
565         ot->poll = facemask_paint_poll;
566
567         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
568
569         RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected objects");
570 }