Changeset View
Standalone View
source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc
| Context not available. | |||||
| b.add_input<decl::Float>("Density").default_value(1.0f).min(0.0f); | b.add_input<decl::Float>("Density").default_value(1.0f).min(0.0f); | ||||
| b.add_input<decl::Float>("Voxel Size").default_value(0.3f).min(0.01f).subtype(PROP_DISTANCE); | b.add_input<decl::Float>("Voxel Size").default_value(0.3f).min(0.01f).subtype(PROP_DISTANCE); | ||||
| b.add_input<decl::Float>("Voxel Amount").default_value(64.0f).min(0.0f); | b.add_input<decl::Float>("Voxel Amount").default_value(64.0f).min(0.0f); | ||||
| b.add_input<decl::String>("Radius"); | b.add_input<decl::Float>("Radius").default_value(0.5f).min(0.0f).supports_field(); | ||||
HooglyBoogly: Not sure if this was a problem before or not, but the new node can use `PROP_DISTANCE` for the… | |||||
| b.add_input<decl::Float>("Radius", "Radius_001").default_value(0.5f).min(0.0f); | |||||
| b.add_output<decl::Geometry>("Geometry"); | b.add_output<decl::Geometry>("Geometry"); | ||||
| } | } | ||||
| Context not available. | |||||
| uiLayoutSetPropSep(layout, true); | uiLayoutSetPropSep(layout, true); | ||||
| uiLayoutSetPropDecorate(layout, false); | uiLayoutSetPropDecorate(layout, false); | ||||
| uiItemR(layout, ptr, "resolution_mode", 0, IFACE_("Resolution"), ICON_NONE); | uiItemR(layout, ptr, "resolution_mode", 0, IFACE_("Resolution"), ICON_NONE); | ||||
| uiItemR(layout, ptr, "input_type_radius", 0, IFACE_("Radius"), ICON_NONE); | |||||
| } | } | ||||
| static void geo_node_points_to_volume_init(bNodeTree *UNUSED(ntree), bNode *node) | static void geo_node_points_to_volume_init(bNodeTree *UNUSED(ntree), bNode *node) | ||||
| Context not available. | |||||
| NodeGeometryPointsToVolume *data = (NodeGeometryPointsToVolume *)MEM_callocN( | NodeGeometryPointsToVolume *data = (NodeGeometryPointsToVolume *)MEM_callocN( | ||||
| sizeof(NodeGeometryPointsToVolume), __func__); | sizeof(NodeGeometryPointsToVolume), __func__); | ||||
| data->resolution_mode = GEO_NODE_POINTS_TO_VOLUME_RESOLUTION_MODE_AMOUNT; | data->resolution_mode = GEO_NODE_POINTS_TO_VOLUME_RESOLUTION_MODE_AMOUNT; | ||||
| data->input_type_radius = GEO_NODE_ATTRIBUTE_INPUT_FLOAT; | |||||
| node->storage = data; | node->storage = data; | ||||
| bNodeSocket *radius_attribute_socket = nodeFindSocket(node, SOCK_IN, "Radius"); | |||||
| bNodeSocketValueString *radius_attribute_socket_value = | |||||
| (bNodeSocketValueString *)radius_attribute_socket->default_value; | |||||
| STRNCPY(radius_attribute_socket_value->value, "radius"); | |||||
| } | } | ||||
| static void geo_node_points_to_volume_update(bNodeTree *UNUSED(ntree), bNode *node) | static void geo_node_points_to_volume_update(bNodeTree *UNUSED(ntree), bNode *node) | ||||
| Context not available. | |||||
| GEO_NODE_POINTS_TO_VOLUME_RESOLUTION_MODE_AMOUNT); | GEO_NODE_POINTS_TO_VOLUME_RESOLUTION_MODE_AMOUNT); | ||||
| nodeSetSocketAvailability( | nodeSetSocketAvailability( | ||||
| voxel_size_socket, data->resolution_mode == GEO_NODE_POINTS_TO_VOLUME_RESOLUTION_MODE_SIZE); | voxel_size_socket, data->resolution_mode == GEO_NODE_POINTS_TO_VOLUME_RESOLUTION_MODE_SIZE); | ||||
| update_attribute_input_socket_availabilities( | |||||
| *node, "Radius", (GeometryNodeAttributeInputMode)data->input_type_radius); | |||||
| } | } | ||||
| #ifdef WITH_OPENVDB | #ifdef WITH_OPENVDB | ||||
| Context not available. | |||||
| return voxel_size; | return voxel_size; | ||||
| } | } | ||||
| static void gather_point_data_from_component(const GeoNodeExecParams ¶ms, | static void gather_point_data_from_component(GeoNodeExecParams ¶ms, | ||||
| const GeometryComponent &component, | const GeometryComponent &component, | ||||
| Vector<float3> &r_positions, | Vector<float3> &r_positions, | ||||
| Vector<float> &r_radii) | Vector<float> &r_radii) | ||||
| { | { | ||||
| GVArray_Typed<float3> positions = component.attribute_get_for_read<float3>( | GVArray_Typed<float3> positions = component.attribute_get_for_read<float3>( | ||||
| "position", ATTR_DOMAIN_POINT, {0, 0, 0}); | "position", ATTR_DOMAIN_POINT, {0, 0, 0}); | ||||
| GVArray_Typed<float> radii = params.get_input_attribute<float>( | |||||
| "Radius", component, ATTR_DOMAIN_POINT, 0.0f); | const Field<float> radius_field = params.extract_input<Field<float>>("Radius"); | ||||
| GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT}; | |||||
| const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_POINT); | |||||
| fn::FieldEvaluator selection_evaluator{field_context, domain_size}; | |||||
| selection_evaluator.add(radius_field); | |||||
| selection_evaluator.evaluate(); | |||||
| const VArray<float> &radii = selection_evaluator.get_evaluated<float>(0); | |||||
| for (const int i : IndexRange(positions.size())) { | for (const int i : IndexRange(positions.size())) { | ||||
| r_positions.append(positions[i]); | r_positions.append(positions[i]); | ||||
| Context not available. | |||||
| static void initialize_volume_component_from_points(const GeometrySet &geometry_set_in, | static void initialize_volume_component_from_points(const GeometrySet &geometry_set_in, | ||||
| GeometrySet &geometry_set_out, | GeometrySet &geometry_set_out, | ||||
| const GeoNodeExecParams ¶ms) | GeoNodeExecParams ¶ms) | ||||
| { | { | ||||
| Vector<float3> positions; | Vector<float3> positions; | ||||
| Vector<float> radii; | Vector<float> radii; | ||||
Not Done Inline ActionsSince this geometry set might be part of a "tree" of nested instances, it might have an instance component that contains more points that could be converted to volumes, so keeping GEO_COMPONENT_TYPE_INSTANCES is necessary here too. HooglyBoogly: Since this geometry set might be part of a "tree" of nested instances, it might have an… | |||||
Not Done Inline ActionsUsing the same vectors for all geometry sets (there might even be multiple threads working on different instances at the same time) likely won't work. They should be declared in the modify_geometry_sets function. Actually, I would recommend moving the modify_geometry_sets loop to the caller, so this function only needs to worry about a single geometry set, that also makes sense since the caller is quite simple currently, it can handle doing a bit more. HooglyBoogly: Using the same vectors for all geometry sets (there might even be multiple threads working on… | |||||
Not Done Inline Actionsvolume is just a raw pointer, so moving it doesn't have any benefit. HooglyBoogly: `volume` is just a raw pointer, so moving it doesn't have any benefit. | |||||
| Context not available. | |||||
| static bNodeType ntype; | static bNodeType ntype; | ||||
| geo_node_type_base( | geo_node_type_base( | ||||
| &ntype, GEO_NODE_LEGACY_POINTS_TO_VOLUME, "Points to Volume", NODE_CLASS_GEOMETRY, 0); | &ntype, GEO_NODE_POINTS_TO_VOLUME, "Points to Volume", NODE_CLASS_GEOMETRY, 0); | ||||
| node_type_storage(&ntype, | node_type_storage(&ntype, | ||||
| "NodeGeometryPointsToVolume", | "NodeGeometryPointsToVolume", | ||||
| node_free_standard_storage, | node_free_standard_storage, | ||||
| Context not available. | |||||
Not sure if this was a problem before or not, but the new node can use PROP_DISTANCE for the radius too.