37#include "RNA_prototypes.hh"
45#define CLNORS_VALID_VEC_LEN (1e-6f)
58 return (r1->
val < r2->
val) ? 1 : ((r1->
val > r2->
val) ? -1 : 0);
71#define NUM_CACHED_INVERSE_POWERS_OF_WEIGHT 128
113 const int face_index)
133 const int face_index,
134 const float curr_val,
135 const bool use_face_influence)
143 const float weight = wn_data->
weight;
147 const bool has_vgroup = dvert !=
nullptr;
148 const bool vert_of_group = has_vgroup &&
152 ((vert_of_group && use_invert_vgroup) || (!vert_of_group && !use_invert_vgroup)))
173 const int loops_num = item_data->
loops_num;
175 cached_inverse_powers_of_weight[loops_num] == 0.0f)
177 cached_inverse_powers_of_weight[loops_num] = 1.0f /
powf(weight, loops_num);
180 cached_inverse_powers_of_weight[loops_num] :
181 1.0f /
powf(weight, loops_num);
183 madd_v3_v3fl(item_data->
normal, face_normals[face_index], curr_val * inverted_n_weight);
190 const int verts_num = wn_data->
verts_num;
206 const short mode = wn_data->
mode;
214 face_strength !=
nullptr;
215 const bool has_vgroup = dvert !=
nullptr;
224 bke::mesh::normals_calc_corners(positions,
234 has_clnors ? clnors.
data() :
nullptr,
253 for (
const int i : faces.index_range()) {
254 const int face_index = mode_pair[i].
index;
255 const float mp_val = mode_pair[i].
val;
257 for (
const int corner : faces[face_index]) {
258 const int mv_index = corner_verts[corner];
262 &items_data[mv_index];
265 wnmd, wn_data, item_data, mv_index, face_index, mp_val, use_face_influence);
271 for (
int i = 0; i < corner_verts.
size(); i++) {
272 const int corner = mode_pair[i].
index;
273 const float ml_val = mode_pair[i].
val;
276 const int face_index = loop_to_face[corner];
277 const int mv_index = corner_verts[corner];
279 &items_data[mv_index];
282 wnmd, wn_data, item_data, mv_index, face_index, ml_val, use_face_influence);
292 zero_v3(items_data[item_index].normal);
301 for (
int corner = 0; corner < corner_verts.
size(); corner++) {
333 for (
int corner = 0; corner < corner_verts.
size(); corner++) {
334 const int mv_index = corner_verts[corner];
335 copy_v3_v3(vert_normals[mv_index], items_data[mv_index].normal);
362 has_clnors ? clnors.
data() :
nullptr,
366 for (
int corner = 0; corner < corner_verts.
size(); corner++) {
367 const int item_index = corner_verts[corner];
368 if (!
is_zero_v3(items_data[item_index].normal)) {
369 copy_v3_v3(corner_normals[corner], items_data[item_index].normal);
397 for (
const int i : faces.index_range()) {
417 for (
const int i : faces.index_range()) {
419 float *index_angle =
static_cast<float *
>(
422 positions, corner_verts.
slice(face), {index_angle, face.size()});
424 ModePair *c_angl = &corner_angle[face.start()];
425 float *angl = index_angle;
426 for (
int corner = face.start(); corner < face.start() + face.size();
427 corner++, c_angl++, angl++)
430 c_angl->
index = corner;
450 for (
const int i : faces.index_range()) {
454 float *index_angle =
static_cast<float *
>(
458 ModePair *cmbnd = &combined[face.start()];
459 float *angl = index_angle;
460 for (
int corner = face.start(); corner < face.start() + face.size(); corner++, cmbnd++, angl++)
464 cmbnd->index = corner;
483 const int verts_num = result->verts_num;
486 const OffsetIndices faces = result->faces();
497 if (wnmd->
weight == 100) {
498 weight =
float(SHRT_MAX);
500 else if (wnmd->
weight == 1) {
501 weight = 1 /
float(SHRT_MAX);
503 else if ((weight - 1) * 25 > 1) {
504 weight = (weight - 1) * 25;
512 const bool has_clnors = clnors !=
nullptr;
522 const Span<int> loop_to_face_map = result->corner_to_face_map();
526 "sharp_edge", bke::AttrDomain::Edge);
531 wn_data.vert_positions = positions;
532 wn_data.vert_normals = result->vert_normals();
533 wn_data.edges = edges;
534 wn_data.sharp_edges = sharp_edges.
span;
536 wn_data.corner_verts = corner_verts;
537 wn_data.corner_edges = corner_edges;
538 wn_data.loop_to_face = loop_to_face_map;
539 wn_data.clnors = {clnors, mesh->corners_num};
540 wn_data.has_clnors = has_clnors;
542 wn_data.faces =
faces;
543 wn_data.face_normals = mesh->face_normals();
544 wn_data.sharp_faces = *attributes.lookup<
bool>(
"sharp_face", bke::AttrDomain::Face);
548 wn_data.dvert = dvert;
549 wn_data.defgrp_index = defgrp_index;
552 wn_data.weight = weight;
553 wn_data.mode = wnmd->
mode;
555 switch (wnmd->
mode) {
569 result->runtime->is_original_bmesh =
false;
631 N_(
"WeightedNormal"),
632 "WeightedNormalModifierData",
634 &RNA_WeightedNormalModifier,
const void * CustomData_get_layer_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
void * CustomData_get_layer_for_write(CustomData *data, eCustomDataType type, int totelem)
void * CustomData_add_layer(CustomData *data, eCustomDataType type, eCDAllocType alloctype, int totelem)
ID * BKE_id_copy_ex(Main *bmain, const ID *id, ID **new_id_p, int flag)
void BKE_modifier_copydata_generic(const ModifierData *md, ModifierData *md_dst, int flag)
@ eModifierTypeFlag_SupportsMapping
@ eModifierTypeFlag_EnableInEditmode
@ eModifierTypeFlag_SupportsEditmode
@ eModifierTypeFlag_AcceptsMesh
#define BLI_assert_unreachable()
MINLINE int compare_ff(float a, float b, float max_diff)
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE bool is_zero_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void zero_v3(float r[3])
MINLINE float normalize_v3(float n[3])
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
#define CD_MASK_MDEFORMVERT
#define CD_MASK_PROP_INT32
#define CD_MASK_CUSTOMLOOPNORMAL
#define DNA_struct_default_get(struct_name)
struct WeightedNormalModifierData WeightedNormalModifierData
@ eModifierType_WeightedNormal
#define MOD_WEIGHTEDNORMALS_FACEWEIGHT_CDLAYER_ID
@ MOD_WEIGHTEDNORMAL_MODE_FACE
@ MOD_WEIGHTEDNORMAL_MODE_FACE_ANGLE
@ MOD_WEIGHTEDNORMAL_MODE_ANGLE
@ MOD_WEIGHTEDNORMAL_KEEP_SHARP
@ MOD_WEIGHTEDNORMAL_FACE_INFLUENCE
@ MOD_WEIGHTEDNORMAL_INVERT_VGROUP
Object is a sort of wrapper for general info.
Read Guarded memory(de)allocation.
void modifier_panel_end(uiLayout *layout, PointerRNA *ptr)
PanelType * modifier_panel_register(ARegionType *region_type, ModifierType type, PanelDrawFn draw)
PointerRNA * modifier_panel_get_property_pointers(Panel *panel, PointerRNA *r_ob_ptr)
void modifier_vgroup_ui(uiLayout *layout, PointerRNA *ptr, PointerRNA *ob_ptr, const char *vgroup_prop, const char *invert_vgroup_prop, const char *text)
void MOD_get_vgroup(const Object *ob, const Mesh *mesh, const char *name, const MDeformVert **dvert, int *defgrp_index)
static void init_data(ModifierData *md)
static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, WeightedNormalData *wn_data)
static void aggregate_item_normal(WeightedNormalModifierData *wnmd, WeightedNormalData *wn_data, WeightedNormalDataAggregateItem *item_data, const int mv_index, const int face_index, const float curr_val, const bool use_face_influence)
static void panel_register(ARegionType *region_type)
static void wn_corner_angle(WeightedNormalModifierData *wnmd, WeightedNormalData *wn_data)
static void wn_face_area(WeightedNormalModifierData *wnmd, WeightedNormalData *wn_data)
#define NUM_CACHED_INVERSE_POWERS_OF_WEIGHT
static Mesh * modify_mesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
ModifierTypeInfo modifierType_WeightedNormal
static int modepair_cmp_by_val_inverse(const void *p1, const void *p2)
static bool check_item_face_strength(WeightedNormalData *wn_data, WeightedNormalDataAggregateItem *item_data, const int face_index)
static void panel_draw(const bContext *, Panel *panel)
static void required_data_mask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
#define CLNORS_VALID_VEC_LEN
static void wn_face_with_angle(WeightedNormalModifierData *wnmd, WeightedNormalData *wn_data)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
IndexRange index_range() const
void reinitialize(const int64_t new_size)
constexpr T * data() const
constexpr Span slice(int64_t start, int64_t size) const
constexpr int64_t size() const
draw_view in_light_buf[] float
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
void normals_corner_custom_set_from_verts(Span< float3 > vert_positions, Span< int2 > edges, OffsetIndices< int > faces, Span< int > corner_verts, Span< int > corner_edges, Span< float3 > vert_normals, Span< float3 > face_normals, Span< bool > sharp_faces, MutableSpan< bool > sharp_edges, MutableSpan< float3 > r_custom_vert_normals, MutableSpan< short2 > r_clnors_data)
void face_angles_calc(Span< float3 > vert_positions, Span< int > face_verts, MutableSpan< float > angles)
float face_area_calc(Span< float3 > vert_positions, Span< int > face_verts)
void normals_calc_corners(Span< float3 > vert_positions, Span< int2 > edges, OffsetIndices< int > faces, Span< int > corner_verts, Span< int > corner_edges, Span< int > corner_to_face_map, Span< float3 > vert_normals, Span< float3 > face_normals, Span< bool > sharp_edges, Span< bool > sharp_faces, const short2 *clnors_data, CornerNormalSpaceArray *r_lnors_spacearr, MutableSpan< float3 > r_corner_normals)
void normals_corner_custom_set(Span< float3 > vert_positions, Span< int2 > edges, OffsetIndices< int > faces, Span< int > corner_verts, Span< int > corner_edges, Span< float3 > vert_normals, Span< float3 > face_normals, Span< bool > sharp_faces, MutableSpan< bool > sharp_edges, MutableSpan< float3 > r_custom_corner_normals, MutableSpan< short2 > r_clnors_data)
blender::MutableSpan< blender::short2 > clnors
blender::Span< int > corner_edges
blender::Span< int > loop_to_face
blender::Span< blender::int2 > edges
blender::VArraySpan< bool > sharp_faces
blender::Span< WeightedNormalDataAggregateItem > items_data
blender::Span< int > corner_verts
blender::Span< blender::float3 > vert_positions
blender::Span< blender::float3 > face_normals
const int * face_strength
const MDeformVert * dvert
blender::MutableSpan< bool > sharp_edges
blender::OffsetIndices< int > faces
blender::Span< blender::float3 > vert_normals
float cached_inverse_powers_of_weight[NUM_CACHED_INVERSE_POWERS_OF_WEIGHT]
MutableVArraySpan< T > span
Array< int > corner_space_indices
Array< CornerNormalSpace > spaces