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