Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/mesh_evaluate.c
| Context not available. | |||||
| return total_area; | return total_area; | ||||
| } | } | ||||
| /* Calculate the volume and volume-weighted centroid of the volume formed by the polygon and the origin. */ | |||||
| /* Results will be negative if the origin is "outside" the polygon (+ve normal side), but the polygon may be non-planar with no effect. */ | |||||
| /* note: volume is 6x actual volume, and centroid is 4x actual volume-weighted centroid (so division can be done once at the end) */ | |||||
| static float mesh_calc_poly_volume_and_weighted_centroid( | |||||
| const MPoly *mpoly, const MLoop *loopstart, const MVert *mvarray, | |||||
| float r_cent[3]) | |||||
| { | |||||
| int i; | |||||
| float tetra_volume; | |||||
| float total_volume = 0.0f; | |||||
| float v1[3], v2[3], v3[3], tetra_cent[3]; | |||||
campbellbarton: No reason to copy into vectors, can assign coords to `const float *` as use them in-place. | |||||
| float v1_cross_v2[3]; | |||||
| copy_v3_v3(v1, mvarray[loopstart[0].v].co); | |||||
| copy_v3_v3(v2, mvarray[loopstart[1].v].co); | |||||
| zero_v3(r_cent); | |||||
| for (i = 2; i < mpoly->totloop; i++) { | |||||
| copy_v3_v3(v3, mvarray[loopstart[i].v].co); | |||||
| // Calculate the 6x volume of the tetrahedron formed by the 3 vertices of the triangle and the origin as the fourth vertex | |||||
| cross_v3_v3v3(v1_cross_v2, v1, v2); | |||||
| tetra_volume = dot_v3v3 (v1_cross_v2, v3); | |||||
| total_volume += tetra_volume; | |||||
| // Calculate the centroid of the tetrahedron formed by the 3 vertices of the triangle and the origin as the fourth vertex | |||||
| // The centroid is simply the average of the 4 vertices. | |||||
| // note that the vector is 4x the actual centroid so the division can be done once at the end | |||||
| add_v3_v3v3(tetra_cent, v1, v2); | |||||
| add_v3_v3(tetra_cent, v3); | |||||
| madd_v3_v3fl(r_cent, tetra_cent, tetra_volume); | |||||
| copy_v3_v3(v2, v3); | |||||
| } | |||||
| return total_volume; | |||||
| } | |||||
| #if 0 /* slow version of the function below */ | #if 0 /* slow version of the function below */ | ||||
| void BKE_mesh_calc_poly_angles(MPoly *mpoly, MLoop *loopstart, | void BKE_mesh_calc_poly_angles(MPoly *mpoly, MLoop *loopstart, | ||||
| MVert *mvarray, float angles[]) | MVert *mvarray, float angles[]) | ||||
| Context not available. | |||||
| return (me->totpoly != 0); | return (me->totpoly != 0); | ||||
| } | } | ||||
| bool BKE_mesh_center_solid_centroid(const Mesh *me, float r_cent[3]) | |||||
| { | |||||
| int i = me->totpoly; | |||||
| MPoly *mpoly; | |||||
| float poly_volume; | |||||
| float total_volume = 0.0f; | |||||
| float poly_cent[3]; | |||||
| zero_v3(r_cent); | |||||
| /* calculate a weighted average of polyhedron centroids */ | |||||
| for (mpoly = me->mpoly; i--; mpoly++) { | |||||
| poly_volume = mesh_calc_poly_volume_and_weighted_centroid(mpoly, me->mloop + mpoly->loopstart, me->mvert, poly_cent); | |||||
| /* poly_cent is already volume-weighted, so no need to multiply by the volume */ | |||||
| add_v3_v3(r_cent, poly_cent); | |||||
| total_volume += poly_volume; | |||||
| } | |||||
| /* otherwise we get NAN for 0 polys */ | |||||
| if (me->totpoly) { | |||||
campbellbartonUnsubmitted Not Done Inline ActionsShould check total_volume != 0.0f instead. campbellbarton: Should check `total_volume != 0.0f` instead. | |||||
| /* multipy by 0.25 to get the correct centroid */ | |||||
| /* no need to divide volume by 6 as the centroid is weighted by 6x the volume, so it all cancels out */ | |||||
| mul_v3_fl(r_cent, 0.25f / total_volume); | |||||
| } | |||||
| /* zero area faces cause this, fallback to median */ | |||||
| if (UNLIKELY(!is_finite_v3(r_cent))) { | |||||
| return BKE_mesh_center_median(me, r_cent); | |||||
| } | |||||
| return (me->totpoly != 0); | |||||
| } | |||||
| /** \} */ | /** \} */ | ||||
| Context not available. | |||||
No reason to copy into vectors, can assign coords to const float * as use them in-place.