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