![]() |
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2006 by Nicholas Bishop 00019 * All rights reserved. 00020 * 00021 * The Original Code is: all of this file. 00022 * 00023 * Contributor(s): Jason Wilkins, Tom Musgrove. 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 * 00027 * Implements the Sculpt Mode tools 00028 * 00029 */ 00030 00036 #include "MEM_guardedalloc.h" 00037 00038 #include "BLI_math.h" 00039 #include "BLI_blenlib.h" 00040 #include "BLI_utildefines.h" 00041 #include "BLI_dynstr.h" 00042 #include "BLI_ghash.h" 00043 #include "BLI_pbvh.h" 00044 #include "BLI_threads.h" 00045 #include "BLI_editVert.h" 00046 #include "BLI_rand.h" 00047 00048 #include "DNA_meshdata_types.h" 00049 #include "DNA_node_types.h" 00050 #include "DNA_object_types.h" 00051 #include "DNA_scene_types.h" 00052 #include "DNA_brush_types.h" 00053 00054 #include "BKE_brush.h" 00055 #include "BKE_cdderivedmesh.h" 00056 #include "BKE_context.h" 00057 #include "BKE_depsgraph.h" 00058 #include "BKE_key.h" 00059 #include "BKE_library.h" 00060 #include "BKE_mesh.h" 00061 #include "BKE_modifier.h" 00062 #include "BKE_multires.h" 00063 #include "BKE_paint.h" 00064 #include "BKE_report.h" 00065 #include "BKE_lattice.h" /* for armature_deform_verts */ 00066 #include "BKE_node.h" 00067 00068 #include "BIF_glutil.h" 00069 00070 #include "WM_api.h" 00071 #include "WM_types.h" 00072 00073 #include "ED_sculpt.h" 00074 #include "ED_screen.h" 00075 #include "ED_view3d.h" 00076 #include "ED_util.h" /* for crazyspace correction */ 00077 #include "paint_intern.h" 00078 #include "sculpt_intern.h" 00079 00080 #include "RNA_access.h" 00081 #include "RNA_define.h" 00082 00083 #include "RE_render_ext.h" 00084 00085 #include "GPU_buffers.h" 00086 00087 #include <math.h> 00088 #include <stdlib.h> 00089 #include <string.h> 00090 00091 #ifdef _OPENMP 00092 #include <omp.h> 00093 #endif 00094 00095 void ED_sculpt_force_update(bContext *C) 00096 { 00097 Object *ob= CTX_data_active_object(C); 00098 00099 if(ob && (ob->mode & OB_MODE_SCULPT)) 00100 multires_force_update(ob); 00101 } 00102 00103 /* Sculpt mode handles multires differently from regular meshes, but only if 00104 it's the last modifier on the stack and it is not on the first level */ 00105 struct MultiresModifierData *sculpt_multires_active(Scene *scene, Object *ob) 00106 { 00107 Mesh *me= (Mesh*)ob->data; 00108 ModifierData *md; 00109 00110 if(!CustomData_get_layer(&me->fdata, CD_MDISPS)) { 00111 /* multires can't work without displacement layer */ 00112 return NULL; 00113 } 00114 00115 for(md= modifiers_getVirtualModifierList(ob); md; md= md->next) { 00116 if(md->type == eModifierType_Multires) { 00117 MultiresModifierData *mmd= (MultiresModifierData*)md; 00118 00119 if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) 00120 continue; 00121 00122 if(mmd->sculptlvl > 0) return mmd; 00123 else return NULL; 00124 } 00125 } 00126 00127 return NULL; 00128 } 00129 00130 /* Check if there are any active modifiers in stack (used for flushing updates at enter/exit sculpt mode) */ 00131 static int sculpt_has_active_modifiers(Scene *scene, Object *ob) 00132 { 00133 ModifierData *md; 00134 00135 md= modifiers_getVirtualModifierList(ob); 00136 00137 /* exception for shape keys because we can edit those */ 00138 for(; md; md= md->next) { 00139 if(modifier_isEnabled(scene, md, eModifierMode_Realtime)) 00140 return 1; 00141 } 00142 00143 return 0; 00144 } 00145 00146 /* Checks if there are any supported deformation modifiers active */ 00147 static int sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob) 00148 { 00149 ModifierData *md; 00150 Mesh *me= (Mesh*)ob->data; 00151 MultiresModifierData *mmd= sculpt_multires_active(scene, ob); 00152 00153 if(mmd) return 0; 00154 00155 /* non-locked shape keys could be handled in the same way as deformed mesh */ 00156 if((ob->shapeflag&OB_SHAPE_LOCK)==0 && me->key && ob->shapenr) 00157 return 1; 00158 00159 md= modifiers_getVirtualModifierList(ob); 00160 00161 /* exception for shape keys because we can edit those */ 00162 for(; md; md= md->next) { 00163 ModifierTypeInfo *mti = modifierType_getInfo(md->type); 00164 if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue; 00165 if(md->type==eModifierType_ShapeKey) continue; 00166 00167 if(mti->type==eModifierTypeType_OnlyDeform) return 1; 00168 else if((sd->flags & SCULPT_ONLY_DEFORM)==0) return 1; 00169 } 00170 00171 return 0; 00172 } 00173 00174 typedef enum StrokeFlags { 00175 CLIP_X = 1, 00176 CLIP_Y = 2, 00177 CLIP_Z = 4 00178 } StrokeFlags; 00179 00180 /* Cache stroke properties. Used because 00181 RNA property lookup isn't particularly fast. 00182 00183 For descriptions of these settings, check the operator properties. 00184 */ 00185 typedef struct StrokeCache { 00186 /* Invariants */ 00187 float initial_radius; 00188 float scale[3]; 00189 int flag; 00190 float clip_tolerance[3]; 00191 float initial_mouse[2]; 00192 00193 /* Variants */ 00194 float radius; 00195 float radius_squared; 00196 //float traced_location[3]; 00197 float true_location[3]; 00198 float location[3]; 00199 00200 float pen_flip; 00201 float invert; 00202 float pressure; 00203 float mouse[2]; 00204 float bstrength; 00205 float tex_mouse[2]; 00206 00207 /* The rest is temporary storage that isn't saved as a property */ 00208 00209 int first_time; /* Beginning of stroke may do some things special */ 00210 00211 /* from ED_view3d_ob_project_mat_get() */ 00212 float projection_mat[4][4]; 00213 00214 /* Clean this up! */ 00215 ViewContext *vc; 00216 Brush *brush; 00217 00218 float (*face_norms)[3]; /* Copy of the mesh faces' normals */ 00219 float special_rotation; /* Texture rotation (radians) for anchored and rake modes */ 00220 int pixel_radius, previous_pixel_radius; 00221 float grab_delta[3], grab_delta_symmetry[3]; 00222 float old_grab_location[3], orig_grab_location[3]; 00223 00224 int symmetry; /* Symmetry index between 0 and 7 bit combo 0 is Brush only; 00225 1 is X mirror; 2 is Y mirror; 3 is XY; 4 is Z; 5 is XZ; 6 is YZ; 7 is XYZ */ 00226 int mirror_symmetry_pass; /* the symmetry pass we are currently on between 0 and 7*/ 00227 float true_view_normal[3]; 00228 float view_normal[3]; 00229 float last_area_normal[3]; 00230 float last_center[3]; 00231 int radial_symmetry_pass; 00232 float symm_rot_mat[4][4]; 00233 float symm_rot_mat_inv[4][4]; 00234 float last_rake[2]; /* Last location of updating rake rotation */ 00235 int original; 00236 00237 float vertex_rotation; 00238 00239 char saved_active_brush_name[MAX_ID_NAME]; 00240 int alt_smooth; 00241 00242 float plane_trim_squared; 00243 00244 rcti previous_r; /* previous redraw rectangle */ 00245 } StrokeCache; 00246 00247 /*** BVH Tree ***/ 00248 00249 /* Get a screen-space rectangle of the modified area */ 00250 static int sculpt_get_redraw_rect(ARegion *ar, RegionView3D *rv3d, 00251 Object *ob, rcti *rect) 00252 { 00253 SculptSession *ss; 00254 PBVH *pbvh= ob->sculpt->pbvh; 00255 float bb_min[3], bb_max[3]; 00256 00257 if(!pbvh) 00258 return 0; 00259 00260 BLI_pbvh_redraw_BB(pbvh, bb_min, bb_max); 00261 00262 /* convert 3D bounding box to screen space */ 00263 if(!paint_convert_bb_to_rect(rect, 00264 bb_min, 00265 bb_max, 00266 ar, 00267 rv3d, 00268 ob)) { 00269 return 0; 00270 } 00271 00272 /* expand redraw rect with redraw rect from previous step to 00273 prevent partial-redraw issues caused by fast strokes. This is 00274 needed here (not in sculpt_flush_update) as it was before 00275 because redraw rectangle should be the same in both of 00276 optimized PBVH draw function and 3d view redraw (if not -- some 00277 mesh parts could disapper from screen (sergey) */ 00278 ss = ob->sculpt; 00279 if(ss->cache) { 00280 if(!BLI_rcti_is_empty(&ss->cache->previous_r)) 00281 BLI_union_rcti(rect, &ss->cache->previous_r); 00282 } 00283 00284 return 1; 00285 } 00286 00287 void sculpt_get_redraw_planes(float planes[4][4], ARegion *ar, 00288 RegionView3D *rv3d, Object *ob) 00289 { 00290 PBVH *pbvh= ob->sculpt->pbvh; 00291 rcti rect; 00292 00293 sculpt_get_redraw_rect(ar, rv3d, ob, &rect); 00294 00295 paint_calc_redraw_planes(planes, ar, rv3d, ob, &rect); 00296 00297 /* clear redraw flag from nodes */ 00298 if(pbvh) 00299 BLI_pbvh_update(pbvh, PBVH_UpdateRedraw, NULL); 00300 } 00301 00302 /************************ Brush Testing *******************/ 00303 00304 typedef struct SculptBrushTest { 00305 float radius_squared; 00306 float location[3]; 00307 float dist; 00308 } SculptBrushTest; 00309 00310 static void sculpt_brush_test_init(SculptSession *ss, SculptBrushTest *test) 00311 { 00312 test->radius_squared= ss->cache->radius_squared; 00313 copy_v3_v3(test->location, ss->cache->location); 00314 test->dist= 0.0f; /* just for initialize */ 00315 } 00316 00317 static int sculpt_brush_test(SculptBrushTest *test, float co[3]) 00318 { 00319 float distsq = len_squared_v3v3(co, test->location); 00320 00321 if(distsq <= test->radius_squared) { 00322 test->dist = sqrt(distsq); 00323 return 1; 00324 } 00325 else { 00326 return 0; 00327 } 00328 } 00329 00330 static int sculpt_brush_test_sq(SculptBrushTest *test, float co[3]) 00331 { 00332 float distsq = len_squared_v3v3(co, test->location); 00333 00334 if(distsq <= test->radius_squared) { 00335 test->dist = distsq; 00336 return 1; 00337 } 00338 else { 00339 return 0; 00340 } 00341 } 00342 00343 static int sculpt_brush_test_fast(SculptBrushTest *test, float co[3]) 00344 { 00345 return len_squared_v3v3(co, test->location) <= test->radius_squared; 00346 } 00347 00348 static int sculpt_brush_test_cube(SculptBrushTest *test, float co[3], float local[4][4]) 00349 { 00350 static const float side = 0.70710678118654752440084436210485; // sqrt(.5); 00351 00352 float local_co[3]; 00353 00354 mul_v3_m4v3(local_co, local, co); 00355 00356 local_co[0] = fabs(local_co[0]); 00357 local_co[1] = fabs(local_co[1]); 00358 local_co[2] = fabs(local_co[2]); 00359 00360 if (local_co[0] <= side && local_co[1] <= side && local_co[2] <= side) { 00361 test->dist = MAX3(local_co[0], local_co[1], local_co[2]) / side; 00362 00363 return 1; 00364 } 00365 else { 00366 return 0; 00367 } 00368 } 00369 00370 static float frontface(Brush *brush, const float sculpt_normal[3], 00371 const short no[3], const float fno[3]) 00372 { 00373 if (brush->flag & BRUSH_FRONTFACE) { 00374 float dot; 00375 00376 if (no) { 00377 float tmp[3]; 00378 00379 normal_short_to_float_v3(tmp, no); 00380 dot= dot_v3v3(tmp, sculpt_normal); 00381 } 00382 else { 00383 dot= dot_v3v3(fno, sculpt_normal); 00384 } 00385 return dot > 0 ? dot : 0; 00386 } 00387 else { 00388 return 1; 00389 } 00390 } 00391 00392 #if 0 00393 00394 static int sculpt_brush_test_cyl(SculptBrushTest *test, float co[3], float location[3], float an[3]) 00395 { 00396 if (sculpt_brush_test_fast(test, co)) { 00397 float t1[3], t2[3], t3[3], dist; 00398 00399 sub_v3_v3v3(t1, location, co); 00400 sub_v3_v3v3(t2, x2, location); 00401 00402 cross_v3_v3v3(t3, an, t1); 00403 00404 dist = len_v3(t3)/len_v3(t2); 00405 00406 test->dist = dist; 00407 00408 return 1; 00409 } 00410 00411 return 0; 00412 } 00413 00414 #endif 00415 00416 /* ===== Sculpting ===== 00417 * 00418 */ 00419 00420 00421 static float overlapped_curve(Brush* br, float x) 00422 { 00423 int i; 00424 const int n = 100 / br->spacing; 00425 const float h = br->spacing / 50.0f; 00426 const float x0 = x-1; 00427 00428 float sum; 00429 00430 sum = 0; 00431 for (i= 0; i < n; i++) { 00432 float xx; 00433 00434 xx = fabs(x0 + i*h); 00435 00436 if (xx < 1.0f) 00437 sum += brush_curve_strength(br, xx, 1); 00438 } 00439 00440 return sum; 00441 } 00442 00443 static float integrate_overlap(Brush* br) 00444 { 00445 int i; 00446 int m= 10; 00447 float g = 1.0f/m; 00448 float max; 00449 00450 max= 0; 00451 for(i= 0; i < m; i++) { 00452 float overlap= overlapped_curve(br, i*g); 00453 00454 if (overlap > max) 00455 max = overlap; 00456 } 00457 00458 return max; 00459 } 00460 00461 /* Uses symm to selectively flip any axis of a coordinate. */ 00462 static void flip_coord(float out[3], float in[3], const char symm) 00463 { 00464 if(symm & SCULPT_SYMM_X) 00465 out[0]= -in[0]; 00466 else 00467 out[0]= in[0]; 00468 if(symm & SCULPT_SYMM_Y) 00469 out[1]= -in[1]; 00470 else 00471 out[1]= in[1]; 00472 if(symm & SCULPT_SYMM_Z) 00473 out[2]= -in[2]; 00474 else 00475 out[2]= in[2]; 00476 } 00477 00478 static float calc_overlap(StrokeCache *cache, const char symm, const char axis, const float angle) 00479 { 00480 float mirror[3]; 00481 float distsq; 00482 00483 //flip_coord(mirror, cache->traced_location, symm); 00484 flip_coord(mirror, cache->true_location, symm); 00485 00486 if(axis != 0) { 00487 float mat[4][4]= MAT4_UNITY; 00488 rotate_m4(mat, axis, angle); 00489 mul_m4_v3(mat, mirror); 00490 } 00491 00492 //distsq = len_squared_v3v3(mirror, cache->traced_location); 00493 distsq = len_squared_v3v3(mirror, cache->true_location); 00494 00495 if (distsq <= 4.0f*(cache->radius_squared)) 00496 return (2.0f*(cache->radius) - sqrtf(distsq)) / (2.0f*(cache->radius)); 00497 else 00498 return 0; 00499 } 00500 00501 static float calc_radial_symmetry_feather(Sculpt *sd, StrokeCache *cache, const char symm, const char axis) 00502 { 00503 int i; 00504 float overlap; 00505 00506 overlap = 0; 00507 for(i = 1; i < sd->radial_symm[axis-'X']; ++i) { 00508 const float angle = 2*M_PI*i/sd->radial_symm[axis-'X']; 00509 overlap += calc_overlap(cache, symm, axis, angle); 00510 } 00511 00512 return overlap; 00513 } 00514 00515 static float calc_symmetry_feather(Sculpt *sd, StrokeCache* cache) 00516 { 00517 if (sd->flags & SCULPT_SYMMETRY_FEATHER) { 00518 float overlap; 00519 int symm = cache->symmetry; 00520 int i; 00521 00522 overlap = 0; 00523 for (i = 0; i <= symm; i++) { 00524 if(i == 0 || (symm & i && (symm != 5 || i != 3) && (symm != 6 || (i != 3 && i != 5)))) { 00525 00526 overlap += calc_overlap(cache, i, 0, 0); 00527 00528 overlap += calc_radial_symmetry_feather(sd, cache, i, 'X'); 00529 overlap += calc_radial_symmetry_feather(sd, cache, i, 'Y'); 00530 overlap += calc_radial_symmetry_feather(sd, cache, i, 'Z'); 00531 } 00532 } 00533 00534 return 1/overlap; 00535 } 00536 else { 00537 return 1; 00538 } 00539 } 00540 00541 /* Return modified brush strength. Includes the direction of the brush, positive 00542 values pull vertices, negative values push. Uses tablet pressure and a 00543 special multiplier found experimentally to scale the strength factor. */ 00544 static float brush_strength(Sculpt *sd, StrokeCache *cache, float feather) 00545 { 00546 const Scene *scene = cache->vc->scene; 00547 Brush *brush = paint_brush(&sd->paint); 00548 00549 /* Primary strength input; square it to make lower values more sensitive */ 00550 const float root_alpha = brush_alpha(scene, brush); 00551 float alpha = root_alpha*root_alpha; 00552 float dir = brush->flag & BRUSH_DIR_IN ? -1 : 1; 00553 float pressure = brush_use_alpha_pressure(scene, brush) ? cache->pressure : 1; 00554 float pen_flip = cache->pen_flip ? -1 : 1; 00555 float invert = cache->invert ? -1 : 1; 00556 float accum = integrate_overlap(brush); 00557 /* spacing is integer percentage of radius, divide by 50 to get 00558 normalized diameter */ 00559 float overlap = (brush->flag & BRUSH_SPACE_ATTEN && 00560 brush->flag & BRUSH_SPACE && 00561 !(brush->flag & BRUSH_ANCHORED) && 00562 (brush->spacing < 100)) ? 1.0f/accum : 1; 00563 float flip = dir * invert * pen_flip; 00564 00565 switch(brush->sculpt_tool){ 00566 case SCULPT_TOOL_CLAY: 00567 case SCULPT_TOOL_CLAY_TUBES: 00568 case SCULPT_TOOL_DRAW: 00569 case SCULPT_TOOL_LAYER: 00570 return alpha * flip * pressure * overlap * feather; 00571 00572 case SCULPT_TOOL_CREASE: 00573 case SCULPT_TOOL_BLOB: 00574 return alpha * flip * pressure * overlap * feather; 00575 00576 case SCULPT_TOOL_INFLATE: 00577 if (flip > 0) { 00578 return 0.250f * alpha * flip * pressure * overlap * feather; 00579 } 00580 else { 00581 return 0.125f * alpha * flip * pressure * overlap * feather; 00582 } 00583 00584 case SCULPT_TOOL_FILL: 00585 case SCULPT_TOOL_SCRAPE: 00586 case SCULPT_TOOL_FLATTEN: 00587 if (flip > 0) { 00588 overlap = (1+overlap) / 2; 00589 return alpha * flip * pressure * overlap * feather; 00590 } 00591 else { 00592 /* reduce strength for DEEPEN, PEAKS, and CONTRAST */ 00593 return 0.5f * alpha * flip * pressure * overlap * feather; 00594 } 00595 00596 case SCULPT_TOOL_SMOOTH: 00597 return alpha * pressure * feather; 00598 00599 case SCULPT_TOOL_PINCH: 00600 if (flip > 0) { 00601 return alpha * flip * pressure * overlap * feather; 00602 } 00603 else { 00604 return 0.25f * alpha * flip * pressure * overlap * feather; 00605 } 00606 00607 case SCULPT_TOOL_NUDGE: 00608 overlap = (1+overlap) / 2; 00609 return alpha * pressure * overlap * feather; 00610 00611 case SCULPT_TOOL_THUMB: 00612 return alpha*pressure*feather; 00613 00614 case SCULPT_TOOL_SNAKE_HOOK: 00615 return feather; 00616 00617 case SCULPT_TOOL_GRAB: 00618 return feather; 00619 00620 case SCULPT_TOOL_ROTATE: 00621 return alpha*pressure*feather; 00622 00623 default: 00624 return 0; 00625 } 00626 } 00627 00628 /* Return a multiplier for brush strength on a particular vertex. */ 00629 static float tex_strength(SculptSession *ss, Brush *br, float point[3], 00630 const float len, 00631 const float sculpt_normal[3], 00632 const short vno[3], 00633 const float fno[3]) 00634 { 00635 MTex *mtex = &br->mtex; 00636 float avg= 1; 00637 00638 if(!mtex->tex) { 00639 avg= 1; 00640 } 00641 else if(mtex->brush_map_mode == MTEX_MAP_MODE_3D) { 00642 float jnk; 00643 00644 /* Get strength by feeding the vertex 00645 location directly into a texture */ 00646 externtex(mtex, point, &avg, 00647 &jnk, &jnk, &jnk, &jnk, 0); 00648 } 00649 else if(ss->texcache) { 00650 float rotation = -mtex->rot; 00651 float symm_point[3], point_2d[2]; 00652 float x, y; 00653 float radius; 00654 00655 /* if the active area is being applied for symmetry, flip it 00656 across the symmetry axis and rotate it back to the orignal 00657 position in order to project it. This insures that the 00658 brush texture will be oriented correctly. */ 00659 00660 flip_coord(symm_point, point, ss->cache->mirror_symmetry_pass); 00661 00662 if (ss->cache->radial_symmetry_pass) 00663 mul_m4_v3(ss->cache->symm_rot_mat_inv, symm_point); 00664 00665 ED_view3d_project_float(ss->cache->vc->ar, symm_point, point_2d, 00666 ss->cache->projection_mat); 00667 00668 /* if fixed mode, keep coordinates relative to mouse */ 00669 if(mtex->brush_map_mode == MTEX_MAP_MODE_FIXED) { 00670 rotation += ss->cache->special_rotation; 00671 00672 point_2d[0] -= ss->cache->tex_mouse[0]; 00673 point_2d[1] -= ss->cache->tex_mouse[1]; 00674 00675 radius = ss->cache->pixel_radius; // use pressure adjusted size for fixed mode 00676 00677 x = point_2d[0] + ss->cache->vc->ar->winrct.xmin; 00678 y = point_2d[1] + ss->cache->vc->ar->winrct.ymin; 00679 } 00680 else /* else (mtex->brush_map_mode == MTEX_MAP_MODE_TILED), 00681 leave the coordinates relative to the screen */ 00682 { 00683 radius = brush_size(ss->cache->vc->scene, br); // use unadjusted size for tiled mode 00684 00685 x = point_2d[0]; 00686 y = point_2d[1]; 00687 } 00688 00689 x /= ss->cache->vc->ar->winx; 00690 y /= ss->cache->vc->ar->winy; 00691 00692 if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) { 00693 x -= 0.5f; 00694 y -= 0.5f; 00695 } 00696 00697 x *= ss->cache->vc->ar->winx / radius; 00698 y *= ss->cache->vc->ar->winy / radius; 00699 00700 /* it is probably worth optimizing for those cases where 00701 the texture is not rotated by skipping the calls to 00702 atan2, sqrtf, sin, and cos. */ 00703 if (rotation > 0.001f || rotation < -0.001f) { 00704 const float angle = atan2f(y, x) + rotation; 00705 const float flen = sqrtf(x*x + y*y); 00706 00707 x = flen * cosf(angle); 00708 y = flen * sinf(angle); 00709 } 00710 00711 x *= br->mtex.size[0]; 00712 y *= br->mtex.size[1]; 00713 00714 x += br->mtex.ofs[0]; 00715 y += br->mtex.ofs[1]; 00716 00717 avg = paint_get_tex_pixel(br, x, y); 00718 } 00719 00720 avg += br->texture_sample_bias; 00721 00722 /* Falloff curve */ 00723 avg *= brush_curve_strength(br, len, ss->cache->radius); 00724 00725 avg *= frontface(br, sculpt_normal, vno, fno); 00726 00727 return avg; 00728 } 00729 00730 typedef struct { 00731 Sculpt *sd; 00732 SculptSession *ss; 00733 float radius_squared; 00734 int original; 00735 } SculptSearchSphereData; 00736 00737 /* Test AABB against sphere */ 00738 static int sculpt_search_sphere_cb(PBVHNode *node, void *data_v) 00739 { 00740 SculptSearchSphereData *data = data_v; 00741 float *center = data->ss->cache->location, nearest[3]; 00742 float t[3], bb_min[3], bb_max[3]; 00743 int i; 00744 00745 if(data->original) 00746 BLI_pbvh_node_get_original_BB(node, bb_min, bb_max); 00747 else 00748 BLI_pbvh_node_get_BB(node, bb_min, bb_max); 00749 00750 for(i = 0; i < 3; ++i) { 00751 if(bb_min[i] > center[i]) 00752 nearest[i] = bb_min[i]; 00753 else if(bb_max[i] < center[i]) 00754 nearest[i] = bb_max[i]; 00755 else 00756 nearest[i] = center[i]; 00757 } 00758 00759 sub_v3_v3v3(t, center, nearest); 00760 00761 return dot_v3v3(t, t) < data->radius_squared; 00762 } 00763 00764 /* Handles clipping against a mirror modifier and SCULPT_LOCK axis flags */ 00765 static void sculpt_clip(Sculpt *sd, SculptSession *ss, float *co, const float val[3]) 00766 { 00767 int i; 00768 00769 for(i=0; i<3; ++i) { 00770 if(sd->flags & (SCULPT_LOCK_X << i)) 00771 continue; 00772 00773 if((ss->cache->flag & (CLIP_X << i)) && (fabsf(co[i]) <= ss->cache->clip_tolerance[i])) 00774 co[i]= 0.0f; 00775 else 00776 co[i]= val[i]; 00777 } 00778 } 00779 00780 static void add_norm_if(float view_vec[3], float out[3], float out_flip[3], float fno[3]) 00781 { 00782 if((dot_v3v3(view_vec, fno)) > 0) { 00783 add_v3_v3(out, fno); 00784 } else { 00785 add_v3_v3(out_flip, fno); /* out_flip is used when out is {0,0,0} */ 00786 } 00787 } 00788 00789 static void calc_area_normal(Sculpt *sd, Object *ob, float an[3], PBVHNode **nodes, int totnode) 00790 { 00791 SculptSession *ss = ob->sculpt; 00792 int n; 00793 00794 float out_flip[3] = {0.0f, 0.0f, 0.0f}; 00795 00796 (void)sd; /* unused w/o openmp */ 00797 00798 zero_v3(an); 00799 00800 #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) 00801 for(n=0; n<totnode; n++) { 00802 PBVHVertexIter vd; 00803 SculptBrushTest test; 00804 SculptUndoNode *unode; 00805 float private_an[3] = {0.0f, 0.0f, 0.0f}; 00806 float private_out_flip[3] = {0.0f, 0.0f, 0.0f}; 00807 00808 unode = sculpt_undo_push_node(ob, nodes[n]); 00809 sculpt_brush_test_init(ss, &test); 00810 00811 if(ss->cache->original) { 00812 BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { 00813 if(sculpt_brush_test_fast(&test, unode->co[vd.i])) { 00814 float fno[3]; 00815 00816 normal_short_to_float_v3(fno, unode->no[vd.i]); 00817 add_norm_if(ss->cache->view_normal, private_an, private_out_flip, fno); 00818 } 00819 } 00820 BLI_pbvh_vertex_iter_end; 00821 } 00822 else { 00823 BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { 00824 if(sculpt_brush_test_fast(&test, vd.co)) { 00825 if(vd.no) { 00826 float fno[3]; 00827 00828 normal_short_to_float_v3(fno, vd.no); 00829 add_norm_if(ss->cache->view_normal, private_an, private_out_flip, fno); 00830 } 00831 else { 00832 add_norm_if(ss->cache->view_normal, private_an, private_out_flip, vd.fno); 00833 } 00834 } 00835 } 00836 BLI_pbvh_vertex_iter_end; 00837 } 00838 00839 #pragma omp critical 00840 { 00841 add_v3_v3(an, private_an); 00842 add_v3_v3(out_flip, private_out_flip); 00843 } 00844 } 00845 00846 if (is_zero_v3(an)) 00847 copy_v3_v3(an, out_flip); 00848 00849 normalize_v3(an); 00850 } 00851 00852 /* This initializes the faces to be moved for this sculpt for draw/layer/flatten; then it 00853 finds average normal for all active vertices - note that this is called once for each mirroring direction */ 00854 static void calc_sculpt_normal(Sculpt *sd, Object *ob, float an[3], PBVHNode **nodes, int totnode) 00855 { 00856 SculptSession *ss = ob->sculpt; 00857 Brush *brush = paint_brush(&sd->paint); 00858 00859 if (ss->cache->mirror_symmetry_pass == 0 && 00860 ss->cache->radial_symmetry_pass == 0 && 00861 (ss->cache->first_time || !(brush->flag & BRUSH_ORIGINAL_NORMAL))) 00862 { 00863 switch (brush->sculpt_plane) { 00864 case SCULPT_DISP_DIR_VIEW: 00865 ED_view3d_global_to_vector(ss->cache->vc->rv3d, ss->cache->vc->rv3d->twmat[3], an); 00866 break; 00867 00868 case SCULPT_DISP_DIR_X: 00869 an[1] = 0.0; 00870 an[2] = 0.0; 00871 an[0] = 1.0; 00872 break; 00873 00874 case SCULPT_DISP_DIR_Y: 00875 an[0] = 0.0; 00876 an[2] = 0.0; 00877 an[1] = 1.0; 00878 break; 00879 00880 case SCULPT_DISP_DIR_Z: 00881 an[0] = 0.0; 00882 an[1] = 0.0; 00883 an[2] = 1.0; 00884 break; 00885 00886 case SCULPT_DISP_DIR_AREA: 00887 calc_area_normal(sd, ob, an, nodes, totnode); 00888 00889 default: 00890 break; 00891 } 00892 00893 copy_v3_v3(ss->cache->last_area_normal, an); 00894 } 00895 else { 00896 copy_v3_v3(an, ss->cache->last_area_normal); 00897 flip_coord(an, an, ss->cache->mirror_symmetry_pass); 00898 mul_m4_v3(ss->cache->symm_rot_mat, an); 00899 } 00900 } 00901 00902 /* For the smooth brush, uses the neighboring vertices around vert to calculate 00903 a smoothed location for vert. Skips corner vertices (used by only one 00904 polygon.) */ 00905 static void neighbor_average(SculptSession *ss, float avg[3], const unsigned vert) 00906 { 00907 int i, skip= -1, total=0; 00908 IndexNode *node= ss->fmap[vert].first; 00909 char ncount= BLI_countlist(&ss->fmap[vert]); 00910 MFace *f; 00911 00912 avg[0] = avg[1] = avg[2] = 0; 00913 00914 /* Don't modify corner vertices */ 00915 if(ncount==1) { 00916 if(ss->deform_cos) copy_v3_v3(avg, ss->deform_cos[vert]); 00917 else copy_v3_v3(avg, ss->mvert[vert].co); 00918 00919 return; 00920 } 00921 00922 while(node){ 00923 f= &ss->mface[node->index]; 00924 00925 if(f->v4) { 00926 skip= (f->v1==vert?2: 00927 f->v2==vert?3: 00928 f->v3==vert?0: 00929 f->v4==vert?1:-1); 00930 } 00931 00932 for(i=0; i<(f->v4?4:3); ++i) { 00933 if(i != skip && (ncount!=2 || BLI_countlist(&ss->fmap[(&f->v1)[i]]) <= 2)) { 00934 if(ss->deform_cos) add_v3_v3(avg, ss->deform_cos[(&f->v1)[i]]); 00935 else add_v3_v3(avg, ss->mvert[(&f->v1)[i]].co); 00936 ++total; 00937 } 00938 } 00939 00940 node= node->next; 00941 } 00942 00943 if(total>0) 00944 mul_v3_fl(avg, 1.0f / total); 00945 else { 00946 if(ss->deform_cos) copy_v3_v3(avg, ss->deform_cos[vert]); 00947 else copy_v3_v3(avg, ss->mvert[vert].co); 00948 } 00949 } 00950 00951 static void do_mesh_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node, float bstrength) 00952 { 00953 Brush *brush = paint_brush(&sd->paint); 00954 PBVHVertexIter vd; 00955 SculptBrushTest test; 00956 00957 CLAMP(bstrength, 0.0f, 1.0f); 00958 00959 sculpt_brush_test_init(ss, &test); 00960 00961 BLI_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { 00962 if(sculpt_brush_test(&test, vd.co)) { 00963 const float fade = bstrength*tex_strength(ss, brush, vd.co, test.dist, 00964 ss->cache->view_normal, vd.no, vd.fno); 00965 float avg[3], val[3]; 00966 00967 neighbor_average(ss, avg, vd.vert_indices[vd.i]); 00968 sub_v3_v3v3(val, avg, vd.co); 00969 mul_v3_fl(val, fade); 00970 00971 add_v3_v3(val, vd.co); 00972 00973 sculpt_clip(sd, ss, vd.co, val); 00974 00975 if(vd.mvert) 00976 vd.mvert->flag |= ME_VERT_PBVH_UPDATE; 00977 } 00978 } 00979 BLI_pbvh_vertex_iter_end; 00980 } 00981 00982 static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node, float bstrength) 00983 { 00984 Brush *brush = paint_brush(&sd->paint); 00985 SculptBrushTest test; 00986 DMGridData **griddata, *data; 00987 DMGridAdjacency *gridadj, *adj; 00988 float (*tmpgrid)[3], (*tmprow)[3]; 00989 int v1, v2, v3, v4; 00990 int *grid_indices, totgrid, gridsize, i, x, y; 00991 00992 sculpt_brush_test_init(ss, &test); 00993 00994 CLAMP(bstrength, 0.0f, 1.0f); 00995 00996 BLI_pbvh_node_get_grids(ss->pbvh, node, &grid_indices, &totgrid, 00997 NULL, &gridsize, &griddata, &gridadj); 00998 00999 #pragma omp critical 01000 { 01001 tmpgrid= MEM_mallocN(sizeof(float)*3*gridsize*gridsize, "tmpgrid"); 01002 tmprow= MEM_mallocN(sizeof(float)*3*gridsize, "tmprow"); 01003 } 01004 01005 for(i = 0; i < totgrid; ++i) { 01006 data = griddata[grid_indices[i]]; 01007 adj = &gridadj[grid_indices[i]]; 01008 01009 memset(tmpgrid, 0, sizeof(float)*3*gridsize*gridsize); 01010 01011 for (y= 0; y < gridsize-1; y++) { 01012 float tmp[3]; 01013 01014 v1 = y*gridsize; 01015 add_v3_v3v3(tmprow[0], data[v1].co, data[v1+gridsize].co); 01016 01017 for (x= 0; x < gridsize-1; x++) { 01018 v1 = x + y*gridsize; 01019 v2 = v1 + 1; 01020 v3 = v1 + gridsize; 01021 v4 = v3 + 1; 01022 01023 add_v3_v3v3(tmprow[x+1], data[v2].co, data[v4].co); 01024 add_v3_v3v3(tmp, tmprow[x+1], tmprow[x]); 01025 01026 add_v3_v3(tmpgrid[v1], tmp); 01027 add_v3_v3(tmpgrid[v2], tmp); 01028 add_v3_v3(tmpgrid[v3], tmp); 01029 add_v3_v3(tmpgrid[v4], tmp); 01030 } 01031 } 01032 01033 /* blend with existing coordinates */ 01034 for(y = 0; y < gridsize; ++y) { 01035 for(x = 0; x < gridsize; ++x) { 01036 float *co; 01037 float *fno; 01038 int index; 01039 01040 if(x == 0 && adj->index[0] == -1) 01041 continue; 01042 01043 if(x == gridsize - 1 && adj->index[2] == -1) 01044 continue; 01045 01046 if(y == 0 && adj->index[3] == -1) 01047 continue; 01048 01049 if(y == gridsize - 1 && adj->index[1] == -1) 01050 continue; 01051 01052 index = x + y*gridsize; 01053 co= data[index].co; 01054 fno= data[index].no; 01055 01056 if(sculpt_brush_test(&test, co)) { 01057 const float fade = bstrength*tex_strength(ss, brush, co, test.dist, 01058 ss->cache->view_normal, NULL, fno); 01059 float *avg, val[3]; 01060 float n; 01061 01062 avg = tmpgrid[x + y*gridsize]; 01063 01064 n = 1/16.0f; 01065 01066 if(x == 0 || x == gridsize - 1) 01067 n *= 2; 01068 01069 if(y == 0 || y == gridsize - 1) 01070 n *= 2; 01071 01072 mul_v3_fl(avg, n); 01073 01074 sub_v3_v3v3(val, avg, co); 01075 mul_v3_fl(val, fade); 01076 01077 add_v3_v3(val, co); 01078 01079 sculpt_clip(sd, ss, co, val); 01080 } 01081 } 01082 } 01083 } 01084 01085 #pragma omp critical 01086 { 01087 MEM_freeN(tmpgrid); 01088 MEM_freeN(tmprow); 01089 } 01090 } 01091 01092 static void smooth(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float bstrength) 01093 { 01094 SculptSession *ss = ob->sculpt; 01095 const int max_iterations = 4; 01096 const float fract = 1.0f/max_iterations; 01097 int iteration, n, count; 01098 float last; 01099 01100 CLAMP(bstrength, 0, 1); 01101 01102 count = (int)(bstrength*max_iterations); 01103 last = max_iterations*(bstrength - count*fract); 01104 01105 for(iteration = 0; iteration <= count; ++iteration) { 01106 #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) 01107 for(n=0; n<totnode; n++) { 01108 if(ss->multires) { 01109 do_multires_smooth_brush(sd, ss, nodes[n], iteration != count ? 1.0f : last); 01110 } 01111 else if(ss->fmap) 01112 do_mesh_smooth_brush(sd, ss, nodes[n], iteration != count ? 1.0f : last); 01113 } 01114 01115 if(ss->multires) 01116 multires_stitch_grids(ob); 01117 } 01118 } 01119 01120 static void do_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) 01121 { 01122 SculptSession *ss = ob->sculpt; 01123 smooth(sd, ob, nodes, totnode, ss->cache->bstrength); 01124 } 01125 01126 static void do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) 01127 { 01128 SculptSession *ss = ob->sculpt; 01129 Brush *brush = paint_brush(&sd->paint); 01130 float offset[3], area_normal[3]; 01131 float bstrength= ss->cache->bstrength; 01132 int n; 01133 01134 calc_sculpt_normal(sd, ob, area_normal, nodes, totnode); 01135 01136 /* offset with as much as possible factored in already */ 01137 mul_v3_v3fl(offset, area_normal, ss->cache->radius); 01138 mul_v3_v3(offset, ss->cache->scale); 01139 mul_v3_fl(offset, bstrength); 01140 01141 /* threaded loop over nodes */ 01142 #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) 01143 for(n=0; n<totnode; n++) { 01144 PBVHVertexIter vd; 01145 SculptBrushTest test; 01146 float (*proxy)[3]; 01147 01148 proxy= BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co; 01149 01150 sculpt_brush_test_init(ss, &test); 01151 01152 BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { 01153 if (sculpt_brush_test(&test, vd.co)) { 01154 /* offset vertex */ 01155 float fade = tex_strength(ss, brush, vd.co, test.dist, 01156 area_normal, vd.no, vd.fno); 01157 01158 mul_v3_v3fl(proxy[vd.i], offset, fade); 01159 01160 if(vd.mvert) 01161 vd.mvert->flag |= ME_VERT_PBVH_UPDATE; 01162 } 01163 } 01164 BLI_pbvh_vertex_iter_end; 01165 } 01166 } 01167 01168 static void do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) 01169 { 01170 SculptSession *ss = ob->sculpt; 01171 const Scene *scene = ss->cache->vc->scene; 01172 Brush *brush = paint_brush(&sd->paint); 01173 float offset[3], area_normal[3]; 01174 float bstrength= ss->cache->bstrength; 01175 float flippedbstrength, crease_correction; 01176 int n; 01177 01178 calc_sculpt_normal(sd, ob, area_normal, nodes, totnode); 01179 01180 /* offset with as much as possible factored in already */ 01181 mul_v3_v3fl(offset, area_normal, ss->cache->radius); 01182 mul_v3_v3(offset, ss->cache->scale); 01183 mul_v3_fl(offset, bstrength); 01184 01185 /* we divide out the squared alpha and multiply by the squared crease to give us the pinch strength */ 01186 01187 if(brush_alpha(scene, brush) > 0.0f) 01188 crease_correction = brush->crease_pinch_factor*brush->crease_pinch_factor/(brush_alpha(scene, brush)*brush_alpha(scene, brush)); 01189 else 01190 crease_correction = brush->crease_pinch_factor*brush->crease_pinch_factor; 01191 01192 /* we always want crease to pinch or blob to relax even when draw is negative */ 01193 flippedbstrength = (bstrength < 0) ? -crease_correction*bstrength : crease_correction*bstrength; 01194 01195 if(brush->sculpt_tool == SCULPT_TOOL_BLOB) flippedbstrength *= -1.0f; 01196 01197 /* threaded loop over nodes */ 01198 #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) 01199 for(n=0; n<totnode; n++) { 01200 PBVHVertexIter vd; 01201 SculptBrushTest test; 01202 float (*proxy)[3]; 01203 01204 proxy= BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co; 01205 01206 sculpt_brush_test_init(ss, &test); 01207 01208 BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { 01209 if(sculpt_brush_test(&test, vd.co)) { 01210 /* offset vertex */ 01211 const float fade = tex_strength(ss, brush, vd.co, test.dist, 01212 area_normal, vd.no, vd.fno); 01213 float val1[3]; 01214 float val2[3]; 01215 01216 /* first we pinch */ 01217 sub_v3_v3v3(val1, test.location, vd.co); 01218 //mul_v3_v3(val1, ss->cache->scale); 01219 mul_v3_fl(val1, fade*flippedbstrength); 01220 01221 /* then we draw */ 01222 mul_v3_v3fl(val2, offset, fade); 01223 01224 add_v3_v3v3(proxy[vd.i], val1, val2); 01225 01226 if(vd.mvert) 01227 vd.mvert->flag |= ME_VERT_PBVH_UPDATE; 01228 } 01229 } 01230 BLI_pbvh_vertex_iter_end; 01231 } 01232 } 01233 01234 static void do_pinch_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) 01235 { 01236 SculptSession *ss = ob->sculpt; 01237 Brush *brush = paint_brush(&sd->paint); 01238 float bstrength= ss->cache->bstrength; 01239 int n; 01240 01241 #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) 01242 for(n=0; n<totnode; n++) { 01243 PBVHVertexIter vd; 01244 SculptBrushTest test; 01245 float (*proxy)[3]; 01246 01247 proxy= BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co; 01248 01249 sculpt_brush_test_init(ss, &test); 01250 01251 BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { 01252 if(sculpt_brush_test(&test, vd.co)) { 01253 float fade = bstrength*tex_strength(ss, brush, vd.co, test.dist, 01254 ss->cache->view_normal, vd.no, vd.fno); 01255 float val[3]; 01256 01257 sub_v3_v3v3(val, test.location, vd.co); 01258 mul_v3_v3fl(proxy[vd.i], val, fade); 01259 01260 if(vd.mvert) 01261 vd.mvert->flag |= ME_VERT_PBVH_UPDATE; 01262 } 01263 } 01264 BLI_pbvh_vertex_iter_end; 01265 } 01266 } 01267 01268 static void do_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) 01269 { 01270 SculptSession *ss = ob->sculpt; 01271 Brush *brush= paint_brush(&sd->paint); 01272 float bstrength= ss->cache->bstrength; 01273 float grab_delta[3], an[3]; 01274 int n; 01275 float len; 01276 01277 if (brush->normal_weight > 0 || brush->flag & BRUSH_FRONTFACE) { 01278 int cache= 1; 01279 /* grab brush requires to test on original data */ 01280 SWAP(int, ss->cache->original, cache); 01281 calc_sculpt_normal(sd, ob, an, nodes, totnode); 01282 SWAP(int, ss->cache->original, cache); 01283 } 01284 01285 copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry); 01286 01287 len = len_v3(grab_delta); 01288 01289 if (brush->normal_weight > 0) { 01290 mul_v3_fl(an, len*brush->normal_weight); 01291 mul_v3_fl(grab_delta, 1.0f - brush->normal_weight); 01292 add_v3_v3(grab_delta, an); 01293 } 01294 01295 #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) 01296 for(n=0; n<totnode; n++) { 01297 PBVHVertexIter vd; 01298 SculptUndoNode* unode; 01299 SculptBrushTest test; 01300 float (*origco)[3]; 01301 short (*origno)[3]; 01302 float (*proxy)[3]; 01303 01304 unode= sculpt_undo_push_node(ob, nodes[n]); 01305 origco= unode->co; 01306 origno= unode->no; 01307 01308 proxy= BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co; 01309 01310 sculpt_brush_test_init(ss, &test); 01311 01312 BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { 01313 if(sculpt_brush_test(&test, origco[vd.i])) { 01314 const float fade = bstrength*tex_strength(ss, brush, origco[vd.i], test.dist, 01315 an, origno[vd.i], NULL); 01316 01317 mul_v3_v3fl(proxy[vd.i], grab_delta, fade); 01318 01319 if(vd.mvert) 01320 vd.mvert->flag |= ME_VERT_PBVH_UPDATE; 01321 } 01322 } 01323 BLI_pbvh_vertex_iter_end; 01324 } 01325 } 01326 01327 static void do_nudge_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) 01328 { 01329 SculptSession *ss = ob->sculpt; 01330 Brush *brush = paint_brush(&sd->paint); 01331 float bstrength = ss->cache->bstrength; 01332 float grab_delta[3]; 01333 int n; 01334 float an[3]; 01335 float tmp[3], cono[3]; 01336 01337 copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry); 01338 01339 calc_sculpt_normal(sd, ob, an, nodes, totnode); 01340 01341 cross_v3_v3v3(tmp, an, grab_delta); 01342 cross_v3_v3v3(cono, tmp, an); 01343 01344 #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) 01345 for(n = 0; n < totnode; n++) { 01346 PBVHVertexIter vd; 01347 SculptBrushTest test; 01348 float (*proxy)[3]; 01349 01350 proxy= BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co; 01351 01352 sculpt_brush_test_init(ss, &test); 01353 01354 BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { 01355 if(sculpt_brush_test(&test, vd.co)) { 01356 const float fade = bstrength*tex_strength(ss, brush, vd.co, test.dist, 01357 an, vd.no, vd.fno); 01358 01359 mul_v3_v3fl(proxy[vd.i], cono, fade); 01360 01361 if(vd.mvert) 01362 vd.mvert->flag |= ME_VERT_PBVH_UPDATE; 01363 } 01364 } 01365 BLI_pbvh_vertex_iter_end; 01366 } 01367 } 01368 01369 static void do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) 01370 { 01371 SculptSession *ss = ob->sculpt; 01372 Brush *brush = paint_brush(&sd->paint); 01373 float bstrength = ss->cache->bstrength; 01374 float grab_delta[3], an[3]; 01375 int n; 01376 float len; 01377 01378 if (brush->normal_weight > 0 || brush->flag & BRUSH_FRONTFACE) 01379 calc_sculpt_normal(sd, ob, an, nodes, totnode); 01380 01381 copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry); 01382 01383 len = len_v3(grab_delta); 01384 01385 if (bstrength < 0) 01386 negate_v3(grab_delta); 01387 01388 if (brush->normal_weight > 0) { 01389 mul_v3_fl(an, len*brush->normal_weight); 01390 mul_v3_fl(grab_delta, 1.0f - brush->normal_weight); 01391 add_v3_v3(grab_delta, an); 01392 } 01393 01394 #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) 01395 for(n = 0; n < totnode; n++) { 01396 PBVHVertexIter vd; 01397 SculptBrushTest test; 01398 float (*proxy)[3]; 01399 01400 proxy= BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co; 01401 01402 sculpt_brush_test_init(ss, &test); 01403 01404 BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { 01405 if(sculpt_brush_test(&test, vd.co)) { 01406 const float fade = bstrength*tex_strength(ss, brush, vd.co, test.dist, 01407 an, vd.no, vd.fno); 01408 01409 mul_v3_v3fl(proxy[vd.i], grab_delta, fade); 01410 01411 if(vd.mvert) 01412 vd.mvert->flag |= ME_VERT_PBVH_UPDATE; 01413 } 01414 } 01415 BLI_pbvh_vertex_iter_end; 01416 } 01417 } 01418 01419 static void do_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) 01420 { 01421 SculptSession *ss = ob->sculpt; 01422 Brush *brush = paint_brush(&sd->paint); 01423 float bstrength = ss->cache->bstrength; 01424 float grab_delta[3]; 01425 int n; 01426 float an[3]; 01427 float tmp[3], cono[3]; 01428 01429 copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry); 01430 01431 calc_sculpt_normal(sd, ob, an, nodes, totnode); 01432 01433 cross_v3_v3v3(tmp, an, grab_delta); 01434 cross_v3_v3v3(cono, tmp, an); 01435 01436 #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) 01437 for(n = 0; n < totnode; n++) { 01438 PBVHVertexIter vd; 01439 SculptUndoNode* unode; 01440 SculptBrushTest test; 01441 float (*origco)[3]; 01442 short (*origno)[3]; 01443 float (*proxy)[3]; 01444 01445 unode= sculpt_undo_push_node(ob, nodes[n]); 01446 origco= unode->co; 01447 origno= unode->no; 01448 01449 proxy= BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co; 01450 01451 sculpt_brush_test_init(ss, &test); 01452 01453 BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { 01454 if(sculpt_brush_test(&test, origco[vd.i])) { 01455 const float fade = bstrength*tex_strength(ss, brush, origco[vd.i], test.dist, 01456 an, origno[vd.i], NULL); 01457 01458 mul_v3_v3fl(proxy[vd.i], cono, fade); 01459 01460 if(vd.mvert) 01461 vd.mvert->flag |= ME_VERT_PBVH_UPDATE; 01462 } 01463 } 01464 BLI_pbvh_vertex_iter_end; 01465 } 01466 } 01467 01468 static void do_rotate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) 01469 { 01470 SculptSession *ss = ob->sculpt; 01471 Brush *brush= paint_brush(&sd->paint); 01472 float bstrength= ss->cache->bstrength; 01473 float an[3]; 01474 int n; 01475 float m[4][4], rot[4][4], lmat[4][4], ilmat[4][4]; 01476 static const int flip[8] = { 1, -1, -1, 1, -1, 1, 1, -1 }; 01477 float angle = ss->cache->vertex_rotation * flip[ss->cache->mirror_symmetry_pass]; 01478 01479 calc_sculpt_normal(sd, ob, an, nodes, totnode); 01480 01481 unit_m4(m); 01482 unit_m4(lmat); 01483 01484 copy_v3_v3(lmat[3], ss->cache->location); 01485 invert_m4_m4(ilmat, lmat); 01486 axis_angle_to_mat4(rot, an, angle); 01487 01488 mul_serie_m4(m, lmat, rot, ilmat, NULL, NULL, NULL, NULL, NULL); 01489 01490 #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) 01491 for(n=0; n<totnode; n++) { 01492 PBVHVertexIter vd; 01493 SculptUndoNode* unode; 01494 SculptBrushTest test; 01495 float (*origco)[3]; 01496 short (*origno)[3]; 01497 float (*proxy)[3]; 01498 01499 unode= sculpt_undo_push_node(ob, nodes[n]); 01500 origco= unode->co; 01501 origno= unode->no; 01502 01503 proxy= BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co; 01504 01505 sculpt_brush_test_init(ss, &test); 01506 01507 BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { 01508 if(sculpt_brush_test(&test, origco[vd.i])) { 01509 const float fade = bstrength*tex_strength(ss, brush, origco[vd.i], test.dist, 01510 an, origno[vd.i], NULL); 01511 01512 mul_v3_m4v3(proxy[vd.i], m, origco[vd.i]); 01513 sub_v3_v3(proxy[vd.i], origco[vd.i]); 01514 mul_v3_fl(proxy[vd.i], fade); 01515 01516 if(vd.mvert) 01517 vd.mvert->flag |= ME_VERT_PBVH_UPDATE; 01518 } 01519 } 01520 BLI_pbvh_vertex_iter_end; 01521 } 01522 } 01523 01524 static void do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) 01525 { 01526 SculptSession *ss = ob->sculpt; 01527 Brush *brush = paint_brush(&sd->paint); 01528 float bstrength= ss->cache->bstrength; 01529 float area_normal[3], offset[3]; 01530 float lim= brush->height; 01531 int n; 01532 01533 if(bstrength < 0) 01534 lim = -lim; 01535 01536 calc_sculpt_normal(sd, ob, area_normal, nodes, totnode); 01537 01538 mul_v3_v3v3(offset, ss->cache->scale, area_normal); 01539 01540 #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) 01541 for(n=0; n<totnode; n++) { 01542 PBVHVertexIter vd; 01543 SculptBrushTest test; 01544 SculptUndoNode *unode; 01545 float (*origco)[3], *layer_disp; 01546 //float (*proxy)[3]; // XXX layer brush needs conversion to proxy but its more complicated 01547 01548 //proxy= BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co; 01549 01550 unode= sculpt_undo_push_node(ob, nodes[n]); 01551 origco=unode->co; 01552 if(!unode->layer_disp) 01553 { 01554 #pragma omp critical 01555 unode->layer_disp= MEM_callocN(sizeof(float)*unode->totvert, "layer disp"); 01556 } 01557 01558 layer_disp= unode->layer_disp; 01559 01560 sculpt_brush_test_init(ss, &test); 01561 01562 BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { 01563 if(sculpt_brush_test(&test, origco[vd.i])) { 01564 const float fade = bstrength*tex_strength(ss, brush, vd.co, test.dist, 01565 area_normal, vd.no, vd.fno); 01566 float *disp= &layer_disp[vd.i]; 01567 float val[3]; 01568 01569 *disp+= fade; 01570 01571 /* Don't let the displacement go past the limit */ 01572 if((lim < 0 && *disp < lim) || (lim >= 0 && *disp > lim)) 01573 *disp = lim; 01574 01575 mul_v3_v3fl(val, offset, *disp); 01576 01577 if(ss->layer_co && (brush->flag & BRUSH_PERSISTENT)) { 01578 int index= vd.vert_indices[vd.i]; 01579 01580 /* persistent base */ 01581 add_v3_v3(val, ss->layer_co[index]); 01582 } 01583 else { 01584 add_v3_v3(val, origco[vd.i]); 01585 } 01586 01587 sculpt_clip(sd, ss, vd.co, val); 01588 01589 if(vd.mvert) 01590 vd.mvert->flag |= ME_VERT_PBVH_UPDATE; 01591 } 01592 } 01593 BLI_pbvh_vertex_iter_end; 01594 } 01595 } 01596 01597 static void do_inflate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) 01598 { 01599 SculptSession *ss = ob->sculpt; 01600 Brush *brush = paint_brush(&sd->paint); 01601 float bstrength= ss->cache->bstrength; 01602 int n; 01603 01604 #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) 01605 for(n=0; n<totnode; n++) { 01606 PBVHVertexIter vd; 01607 SculptBrushTest test; 01608 float (*proxy)[3]; 01609 01610 proxy= BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co; 01611 01612 sculpt_brush_test_init(ss, &test); 01613 01614 BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { 01615 if(sculpt_brush_test(&test, vd.co)) { 01616 const float fade = bstrength*tex_strength(ss, brush, vd.co, test.dist, 01617 ss->cache->view_normal, vd.no, vd.fno); 01618 float val[3]; 01619 01620 if(vd.fno) copy_v3_v3(val, vd.fno); 01621 else normal_short_to_float_v3(val, vd.no); 01622 01623 mul_v3_fl(val, fade * ss->cache->radius); 01624 mul_v3_v3v3(proxy[vd.i], val, ss->cache->scale); 01625 01626 if(vd.mvert) 01627 vd.mvert->flag |= ME_VERT_PBVH_UPDATE; 01628 } 01629 } 01630 BLI_pbvh_vertex_iter_end; 01631 } 01632 } 01633 01634 static void calc_flatten_center(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float fc[3]) 01635 { 01636 SculptSession *ss = ob->sculpt; 01637 int n; 01638 01639 float count = 0; 01640 01641 (void)sd; /* unused w/o openmp */ 01642 01643 zero_v3(fc); 01644 01645 #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) 01646 for(n=0; n<totnode; n++) { 01647 PBVHVertexIter vd; 01648 SculptBrushTest test; 01649 SculptUndoNode *unode; 01650 float private_fc[3] = {0.0f, 0.0f, 0.0f}; 01651 int private_count = 0; 01652 01653 unode = sculpt_undo_push_node(ob, nodes[n]); 01654 sculpt_brush_test_init(ss, &test); 01655 01656 if(ss->cache->original) { 01657 BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { 01658 if(sculpt_brush_test_fast(&test, unode->co[vd.i])) { 01659 add_v3_v3(private_fc, unode->co[vd.i]); 01660 private_count++; 01661 } 01662 } 01663 BLI_pbvh_vertex_iter_end; 01664 } 01665 else { 01666 BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { 01667 if(sculpt_brush_test_fast(&test, vd.co)) { 01668 add_v3_v3(private_fc, vd.co); 01669 private_count++; 01670 } 01671 } 01672 BLI_pbvh_vertex_iter_end; 01673 } 01674 01675 #pragma omp critical 01676 { 01677 add_v3_v3(fc, private_fc); 01678 count += private_count; 01679 } 01680 } 01681 01682 mul_v3_fl(fc, 1.0f / count); 01683 } 01684 01685 /* this calculates flatten center and area normal together, 01686 amortizing the memory bandwidth and loop overhead to calculate both at the same time */ 01687 static void calc_area_normal_and_flatten_center(Sculpt *sd, Object *ob, 01688 PBVHNode **nodes, int totnode, 01689 float an[3], float fc[3]) 01690 { 01691 SculptSession *ss = ob->sculpt; 01692 int n; 01693 01694 // an 01695 float out_flip[3] = {0.0f, 0.0f, 0.0f}; 01696 01697 // fc 01698 float count = 0; 01699 01700 (void)sd; /* unused w/o openmp */ 01701 01702 // an 01703 zero_v3(an); 01704 01705 // fc 01706 zero_v3(fc); 01707 01708 #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) 01709 for(n=0; n<totnode; n++) { 01710 PBVHVertexIter vd; 01711 SculptBrushTest test; 01712 SculptUndoNode *unode; 01713 float private_an[3] = {0.0f, 0.0f, 0.0f}; 01714 float private_out_flip[3] = {0.0f, 0.0f, 0.0f}; 01715 float private_fc[3] = {0.0f, 0.0f, 0.0f}; 01716 int private_count = 0; 01717 01718 unode = sculpt_undo_push_node(ob, nodes[n]); 01719 sculpt_brush_test_init(ss, &test); 01720 01721 if(ss->cache->original) { 01722 BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { 01723 if(sculpt_brush_test_fast(&test, unode->co[vd.i])) { 01724 // an 01725 float fno[3]; 01726 01727 normal_short_to_float_v3(fno, unode->no[vd.i]); 01728 add_norm_if(ss->cache->view_normal, private_an, private_out_flip, fno); 01729 01730 // fc 01731 add_v3_v3(private_fc, unode->co[vd.i]); 01732 private_count++; 01733 } 01734 } 01735 BLI_pbvh_vertex_iter_end; 01736 } 01737 else { 01738 BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { 01739 if(sculpt_brush_test_fast(&test, vd.co)) { 01740 // an 01741 if(vd.no) { 01742 float fno[3]; 01743 01744 normal_short_to_float_v3(fno, vd.no); 01745 add_norm_if(ss->cache->view_normal, private_an, private_out_flip, fno); 01746 } 01747 else { 01748 add_norm_if(ss->cache->view_normal, private_an, private_out_flip, vd.fno); 01749 } 01750 01751 // fc 01752 add_v3_v3(private_fc, vd.co); 01753 private_count++; 01754 } 01755 } 01756 BLI_pbvh_vertex_iter_end; 01757 } 01758 01759 #pragma omp critical 01760 { 01761 // an 01762 add_v3_v3(an, private_an); 01763 add_v3_v3(out_flip, private_out_flip); 01764 01765 // fc 01766 add_v3_v3(fc, private_fc); 01767 count += private_count; 01768 } 01769 } 01770 01771 // an 01772 if (is_zero_v3(an)) 01773 copy_v3_v3(an, out_flip); 01774 01775 normalize_v3(an); 01776 01777 // fc 01778 if (count != 0) { 01779 mul_v3_fl(fc, 1.0f / count); 01780 } 01781 else { 01782 zero_v3(fc); 01783 } 01784 } 01785 01786 static void calc_sculpt_plane(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float an[3], float fc[3]) 01787 { 01788 SculptSession *ss = ob->sculpt; 01789 Brush *brush = paint_brush(&sd->paint); 01790 01791 if (ss->cache->mirror_symmetry_pass == 0 && 01792 ss->cache->radial_symmetry_pass == 0 && 01793 (ss->cache->first_time || !(brush->flag & BRUSH_ORIGINAL_NORMAL))) 01794 { 01795 switch (brush->sculpt_plane) { 01796 case SCULPT_DISP_DIR_VIEW: 01797 ED_view3d_global_to_vector(ss->cache->vc->rv3d, ss->cache->vc->rv3d->twmat[3], an); 01798 break; 01799 01800 case SCULPT_DISP_DIR_X: 01801 an[1] = 0.0; 01802 an[2] = 0.0; 01803 an[0] = 1.0; 01804 break; 01805 01806 case SCULPT_DISP_DIR_Y: 01807 an[0] = 0.0; 01808 an[2] = 0.0; 01809 an[1] = 1.0; 01810 break; 01811 01812 case SCULPT_DISP_DIR_Z: 01813 an[0] = 0.0; 01814 an[1] = 0.0; 01815 an[2] = 1.0; 01816 break; 01817 01818 case SCULPT_DISP_DIR_AREA: 01819 calc_area_normal_and_flatten_center(sd, ob, nodes, totnode, an, fc); 01820 01821 default: 01822 break; 01823 } 01824 01825 // fc 01826 /* flatten center has not been calculated yet if we are not using the area normal */ 01827 if (brush->sculpt_plane != SCULPT_DISP_DIR_AREA) 01828 calc_flatten_center(sd, ob, nodes, totnode, fc); 01829 01830 // an 01831 copy_v3_v3(ss->cache->last_area_normal, an); 01832 01833 // fc 01834 copy_v3_v3(ss->cache->last_center, fc); 01835 } 01836 else { 01837 // an 01838 copy_v3_v3(an, ss->cache->last_area_normal); 01839 01840 // fc 01841 copy_v3_v3(fc, ss->cache->last_center); 01842 01843 // an 01844 flip_coord(an, an, ss->cache->mirror_symmetry_pass); 01845 01846 // fc 01847 flip_coord(fc, fc, ss->cache->mirror_symmetry_pass); 01848 01849 // an 01850 mul_m4_v3(ss->cache->symm_rot_mat, an); 01851 01852 // fc 01853 mul_m4_v3(ss->cache->symm_rot_mat, fc); 01854 } 01855 } 01856 01857 /* Projects a point onto a plane along the plane's normal */ 01858 static void point_plane_project(float intr[3], float co[3], float plane_normal[3], float plane_center[3]) 01859 { 01860 sub_v3_v3v3(intr, co, plane_center); 01861 mul_v3_v3fl(intr, plane_normal, dot_v3v3(plane_normal, intr)); 01862 sub_v3_v3v3(intr, co, intr); 01863 } 01864 01865 static int plane_trim(StrokeCache *cache, Brush *brush, float val[3]) 01866 { 01867 return !(brush->flag & BRUSH_PLANE_TRIM) || (dot_v3v3(val, val) <= cache->radius_squared*cache->plane_trim_squared); 01868 } 01869 01870 static int plane_point_side_flip(float co[3], float plane_normal[3], float plane_center[3], int flip) 01871 { 01872 float delta[3]; 01873 float d; 01874 01875 sub_v3_v3v3(delta, co, plane_center); 01876 d = dot_v3v3(plane_normal, delta); 01877 01878 if (flip) d = -d; 01879 01880 return d <= 0.0f; 01881 } 01882 01883 static int plane_point_side(float co[3], float plane_normal[3], float plane_center[3]) 01884 { 01885 float delta[3]; 01886 01887 sub_v3_v3v3(delta, co, plane_center); 01888 return dot_v3v3(plane_normal, delta) <= 0.0f; 01889 } 01890 01891 static float get_offset(Sculpt *sd, SculptSession *ss) 01892 { 01893 Brush* brush = paint_brush(&sd->paint); 01894 01895 float rv = brush->plane_offset; 01896 01897 if (brush->flag & BRUSH_OFFSET_PRESSURE) { 01898 rv *= ss->cache->pressure; 01899 } 01900 01901 return rv; 01902 } 01903 01904 static void do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) 01905 { 01906 SculptSession *ss = ob->sculpt; 01907 Brush *brush = paint_brush(&sd->paint); 01908 01909 float bstrength = ss->cache->bstrength; 01910 const float radius = ss->cache->radius; 01911 01912 float an[3]; 01913 float fc[3]; 01914 01915 float offset = get_offset(sd, ss); 01916 01917 float displace; 01918 01919 int n; 01920 01921 float temp[3]; 01922 01923 calc_sculpt_plane(sd, ob, nodes, totnode, an, fc); 01924 01925 displace = radius*offset; 01926 01927 mul_v3_v3v3(temp, an, ss->cache->scale); 01928 mul_v3_fl(temp, displace); 01929 add_v3_v3(fc, temp); 01930 01931 #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) 01932 for(n = 0; n < totnode; n++) { 01933 PBVHVertexIter vd; 01934 SculptBrushTest test; 01935 float (*proxy)[3]; 01936 01937 proxy= BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co; 01938 01939 sculpt_brush_test_init(ss, &test); 01940 01941 BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { 01942 if (sculpt_brush_test_sq(&test, vd.co)) { 01943 float intr[3]; 01944 float val[3]; 01945 01946 point_plane_project(intr, vd.co, an, fc); 01947 01948 sub_v3_v3v3(val, intr, vd.co); 01949 01950 if (plane_trim(ss->cache, brush, val)) { 01951 const float fade = bstrength*tex_strength(ss, brush, vd.co, sqrt(test.dist), 01952 an, vd.no, vd.fno); 01953 01954 mul_v3_v3fl(proxy[vd.i], val, fade); 01955 01956 if(vd.mvert) 01957 vd.mvert->flag |= ME_VERT_PBVH_UPDATE; 01958 } 01959 } 01960 } 01961 BLI_pbvh_vertex_iter_end; 01962 } 01963 } 01964 01965 static void do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) 01966 { 01967 SculptSession *ss = ob->sculpt; 01968 Brush *brush = paint_brush(&sd->paint); 01969 01970 float bstrength = ss->cache->bstrength; 01971 float radius = ss->cache->radius; 01972 float offset = get_offset(sd, ss); 01973 01974 float displace; 01975 01976 float an[3]; // area normal 01977 float fc[3]; // flatten center 01978 01979 int n; 01980 01981 float temp[3]; 01982 //float p[3]; 01983 01984 int flip; 01985 01986 calc_sculpt_plane(sd, ob, nodes, totnode, an, fc); 01987 01988 flip = bstrength < 0; 01989 01990 if (flip) { 01991 bstrength = -bstrength; 01992 radius = -radius; 01993 } 01994 01995 displace = radius * (0.25f+offset); 01996 01997 mul_v3_v3v3(temp, an, ss->cache->scale); 01998 mul_v3_fl(temp, displace); 01999 add_v3_v3(fc, temp); 02000 02001 //add_v3_v3v3(p, ss->cache->location, an); 02002 02003 #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) 02004 for (n = 0; n < totnode; n++) { 02005 PBVHVertexIter vd; 02006 SculptBrushTest test; 02007 float (*proxy)[3]; 02008 02009 proxy= BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co; 02010 02011 sculpt_brush_test_init(ss, &test); 02012 02013 BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { 02014 if (sculpt_brush_test_sq(&test, vd.co)) { 02015 if (plane_point_side_flip(vd.co, an, fc, flip)) { 02016 //if (sculpt_brush_test_cyl(&test, vd.co, ss->cache->location, p)) { 02017 float intr[3]; 02018 float val[3]; 02019 02020 point_plane_project(intr, vd.co, an, fc); 02021 02022 sub_v3_v3v3(val, intr, vd.co); 02023 02024 if (plane_trim(ss->cache, brush, val)) { 02025 const float fade = bstrength*tex_strength(ss, brush, vd.co, 02026 sqrt(test.dist), 02027 an, vd.no, vd.fno); 02028 02029 mul_v3_v3fl(proxy[vd.i], val, fade); 02030 02031 if(vd.mvert) 02032 vd.mvert->flag |= ME_VERT_PBVH_UPDATE; 02033 } 02034 } 02035 } 02036 } 02037 BLI_pbvh_vertex_iter_end; 02038 } 02039 } 02040 02041 static void do_clay_tubes_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) 02042 { 02043 SculptSession *ss = ob->sculpt; 02044 Brush *brush = paint_brush(&sd->paint); 02045 02046 float bstrength = ss->cache->bstrength; 02047 float radius = ss->cache->radius; 02048 float offset = get_offset(sd, ss); 02049 02050 float displace; 02051 02052 float sn[3]; // sculpt normal 02053 float an[3]; // area normal 02054 float fc[3]; // flatten center 02055 02056 int n; 02057 02058 float temp[3]; 02059 float mat[4][4]; 02060 float scale[4][4]; 02061 float tmat[4][4]; 02062 02063 int flip; 02064 02065 calc_sculpt_plane(sd, ob, nodes, totnode, sn, fc); 02066 02067 if (brush->sculpt_plane != SCULPT_DISP_DIR_AREA || (brush->flag & BRUSH_ORIGINAL_NORMAL)) 02068 calc_area_normal(sd, ob, an, nodes, totnode); 02069 else 02070 copy_v3_v3(an, sn); 02071 02072 if (ss->cache->first_time) 02073 return; // delay the first daub because grab delta is not setup 02074 02075 flip = bstrength < 0; 02076 02077 if (flip) { 02078 bstrength = -bstrength; 02079 radius = -radius; 02080 } 02081 02082 displace = radius * (0.25f+offset); 02083 02084 mul_v3_v3v3(temp, sn, ss->cache->scale); 02085 mul_v3_fl(temp, displace); 02086 add_v3_v3(fc, temp); 02087 02088 cross_v3_v3v3(mat[0], an, ss->cache->grab_delta_symmetry); mat[0][3] = 0; 02089 cross_v3_v3v3(mat[1], an, mat[0]); mat[1][3] = 0; 02090 copy_v3_v3(mat[2], an); mat[2][3] = 0; 02091 copy_v3_v3(mat[3], ss->cache->location); mat[3][3] = 1; 02092 normalize_m4(mat); 02093 scale_m4_fl(scale, ss->cache->radius); 02094 mult_m4_m4m4(tmat, mat, scale); 02095 invert_m4_m4(mat, tmat); 02096 02097 #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) 02098 for (n = 0; n < totnode; n++) { 02099 PBVHVertexIter vd; 02100 SculptBrushTest test; 02101 float (*proxy)[3]; 02102 02103 proxy= BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co; 02104 02105 sculpt_brush_test_init(ss, &test); 02106 02107 BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { 02108 if (sculpt_brush_test_cube(&test, vd.co, mat)) { 02109 if (plane_point_side_flip(vd.co, sn, fc, flip)) { 02110 float intr[3]; 02111 float val[3]; 02112 02113 point_plane_project(intr, vd.co, sn, fc); 02114 02115 sub_v3_v3v3(val, intr, vd.co); 02116 02117 if (plane_trim(ss->cache, brush, val)) { 02118 const float fade = bstrength*tex_strength(ss, brush, vd.co, 02119 ss->cache->radius*test.dist, 02120 an, vd.no, vd.fno); 02121 02122 mul_v3_v3fl(proxy[vd.i], val, fade); 02123 02124 if(vd.mvert) 02125 vd.mvert->flag |= ME_VERT_PBVH_UPDATE; 02126 } 02127 } 02128 } 02129 } 02130 BLI_pbvh_vertex_iter_end; 02131 } 02132 } 02133 02134 static void do_fill_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) 02135 { 02136 SculptSession *ss = ob->sculpt; 02137 Brush *brush = paint_brush(&sd->paint); 02138 02139 float bstrength = ss->cache->bstrength; 02140 const float radius = ss->cache->radius; 02141 02142 float an[3]; 02143 float fc[3]; 02144 float offset = get_offset(sd, ss); 02145 02146 float displace; 02147 02148 int n; 02149 02150 float temp[3]; 02151 02152 calc_sculpt_plane(sd, ob, nodes, totnode, an, fc); 02153 02154 displace = radius*offset; 02155 02156 mul_v3_v3v3(temp, an, ss->cache->scale); 02157 mul_v3_fl(temp, displace); 02158 add_v3_v3(fc, temp); 02159 02160 #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) 02161 for (n = 0; n < totnode; n++) { 02162 PBVHVertexIter vd; 02163 SculptBrushTest test; 02164 float (*proxy)[3]; 02165 02166 proxy= BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co; 02167 02168 sculpt_brush_test_init(ss, &test); 02169 02170 BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { 02171 if (sculpt_brush_test_sq(&test, vd.co)) { 02172 if (plane_point_side(vd.co, an, fc)) { 02173 float intr[3]; 02174 float val[3]; 02175 02176 point_plane_project(intr, vd.co, an, fc); 02177 02178 sub_v3_v3v3(val, intr, vd.co); 02179 02180 if (plane_trim(ss->cache, brush, val)) { 02181 const float fade = bstrength*tex_strength(ss, brush, vd.co, 02182 sqrt(test.dist), 02183 an, vd.no, vd.fno); 02184 02185 mul_v3_v3fl(proxy[vd.i], val, fade); 02186 02187 if(vd.mvert) 02188 vd.mvert->flag |= ME_VERT_PBVH_UPDATE; 02189 } 02190 } 02191 } 02192 } 02193 BLI_pbvh_vertex_iter_end; 02194 } 02195 } 02196 02197 static void do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) 02198 { 02199 SculptSession *ss = ob->sculpt; 02200 Brush *brush = paint_brush(&sd->paint); 02201 02202 float bstrength = ss->cache->bstrength; 02203 const float radius = ss->cache->radius; 02204 02205 float an[3]; 02206 float fc[3]; 02207 float offset = get_offset(sd, ss); 02208 02209 float displace; 02210 02211 int n; 02212 02213 float temp[3]; 02214 02215 calc_sculpt_plane(sd, ob, nodes, totnode, an, fc); 02216 02217 displace = -radius*offset; 02218 02219 mul_v3_v3v3(temp, an, ss->cache->scale); 02220 mul_v3_fl(temp, displace); 02221 add_v3_v3(fc, temp); 02222 02223 #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) 02224 for (n = 0; n < totnode; n++) { 02225 PBVHVertexIter vd; 02226 SculptBrushTest test; 02227 float (*proxy)[3]; 02228 02229 proxy= BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co; 02230 02231 sculpt_brush_test_init(ss, &test); 02232 02233 BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { 02234 if (sculpt_brush_test_sq(&test, vd.co)) { 02235 if (!plane_point_side(vd.co, an, fc)) { 02236 float intr[3]; 02237 float val[3]; 02238 02239 point_plane_project(intr, vd.co, an, fc); 02240 02241 sub_v3_v3v3(val, intr, vd.co); 02242 02243 if (plane_trim(ss->cache, brush, val)) { 02244 const float fade = bstrength*tex_strength(ss, brush, vd.co, 02245 sqrt(test.dist), 02246 an, vd.no, vd.fno); 02247 02248 mul_v3_v3fl(proxy[vd.i], val, fade); 02249 02250 if(vd.mvert) 02251 vd.mvert->flag |= ME_VERT_PBVH_UPDATE; 02252 } 02253 } 02254 } 02255 } 02256 BLI_pbvh_vertex_iter_end; 02257 } 02258 } 02259 02260 void sculpt_vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3]) 02261 { 02262 Mesh *me= (Mesh*)ob->data; 02263 float (*ofs)[3]= NULL; 02264 int a, is_basis= 0; 02265 KeyBlock *currkey; 02266 02267 /* for relative keys editing of base should update other keys */ 02268 if (me->key->type == KEY_RELATIVE) 02269 for (currkey = me->key->block.first; currkey; currkey= currkey->next) 02270 if(ob->shapenr-1 == currkey->relative) { 02271 is_basis= 1; 02272 break; 02273 } 02274 02275 if (is_basis) { 02276 ofs= key_to_vertcos(ob, kb); 02277 02278 /* calculate key coord offsets (from previous location) */ 02279 for (a= 0; a < me->totvert; a++) { 02280 sub_v3_v3v3(ofs[a], vertCos[a], ofs[a]); 02281 } 02282 02283 /* apply offsets on other keys */ 02284 currkey = me->key->block.first; 02285 while (currkey) { 02286 int apply_offset = ((currkey != kb) && (ob->shapenr-1 == currkey->relative)); 02287 02288 if (apply_offset) 02289 offset_to_key(ob, currkey, ofs); 02290 02291 currkey= currkey->next; 02292 } 02293 02294 MEM_freeN(ofs); 02295 } 02296 02297 /* modifying of basis key should update mesh */ 02298 if (kb == me->key->refkey) { 02299 MVert *mvert= me->mvert; 02300 02301 for (a= 0; a < me->totvert; a++, mvert++) 02302 copy_v3_v3(mvert->co, vertCos[a]); 02303 02304 mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL); 02305 } 02306 02307 /* apply new coords on active key block */ 02308 vertcos_to_key(ob, kb, vertCos); 02309 } 02310 02311 static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush) 02312 { 02313 SculptSession *ss = ob->sculpt; 02314 SculptSearchSphereData data; 02315 PBVHNode **nodes = NULL; 02316 int n, totnode; 02317 02318 /* Build a list of all nodes that are potentially within the brush's area of influence */ 02319 data.ss = ss; 02320 data.sd = sd; 02321 data.radius_squared = ss->cache->radius_squared; 02322 data.original = ELEM4(brush->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_ROTATE, SCULPT_TOOL_THUMB, SCULPT_TOOL_LAYER); 02323 BLI_pbvh_search_gather(ss->pbvh, sculpt_search_sphere_cb, &data, &nodes, &totnode); 02324 02325 /* Only act if some verts are inside the brush area */ 02326 if (totnode) { 02327 #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) 02328 for (n= 0; n < totnode; n++) { 02329 sculpt_undo_push_node(ob, nodes[n]); 02330 BLI_pbvh_node_mark_update(nodes[n]); 02331 } 02332 02333 /* Apply one type of brush action */ 02334 switch(brush->sculpt_tool){ 02335 case SCULPT_TOOL_DRAW: 02336 do_draw_brush(sd, ob, nodes, totnode); 02337 break; 02338 case SCULPT_TOOL_SMOOTH: 02339 do_smooth_brush(sd, ob, nodes, totnode); 02340 break; 02341 case SCULPT_TOOL_CREASE: 02342 do_crease_brush(sd, ob, nodes, totnode); 02343 break; 02344 case SCULPT_TOOL_BLOB: 02345 do_crease_brush(sd, ob, nodes, totnode); 02346 break; 02347 case SCULPT_TOOL_PINCH: 02348 do_pinch_brush(sd, ob, nodes, totnode); 02349 break; 02350 case SCULPT_TOOL_INFLATE: 02351 do_inflate_brush(sd, ob, nodes, totnode); 02352 break; 02353 case SCULPT_TOOL_GRAB: 02354 do_grab_brush(sd, ob, nodes, totnode); 02355 break; 02356 case SCULPT_TOOL_ROTATE: 02357 do_rotate_brush(sd, ob, nodes, totnode); 02358 break; 02359 case SCULPT_TOOL_SNAKE_HOOK: 02360 do_snake_hook_brush(sd, ob, nodes, totnode); 02361 break; 02362 case SCULPT_TOOL_NUDGE: 02363 do_nudge_brush(sd, ob, nodes, totnode); 02364 break; 02365 case SCULPT_TOOL_THUMB: 02366 do_thumb_brush(sd, ob, nodes, totnode); 02367 break; 02368 case SCULPT_TOOL_LAYER: 02369 do_layer_brush(sd, ob, nodes, totnode); 02370 break; 02371 case SCULPT_TOOL_FLATTEN: 02372 do_flatten_brush(sd, ob, nodes, totnode); 02373 break; 02374 case SCULPT_TOOL_CLAY: 02375 do_clay_brush(sd, ob, nodes, totnode); 02376 break; 02377 case SCULPT_TOOL_CLAY_TUBES: 02378 do_clay_tubes_brush(sd, ob, nodes, totnode); 02379 break; 02380 case SCULPT_TOOL_FILL: 02381 do_fill_brush(sd, ob, nodes, totnode); 02382 break; 02383 case SCULPT_TOOL_SCRAPE: 02384 do_scrape_brush(sd, ob, nodes, totnode); 02385 break; 02386 } 02387 02388 if (brush->sculpt_tool != SCULPT_TOOL_SMOOTH && brush->autosmooth_factor > 0) { 02389 if (brush->flag & BRUSH_INVERSE_SMOOTH_PRESSURE) { 02390 smooth(sd, ob, nodes, totnode, brush->autosmooth_factor*(1-ss->cache->pressure)); 02391 } 02392 else { 02393 smooth(sd, ob, nodes, totnode, brush->autosmooth_factor); 02394 } 02395 } 02396 02397 MEM_freeN(nodes); 02398 } 02399 } 02400 02401 /* flush displacement from deformed PBVH vertex to original mesh */ 02402 static void sculpt_flush_pbvhvert_deform(Object *ob, PBVHVertexIter *vd) 02403 { 02404 SculptSession *ss = ob->sculpt; 02405 Mesh *me= ob->data; 02406 float disp[3], newco[3]; 02407 int index= vd->vert_indices[vd->i]; 02408 02409 sub_v3_v3v3(disp, vd->co, ss->deform_cos[index]); 02410 mul_m3_v3(ss->deform_imats[index], disp); 02411 add_v3_v3v3(newco, disp, ss->orig_cos[index]); 02412 02413 copy_v3_v3(ss->deform_cos[index], vd->co); 02414 copy_v3_v3(ss->orig_cos[index], newco); 02415 02416 if(!ss->kb) 02417 copy_v3_v3(me->mvert[index].co, newco); 02418 } 02419 02420 static void sculpt_combine_proxies(Sculpt *sd, Object *ob) 02421 { 02422 SculptSession *ss = ob->sculpt; 02423 Brush *brush= paint_brush(&sd->paint); 02424 PBVHNode** nodes; 02425 int totnode, n; 02426 02427 BLI_pbvh_gather_proxies(ss->pbvh, &nodes, &totnode); 02428 02429 if(!ELEM(brush->sculpt_tool, SCULPT_TOOL_SMOOTH, SCULPT_TOOL_LAYER)) { 02430 /* these brushes start from original coordinates */ 02431 const int use_orco = (ELEM3(brush->sculpt_tool, SCULPT_TOOL_GRAB, 02432 SCULPT_TOOL_ROTATE, SCULPT_TOOL_THUMB)); 02433 02434 #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) 02435 for (n= 0; n < totnode; n++) { 02436 PBVHVertexIter vd; 02437 PBVHProxyNode* proxies; 02438 int proxy_count; 02439 float (*orco)[3]; 02440 02441 if(use_orco) 02442 orco= sculpt_undo_push_node(ob, nodes[n])->co; 02443 02444 BLI_pbvh_node_get_proxies(nodes[n], &proxies, &proxy_count); 02445 02446 BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { 02447 float val[3]; 02448 int p; 02449 02450 if(use_orco) 02451 copy_v3_v3(val, orco[vd.i]); 02452 else 02453 copy_v3_v3(val, vd.co); 02454 02455 for (p= 0; p < proxy_count; p++) 02456 add_v3_v3(val, proxies[p].co[vd.i]); 02457 02458 sculpt_clip(sd, ss, vd.co, val); 02459 02460 if(ss->modifiers_active) 02461 sculpt_flush_pbvhvert_deform(ob, &vd); 02462 } 02463 BLI_pbvh_vertex_iter_end; 02464 02465 BLI_pbvh_node_free_proxies(nodes[n]); 02466 } 02467 } 02468 02469 if (nodes) 02470 MEM_freeN(nodes); 02471 } 02472 02473 /* copy the modified vertices from bvh to the active key */ 02474 static void sculpt_update_keyblock(Object *ob) 02475 { 02476 SculptSession *ss = ob->sculpt; 02477 float (*vertCos)[3]; 02478 02479 /* Keyblock update happens after hadning deformation caused by modifiers, 02480 so ss->orig_cos would be updated with new stroke */ 02481 if(ss->orig_cos) vertCos = ss->orig_cos; 02482 else vertCos = BLI_pbvh_get_vertCos(ss->pbvh); 02483 02484 if (vertCos) { 02485 sculpt_vertcos_to_key(ob, ss->kb, vertCos); 02486 02487 if(vertCos != ss->orig_cos) 02488 MEM_freeN(vertCos); 02489 } 02490 } 02491 02492 /* flush displacement from deformed PBVH to original layer */ 02493 static void sculpt_flush_stroke_deform(Sculpt *sd, Object *ob) 02494 { 02495 SculptSession *ss = ob->sculpt; 02496 Brush *brush= paint_brush(&sd->paint); 02497 02498 if(ELEM(brush->sculpt_tool, SCULPT_TOOL_SMOOTH, SCULPT_TOOL_LAYER)) { 02499 /* this brushes aren't using proxies, so sculpt_combine_proxies() wouldn't 02500 propagate needed deformation to original base */ 02501 02502 int n, totnode; 02503 Mesh *me= (Mesh*)ob->data; 02504 PBVHNode** nodes; 02505 float (*vertCos)[3]= NULL; 02506 02507 if(ss->kb) 02508 vertCos= MEM_callocN(sizeof(*vertCos)*me->totvert, "flushStrokeDeofrm keyVerts"); 02509 02510 BLI_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode); 02511 02512 #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) 02513 for (n= 0; n < totnode; n++) { 02514 PBVHVertexIter vd; 02515 02516 BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { 02517 sculpt_flush_pbvhvert_deform(ob, &vd); 02518 02519 if(vertCos) { 02520 int index= vd.vert_indices[vd.i]; 02521 copy_v3_v3(vertCos[index], ss->orig_cos[index]); 02522 } 02523 } 02524 BLI_pbvh_vertex_iter_end; 02525 } 02526 02527 if(vertCos) { 02528 sculpt_vertcos_to_key(ob, ss->kb, vertCos); 02529 MEM_freeN(vertCos); 02530 } 02531 02532 MEM_freeN(nodes); 02533 02534 /* Modifiers could depend on mesh normals, so we should update them/ 02535 Note, then if sculpting happens on locked key, normals should be re-calculated 02536 after applying coords from keyblock on base mesh */ 02537 mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL); 02538 } else if (ss->kb) 02539 sculpt_update_keyblock(ob); 02540 } 02541 02542 //static int max_overlap_count(Sculpt *sd) 02543 //{ 02544 // int count[3]; 02545 // int i, j; 02546 // 02547 // for (i= 0; i < 3; i++) { 02548 // count[i] = sd->radial_symm[i]; 02549 // 02550 // for (j= 0; j < 3; j++) { 02551 // if (i != j && sd->flags & (SCULPT_SYMM_X<<i)) 02552 // count[i] *= 2; 02553 // } 02554 // } 02555 // 02556 // return MAX3(count[0], count[1], count[2]); 02557 //} 02558 02559 /* Flip all the editdata across the axis/axes specified by symm. Used to 02560 calculate multiple modifications to the mesh when symmetry is enabled. */ 02561 static void calc_brushdata_symm(Sculpt *sd, StrokeCache *cache, const char symm, 02562 const char axis, const float angle, 02563 const float UNUSED(feather)) 02564 { 02565 (void)sd; /* unused */ 02566 02567 flip_coord(cache->location, cache->true_location, symm); 02568 flip_coord(cache->grab_delta_symmetry, cache->grab_delta, symm); 02569 flip_coord(cache->view_normal, cache->true_view_normal, symm); 02570 02571 // XXX This reduces the length of the grab delta if it approaches the line of symmetry 02572 // XXX However, a different approach appears to be needed 02573 //if (sd->flags & SCULPT_SYMMETRY_FEATHER) { 02574 // float frac = 1.0f/max_overlap_count(sd); 02575 // float reduce = (feather-frac)/(1-frac); 02576 02577 // printf("feather: %f frac: %f reduce: %f\n", feather, frac, reduce); 02578 02579 // if (frac < 1) 02580 // mul_v3_fl(cache->grab_delta_symmetry, reduce); 02581 //} 02582 02583 unit_m4(cache->symm_rot_mat); 02584 unit_m4(cache->symm_rot_mat_inv); 02585 02586 if(axis) { /* expects XYZ */ 02587 rotate_m4(cache->symm_rot_mat, axis, angle); 02588 rotate_m4(cache->symm_rot_mat_inv, axis, -angle); 02589 } 02590 02591 mul_m4_v3(cache->symm_rot_mat, cache->location); 02592 mul_m4_v3(cache->symm_rot_mat, cache->grab_delta_symmetry); 02593 } 02594 02595 static void do_radial_symmetry(Sculpt *sd, Object *ob, Brush *brush, 02596 const char symm, const int axis, 02597 const float feather) 02598 { 02599 SculptSession *ss = ob->sculpt; 02600 int i; 02601 02602 for(i = 1; i < sd->radial_symm[axis-'X']; ++i) { 02603 const float angle = 2*M_PI*i/sd->radial_symm[axis-'X']; 02604 ss->cache->radial_symmetry_pass= i; 02605 calc_brushdata_symm(sd, ss->cache, symm, axis, angle, feather); 02606 do_brush_action(sd, ob, brush); 02607 } 02608 } 02609 02610 /* noise texture gives different values for the same input coord; this 02611 can tear a multires mesh during sculpting so do a stitch in this 02612 case */ 02613 static void sculpt_fix_noise_tear(Sculpt *sd, Object *ob) 02614 { 02615 SculptSession *ss = ob->sculpt; 02616 Brush *brush = paint_brush(&sd->paint); 02617 MTex *mtex = &brush->mtex; 02618 02619 if(ss->multires && mtex->tex && mtex->tex->type == TEX_NOISE) 02620 multires_stitch_grids(ob); 02621 } 02622 02623 static void do_symmetrical_brush_actions(Sculpt *sd, Object *ob) 02624 { 02625 Brush *brush = paint_brush(&sd->paint); 02626 SculptSession *ss = ob->sculpt; 02627 StrokeCache *cache = ss->cache; 02628 const char symm = sd->flags & 7; 02629 int i; 02630 02631 float feather = calc_symmetry_feather(sd, ss->cache); 02632 02633 cache->bstrength= brush_strength(sd, cache, feather); 02634 02635 cache->symmetry= symm; 02636 02637 /* symm is a bit combination of XYZ - 1 is mirror X; 2 is Y; 3 is XY; 4 is Z; 5 is XZ; 6 is YZ; 7 is XYZ */ 02638 for(i = 0; i <= symm; ++i) { 02639 if(i == 0 || (symm & i && (symm != 5 || i != 3) && (symm != 6 || (i != 3 && i != 5)))) { 02640 cache->mirror_symmetry_pass= i; 02641 cache->radial_symmetry_pass= 0; 02642 02643 calc_brushdata_symm(sd, cache, i, 0, 0, feather); 02644 do_brush_action(sd, ob, brush); 02645 02646 do_radial_symmetry(sd, ob, brush, i, 'X', feather); 02647 do_radial_symmetry(sd, ob, brush, i, 'Y', feather); 02648 do_radial_symmetry(sd, ob, brush, i, 'Z', feather); 02649 } 02650 } 02651 02652 sculpt_combine_proxies(sd, ob); 02653 02654 /* hack to fix noise texture tearing mesh */ 02655 sculpt_fix_noise_tear(sd, ob); 02656 02657 if (ss->modifiers_active) 02658 sculpt_flush_stroke_deform(sd, ob); 02659 02660 cache->first_time= 0; 02661 } 02662 02663 static void sculpt_update_tex(const Scene *scene, Sculpt *sd, SculptSession *ss) 02664 { 02665 Brush *brush = paint_brush(&sd->paint); 02666 const int radius= brush_size(scene, brush); 02667 02668 if(ss->texcache) { 02669 MEM_freeN(ss->texcache); 02670 ss->texcache= NULL; 02671 } 02672 02673 /* Need to allocate a bigger buffer for bigger brush size */ 02674 ss->texcache_side = 2*radius; 02675 if(!ss->texcache || ss->texcache_side > ss->texcache_actual) { 02676 ss->texcache = brush_gen_texture_cache(brush, radius); 02677 ss->texcache_actual = ss->texcache_side; 02678 } 02679 } 02680 02681 void sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob, int need_fmap) 02682 { 02683 DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); 02684 SculptSession *ss = ob->sculpt; 02685 MultiresModifierData *mmd= sculpt_multires_active(scene, ob); 02686 02687 ss->modifiers_active= sculpt_modifiers_active(scene, sd, ob); 02688 02689 if(!mmd) ss->kb= ob_get_keyblock(ob); 02690 else ss->kb= NULL; 02691 02692 if(mmd) { 02693 ss->multires = mmd; 02694 ss->totvert = dm->getNumVerts(dm); 02695 ss->totface = dm->getNumFaces(dm); 02696 ss->mvert= NULL; 02697 ss->mface= NULL; 02698 ss->face_normals= NULL; 02699 } 02700 else { 02701 Mesh *me = get_mesh(ob); 02702 ss->totvert = me->totvert; 02703 ss->totface = me->totface; 02704 ss->mvert = me->mvert; 02705 ss->mface = me->mface; 02706 ss->face_normals = NULL; 02707 ss->multires = NULL; 02708 } 02709 02710 ss->pbvh = dm->getPBVH(ob, dm); 02711 ss->fmap = (need_fmap && dm->getFaceMap)? dm->getFaceMap(ob, dm): NULL; 02712 02713 if(ss->modifiers_active) { 02714 if(!ss->orig_cos) { 02715 int a; 02716 02717 free_sculptsession_deformMats(ss); 02718 02719 if(ss->kb) ss->orig_cos = key_to_vertcos(ob, ss->kb); 02720 else ss->orig_cos = mesh_getVertexCos(ob->data, NULL); 02721 02722 crazyspace_build_sculpt(scene, ob, &ss->deform_imats, &ss->deform_cos); 02723 BLI_pbvh_apply_vertCos(ss->pbvh, ss->deform_cos); 02724 02725 for(a = 0; a < ((Mesh*)ob->data)->totvert; ++a) 02726 invert_m3(ss->deform_imats[a]); 02727 } 02728 } else free_sculptsession_deformMats(ss); 02729 02730 /* if pbvh is deformed, key block is already applied to it */ 02731 if (ss->kb && !BLI_pbvh_isDeformed(ss->pbvh)) { 02732 float (*vertCos)[3]= key_to_vertcos(ob, ss->kb); 02733 02734 if (vertCos) { 02735 /* apply shape keys coordinates to PBVH */ 02736 BLI_pbvh_apply_vertCos(ss->pbvh, vertCos); 02737 MEM_freeN(vertCos); 02738 } 02739 } 02740 } 02741 02742 static int sculpt_mode_poll(bContext *C) 02743 { 02744 Object *ob = CTX_data_active_object(C); 02745 return ob && ob->mode & OB_MODE_SCULPT; 02746 } 02747 02748 int sculpt_poll(bContext *C) 02749 { 02750 return sculpt_mode_poll(C) && paint_poll(C); 02751 } 02752 02753 static const char *sculpt_tool_name(Sculpt *sd) 02754 { 02755 Brush *brush = paint_brush(&sd->paint); 02756 02757 switch(brush->sculpt_tool) { 02758 case SCULPT_TOOL_DRAW: 02759 return "Draw Brush"; break; 02760 case SCULPT_TOOL_SMOOTH: 02761 return "Smooth Brush"; break; 02762 case SCULPT_TOOL_CREASE: 02763 return "Crease Brush"; break; 02764 case SCULPT_TOOL_BLOB: 02765 return "Blob Brush"; break; 02766 case SCULPT_TOOL_PINCH: 02767 return "Pinch Brush"; break; 02768 case SCULPT_TOOL_INFLATE: 02769 return "Inflate Brush"; break; 02770 case SCULPT_TOOL_GRAB: 02771 return "Grab Brush"; break; 02772 case SCULPT_TOOL_NUDGE: 02773 return "Nudge Brush"; break; 02774 case SCULPT_TOOL_THUMB: 02775 return "Thumb Brush"; break; 02776 case SCULPT_TOOL_LAYER: 02777 return "Layer Brush"; break; 02778 case SCULPT_TOOL_FLATTEN: 02779 return "Flatten Brush"; break; 02780 case SCULPT_TOOL_CLAY: 02781 return "Clay Brush"; break; 02782 case SCULPT_TOOL_CLAY_TUBES: 02783 return "Clay Tubes Brush"; break; 02784 case SCULPT_TOOL_FILL: 02785 return "Fill Brush"; break; 02786 case SCULPT_TOOL_SCRAPE: 02787 return "Scrape Brush"; break; 02788 default: 02789 return "Sculpting"; break; 02790 } 02791 } 02792 02793 /**** Operator for applying a stroke (various attributes including mouse path) 02794 using the current brush. ****/ 02795 02796 static void sculpt_cache_free(StrokeCache *cache) 02797 { 02798 if(cache->face_norms) 02799 MEM_freeN(cache->face_norms); 02800 MEM_freeN(cache); 02801 } 02802 02803 /* Initialize mirror modifier clipping */ 02804 static void sculpt_init_mirror_clipping(Object *ob, SculptSession *ss) 02805 { 02806 ModifierData *md; 02807 int i; 02808 02809 for(md= ob->modifiers.first; md; md= md->next) { 02810 if(md->type==eModifierType_Mirror && 02811 (md->mode & eModifierMode_Realtime)) { 02812 MirrorModifierData *mmd = (MirrorModifierData*)md; 02813 02814 if(mmd->flag & MOD_MIR_CLIPPING) { 02815 /* check each axis for mirroring */ 02816 for(i = 0; i < 3; ++i) { 02817 if(mmd->flag & (MOD_MIR_AXIS_X << i)) { 02818 /* enable sculpt clipping */ 02819 ss->cache->flag |= CLIP_X << i; 02820 02821 /* update the clip tolerance */ 02822 if(mmd->tolerance > 02823 ss->cache->clip_tolerance[i]) 02824 ss->cache->clip_tolerance[i] = 02825 mmd->tolerance; 02826 } 02827 } 02828 } 02829 } 02830 } 02831 } 02832 02833 /* Initialize the stroke cache invariants from operator properties */ 02834 static void sculpt_update_cache_invariants(bContext* C, Sculpt *sd, SculptSession *ss, wmOperator *op, wmEvent *event) 02835 { 02836 StrokeCache *cache = MEM_callocN(sizeof(StrokeCache), "stroke cache"); 02837 Brush *brush = paint_brush(&sd->paint); 02838 ViewContext *vc = paint_stroke_view_context(op->customdata); 02839 Object *ob= CTX_data_active_object(C); 02840 int i; 02841 int mode; 02842 02843 ss->cache = cache; 02844 02845 /* Set scaling adjustment */ 02846 ss->cache->scale[0] = 1.0f / ob->size[0]; 02847 ss->cache->scale[1] = 1.0f / ob->size[1]; 02848 ss->cache->scale[2] = 1.0f / ob->size[2]; 02849 02850 ss->cache->plane_trim_squared = brush->plane_trim * brush->plane_trim; 02851 02852 ss->cache->flag = 0; 02853 02854 sculpt_init_mirror_clipping(ob, ss); 02855 02856 /* Initial mouse location */ 02857 if (event) { 02858 ss->cache->initial_mouse[0] = event->x; 02859 ss->cache->initial_mouse[1] = event->y; 02860 } 02861 else { 02862 ss->cache->initial_mouse[0] = 0; 02863 ss->cache->initial_mouse[1] = 0; 02864 } 02865 02866 mode = RNA_enum_get(op->ptr, "mode"); 02867 cache->invert = mode == BRUSH_STROKE_INVERT; 02868 cache->alt_smooth = mode == BRUSH_STROKE_SMOOTH; 02869 02870 /* not very nice, but with current events system implementation 02871 we can't handle brush appearance inversion hotkey separately (sergey) */ 02872 if(cache->invert) brush->flag |= BRUSH_INVERTED; 02873 else brush->flag &= ~BRUSH_INVERTED; 02874 02875 /* Alt-Smooth */ 02876 if (ss->cache->alt_smooth) { 02877 Paint *p= &sd->paint; 02878 Brush *br; 02879 02880 BLI_strncpy(cache->saved_active_brush_name, brush->id.name+2, sizeof(cache->saved_active_brush_name)); 02881 02882 br= (Brush *)find_id("BR", "Smooth"); 02883 if(br) { 02884 paint_brush_set(p, br); 02885 brush = br; 02886 } 02887 } 02888 02889 copy_v2_v2(cache->mouse, cache->initial_mouse); 02890 copy_v2_v2(cache->tex_mouse, cache->initial_mouse); 02891 02892 /* Truly temporary data that isn't stored in properties */ 02893 02894 cache->vc = vc; 02895 02896 cache->brush = brush; 02897 02898 /* cache projection matrix */ 02899 ED_view3d_ob_project_mat_get(cache->vc->rv3d, ob, cache->projection_mat); 02900 02901 ED_view3d_global_to_vector(cache->vc->rv3d, cache->vc->rv3d->twmat[3], cache->true_view_normal); 02902 /* Initialize layer brush displacements and persistent coords */ 02903 if(brush->sculpt_tool == SCULPT_TOOL_LAYER) { 02904 /* not supported yet for multires */ 02905 if(!ss->multires && !ss->layer_co && (brush->flag & BRUSH_PERSISTENT)) { 02906 if(!ss->layer_co) 02907 ss->layer_co= MEM_mallocN(sizeof(float) * 3 * ss->totvert, 02908 "sculpt mesh vertices copy"); 02909 02910 if(ss->deform_cos) memcpy(ss->layer_co, ss->deform_cos, ss->totvert); 02911 else { 02912 for(i = 0; i < ss->totvert; ++i) { 02913 copy_v3_v3(ss->layer_co[i], ss->mvert[i].co); 02914 } 02915 } 02916 } 02917 } 02918 02919 /* Make copies of the mesh vertex locations and normals for some tools */ 02920 if(brush->flag & BRUSH_ANCHORED) { 02921 if(ss->face_normals) { 02922 float *fn = ss->face_normals; 02923 cache->face_norms= MEM_mallocN(sizeof(float) * 3 * ss->totface, "Sculpt face norms"); 02924 for(i = 0; i < ss->totface; ++i, fn += 3) 02925 copy_v3_v3(cache->face_norms[i], fn); 02926 } 02927 02928 cache->original = 1; 02929 } 02930 02931 if(ELEM8(brush->sculpt_tool, 02932 SCULPT_TOOL_DRAW, SCULPT_TOOL_CREASE, SCULPT_TOOL_BLOB, 02933 SCULPT_TOOL_LAYER, SCULPT_TOOL_INFLATE, SCULPT_TOOL_CLAY, 02934 SCULPT_TOOL_CLAY_TUBES, SCULPT_TOOL_ROTATE)) 02935 if(!(brush->flag & BRUSH_ACCUMULATE)) 02936 cache->original = 1; 02937 02938 cache->special_rotation = (brush->flag & BRUSH_RAKE) ? sd->last_angle : 0; 02939 //cache->last_rake[0] = sd->last_x; 02940 //cache->last_rake[1] = sd->last_y; 02941 02942 cache->first_time= 1; 02943 02944 cache->vertex_rotation= 0; 02945 } 02946 02947 static void sculpt_update_brush_delta(Sculpt *sd, Object *ob, Brush *brush) 02948 { 02949 SculptSession *ss = ob->sculpt; 02950 StrokeCache *cache = ss->cache; 02951 int tool = brush->sculpt_tool; 02952 02953 if(ELEM5(tool, 02954 SCULPT_TOOL_GRAB, SCULPT_TOOL_NUDGE, 02955 SCULPT_TOOL_CLAY_TUBES, SCULPT_TOOL_SNAKE_HOOK, 02956 SCULPT_TOOL_THUMB)) { 02957 float grab_location[3], imat[4][4], delta[3], loc[3]; 02958 02959 if(cache->first_time) { 02960 copy_v3_v3(cache->orig_grab_location, 02961 cache->true_location); 02962 } 02963 else if(tool == SCULPT_TOOL_SNAKE_HOOK) 02964 add_v3_v3(cache->true_location, cache->grab_delta); 02965 02966 /* compute 3d coordinate at same z from original location + mouse */ 02967 mul_v3_m4v3(loc, ob->obmat, cache->orig_grab_location); 02968 initgrabz(cache->vc->rv3d, loc[0], loc[1], loc[2]); 02969 02970 ED_view3d_win_to_delta(cache->vc->ar, cache->mouse, grab_location); 02971 02972 /* compute delta to move verts by */ 02973 if(!cache->first_time) { 02974 switch(tool) { 02975 case SCULPT_TOOL_GRAB: 02976 case SCULPT_TOOL_THUMB: 02977 sub_v3_v3v3(delta, grab_location, cache->old_grab_location); 02978 invert_m4_m4(imat, ob->obmat); 02979 mul_mat3_m4_v3(imat, delta); 02980 add_v3_v3(cache->grab_delta, delta); 02981 break; 02982 case SCULPT_TOOL_CLAY_TUBES: 02983 case SCULPT_TOOL_NUDGE: 02984 sub_v3_v3v3(cache->grab_delta, grab_location, cache->old_grab_location); 02985 invert_m4_m4(imat, ob->obmat); 02986 mul_mat3_m4_v3(imat, cache->grab_delta); 02987 break; 02988 case SCULPT_TOOL_SNAKE_HOOK: 02989 sub_v3_v3v3(cache->grab_delta, grab_location, cache->old_grab_location); 02990 invert_m4_m4(imat, ob->obmat); 02991 mul_mat3_m4_v3(imat, cache->grab_delta); 02992 break; 02993 } 02994 } 02995 else { 02996 zero_v3(cache->grab_delta); 02997 } 02998 02999 copy_v3_v3(cache->old_grab_location, grab_location); 03000 03001 if(tool == SCULPT_TOOL_GRAB) 03002 copy_v3_v3(sd->anchored_location, cache->true_location); 03003 else if(tool == SCULPT_TOOL_THUMB) 03004 copy_v3_v3(sd->anchored_location, cache->orig_grab_location); 03005 03006 if(ELEM(tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_THUMB)) { 03007 /* location stays the same for finding vertices in brush radius */ 03008 copy_v3_v3(cache->true_location, cache->orig_grab_location); 03009 03010 sd->draw_anchored = 1; 03011 copy_v2_v2(sd->anchored_initial_mouse, cache->initial_mouse); 03012 sd->anchored_size = cache->pixel_radius; 03013 } 03014 } 03015 } 03016 03017 /* Initialize the stroke cache variants from operator properties */ 03018 static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, 03019 struct PaintStroke *stroke, 03020 PointerRNA *ptr) 03021 { 03022 Scene *scene = CTX_data_scene(C); 03023 SculptSession *ss = ob->sculpt; 03024 StrokeCache *cache = ss->cache; 03025 Brush *brush = paint_brush(&sd->paint); 03026 03027 int dx, dy; 03028 03029 //RNA_float_get_array(ptr, "location", cache->traced_location); 03030 03031 if (cache->first_time || 03032 !((brush->flag & BRUSH_ANCHORED)|| 03033 (brush->sculpt_tool == SCULPT_TOOL_SNAKE_HOOK)|| 03034 (brush->sculpt_tool == SCULPT_TOOL_ROTATE)) 03035 ) 03036 { 03037 RNA_float_get_array(ptr, "location", cache->true_location); 03038 } 03039 03040 cache->pen_flip = RNA_boolean_get(ptr, "pen_flip"); 03041 RNA_float_get_array(ptr, "mouse", cache->mouse); 03042 03043 /* XXX: Use preassure value from first brush step for brushes which don't 03044 support strokes (grab, thumb). They depends on initial state and 03045 brush coord/pressure/etc. 03046 It's more an events design issue, which doesn't split coordinate/pressure/angle 03047 changing events. We should avoid this after events system re-design */ 03048 if(paint_space_stroke_enabled(brush) || cache->first_time) 03049 cache->pressure = RNA_float_get(ptr, "pressure"); 03050 03051 /* Truly temporary data that isn't stored in properties */ 03052 03053 sd->draw_pressure= 1; 03054 sd->pressure_value= cache->pressure; 03055 03056 cache->previous_pixel_radius = cache->pixel_radius; 03057 cache->pixel_radius = brush_size(scene, brush); 03058 03059 if(cache->first_time) { 03060 if (!brush_use_locked_size(scene, brush)) { 03061 cache->initial_radius= paint_calc_object_space_radius(cache->vc, cache->true_location, brush_size(scene, brush)); 03062 brush_set_unprojected_radius(scene, brush, cache->initial_radius); 03063 } 03064 else { 03065 cache->initial_radius= brush_unprojected_radius(scene, brush); 03066 } 03067 } 03068 03069 if(brush_use_size_pressure(scene, brush)) { 03070 cache->pixel_radius *= cache->pressure; 03071 cache->radius= cache->initial_radius * cache->pressure; 03072 } 03073 else 03074 cache->radius= cache->initial_radius; 03075 03076 cache->radius_squared = cache->radius*cache->radius; 03077 03078 if(!(brush->flag & BRUSH_ANCHORED || 03079 ELEM4(brush->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_SNAKE_HOOK, 03080 SCULPT_TOOL_THUMB, SCULPT_TOOL_ROTATE))) { 03081 copy_v2_v2(cache->tex_mouse, cache->mouse); 03082 03083 if ( (brush->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED) && 03084 (brush->flag & BRUSH_RANDOM_ROTATION) && 03085 !(brush->flag & BRUSH_RAKE)) 03086 { 03087 cache->special_rotation = 2.0f*(float)M_PI*BLI_frand(); 03088 } 03089 } 03090 03091 if(brush->flag & BRUSH_ANCHORED) { 03092 int hit = 0; 03093 03094 dx = cache->mouse[0] - cache->initial_mouse[0]; 03095 dy = cache->mouse[1] - cache->initial_mouse[1]; 03096 03097 sd->anchored_size = cache->pixel_radius = sqrt(dx*dx + dy*dy); 03098 03099 cache->special_rotation = atan2(dx, dy) + M_PI; 03100 03101 if (brush->flag & BRUSH_EDGE_TO_EDGE) { 03102 float halfway[2]; 03103 float out[3]; 03104 03105 halfway[0] = (float)dx * 0.5f + cache->initial_mouse[0]; 03106 halfway[1] = (float)dy * 0.5f + cache->initial_mouse[1]; 03107 03108 if (sculpt_stroke_get_location(C, stroke, out, halfway)) { 03109 copy_v3_v3(sd->anchored_location, out); 03110 copy_v2_v2(sd->anchored_initial_mouse, halfway); 03111 copy_v2_v2(cache->tex_mouse, halfway); 03112 copy_v3_v3(cache->true_location, sd->anchored_location); 03113 sd->anchored_size /= 2.0f; 03114 cache->pixel_radius /= 2.0f; 03115 hit = 1; 03116 } 03117 } 03118 03119 if (!hit) 03120 copy_v2_v2(sd->anchored_initial_mouse, cache->initial_mouse); 03121 03122 cache->radius= paint_calc_object_space_radius(paint_stroke_view_context(stroke), 03123 cache->true_location, 03124 cache->pixel_radius); 03125 cache->radius_squared = cache->radius*cache->radius; 03126 03127 copy_v3_v3(sd->anchored_location, cache->true_location); 03128 03129 sd->draw_anchored = 1; 03130 } 03131 else if(brush->flag & BRUSH_RAKE) { 03132 const float u = 0.5f; 03133 const float v = 1 - u; 03134 const float r = 20; 03135 03136 const float dx = cache->last_rake[0] - cache->mouse[0]; 03137 const float dy = cache->last_rake[1] - cache->mouse[1]; 03138 03139 if (cache->first_time) { 03140 copy_v2_v2(cache->last_rake, cache->mouse); 03141 } 03142 else if (dx*dx + dy*dy >= r*r) { 03143 cache->special_rotation = atan2(dx, dy); 03144 03145 cache->last_rake[0] = u*cache->last_rake[0] + v*cache->mouse[0]; 03146 cache->last_rake[1] = u*cache->last_rake[1] + v*cache->mouse[1]; 03147 } 03148 } 03149 03150 sculpt_update_brush_delta(sd, ob, brush); 03151 03152 if(brush->sculpt_tool == SCULPT_TOOL_ROTATE) { 03153 dx = cache->mouse[0] - cache->initial_mouse[0]; 03154 dy = cache->mouse[1] - cache->initial_mouse[1]; 03155 03156 cache->vertex_rotation = -atan2(dx, dy) * cache->bstrength; 03157 03158 sd->draw_anchored = 1; 03159 copy_v2_v2(sd->anchored_initial_mouse, cache->initial_mouse); 03160 copy_v3_v3(sd->anchored_location, cache->true_location); 03161 sd->anchored_size = cache->pixel_radius; 03162 } 03163 03164 sd->special_rotation = cache->special_rotation; 03165 } 03166 03167 static void sculpt_stroke_modifiers_check(bContext *C, Object *ob) 03168 { 03169 SculptSession *ss = ob->sculpt; 03170 03171 if(ss->modifiers_active) { 03172 Sculpt *sd = CTX_data_tool_settings(C)->sculpt; 03173 Brush *brush = paint_brush(&sd->paint); 03174 03175 sculpt_update_mesh_elements(CTX_data_scene(C), sd, ob, brush->sculpt_tool == SCULPT_TOOL_SMOOTH); 03176 } 03177 } 03178 03179 typedef struct { 03180 SculptSession *ss; 03181 float *ray_start, *ray_normal; 03182 int hit; 03183 float dist; 03184 int original; 03185 } SculptRaycastData; 03186 03187 static void sculpt_raycast_cb(PBVHNode *node, void *data_v, float* tmin) 03188 { 03189 if (BLI_pbvh_node_get_tmin(node) < *tmin) { 03190 SculptRaycastData *srd = data_v; 03191 float (*origco)[3]= NULL; 03192 03193 if(srd->original && srd->ss->cache) { 03194 /* intersect with coordinates from before we started stroke */ 03195 SculptUndoNode *unode= sculpt_undo_get_node(node); 03196 origco= (unode)? unode->co: NULL; 03197 } 03198 03199 if (BLI_pbvh_node_raycast(srd->ss->pbvh, node, origco, srd->ray_start, srd->ray_normal, &srd->dist)) { 03200 srd->hit = 1; 03201 *tmin = srd->dist; 03202 } 03203 } 03204 } 03205 03206 /* Do a raycast in the tree to find the 3d brush location 03207 (This allows us to ignore the GL depth buffer) 03208 Returns 0 if the ray doesn't hit the mesh, non-zero otherwise 03209 */ 03210 int sculpt_stroke_get_location(bContext *C, struct PaintStroke *stroke, float out[3], float mouse[2]) 03211 { 03212 ViewContext *vc = paint_stroke_view_context(stroke); 03213 Object *ob = vc->obact; 03214 SculptSession *ss= ob->sculpt; 03215 StrokeCache *cache= ss->cache; 03216 float ray_start[3], ray_end[3], ray_normal[3], dist; 03217 float obimat[4][4]; 03218 float mval[2]; 03219 SculptRaycastData srd; 03220 03221 mval[0] = mouse[0] - vc->ar->winrct.xmin; 03222 mval[1] = mouse[1] - vc->ar->winrct.ymin; 03223 03224 sculpt_stroke_modifiers_check(C, ob); 03225 03226 ED_view3d_win_to_segment_clip(vc->ar, vc->v3d, mval, ray_start, ray_end); 03227 03228 invert_m4_m4(obimat, ob->obmat); 03229 mul_m4_v3(obimat, ray_start); 03230 mul_m4_v3(obimat, ray_end); 03231 03232 sub_v3_v3v3(ray_normal, ray_end, ray_start); 03233 dist= normalize_v3(ray_normal); 03234 03235 srd.ss = vc->obact->sculpt; 03236 srd.ray_start = ray_start; 03237 srd.ray_normal = ray_normal; 03238 srd.dist = dist; 03239 srd.hit = 0; 03240 srd.original = (cache)? cache->original: 0; 03241 BLI_pbvh_raycast(ss->pbvh, sculpt_raycast_cb, &srd, 03242 ray_start, ray_normal, srd.original); 03243 03244 copy_v3_v3(out, ray_normal); 03245 mul_v3_fl(out, srd.dist); 03246 add_v3_v3(out, ray_start); 03247 03248 return srd.hit; 03249 } 03250 03251 static void sculpt_brush_init_tex(const Scene *scene, Sculpt *sd, SculptSession *ss) 03252 { 03253 Brush *brush = paint_brush(&sd->paint); 03254 MTex *mtex= &brush->mtex; 03255 03256 /* init mtex nodes */ 03257 if(mtex->tex && mtex->tex->nodetree) 03258 ntreeTexBeginExecTree(mtex->tex->nodetree, 1); /* has internal flag to detect it only does it once */ 03259 03260 /* TODO: Shouldn't really have to do this at the start of every 03261 stroke, but sculpt would need some sort of notification when 03262 changes are made to the texture. */ 03263 sculpt_update_tex(scene, sd, ss); 03264 } 03265 03266 static int sculpt_brush_stroke_init(bContext *C, wmOperator *op) 03267 { 03268 Scene *scene= CTX_data_scene(C); 03269 Object *ob= CTX_data_active_object(C); 03270 Sculpt *sd = CTX_data_tool_settings(C)->sculpt; 03271 SculptSession *ss = CTX_data_active_object(C)->sculpt; 03272 Brush *brush = paint_brush(&sd->paint); 03273 int mode= RNA_enum_get(op->ptr, "mode"); 03274 int is_smooth= 0; 03275 03276 view3d_operator_needs_opengl(C); 03277 sculpt_brush_init_tex(scene, sd, ss); 03278 03279 is_smooth|= mode == BRUSH_STROKE_SMOOTH; 03280 is_smooth|= brush->sculpt_tool == SCULPT_TOOL_SMOOTH; 03281 03282 sculpt_update_mesh_elements(scene, sd, ob, is_smooth); 03283 03284 return 1; 03285 } 03286 03287 static void sculpt_restore_mesh(Sculpt *sd, SculptSession *ss) 03288 { 03289 Brush *brush = paint_brush(&sd->paint); 03290 03291 /* Restore the mesh before continuing with anchored stroke */ 03292 if((brush->flag & BRUSH_ANCHORED) || 03293 (brush->sculpt_tool == SCULPT_TOOL_GRAB && 03294 brush_use_size_pressure(ss->cache->vc->scene, brush)) || 03295 (brush->flag & BRUSH_RESTORE_MESH)) 03296 { 03297 StrokeCache *cache = ss->cache; 03298 int i; 03299 03300 PBVHNode **nodes; 03301 int n, totnode; 03302 03303 BLI_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode); 03304 03305 #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) 03306 for(n=0; n<totnode; n++) { 03307 SculptUndoNode *unode; 03308 03309 unode= sculpt_undo_get_node(nodes[n]); 03310 if(unode) { 03311 PBVHVertexIter vd; 03312 03313 BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { 03314 copy_v3_v3(vd.co, unode->co[vd.i]); 03315 if(vd.no) copy_v3_v3_short(vd.no, unode->no[vd.i]); 03316 else normal_short_to_float_v3(vd.fno, unode->no[vd.i]); 03317 03318 if(vd.mvert) vd.mvert->flag |= ME_VERT_PBVH_UPDATE; 03319 } 03320 BLI_pbvh_vertex_iter_end; 03321 03322 BLI_pbvh_node_mark_update(nodes[n]); 03323 } 03324 } 03325 03326 if(ss->face_normals) { 03327 float *fn = ss->face_normals; 03328 for(i = 0; i < ss->totface; ++i, fn += 3) 03329 copy_v3_v3(fn, cache->face_norms[i]); 03330 } 03331 03332 if(nodes) 03333 MEM_freeN(nodes); 03334 } 03335 } 03336 03337 static void sculpt_flush_update(bContext *C) 03338 { 03339 Object *ob = CTX_data_active_object(C); 03340 SculptSession *ss = ob->sculpt; 03341 ARegion *ar = CTX_wm_region(C); 03342 MultiresModifierData *mmd = ss->multires; 03343 03344 if(mmd) 03345 multires_mark_as_modified(ob); 03346 if(ob->derivedFinal) /* VBO no longer valid */ 03347 GPU_drawobject_free(ob->derivedFinal); 03348 03349 if(ss->modifiers_active) { 03350 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 03351 ED_region_tag_redraw(ar); 03352 } 03353 else { 03354 rcti r; 03355 03356 BLI_pbvh_update(ss->pbvh, PBVH_UpdateBB, NULL); 03357 if (sculpt_get_redraw_rect(ar, CTX_wm_region_view3d(C), ob, &r)) { 03358 if (ss->cache) 03359 ss->cache->previous_r= r; 03360 03361 r.xmin += ar->winrct.xmin + 1; 03362 r.xmax += ar->winrct.xmin - 1; 03363 r.ymin += ar->winrct.ymin + 1; 03364 r.ymax += ar->winrct.ymin - 1; 03365 03366 ss->partial_redraw = 1; 03367 ED_region_tag_redraw_partial(ar, &r); 03368 } 03369 } 03370 } 03371 03372 /* Returns whether the mouse/stylus is over the mesh (1) 03373 or over the background (0) */ 03374 static int over_mesh(bContext *C, struct wmOperator *op, float x, float y) 03375 { 03376 float mouse[2], co[3]; 03377 03378 mouse[0] = x; 03379 mouse[1] = y; 03380 03381 return sculpt_stroke_get_location(C, op->customdata, co, mouse); 03382 } 03383 03384 static int sculpt_stroke_test_start(bContext *C, struct wmOperator *op, 03385 wmEvent *event) 03386 { 03387 /* Don't start the stroke until mouse goes over the mesh. 03388 * note: event will only be null when re-executing the saved stroke. */ 03389 if(event==NULL || over_mesh(C, op, event->x, event->y)) { 03390 Object *ob = CTX_data_active_object(C); 03391 SculptSession *ss = ob->sculpt; 03392 Sculpt *sd = CTX_data_tool_settings(C)->sculpt; 03393 03394 ED_view3d_init_mats_rv3d(ob, CTX_wm_region_view3d(C)); 03395 03396 sculpt_update_cache_invariants(C, sd, ss, op, event); 03397 03398 sculpt_undo_push_begin(sculpt_tool_name(sd)); 03399 03400 #ifdef _OPENMP 03401 /* If using OpenMP then create a number of threads two times the 03402 number of processor cores. 03403 Justification: Empirically I've found that two threads per 03404 processor gives higher throughput. */ 03405 if (sd->flags & SCULPT_USE_OPENMP) { 03406 int num_procs; 03407 03408 num_procs = omp_get_num_procs(); 03409 omp_set_num_threads(2*num_procs); 03410 } 03411 #endif 03412 03413 return 1; 03414 } 03415 else 03416 return 0; 03417 } 03418 03419 static void sculpt_stroke_update_step(bContext *C, struct PaintStroke *stroke, PointerRNA *itemptr) 03420 { 03421 Sculpt *sd = CTX_data_tool_settings(C)->sculpt; 03422 Object *ob = CTX_data_active_object(C); 03423 SculptSession *ss = ob->sculpt; 03424 03425 sculpt_stroke_modifiers_check(C, ob); 03426 sculpt_update_cache_variants(C, sd, ob, stroke, itemptr); 03427 sculpt_restore_mesh(sd, ss); 03428 do_symmetrical_brush_actions(sd, ob); 03429 03430 /* Cleanup */ 03431 sculpt_flush_update(C); 03432 } 03433 03434 static void sculpt_brush_exit_tex(Sculpt *sd) 03435 { 03436 Brush *brush= paint_brush(&sd->paint); 03437 MTex *mtex= &brush->mtex; 03438 03439 if(mtex->tex && mtex->tex->nodetree) 03440 ntreeTexEndExecTree(mtex->tex->nodetree->execdata, 1); 03441 } 03442 03443 static void sculpt_stroke_done(bContext *C, struct PaintStroke *UNUSED(stroke)) 03444 { 03445 Object *ob= CTX_data_active_object(C); 03446 SculptSession *ss = ob->sculpt; 03447 Sculpt *sd = CTX_data_tool_settings(C)->sculpt; 03448 03449 // reset values used to draw brush after completing the stroke 03450 sd->draw_anchored= 0; 03451 sd->draw_pressure= 0; 03452 sd->special_rotation= 0; 03453 03454 /* Finished */ 03455 if(ss->cache) { 03456 Brush *brush= paint_brush(&sd->paint); 03457 brush->flag &= ~BRUSH_INVERTED; 03458 03459 sculpt_stroke_modifiers_check(C, ob); 03460 03461 /* Alt-Smooth */ 03462 if (ss->cache->alt_smooth) { 03463 Paint *p= &sd->paint; 03464 brush= (Brush *)find_id("BR", ss->cache->saved_active_brush_name); 03465 if(brush) { 03466 paint_brush_set(p, brush); 03467 } 03468 } 03469 03470 sculpt_cache_free(ss->cache); 03471 ss->cache = NULL; 03472 03473 sculpt_undo_push_end(); 03474 03475 BLI_pbvh_update(ss->pbvh, PBVH_UpdateOriginalBB, NULL); 03476 03477 /* optimization: if there is locked key and active modifiers present in */ 03478 /* the stack, keyblock is updating at each step. otherwise we could update */ 03479 /* keyblock only when stroke is finished */ 03480 if(ss->kb && !ss->modifiers_active) sculpt_update_keyblock(ob); 03481 03482 ss->partial_redraw = 0; 03483 03484 /* try to avoid calling this, only for e.g. linked duplicates now */ 03485 if(((Mesh*)ob->data)->id.us > 1) 03486 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 03487 03488 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); 03489 } 03490 03491 sculpt_brush_exit_tex(sd); 03492 } 03493 03494 static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, wmEvent *event) 03495 { 03496 struct PaintStroke *stroke; 03497 int ignore_background_click; 03498 03499 if(!sculpt_brush_stroke_init(C, op)) 03500 return OPERATOR_CANCELLED; 03501 03502 stroke = paint_stroke_new(C, sculpt_stroke_get_location, 03503 sculpt_stroke_test_start, 03504 sculpt_stroke_update_step, 03505 sculpt_stroke_done, event->type); 03506 03507 op->customdata = stroke; 03508 03509 /* For tablet rotation */ 03510 ignore_background_click = RNA_boolean_get(op->ptr, 03511 "ignore_background_click"); 03512 03513 if(ignore_background_click && !over_mesh(C, op, event->x, event->y)) { 03514 paint_stroke_free(stroke); 03515 return OPERATOR_PASS_THROUGH; 03516 } 03517 03518 /* add modal handler */ 03519 WM_event_add_modal_handler(C, op); 03520 03521 op->type->modal(C, op, event); 03522 03523 return OPERATOR_RUNNING_MODAL; 03524 } 03525 03526 static int sculpt_brush_stroke_exec(bContext *C, wmOperator *op) 03527 { 03528 if(!sculpt_brush_stroke_init(C, op)) 03529 return OPERATOR_CANCELLED; 03530 03531 op->customdata = paint_stroke_new(C, sculpt_stroke_get_location, sculpt_stroke_test_start, 03532 sculpt_stroke_update_step, sculpt_stroke_done, 0); 03533 03534 /* frees op->customdata */ 03535 paint_stroke_exec(C, op); 03536 03537 return OPERATOR_FINISHED; 03538 } 03539 03540 static int sculpt_brush_stroke_cancel(bContext *C, wmOperator *op) 03541 { 03542 Object *ob= CTX_data_active_object(C); 03543 SculptSession *ss = ob->sculpt; 03544 Sculpt *sd = CTX_data_tool_settings(C)->sculpt; 03545 03546 paint_stroke_cancel(C, op); 03547 03548 if(ss->cache) { 03549 sculpt_cache_free(ss->cache); 03550 ss->cache = NULL; 03551 } 03552 03553 sculpt_brush_exit_tex(sd); 03554 03555 return OPERATOR_CANCELLED; 03556 } 03557 03558 static void SCULPT_OT_brush_stroke(wmOperatorType *ot) 03559 { 03560 static EnumPropertyItem stroke_mode_items[] = { 03561 {BRUSH_STROKE_NORMAL, "NORMAL", 0, "Normal", "Apply brush normally"}, 03562 {BRUSH_STROKE_INVERT, "INVERT", 0, "Invert", "Invert action of brush for duration of stroke"}, 03563 {BRUSH_STROKE_SMOOTH, "SMOOTH", 0, "Smooth", "Switch brush to smooth mode for duration of stroke"}, 03564 {0} 03565 }; 03566 03567 /* identifiers */ 03568 ot->name= "Sculpt Mode"; 03569 ot->idname= "SCULPT_OT_brush_stroke"; 03570 03571 /* api callbacks */ 03572 ot->invoke= sculpt_brush_stroke_invoke; 03573 ot->modal= paint_stroke_modal; 03574 ot->exec= sculpt_brush_stroke_exec; 03575 ot->poll= sculpt_poll; 03576 ot->cancel= sculpt_brush_stroke_cancel; 03577 03578 /* flags (sculpt does own undo? (ton) */ 03579 ot->flag= OPTYPE_BLOCKING; 03580 03581 /* properties */ 03582 03583 RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, 03584 "Stroke", ""); 03585 03586 RNA_def_enum(ot->srna, "mode", stroke_mode_items, BRUSH_STROKE_NORMAL, 03587 "Sculpt Stroke Mode", 03588 "Action taken when a sculpt stroke is made"); 03589 03590 RNA_def_boolean(ot->srna, "ignore_background_click", 0, 03591 "Ignore Background Click", 03592 "Clicks on the background do not start the stroke"); 03593 } 03594 03595 /**** Reset the copy of the mesh that is being sculpted on (currently just for the layer brush) ****/ 03596 03597 static int sculpt_set_persistent_base(bContext *C, wmOperator *UNUSED(op)) 03598 { 03599 SculptSession *ss = CTX_data_active_object(C)->sculpt; 03600 03601 if(ss) { 03602 if(ss->layer_co) 03603 MEM_freeN(ss->layer_co); 03604 ss->layer_co = NULL; 03605 } 03606 03607 return OPERATOR_FINISHED; 03608 } 03609 03610 static void SCULPT_OT_set_persistent_base(wmOperatorType *ot) 03611 { 03612 /* identifiers */ 03613 ot->name= "Set Persistent Base"; 03614 ot->idname= "SCULPT_OT_set_persistent_base"; 03615 03616 /* api callbacks */ 03617 ot->exec= sculpt_set_persistent_base; 03618 ot->poll= sculpt_mode_poll; 03619 03620 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 03621 } 03622 03623 /**** Toggle operator for turning sculpt mode on or off ****/ 03624 03625 static void sculpt_init_session(Scene *scene, Object *ob) 03626 { 03627 ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session"); 03628 03629 sculpt_update_mesh_elements(scene, scene->toolsettings->sculpt, ob, 0); 03630 } 03631 03632 static int sculpt_toggle_mode(bContext *C, wmOperator *UNUSED(op)) 03633 { 03634 Scene *scene = CTX_data_scene(C); 03635 ToolSettings *ts = CTX_data_tool_settings(C); 03636 Object *ob = CTX_data_active_object(C); 03637 MultiresModifierData *mmd= sculpt_multires_active(scene, ob); 03638 int flush_recalc= 0; 03639 03640 /* multires in sculpt mode could have different from object mode subdivision level */ 03641 flush_recalc |= mmd && mmd->sculptlvl != mmd->lvl; 03642 /* if object has got active modifiers, it's dm could be different in sculpt mode */ 03643 flush_recalc |= sculpt_has_active_modifiers(scene, ob); 03644 03645 if(ob->mode & OB_MODE_SCULPT) { 03646 if(mmd) 03647 multires_force_update(ob); 03648 03649 if(flush_recalc) 03650 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 03651 03652 /* Leave sculptmode */ 03653 ob->mode &= ~OB_MODE_SCULPT; 03654 03655 free_sculptsession(ob); 03656 } 03657 else { 03658 /* Enter sculptmode */ 03659 ob->mode |= OB_MODE_SCULPT; 03660 03661 if(flush_recalc) 03662 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 03663 03664 /* Create persistent sculpt mode data */ 03665 if(!ts->sculpt) { 03666 ts->sculpt = MEM_callocN(sizeof(Sculpt), "sculpt mode data"); 03667 03668 /* Turn on X plane mirror symmetry by default */ 03669 ts->sculpt->flags |= SCULPT_SYMM_X; 03670 } 03671 03672 /* Create sculpt mode session data */ 03673 if(ob->sculpt) 03674 free_sculptsession(ob); 03675 03676 sculpt_init_session(scene, ob); 03677 03678 paint_init(&ts->sculpt->paint, PAINT_CURSOR_SCULPT); 03679 03680 paint_cursor_start(C, sculpt_poll); 03681 } 03682 03683 WM_event_add_notifier(C, NC_SCENE|ND_MODE, CTX_data_scene(C)); 03684 03685 return OPERATOR_FINISHED; 03686 } 03687 03688 static void SCULPT_OT_sculptmode_toggle(wmOperatorType *ot) 03689 { 03690 /* identifiers */ 03691 ot->name= "Sculpt Mode"; 03692 ot->idname= "SCULPT_OT_sculptmode_toggle"; 03693 03694 /* api callbacks */ 03695 ot->exec= sculpt_toggle_mode; 03696 ot->poll= ED_operator_object_active_editable_mesh; 03697 03698 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 03699 } 03700 03701 void ED_operatortypes_sculpt(void) 03702 { 03703 WM_operatortype_append(SCULPT_OT_brush_stroke); 03704 WM_operatortype_append(SCULPT_OT_sculptmode_toggle); 03705 WM_operatortype_append(SCULPT_OT_set_persistent_base); 03706 }