Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 * 00018 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00019 * All rights reserved. 00020 * 00021 * The Original Code is: all of this file. 00022 * 00023 * Contributor(s): none yet. 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00032 #include <math.h> 00033 #include <stdlib.h> 00034 00035 #include "DNA_mesh_types.h" 00036 #include "DNA_meshdata_types.h" 00037 #include "DNA_object_types.h" 00038 00039 #include "DNA_scene_types.h" 00040 #include "DNA_brush_types.h" 00041 00042 #include "BLI_math.h" 00043 #include "BLI_utildefines.h" 00044 00045 #include "BKE_brush.h" 00046 #include "BKE_context.h" 00047 #include "BKE_DerivedMesh.h" 00048 #include "BKE_paint.h" 00049 00050 #include "RNA_access.h" 00051 #include "RNA_define.h" 00052 00053 #include "BIF_gl.h" 00054 /* TODO: remove once projectf goes away */ 00055 #include "BIF_glutil.h" 00056 00057 #include "RE_shader_ext.h" 00058 00059 #include "ED_view3d.h" 00060 #include "ED_screen.h" 00061 00062 #include "BLO_sys_types.h" 00063 #include "ED_mesh.h" /* for face mask functions */ 00064 00065 #include "WM_api.h" 00066 #include "WM_types.h" 00067 00068 #include "paint_intern.h" 00069 00070 /* Convert the object-space axis-aligned bounding box (expressed as 00071 its minimum and maximum corners) into a screen-space rectangle, 00072 returns zero if the result is empty */ 00073 int paint_convert_bb_to_rect(rcti *rect, 00074 const float bb_min[3], 00075 const float bb_max[3], 00076 const ARegion *ar, 00077 RegionView3D *rv3d, 00078 Object *ob) 00079 { 00080 float projection_mat[4][4]; 00081 int i, j, k; 00082 00083 rect->xmin = rect->ymin = INT_MAX; 00084 rect->xmax = rect->ymax = INT_MIN; 00085 00086 /* return zero if the bounding box has non-positive volume */ 00087 if(bb_min[0] > bb_max[0] || bb_min[1] > bb_max[1] || bb_min[2] > bb_max[2]) 00088 return 0; 00089 00090 ED_view3d_ob_project_mat_get(rv3d, ob, projection_mat); 00091 00092 for(i = 0; i < 2; ++i) { 00093 for(j = 0; j < 2; ++j) { 00094 for(k = 0; k < 2; ++k) { 00095 float vec[3], proj[2]; 00096 vec[0] = i ? bb_min[0] : bb_max[0]; 00097 vec[1] = j ? bb_min[1] : bb_max[1]; 00098 vec[2] = k ? bb_min[2] : bb_max[2]; 00099 /* convert corner to screen space */ 00100 ED_view3d_project_float(ar, vec, proj, 00101 projection_mat); 00102 /* expand 2D rectangle */ 00103 rect->xmin = MIN2(rect->xmin, proj[0]); 00104 rect->xmax = MAX2(rect->xmax, proj[0]); 00105 rect->ymin = MIN2(rect->ymin, proj[1]); 00106 rect->ymax = MAX2(rect->ymax, proj[1]); 00107 } 00108 } 00109 } 00110 00111 /* return false if the rectangle has non-positive area */ 00112 return rect->xmin < rect->xmax && rect->ymin < rect->ymax; 00113 } 00114 00115 /* Get four planes in object-space that describe the projection of 00116 screen_rect from screen into object-space (essentially converting a 00117 2D screens-space bounding box into four 3D planes) */ 00118 void paint_calc_redraw_planes(float planes[4][4], 00119 const ARegion *ar, 00120 RegionView3D *rv3d, 00121 Object *ob, 00122 const rcti *screen_rect) 00123 { 00124 BoundBox bb; 00125 bglMats mats; 00126 rcti rect; 00127 00128 memset(&bb, 0, sizeof(BoundBox)); 00129 view3d_get_transformation(ar, rv3d, ob, &mats); 00130 00131 /* use some extra space just in case */ 00132 rect = *screen_rect; 00133 rect.xmin -= 2; 00134 rect.xmax += 2; 00135 rect.ymin -= 2; 00136 rect.ymax += 2; 00137 00138 ED_view3d_calc_clipping(&bb, planes, &mats, &rect); 00139 mul_m4_fl(planes, -1.0f); 00140 } 00141 00142 /* convert a point in model coordinates to 2D screen coordinates */ 00143 /* TODO: can be deleted once all calls are replaced with 00144 view3d_project_float() */ 00145 void projectf(bglMats *mats, const float v[3], float p[2]) 00146 { 00147 double ux, uy, uz; 00148 00149 gluProject(v[0],v[1],v[2], mats->modelview, mats->projection, 00150 (GLint *)mats->viewport, &ux, &uy, &uz); 00151 p[0]= ux; 00152 p[1]= uy; 00153 } 00154 00155 float paint_calc_object_space_radius(ViewContext *vc, const float center[3], 00156 float pixel_radius) 00157 { 00158 Object *ob = vc->obact; 00159 float delta[3], scale, loc[3]; 00160 float mval_f[2]; 00161 00162 mul_v3_m4v3(loc, ob->obmat, center); 00163 00164 initgrabz(vc->rv3d, loc[0], loc[1], loc[2]); 00165 00166 mval_f[0]= pixel_radius; 00167 mval_f[1]= 0.0f; 00168 ED_view3d_win_to_delta(vc->ar, mval_f, delta); 00169 00170 scale= fabsf(mat4_to_scale(ob->obmat)); 00171 scale= (scale == 0.0f)? 1.0f: scale; 00172 00173 return len_v3(delta)/scale; 00174 } 00175 00176 float paint_get_tex_pixel(Brush* br, float u, float v) 00177 { 00178 TexResult texres; 00179 float co[3]; 00180 int hasrgb; 00181 00182 co[0] = u; 00183 co[1] = v; 00184 co[2] = 0; 00185 00186 memset(&texres, 0, sizeof(TexResult)); 00187 hasrgb = multitex_ext(br->mtex.tex, co, NULL, NULL, 0, &texres); 00188 00189 if (hasrgb & TEX_RGB) 00190 texres.tin = (0.35f*texres.tr + 0.45f*texres.tg + 0.2f*texres.tb)*texres.ta; 00191 00192 return texres.tin; 00193 } 00194 00195 /* 3D Paint */ 00196 00197 static void imapaint_project(Object *ob, float *model, float *proj, float *co, float *pco) 00198 { 00199 copy_v3_v3(pco, co); 00200 pco[3]= 1.0f; 00201 00202 mul_m4_v3(ob->obmat, pco); 00203 mul_m4_v3((float(*)[4])model, pco); 00204 mul_m4_v4((float(*)[4])proj, pco); 00205 } 00206 00207 static void imapaint_tri_weights(Object *ob, float *v1, float *v2, float *v3, float *co, float *w) 00208 { 00209 float pv1[4], pv2[4], pv3[4], h[3], divw; 00210 float model[16], proj[16], wmat[3][3], invwmat[3][3]; 00211 GLint view[4]; 00212 00213 /* compute barycentric coordinates */ 00214 00215 /* get the needed opengl matrices */ 00216 glGetIntegerv(GL_VIEWPORT, view); 00217 glGetFloatv(GL_MODELVIEW_MATRIX, model); 00218 glGetFloatv(GL_PROJECTION_MATRIX, proj); 00219 view[0] = view[1] = 0; 00220 00221 /* project the verts */ 00222 imapaint_project(ob, model, proj, v1, pv1); 00223 imapaint_project(ob, model, proj, v2, pv2); 00224 imapaint_project(ob, model, proj, v3, pv3); 00225 00226 /* do inverse view mapping, see gluProject man page */ 00227 h[0]= (co[0] - view[0])*2.0f/view[2] - 1; 00228 h[1]= (co[1] - view[1])*2.0f/view[3] - 1; 00229 h[2]= 1.0f; 00230 00231 /* solve for(w1,w2,w3)/perspdiv in: 00232 h*perspdiv = Project*Model*(w1*v1 + w2*v2 + w3*v3) */ 00233 00234 wmat[0][0]= pv1[0]; wmat[1][0]= pv2[0]; wmat[2][0]= pv3[0]; 00235 wmat[0][1]= pv1[1]; wmat[1][1]= pv2[1]; wmat[2][1]= pv3[1]; 00236 wmat[0][2]= pv1[3]; wmat[1][2]= pv2[3]; wmat[2][2]= pv3[3]; 00237 00238 invert_m3_m3(invwmat, wmat); 00239 mul_m3_v3(invwmat, h); 00240 00241 copy_v3_v3(w, h); 00242 00243 /* w is still divided by perspdiv, make it sum to one */ 00244 divw= w[0] + w[1] + w[2]; 00245 if(divw != 0.0f) 00246 mul_v3_fl(w, 1.0f/divw); 00247 } 00248 00249 /* compute uv coordinates of mouse in face */ 00250 void imapaint_pick_uv(Scene *scene, Object *ob, unsigned int faceindex, const int xy[2], float uv[2]) 00251 { 00252 DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); 00253 const int *index = dm->getFaceDataArray(dm, CD_ORIGINDEX); 00254 MTFace *tface = dm->getFaceDataArray(dm, CD_MTFACE), *tf; 00255 int numfaces = dm->getNumFaces(dm), a, findex; 00256 float p[2], w[3], absw, minabsw; 00257 MFace mf; 00258 MVert mv[4]; 00259 00260 minabsw = 1e10; 00261 uv[0] = uv[1] = 0.0; 00262 00263 /* test all faces in the derivedmesh with the original index of the picked face */ 00264 for(a = 0; a < numfaces; a++) { 00265 findex= index ? index[a]: a; 00266 00267 if(findex == faceindex) { 00268 dm->getFace(dm, a, &mf); 00269 00270 dm->getVert(dm, mf.v1, &mv[0]); 00271 dm->getVert(dm, mf.v2, &mv[1]); 00272 dm->getVert(dm, mf.v3, &mv[2]); 00273 if(mf.v4) 00274 dm->getVert(dm, mf.v4, &mv[3]); 00275 00276 tf= &tface[a]; 00277 00278 p[0]= xy[0]; 00279 p[1]= xy[1]; 00280 00281 if(mf.v4) { 00282 /* the triangle with the largest absolute values is the one 00283 with the most negative weights */ 00284 imapaint_tri_weights(ob, mv[0].co, mv[1].co, mv[3].co, p, w); 00285 absw= fabs(w[0]) + fabs(w[1]) + fabs(w[2]); 00286 if(absw < minabsw) { 00287 uv[0]= tf->uv[0][0]*w[0] + tf->uv[1][0]*w[1] + tf->uv[3][0]*w[2]; 00288 uv[1]= tf->uv[0][1]*w[0] + tf->uv[1][1]*w[1] + tf->uv[3][1]*w[2]; 00289 minabsw = absw; 00290 } 00291 00292 imapaint_tri_weights(ob, mv[1].co, mv[2].co, mv[3].co, p, w); 00293 absw= fabs(w[0]) + fabs(w[1]) + fabs(w[2]); 00294 if(absw < minabsw) { 00295 uv[0]= tf->uv[1][0]*w[0] + tf->uv[2][0]*w[1] + tf->uv[3][0]*w[2]; 00296 uv[1]= tf->uv[1][1]*w[0] + tf->uv[2][1]*w[1] + tf->uv[3][1]*w[2]; 00297 minabsw = absw; 00298 } 00299 } 00300 else { 00301 imapaint_tri_weights(ob, mv[0].co, mv[1].co, mv[2].co, p, w); 00302 absw= fabs(w[0]) + fabs(w[1]) + fabs(w[2]); 00303 if(absw < minabsw) { 00304 uv[0]= tf->uv[0][0]*w[0] + tf->uv[1][0]*w[1] + tf->uv[2][0]*w[2]; 00305 uv[1]= tf->uv[0][1]*w[0] + tf->uv[1][1]*w[1] + tf->uv[2][1]*w[2]; 00306 minabsw = absw; 00307 } 00308 } 00309 } 00310 } 00311 00312 dm->release(dm); 00313 } 00314 00316 int imapaint_pick_face(ViewContext *vc, Mesh *me, const int mval[2], unsigned int *index) 00317 { 00318 if(!me || me->totface==0) 00319 return 0; 00320 00321 /* sample only on the exact position */ 00322 *index = view3d_sample_backbuf(vc, mval[0], mval[1]); 00323 00324 if((*index)<=0 || (*index)>(unsigned int)me->totface) 00325 return 0; 00326 00327 (*index)--; 00328 00329 return 1; 00330 } 00331 00332 /* used for both 3d view and image window */ 00333 void paint_sample_color(Scene *scene, ARegion *ar, int x, int y) /* frontbuf */ 00334 { 00335 Brush *br = paint_brush(paint_get_active(scene)); 00336 unsigned int col; 00337 char *cp; 00338 00339 CLAMP(x, 0, ar->winx); 00340 CLAMP(y, 0, ar->winy); 00341 00342 glReadBuffer(GL_FRONT); 00343 glReadPixels(x+ar->winrct.xmin, y+ar->winrct.ymin, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col); 00344 glReadBuffer(GL_BACK); 00345 00346 cp = (char *)&col; 00347 00348 if(br) { 00349 br->rgb[0]= cp[0]/255.0f; 00350 br->rgb[1]= cp[1]/255.0f; 00351 br->rgb[2]= cp[2]/255.0f; 00352 } 00353 } 00354 00355 static int brush_curve_preset_exec(bContext *C, wmOperator *op) 00356 { 00357 Brush *br = paint_brush(paint_get_active(CTX_data_scene(C))); 00358 brush_curve_preset(br, RNA_enum_get(op->ptr, "shape")); 00359 00360 return OPERATOR_FINISHED; 00361 } 00362 00363 static int brush_curve_preset_poll(bContext *C) 00364 { 00365 Brush *br = paint_brush(paint_get_active(CTX_data_scene(C))); 00366 00367 return br && br->curve; 00368 } 00369 00370 void BRUSH_OT_curve_preset(wmOperatorType *ot) 00371 { 00372 static EnumPropertyItem prop_shape_items[] = { 00373 {CURVE_PRESET_SHARP, "SHARP", 0, "Sharp", ""}, 00374 {CURVE_PRESET_SMOOTH, "SMOOTH", 0, "Smooth", ""}, 00375 {CURVE_PRESET_MAX, "MAX", 0, "Max", ""}, 00376 {CURVE_PRESET_LINE, "LINE", 0, "Line", ""}, 00377 {CURVE_PRESET_ROUND, "ROUND", 0, "Round", ""}, 00378 {CURVE_PRESET_ROOT, "ROOT", 0, "Root", ""}, 00379 {0, NULL, 0, NULL, NULL}}; 00380 00381 ot->name= "Preset"; 00382 ot->description= "Set brush shape"; 00383 ot->idname= "BRUSH_OT_curve_preset"; 00384 00385 ot->exec= brush_curve_preset_exec; 00386 ot->poll= brush_curve_preset_poll; 00387 00388 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00389 00390 RNA_def_enum(ot->srna, "shape", prop_shape_items, CURVE_PRESET_SMOOTH, "Mode", ""); 00391 } 00392 00393 00394 /* face-select ops */ 00395 static int paint_select_linked_exec(bContext *C, wmOperator *UNUSED(op)) 00396 { 00397 paintface_select_linked(C, CTX_data_active_object(C), NULL, 2); 00398 ED_region_tag_redraw(CTX_wm_region(C)); 00399 return OPERATOR_FINISHED; 00400 } 00401 00402 void PAINT_OT_face_select_linked(wmOperatorType *ot) 00403 { 00404 ot->name= "Select Linked"; 00405 ot->description= "Select linked faces"; 00406 ot->idname= "PAINT_OT_face_select_linked"; 00407 00408 ot->exec= paint_select_linked_exec; 00409 ot->poll= facemask_paint_poll; 00410 00411 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00412 } 00413 00414 static int paint_select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *event) 00415 { 00416 int mode= RNA_boolean_get(op->ptr, "extend") ? 1:0; 00417 paintface_select_linked(C, CTX_data_active_object(C), event->mval, mode); 00418 ED_region_tag_redraw(CTX_wm_region(C)); 00419 return OPERATOR_FINISHED; 00420 } 00421 00422 void PAINT_OT_face_select_linked_pick(wmOperatorType *ot) 00423 { 00424 ot->name= "Select Linked Pick"; 00425 ot->description= "Select linked faces"; 00426 ot->idname= "PAINT_OT_face_select_linked_pick"; 00427 00428 ot->invoke= paint_select_linked_pick_invoke; 00429 ot->poll= facemask_paint_poll; 00430 00431 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00432 00433 RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend the existing selection"); 00434 } 00435 00436 00437 static int face_select_all_exec(bContext *C, wmOperator *op) 00438 { 00439 Object *ob= CTX_data_active_object(C); 00440 paintface_deselect_all_visible(ob, RNA_enum_get(op->ptr, "action"), TRUE); 00441 ED_region_tag_redraw(CTX_wm_region(C)); 00442 return OPERATOR_FINISHED; 00443 } 00444 00445 00446 void PAINT_OT_face_select_all(wmOperatorType *ot) 00447 { 00448 ot->name= "Face Selection"; 00449 ot->description= "Change selection for all faces"; 00450 ot->idname= "PAINT_OT_face_select_all"; 00451 00452 ot->exec= face_select_all_exec; 00453 ot->poll= facemask_paint_poll; 00454 00455 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00456 00457 WM_operator_properties_select_all(ot); 00458 } 00459 00460 00461 static int vert_select_all_exec(bContext *C, wmOperator *op) 00462 { 00463 Object *ob= CTX_data_active_object(C); 00464 paintvert_deselect_all_visible(ob, RNA_enum_get(op->ptr, "action"), TRUE); 00465 ED_region_tag_redraw(CTX_wm_region(C)); 00466 return OPERATOR_FINISHED; 00467 } 00468 00469 00470 void PAINT_OT_vert_select_all(wmOperatorType *ot) 00471 { 00472 ot->name= "Vertex Selection"; 00473 ot->description= "Change selection for all vertices"; 00474 ot->idname= "PAINT_OT_vert_select_all"; 00475 00476 ot->exec= vert_select_all_exec; 00477 ot->poll= vert_paint_poll; 00478 00479 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00480 00481 WM_operator_properties_select_all(ot); 00482 } 00483 00484 static int vert_select_inverse_exec(bContext *C, wmOperator *UNUSED(op)) 00485 { 00486 Object *ob= CTX_data_active_object(C); 00487 paintvert_deselect_all_visible(ob, SEL_INVERT, TRUE); 00488 ED_region_tag_redraw(CTX_wm_region(C)); 00489 return OPERATOR_FINISHED; 00490 } 00491 00492 void PAINT_OT_vert_select_inverse(wmOperatorType *ot) 00493 { 00494 ot->name= "Vertex Select Invert"; 00495 ot->description= "Invert selection of vertices"; 00496 ot->idname= "PAINT_OT_vert_select_inverse"; 00497 00498 ot->exec= vert_select_inverse_exec; 00499 ot->poll= vert_paint_poll; 00500 00501 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00502 } 00503 static int face_select_inverse_exec(bContext *C, wmOperator *UNUSED(op)) 00504 { 00505 Object *ob= CTX_data_active_object(C); 00506 paintface_deselect_all_visible(ob, SEL_INVERT, TRUE); 00507 ED_region_tag_redraw(CTX_wm_region(C)); 00508 return OPERATOR_FINISHED; 00509 } 00510 00511 00512 void PAINT_OT_face_select_inverse(wmOperatorType *ot) 00513 { 00514 ot->name= "Face Select Invert"; 00515 ot->description= "Invert selection of faces"; 00516 ot->idname= "PAINT_OT_face_select_inverse"; 00517 00518 ot->exec= face_select_inverse_exec; 00519 ot->poll= facemask_paint_poll; 00520 00521 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00522 } 00523 00524 static int face_select_hide_exec(bContext *C, wmOperator *op) 00525 { 00526 const int unselected= RNA_boolean_get(op->ptr, "unselected"); 00527 Object *ob= CTX_data_active_object(C); 00528 paintface_hide(ob, unselected); 00529 ED_region_tag_redraw(CTX_wm_region(C)); 00530 return OPERATOR_FINISHED; 00531 } 00532 00533 void PAINT_OT_face_select_hide(wmOperatorType *ot) 00534 { 00535 ot->name= "Face Select Hide"; 00536 ot->description= "Hide selected faces"; 00537 ot->idname= "PAINT_OT_face_select_hide"; 00538 00539 ot->exec= face_select_hide_exec; 00540 ot->poll= facemask_paint_poll; 00541 00542 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00543 00544 RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected objects"); 00545 } 00546 00547 static int face_select_reveal_exec(bContext *C, wmOperator *UNUSED(op)) 00548 { 00549 Object *ob= CTX_data_active_object(C); 00550 paintface_reveal(ob); 00551 ED_region_tag_redraw(CTX_wm_region(C)); 00552 return OPERATOR_FINISHED; 00553 } 00554 00555 void PAINT_OT_face_select_reveal(wmOperatorType *ot) 00556 { 00557 ot->name= "Face Select Reveal"; 00558 ot->description= "Reveal hidden faces"; 00559 ot->idname= "PAINT_OT_face_select_reveal"; 00560 00561 ot->exec= face_select_reveal_exec; 00562 ot->poll= facemask_paint_poll; 00563 00564 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00565 00566 RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected objects"); 00567 }