Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2021-03-29 06:23:49 +0300
committerCampbell Barton <ideasman42@gmail.com>2021-03-29 06:31:05 +0300
commit6af4163a3f190ed8b33a622ac038d9df88757a20 (patch)
tree6bf488d1301ad4dad521c718ecce89f621466689 /source/blender/editors/mesh
parent27a7b2e27ae8088dccfa87e66c820dc2e37c113a (diff)
Knife: reduce redundant face picking queries
Reduce the maximum number of queries to find the face under the mouse cursor from 6x to 2x on cursor motion. Calculating the screen-space detail could perform 2x look-ups which have already been calculated.
Diffstat (limited to 'source/blender/editors/mesh')
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c82
1 files changed, 43 insertions, 39 deletions
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index f8b4bf52920..1e6a2c80f91 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -1931,64 +1931,68 @@ static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd,
/**
* Find the 2d screen space density of vertices within a radius.
* Used to scale snapping distance for picking edges/verts.
+ *
+ * Arguments `f` and `cageco` should be the result of a call to #knife_find_closest_face.
*/
-static int knife_sample_screen_density(KnifeTool_OpData *kcd, const float radius)
+static int knife_sample_screen_density_from_closest_face(KnifeTool_OpData *kcd,
+ const float radius,
+ BMFace *f,
+ const float cageco[3])
{
- BMFace *f;
- bool is_space;
- float co[3], cageco[3], sco[2];
-
- BLI_assert(kcd->is_interactive == true);
-
- f = knife_find_closest_face(kcd, co, cageco, &is_space);
-
- if (f && !is_space) {
- const float radius_sq = radius * radius;
- ListBase *list;
- Ref *ref;
- float dis_sq;
- int c = 0;
+ const float radius_sq = radius * radius;
+ ListBase *list;
+ Ref *ref;
+ float sco[2];
+ float dis_sq;
+ int c = 0;
- knife_project_v2(kcd, cageco, sco);
+ knife_project_v2(kcd, cageco, sco);
- list = knife_get_face_kedges(kcd, f);
- for (ref = list->first; ref; ref = ref->next) {
- KnifeEdge *kfe = ref->ref;
- int i;
+ list = knife_get_face_kedges(kcd, f);
+ for (ref = list->first; ref; ref = ref->next) {
+ KnifeEdge *kfe = ref->ref;
+ int i;
- for (i = 0; i < 2; i++) {
- KnifeVert *kfv = i ? kfe->v2 : kfe->v1;
- float kfv_sco[2];
+ for (i = 0; i < 2; i++) {
+ KnifeVert *kfv = i ? kfe->v2 : kfe->v1;
+ float kfv_sco[2];
- knife_project_v2(kcd, kfv->cageco, kfv_sco);
+ knife_project_v2(kcd, kfv->cageco, kfv_sco);
- dis_sq = len_squared_v2v2(kfv_sco, sco);
- if (dis_sq < radius_sq) {
- if (RV3D_CLIPPING_ENABLED(kcd->vc.v3d, kcd->vc.rv3d)) {
- if (ED_view3d_clipping_test(kcd->vc.rv3d, kfv->cageco, true) == 0) {
- c++;
- }
- }
- else {
+ dis_sq = len_squared_v2v2(kfv_sco, sco);
+ if (dis_sq < radius_sq) {
+ if (RV3D_CLIPPING_ENABLED(kcd->vc.v3d, kcd->vc.rv3d)) {
+ if (ED_view3d_clipping_test(kcd->vc.rv3d, kfv->cageco, true) == 0) {
c++;
}
}
+ else {
+ c++;
+ }
}
}
-
- return c;
}
- return 0;
+ return c;
}
-/* returns snapping distance for edges/verts, scaled by the density of the
- * surrounding mesh (in screen space)*/
+/**
+ * \return the snapping distance for edges/verts, scaled by the density of the
+ * surrounding mesh (in screen space).
+ *
+ * \note Face values in `kcd->curr` must be up to date.
+ */
static float knife_snap_size(KnifeTool_OpData *kcd, float maxsize)
{
- float density = (float)knife_sample_screen_density(kcd, maxsize * 2.0f);
+ BLI_assert(kcd->is_interactive == true);
+ int density = 0;
+
+ if (!kcd->curr.is_space) {
+ density = (float)knife_sample_screen_density_from_closest_face(
+ kcd, maxsize * 2.0f, kcd->curr.bmface, kcd->curr.cage);
+ }
- return min_ff(maxsize / (density * 0.5f), maxsize);
+ return density ? min_ff(maxsize / ((float)density * 0.5f), maxsize) : maxsize;
}
/* p is closest point on edge to the mouse cursor */