diff options
author | Campbell Barton <ideasman42@gmail.com> | 2017-10-06 13:25:33 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2017-10-06 13:25:33 +0300 |
commit | ea606a7847a316a82b365155f666b33e81ff4c2e (patch) | |
tree | d58158c83fd66000fbe9db0c45fa39b6fc02076e /source/blender/blenkernel | |
parent | d7d32ad45217736c677edd22906d980d03aeb175 (diff) | |
parent | 3df139c53062a141403ea9d359715ca3635c243c (diff) |
Merge branch 'master' into blender28
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_brush.h | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_pbvh.h | 18 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/brush.c | 16 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/colortools.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/image.c | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mball_tessellate.c | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh_evaluate.c | 11 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/pbvh.c | 286 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/pbvh_bmesh.c | 125 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/pbvh_intern.h | 18 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/scene.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/seqeffects.c | 96 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/softbody.c | 4 |
13 files changed, 470 insertions, 123 deletions
diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h index c6d4217780e..7c2873046d5 100644 --- a/source/blender/blenkernel/BKE_brush.h +++ b/source/blender/blenkernel/BKE_brush.h @@ -103,9 +103,11 @@ void BKE_brush_alpha_set(struct Scene *scene, struct Brush *brush, float alpha); float BKE_brush_weight_get(const struct Scene *scene, const struct Brush *brush); void BKE_brush_weight_set(const struct Scene *scene, struct Brush *brush, float value); -int BKE_brush_use_locked_size(const struct Scene *scene, const struct Brush *brush); -int BKE_brush_use_alpha_pressure(const struct Scene *scene, const struct Brush *brush); -int BKE_brush_use_size_pressure(const struct Scene *scene, const struct Brush *brush); +bool BKE_brush_use_locked_size(const struct Scene *scene, const struct Brush *brush); +bool BKE_brush_use_alpha_pressure(const struct Scene *scene, const struct Brush *brush); +bool BKE_brush_use_size_pressure(const struct Scene *scene, const struct Brush *brush); + +bool BKE_brush_sculpt_has_secondary_color(const struct Brush *brush); /* scale unprojected radius to reflect a change in the brush's 2D size */ void BKE_brush_scale_unprojected_radius( diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index 8412127c701..9aea5dc95a0 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -60,6 +60,8 @@ typedef bool (*BKE_pbvh_SearchCallback)(PBVHNode *node, void *data); typedef void (*BKE_pbvh_HitCallback)(PBVHNode *node, void *data); typedef void (*BKE_pbvh_HitOccludedCallback)(PBVHNode *node, void *data, float *tmin); +typedef void (*BKE_pbvh_SearchNearestCallback)(PBVHNode *node, void *data, float *tmin); + /* Building */ PBVH *BKE_pbvh_new(void); @@ -102,12 +104,12 @@ void BKE_pbvh_raycast( bool BKE_pbvh_node_raycast( PBVH *bvh, PBVHNode *node, float (*origco)[3], bool use_origco, const float ray_start[3], const float ray_normal[3], - float *dist); + float *depth); bool BKE_pbvh_bmesh_node_raycast_detail( PBVHNode *node, const float ray_start[3], const float ray_normal[3], - float *dist, float *r_detail); + float *depth, float *r_detail); /* for orthographic cameras, project the far away ray segment points to the root node so * we can have better precision. */ @@ -115,6 +117,16 @@ void BKE_pbvh_raycast_project_ray_root( PBVH *bvh, bool original, float ray_start[3], float ray_end[3], float ray_normal[3]); +void BKE_pbvh_find_nearest_to_ray( + PBVH *bvh, BKE_pbvh_HitOccludedCallback cb, void *data, + const float ray_start[3], const float ray_normal[3], + bool original); + +bool BKE_pbvh_node_find_nearest_to_ray( + PBVH *bvh, PBVHNode *node, float (*origco)[3], bool use_origco, + const float ray_start[3], const float ray_normal[3], + float *depth, float *dist_sq); + /* Drawing */ void BKE_pbvh_node_draw(PBVHNode *node, void *data); @@ -160,7 +172,7 @@ typedef enum { bool BKE_pbvh_bmesh_update_topology( PBVH *bvh, PBVHTopologyUpdateMode mode, const float center[3], const float view_normal[3], - float radius); + float radius, const bool use_frontface, const bool use_projected); /* Node Access */ diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 4a54ab26373..aeaead578a1 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -821,7 +821,7 @@ int BKE_brush_size_get(const Scene *scene, const Brush *brush) return size; } -int BKE_brush_use_locked_size(const Scene *scene, const Brush *brush) +bool BKE_brush_use_locked_size(const Scene *scene, const Brush *brush) { const short us_flag = scene->toolsettings->unified_paint_settings.flag; @@ -830,7 +830,7 @@ int BKE_brush_use_locked_size(const Scene *scene, const Brush *brush) (brush->flag & BRUSH_LOCK_SIZE); } -int BKE_brush_use_size_pressure(const Scene *scene, const Brush *brush) +bool BKE_brush_use_size_pressure(const Scene *scene, const Brush *brush) { const short us_flag = scene->toolsettings->unified_paint_settings.flag; @@ -839,7 +839,7 @@ int BKE_brush_use_size_pressure(const Scene *scene, const Brush *brush) (brush->flag & BRUSH_SIZE_PRESSURE); } -int BKE_brush_use_alpha_pressure(const Scene *scene, const Brush *brush) +bool BKE_brush_use_alpha_pressure(const Scene *scene, const Brush *brush) { const short us_flag = scene->toolsettings->unified_paint_settings.flag; @@ -848,6 +848,16 @@ int BKE_brush_use_alpha_pressure(const Scene *scene, const Brush *brush) (brush->flag & BRUSH_ALPHA_PRESSURE); } +bool BKE_brush_sculpt_has_secondary_color(const Brush *brush) +{ + return ELEM( + brush->sculpt_tool, SCULPT_TOOL_BLOB, SCULPT_TOOL_DRAW, + SCULPT_TOOL_INFLATE, SCULPT_TOOL_CLAY, SCULPT_TOOL_CLAY_STRIPS, + SCULPT_TOOL_PINCH, SCULPT_TOOL_CREASE, SCULPT_TOOL_LAYER, + SCULPT_TOOL_FLATTEN, SCULPT_TOOL_FILL, SCULPT_TOOL_SCRAPE, + SCULPT_TOOL_MASK); +} + void BKE_brush_unprojected_radius_set(Scene *scene, Brush *brush, float unprojected_radius) { UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index ee0f904c3a6..310255a15c1 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -1380,7 +1380,7 @@ void scopes_update(Scopes *scopes, ImBuf *ibuf, const ColorManagedViewSettings * /* Keep number of threads in sync with the merge parts below. */ ScopesUpdateData data = { - .scopes = scopes, . ibuf = ibuf, + .scopes = scopes, .ibuf = ibuf, .cm_processor = cm_processor, .display_buffer = display_buffer, .ycc_mode = ycc_mode, .bin_lum = bin_lum, .bin_r = bin_r, .bin_g = bin_g, .bin_b = bin_b, .bin_a = bin_a, }; diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index f826f655309..33a690b32c6 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -1455,8 +1455,7 @@ static bool do_add_image_extension(char *string, const char imtype, const ImageF if (extension) { /* prefer this in many cases to avoid .png.tga, but in certain cases it breaks */ /* remove any other known image extension */ - if (BLI_testextensie_array(string, imb_ext_image)) - { + if (BLI_testextensie_array(string, imb_ext_image)) { return BLI_replace_extension(string, FILE_MAX, extension); } else { diff --git a/source/blender/blenkernel/intern/mball_tessellate.c b/source/blender/blenkernel/intern/mball_tessellate.c index 1d9c580d45b..d8e3df239df 100644 --- a/source/blender/blenkernel/intern/mball_tessellate.c +++ b/source/blender/blenkernel/intern/mball_tessellate.c @@ -424,13 +424,13 @@ static void make_face(PROCESS *process, int i1, int i2, int i3, int i4) #ifdef USE_ACCUM_NORMAL if (i4 == 0) { normal_tri_v3(n, process->co[i1], process->co[i2], process->co[i3]); - accumulate_vertex_normals( + accumulate_vertex_normals_v3( process->no[i1], process->no[i2], process->no[i3], NULL, n, process->co[i1], process->co[i2], process->co[i3], NULL); } else { normal_quad_v3(n, process->co[i1], process->co[i2], process->co[i3], process->co[i4]); - accumulate_vertex_normals( + accumulate_vertex_normals_v3( process->no[i1], process->no[i2], process->no[i3], process->no[i4], n, process->co[i1], process->co[i2], process->co[i3], process->co[i4]); } diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c index 654a25cbb3d..4a1952c798b 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.c +++ b/source/blender/blenkernel/intern/mesh_evaluate.c @@ -225,7 +225,7 @@ static void mesh_calc_normals_poly_accum_task_cb(void *userdata, const int pidx) } /* accumulate angle weighted face normal */ - /* inline version of #accumulate_vertex_normals_poly */ + /* inline version of #accumulate_vertex_normals_poly_v3 */ { const float *prev_edge = edgevecbuf[nverts - 1]; @@ -334,8 +334,9 @@ void BKE_mesh_calc_normals_tessface( else normal_tri_v3(f_no, mverts[mf->v1].co, mverts[mf->v2].co, mverts[mf->v3].co); - accumulate_vertex_normals(tnorms[mf->v1], tnorms[mf->v2], tnorms[mf->v3], n4, - f_no, mverts[mf->v1].co, mverts[mf->v2].co, mverts[mf->v3].co, c4); + accumulate_vertex_normals_v3( + tnorms[mf->v1], tnorms[mf->v2], tnorms[mf->v3], n4, + f_no, mverts[mf->v1].co, mverts[mf->v2].co, mverts[mf->v3].co, c4); } /* following Mesh convention; we use vertex coordinate itself for normal in this case */ @@ -379,7 +380,7 @@ void BKE_mesh_calc_normals_looptri( f_no, mverts[vtri[0]].co, mverts[vtri[1]].co, mverts[vtri[2]].co); - accumulate_vertex_normals_tri( + accumulate_vertex_normals_tri_v3( tnorms[vtri[0]], tnorms[vtri[1]], tnorms[vtri[2]], f_no, mverts[vtri[0]].co, mverts[vtri[1]].co, mverts[vtri[2]].co); } @@ -845,7 +846,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli // printf("\thandling edge %d / loop %d\n", mlfan_curr->e, mlfan_curr_index); { - /* Code similar to accumulate_vertex_normals_poly. */ + /* Code similar to accumulate_vertex_normals_poly_v3. */ /* Calculate angle between the two poly edges incident on this vertex. */ const float fac = saacos(dot_v3v3(vec_curr, vec_prev)); /* Accumulate */ diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index a90a5e2a10b..6fc89eb778a 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -608,7 +608,8 @@ void BKE_pbvh_build_grids(PBVH *bvh, CCGElem **grids, MEM_freeN(prim_bbc); } -void BKE_pbvh_set_ccgdm(PBVH *bvh, CCGDerivedMesh *ccgdm) { +void BKE_pbvh_set_ccgdm(PBVH *bvh, CCGDerivedMesh *ccgdm) +{ bvh->ccgdm = ccgdm; } @@ -1336,7 +1337,8 @@ void BKE_pbvh_get_grid_key(const PBVH *bvh, CCGKey *key) *key = bvh->gridkey; } -CCGDerivedMesh *BKE_pbvh_get_ccgdm(const PBVH *bvh) { +CCGDerivedMesh *BKE_pbvh_get_ccgdm(const PBVH *bvh) +{ return bvh->ccgdm; } @@ -1539,14 +1541,16 @@ void BKE_pbvh_raycast( bool ray_face_intersection_quad( const float ray_start[3], const float ray_normal[3], const float t0[3], const float t1[3], const float t2[3], const float t3[3], - float *dist) + float *depth) { - float dist_test; + float depth_test; - if ((isect_ray_tri_epsilon_v3(ray_start, ray_normal, t0, t1, t2, &dist_test, NULL, 0.1f) && (dist_test < *dist)) || - (isect_ray_tri_epsilon_v3(ray_start, ray_normal, t0, t2, t3, &dist_test, NULL, 0.1f) && (dist_test < *dist))) + if ((isect_ray_tri_epsilon_v3( + ray_start, ray_normal, t0, t1, t2, &depth_test, NULL, 0.1f) && (depth_test < *depth)) || + (isect_ray_tri_epsilon_v3( + ray_start, ray_normal, t0, t2, t3, &depth_test, NULL, 0.1f) && (depth_test < *depth))) { - *dist = dist_test; + *depth = depth_test; return true; } else { @@ -1557,12 +1561,82 @@ bool ray_face_intersection_quad( bool ray_face_intersection_tri( const float ray_start[3], const float ray_normal[3], const float t0[3], const float t1[3], const float t2[3], - float *dist) + float *depth) +{ + float depth_test; + + if ((isect_ray_tri_epsilon_v3( + ray_start, ray_normal, t0, t1, t2, &depth_test, NULL, 0.1f) && (depth_test < *depth))) + { + *depth = depth_test; + return true; + } + else { + return false; + } +} + +/* Take advantage of the fact we know this wont be an intersection. + * Just handle ray-tri edges. */ +static float dist_squared_ray_to_tri_v3_fast( + const float ray_origin[3], const float ray_direction[3], + const float v0[3], const float v1[3], const float v2[3], + float r_point[3], float *r_depth) +{ + const float *tri[3] = {v0, v1, v2}; + float dist_sq_best = FLT_MAX; + for (int i = 0, j = 2; i < 3; j = i++) { + float point_test[3], depth_test = FLT_MAX; + const float dist_sq_test = dist_squared_ray_to_seg_v3( + ray_origin, ray_direction, tri[i], tri[j], point_test, &depth_test); + if (dist_sq_test < dist_sq_best || i == 0) { + copy_v3_v3(r_point, point_test); + *r_depth = depth_test; + dist_sq_best = dist_sq_test; + } + } + return dist_sq_best; +} + +bool ray_face_nearest_quad( + const float ray_start[3], const float ray_normal[3], + const float t0[3], const float t1[3], const float t2[3], const float t3[3], + float *depth, float *dist_sq) +{ + float dist_sq_test; + float co[3], depth_test; + + if (((dist_sq_test = dist_squared_ray_to_tri_v3_fast( + ray_start, ray_normal, t0, t1, t2, co, &depth_test)) < *dist_sq)) + { + *dist_sq = dist_sq_test; + *depth = depth_test; + if (((dist_sq_test = dist_squared_ray_to_tri_v3_fast( + ray_start, ray_normal, t0, t2, t3, co, &depth_test)) < *dist_sq)) + { + *dist_sq = dist_sq_test; + *depth = depth_test; + } + return true; + } + else { + return false; + } +} + +bool ray_face_nearest_tri( + const float ray_start[3], const float ray_normal[3], + const float t0[3], const float t1[3], const float t2[3], + float *depth, float *dist_sq) { - float dist_test; + float dist_sq_test; + float co[3], depth_test; - if ((isect_ray_tri_epsilon_v3(ray_start, ray_normal, t0, t1, t2, &dist_test, NULL, 0.1f) && (dist_test < *dist))) { - *dist = dist_test; + if (((dist_sq_test = dist_squared_ray_to_tri_v3_fast( + ray_start, ray_normal, t0, t1, t2, co, &depth_test)) < *dist_sq)) + { + *dist_sq = dist_sq_test; + *depth = depth_test; return true; } else { @@ -1574,7 +1648,7 @@ static bool pbvh_faces_node_raycast( PBVH *bvh, const PBVHNode *node, float (*origco)[3], const float ray_start[3], const float ray_normal[3], - float *dist) + float *depth) { const MVert *vert = bvh->verts; const MLoop *mloop = bvh->mloop; @@ -1596,7 +1670,7 @@ static bool pbvh_faces_node_raycast( origco[face_verts[0]], origco[face_verts[1]], origco[face_verts[2]], - dist); + depth); } else { /* intersect with current coordinates */ @@ -1605,7 +1679,7 @@ static bool pbvh_faces_node_raycast( vert[mloop[lt->tri[0]].v].co, vert[mloop[lt->tri[1]].v].co, vert[mloop[lt->tri[2]].v].co, - dist); + depth); } } @@ -1616,7 +1690,7 @@ static bool pbvh_grids_node_raycast( PBVH *bvh, PBVHNode *node, float (*origco)[3], const float ray_start[3], const float ray_normal[3], - float *dist) + float *depth) { const int totgrid = node->totprim; const int gridsize = bvh->gridkey.grid_size; @@ -1646,7 +1720,7 @@ static bool pbvh_grids_node_raycast( origco[y * gridsize + x + 1], origco[(y + 1) * gridsize + x + 1], origco[(y + 1) * gridsize + x], - dist); + depth); } else { hit |= ray_face_intersection_quad( @@ -1655,7 +1729,7 @@ static bool pbvh_grids_node_raycast( CCG_grid_elem_co(&bvh->gridkey, grid, x + 1, y), CCG_grid_elem_co(&bvh->gridkey, grid, x + 1, y + 1), CCG_grid_elem_co(&bvh->gridkey, grid, x, y + 1), - dist); + depth); } } } @@ -1670,7 +1744,7 @@ static bool pbvh_grids_node_raycast( bool BKE_pbvh_node_raycast( PBVH *bvh, PBVHNode *node, float (*origco)[3], bool use_origco, const float ray_start[3], const float ray_normal[3], - float *dist) + float *depth) { bool hit = false; @@ -1681,16 +1755,16 @@ bool BKE_pbvh_node_raycast( case PBVH_FACES: hit |= pbvh_faces_node_raycast( bvh, node, origco, - ray_start, ray_normal, dist); + ray_start, ray_normal, depth); break; case PBVH_GRIDS: hit |= pbvh_grids_node_raycast( bvh, node, origco, - ray_start, ray_normal, dist); + ray_start, ray_normal, depth); break; case PBVH_BMESH: hit = pbvh_bmesh_node_raycast( - node, ray_start, ray_normal, dist, use_origco); + node, ray_start, ray_normal, depth, use_origco); break; } @@ -1741,6 +1815,176 @@ void BKE_pbvh_raycast_project_ray_root( } } +/* -------------------------------------------------------------------- */ + +typedef struct { + struct DistRayAABB_Precalc dist_ray_to_aabb_precalc; + bool original; +} FindNearestRayData; + +static bool nearest_to_ray_aabb_dist_sq(PBVHNode *node, void *data_v) +{ + FindNearestRayData *rcd = data_v; + const float *bb_min, *bb_max; + + if (rcd->original) { + /* BKE_pbvh_node_get_original_BB */ + bb_min = node->orig_vb.bmin; + bb_max = node->orig_vb.bmax; + } + else { + /* BKE_pbvh_node_get_BB */ + bb_min = node->vb.bmin; + bb_max = node->vb.bmax; + } + + float co_dummy[3], depth; + node->tmin = dist_squared_ray_to_aabb_v3(&rcd->dist_ray_to_aabb_precalc, bb_min, bb_max, co_dummy, &depth); + /* Ideally we would skip distances outside the range. */ + return depth > 0.0f; +} + +void BKE_pbvh_find_nearest_to_ray( + PBVH *bvh, BKE_pbvh_SearchNearestCallback cb, void *data, + const float ray_start[3], const float ray_normal[3], + bool original) +{ + FindNearestRayData ncd; + + dist_squared_ray_to_aabb_v3_precalc(&ncd.dist_ray_to_aabb_precalc, ray_start, ray_normal); + ncd.original = original; + + BKE_pbvh_search_callback_occluded(bvh, nearest_to_ray_aabb_dist_sq, &ncd, cb, data); +} + + +static bool pbvh_faces_node_nearest_to_ray( + PBVH *bvh, const PBVHNode *node, + float (*origco)[3], + const float ray_start[3], const float ray_normal[3], + float *depth, float *dist_sq) +{ + const MVert *vert = bvh->verts; + const MLoop *mloop = bvh->mloop; + const int *faces = node->prim_indices; + int i, totface = node->totprim; + bool hit = false; + + for (i = 0; i < totface; ++i) { + const MLoopTri *lt = &bvh->looptri[faces[i]]; + const int *face_verts = node->face_vert_indices[i]; + + if (paint_is_face_hidden(lt, vert, mloop)) + continue; + + if (origco) { + /* intersect with backuped original coordinates */ + hit |= ray_face_nearest_tri( + ray_start, ray_normal, + origco[face_verts[0]], + origco[face_verts[1]], + origco[face_verts[2]], + depth, dist_sq); + } + else { + /* intersect with current coordinates */ + hit |= ray_face_nearest_tri( + ray_start, ray_normal, + vert[mloop[lt->tri[0]].v].co, + vert[mloop[lt->tri[1]].v].co, + vert[mloop[lt->tri[2]].v].co, + depth, dist_sq); + } + } + + return hit; +} + +static bool pbvh_grids_node_nearest_to_ray( + PBVH *bvh, PBVHNode *node, + float (*origco)[3], + const float ray_start[3], const float ray_normal[3], + float *depth, float *dist_sq) +{ + const int totgrid = node->totprim; + const int gridsize = bvh->gridkey.grid_size; + bool hit = false; + + for (int i = 0; i < totgrid; ++i) { + CCGElem *grid = bvh->grids[node->prim_indices[i]]; + BLI_bitmap *gh; + + if (!grid) + continue; + + gh = bvh->grid_hidden[node->prim_indices[i]]; + + for (int y = 0; y < gridsize - 1; ++y) { + for (int x = 0; x < gridsize - 1; ++x) { + /* check if grid face is hidden */ + if (gh) { + if (paint_is_grid_face_hidden(gh, gridsize, x, y)) + continue; + } + + if (origco) { + hit |= ray_face_nearest_quad( + ray_start, ray_normal, + origco[y * gridsize + x], + origco[y * gridsize + x + 1], + origco[(y + 1) * gridsize + x + 1], + origco[(y + 1) * gridsize + x], + depth, dist_sq); + } + else { + hit |= ray_face_nearest_quad( + ray_start, ray_normal, + CCG_grid_elem_co(&bvh->gridkey, grid, x, y), + CCG_grid_elem_co(&bvh->gridkey, grid, x + 1, y), + CCG_grid_elem_co(&bvh->gridkey, grid, x + 1, y + 1), + CCG_grid_elem_co(&bvh->gridkey, grid, x, y + 1), + depth, dist_sq); + } + } + } + + if (origco) + origco += gridsize * gridsize; + } + + return hit; +} + +bool BKE_pbvh_node_find_nearest_to_ray( + PBVH *bvh, PBVHNode *node, float (*origco)[3], bool use_origco, + const float ray_start[3], const float ray_normal[3], + float *depth, float *dist_sq) +{ + bool hit = false; + + if (node->flag & PBVH_FullyHidden) + return false; + + switch (bvh->type) { + case PBVH_FACES: + hit |= pbvh_faces_node_nearest_to_ray( + bvh, node, origco, + ray_start, ray_normal, depth, dist_sq); + break; + case PBVH_GRIDS: + hit |= pbvh_grids_node_nearest_to_ray( + bvh, node, origco, + ray_start, ray_normal, depth, dist_sq); + break; + case PBVH_BMESH: + hit = pbvh_bmesh_node_nearest_to_ray( + node, ray_start, ray_normal, depth, dist_sq, use_origco); + break; + } + + return hit; +} + typedef struct { DMSetMaterial setMaterial; bool wireframe; diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c index c5e49883dc6..187891e7210 100644 --- a/source/blender/blenkernel/intern/pbvh_bmesh.c +++ b/source/blender/blenkernel/intern/pbvh_bmesh.c @@ -718,20 +718,24 @@ static void pbvh_bmesh_node_drop_orig(PBVHNode *node) /****************************** EdgeQueue *****************************/ -typedef struct { +struct EdgeQueue; + +typedef struct EdgeQueue { Heap *heap; const float *center; + float center_proj[3]; /* for when we use projected coords. */ float radius_squared; float limit_len_squared; #ifdef USE_EDGEQUEUE_EVEN_SUBDIV float limit_len; #endif -#ifdef USE_EDGEQUEUE_FRONTFACE + bool (*edge_queue_tri_in_range)(const struct EdgeQueue *q, BMFace *f); + const float *view_normal; +#ifdef USE_EDGEQUEUE_FRONTFACE unsigned int use_view_normal : 1; #endif - } EdgeQueue; typedef struct { @@ -785,7 +789,6 @@ static bool edge_queue_tri_in_sphere(const EdgeQueue *q, BMFace *f) float c[3]; /* Get closest point in triangle to sphere center */ - // BM_iter_as_array(NULL, BM_VERTS_OF_FACE, f, (void **)v_tri, 3); BM_face_as_array_vert_tri(f, v_tri); closest_on_tri_to_point_v3(c, q->center, v_tri[0]->co, v_tri[1]->co, v_tri[2]->co); @@ -794,6 +797,25 @@ static bool edge_queue_tri_in_sphere(const EdgeQueue *q, BMFace *f) return len_squared_v3v3(q->center, c) <= q->radius_squared; } +static bool edge_queue_tri_in_circle(const EdgeQueue *q, BMFace *f) +{ + BMVert *v_tri[3]; + float c[3]; + float tri_proj[3][3]; + + /* Get closest point in triangle to sphere center */ + BM_face_as_array_vert_tri(f, v_tri); + + project_plane_normalized_v3_v3v3(tri_proj[0], v_tri[0]->co, q->view_normal); + project_plane_normalized_v3_v3v3(tri_proj[1], v_tri[1]->co, q->view_normal); + project_plane_normalized_v3_v3v3(tri_proj[2], v_tri[2]->co, q->view_normal); + + closest_on_tri_to_point_v3(c, q->center_proj, tri_proj[0], tri_proj[1], tri_proj[2]); + + /* Check if triangle intersects the sphere */ + return len_squared_v3v3(q->center_proj, c) <= q->radius_squared; +} + /* Return true if the vertex mask is less than 1.0, false otherwise */ static bool check_mask(EdgeQueueContext *eq_ctx, BMVert *v) { @@ -929,7 +951,7 @@ static void long_edge_queue_face_add( } #endif - if (edge_queue_tri_in_sphere(eq_ctx->q, f)) { + if (eq_ctx->q->edge_queue_tri_in_range(eq_ctx->q, f)) { /* Check each edge of the face */ BMLoop *l_first = BM_FACE_FIRST_LOOP(f); BMLoop *l_iter = l_first; @@ -960,7 +982,7 @@ static void short_edge_queue_face_add( } #endif - if (edge_queue_tri_in_sphere(eq_ctx->q, f)) { + if (eq_ctx->q->edge_queue_tri_in_range(eq_ctx->q, f)) { BMLoop *l_iter; BMLoop *l_first; @@ -984,7 +1006,7 @@ static void short_edge_queue_face_add( static void long_edge_queue_create( EdgeQueueContext *eq_ctx, PBVH *bvh, const float center[3], const float view_normal[3], - float radius) + float radius, const bool use_frontface, const bool use_projected) { eq_ctx->q->heap = BLI_heap_new(); eq_ctx->q->center = center; @@ -994,13 +1016,22 @@ static void long_edge_queue_create( eq_ctx->q->limit_len = bvh->bm_max_edge_len; #endif -#ifdef USE_EDGEQUEUE_FRONTFACE eq_ctx->q->view_normal = view_normal; - eq_ctx->q->use_view_normal = (view_normal != NULL); + +#ifdef USE_EDGEQUEUE_FRONTFACE + eq_ctx->q->use_view_normal = use_frontface; #else - UNUSED_VARS(view_normal); + UNUSED_VARS(use_frontface); #endif + if (use_projected) { + eq_ctx->q->edge_queue_tri_in_range = edge_queue_tri_in_circle; + project_plane_normalized_v3_v3v3(eq_ctx->q->center_proj, center, view_normal); + } + else { + eq_ctx->q->edge_queue_tri_in_range = edge_queue_tri_in_sphere; + } + #ifdef USE_EDGEQUEUE_TAG_VERIFY pbvh_bmesh_edge_tag_verify(bvh); #endif @@ -1037,7 +1068,7 @@ static void long_edge_queue_create( static void short_edge_queue_create( EdgeQueueContext *eq_ctx, PBVH *bvh, const float center[3], const float view_normal[3], - float radius) + float radius, const bool use_frontface, const bool use_projected) { eq_ctx->q->heap = BLI_heap_new(); eq_ctx->q->center = center; @@ -1047,13 +1078,22 @@ static void short_edge_queue_create( eq_ctx->q->limit_len = bvh->bm_min_edge_len; #endif -#ifdef USE_EDGEQUEUE_FRONTFACE eq_ctx->q->view_normal = view_normal; - eq_ctx->q->use_view_normal = (view_normal != NULL); + +#ifdef USE_EDGEQUEUE_FRONTFACE + eq_ctx->q->use_view_normal = use_frontface; #else - UNUSED_VARS(view_normal); + UNUSED_VARS(use_frontface); #endif + if (use_projected) { + eq_ctx->q->edge_queue_tri_in_range = edge_queue_tri_in_circle; + project_plane_normalized_v3_v3v3(eq_ctx->q->center_proj, center, view_normal); + } + else { + eq_ctx->q->edge_queue_tri_in_range = edge_queue_tri_in_sphere; + } + for (int n = 0; n < bvh->totnode; n++) { PBVHNode *node = &bvh->nodes[n]; @@ -1466,7 +1506,7 @@ static bool pbvh_bmesh_collapse_short_edges( bool pbvh_bmesh_node_raycast( PBVHNode *node, const float ray_start[3], - const float ray_normal[3], float *dist, + const float ray_normal[3], float *depth, bool use_original) { bool hit = false; @@ -1479,7 +1519,7 @@ bool pbvh_bmesh_node_raycast( node->bm_orco[t[0]], node->bm_orco[t[1]], node->bm_orco[t[2]], - dist); + depth); } } else { @@ -1498,7 +1538,7 @@ bool pbvh_bmesh_node_raycast( v_tri[0]->co, v_tri[1]->co, v_tri[2]->co, - dist); + depth); } } } @@ -1509,7 +1549,7 @@ bool pbvh_bmesh_node_raycast( bool BKE_pbvh_bmesh_node_raycast_detail( PBVHNode *node, const float ray_start[3], const float ray_normal[3], - float *dist, float *r_detail) + float *depth, float *r_detail) { if (node->flag & PBVH_FullyHidden) return 0; @@ -1531,7 +1571,7 @@ bool BKE_pbvh_bmesh_node_raycast_detail( v_tri[0]->co, v_tri[1]->co, v_tri[2]->co, - dist); + depth); if (hit_local) { f_hit = f; @@ -1554,6 +1594,47 @@ bool BKE_pbvh_bmesh_node_raycast_detail( return hit; } +bool pbvh_bmesh_node_nearest_to_ray( + PBVHNode *node, const float ray_start[3], + const float ray_normal[3], float *depth, float *dist_sq, + bool use_original) +{ + bool hit = false; + + if (use_original && node->bm_tot_ortri) { + for (int i = 0; i < node->bm_tot_ortri; i++) { + const int *t = node->bm_ortri[i]; + hit |= ray_face_nearest_tri( + ray_start, ray_normal, + node->bm_orco[t[0]], + node->bm_orco[t[1]], + node->bm_orco[t[2]], + depth, dist_sq); + } + } + else { + GSetIterator gs_iter; + + GSET_ITER (gs_iter, node->bm_faces) { + BMFace *f = BLI_gsetIterator_getKey(&gs_iter); + + BLI_assert(f->len == 3); + if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) { + BMVert *v_tri[3]; + + BM_face_as_array_vert_tri(f, v_tri); + hit |= ray_face_nearest_tri( + ray_start, ray_normal, + v_tri[0]->co, + v_tri[1]->co, + v_tri[2]->co, + depth, dist_sq); + } + } + } + + return hit; +} void pbvh_bmesh_normals_update(PBVHNode **nodes, int totnode) { @@ -1854,7 +1935,7 @@ void BKE_pbvh_build_bmesh( bool BKE_pbvh_bmesh_update_topology( PBVH *bvh, PBVHTopologyUpdateMode mode, const float center[3], const float view_normal[3], - float radius) + float radius, const bool use_frontface, const bool use_projected) { /* 2 is enough for edge faces - manifold edge */ BLI_buffer_declare_static(BMLoop *, edge_loops, BLI_BUFFER_NOP, 2); @@ -1877,7 +1958,7 @@ bool BKE_pbvh_bmesh_update_topology( cd_vert_mask_offset, cd_vert_node_offset, cd_face_node_offset, }; - short_edge_queue_create(&eq_ctx, bvh, center, view_normal, radius); + short_edge_queue_create(&eq_ctx, bvh, center, view_normal, radius, use_frontface, use_projected); modified |= pbvh_bmesh_collapse_short_edges( &eq_ctx, bvh, &deleted_faces); BLI_heap_free(q.heap, NULL); @@ -1892,7 +1973,7 @@ bool BKE_pbvh_bmesh_update_topology( cd_vert_mask_offset, cd_vert_node_offset, cd_face_node_offset, }; - long_edge_queue_create(&eq_ctx, bvh, center, view_normal, radius); + long_edge_queue_create(&eq_ctx, bvh, center, view_normal, radius, use_frontface, use_projected); modified |= pbvh_bmesh_subdivide_long_edges( &eq_ctx, bvh, &edge_loops); BLI_heap_free(q.heap, NULL); diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h index 01057318568..e05a3068682 100644 --- a/source/blender/blenkernel/intern/pbvh_intern.h +++ b/source/blender/blenkernel/intern/pbvh_intern.h @@ -185,11 +185,21 @@ void pbvh_grow_nodes(PBVH *bvh, int totnode); bool ray_face_intersection_quad( const float ray_start[3], const float ray_normal[3], const float *t0, const float *t1, const float *t2, const float *t3, - float *r_dist); + float *depth); bool ray_face_intersection_tri( const float ray_start[3], const float ray_normal[3], const float *t0, const float *t1, const float *t2, - float *r_dist); + float *depth); + +bool ray_face_nearest_quad( + const float ray_start[3], const float ray_normal[3], + const float *t0, const float *t1, const float *t2, const float *t3, + float *r_depth, float *r_dist_sq); +bool ray_face_nearest_tri( + const float ray_start[3], const float ray_normal[3], + const float *t0, const float *t1, const float *t2, + float *r_depth, float *r_dist_sq); + void pbvh_update_BB_redraw(PBVH *bvh, PBVHNode **nodes, int totnode, int flag); /* pbvh_bmesh.c */ @@ -197,6 +207,10 @@ bool pbvh_bmesh_node_raycast( PBVHNode *node, const float ray_start[3], const float ray_normal[3], float *dist, bool use_original); +bool pbvh_bmesh_node_nearest_to_ray( + PBVHNode *node, const float ray_start[3], + const float ray_normal[3], float *depth, float *dist_sq, + bool use_original); void pbvh_bmesh_normals_update(PBVHNode **nodes, int totnode); diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 1b0e09afcb5..fca0ff92a45 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -2019,7 +2019,7 @@ int BKE_scene_num_threads(const Scene *scene) int BKE_render_preview_pixel_size(const RenderData *r) { if (r->preview_pixel_size == 0) { - return (U.pixelsize > 1.5f)? 2 : 1; + return (U.pixelsize > 1.5f) ? 2 : 1; } return r->preview_pixel_size; } diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c index e435d87024e..a2c45057bf7 100644 --- a/source/blender/blenkernel/intern/seqeffects.c +++ b/source/blender/blenkernel/intern/seqeffects.c @@ -1861,7 +1861,7 @@ static void RVBlurBitmap2_float(float *map, int width, int height, float blur, i float *filter = NULL; int x, y, i, fx, fy; int index, ix, halfWidth; - float fval, k, curColor[3], curColor2[3], weight = 0; + float fval, k, curColor[4], curColor2[4], weight = 0; /* If we're not really blurring, bail out */ if (blur <= 0) @@ -1906,47 +1906,38 @@ static void RVBlurBitmap2_float(float *map, int width, int height, float blur, i for (y = 0; y < height; y++) { /* Do the left & right strips */ for (x = 0; x < halfWidth; x++) { - index = (x + y * width) * 4; fx = 0; - curColor[0] = curColor[1] = curColor[2] = 0.0f; - curColor2[0] = curColor2[1] = curColor2[2] = 0.0f; + zero_v4(curColor); + zero_v4(curColor2); for (i = x - halfWidth; i < x + halfWidth; i++) { if ((i >= 0) && (i < width)) { - curColor[0] += map[(i + y * width) * 4 + GlowR] * filter[fx]; - curColor[1] += map[(i + y * width) * 4 + GlowG] * filter[fx]; - curColor[2] += map[(i + y * width) * 4 + GlowB] * filter[fx]; + index = (i + y * width) * 4; + madd_v4_v4fl(curColor, map + index, filter[fx]); - curColor2[0] += map[(width - 1 - i + y * width) * 4 + GlowR] * filter[fx]; - curColor2[1] += map[(width - 1 - i + y * width) * 4 + GlowG] * filter[fx]; - curColor2[2] += map[(width - 1 - i + y * width) * 4 + GlowB] * filter[fx]; + index = (width - 1 - i + y * width) * 4; + madd_v4_v4fl(curColor2, map + index, filter[fx]); } fx++; } - temp[index + GlowR] = curColor[0]; - temp[index + GlowG] = curColor[1]; - temp[index + GlowB] = curColor[2]; - - temp[((width - 1 - x + y * width) * 4) + GlowR] = curColor2[0]; - temp[((width - 1 - x + y * width) * 4) + GlowG] = curColor2[1]; - temp[((width - 1 - x + y * width) * 4) + GlowB] = curColor2[2]; + index = (x + y * width) * 4; + copy_v4_v4(temp + index, curColor); + index = (width - 1 - x + y * width) * 4; + copy_v4_v4(temp + index, curColor2); } /* Do the main body */ for (x = halfWidth; x < width - halfWidth; x++) { - index = (x + y * width) * 4; fx = 0; - zero_v3(curColor); + zero_v4(curColor); for (i = x - halfWidth; i < x + halfWidth; i++) { - curColor[0] += map[(i + y * width) * 4 + GlowR] * filter[fx]; - curColor[1] += map[(i + y * width) * 4 + GlowG] * filter[fx]; - curColor[2] += map[(i + y * width) * 4 + GlowB] * filter[fx]; + index = (i + y * width) * 4; + madd_v4_v4fl(curColor, map + index, filter[fx]); fx++; } - temp[index + GlowR] = curColor[0]; - temp[index + GlowG] = curColor[1]; - temp[index + GlowB] = curColor[2]; + index = (x + y * width) * 4; + copy_v4_v4(temp + index, curColor); } } @@ -1957,46 +1948,39 @@ static void RVBlurBitmap2_float(float *map, int width, int height, float blur, i for (x = 0; x < width; x++) { /* Do the top & bottom strips */ for (y = 0; y < halfWidth; y++) { - index = (x + y * width) * 4; fy = 0; - zero_v3(curColor); - zero_v3(curColor2); + zero_v4(curColor); + zero_v4(curColor2); for (i = y - halfWidth; i < y + halfWidth; i++) { if ((i >= 0) && (i < height)) { /* Bottom */ - curColor[0] += map[(x + i * width) * 4 + GlowR] * filter[fy]; - curColor[1] += map[(x + i * width) * 4 + GlowG] * filter[fy]; - curColor[2] += map[(x + i * width) * 4 + GlowB] * filter[fy]; + index = (x + i * width) * 4; + madd_v4_v4fl(curColor, map + index, filter[fy]); /* Top */ - curColor2[0] += map[(x + (height - 1 - i) * width) * 4 + GlowR] * filter[fy]; - curColor2[1] += map[(x + (height - 1 - i) * width) * 4 + GlowG] * filter[fy]; - curColor2[2] += map[(x + (height - 1 - i) * width) * 4 + GlowB] * filter[fy]; + index = (x + (height - 1 - i) * width) * 4; + madd_v4_v4fl(curColor2, map + index, filter[fy]); } fy++; } - temp[index + GlowR] = curColor[0]; - temp[index + GlowG] = curColor[1]; - temp[index + GlowB] = curColor[2]; - temp[((x + (height - 1 - y) * width) * 4) + GlowR] = curColor2[0]; - temp[((x + (height - 1 - y) * width) * 4) + GlowG] = curColor2[1]; - temp[((x + (height - 1 - y) * width) * 4) + GlowB] = curColor2[2]; + index = (x + y * width) * 4; + copy_v4_v4(temp + index, curColor); + + index = (x + (height - 1 - y) * width) * 4; + copy_v4_v4(temp + index, curColor2); } /* Do the main body */ for (y = halfWidth; y < height - halfWidth; y++) { - index = (x + y * width) * 4; fy = 0; - zero_v3(curColor); + zero_v4(curColor); for (i = y - halfWidth; i < y + halfWidth; i++) { - curColor[0] += map[(x + i * width) * 4 + GlowR] * filter[fy]; - curColor[1] += map[(x + i * width) * 4 + GlowG] * filter[fy]; - curColor[2] += map[(x + i * width) * 4 + GlowB] * filter[fy]; + index = (x + i * width) * 4; + madd_v4_v4fl(curColor, map + index, filter[fy]); fy++; } - temp[index + GlowR] = curColor[0]; - temp[index + GlowG] = curColor[1]; - temp[index + GlowB] = curColor[2]; + index = (x + y * width) * 4; + copy_v4_v4(temp + index, curColor); } } @@ -2015,10 +1999,10 @@ static void RVAddBitmaps_float(float *a, float *b, float *c, int width, int heig for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { index = (x + y * width) * 4; - c[index + GlowR] = MIN2(1.0f, a[index + GlowR] + b[index + GlowR]); - c[index + GlowG] = MIN2(1.0f, a[index + GlowG] + b[index + GlowG]); - c[index + GlowB] = MIN2(1.0f, a[index + GlowB] + b[index + GlowB]); - c[index + GlowA] = MIN2(1.0f, a[index + GlowA] + b[index + GlowA]); + c[index + GlowR] = min_ff(1.0f, a[index + GlowR] + b[index + GlowR]); + c[index + GlowG] = min_ff(1.0f, a[index + GlowG] + b[index + GlowG]); + c[index + GlowB] = min_ff(1.0f, a[index + GlowB] + b[index + GlowB]); + c[index + GlowA] = min_ff(1.0f, a[index + GlowA] + b[index + GlowA]); } } } @@ -2035,10 +2019,10 @@ static void RVIsolateHighlights_float(float *in, float *out, int width, int heig /* Isolate the intensity */ intensity = (in[index + GlowR] + in[index + GlowG] + in[index + GlowB] - threshold); if (intensity > 0) { - out[index + GlowR] = MIN2(clamp, (in[index + GlowR] * boost * intensity)); - out[index + GlowG] = MIN2(clamp, (in[index + GlowG] * boost * intensity)); - out[index + GlowB] = MIN2(clamp, (in[index + GlowB] * boost * intensity)); - out[index + GlowA] = MIN2(clamp, (in[index + GlowA] * boost * intensity)); + out[index + GlowR] = min_ff(clamp, (in[index + GlowR] * boost * intensity)); + out[index + GlowG] = min_ff(clamp, (in[index + GlowG] * boost * intensity)); + out[index + GlowB] = min_ff(clamp, (in[index + GlowB] * boost * intensity)); + out[index + GlowA] = min_ff(clamp, (in[index + GlowA] * boost * intensity)); } else { out[index + GlowR] = 0; diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index 7cea1e4940f..1ba8fe83971 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -3414,7 +3414,7 @@ static void softbody_update_positions(Object *ob, SoftBody *sb, float (*vertexCo * lloc, lrot, lscale are allowed to be NULL, just in case you don't need it. * should be pretty useful for pythoneers :) * not! velocity .. 2nd order stuff - * vcloud_estimate_transform see + * vcloud_estimate_transform_v3 see */ void SB_estimate_transform(Object *ob, float lloc[3], float lrot[3][3], float lscale[3][3]) @@ -3438,7 +3438,7 @@ void SB_estimate_transform(Object *ob, float lloc[3], float lrot[3][3], float ls copy_v3_v3(opos[a], bp->pos); } - vcloud_estimate_transform(sb->totpoint, opos, NULL, rpos, NULL, com, rcom, lrot, lscale); + vcloud_estimate_transform_v3(sb->totpoint, opos, NULL, rpos, NULL, com, rcom, lrot, lscale); //sub_v3_v3(com, rcom); if (lloc) copy_v3_v3(lloc, com); copy_v3_v3(sb->lcom, com); |