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)
127 const int face_index,
128 const float curr_val,
129 const bool use_face_influence)
137 const float weight = wn_data->
weight;
141 const bool has_vgroup = dvert !=
nullptr;
142 const bool vert_of_group = has_vgroup &&
146 ((vert_of_group && use_invert_vgroup) || (!vert_of_group && !use_invert_vgroup)))
167 const int loops_num = item_data->
loops_num;
169 cached_inverse_powers_of_weight[loops_num] == 0.0f)
171 cached_inverse_powers_of_weight[loops_num] = 1.0f /
powf(weight, loops_num);
174 cached_inverse_powers_of_weight[loops_num] :
175 1.0f /
powf(weight, loops_num);
177 madd_v3_v3fl(item_data->
normal, face_normals[face_index], curr_val * inverted_n_weight);
184 const int verts_num = wn_data->
verts_num;
199 const short mode = wn_data->
mode;
206 face_strength !=
nullptr;
207 const bool has_vgroup = dvert !=
nullptr;
243 for (
const int i :
faces.index_range()) {
244 const int face_index = mode_pair[
i].
index;
245 const float mp_val = mode_pair[
i].
val;
247 for (
const int corner :
faces[face_index]) {
248 const int mv_index = corner_verts[corner];
252 &items_data[mv_index];
255 wnmd, wn_data, item_data, mv_index, face_index, mp_val, use_face_influence);
261 for (
int i = 0;
i < corner_verts.
size();
i++) {
262 const int corner = mode_pair[
i].
index;
263 const float ml_val = mode_pair[
i].
val;
266 const int face_index = loop_to_face[corner];
267 const int mv_index = corner_verts[corner];
269 &items_data[mv_index];
272 wnmd, wn_data, item_data, mv_index, face_index, ml_val, use_face_influence);
282 zero_v3(items_data[item_index].normal);
291 for (
int corner = 0; corner < corner_verts.
size(); corner++) {
323 for (
int corner = 0; corner < corner_verts.
size(); corner++) {
324 const int mv_index = corner_verts[corner];
325 copy_v3_v3(vert_normals[mv_index], items_data[mv_index].normal);
354 for (
int corner = 0; corner < corner_verts.
size(); corner++) {
355 const int item_index = corner_verts[corner];
356 if (!
is_zero_v3(items_data[item_index].normal)) {
357 copy_v3_v3(corner_normals[corner], items_data[item_index].normal);
384 for (
const int i :
faces.index_range()) {
403 for (
const int i :
faces.index_range()) {
407 positions, corner_verts.
slice(face), {index_angle, face.size()});
410 float *angl = index_angle;
411 for (
int corner = face.
start(); corner < face.
start() + face.
size();
412 corner++, c_angl++, angl++)
414 c_angl->
val = float(
M_PI) - *angl;
415 c_angl->
index = corner;
434 for (
const int i :
faces.index_range()) {
442 float *angl = index_angle;
443 for (
int corner = face.
start(); corner < face.
start() + face.
size(); corner++, cmbnd++, angl++)
446 cmbnd->val = (float(
M_PI) - *angl) * face_area;
447 cmbnd->index = corner;
466 const int verts_num =
result->verts_num;
478 float weight = float(wnmd->
weight) / 50.0f;
479 if (wnmd->
weight == 100) {
480 weight = float(SHRT_MAX);
482 else if (wnmd->
weight == 1) {
483 weight = 1 / float(SHRT_MAX);
485 else if ((weight - 1) * 25 > 1) {
486 weight = (weight - 1) * 25;
515 wn_data.
clnors = clnors.span;
523 wn_data.
dvert = dvert;
530 switch (wnmd->
mode) {
544 result->runtime->is_original_bmesh =
false;
605 N_(
"WeightedNormal"),
606 "WeightedNormalModifierData",
608 &RNA_WeightedNormalModifier,
const void * CustomData_get_layer_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
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 DNA_struct_default_get(struct_name)
@ 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
@ eModifierType_WeightedNormal
#define MOD_WEIGHTEDNORMALS_FACEWEIGHT_CDLAYER_ID
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)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
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, eCustomDataType data_type, const AttributeInit &initializer=AttributeInitDefaultValue())
VecBase< short, 2 > short2
VecBase< float, 3 > float3
#define CD_MASK_MDEFORMVERT
#define CD_MASK_PROP_INT32
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 int * face_strength
const MDeformVert * dvert
blender::MutableSpan< bool > sharp_edges
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 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)