32#include "RNA_prototypes.hh"
40#define CLNORS_VALID_VEC_LEN (1e-6f)
53 return (r1->
val < r2->
val) ? 1 : ((r1->
val > r2->
val) ? -1 : 0);
66#define NUM_CACHED_INVERSE_POWERS_OF_WEIGHT 128
107 const int face_index)
125 const int face_index,
126 const float curr_val,
127 const bool use_face_influence)
135 const float weight = wn_data->
weight;
139 const bool has_vgroup = dvert !=
nullptr;
140 const bool vert_of_group = has_vgroup &&
144 ((vert_of_group && use_invert_vgroup) || (!vert_of_group && !use_invert_vgroup)))
165 const int loops_num = item_data->
loops_num;
167 cached_inverse_powers_of_weight[loops_num] == 0.0f)
169 cached_inverse_powers_of_weight[loops_num] = 1.0f /
powf(weight, loops_num);
172 cached_inverse_powers_of_weight[loops_num] :
173 1.0f /
powf(weight, loops_num);
175 madd_v3_v3fl(item_data->
normal, face_normals[face_index], curr_val * inverted_n_weight);
182 const int verts_num = wn_data->
verts_num;
197 const short mode = wn_data->
mode;
205 const bool has_vgroup = dvert !=
nullptr;
241 for (
const int i :
faces.index_range()) {
242 const int face_index = mode_pair[
i].
index;
243 const float mp_val = mode_pair[
i].
val;
245 for (
const int corner :
faces[face_index]) {
246 const int mv_index = corner_verts[corner];
250 &items_data[mv_index];
253 wnmd, wn_data, item_data, mv_index, face_index, mp_val, use_face_influence);
259 for (
int i = 0;
i < corner_verts.
size();
i++) {
260 const int corner = mode_pair[
i].
index;
261 const float ml_val = mode_pair[
i].
val;
264 const int face_index = loop_to_face[corner];
265 const int mv_index = corner_verts[corner];
267 &items_data[mv_index];
270 wnmd, wn_data, item_data, mv_index, face_index, ml_val, use_face_influence);
280 zero_v3(items_data[item_index].normal);
289 for (
int corner = 0; corner < corner_verts.
size(); corner++) {
321 for (
int corner = 0; corner < corner_verts.
size(); corner++) {
322 const int mv_index = corner_verts[corner];
323 copy_v3_v3(vert_normals[mv_index], items_data[mv_index].normal);
352 for (
int corner = 0; corner < corner_verts.
size(); corner++) {
353 const int item_index = corner_verts[corner];
354 if (!
is_zero_v3(items_data[item_index].normal)) {
355 copy_v3_v3(corner_normals[corner], items_data[item_index].normal);
382 for (
const int i :
faces.index_range()) {
401 for (
const int i :
faces.index_range()) {
405 positions, corner_verts.
slice(face), {index_angle, face.size()});
408 float *angl = index_angle;
409 for (
int corner = face.
start(); corner < face.
start() + face.
size();
410 corner++, c_angl++, angl++)
413 c_angl->
index = corner;
432 for (
const int i :
faces.index_range()) {
440 float *angl = index_angle;
441 for (
int corner = face.
start(); corner < face.
start() + face.
size(); corner++, cmbnd++, angl++)
444 cmbnd->val = (
float(
M_PI) - *angl) * face_area;
445 cmbnd->index = corner;
464 const int verts_num =
result->verts_num;
477 if (wnmd->
weight == 100) {
478 weight =
float(SHRT_MAX);
480 else if (wnmd->
weight == 1) {
481 weight = 1 /
float(SHRT_MAX);
483 else if ((weight - 1) * 25 > 1) {
484 weight = (weight - 1) * 25;
513 wn_data.
clnors = clnors.span;
521 wn_data.
dvert = dvert;
528 switch (wnmd->
mode) {
542 result->runtime->is_original_bmesh =
false;
603 N_(
"WeightedNormal"),
604 "WeightedNormalModifierData",
606 &RNA_WeightedNormalModifier,
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 DNA_struct_default_get(struct_name)
@ MOD_WEIGHTEDNORMAL_MODE_FACE
@ MOD_WEIGHTEDNORMAL_MODE_FACE_ANGLE
@ MOD_WEIGHTEDNORMAL_MODE_ANGLE
@ eModifierType_WeightedNormal
#define MOD_WEIGHTEDNORMALS_FACEWEIGHT_CDLAYER_ID
@ MOD_WEIGHTEDNORMAL_KEEP_SHARP
@ MOD_WEIGHTEDNORMAL_FACE_INFLUENCE
@ MOD_WEIGHTEDNORMAL_INVERT_VGROUP
Read Guarded memory(de)allocation.
static void init_data(ModifierData *md)
static void panel_register(ARegionType *region_type)
static void required_data_mask(ModifierData *, CustomData_MeshMasks *r_cddata_masks)
static void panel_draw(const bContext *, Panel *panel)
static Mesh * modify_mesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
void modifier_vgroup_ui(uiLayout *layout, PointerRNA *ptr, PointerRNA *ob_ptr, const StringRefNull vgroup_prop, const std::optional< StringRefNull > invert_vgroup_prop, const std::optional< StringRefNull > text)
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_error_message_draw(uiLayout *layout, PointerRNA *ptr)
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)
static void wn_face_with_angle(WeightedNormalModifierData *wnmd, WeightedNormalData *wn_data)
IndexRange index_range() const
void reinitialize(const int64_t new_size)
void reinitialize(const int64_t new_size)
constexpr int64_t size() const
constexpr int64_t start() const
constexpr Span slice(int64_t start, int64_t size) const
constexpr int64_t size() const
GAttributeReader lookup(const StringRef attribute_id) const
GSpanAttributeWriter lookup_or_add_for_write_span(StringRef attribute_id, AttrDomain domain, AttrType data_type, const AttributeInit &initializer=AttributeInitDefaultValue())
VecBase< short, 2 > short2
VecBase< float, 3 > float3
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
void fill_index_range(MutableSpan< T > span, const T start=0)
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, OffsetIndices< int > faces, Span< int > corner_verts, Span< int > corner_edges, GroupedSpan< int > vert_to_face_map, Span< float3 > face_normals, Span< bool > sharp_edges, Span< bool > sharp_faces, Span< short2 > custom_normals, CornerNormalSpaceArray *r_fan_spaces, MutableSpan< float3 > r_corner_normals)
void normals_corner_custom_set_from_verts(Span< float3 > vert_positions, OffsetIndices< int > faces, Span< int > corner_verts, Span< int > corner_edges, GroupedSpan< int > vert_to_face_map, 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 normals_corner_custom_set(Span< float3 > vert_positions, OffsetIndices< int > faces, Span< int > corner_verts, Span< int > corner_edges, GroupedSpan< int > vert_to_face_map, 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::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 MDeformVert * dvert
blender::MutableSpan< bool > sharp_edges
blender::VArray< int > face_strength
blender::OffsetIndices< int > faces
blender::GroupedSpan< int > vert_to_face_map
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
Vector< CornerNormalSpace > spaces
uiLayout & column(bool align)
void use_property_split_set(bool value)
void prop(PointerRNA *ptr, PropertyRNA *prop, int index, int value, eUI_Item_Flag flag, std::optional< blender::StringRef > name_opt, int icon, std::optional< blender::StringRef > placeholder=std::nullopt)