Commit: 55f15f10fada80ba6c2098982c89f07f332c6e88
Author: Hans Goudey
Date:   Mon Aug 12 09:30:27 2019 -0400
Branches: soc-2019-bevel-profiles
https://developer.blender.org/rB55f15f10fada80ba6c2098982c89f07f332c6e88

Bevel: New profile orientation regularization implementation

The new implementation has cleaner shorter code than the last. It's
recursive and it walks along edges rather then edge halves. It fails
at 4 way intersections but a single chain of beveled edges works better
than the last code which is still included in this commit behind an #if 0.

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

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 62e209901f8..f6ce9101a9d 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -53,6 +53,8 @@
 #define BEVEL_EPSILON_BIG_SQ 1e-8f
 #define BEVEL_EPSILON_ANG DEG2RADF(2.0f)
 #define BEVEL_SMALL_ANG DEG2RADF(10.0f)
+/** Difference in dots that corresponds to 10 degree difference */
+#define BEVEL_SMALL_ANG_DOT 1 - cosf(BEVEL_SMALL_ANG)
 #define BEVEL_MAX_ADJUST_PCT 10.0f
 #define BEVEL_MAX_AUTO_ADJUST_PCT 300.0f
 #define BEVEL_MATCH_SPEC_WEIGHT 0.2
@@ -61,8 +63,9 @@
 #define DEBUG_CUSTOM_PROFILE_WELD 0
 #define DEBUG_CUSTOM_PROFILE_ADJ 0
 #define DEBUG_CUSTOM_PROFILE_PIPE 0
-#define DEBUG_CUSTOM_PROFILE_ORIENTATION 0
-#define DEBUG_CUSTOM_PROFILE_ORIENTATION_DRAW DEBUG_CUSTOM_PROFILE_ORIENTATION 
| 0
+#define DEBUG_CUSTOM_PROFILE_ORIENTATION 1
+#define DEBUG_CUSTOM_PROFILE_NEXT_EDGEHALF_BEV 1
+#define DEBUG_CUSTOM_PROFILE_ORIENTATION_DRAW 
DEBUG_CUSTOM_PROFILE_NEXT_EDGEHALF_BEV | 1
 #define DEBUG_CUSTOM_PROFILE_CUTOFF 0
 
 #if DEBUG_CUSTOM_PROFILE_ORIENTATION_DRAW | DEBUG_CUSTOM_PROFILE_PIPE
@@ -87,7 +90,7 @@ struct BoundVert;
 
 /* Data for one end of an edge involved in a bevel */
 typedef struct EdgeHalf {
-  /** In CCW order */
+  /** Other EdgeHalves connected to the same BevVert, in CCW order. */
   struct EdgeHalf *next, *prev;
   /** Original mesh edge */
   BMEdge *e;
@@ -118,7 +121,7 @@ typedef struct EdgeHalf {
   /** Is e a seam for custom loopdata (e.g., UVs)? */
   bool is_seam;
   /** Used during the custom profile orientation pass */
-  bool visited_custom;
+  bool visited_rpo;
   char _pad[4];
 } EdgeHalf;
 
@@ -697,7 +700,7 @@ static BMFace *bev_create_ngon(BMesh *bm,
   }
 
   if (mat_nr >= 0) {
-    f->mat_nr = mat_nr;
+    f->mat_nr = (short)mat_nr;
   }
   return f;
 }
@@ -1047,7 +1050,7 @@ static void offset_meet(
     normalize_v3(norm_perp1);
     copy_v3_v3(off1a, v->co);
     d = max_ff(e1->offset_r, e2->offset_l);
-    d = d / cos(ang / 2.0f);
+    d = d / cosf(ang / 2.0f);
     madd_v3_v3fl(off1a, norm_perp1, d);
     copy_v3_v3(meetco, off1a);
   }
@@ -2310,9 +2313,14 @@ static void calculate_vm_profiles(BevelParams *bp, 
BevVert *bv, VMesh *vm)
   bndv = vm->boundstart;
   do {
     set_profile_params(bp, bv, bndv);
+    /* Use the miter profile spacing struct if the default is filled with the 
custom profile. */
     bool miter_profile = bp->use_custom_profile && (bndv->is_arc_start || 
bndv->is_patch_start);
-    /* We probably don't know the orientation at this point, so don't reverse 
the profiles */
-    calculate_profile(bp, bndv, false, miter_profile);
+    /* Don't bother reversing the profile if it's a miter profile */
+    bool reverse_profile = !bndv->is_profile_start && !miter_profile;
+//    printf("miter_profile: %d, reverse_profile: %d\n", miter_profile, 
reverse_profile);
+    BLI_assert(!(miter_profile && reverse_profile));
+
+    calculate_profile(bp, bndv, reverse_profile, miter_profile);
   } while ((bndv = bndv->next) != vm->boundstart);
 }
 
@@ -2415,7 +2423,7 @@ static void build_boundary_terminal_edge(BevelParams *bp,
     /* TODO: should do something else if angle between e and e->prev > 180 */
     offset_meet(e->prev, e, bv->v, e->fprev, false, co);
     if (construct) {
-      bndv = add_new_bound_vert(mem_arena, vm, co);
+      bndv =  add_new_bound_vert(mem_arena, vm, co);
       bndv->efirst = e->prev;
       bndv->elast = bndv->ebev = e;
       e->leftv = bndv;
@@ -2439,7 +2447,7 @@ static void build_boundary_terminal_edge(BevelParams *bp,
     /* For the edges not adjacent to the beveled edge, slide the bevel amount 
along. */
     d = efirst->offset_l_spec;
     if (bp->use_custom_profile || bp->profile < 0.25f) {
-      d *= sqrtf(2.0f); /* Need to go further down the edge to make room for 
full profile area */
+      d *= sqrtf(2.0f); /* Need to go further along the edge to make room for 
full profile area. */
     }
     for (e = e->next; e->next != efirst; e = e->next) {
       slide_dist(e, bv->v, d, co);
@@ -2457,13 +2465,12 @@ static void build_boundary_terminal_edge(BevelParams 
*bp,
   calculate_vm_profiles(bp, bv, vm);
 
   if (bv->edgecount >= 3) {
-    /* special case: snap profile to plane of adjacent two edges */
+    /* Special case: snap profile to plane of adjacent two edges. */
     bndv = vm->boundstart;
     BLI_assert(bndv->ebev != NULL);
     move_profile_plane(bndv, bv->v);
-    /* This step happens before profile orientation regularization, so don't 
reverse the profile */
+    /* This step happens before the profile orientation pass so don't reverse 
the profile. */
     calculate_profile(bp, bndv, false, false);
-
   }
 
   if (construct) {
@@ -3018,192 +3025,141 @@ static bool adjust_the_cycle_or_chain_fast(BoundVert 
*vstart, int np, bool iscyc
 }
 #endif
 
+#if 0
 /** 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 */
+ * \param r_bv The BevVert conencted to the EdgeHalf-- updated if we're 
travelling to the other
+ *        EdgeHalf of an original edge
+ * \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. */
 static EdgeHalf *next_edgehalf_bev(BevelParams *bp,
-                                    EdgeHalf *start_edge,
-                                    bool toward_bv,
-                                    BevVert **r_bv)
+                                   EdgeHalf *start_edge,
+                                   bool toward_bv,
+                                   BevVert **r_bv)
 {
   EdgeHalf *new_edge;
   EdgeHalf *next_edge = NULL;
-  float d_start[3];
-  float d_new[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 d_start_edge[3], d_new_edge[3];
+  float best_angle = FLT_MAX; /* Initialized to the biggest angle ever. */
   float second_best_angle = best_angle;
-#if DEBUG_CUSTOM_PROFILE_ORIENTATION
-  printf("NEXT EDGEHALF BEV");
-#endif
+  float new_angle;
+  printf("Next EdgeHalf Bev:");
   BLI_assert(r_bv != NULL);
 
-  /* Case 1: The next EdgeHalf is across a BevVert from the current EdgeHalf */
+  /* Case 1: The next EdgeHalf is across a BevVert from the current EdgeHalf. 
*/
   if (toward_bv) {
-    /* 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(start_edge->e->v1->co, (*r_bv)->v->co));
-    v2_dist_to_bv = fabsf(len_v3v3(start_edge->e->v2->co, (*r_bv)->v->co));
-    if (v1_dist_to_bv < v2_dist_to_bv) {
-      sub_v3_v3v3(d_start, start_edge->e->v1->co, start_edge->e->v2->co);
+    /* Check for one or two total beveled edges, everything else gets a 
general solution. */
+    if ((*r_bv)->selcount == 1) {
+      if (start_edge->e->v1 == (*r_bv)->v) {
+        sub_v3_v3v3(d_start_edge, start_edge->e->v1->co, 
start_edge->e->v2->co);
+      }
+      else {
+        sub_v3_v3v3(d_start_edge, start_edge->e->v2->co, 
start_edge->e->v1->co);
+      }
+      printf("[d_start:{%.2f, %.2f, %.2f}]", (double)d_start_edge[0],
+                                             (double)d_start_edge[1],
+                                             (double)d_start_edge[2]);
+      printf("[toward_bv](NULL -- only 1)\n");
+      return NULL; /* No other edges to go to. */
+    }
+
+    /* 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. */
+    if (start_edge->e->v1 == (*r_bv)->v) {
+      sub_v3_v3v3(d_start_edge, start_edge->e->v1->co, start_edge->e->v2->co);
     }
     else {
-      sub_v3_v3v3(d_start, start_edge->e->v2->co, start_edge->e->v1->co);
+      sub_v3_v3v3(d_start_edge, start_edge->e->v2->co, start_edge->e->v1->co);
     }
-#if DEBUG_CUSTOM_PROFILE_ORIENTATION
+    BLI_assert((start_edge->e->v1 == (*r_bv)->v) ==
+               compare_v3v3(start_edge->e->v1->co, (*r_bv)->v->co, 
BEVEL_EPSILON));
     printf("[toward_bv]");
-    printf("[d_start:(%0.2f, %0.2f, %0.2f)]", (double)d_start[0],
-                                              (double)d_start[1],
-                                              (double)d_start[2]);
-#endif
-
-    /* Find the beveled edge coming out of the BevVert most parallel to the 
current edge */
-    new_edge = start_edge;
-    new_edge = new_edge->next;
-#if DEBUG_CUSTOM_PROFILE_ORIENTATION
-//    if (new_edge) {
-//      printf("[new_edge]");
-//      if (new_edge == start_edge) {
-//        printf("[new_edge == cur_edge]\n");
-//        printf("Beveled Edge Count for BevVert: %d\n", (*r_bv)->selcount);
-////        dump_bv(*r_bv);
-//      }
-//    } else {
-//      printf("[!new_edge]");
-//    }
-#endif
-    while (new_edge && new_edge != start_edge) {
+    printf("[d_start:(%.2f, %.2f, %.2f)]", (double)d_start_edge[0],
+                                           (double)d_start_edge[1],
+                                           (double)d_start_edge[2]);
+    /* Find the beveled edge coming out of the BevVert that's most parallel to 
the current edge. */
+    new_edge = start_edge->next;
+    BLI_assert(new_edge);
+    while (new_edge != start_edge) {
       if (!new_edge->is_bev) {
         new_edge = new_edge->next;
         continue;
       }
-#if DEBUG_CUSTOM_PROFILE_ORIENTATION
       printf("[new_edge]");
-#endif
-      /* Find dir

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to