[Bf-blender-cvs] [6264cfd8a59] soc-2019-bevel-profiles: Progress on implementation of profile orientation regularization

Hans Goudey noreply at git.blender.org
Sat Jun 8 04:55:19 CEST 2019


Commit: 6264cfd8a59fcd79fcba514e4201d7a14054cfc1
Author: Hans Goudey
Date:   Fri Jun 7 22:55:31 2019 -0400
Branches: soc-2019-bevel-profiles
https://developer.blender.org/rB6264cfd8a59fcd79fcba514e4201d7a14054cfc1

Progress on implementation of profile orientation regularization

===================================================================

M	source/blender/bmesh/tools/bmesh_bevel.c

===================================================================

diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index 1976950486b..7d627f90ecc 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -167,19 +167,19 @@ typedef struct BoundVert {
   EdgeHalf *efirst;
   EdgeHalf *elast;
   /** The "edge between" that this is on, in offset_on_edge_between case. */
-  EdgeHalf *eon;
+  EdgeHalf *eon; /* HANS-QUESTION: What is the "eon edge?" */
   /** Beveled edge whose left side is attached here, if any. */
   EdgeHalf *ebev;
   /** Used for vmesh indexing. */
   int index;
-  /** When eon set, ratio of sines of angles to eon edge. */ /* HANS-QUESTION: What is the "eon edge?" */
+  /** When eon set, ratio of sines of angles to eon edge. */
   float sinratio;
   /** Adjustment chain or cycle link pointer. */
   struct BoundVert *adjchain;
   /** Edge profile between this and next BoundVert. */
   Profile profile;
-  /* HANS-QUESTION: Why is the profile stored in the BoundVert?
-   * There are two boundverts for every beveled EdgeHalf, so it seems that there would be duplicate information */
+  /* HANS-QUESTION: Why is the profile stored in the BoundVert? There are two boundverts
+   * for every beveled EdgeHalf, so it seems that there would be duplicate information */
   /** Are any of the edges attached here seams? */
   bool any_seam;
   /** Used during delta adjust pass */
@@ -189,7 +189,9 @@ typedef struct BoundVert {
   /** This boundvert begins a patch profile */
   bool is_patch_start;
   /** Is this boundvert the side of the custom profile's start */
-  bool is_profile_start; /* HANS-TODO: Make sure that storing this in the BoundVert is the best option */
+  /* HANS-TODO: It's possible that I could just switch which BoundVert is left and which is
+   * right instead of storing this extra boolean.*/
+  bool is_profile_start;
   /** Length of seam starting from current boundvert to next boundvert with ccw ordering */
   int seam_len;
   /** Same as seam_len but defines length of sharp edges */
@@ -5485,84 +5487,158 @@ static void find_bevel_edge_order(BMesh *bm, BevVert *bv, BMEdge *first_bme)
   }
 }
 
-/* Helper function to return the next Beveled EdgeHalf along a path. This will also
- * update the BevVert to the next one if we are moving to the other EdgeHald of an edge */
-/* HANS-TODO: Maybe move (rename?) this function to the top with the other helpers? */
-static EdgeHalf * next_edgehalf_bev(BevelParams *bp, EdgeHalf *cur, bool toward_bv, BevVert **bv) {
-  EdgeHalf * next;
+/* HANS-TODO: Maybe move (and rename?) this function to the top with the other helpers? */
+/** Helper function to return the next Beveled EdgeHalf along a path.
+ *
+ * \note Right now this returns the most parallel edge if it's the most parallel by
+ * at least 10 degrees. This is a somewhat arbitrary choice, and we may find it's not even
+ * worth it to continue the path across a BevVert with 3 or more connected beveled edges
+ *
+ * \param toward_bv Whether the direction to travel points toward or away from the BevVert
+ *        connected to the current EdgeHalf
+ * \param r_bv The BevVert conencted to the EdgeHalf which is updated if the we switch
+          EdgeHalves in the current edge */
+static EdgeHalf * next_edgehalf_bev(BevelParams *bp,
+                                    EdgeHalf *cur_edge,
+                                    bool toward_bv,
+                                    BevVert **r_bv)
+{
+  EdgeHalf *new_edge;
+  EdgeHalf *next_edge;
+  float d_cur[3];
+  float d_other[3];
+  float v1_dist_to_bv;
+  float v2_dist_to_bv;
+  float new_angle;
+  float best_angle = (float)M_PI; /* Initialized to the LEAST parallel angle */
+  float second_best_angle;
+
 
   /* Case 1: The next EdgeHalf is across a BevVert from the current EdgeHalf */
   if (toward_bv) {
-    /* Find the other beveled edges coming out of the BevVert */
+    /* Find the direction vector of the current edge (pointing INTO the BevVert) .
+     * v1 and v2 don't necessarily have an order, so we need to check which is closer to bv */
+    v1_dist_to_bv = fabsf(len_v3v3(cur_edge->e->v1->co, (*r_bv)->v->co));
+    v2_dist_to_bv = fabsf(len_v3v3(cur_edge->e->v2->co, (*r_bv)->v->co));
+    /* HANS-TODO: Helper function for this comparison? */
+    if (v1_dist_to_bv < v2_dist_to_bv) {
+      sub_v3_v3v3(d_cur, cur_edge->e->v1->co, cur_edge->e->v2->co);
+    }
+    else {
+      sub_v3_v3v3(d_cur, cur_edge->e->v2->co, cur_edge->e->v1->co);
+    }
 
-    /* Find the best choice for the next EdgeHalf, return NULL if no next beveled edge
-     * First choice is the beveled edge that's the most parallel with the current edge */
+    /* Find the beveled edge coming out of the BevVert most parallel to the current edge */
+    new_edge = cur_edge;
+    while ((new_edge = next_bev(*r_bv, new_edge)) != cur_edge) {
+      /* Find direction vector of the possible next edge (pointing OUT of the BevVert) */
+      v1_dist_to_bv = fabsf(len_v3v3(new_edge->e->v1->co, (*r_bv)->v->co));
+      v2_dist_to_bv = fabsf(len_v3v3(new_edge->e->v2->co, (*r_bv)->v->co));
+      if (v1_dist_to_bv > v2_dist_to_bv) {
+        sub_v3_v3v3(d_other, new_edge->e->v1->co, new_edge->e->v2->co);
+      }
+      else {
+        sub_v3_v3v3(d_other, new_edge->e->v2->co, new_edge->e->v1->co);
+      }
 
-  } /* Case 2: The next EdgeHalf is the other side of the BMEdge */
-  else {
-    /* Because it's part of the same BMEdge, we know the other edge half will also be beveled */
-    next = find_other_end_edge_half(bp, cur, bv);
+      /* Use this edge if it is the most parallel to the orignial so far */
+      new_angle = angle_v3v3(d_cur, d_other);
+      if (new_angle < best_angle) {
+        second_best_angle = best_angle; /* To remember if the choice was too close */
+        best_angle = new_angle;
+        next_edge = new_edge;
+      }
+    }
+
+    /* Only return a new Edge if the choice of next edge was not too close */
+    if (second_best_angle < best_angle + DEG2RADF(10.0f) ||
+        second_best_angle > best_angle - DEG2RADF(10.0f)) { /* HANS-TODO: Macro for this? */
+      return NULL;
+    }
+    else {
+      return (next_edge->is_bev) ? next_edge : NULL; /* And only if the next edge is beveled */
+    }
+#ifdef DEBUG_CUSTOM_PROFILE_ORIENTATION
+    printf("We shouldn't be here!\n");
+#endif
   }
 
-  return next;
+  /* Case 2: The next EdgeHalf is the other side of the BMEdge.
+   * Because it's part of the same BMEdge, we know the other edge half will also be beveled */
+  next_edge = find_other_end_edge_half(bp, cur_edge, r_bv);
+  return next_edge;
 }
 
 /* The custom profiles are not necessarily symmetrical, so along beveled edges
  * the profiles can start from opposite sides of the edge. In order to fix this we
  * need to travel along the beveled edges marking consistent boundverts for the
  * bevels to start from. */
-static void regularize_profile_orientation(BevelParams * bp, BMesh *bm) /* HANS-TODO: Possible relocate this function */
+static void regularize_profile_orientation(BevelParams * bp, BMEdge *bme) /* HANS-TODO: Possible relocate this function */
 {
-  BMIter iter;
-  BMEdge *bme;
   BevVert *bv;
   BevVert *r_next_bv;
-  EdgeHalf *e;
+  EdgeHalf *start_edge;
+  EdgeHalf *edge;
   bool toward_bv;
+  BoundVert *last_bndv;
+  BoundVert *bndv;
 
   /* Start at the first EdgeHalf. Once the travelling is finished for that EdgeHalf,
    * go to the next non-visited one and start the travel process from there. */
-  BM_ITER_MESH (bme, &iter, bm, BM_EDGES_OF_MESH) { /* HANS-TODO: Move loop to bm_mesh_bevel maybe? */
-    if (BM_elem_flag_test(bme, BM_ELEM_TAG) && e->is_bev && ! e->visited_custom) {
-      bv = find_bevvert(bp, bme->v1);
-      e = find_edge_half(bv, bme);
-
-      /* Pick a BoundVert on one side of the profile to use for the first side of the profile */
-      e->rightv->is_profile_start = true; /* HANS-TODO: Possibly use a more advanced metric here */
-      e->leftv->is_profile_start = false;
-
-      /* Travel to the next BevVert(s) in both directions if there are more than two, pick the
-       * two best directions to follow, because we lose continuity at >2 way intersections anyway */
-
-      /* Towards the BevVert */
-      toward_bv = true;
-      while (next_edgehalf_bev(bp, e, toward_bv, &r_next_bv)) {
-        /* Stop if this EdgeHalf was already visited */
-        if (e->visited_custom) {
-          break;
-        }
+  bv = find_bevvert(bp, bme->v1); /* HANS-TODO: This could be wrong because it might matter which vert it gets */
+  start_edge = find_edge_half(bv, bme);
+  if (!start_edge->is_bev || start_edge->visited_custom) {
+#ifdef DEBUG_CUSTOM_PROFILE_ORIENTATION
+    if (!start_edge->is_bev) {
+      printf("If it gets to this point the BM_ELEM_TAG check is not an 'is_bev' check\n");
+    }
+#endif
+    return;
+  }
 
-        /* Mark the correct BoundVert as the start of the newly visited profile */
-        /* The correct boundvert will be the one that's connected to the old is_profile_start boundvert
-         * BUT! The edges that connect the boundverts might not have been generated at this point.
-         * I will need to check that */
+  /* Pick a BoundVert on one side of the profile to use for the start of the profile */
+  start_edge->rightv->is_profile_start = true;
+  start_edge->leftv->is_profile_start = false; /* HANS-TODO: Possibly use a more advanced metric here for the start edge */
+  last_bndv = start_edge->rightv;
 
-        /* The next jump will in the opposite direction relative to the BevVert*/
-        toward_bv = !toward_bv;
-      }
-      /* Now the other direction, away from the BoundVert */
-      while (next_edgehalf_bev(bp, e, e, &r_next_bv)) {
-        /* Stop if this EdgeHalf was already visited */
-        if (e->visited_custom) {
-          break;
-        }
+  /* Continue the path in the direction of the BevVert the EdgeHalf is attached to */
+  edge = start_edge;
+  toward_bv = true;
+  while ((edge = next_edgehalf_bev(bp, edge, toward_bv, &r_next_bv))) {
+    /* Stop if this EdgeHalf was already visited */
+    if (edge->visited_custom) {
+      break;
+    }
 
-        /* Mark the correct B

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list