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