33 N_(
"Interpolate the attribute from the corners of the hit face")},
38 N_(
"Use the attribute value of the closest mesh element")},
39 {0,
nullptr, 0,
nullptr,
nullptr},
44 const bNode *node =
b.node_or_null();
50 if (node !=
nullptr) {
53 b.add_input(data_type,
"Attribute").hide_value().field_on_all();
58 .description(
"Mapping from the target geometry to hit points");
64 .default_value({0.0f, 0.0f, -1.0f})
68 .default_value(100.0f)
72 .structure_type(StructureType::Dynamic);
74 b.add_output<
decl::Bool>(
"Is Hit").dependent_field({2, 3, 4});
75 b.add_output<
decl::Vector>(
"Hit Position").dependent_field({2, 3, 4});
76 b.add_output<
decl::Vector>(
"Hit Normal").dependent_field({2, 3, 4});
77 b.add_output<
decl::Float>(
"Hit Distance").dependent_field({2, 3, 4});
79 if (node !=
nullptr) {
81 b.add_output(data_type,
"Attribute").dependent_field({2, 3, 4});
108 bNode &node =
params.add_node(
"GeometryNodeRaycast");
109 node_storage(node).data_type = *type;
110 params.update_and_connect_available_socket(node,
"Attribute");
127 if (tree_data.
tree ==
nullptr) {
131 mask.foreach_index([&](
const int i) {
132 const float ray_length = ray_lengths[
i];
133 const float3 ray_origin = ray_origins[
i];
134 const float3 ray_direction = ray_directions[
i];
138 hit.
dist = ray_length;
148 r_hit[
i] = hit.
index >= 0;
152 r_hit_indices[
i] = hit.
index;
155 r_hit_positions[
i] = hit.
co;
158 r_hit_normals[
i] = hit.
no;
161 r_hit_distances[
i] = hit.
dist;
169 r_hit_indices[
i] = -1;
172 r_hit_positions[
i] =
float3(0.0f, 0.0f, 0.0f);
175 r_hit_normals[
i] =
float3(0.0f, 0.0f, 0.0f);
178 r_hit_distances[
i] = ray_length;
191 target_.ensure_owns_direct_data();
192 static const mf::Signature
signature = []() {
194 mf::SignatureBuilder builder{
"Raycast",
signature};
195 builder.single_input<
float3>(
"Source Position");
196 builder.single_input<
float3>(
"Ray Direction");
197 builder.single_input<
float>(
"Ray Length");
198 builder.single_output<
bool>(
"Is Hit", mf::ParamFlag::SupportsUnusedOutput);
199 builder.single_output<
float3>(
"Hit Position", mf::ParamFlag::SupportsUnusedOutput);
200 builder.single_output<
float3>(
"Hit Normal", mf::ParamFlag::SupportsUnusedOutput);
201 builder.single_output<
float>(
"Distance", mf::ParamFlag::SupportsUnusedOutput);
202 builder.single_output<
int>(
"Triangle Index", mf::ParamFlag::SupportsUnusedOutput);
211 const Mesh &
mesh = *target_.get_mesh();
215 params.readonly_single_input<
float3>(0,
"Source Position"),
216 params.readonly_single_input<
float3>(1,
"Ray Direction"),
217 params.readonly_single_input<
float>(2,
"Ray Length"),
218 params.uninitialized_single_output_if_required<
bool>(3,
"Is Hit"),
219 params.uninitialized_single_output_if_required<
int>(7,
"Triangle Index"),
220 params.uninitialized_single_output_if_required<
float3>(4,
"Hit Position"),
221 params.uninitialized_single_output_if_required<
float3>(5,
"Hit Normal"),
222 params.uninitialized_single_output_if_required<
float>(6,
"Distance"));
232 params.set_default_remaining_outputs();
237 params.set_default_remaining_outputs();
243 params.set_default_remaining_outputs();
247 std::string error_message;
253 static auto normalize_fn = mf::build::SI1_SO<float3, float3>(
256 mf::build::exec_presets::AllSpanOrSingle());
260 {&normalized_direction},
264 params.set_default_remaining_outputs();
279 std::make_unique<RaycastFunction>(target),
280 {&position, &normalized_direction, &ray_length},
281 {&is_hit, &hit_position, &hit_normal, &hit_distance, &triangle_index},
285 params.set_default_remaining_outputs();
290 params.set_output(
"Is Hit", std::move(is_hit));
291 params.set_output(
"Hit Position", hit_position);
292 params.set_output(
"Hit Normal", std::move(hit_normal));
293 params.set_output(
"Hit Distance", std::move(hit_distance));
295 if (!
params.output_is_required(
"Attribute")) {
305 std::make_shared<bke::mesh_surface_sample::BaryWeightFromPositionFn>(target),
306 {&hit_position, &triangle_index_copy},
311 params.set_default_remaining_outputs();
318 std::make_shared<bke::mesh_surface_sample::CornerBaryWeightFromPositionFn>(target),
319 {&hit_position, &triangle_index_copy},
324 params.set_default_remaining_outputs();
333 std::make_shared<bke::mesh_surface_sample::BaryWeightSampleFn>(std::move(target),
335 {&triangle_index, &bary_weights},
340 params.set_default_remaining_outputs();
345 params.set_output(
"Attribute", std::move(sampled_atribute));
353 "Type of data stored in attribute",
367 "Cast rays from the context geometry onto a target geometry, and retrieve information from "
#define NODE_STORAGE_FUNCS(StorageT)
#define NODE_CLASS_GEOMETRY
int BLI_bvhtree_ray_cast(const BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata)
@ NODE_DEFAULT_INPUT_POSITION_FIELD
GeometryNodeRaycastMapMode
@ GEO_NODE_RAYCAST_NEAREST
@ GEO_NODE_RAYCAST_INTERPOLATED
#define NOD_REGISTER_NODE(REGISTER_FUNC)
#define NOD_storage_enum_accessors(member)
BMesh const char void * data
ATTR_WARN_UNUSED_RESULT const BMVert * v
constexpr bool is_empty() const
const Signature & signature() const
void set_signature(const Signature *signature)
Vector< SocketDeclaration * > inputs
Vector< SocketDeclaration * > outputs
StructureType structure_type
void call(const IndexMask &mask, mf::Params params, mf::Context) const override
RaycastFunction(GeometrySet target)
void * MEM_callocN(size_t len, const char *str)
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
void node_register_type(bNodeType &ntype)
void node_type_storage(bNodeType &ntype, std::optional< StringRefNull > storagename, void(*freefunc)(bNode *node), void(*copyfunc)(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node))
std::optional< eCustomDataType > socket_type_to_custom_data_type(eNodeSocketDatatype type)
void node_type_size_preset(bNodeType &ntype, eNodeSizePreset size)
MatBase< T, NumCol, NumRow > normalize(const MatBase< T, NumCol, NumRow > &a)
const EnumPropertyItem * attribute_type_type_with_socket_fn(bContext *, PointerRNA *, PropertyRNA *, bool *r_free)
static EnumPropertyItem interpolation_items[]
static void node_geo_exec(GeoNodeExecParams params)
static void node_init(bNodeTree *, bNode *node)
static void node_rna(StructRNA *srna)
static void node_layout(uiLayout *layout, bContext *, PointerRNA *ptr)
static void raycast_to_mesh(const IndexMask &mask, const Mesh &mesh, const VArray< float3 > &ray_origins, const VArray< float3 > &ray_directions, const VArray< float > &ray_lengths, const MutableSpan< bool > r_hit, const MutableSpan< int > r_hit_indices, const MutableSpan< float3 > r_hit_positions, const MutableSpan< float3 > r_hit_normals, const MutableSpan< float > r_hit_distances)
static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms)
static void node_register()
static void node_declare(NodeDeclarationBuilder &b)
void search_link_ops_for_declarations(GatherLinkSearchOpParams ¶ms, Span< SocketDeclaration * > declarations)
PropertyRNA * RNA_def_node_enum(StructRNA *srna, const char *identifier, const char *ui_name, const char *ui_description, const EnumPropertyItem *static_items, const EnumRNAAccessors accessors, std::optional< int > default_value, const EnumPropertyItemFunc item_func, const bool allow_animation)
bool execute_multi_function_on_value_variant(const MultiFunction &fn, const std::shared_ptr< MultiFunction > &owned_fn, const Span< SocketValueVariant * > input_values, const Span< SocketValueVariant * > output_values, GeoNodesUserData *user_data, std::string &r_error_message)
VecBase< float, 3 > float3
void geo_node_type_base(blender::bke::bNodeType *ntype, std::string idname, const std::optional< int16_t > legacy_type)
void node_free_standard_storage(bNode *node)
void node_copy_standard_storage(bNodeTree *, bNode *dest_node, const bNode *src_node)
const EnumPropertyItem rna_enum_attribute_type_items[]
BVHTree_RayCastCallback raycast_callback
const Mesh * get_mesh() const
std::string ui_description
void(* initfunc)(bNodeTree *ntree, bNode *node)
NodeGeometryExecFunction geometry_node_execute
const char * enum_name_legacy
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
NodeGatherSocketLinkOperationsFunction gather_link_search_ops
NodeDeclareFunction declare
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)