Fix #119178: Geometry Nodes: Its possible to write non-normalized quaternion attribute from python API #119628

Open
Lleu Yang wants to merge 2 commits from megakite/blender:fix-119178 into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
1 changed files with 17 additions and 0 deletions

View File

@ -21,6 +21,7 @@
#include "DNA_pointcloud_types.h"
#include "BLI_math_color.h"
#include "BLI_math_quaternion.hh"
#include "BKE_attribute.hh"
#include "BKE_customdata.hh"
@ -306,6 +307,21 @@ static int rna_Attribute_domain_get(PointerRNA *ptr)
BKE_id_attribute_domain(ptr->owner_id, static_cast<const CustomDataLayer *>(ptr->data)));
}
static void rna_Attribute_quaternion_value_set(PointerRNA *ptr, const float *values)
{
using blender::VecBase;
using blender::math::Quaternion;
using blender::math::normalize;
float *data = static_cast<float *>(ptr->data);
megakite marked this conversation as resolved Outdated

const Quaternion src = math::normalize(Quaternion(VecBase<float, 4>(values)));
?

`const Quaternion src = math::normalize(Quaternion(VecBase<float, 4>(values)));` ?

This is indeed better since math::normalize provides both unit scale validation and normalization. Will change. Thanks!

Edit: Sorry for the frustration. I have looked into the wrong function. In fact math::normalize doesn't check before actual calculation. I wonder if there's any practical difference in performance between the check-before-calc method and calc-immediately method?

This is indeed better since `math::normalize` provides both unit scale validation and normalization. Will change. Thanks! Edit: Sorry for the frustration. I have looked into the wrong function. In fact `math::normalize` doesn't check before actual calculation. I wonder if there's any practical difference in performance between the check-before-calc method and calc-immediately method?

Not sure if branch with non-zero cost check actually will make it faster.

Not sure if branch with non-zero cost check actually will make it faster.

I have done a quick benchmark, and it shows that there's little difference between the two methods. I will change my code since your line reduces unnecessary complexity. Again, thanks!

I have done a quick [benchmark](https://projects.blender.org/attachments/e3421f8c-f30e-4afd-b455-27928ff518c8), and it shows that there's little difference between the two methods. I will change my code since your line reduces unnecessary complexity. Again, thanks!
const Quaternion src = normalize(Quaternion(VecBase<float, 4>(values)));
data[0] = src.w;
data[1] = src.x;
data[2] = src.y;
data[3] = src.z;
}
static bool rna_Attribute_is_internal_get(PointerRNA *ptr)
{
const CustomDataLayer *layer = (const CustomDataLayer *)ptr->data;
@ -1101,6 +1117,7 @@ static void rna_def_attribute_quaternion(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Value", "Quaternion");
RNA_def_property_float_sdna(prop, nullptr, "x");
RNA_def_property_array(prop, 4);
RNA_def_property_float_funcs(prop, nullptr, "rna_Attribute_quaternion_value_set", nullptr);
RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
}