Geometry Nodes: Image Info Node
This commit adds a new "Image Info" node to retrieve various information from an image like its width, height, and whether it has an alpha channel. It is also possible to retrieve the FPS and frame count of video files. Differential Revision: https://developer.blender.org/D15042
This commit is contained in:
parent
b64042b482
commit
efcd587bc2
@ -139,6 +139,7 @@ class NODE_MT_geometry_node_GEO_INPUT(Menu):
|
||||
node_add_menu.add_node_type(layout, "FunctionNodeInputBool")
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeCollectionInfo")
|
||||
node_add_menu.add_node_type(layout, "FunctionNodeInputColor")
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeImageInfo")
|
||||
node_add_menu.add_node_type(layout, "FunctionNodeInputInt")
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeIsViewport")
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeInputMaterial")
|
||||
|
@ -1546,6 +1546,7 @@ struct TexResult;
|
||||
#define GEO_NODE_MESH_TOPOLOGY_VERTEX_OF_CORNER 1186
|
||||
#define GEO_NODE_SAMPLE_UV_SURFACE 1187
|
||||
#define GEO_NODE_SET_CURVE_NORMAL 1188
|
||||
#define GEO_NODE_IMAGE_INFO 1189
|
||||
|
||||
/** \} */
|
||||
|
||||
|
@ -4753,6 +4753,7 @@ static void registerGeometryNodes()
|
||||
register_node_type_geo_field_at_index();
|
||||
register_node_type_geo_flip_faces();
|
||||
register_node_type_geo_geometry_to_instance();
|
||||
register_node_type_geo_image_info();
|
||||
register_node_type_geo_image_texture();
|
||||
register_node_type_geo_input_curve_handles();
|
||||
register_node_type_geo_input_curve_tilt();
|
||||
|
@ -62,6 +62,7 @@ void register_node_type_geo_extrude_mesh(void);
|
||||
void register_node_type_geo_field_at_index(void);
|
||||
void register_node_type_geo_flip_faces(void);
|
||||
void register_node_type_geo_geometry_to_instance(void);
|
||||
void register_node_type_geo_image_info(void);
|
||||
void register_node_type_geo_image_texture(void);
|
||||
void register_node_type_geo_input_curve_handles(void);
|
||||
void register_node_type_geo_input_curve_tilt(void);
|
||||
|
@ -319,6 +319,7 @@ DefNode(GeometryNode, GEO_NODE_FILL_CURVE, def_geo_curve_fill, "FILL_CURVE", Fil
|
||||
DefNode(GeometryNode, GEO_NODE_FILLET_CURVE, def_geo_curve_fillet, "FILLET_CURVE", FilletCurve, "Fillet Curve", "Round corners by generating circular arcs on each control point")
|
||||
DefNode(GeometryNode, GEO_NODE_FLIP_FACES, 0, "FLIP_FACES", FlipFaces, "Flip Faces", "Reverse the order of the vertices and edges of selected faces, flipping their normal direction")
|
||||
DefNode(GeometryNode, GEO_NODE_GEOMETRY_TO_INSTANCE, 0, "GEOMETRY_TO_INSTANCE", GeometryToInstance, "Geometry to Instance", "Convert each input geometry into an instance, which can be much faster than the Join Geometry node when the inputs are large")
|
||||
DefNode(GeometryNode, GEO_NODE_IMAGE_INFO, 0, "IMAGE_INFO", ImageInfo, "Image Info", "Retrieve information about an image")
|
||||
DefNode(GeometryNode, GEO_NODE_IMAGE_TEXTURE, def_geo_image_texture, "IMAGE_TEXTURE", ImageTexture, "Image Texture", "Sample values from an image texture")
|
||||
DefNode(GeometryNode, GEO_NODE_INPUT_CURVE_HANDLES, 0, "INPUT_CURVE_HANDLES", InputCurveHandlePositions,"Curve Handle Positions", "Retrieve the position of each Bézier control point's handles")
|
||||
DefNode(GeometryNode, GEO_NODE_INPUT_CURVE_TILT, 0, "INPUT_CURVE_TILT", InputCurveTilt, "Curve Tilt", "Retrieve the angle at each control point used to twist the curve's normal around its tangent")
|
||||
|
@ -72,6 +72,7 @@ set(SRC
|
||||
nodes/node_geo_field_at_index.cc
|
||||
nodes/node_geo_flip_faces.cc
|
||||
nodes/node_geo_geometry_to_instance.cc
|
||||
nodes/node_geo_image_info.cc
|
||||
nodes/node_geo_image_texture.cc
|
||||
nodes/node_geo_input_curve_handles.cc
|
||||
nodes/node_geo_input_curve_tilt.cc
|
||||
|
95
source/blender/nodes/geometry/nodes/node_geo_image_info.cc
Normal file
95
source/blender/nodes/geometry/nodes/node_geo_image_info.cc
Normal file
@ -0,0 +1,95 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "BKE_image.h"
|
||||
|
||||
#include "BLI_path_util.h"
|
||||
|
||||
#include "IMB_colormanagement.h"
|
||||
#include "IMB_imbuf.h"
|
||||
#include "IMB_imbuf_types.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "node_geometry_util.hh"
|
||||
|
||||
namespace blender::nodes::node_geo_image_info_cc {
|
||||
|
||||
static void node_declare(NodeDeclarationBuilder &b)
|
||||
{
|
||||
b.add_input<decl::Image>(N_("Image")).hide_label();
|
||||
b.add_input<decl::Int>(N_("Frame"))
|
||||
.min(0)
|
||||
.description(N_("Which frame to use for videos. Note that different frames in videos can "
|
||||
"have different resolutions"));
|
||||
|
||||
b.add_output<decl::Int>(N_("Width"));
|
||||
b.add_output<decl::Int>(N_("Height"));
|
||||
b.add_output<decl::Bool>(N_("Has Alpha"))
|
||||
.description(N_("Whether the image has an alpha channel"));
|
||||
|
||||
b.add_output<decl::Int>(N_("Frame Count"))
|
||||
.description(N_("The number of animation frames. If a single image, then 1"));
|
||||
b.add_output<decl::Float>(N_("FPS")).description(
|
||||
N_("Animation playback speed in frames per second. If a single image, then 0"));
|
||||
}
|
||||
|
||||
static void node_geo_exec(GeoNodeExecParams params)
|
||||
{
|
||||
Image *image = params.get_input<Image *>("Image");
|
||||
const int frame = params.get_input<int>("Frame");
|
||||
if (!image) {
|
||||
params.set_default_remaining_outputs();
|
||||
return;
|
||||
}
|
||||
|
||||
ImageUser image_user;
|
||||
BKE_imageuser_default(&image_user);
|
||||
image_user.frames = INT_MAX;
|
||||
image_user.framenr = BKE_image_is_animated(image) ? frame : 0;
|
||||
|
||||
void *lock;
|
||||
ImBuf *ibuf = BKE_image_acquire_ibuf(image, &image_user, &lock);
|
||||
BLI_SCOPED_DEFER([&]() { BKE_image_release_ibuf(image, ibuf, lock); });
|
||||
if (!ibuf) {
|
||||
params.set_default_remaining_outputs();
|
||||
return;
|
||||
}
|
||||
|
||||
params.set_output("Has Alpha", ELEM(ibuf->planes, 32, 16));
|
||||
params.set_output("Width", ibuf->x);
|
||||
params.set_output("Height", ibuf->y);
|
||||
|
||||
int frames = 1;
|
||||
float fps = 0.0f;
|
||||
|
||||
if (ImageAnim *ianim = static_cast<ImageAnim *>(image->anims.first)) {
|
||||
auto *anim = ianim->anim;
|
||||
if (anim) {
|
||||
frames = IMB_anim_get_duration(anim, IMB_TC_NONE);
|
||||
|
||||
short fps_sec = 0;
|
||||
float fps_sec_base = 0.0f;
|
||||
IMB_anim_get_fps(anim, &fps_sec, &fps_sec_base, true);
|
||||
fps = float(fps_sec) / fps_sec_base;
|
||||
}
|
||||
}
|
||||
|
||||
params.set_output("Frame Count", frames);
|
||||
params.set_output("FPS", fps);
|
||||
}
|
||||
|
||||
} // namespace blender::nodes::node_geo_image_info_cc
|
||||
|
||||
void register_node_type_geo_image_info()
|
||||
{
|
||||
namespace file_ns = blender::nodes::node_geo_image_info_cc;
|
||||
|
||||
static bNodeType ntype;
|
||||
|
||||
geo_node_type_base(&ntype, GEO_NODE_IMAGE_INFO, "Image Info", NODE_CLASS_INPUT);
|
||||
ntype.declare = file_ns::node_declare;
|
||||
ntype.geometry_node_execute = file_ns::node_geo_exec;
|
||||
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
Loading…
Reference in New Issue
Block a user