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