Changeset View
Changeset View
Standalone View
Standalone View
source/blender/modifiers/intern/MOD_surfacedeform.c
| Show First 20 Lines • Show All 108 Lines • ▼ Show 20 Lines | typedef struct SDefBindPoly { | ||||
| /** Coordinates projected into 2D space using `normal`. */ | /** Coordinates projected into 2D space using `normal`. */ | ||||
| float (*coords_v2)[2]; | float (*coords_v2)[2]; | ||||
| /** The point being queried projected into 2D space using `normal`. */ | /** The point being queried projected into 2D space using `normal`. */ | ||||
| float point_v2[2]; | float point_v2[2]; | ||||
| float weight_angular; | float weight_angular; | ||||
| float weight_dist_proj; | float weight_dist_proj; | ||||
| float weight_dist; | float weight_dist; | ||||
| float weight; | float weight; | ||||
| /** Distances from the centroid to edges flanking the corner vertex, used to penalize | |||||
| * small or long and narrow faces in favor of bigger and more square ones. */ | |||||
| float scales[2]; | float scales[2]; | ||||
| /** Distance weight from the corner vertex to the chord line, used to penalize | |||||
| * cases with the three consecutive vertices being nearly in line. */ | |||||
| float scale_mid; | |||||
| /** Center of `coords` */ | /** Center of `coords` */ | ||||
| float centroid[3]; | float centroid[3]; | ||||
| /** Center of `coords_v2` */ | /** Center of `coords_v2` */ | ||||
| float centroid_v2[2]; | float centroid_v2[2]; | ||||
| /** | /** | ||||
| * The calculated normal of coords (could be shared between faces). | * The calculated normal of coords (could be shared between faces). | ||||
| */ | */ | ||||
| float normal[3]; | float normal[3]; | ||||
| /** Vectors pointing from the centroid to the midpoints of the two edges | |||||
| * flanking the corner vertex. */ | |||||
| float cent_edgemid_vecs_v2[2][2]; | float cent_edgemid_vecs_v2[2][2]; | ||||
| /** | /** Angle between the cent_edgemid_vecs_v2 vectors. */ | ||||
| * The unsigned angle of this face-corner in `[0.0 .. PI]` range, | |||||
| * where a small value is a thin corner. PI is a straight line. | |||||
| * Take care dividing by this value as it can approach zero. | |||||
| */ | |||||
| float edgemid_angle; | float edgemid_angle; | ||||
| /** Angles between the centroid-to-point and cent_edgemid_vecs_v2 vectors. | |||||
| * Positive values measured towards the corner; clamped non-negative. */ | |||||
| float point_edgemid_angles[2]; | float point_edgemid_angles[2]; | ||||
| /** Angles between the centroid-to-corner and cent_edgemid_vecs_v2 vectors. */ | |||||
| float corner_edgemid_angles[2]; | float corner_edgemid_angles[2]; | ||||
| /** Weight of the bind mode based on the corner and two adjacent vertices, | |||||
| * versus the one based on the centroid and the dominant edge. */ | |||||
| float dominant_angle_weight; | float dominant_angle_weight; | ||||
| /** Index of the input polygon. */ | /** Index of the input polygon. */ | ||||
| uint index; | uint index; | ||||
| /** Number of vertices in this face. */ | /** Number of vertices in this face. */ | ||||
| uint numverts; | uint numverts; | ||||
| /** | /** | ||||
| * This polygons loop-start. | * This polygons loop-start. | ||||
| * \note that we could look this up from the polygon. | * \note that we could look this up from the polygon. | ||||
| ▲ Show 20 Lines • Show All 266 Lines • ▼ Show 20 Lines | if (len_squared_v3v3(point_co, data->targetCos[edge->v1]) < | ||||
| return edge->v1; | return edge->v1; | ||||
| } | } | ||||
| return edge->v2; | return edge->v2; | ||||
| } | } | ||||
| BLI_INLINE int isPolyValid(const float coords[][2], const uint nr) | BLI_INLINE int isPolyValid(const float coords[][2], const uint nr) | ||||
| { | { | ||||
| float prev_co[2]; | float prev_co[2], prev_prev_co[2]; | ||||
| float curr_vec[2], prev_vec[2]; | float curr_vec[2], prev_vec[2]; | ||||
| if (!is_poly_convex_v2(coords, nr)) { | if (!is_poly_convex_v2(coords, nr)) { | ||||
| return MOD_SDEF_BIND_RESULT_CONCAVE_ERR; | return MOD_SDEF_BIND_RESULT_CONCAVE_ERR; | ||||
| } | } | ||||
| copy_v2_v2(prev_prev_co, coords[nr - 2]); | |||||
| copy_v2_v2(prev_co, coords[nr - 1]); | copy_v2_v2(prev_co, coords[nr - 1]); | ||||
| sub_v2_v2v2(prev_vec, prev_co, coords[nr - 2]); | sub_v2_v2v2(prev_vec, prev_co, coords[nr - 2]); | ||||
| normalize_v2(prev_vec); | normalize_v2(prev_vec); | ||||
| for (int i = 0; i < nr; i++) { | for (int i = 0; i < nr; i++) { | ||||
| sub_v2_v2v2(curr_vec, coords[i], prev_co); | sub_v2_v2v2(curr_vec, coords[i], prev_co); | ||||
| /* Check ovelap between directly adjacent vertices. */ | |||||
| const float curr_len = normalize_v2(curr_vec); | const float curr_len = normalize_v2(curr_vec); | ||||
| if (curr_len < FLT_EPSILON) { | if (curr_len < FLT_EPSILON) { | ||||
| return MOD_SDEF_BIND_RESULT_OVERLAP_ERR; | return MOD_SDEF_BIND_RESULT_OVERLAP_ERR; | ||||
| } | } | ||||
| /* Check ovelap between vertices skipping one. */ | |||||
| if (len_squared_v2v2(prev_prev_co, coords[i]) < FLT_EPSILON * FLT_EPSILON) { | |||||
| return MOD_SDEF_BIND_RESULT_OVERLAP_ERR; | |||||
| } | |||||
| /* Check for adjacent parallel edges. */ | |||||
| if (1.0f - dot_v2v2(prev_vec, curr_vec) < FLT_EPSILON) { | if (1.0f - dot_v2v2(prev_vec, curr_vec) < FLT_EPSILON) { | ||||
| return MOD_SDEF_BIND_RESULT_CONCAVE_ERR; | return MOD_SDEF_BIND_RESULT_CONCAVE_ERR; | ||||
| } | } | ||||
| copy_v2_v2(prev_prev_co, prev_co); | |||||
| copy_v2_v2(prev_co, coords[i]); | copy_v2_v2(prev_co, coords[i]); | ||||
| copy_v2_v2(prev_vec, curr_vec); | copy_v2_v2(prev_vec, curr_vec); | ||||
| } | } | ||||
| return MOD_SDEF_BIND_RESULT_SUCCESS; | return MOD_SDEF_BIND_RESULT_SUCCESS; | ||||
| } | } | ||||
| static void freeBindData(SDefBindWeightData *const bwdata) | static void freeBindData(SDefBindWeightData *const bwdata) | ||||
| { | { | ||||
| SDefBindPoly *bpoly = bwdata->bind_polys; | SDefBindPoly *bpoly = bwdata->bind_polys; | ||||
| if (bwdata->bind_polys) { | if (bwdata->bind_polys) { | ||||
| for (int i = 0; i < bwdata->numpoly; bpoly++, i++) { | for (int i = 0; i < bwdata->numpoly; bpoly++, i++) { | ||||
| MEM_SAFE_FREE(bpoly->coords); | MEM_SAFE_FREE(bpoly->coords); | ||||
| MEM_SAFE_FREE(bpoly->coords_v2); | MEM_SAFE_FREE(bpoly->coords_v2); | ||||
| } | } | ||||
| MEM_freeN(bwdata->bind_polys); | MEM_freeN(bwdata->bind_polys); | ||||
| } | } | ||||
| MEM_freeN(bwdata); | MEM_freeN(bwdata); | ||||
| } | } | ||||
| BLI_INLINE float computeAngularWeight(const float point_angle) | BLI_INLINE float computeAngularWeight(const float point_angle, const float edgemid_angle) | ||||
| { | { | ||||
| return sinf(point_angle * M_PI_2); | return sinf(min_ff(point_angle / edgemid_angle, 1) * M_PI_2); | ||||
| } | } | ||||
| BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data, | BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data, | ||||
| const float point_co[3]) | const float point_co[3]) | ||||
| { | { | ||||
| const uint nearest = nearestVert(data, point_co); | const uint nearest = nearestVert(data, point_co); | ||||
| const SDefAdjacency *const vert_edges = data->vert_edges[nearest].first; | const SDefAdjacency *const vert_edges = data->vert_edges[nearest].first; | ||||
| const SDefEdgePolys *const edge_polys = data->edge_polys; | const SDefEdgePolys *const edge_polys = data->edge_polys; | ||||
| ▲ Show 20 Lines • Show All 124 Lines • ▼ Show 20 Lines | for (int i = 0; i < edge_polys[edge_ind].num; i++) { | ||||
| /* Initialize weight components */ | /* Initialize weight components */ | ||||
| bpoly->weight_angular = 1.0f; | bpoly->weight_angular = 1.0f; | ||||
| bpoly->weight_dist_proj = len_v2v2(bpoly->centroid_v2, bpoly->point_v2); | bpoly->weight_dist_proj = len_v2v2(bpoly->centroid_v2, bpoly->point_v2); | ||||
| bpoly->weight_dist = len_v3v3(bpoly->centroid, point_co); | bpoly->weight_dist = len_v3v3(bpoly->centroid, point_co); | ||||
| avg_point_dist += bpoly->weight_dist; | avg_point_dist += bpoly->weight_dist; | ||||
| /* Common vertex coordinates. */ | |||||
| const float *const vert0_v2 = bpoly->coords_v2[bpoly->edge_vert_inds[0]]; | |||||
| const float *const vert1_v2 = bpoly->coords_v2[bpoly->edge_vert_inds[1]]; | |||||
| const float *const corner_v2 = bpoly->coords_v2[bpoly->corner_ind]; | |||||
| /* Compute centroid to mid-edge vectors */ | /* Compute centroid to mid-edge vectors */ | ||||
| mid_v2_v2v2(bpoly->cent_edgemid_vecs_v2[0], | mid_v2_v2v2(bpoly->cent_edgemid_vecs_v2[0], vert0_v2, corner_v2); | ||||
| bpoly->coords_v2[bpoly->edge_vert_inds[0]], | mid_v2_v2v2(bpoly->cent_edgemid_vecs_v2[1], vert1_v2, corner_v2); | ||||
| bpoly->coords_v2[bpoly->corner_ind]); | |||||
| mid_v2_v2v2(bpoly->cent_edgemid_vecs_v2[1], | |||||
| bpoly->coords_v2[bpoly->edge_vert_inds[1]], | |||||
| bpoly->coords_v2[bpoly->corner_ind]); | |||||
| sub_v2_v2(bpoly->cent_edgemid_vecs_v2[0], bpoly->centroid_v2); | sub_v2_v2(bpoly->cent_edgemid_vecs_v2[0], bpoly->centroid_v2); | ||||
| sub_v2_v2(bpoly->cent_edgemid_vecs_v2[1], bpoly->centroid_v2); | sub_v2_v2(bpoly->cent_edgemid_vecs_v2[1], bpoly->centroid_v2); | ||||
| /* Compute poly scales with respect to mid-edges, and normalize the vectors */ | normalize_v2(bpoly->cent_edgemid_vecs_v2[0]); | ||||
| bpoly->scales[0] = normalize_v2(bpoly->cent_edgemid_vecs_v2[0]); | normalize_v2(bpoly->cent_edgemid_vecs_v2[1]); | ||||
| bpoly->scales[1] = normalize_v2(bpoly->cent_edgemid_vecs_v2[1]); | |||||
| /* Compute poly scales with respect to the two edges. */ | |||||
| bpoly->scales[0] = dist_to_line_v2(bpoly->centroid_v2, vert0_v2, corner_v2); | |||||
| bpoly->scales[1] = dist_to_line_v2(bpoly->centroid_v2, vert1_v2, corner_v2); | |||||
| /* Compute the required polygon angles */ | /* Compute the angle between the edge mid vectors. */ | ||||
| bpoly->edgemid_angle = angle_normalized_v2v2(bpoly->cent_edgemid_vecs_v2[0], | bpoly->edgemid_angle = angle_normalized_v2v2(bpoly->cent_edgemid_vecs_v2[0], | ||||
| bpoly->cent_edgemid_vecs_v2[1]); | bpoly->cent_edgemid_vecs_v2[1]); | ||||
| sub_v2_v2v2(tmp_vec_v2, bpoly->coords_v2[bpoly->corner_ind], bpoly->centroid_v2); | /* Compute the angles between the corner and the edge mid vectors. The angles | ||||
| * are computed signed in order to correctly clamp point_edgemid_angles later. */ | |||||
| float corner_angles[2]; | |||||
| sub_v2_v2v2(tmp_vec_v2, corner_v2, bpoly->centroid_v2); | |||||
| normalize_v2(tmp_vec_v2); | normalize_v2(tmp_vec_v2); | ||||
| bpoly->corner_edgemid_angles[0] = angle_normalized_v2v2(tmp_vec_v2, | corner_angles[0] = angle_signed_v2v2(tmp_vec_v2, bpoly->cent_edgemid_vecs_v2[0]); | ||||
| bpoly->cent_edgemid_vecs_v2[0]); | corner_angles[1] = angle_signed_v2v2(tmp_vec_v2, bpoly->cent_edgemid_vecs_v2[1]); | ||||
| bpoly->corner_edgemid_angles[1] = angle_normalized_v2v2(tmp_vec_v2, | |||||
| bpoly->cent_edgemid_vecs_v2[1]); | bpoly->corner_edgemid_angles[0] = fabsf(corner_angles[0]); | ||||
| bpoly->corner_edgemid_angles[1] = fabsf(corner_angles[1]); | |||||
| /* Verify that the computed values are valid (the polygon isn't somehow | |||||
| * degenerate despite having passed isPolyValid). */ | |||||
| if (bpoly->scales[0] < FLT_EPSILON || bpoly->scales[1] < FLT_EPSILON || | |||||
| bpoly->edgemid_angle < FLT_EPSILON || bpoly->corner_edgemid_angles[0] < FLT_EPSILON || | |||||
| bpoly->corner_edgemid_angles[1] < FLT_EPSILON) { | |||||
| freeBindData(bwdata); | |||||
| data->success = MOD_SDEF_BIND_RESULT_GENERIC_ERR; | |||||
| return NULL; | |||||
| } | |||||
| /* Check for infinite weights, and compute angular data otherwise. */ | /* Check for infinite weights, and compute angular data otherwise. */ | ||||
| if (bpoly->weight_dist < FLT_EPSILON) { | if (bpoly->weight_dist < FLT_EPSILON) { | ||||
| inf_weight_flags |= MOD_SDEF_INFINITE_WEIGHT_DIST_PROJ; | inf_weight_flags |= MOD_SDEF_INFINITE_WEIGHT_DIST_PROJ; | ||||
| inf_weight_flags |= MOD_SDEF_INFINITE_WEIGHT_DIST; | inf_weight_flags |= MOD_SDEF_INFINITE_WEIGHT_DIST; | ||||
| } | } | ||||
| else if (bpoly->weight_dist_proj < FLT_EPSILON) { | else if (bpoly->weight_dist_proj < FLT_EPSILON) { | ||||
| inf_weight_flags |= MOD_SDEF_INFINITE_WEIGHT_DIST_PROJ; | inf_weight_flags |= MOD_SDEF_INFINITE_WEIGHT_DIST_PROJ; | ||||
| } | } | ||||
| else { | else { | ||||
| float cent_point_vec[2]; | /* Compute angles between the point and the edge mid vectors. */ | ||||
| float cent_point_vec[2], point_angles[2]; | |||||
| sub_v2_v2v2(cent_point_vec, bpoly->point_v2, bpoly->centroid_v2); | sub_v2_v2v2(cent_point_vec, bpoly->point_v2, bpoly->centroid_v2); | ||||
| normalize_v2(cent_point_vec); | normalize_v2(cent_point_vec); | ||||
| bpoly->point_edgemid_angles[0] = angle_normalized_v2v2(cent_point_vec, | point_angles[0] = angle_signed_v2v2(cent_point_vec, bpoly->cent_edgemid_vecs_v2[0]) * | ||||
| bpoly->cent_edgemid_vecs_v2[0]); | signf(corner_angles[0]); | ||||
| bpoly->point_edgemid_angles[1] = angle_normalized_v2v2(cent_point_vec, | point_angles[1] = angle_signed_v2v2(cent_point_vec, bpoly->cent_edgemid_vecs_v2[1]) * | ||||
| bpoly->cent_edgemid_vecs_v2[1]); | signf(corner_angles[1]); | ||||
| if (point_angles[0] <= 0 && point_angles[1] <= 0) { | |||||
| /* If the point is outside the corner formed by the edge mid vectors, | |||||
| * choose to clamp the closest side and flip the other. */ | |||||
| if (point_angles[0] < point_angles[1]) { | |||||
| point_angles[0] = bpoly->edgemid_angle - point_angles[1]; | |||||
| } | |||||
| else { | |||||
| point_angles[1] = bpoly->edgemid_angle - point_angles[0]; | |||||
| } | |||||
| } | |||||
| bpoly->point_edgemid_angles[0] = max_ff(0, point_angles[0]); | |||||
| bpoly->point_edgemid_angles[1] = max_ff(0, point_angles[1]); | |||||
| /* Compute the distance scale for the corner. The base value is the orthogonal | |||||
| * distance from the corner to the chord, scaled by sqrt(2) to preserve the old | |||||
| * values in case of a square grid. This doesn't use the centroid because the | |||||
| * LOOPTRI method only uses these three vertices. */ | |||||
| bpoly->scale_mid = area_tri_v2(vert0_v2, corner_v2, vert1_v2) / | |||||
| len_v2v2(vert0_v2, vert1_v2) * sqrtf(2); | |||||
| if (bpoly->inside) { | |||||
| /* When inside, interpolate to centroid-based scale close to the center. */ | |||||
| float min_dist = min_ff(bpoly->scales[0], bpoly->scales[1]); | |||||
| bpoly->scale_mid = interpf(bpoly->scale_mid, | |||||
| (bpoly->scales[0] + bpoly->scales[1]) / 2, | |||||
| min_ff(bpoly->weight_dist_proj / min_dist, 1)); | |||||
| } | |||||
| /* Verify that the additional computed values are valid. */ | |||||
| if (bpoly->scale_mid < FLT_EPSILON || | |||||
| bpoly->point_edgemid_angles[0] + bpoly->point_edgemid_angles[1] < FLT_EPSILON) { | |||||
| freeBindData(bwdata); | |||||
| data->success = MOD_SDEF_BIND_RESULT_GENERIC_ERR; | |||||
| return NULL; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| avg_point_dist /= bwdata->numpoly; | avg_point_dist /= bwdata->numpoly; | ||||
| /* If weights 1 and 2 are not infinite, loop over all adjacent edges again, | /* If weights 1 and 2 are not infinite, loop over all adjacent edges again, | ||||
| Show All 23 Lines | for (vedge = vert_edges; vedge; vedge = vedge->next) { | ||||
| } | } | ||||
| j++; | j++; | ||||
| } | } | ||||
| } | } | ||||
| /* Compute angular weight component */ | /* Compute angular weight component */ | ||||
| if (epolys->num == 1) { | if (epolys->num == 1) { | ||||
| ang_weights[0] = computeAngularWeight(bpolys[0]->point_edgemid_angles[edge_on_poly[0]]); | ang_weights[0] = computeAngularWeight(bpolys[0]->point_edgemid_angles[edge_on_poly[0]], | ||||
| bpolys[0]->edgemid_angle); | |||||
| bpolys[0]->weight_angular *= ang_weights[0] * ang_weights[0]; | bpolys[0]->weight_angular *= ang_weights[0] * ang_weights[0]; | ||||
| } | } | ||||
| else if (epolys->num == 2) { | else if (epolys->num == 2) { | ||||
| ang_weights[0] = computeAngularWeight(bpolys[0]->point_edgemid_angles[edge_on_poly[0]]); | ang_weights[0] = computeAngularWeight(bpolys[0]->point_edgemid_angles[edge_on_poly[0]], | ||||
| ang_weights[1] = computeAngularWeight(bpolys[1]->point_edgemid_angles[edge_on_poly[1]]); | bpolys[0]->edgemid_angle); | ||||
| ang_weights[1] = computeAngularWeight(bpolys[1]->point_edgemid_angles[edge_on_poly[1]], | |||||
| bpolys[1]->edgemid_angle); | |||||
| bpolys[0]->weight_angular *= ang_weights[0] * ang_weights[1]; | bpolys[0]->weight_angular *= ang_weights[0] * ang_weights[1]; | ||||
| bpolys[1]->weight_angular *= ang_weights[0] * ang_weights[1]; | bpolys[1]->weight_angular *= ang_weights[0] * ang_weights[1]; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Compute scaling and falloff: | /* Compute scaling and falloff: | ||||
| Show All 21 Lines | for (int i = 0; i < bwdata->numpoly; bpoly++, i++) { | ||||
| bpoly->dominant_edge = 0; | bpoly->dominant_edge = 0; | ||||
| bpoly->dominant_angle_weight = corner_angle_weights[0]; | bpoly->dominant_angle_weight = corner_angle_weights[0]; | ||||
| } | } | ||||
| else { | else { | ||||
| bpoly->dominant_edge = 1; | bpoly->dominant_edge = 1; | ||||
| bpoly->dominant_angle_weight = corner_angle_weights[1]; | bpoly->dominant_angle_weight = corner_angle_weights[1]; | ||||
| } | } | ||||
| /* Check for invalid weights just in case computations fail. */ | |||||
| if (bpoly->dominant_angle_weight < 0 || bpoly->dominant_angle_weight > 1) { | |||||
| freeBindData(bwdata); | |||||
| data->success = MOD_SDEF_BIND_RESULT_GENERIC_ERR; | |||||
| return NULL; | |||||
| } | |||||
| bpoly->dominant_angle_weight = sinf(bpoly->dominant_angle_weight * M_PI_2); | bpoly->dominant_angle_weight = sinf(bpoly->dominant_angle_weight * M_PI_2); | ||||
| /* Compute quadratic angular scale interpolation weight */ | /* Compute quadratic angular scale interpolation weight */ | ||||
| { | { | ||||
| const float edge_angle_a = bpoly->point_edgemid_angles[bpoly->dominant_edge]; | const float edge_angle_a = bpoly->point_edgemid_angles[bpoly->dominant_edge]; | ||||
| const float edge_angle_b = bpoly->point_edgemid_angles[!bpoly->dominant_edge]; | const float edge_angle_b = bpoly->point_edgemid_angles[!bpoly->dominant_edge]; | ||||
| /* Clamp so skinny faces with near zero `edgemid_angle` | /* Clamp so skinny faces with near zero `edgemid_angle` | ||||
| * won't cause numeric problems. see T81988. */ | * won't cause numeric problems. see T81988. */ | ||||
| scale_weight = edge_angle_a / max_ff(edge_angle_a, bpoly->edgemid_angle); | scale_weight = edge_angle_a / max_ff(edge_angle_a, bpoly->edgemid_angle); | ||||
| scale_weight /= scale_weight + (edge_angle_b / max_ff(edge_angle_b, bpoly->edgemid_angle)); | scale_weight /= scale_weight + (edge_angle_b / max_ff(edge_angle_b, bpoly->edgemid_angle)); | ||||
| } | } | ||||
| sqr = scale_weight * scale_weight; | sqr = scale_weight * scale_weight; | ||||
| inv_sqr = 1.0f - scale_weight; | inv_sqr = 1.0f - scale_weight; | ||||
| inv_sqr *= inv_sqr; | inv_sqr *= inv_sqr; | ||||
| scale_weight = sqr / (sqr + inv_sqr); | scale_weight = sqr / (sqr + inv_sqr); | ||||
| BLI_assert(scale_weight >= 0 && scale_weight <= 1); | |||||
| /* Compute interpolated scale (no longer need the individual scales, | /* Compute interpolated scale (no longer need the individual scales, | ||||
| * so simply storing the result over the scale in index zero) */ | * so simply storing the result over the scale in index zero) */ | ||||
| bpoly->scales[0] = bpoly->scales[bpoly->dominant_edge] * (1.0f - scale_weight) + | bpoly->scales[0] = interpf(bpoly->scale_mid, | ||||
| bpoly->scales[!bpoly->dominant_edge] * scale_weight; | interpf(bpoly->scales[!bpoly->dominant_edge], | ||||
| bpoly->scales[bpoly->dominant_edge], | |||||
| scale_weight), | |||||
| bpoly->dominant_angle_weight); | |||||
| /* Scale the point distance weights, and introduce falloff */ | /* Scale the point distance weights, and introduce falloff */ | ||||
| bpoly->weight_dist_proj /= bpoly->scales[0]; | bpoly->weight_dist_proj /= bpoly->scales[0]; | ||||
| bpoly->weight_dist_proj = powf(bpoly->weight_dist_proj, data->falloff); | bpoly->weight_dist_proj = powf(bpoly->weight_dist_proj, data->falloff); | ||||
| bpoly->weight_dist /= avg_point_dist; | bpoly->weight_dist /= avg_point_dist; | ||||
| bpoly->weight_dist = powf(bpoly->weight_dist, data->falloff); | bpoly->weight_dist = powf(bpoly->weight_dist, data->falloff); | ||||
| ▲ Show 20 Lines • Show All 813 Lines • Show Last 20 Lines | |||||