28 b.add_input<
decl::Vector>(
N_(
"Attribute")).hide_value().supports_field();
29 b.add_input<
decl::Float>(
N_(
"Attribute"),
"Attribute_001").hide_value().supports_field();
30 b.add_input<
decl::Color>(
N_(
"Attribute"),
"Attribute_002").hide_value().supports_field();
31 b.add_input<
decl::Bool>(
N_(
"Attribute"),
"Attribute_003").hide_value().supports_field();
32 b.add_input<
decl::Int>(
N_(
"Attribute"),
"Attribute_004").hide_value().supports_field();
36 .default_value({0.0f, 0.0f, -1.0f})
39 .default_value(100.0f)
49 b.add_output<
decl::Vector>(
N_(
"Attribute")).dependent_field({1, 2, 3, 4, 5, 6});
50 b.add_output<
decl::Float>(
N_(
"Attribute"),
"Attribute_001").dependent_field({1, 2, 3, 4, 5, 6});
51 b.add_output<
decl::Color>(
N_(
"Attribute"),
"Attribute_002").dependent_field({1, 2, 3, 4, 5, 6});
52 b.add_output<
decl::Bool>(
N_(
"Attribute"),
"Attribute_003").dependent_field({1, 2, 3, 4, 5, 6});
53 b.add_output<
decl::Int>(
N_(
"Attribute"),
"Attribute_004").dependent_field({1, 2, 3, 4, 5, 6});
58 uiItemR(layout,
ptr,
"data_type", 0,
"", ICON_NONE);
59 uiItemR(layout,
ptr,
"mapping", 0,
"", ICON_NONE);
113 node_storage(
node).data_type = *
type;
114 params.update_and_connect_available_socket(
node,
"Attribute");
123 return eAttributeMapMode::INTERPOLATED;
126 return eAttributeMapMode::NEAREST;
146 if (tree_data.
tree ==
nullptr) {
152 for (
const int i :
mask) {
153 const float ray_length = ray_lengths[i];
154 const float3 ray_origin = ray_origins[i];
159 hit.
dist = ray_length;
169 r_hit[i] = hit.
index >= 0;
173 r_hit_indices[i] = hit.
index;
176 r_hit_positions[i] = hit.
co;
179 r_hit_normals[i] = hit.
no;
182 r_hit_distances[i] = hit.
dist;
190 r_hit_indices[i] = -1;
193 r_hit_positions[i] =
float3(0.0f, 0.0f, 0.0f);
196 r_hit_normals[i] =
float3(0.0f, 0.0f, 0.0f);
199 r_hit_distances[i] = ray_length;
211 std::optional<GeometryComponentFieldContext> target_context_;
212 std::unique_ptr<FieldEvaluator> target_evaluator_;
213 const GVArray *target_data_ =
nullptr;
227 this->evaluate_target_field(std::move(src_field));
228 signature_ = create_signature();
229 this->set_signature(&signature_);
236 signature.single_input<
float3>(
"Ray Direction");
237 signature.single_input<
float>(
"Ray Length");
238 signature.single_output<
bool>(
"Is Hit");
239 signature.single_output<
float3>(
"Hit Position");
240 signature.single_output<
float3>(
"Hit Normal");
241 signature.single_output<
float>(
"Distance");
243 signature.single_output(
"Attribute", target_data_->
type());
245 return signature.build();
254 (target_data_) ?
params.uninitialized_single_output<
float3>(4,
"Hit Position") :
255 params.uninitialized_single_output_if_required<
float3>(4,
"Hit Position");
268 params.readonly_single_input<
float3>(0,
"Source Position"),
269 params.readonly_single_input<
float3>(1,
"Ray Direction"),
270 params.readonly_single_input<
float>(2,
"Ray Length"),
271 params.uninitialized_single_output_if_required<
bool>(3,
"Is Hit"),
274 params.uninitialized_single_output_if_required<
float3>(5,
"Hit Normal"),
275 params.uninitialized_single_output_if_required<
float>(6,
"Distance"),
281 if (hit_count <
mask.size()) {
286 hit_mask_indices.
reserve(hit_count);
288 if (hit_indices[i] != -1) {
289 hit_mask_indices.
append(i);
308 void evaluate_target_field(
GField src_field)
316 target_evaluator_ = std::make_unique<FieldEvaluator>(*target_context_, domain_size);
317 target_evaluator_->add(std::move(src_field));
318 target_evaluator_->evaluate();
319 target_data_ = &target_evaluator_->get_evaluated(0);
327 if (
params.output_is_required(
"Attribute_001")) {
332 if (
params.output_is_required(
"Attribute")) {
337 if (
params.output_is_required(
"Attribute_002")) {
342 if (
params.output_is_required(
"Attribute_003")) {
347 if (
params.output_is_required(
"Attribute_004")) {
393 params.set_default_remaining_outputs();
398 params.set_default_remaining_outputs();
403 params.error_message_add(NodeWarningType::Error,
TIP_(
"The target mesh must have faces"));
404 params.set_default_remaining_outputs();
409 const bool do_attribute_transfer =
bool(field);
414 auto fn = std::make_unique<RaycastFunction>(std::move(target), std::move(field), mapping);
417 {std::move(position_field), std::move(direction_field), std::move(length_field)}));
423 if (do_attribute_transfer) {
void free_bvhtree_from_mesh(struct BVHTreeFromMesh *data)
BVHTree * BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data, const struct Mesh *mesh, BVHCacheType bvh_cache_type, int tree_type)
@ GEO_COMPONENT_TYPE_MESH
void node_type_update(struct bNodeType *ntype, void(*updatefunc)(struct bNodeTree *ntree, struct bNode *node))
#define NODE_STORAGE_FUNCS(StorageT)
void nodeSetSocketAvailability(struct bNodeTree *ntree, struct bNodeSocket *sock, bool is_available)
void node_type_init(struct bNodeType *ntype, void(*initfunc)(struct bNodeTree *ntree, struct bNode *node))
void node_type_size_preset(struct bNodeType *ntype, eNodeSizePreset size)
#define NODE_CLASS_GEOMETRY
void node_type_storage(struct bNodeType *ntype, const char *storagename, void(*freefunc)(struct bNode *node), void(*copyfunc)(struct bNodeTree *dest_ntree, struct bNode *dest_node, const struct bNode *src_node))
void nodeRegisterType(struct bNodeType *ntype)
#define BLI_assert_unreachable()
int BLI_bvhtree_ray_cast(BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata)
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define BLI_SCOPED_DEFER(function_to_defer)
GeometryNodeRaycastMapMode
@ GEO_NODE_RAYCAST_NEAREST
@ GEO_NODE_RAYCAST_INTERPOLATED
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
int attribute_domain_size(eAttrDomain domain) const
void reinitialize(const int64_t new_size)
const CPPType & type() const
constexpr bool is_empty() const
void append(const T &value)
void reserve(const int64_t min_capacity)
const CPPType & cpp_type() const
void single_input(const char *name)
Span< SocketDeclarationPtr > outputs() const
Span< SocketDeclarationPtr > inputs() const
void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
fn::MFSignature create_signature()
RaycastFunction(GeometrySet target, GField src_field, GeometryNodeRaycastMapMode mapping)
ccl_device_inline float2 interp(const float2 &a, const float2 &b, float t)
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
eCustomDataType cpp_type_to_custom_data_type(const blender::CPPType &type)
vec_base< T, Size > normalize(const vec_base< T, Size > &v)
static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
static void node_geo_exec(GeoNodeExecParams params)
static void output_attribute_field(GeoNodeExecParams ¶ms, GField field)
static void node_init(bNodeTree *UNUSED(tree), bNode *node)
static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms)
static void raycast_to_mesh(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, int &hit_count)
static GField get_input_attribute_field(GeoNodeExecParams ¶ms, const eCustomDataType data_type)
static eAttributeMapMode get_map_mode(GeometryNodeRaycastMapMode map_mode)
static void node_update(bNodeTree *ntree, bNode *node)
static void node_declare(NodeDeclarationBuilder &b)
std::optional< eCustomDataType > node_data_type_to_custom_data_type(const eNodeSocketDatatype type)
void search_link_ops_for_declarations(GatherLinkSearchOpParams ¶ms, Span< SocketDeclarationPtr > declarations)
vec_base< float, 3 > float3
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
static void node_init(const struct bContext *C, bNodeTree *ntree, bNode *node)
void register_node_type_geo_raycast()
void geo_node_type_base(bNodeType *ntype, int type, const char *name, short nclass)
void node_copy_standard_storage(bNodeTree *UNUSED(dest_ntree), bNode *dest_node, const bNode *src_node)
void node_free_standard_storage(bNode *node)
BVHTree_RayCastCallback raycast_callback
void ensure_owns_direct_data()
const GeometryComponent * get_component_for_read(GeometryComponentType component_type) const
const Mesh * get_mesh_for_read() const
struct bNodeSocket * next
NodeGeometryExecFunction geometry_node_execute
NodeGatherSocketLinkOperationsFunction gather_link_search_ops
void(* draw_buttons)(struct uiLayout *, struct bContext *C, struct PointerRNA *ptr)
NodeDeclareFunction declare