Cleanup: use '_len' instead of '_size' w/ BLI API
[blender.git] / source / blender / editors / uvedit / uvedit_parametrizer.c
index e1495b617f85ab8797152cf157d8f7cfc0c0993f..f8a93bd2ce3b292ba587bb9da06b1f77e2adecdb 100644 (file)
@@ -740,6 +740,16 @@ static PVert *p_vert_add(PHandle *handle, PHashKey key, const float co[3], PEdge
 {
        PVert *v = (PVert *)BLI_memarena_alloc(handle->arena, sizeof(*v));
        copy_v3_v3(v->co, co);
+
+       /* Sanity check, a single nan/inf point causes the entire result to be invalid.
+        * Note that values within the calculation may _become_ non-finite,
+        * so the rest of the code still needs to take this possibility into account. */
+       for (int i = 0; i < 3; i++) {
+               if (UNLIKELY(!isfinite(v->co[i]))) {
+                       v->co[i] = 0.0f;
+               }
+       }
+
        v->u.key = key;
        v->edge = e;
        v->flag = 0;
@@ -1281,7 +1291,7 @@ static void p_chart_fill_boundary(PChart *chart, PEdge *be, int nedges)
                while (nedges > 2) {
                        PEdge *ne, *ne1, *ne2;
 
-                       e = (PEdge *)BLI_heap_popmin(heap);
+                       e = (PEdge *)BLI_heap_pop_min(heap);
 
                        e1 = p_boundary_edge_prev(e);
                        e2 = p_boundary_edge_next(e);
@@ -2175,12 +2185,12 @@ static void p_chart_simplify_compute(PChart *chart)
                e->u.nextcollapse = NULL;
 
        /* pop edge collapse out of heap one by one */
-       while (!BLI_heap_empty(heap)) {
+       while (!BLI_heap_is_empty(heap)) {
                if (ncollapsed == NCOLLAPSE)
                        break;
 
                HeapNode *link = BLI_heap_top(heap);
-               PEdge *edge = (PEdge *)BLI_heap_popmin(heap), *pair = edge->pair;
+               PEdge *edge = (PEdge *)BLI_heap_pop_min(heap), *pair = edge->pair;
                PVert *oldv, *keepv;
                PEdge *wheele, *nexte;
 
@@ -2794,7 +2804,7 @@ static PBool p_chart_abf_solve(PChart *chart)
 
 static void p_chart_pin_positions(PChart *chart, PVert **pin1, PVert **pin2)
 {
-       if (pin1 == pin2) {
+       if (!*pin1 || !*pin2 || *pin1 == *pin2) {
                /* degenerate case */
                PFace *f = chart->faces;
                *pin1 = f->edge->vert;
@@ -2849,7 +2859,7 @@ static PBool p_chart_symmetry_pins(PChart *chart, PEdge *outer, PVert **pin1, PV
        PEdge *cure = NULL, *firste1 = NULL, *firste2 = NULL, *nextbe;
        float maxlen = 0.0f, curlen = 0.0f, totlen = 0.0f, firstlen = 0.0f;
        float len1, len2;
+
        /* find longest series of verts split in the chart itself, these are
         * marked during construction */
        be = outer;
@@ -3040,8 +3050,10 @@ static void p_chart_lscm_begin(PChart *chart, PBool live, PBool abf)
 
                        p_chart_boundaries(chart, NULL, &outer);
 
-                       if (!p_chart_symmetry_pins(chart, outer, &pin1, &pin2))
+                       /* outer can be NULL with non-finite coords. */
+                       if (!(outer && p_chart_symmetry_pins(chart, outer, &pin1, &pin2))) {
                                p_chart_extrema_verts(chart, &pin1, &pin2);
+                       }
 
                        chart->u.lscm.pin1 = pin1;
                        chart->u.lscm.pin2 = pin2;
@@ -4166,6 +4178,7 @@ static void p_add_ngon(ParamHandle *handle, ParamKey key, int nverts,
 
        while (nverts > 2) {
                float minangle = FLT_MAX;
+               float minshape = FLT_MAX;
                int i, mini = 0;
 
                /* find corner with smallest angle */
@@ -4181,8 +4194,20 @@ static void p_add_ngon(ParamHandle *handle, ParamKey key, int nverts,
                        if (normal && (dot_v3v3(n, normal) < 0.0f))
                                angle = (float)(2.0 * M_PI) - angle;
 
-                       if (angle < minangle) {
+                       float other_angle = p_vec_angle(co[v2], co[v0], co[v1]);
+                       float shape = fabsf((float)M_PI - angle - 2.0f * other_angle);
+
+                       if (fabsf(angle - minangle) < 0.01f) {
+                               /* for nearly equal angles, try to get well shaped triangles */
+                               if (shape < minshape) {
+                                       minangle = angle;
+                                       minshape = shape;
+                                       mini = i;
+                               }
+                       }
+                       else if (angle < minangle) {
                                minangle = angle;
+                               minshape = shape;
                                mini = i;
                        }
                }
@@ -4458,7 +4483,7 @@ static void param_pack_rotate(ParamHandle *handle)
 
                p_chart_uv_to_array(chart, points);
 
-               angle = BLI_convexhull_aabb_fit_points_2d((const float (*)[2])points, chart->nverts);
+               angle = BLI_convexhull_aabb_fit_points_2d(points, chart->nverts);
 
                MEM_freeN(points);