[Bf-blender-cvs] [415c19a2213] soc-2019-bevel-profiles: Bevel: Profile Orientation Regularization Fixed

Hans Goudey noreply at git.blender.org
Mon Aug 12 21:12:15 CEST 2019


Commit: 415c19a221338341768acdbea19a5aa091312e35
Author: Hans Goudey
Date:   Mon Aug 12 15:11:45 2019 -0400
Branches: soc-2019-bevel-profiles
https://developer.blender.org/rB415c19a221338341768acdbea19a5aa091312e35

Bevel: Profile Orientation Regularization Fixed

The same fix (only setting the orientation of the left boundvert) also
applied for the original code, so there are now two working
implementations. Both are still in in case the second implementation
turns out to be faster for some reason.

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

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 f6ce9101a9d..e5600bf9bea 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -53,7 +53,7 @@
 #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 */
+/** Difference in dot products that corresponds to 10 degree difference between vectors. */
 #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
@@ -62,13 +62,13 @@
 #define DEBUG_CUSTOM_PROFILE_SAMPLE 0
 #define DEBUG_CUSTOM_PROFILE_WELD 0
 #define DEBUG_CUSTOM_PROFILE_ADJ 0
-#define DEBUG_CUSTOM_PROFILE_PIPE 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_PROFILE_ORIENTATION_DRAW
 #define DEBUG_CUSTOM_PROFILE_CUTOFF 0
 
-#if DEBUG_CUSTOM_PROFILE_ORIENTATION_DRAW | DEBUG_CUSTOM_PROFILE_PIPE
+#if defined(DEBUG_PROFILE_ORIENTATION_DRAW) || defined(DEBUG_CUSTOM_PROFILE_PIPE)
+static float debug_color_red[4] = {1.0f, 0.0f, 0.0f, 1.0f};
+static float debug_color_blue[4] = {0.0f, 0.0f, 1.0f, 1.0f};
 extern void DRW_debug_sphere(const float center[3], const float radius, const float color[4]);
 extern void DRW_debug_line_v3v3(const float v1[3], const float v2[3], const float color[4]);
 #endif
@@ -165,7 +165,7 @@ typedef struct Profile {
 #define PRO_LINE_R 1.0f
 #define PRO_SQUARE_IN_R 0.0f
 
-/* The un-transformed 2D storage of profile vertex locations. Also for non-custom profiles
+/** The un-transformed 2D storage of profile vertex locations. Also for non-custom profiles
  * this serves as a cache for the results of the expensive calculation of u parameter values to
  * get even spacing on superellipse for current BevelParams seg
  * and pro_super_r. */
@@ -184,7 +184,7 @@ typedef struct ProfileSpacing {
   float fullness;
 } ProfileSpacing;
 
-/* An element in a cyclic boundary of a Vertex Mesh (VMesh) */
+/** An element in a cyclic boundary of a Vertex Mesh (VMesh) */
 typedef struct BoundVert {
   /** In CCW order. */
   struct BoundVert *next, *prev;
@@ -221,7 +221,7 @@ typedef struct BoundVert {
   int sharp_len;
 } BoundVert;
 
-/* Mesh structure replacing a vertex */
+/** Mesh structure replacing a vertex */
 typedef struct VMesh {
   /** Allocated array - size and structure depends on kind */
   NewVert *mesh;
@@ -286,7 +286,7 @@ typedef enum {
 static const char* fkind_names[] = {"F_NONE", "F_ORIG", "F_VERT", "F_EDGE", "F_RECON"}; /* DEBUG */
 #endif
 
-/* Bevel parameters and state */
+/** Bevel parameters and state */
 typedef struct BevelParams {
   /** Records BevVerts made: key BMVert*, value BevVert* */
   GHash *vert_hash;
@@ -3025,15 +3025,15 @@ static bool adjust_the_cycle_or_chain_fast(BoundVert *vstart, int np, bool iscyc
 }
 #endif
 
-#if 0
+#ifndef OTHER_RPO_CODE
 /** Helper function to return the next Beveled EdgeHalf along a path.
  * \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-- 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. */
+ * \note This only returns the most parallel edge if it's the most parallel by
+ * at least 10 degrees. This is a somewhat arbitrary choice, but it makes sure that consistent
+ * orientation paths only continue in obvious ways. */
 static EdgeHalf *next_edgehalf_bev(BevelParams *bp,
                                    EdgeHalf *start_edge,
                                    bool toward_bv,
@@ -3041,185 +3041,129 @@ static EdgeHalf *next_edgehalf_bev(BevelParams *bp,
 {
   EdgeHalf *new_edge;
   EdgeHalf *next_edge = NULL;
-  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;
-  float new_angle;
-  printf("Next EdgeHalf Bev:");
-  BLI_assert(r_bv != NULL);
+  float dir_start_edge[3], dir_new_edge[3];
+  float second_best_dot = 0.0f, best_dot = 0.0f;
+  float new_dot;
 
   /* Case 1: The next EdgeHalf is across a BevVert from the current EdgeHalf. */
   if (toward_bv) {
-    /* Check for one or two total beveled edges, everything else gets a general solution. */
+    /* Skip all the logic if there's only one beveled edge at the vertex, we're at an end. */
     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);
+      sub_v3_v3v3(dir_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);
-    }
-    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:(%.2f, %.2f, %.2f)]", (double)d_start_edge[0],
-                                           (double)d_start_edge[1],
-                                           (double)d_start_edge[2]);
+      sub_v3_v3v3(dir_start_edge, start_edge->e->v2->co, start_edge->e->v1->co);
+    }
+    normalize_v3(dir_start_edge);
+
     /* 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;
       }
-      printf("[new_edge]");
       /* Find direction vector of the possible next edge (pointing OUT of the BevVert). */
       if (new_edge->e->v2 == (*r_bv)->v) {
-        sub_v3_v3v3(d_new_edge, new_edge->e->v1->co, new_edge->e->v2->co);
+        sub_v3_v3v3(dir_new_edge, new_edge->e->v1->co, new_edge->e->v2->co);
       }
       else {
-        sub_v3_v3v3(d_new_edge, new_edge->e->v2->co, new_edge->e->v1->co);
+        sub_v3_v3v3(dir_new_edge, new_edge->e->v2->co, new_edge->e->v1->co);
       }
+      normalize_v3(dir_new_edge);
 
       /* Use this edge if it is the most parallel to the orignial so far */
-      new_angle = angle_v3v3(d_start_edge, d_new_edge);
-      BLI_assert((start_edge->e->v2 == (*r_bv)->v) ==
-                 compare_v3v3(start_edge->e->v2->co, (*r_bv)->v->co, BEVEL_EPSILON));
-      printf("[d_new:{%.2f, %.2f, %.2f}]", (double)d_new_edge[0],
-                                           (double)d_new_edge[1],
-                                           (double)d_new_edge[2]);
-      printf("[angle:%.1f]", RAD2DEG(new_angle));
-      if (new_angle <= best_angle) { /* <= so equal angles replace both initialized values. */
-        second_best_angle = best_angle; /* For remembering if the choice was too close */
-        best_angle = new_angle;
+      new_dot = dot_v3v3(dir_new_edge, dir_start_edge);
+      if (new_dot > best_dot) {
+        second_best_dot = best_dot; /* For remembering if the choice was too close. */
+        best_dot = new_dot;
         next_edge = new_edge;
       }
+      else if (new_dot > second_best_dot) {
+        second_best_dot = new_dot;
+      }
+
       new_edge = new_edge->next;
-      BLI_assert(new_edge);
     }
 
-    /* Only return a new Edge if one was found and if the choice of next edge was not too close */
-    if (compare_ff(best_angle, second_best_angle, DEG2RADF(10.0f))) {
-      printf("(NULL -- No best angle)\n");
+    /* Only return a new Edge if one was found and if the choice of next edge was not too close. */
+    if ((next_edge != NULL) && compare_ff(best_dot, second_best_dot, BEVEL_SMALL_ANG_DOT)) {
       return NULL;
     }
     else {
-      BLI_assert(next_edge->is_bev);
-      printf("(next_edge)\n");
       return next_edge;
     }
   }
   else {
     /* Case 2: The next EdgeHalf is the other side of the BMEdge.
-     * It's part of the same BMEdge, so we know the other EdgeHalf is also beveled */
+     * It's part of the same BMEdge, so we know the other EdgeHalf is also beveled. */
     next_edge = find_other_end_edge_half(bp, start_edge, r_bv);
-    printf("[away_bv]");
-    if (*r_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_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]);
-    }
-    if (next_edge) {
-      printf("(next_edge)\n");
-    } else {
-      printf("(NULL - !other_edge_half)\n");
-    }
     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 bound

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list