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