diff options
Diffstat (limited to 'source')
7 files changed, 137 insertions, 32 deletions
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index d68712202c9..9463ea81bfc 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -278,7 +278,8 @@ void BKE_mesh_poly_edgebitmap_insert( bool BKE_mesh_center_median(const struct Mesh *me, float r_cent[3]); bool BKE_mesh_center_bounds(const struct Mesh *me, float r_cent[3]); -bool BKE_mesh_center_centroid(const struct Mesh *me, float r_cent[3]); +bool BKE_mesh_center_of_surface(const struct Mesh *me, float r_cent[3]); +bool BKE_mesh_center_of_volume(const struct Mesh *me, float r_cent[3]); void BKE_mesh_calc_volume( const struct MVert *mverts, const int mverts_num, diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c index ca8b58ffae3..654a25cbb3d 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.c +++ b/source/blender/blenkernel/intern/mesh_evaluate.c @@ -1856,11 +1856,14 @@ float BKE_mesh_calc_poly_area( * - http://forums.cgsociety.org/archive/index.php?t-756235.html * - http://www.globalspec.com/reference/52702/203279/4-8-the-centroid-of-a-tetrahedron * - * \note volume is 6x actual volume, and centroid is 4x actual volume-weighted centroid - * (so division can be done once at the end) - * \note results will have bias if polygon is non-planar. + * \note + * - Volume is 6x actual volume, and centroid is 4x actual volume-weighted centroid + * (so division can be done once at the end). + * - Results will have bias if polygon is non-planar. + * - The resulting volume will only be correct if the mesh is manifold and has consistent face winding + * (non-contiguous face normals or holes in the mesh surface). */ -static float mesh_calc_poly_volume_and_weighted_centroid( +static float mesh_calc_poly_volume_centroid( const MPoly *mpoly, const MLoop *loopstart, const MVert *mvarray, float r_cent[3]) { @@ -1897,6 +1900,43 @@ static float mesh_calc_poly_volume_and_weighted_centroid( return total_volume; } +/** + * \note + * - Results won't be correct if polygon is non-planar. + * - This has the advantage over #mesh_calc_poly_volume_centroid + * that it doesn't depend on solid geometry, instead it weights the surface by volume. + */ +static float mesh_calc_poly_area_centroid( + const MPoly *mpoly, const MLoop *loopstart, const MVert *mvarray, + float r_cent[3]) +{ + int i; + float tri_area; + float total_area = 0.0f; + float v1[3], v2[3], v3[3], normal[3], tri_cent[3]; + + BKE_mesh_calc_poly_normal(mpoly, loopstart, mvarray, normal); + 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); + + tri_area = area_tri_signed_v3(v1, v2, v3, normal); + total_area += tri_area; + + mid_v3_v3v3v3(tri_cent, v1, v2, v3); + madd_v3_v3fl(r_cent, tri_cent, tri_area); + + copy_v3_v3(v2, v3); + } + + mul_v3_fl(r_cent, 1.0f / total_area); + + return total_area; +} + #if 0 /* slow version of the function below */ void BKE_mesh_calc_poly_angles(MPoly *mpoly, MLoop *loopstart, MVert *mvarray, float angles[]) @@ -2011,7 +2051,40 @@ bool BKE_mesh_center_bounds(const Mesh *me, float r_cent[3]) return false; } -bool BKE_mesh_center_centroid(const Mesh *me, float r_cent[3]) +bool BKE_mesh_center_of_surface(const Mesh *me, float r_cent[3]) +{ + int i = me->totpoly; + MPoly *mpoly; + float poly_area; + float total_area = 0.0f; + float poly_cent[3]; + + zero_v3(r_cent); + + /* calculate a weighted average of polygon centroids */ + for (mpoly = me->mpoly; i--; mpoly++) { + poly_area = mesh_calc_poly_area_centroid(mpoly, me->mloop + mpoly->loopstart, me->mvert, poly_cent); + + madd_v3_v3fl(r_cent, poly_cent, poly_area); + total_area += poly_area; + } + /* otherwise we get NAN for 0 polys */ + if (me->totpoly) { + mul_v3_fl(r_cent, 1.0f / total_area); + } + + /* 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); +} + +/** + * \note Mesh must be manifold with consistent face-winding, see #mesh_calc_poly_volume_centroid for details. + */ +bool BKE_mesh_center_of_volume(const Mesh *me, float r_cent[3]) { int i = me->totpoly; MPoly *mpoly; @@ -2023,7 +2096,7 @@ bool BKE_mesh_center_centroid(const Mesh *me, float r_cent[3]) /* 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_volume = mesh_calc_poly_volume_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); @@ -2043,6 +2116,7 @@ bool BKE_mesh_center_centroid(const Mesh *me, float r_cent[3]) return (me->totpoly != 0); } + /** \} */ diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c index 4f758bde7f9..ac9c60e8999 100644 --- a/source/blender/blenkernel/intern/particle_distribute.c +++ b/source/blender/blenkernel/intern/particle_distribute.c @@ -429,7 +429,6 @@ static void distribute_from_verts_exec(ParticleTask *thread, ParticleData *pa, i ParticleThreadContext *ctx= thread->ctx; MFace *mface; - DM_ensure_tessface(ctx->dm); mface = ctx->dm->getTessFaceDataArray(ctx->dm, CD_MFACE); int rng_skip_tot = PSYS_RND_DIST_SKIP; /* count how many rng_* calls wont need skipping */ @@ -899,10 +898,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti else dm= CDDM_from_mesh((Mesh*)ob->data); - /* BMESH ONLY, for verts we don't care about tessfaces */ - if (from != PART_FROM_VERT) { - DM_ensure_tessface(dm); - } + DM_ensure_tessface(dm); /* we need orco for consistent distributions */ if (!CustomData_has_layer(&dm->vertData, CD_ORCO)) diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index 1baa1926bd2..32c342f9f02 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -734,7 +734,8 @@ enum { GEOMETRY_TO_ORIGIN = 0, ORIGIN_TO_GEOMETRY, ORIGIN_TO_CURSOR, - ORIGIN_TO_CENTER_OF_MASS + ORIGIN_TO_CENTER_OF_MASS_SURFACE, + ORIGIN_TO_CENTER_OF_MASS_VOLUME, }; static int object_origin_set_exec(bContext *C, wmOperator *op) @@ -891,10 +892,21 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) if (obedit == NULL && ob->type == OB_MESH) { Mesh *me = ob->data; - if (centermode == ORIGIN_TO_CURSOR) { /* done */ } - else if (centermode == ORIGIN_TO_CENTER_OF_MASS) { BKE_mesh_center_centroid(me, cent); } - else if (around == V3D_AROUND_CENTER_MEAN) { BKE_mesh_center_median(me, cent); } - else { BKE_mesh_center_bounds(me, cent); } + if (centermode == ORIGIN_TO_CURSOR) { + /* done */ + } + else if (centermode == ORIGIN_TO_CENTER_OF_MASS_SURFACE) { + BKE_mesh_center_of_surface(me, cent); + } + else if (centermode == ORIGIN_TO_CENTER_OF_MASS_VOLUME) { + BKE_mesh_center_of_volume(me, cent); + } + else if (around == V3D_AROUND_CENTER_MEAN) { + BKE_mesh_center_median(me, cent); + } + else { + BKE_mesh_center_bounds(me, cent); + } negate_v3_v3(cent_neg, cent); BKE_mesh_translate(me, cent_neg, 1); @@ -1105,11 +1117,14 @@ void OBJECT_OT_origin_set(wmOperatorType *ot) static EnumPropertyItem prop_set_center_types[] = { {GEOMETRY_TO_ORIGIN, "GEOMETRY_ORIGIN", 0, "Geometry to Origin", "Move object geometry to object origin"}, {ORIGIN_TO_GEOMETRY, "ORIGIN_GEOMETRY", 0, "Origin to Geometry", - "Move object origin to center of object geometry"}, + "Calculate the center of geometry based on the current pivot point (median, otherwise bounding-box)"}, {ORIGIN_TO_CURSOR, "ORIGIN_CURSOR", 0, "Origin to 3D Cursor", - "Move object origin to position of the 3D cursor"}, - {ORIGIN_TO_CENTER_OF_MASS, "ORIGIN_CENTER_OF_MASS", 0, "Origin to Center of Mass", - "Move object origin to the object center of mass (assuming uniform density)"}, + "Move object origin to position of the 3D cursor"}, + /* Intentional naming mismatch since some scripts refer to this. */ + {ORIGIN_TO_CENTER_OF_MASS_SURFACE, "ORIGIN_CENTER_OF_MASS", 0, "Origin to Center of Mass (Surface)", + "Calculate the center of mass from the surface area"}, + {ORIGIN_TO_CENTER_OF_MASS_VOLUME, "ORIGIN_CENTER_OF_VOLUME", 0, "Origin to Center of Mass (Volume)", + "Calculate the center of mass from the volume (must be manifold geometry with consistent normals)"}, {0, NULL, 0, NULL, NULL} }; diff --git a/source/blender/nodes/shader/nodes/node_shader_fresnel.c b/source/blender/nodes/shader/nodes/node_shader_fresnel.c index e78bb2b0b24..b285f1a8a3e 100644 --- a/source/blender/nodes/shader/nodes/node_shader_fresnel.c +++ b/source/blender/nodes/shader/nodes/node_shader_fresnel.c @@ -51,14 +51,23 @@ static int node_shader_gpu_fresnel(GPUMaterial *mat, bNode *node, bNodeExecData return GPU_stack_link(mat, node, "node_fresnel", in, out, GPU_builtin(GPU_VIEW_POSITION)); } -static void node_shader_exec_fresnel(void *data, int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out) +static void node_shader_exec_fresnel(void *data, int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out) { ShadeInput *shi = ((ShaderCallData *)data)->shi; - float eta = max_ff(in[0]->vec[0], 0.00001); + + /* Compute IOR. */ + float eta; + nodestack_get_vec(&eta, SOCK_FLOAT, in[0]); + eta = max_ff(eta, 0.00001); + eta = shi->flippednor ? 1 / eta : eta; + + /* Get normal from socket, but only if linked. */ + bNodeSocket *sock_normal = node->inputs.first; + sock_normal = sock_normal->next; float n[3]; - if (in[1]->hasinput) { - copy_v3_v3(n, in[1]->vec); + if (sock_normal->link) { + nodestack_get_vec(n, SOCK_VECTOR, in[1]); } else { copy_v3_v3(n, shi->vn); @@ -68,7 +77,7 @@ static void node_shader_exec_fresnel(void *data, int UNUSED(thread), bNode *UNUS mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEW_MATRIX), n); } - out[0]->vec[0] = RE_fresnel_dielectric(shi->view, n, shi->flippednor ? 1 / eta : eta); + out[0]->vec[0] = RE_fresnel_dielectric(shi->view, n, eta); } /* node type definition */ diff --git a/source/blender/nodes/shader/nodes/node_shader_layer_weight.c b/source/blender/nodes/shader/nodes/node_shader_layer_weight.c index e84d8e7241c..3ab73fdde18 100644 --- a/source/blender/nodes/shader/nodes/node_shader_layer_weight.c +++ b/source/blender/nodes/shader/nodes/node_shader_layer_weight.c @@ -52,24 +52,33 @@ static int node_shader_gpu_layer_weight(GPUMaterial *mat, bNode *node, bNodeExec return GPU_stack_link(mat, node, "node_layer_weight", in, out, GPU_builtin(GPU_VIEW_POSITION)); } -static void node_shader_exec_layer_weight(void *data, int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out) +static void node_shader_exec_layer_weight(void *data, int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out) { ShadeInput *shi = ((ShaderCallData *)data)->shi; - float blend = in[0]->vec[0]; + + /* Compute IOR. */ + float blend; + nodestack_get_vec(&blend, SOCK_FLOAT, in[0]); float eta = max_ff(1 - blend, 0.00001); + eta = shi->flippednor ? eta : 1 / eta; + + /* Get normal from socket, but only if linked. */ + bNodeSocket *sock_normal = node->inputs.first; + sock_normal = sock_normal->next; float n[3]; - if (in[1]->hasinput) { - copy_v3_v3(n, in[1]->vec); + if (sock_normal->link) { + nodestack_get_vec(n, SOCK_VECTOR, in[1]); } else { copy_v3_v3(n, shi->vn); } + if (shi->use_world_space_shading) mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEW_MATRIX), n); - out[0]->vec[0] = RE_fresnel_dielectric(shi->view, n, shi->flippednor ? eta : 1 / eta); + out[0]->vec[0] = RE_fresnel_dielectric(shi->view, n, eta); float facing = fabs(dot_v3v3(shi->view, n)); if (blend != 0.5) { diff --git a/source/gameengine/Expressions/EXP_PyObjectPlus.h b/source/gameengine/Expressions/EXP_PyObjectPlus.h index 32dc79cf6eb..504d79f7cbb 100644 --- a/source/gameengine/Expressions/EXP_PyObjectPlus.h +++ b/source/gameengine/Expressions/EXP_PyObjectPlus.h @@ -44,7 +44,8 @@ #include "STR_String.h" #include "MT_Vector3.h" #include "SG_QList.h" -#include <stddef.h> +#include <cstddef> +#include <cstdint> #ifdef WITH_PYTHON #ifdef USE_MATHUTILS |