Math Lib: avoid having to pass a pre-calculated normal tot area_poly_v3
add normal_poly_v3
This commit is contained in:
parent
e4c2a3c31c
commit
28a829893c
|
@ -192,7 +192,7 @@ void BKE_mesh_calc_poly_center(
|
|||
struct MVert *mvarray, float cent[3]);
|
||||
float BKE_mesh_calc_poly_area(
|
||||
struct MPoly *mpoly, struct MLoop *loopstart,
|
||||
struct MVert *mvarray, const float polynormal[3]);
|
||||
struct MVert *mvarray);
|
||||
void BKE_mesh_calc_poly_angles(
|
||||
struct MPoly *mpoly, struct MLoop *loopstart,
|
||||
struct MVert *mvarray, float angles[]);
|
||||
|
|
|
@ -872,7 +872,7 @@ void BKE_mesh_calc_poly_center(MPoly *mpoly, MLoop *loopstart,
|
|||
|
||||
/* note, passing polynormal is only a speedup so we can skip calculating it */
|
||||
float BKE_mesh_calc_poly_area(MPoly *mpoly, MLoop *loopstart,
|
||||
MVert *mvarray, const float polynormal[3])
|
||||
MVert *mvarray)
|
||||
{
|
||||
if (mpoly->totloop == 3) {
|
||||
return area_tri_v3(mvarray[loopstart[0].v].co,
|
||||
|
@ -890,22 +890,16 @@ float BKE_mesh_calc_poly_area(MPoly *mpoly, MLoop *loopstart,
|
|||
else {
|
||||
int i;
|
||||
MLoop *l_iter = loopstart;
|
||||
float area, polynorm_local[3];
|
||||
float area;
|
||||
float (*vertexcos)[3] = BLI_array_alloca(vertexcos, (size_t)mpoly->totloop);
|
||||
const float *no = polynormal ? polynormal : polynorm_local;
|
||||
|
||||
/* pack vertex cos into an array for area_poly_v3 */
|
||||
for (i = 0; i < mpoly->totloop; i++, l_iter++) {
|
||||
copy_v3_v3(vertexcos[i], mvarray[l_iter->v].co);
|
||||
}
|
||||
|
||||
/* need normal for area_poly_v3 as well */
|
||||
if (polynormal == NULL) {
|
||||
BKE_mesh_calc_poly_normal(mpoly, loopstart, mvarray, polynorm_local);
|
||||
}
|
||||
|
||||
/* finally calculate the area */
|
||||
area = area_poly_v3((const float (*)[3])vertexcos, (unsigned int)mpoly->totloop, no);
|
||||
area = area_poly_v3((const float (*)[3])vertexcos, (unsigned int)mpoly->totloop);
|
||||
|
||||
return area;
|
||||
}
|
||||
|
|
|
@ -693,7 +693,7 @@ static void get_dupliface_transform(MPoly *mpoly, MLoop *mloop, MVert *mvert,
|
|||
}
|
||||
/* scale */
|
||||
if (use_scale) {
|
||||
float area = BKE_mesh_calc_poly_area(mpoly, mloop, mvert, f_no);
|
||||
float area = BKE_mesh_calc_poly_area(mpoly, mloop, mvert);
|
||||
scale = sqrtf(area) * scale_fac;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -49,13 +49,14 @@ void cent_quad_v3(float r[3], const float a[3], const float b[3], const float c[
|
|||
|
||||
float normal_tri_v3(float r[3], const float a[3], const float b[3], const float c[3]);
|
||||
float normal_quad_v3(float r[3], const float a[3], const float b[3], const float c[3], const float d[3]);
|
||||
float normal_poly_v3(float r[3], const float verts[][3], unsigned int nr);
|
||||
|
||||
MINLINE float area_tri_v2(const float a[2], const float b[2], const float c[2]);
|
||||
MINLINE float area_tri_signed_v2(const float v1[2], const float v2[2], const float v3[2]);
|
||||
float area_tri_v3(const float a[3], const float b[3], const float c[3]);
|
||||
float area_tri_signed_v3(const float v1[3], const float v2[3], const float v3[3], const float normal[3]);
|
||||
float area_quad_v3(const float a[3], const float b[3], const float c[3], const float d[3]);
|
||||
float area_poly_v3(const float verts[][3], unsigned int nr, const float normal[3]);
|
||||
float area_poly_v3(const float verts[][3], unsigned int nr);
|
||||
float area_poly_v2(const float verts[][2], unsigned int nr);
|
||||
float cotangent_tri_weight_v3(const float v1[3], const float v2[3], const float v3[3]);
|
||||
|
||||
|
|
|
@ -88,6 +88,27 @@ float normal_quad_v3(float n[3], const float v1[3], const float v2[3], const flo
|
|||
return normalize_v3(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the normal of a planar
|
||||
* polygon See Graphics Gems for
|
||||
* computing newell normal.
|
||||
*/
|
||||
float normal_poly_v3(float n[3], const float verts[][3], unsigned int nr)
|
||||
{
|
||||
float const *v_prev = verts[nr - 1];
|
||||
float const *v_curr = verts[0];
|
||||
unsigned int i;
|
||||
|
||||
zero_v3(n);
|
||||
|
||||
/* Newell's Method */
|
||||
for (i = 0; i < nr; v_prev = v_curr, v_curr = verts[++i]) {
|
||||
add_newell_cross_v3_v3v3(n, v_prev, v_curr);
|
||||
}
|
||||
|
||||
return normalize_v3(n);
|
||||
}
|
||||
|
||||
/* only convex Quadrilaterals */
|
||||
float area_quad_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3])
|
||||
{
|
||||
|
@ -134,25 +155,10 @@ float area_tri_signed_v3(const float v1[3], const float v2[3], const float v3[3]
|
|||
return area;
|
||||
}
|
||||
|
||||
float area_poly_v3(const float verts[][3], unsigned int nr, const float normal[3])
|
||||
float area_poly_v3(const float verts[][3], unsigned int nr)
|
||||
{
|
||||
unsigned int a;
|
||||
int px, py;
|
||||
const float max = axis_dominant_v3_max(&px, &py, normal);
|
||||
float area;
|
||||
const float *co_curr, *co_prev;
|
||||
|
||||
/* The Trapezium Area Rule */
|
||||
co_prev = verts[nr - 1];
|
||||
co_curr = verts[0];
|
||||
area = 0.0f;
|
||||
for (a = 0; a < nr; a++) {
|
||||
area += (co_curr[px] - co_prev[px]) * (co_curr[py] + co_prev[py]);
|
||||
co_prev = co_curr;
|
||||
co_curr += 3;
|
||||
}
|
||||
|
||||
return fabsf(0.5f * area / max);
|
||||
float n[3];
|
||||
return normal_poly_v3(n, verts, nr) * 0.5f;
|
||||
}
|
||||
|
||||
float cross_poly_v2(const float verts[][2], unsigned int nr)
|
||||
|
|
|
@ -69,34 +69,10 @@ static bool testedgesidef(const float v1[2], const float v2[2], const float v3[2
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief COMPUTE POLY NORMAL
|
||||
*
|
||||
* Computes the normal of a planar
|
||||
* polygon See Graphics Gems for
|
||||
* computing newell normal.
|
||||
*/
|
||||
static void calc_poly_normal(float normal[3], float verts[][3], int nverts)
|
||||
{
|
||||
float const *v_prev = verts[nverts - 1];
|
||||
float const *v_curr = verts[0];
|
||||
float n[3] = {0.0f};
|
||||
int i;
|
||||
|
||||
/* Newell's Method */
|
||||
for (i = 0; i < nverts; v_prev = v_curr, v_curr = verts[++i]) {
|
||||
add_newell_cross_v3_v3v3(n, v_prev, v_curr);
|
||||
}
|
||||
|
||||
if (UNLIKELY(normalize_v3_v3(normal, n) == 0.0f)) {
|
||||
normal[2] = 1.0f; /* other axis set to 0.0 */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief COMPUTE POLY NORMAL (BMFace)
|
||||
*
|
||||
* Same as #calc_poly_normal but operates directly on a bmesh face.
|
||||
* Same as #normal_poly_v3 but operates directly on a bmesh face.
|
||||
*/
|
||||
static void bm_face_calc_poly_normal(const BMFace *f, float n[3])
|
||||
{
|
||||
|
@ -229,15 +205,15 @@ void BM_face_calc_tessellation(const BMFace *f, BMLoop **r_loops, unsigned int (
|
|||
*/
|
||||
float BM_face_calc_area(BMFace *f)
|
||||
{
|
||||
BMLoop *l;
|
||||
BMIter iter;
|
||||
BMLoop *l_iter, *l_first;
|
||||
float (*verts)[3] = BLI_array_alloca(verts, f->len);
|
||||
float area;
|
||||
int i;
|
||||
unsigned int i = 0;
|
||||
|
||||
BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, i) {
|
||||
copy_v3_v3(verts[i], l->v->co);
|
||||
}
|
||||
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
|
||||
do {
|
||||
copy_v3_v3(verts[i++], l_iter->v->co);
|
||||
} while ((l_iter = l_iter->next) != l_first);
|
||||
|
||||
if (f->len == 3) {
|
||||
area = area_tri_v3(verts[0], verts[1], verts[2]);
|
||||
|
@ -246,9 +222,7 @@ float BM_face_calc_area(BMFace *f)
|
|||
area = area_quad_v3(verts[0], verts[1], verts[2], verts[3]);
|
||||
}
|
||||
else {
|
||||
float normal[3];
|
||||
calc_poly_normal(normal, verts, f->len);
|
||||
area = area_poly_v3((const float (*)[3])verts, f->len, normal);
|
||||
area = area_poly_v3((const float (*)[3])verts, f->len);
|
||||
}
|
||||
|
||||
return area;
|
||||
|
|
|
@ -398,7 +398,7 @@ static float rna_MeshPolygon_area_get(PointerRNA *ptr)
|
|||
Mesh *me = (Mesh *)ptr->id.data;
|
||||
MPoly *mp = (MPoly *)ptr->data;
|
||||
|
||||
return BKE_mesh_calc_poly_area(mp, me->mloop + mp->loopstart, me->mvert, NULL);
|
||||
return BKE_mesh_calc_poly_area(mp, me->mloop + mp->loopstart, me->mvert);
|
||||
}
|
||||
|
||||
static void rna_MeshTessFace_normal_get(PointerRNA *ptr, float *values)
|
||||
|
|
Loading…
Reference in New Issue