30 const bNode *node =
b.node_or_null();
35 if (node !=
nullptr) {
38 b.add_input(data_type,
"Attribute").hide_value().field_on_all();
49 b.add_output<
decl::Bool>(
"Is Hit").dependent_field({2, 3, 4});
50 b.add_output<
decl::Vector>(
"Hit Position").dependent_field({2, 3, 4});
51 b.add_output<
decl::Vector>(
"Hit Normal").dependent_field({2, 3, 4});
52 b.add_output<
decl::Float>(
"Hit Distance").dependent_field({2, 3, 4});
54 if (node !=
nullptr) {
56 b.add_output(data_type,
"Attribute").dependent_field({2, 3, 4});
85 bNode &node =
params.add_node(
"GeometryNodeRaycast");
86 node_storage(node).data_type = *type;
87 params.update_and_connect_available_socket(node,
"Attribute");
104 if (tree_data.
tree ==
nullptr) {
108 mask.foreach_index([&](
const int i) {
109 const float ray_length = ray_lengths[
i];
110 const float3 ray_origin = ray_origins[
i];
111 const float3 ray_direction = ray_directions[
i];
115 hit.
dist = ray_length;
125 r_hit[
i] = hit.
index >= 0;
129 r_hit_indices[
i] = hit.
index;
132 r_hit_positions[
i] = hit.
co;
135 r_hit_normals[
i] = hit.
no;
138 r_hit_distances[
i] = hit.
dist;
146 r_hit_indices[
i] = -1;
149 r_hit_positions[
i] =
float3(0.0f, 0.0f, 0.0f);
152 r_hit_normals[
i] =
float3(0.0f, 0.0f, 0.0f);
155 r_hit_distances[
i] = ray_length;
168 target_.ensure_owns_direct_data();
169 static const mf::Signature
signature = []() {
171 mf::SignatureBuilder builder{
"Raycast",
signature};
172 builder.single_input<
float3>(
"Source Position");
173 builder.single_input<
float3>(
"Ray Direction");
174 builder.single_input<
float>(
"Ray Length");
175 builder.single_output<
bool>(
"Is Hit", mf::ParamFlag::SupportsUnusedOutput);
176 builder.single_output<
float3>(
"Hit Position", mf::ParamFlag::SupportsUnusedOutput);
177 builder.single_output<
float3>(
"Hit Normal", mf::ParamFlag::SupportsUnusedOutput);
178 builder.single_output<
float>(
"Distance", mf::ParamFlag::SupportsUnusedOutput);
179 builder.single_output<
int>(
"Triangle Index", mf::ParamFlag::SupportsUnusedOutput);
188 const Mesh &
mesh = *target_.get_mesh();
192 params.readonly_single_input<
float3>(0,
"Source Position"),
193 params.readonly_single_input<
float3>(1,
"Ray Direction"),
194 params.readonly_single_input<
float>(2,
"Ray Length"),
195 params.uninitialized_single_output_if_required<
bool>(3,
"Is Hit"),
196 params.uninitialized_single_output_if_required<
int>(7,
"Triangle Index"),
197 params.uninitialized_single_output_if_required<
float3>(4,
"Hit Position"),
198 params.uninitialized_single_output_if_required<
float3>(5,
"Hit Normal"),
199 params.uninitialized_single_output_if_required<
float>(6,
"Distance"));
210 params.set_default_remaining_outputs();
215 params.set_default_remaining_outputs();
221 params.set_default_remaining_outputs();
225 static auto normalize_fn = mf::build::SI1_SO<float3, float3>(
228 mf::build::exec_presets::AllSpanOrSingle());
239 params.set_output(
"Hit Position", hit_position);
243 if (!
params.output_is_required(
"Attribute")) {
253 std::make_shared<bke::mesh_surface_sample::BaryWeightFromPositionFn>(target),
254 {hit_position, triangle_index}));
258 std::make_shared<bke::mesh_surface_sample::CornerBaryWeightFromPositionFn>(target),
259 {hit_position, triangle_index}));
263 std::make_shared<bke::mesh_surface_sample::BaryWeightSampleFn>(std::move(target),
265 {triangle_index, bary_weights});
276 "Interpolate the attribute from the corners of the hit face"},
281 "Use the attribute value of the closest mesh element"},
282 {0,
nullptr, 0,
nullptr,
nullptr},
288 "Mapping from the target geometry to hit points",
295 "Type of data stored in attribute",
309 "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)
static std::shared_ptr< FieldOperation > Create(std::shared_ptr< const mf::MultiFunction > function, Vector< GField > inputs={})
Vector< SocketDeclaration * > inputs
Vector< SocketDeclaration * > outputs
bool only_realized_data() const
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 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)
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)