Geometry Nodes: reduce code duplication with new GeometyrFieldInput

Most of our field inputs are currently specific to geometry. This patch introduces
a new `GeometryFieldInput` that reduces the overhead of adding new geometry
field input.

Differential Revision: https://developer.blender.org/D13489
This commit is contained in:
2021-12-06 19:05:29 +01:00
parent 2814740f5b
commit 2d4c7fa896
16 changed files with 278 additions and 374 deletions

View File

@@ -38,6 +38,7 @@ using bke::AttributeFieldInput;
using bke::AttributeIDRef;
using bke::geometry_set_realize_instances;
using bke::GeometryComponentFieldContext;
using bke::GeometryFieldInput;
using bke::OutputAttribute;
using bke::OutputAttribute_Typed;
using bke::ReadAttributeLookup;

View File

@@ -51,69 +51,61 @@ static void select_by_spline(const int start, const int end, MutableSpan<bool> r
r_selection.slice(size - end_use, end_use).fill(true);
}
class EndpointFieldInput final : public fn::FieldInput {
class EndpointFieldInput final : public GeometryFieldInput {
Field<int> start_size_;
Field<int> end_size_;
public:
EndpointFieldInput(Field<int> start_size, Field<int> end_size)
: FieldInput(CPPType::get<bool>(), "Endpoint Selection node"),
: GeometryFieldInput(CPPType::get<bool>(), "Endpoint Selection node"),
start_size_(start_size),
end_size_(end_size)
{
category_ = Category::Generated;
}
GVArray get_varray_for_context(const fn::FieldContext &context,
IndexMask UNUSED(mask),
ResourceScope &UNUSED(scope)) const final
GVArray get_varray_for_context(const GeometryComponent &component,
const AttributeDomain domain,
IndexMask UNUSED(mask)) const final
{
if (const GeometryComponentFieldContext *geometry_context =
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
const GeometryComponent &component = geometry_context->geometry_component();
const AttributeDomain domain = geometry_context->domain();
if (component.type() != GEO_COMPONENT_TYPE_CURVE || domain != ATTR_DOMAIN_POINT) {
return nullptr;
}
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
const CurveEval *curve = curve_component.get_for_read();
Array<int> control_point_offsets = curve->control_point_offsets();
if (curve == nullptr || control_point_offsets.last() == 0) {
return nullptr;
}
GeometryComponentFieldContext size_context{curve_component, ATTR_DOMAIN_CURVE};
fn::FieldEvaluator evaluator{size_context, curve->splines().size()};
evaluator.add(start_size_);
evaluator.add(end_size_);
evaluator.evaluate();
const VArray<int> &start_size = evaluator.get_evaluated<int>(0);
const VArray<int> &end_size = evaluator.get_evaluated<int>(1);
const int point_size = control_point_offsets.last();
Array<bool> selection(point_size, false);
int current_point = 0;
MutableSpan<bool> selection_span = selection.as_mutable_span();
for (int i : IndexRange(curve->splines().size())) {
const SplinePtr &spline = curve->splines()[i];
if (start_size[i] <= 0 && end_size[i] <= 0) {
selection_span.slice(current_point, spline->size()).fill(false);
}
else {
int start_use = std::max(start_size[i], 0);
int end_use = std::max(end_size[i], 0);
select_by_spline(
start_use, end_use, selection_span.slice(current_point, spline->size()));
}
current_point += spline->size();
}
return VArray<bool>::ForContainer(std::move(selection));
if (component.type() != GEO_COMPONENT_TYPE_CURVE || domain != ATTR_DOMAIN_POINT) {
return nullptr;
}
return {};
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
const CurveEval *curve = curve_component.get_for_read();
Array<int> control_point_offsets = curve->control_point_offsets();
if (curve == nullptr || control_point_offsets.last() == 0) {
return nullptr;
}
GeometryComponentFieldContext size_context{curve_component, ATTR_DOMAIN_CURVE};
fn::FieldEvaluator evaluator{size_context, curve->splines().size()};
evaluator.add(start_size_);
evaluator.add(end_size_);
evaluator.evaluate();
const VArray<int> &start_size = evaluator.get_evaluated<int>(0);
const VArray<int> &end_size = evaluator.get_evaluated<int>(1);
const int point_size = control_point_offsets.last();
Array<bool> selection(point_size, false);
int current_point = 0;
MutableSpan<bool> selection_span = selection.as_mutable_span();
for (int i : IndexRange(curve->splines().size())) {
const SplinePtr &spline = curve->splines()[i];
if (start_size[i] <= 0 && end_size[i] <= 0) {
selection_span.slice(current_point, spline->size()).fill(false);
}
else {
int start_use = std::max(start_size[i], 0);
int end_use = std::max(end_size[i], 0);
select_by_spline(start_use, end_use, selection_span.slice(current_point, spline->size()));
}
current_point += spline->size();
}
return VArray<bool>::ForContainer(std::move(selection));
};
uint64_t hash() const override

View File

@@ -83,44 +83,40 @@ static void select_by_handle_type(const CurveEval &curve,
}
}
class HandleTypeFieldInput final : public fn::FieldInput {
class HandleTypeFieldInput final : public GeometryFieldInput {
BezierSpline::HandleType type_;
GeometryNodeCurveHandleMode mode_;
public:
HandleTypeFieldInput(BezierSpline::HandleType type, GeometryNodeCurveHandleMode mode)
: FieldInput(CPPType::get<bool>(), "Handle Type Selection node"), type_(type), mode_(mode)
: GeometryFieldInput(CPPType::get<bool>(), "Handle Type Selection node"),
type_(type),
mode_(mode)
{
category_ = Category::Generated;
}
GVArray get_varray_for_context(const fn::FieldContext &context,
IndexMask mask,
ResourceScope &UNUSED(scope)) const final
GVArray get_varray_for_context(const GeometryComponent &component,
const AttributeDomain domain,
IndexMask mask) const final
{
if (const GeometryComponentFieldContext *geometry_context =
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
if (component.type() != GEO_COMPONENT_TYPE_CURVE) {
return {};
}
const GeometryComponent &component = geometry_context->geometry_component();
const AttributeDomain domain = geometry_context->domain();
if (component.type() != GEO_COMPONENT_TYPE_CURVE) {
return {};
}
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
const CurveEval *curve = curve_component.get_for_read();
if (curve == nullptr) {
return {};
}
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
const CurveEval *curve = curve_component.get_for_read();
if (curve == nullptr) {
return {};
}
if (domain == ATTR_DOMAIN_POINT) {
Array<bool> selection(mask.min_array_size());
select_by_handle_type(*curve, type_, mode_, selection);
return VArray<bool>::ForContainer(std::move(selection));
}
if (domain == ATTR_DOMAIN_POINT) {
Array<bool> selection(mask.min_array_size());
select_by_handle_type(*curve, type_, mode_, selection);
return VArray<bool>::ForContainer(std::move(selection));
}
return {};
};
}
uint64_t hash() const override
{

View File

@@ -202,29 +202,22 @@ static VArray<int> construct_index_on_spline_varray(const CurveEval &curve,
return {};
}
class CurveParameterFieldInput final : public fn::FieldInput {
class CurveParameterFieldInput final : public GeometryFieldInput {
public:
CurveParameterFieldInput() : fn::FieldInput(CPPType::get<float>(), "Curve Parameter node")
CurveParameterFieldInput() : GeometryFieldInput(CPPType::get<float>(), "Curve Parameter node")
{
category_ = Category::Generated;
}
GVArray get_varray_for_context(const fn::FieldContext &context,
IndexMask mask,
ResourceScope &UNUSED(scope)) const final
GVArray get_varray_for_context(const GeometryComponent &component,
const AttributeDomain domain,
IndexMask mask) const final
{
if (const GeometryComponentFieldContext *geometry_context =
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
const GeometryComponent &component = geometry_context->geometry_component();
const AttributeDomain domain = geometry_context->domain();
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
const CurveEval *curve = curve_component.get_for_read();
if (curve) {
return construct_curve_parameter_varray(*curve, mask, domain);
}
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
const CurveEval *curve = curve_component.get_for_read();
if (curve) {
return construct_curve_parameter_varray(*curve, mask, domain);
}
}
return {};
@@ -242,28 +235,22 @@ class CurveParameterFieldInput final : public fn::FieldInput {
}
};
class CurveLengthFieldInput final : public fn::FieldInput {
class CurveLengthFieldInput final : public GeometryFieldInput {
public:
CurveLengthFieldInput() : fn::FieldInput(CPPType::get<float>(), "Curve Length node")
CurveLengthFieldInput() : GeometryFieldInput(CPPType::get<float>(), "Curve Length node")
{
category_ = Category::Generated;
}
GVArray get_varray_for_context(const fn::FieldContext &context,
IndexMask mask,
ResourceScope &UNUSED(scope)) const final
GVArray get_varray_for_context(const GeometryComponent &component,
const AttributeDomain domain,
IndexMask mask) const final
{
if (const GeometryComponentFieldContext *geometry_context =
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
const GeometryComponent &component = geometry_context->geometry_component();
const AttributeDomain domain = geometry_context->domain();
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
const CurveEval *curve = curve_component.get_for_read();
if (curve) {
return construct_curve_length_varray(*curve, mask, domain);
}
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
const CurveEval *curve = curve_component.get_for_read();
if (curve) {
return construct_curve_length_varray(*curve, mask, domain);
}
}
return {};
@@ -281,28 +268,22 @@ class CurveLengthFieldInput final : public fn::FieldInput {
}
};
class IndexOnSplineFieldInput final : public fn::FieldInput {
class IndexOnSplineFieldInput final : public GeometryFieldInput {
public:
IndexOnSplineFieldInput() : fn::FieldInput(CPPType::get<int>(), "Spline Index")
IndexOnSplineFieldInput() : GeometryFieldInput(CPPType::get<int>(), "Spline Index")
{
category_ = Category::Generated;
}
GVArray get_varray_for_context(const fn::FieldContext &context,
IndexMask mask,
ResourceScope &UNUSED(scope)) const final
GVArray get_varray_for_context(const GeometryComponent &component,
const AttributeDomain domain,
IndexMask mask) const final
{
if (const GeometryComponentFieldContext *geometry_context =
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
const GeometryComponent &component = geometry_context->geometry_component();
const AttributeDomain domain = geometry_context->domain();
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
const CurveEval *curve = curve_component.get_for_read();
if (curve) {
return construct_index_on_spline_varray(*curve, mask, domain);
}
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
const CurveEval *curve = curve_component.get_for_read();
if (curve) {
return construct_index_on_spline_varray(*curve, mask, domain);
}
}
return {};

View File

@@ -61,29 +61,24 @@ static VArray<int> construct_edge_vertices_gvarray(const MeshComponent &componen
return {};
}
class EdgeVerticesFieldInput final : public fn::FieldInput {
class EdgeVerticesFieldInput final : public GeometryFieldInput {
private:
VertexNumber vertex_;
public:
EdgeVerticesFieldInput(VertexNumber vertex)
: fn::FieldInput(CPPType::get<int>(), "Edge Vertices Field"), vertex_(vertex)
: GeometryFieldInput(CPPType::get<int>(), "Edge Vertices Field"), vertex_(vertex)
{
category_ = Category::Generated;
}
GVArray get_varray_for_context(const fn::FieldContext &context,
IndexMask UNUSED(mask),
ResourceScope &UNUSED(scope)) const final
GVArray get_varray_for_context(const GeometryComponent &component,
const AttributeDomain domain,
IndexMask UNUSED(mask)) const final
{
if (const GeometryComponentFieldContext *geometry_context =
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
const GeometryComponent &component = geometry_context->geometry_component();
const AttributeDomain domain = geometry_context->domain();
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
return construct_edge_vertices_gvarray(mesh_component, vertex_, domain);
}
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
return construct_edge_vertices_gvarray(mesh_component, vertex_, domain);
}
return {};
}
@@ -128,29 +123,24 @@ static VArray<float3> construct_edge_positions_gvarray(const MeshComponent &comp
domain);
}
class EdgePositionFieldInput final : public fn::FieldInput {
class EdgePositionFieldInput final : public GeometryFieldInput {
private:
VertexNumber vertex_;
public:
EdgePositionFieldInput(VertexNumber vertex)
: fn::FieldInput(CPPType::get<float3>(), "Edge Position Field"), vertex_(vertex)
: GeometryFieldInput(CPPType::get<float3>(), "Edge Position Field"), vertex_(vertex)
{
category_ = Category::Generated;
}
GVArray get_varray_for_context(const fn::FieldContext &context,
IndexMask UNUSED(mask),
ResourceScope &UNUSED(scope)) const final
GVArray get_varray_for_context(const GeometryComponent &component,
const AttributeDomain domain,
IndexMask UNUSED(mask)) const final
{
if (const GeometryComponentFieldContext *geometry_context =
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
const GeometryComponent &component = geometry_context->geometry_component();
const AttributeDomain domain = geometry_context->domain();
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
return construct_edge_positions_gvarray(mesh_component, vertex_, domain);
}
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
return construct_edge_positions_gvarray(mesh_component, vertex_, domain);
}
return {};
}

View File

@@ -47,25 +47,20 @@ static VArray<float> construct_face_area_gvarray(const MeshComponent &component,
VArray<float>::ForFunc(mesh->totpoly, area_fn), ATTR_DOMAIN_FACE, domain);
}
class FaceAreaFieldInput final : public fn::FieldInput {
class FaceAreaFieldInput final : public GeometryFieldInput {
public:
FaceAreaFieldInput() : fn::FieldInput(CPPType::get<float>(), "Face Area Field")
FaceAreaFieldInput() : GeometryFieldInput(CPPType::get<float>(), "Face Area Field")
{
category_ = Category::Generated;
}
GVArray get_varray_for_context(const fn::FieldContext &context,
IndexMask UNUSED(mask),
ResourceScope &UNUSED(scope)) const final
GVArray get_varray_for_context(const GeometryComponent &component,
const AttributeDomain domain,
IndexMask UNUSED(mask)) const final
{
if (const GeometryComponentFieldContext *geometry_context =
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
const GeometryComponent &component = geometry_context->geometry_component();
const AttributeDomain domain = geometry_context->domain();
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
return construct_face_area_gvarray(mesh_component, domain);
}
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
return construct_face_area_gvarray(mesh_component, domain);
}
return {};
}

View File

@@ -58,25 +58,21 @@ static VArray<int> construct_neighbor_count_gvarray(const MeshComponent &compone
VArray<int>::ForContainer(std::move(poly_count)), ATTR_DOMAIN_FACE, domain);
}
class FaceNeighborCountFieldInput final : public fn::FieldInput {
class FaceNeighborCountFieldInput final : public GeometryFieldInput {
public:
FaceNeighborCountFieldInput() : fn::FieldInput(CPPType::get<int>(), "Face Neighbor Count Field")
FaceNeighborCountFieldInput()
: GeometryFieldInput(CPPType::get<int>(), "Face Neighbor Count Field")
{
category_ = Category::Generated;
}
GVArray get_varray_for_context(const fn::FieldContext &context,
IndexMask UNUSED(mask),
ResourceScope &UNUSED(scope)) const final
GVArray get_varray_for_context(const GeometryComponent &component,
const AttributeDomain domain,
IndexMask UNUSED(mask)) const final
{
if (const GeometryComponentFieldContext *geometry_context =
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
const GeometryComponent &component = geometry_context->geometry_component();
const AttributeDomain domain = geometry_context->domain();
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
return construct_neighbor_count_gvarray(mesh_component, domain);
}
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
return construct_neighbor_count_gvarray(mesh_component, domain);
}
return {};
}
@@ -108,25 +104,20 @@ static VArray<int> construct_vertex_count_gvarray(const MeshComponent &component
domain);
}
class FaceVertexCountFieldInput final : public fn::FieldInput {
class FaceVertexCountFieldInput final : public GeometryFieldInput {
public:
FaceVertexCountFieldInput() : fn::FieldInput(CPPType::get<int>(), "Vertex Count Field")
FaceVertexCountFieldInput() : GeometryFieldInput(CPPType::get<int>(), "Vertex Count Field")
{
category_ = Category::Generated;
}
GVArray get_varray_for_context(const fn::FieldContext &context,
IndexMask UNUSED(mask),
ResourceScope &UNUSED(scope)) const final
GVArray get_varray_for_context(const GeometryComponent &component,
const AttributeDomain domain,
IndexMask UNUSED(mask)) const final
{
if (const GeometryComponentFieldContext *geometry_context =
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
const GeometryComponent &component = geometry_context->geometry_component();
const AttributeDomain domain = geometry_context->domain();
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
return construct_vertex_count_gvarray(mesh_component, domain);
}
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
return construct_vertex_count_gvarray(mesh_component, domain);
}
return {};
}

View File

@@ -52,25 +52,20 @@ static VArray<int> construct_vertex_count_gvarray(const MeshComponent &component
return {};
}
class VertexCountFieldInput final : public fn::FieldInput {
class VertexCountFieldInput final : public GeometryFieldInput {
public:
VertexCountFieldInput() : fn::FieldInput(CPPType::get<int>(), "Vertex Count Field")
VertexCountFieldInput() : GeometryFieldInput(CPPType::get<int>(), "Vertex Count Field")
{
category_ = Category::Generated;
}
GVArray get_varray_for_context(const fn::FieldContext &context,
IndexMask UNUSED(mask),
ResourceScope &UNUSED(scope)) const final
GVArray get_varray_for_context(const GeometryComponent &component,
const AttributeDomain domain,
IndexMask UNUSED(mask)) const final
{
if (const GeometryComponentFieldContext *geometry_context =
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
const GeometryComponent &component = geometry_context->geometry_component();
const AttributeDomain domain = geometry_context->domain();
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
return construct_vertex_count_gvarray(mesh_component, domain);
}
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
return construct_vertex_count_gvarray(mesh_component, domain);
}
return {};
}
@@ -106,25 +101,20 @@ static VArray<int> construct_face_count_gvarray(const MeshComponent &component,
return {};
}
class VertexFaceCountFieldInput final : public fn::FieldInput {
class VertexFaceCountFieldInput final : public GeometryFieldInput {
public:
VertexFaceCountFieldInput() : fn::FieldInput(CPPType::get<int>(), "Vertex Face Count Field")
VertexFaceCountFieldInput() : GeometryFieldInput(CPPType::get<int>(), "Vertex Face Count Field")
{
category_ = Category::Generated;
}
GVArray get_varray_for_context(const fn::FieldContext &context,
IndexMask UNUSED(mask),
ResourceScope &UNUSED(scope)) const final
GVArray get_varray_for_context(const GeometryComponent &component,
const AttributeDomain domain,
IndexMask UNUSED(mask)) const final
{
if (const GeometryComponentFieldContext *geometry_context =
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
const GeometryComponent &component = geometry_context->geometry_component();
const AttributeDomain domain = geometry_context->domain();
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
return construct_face_count_gvarray(mesh_component, domain);
}
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
return construct_face_count_gvarray(mesh_component, domain);
}
return {};
}

View File

@@ -93,8 +93,7 @@ static VArray<float3> mesh_vertex_normals(const Mesh &mesh,
static VArray<float3> construct_mesh_normals_gvarray(const MeshComponent &mesh_component,
const Mesh &mesh,
const IndexMask mask,
const AttributeDomain domain,
ResourceScope &UNUSED(scope))
const AttributeDomain domain)
{
Span<MVert> verts{mesh.mvert, mesh.totvert};
Span<MEdge> edges{mesh.medge, mesh.totedge};
@@ -199,8 +198,7 @@ static Array<float3> curve_normal_point_domain(const CurveEval &curve)
}
static VArray<float3> construct_curve_normal_gvarray(const CurveComponent &component,
const AttributeDomain domain,
ResourceScope &UNUSED(scope))
const AttributeDomain domain)
{
const CurveEval *curve = component.get_for_read();
if (curve == nullptr) {
@@ -231,36 +229,29 @@ static VArray<float3> construct_curve_normal_gvarray(const CurveComponent &compo
return nullptr;
}
class NormalFieldInput final : public fn::FieldInput {
class NormalFieldInput final : public GeometryFieldInput {
public:
NormalFieldInput() : fn::FieldInput(CPPType::get<float3>(), "Normal node")
NormalFieldInput() : GeometryFieldInput(CPPType::get<float3>(), "Normal node")
{
category_ = Category::Generated;
}
GVArray get_varray_for_context(const fn::FieldContext &context,
IndexMask mask,
ResourceScope &scope) const final
GVArray get_varray_for_context(const GeometryComponent &component,
const AttributeDomain domain,
IndexMask mask) const final
{
if (const GeometryComponentFieldContext *geometry_context =
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
const GeometryComponent &component = geometry_context->geometry_component();
const AttributeDomain domain = geometry_context->domain();
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
const Mesh *mesh = mesh_component.get_for_read();
if (mesh == nullptr) {
return {};
}
return construct_mesh_normals_gvarray(mesh_component, *mesh, mask, domain, scope);
}
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
return construct_curve_normal_gvarray(curve_component, domain, scope);
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
const Mesh *mesh = mesh_component.get_for_read();
if (mesh == nullptr) {
return {};
}
return construct_mesh_normals_gvarray(mesh_component, *mesh, mask, domain);
}
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
return construct_curve_normal_gvarray(curve_component, domain);
}
return {};
}

View File

@@ -31,8 +31,7 @@ static void node_declare(NodeDeclarationBuilder &b)
*/
static VArray<float> construct_spline_length_gvarray(const CurveComponent &component,
const AttributeDomain domain,
ResourceScope &UNUSED(scope))
const AttributeDomain domain)
{
const CurveEval *curve = component.get_for_read();
if (curve == nullptr) {
@@ -54,26 +53,20 @@ static VArray<float> construct_spline_length_gvarray(const CurveComponent &compo
return {};
}
class SplineLengthFieldInput final : public fn::FieldInput {
class SplineLengthFieldInput final : public GeometryFieldInput {
public:
SplineLengthFieldInput() : fn::FieldInput(CPPType::get<float>(), "Spline Length node")
SplineLengthFieldInput() : GeometryFieldInput(CPPType::get<float>(), "Spline Length node")
{
category_ = Category::Generated;
}
GVArray get_varray_for_context(const fn::FieldContext &context,
IndexMask UNUSED(mask),
ResourceScope &scope) const final
GVArray get_varray_for_context(const GeometryComponent &component,
const AttributeDomain domain,
IndexMask UNUSED(mask)) const final
{
if (const GeometryComponentFieldContext *geometry_context =
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
const GeometryComponent &component = geometry_context->geometry_component();
const AttributeDomain domain = geometry_context->domain();
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
return construct_spline_length_gvarray(curve_component, domain, scope);
}
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
return construct_spline_length_gvarray(curve_component, domain);
}
return {};
}
@@ -95,8 +88,7 @@ class SplineLengthFieldInput final : public fn::FieldInput {
*/
static VArray<int> construct_spline_count_gvarray(const CurveComponent &component,
const AttributeDomain domain,
ResourceScope &UNUSED(scope))
const AttributeDomain domain)
{
const CurveEval *curve = component.get_for_read();
if (curve == nullptr) {
@@ -118,26 +110,20 @@ static VArray<int> construct_spline_count_gvarray(const CurveComponent &componen
return {};
}
class SplineCountFieldInput final : public fn::FieldInput {
class SplineCountFieldInput final : public GeometryFieldInput {
public:
SplineCountFieldInput() : fn::FieldInput(CPPType::get<int>(), "Spline Point Count")
SplineCountFieldInput() : GeometryFieldInput(CPPType::get<int>(), "Spline Point Count")
{
category_ = Category::Generated;
}
GVArray get_varray_for_context(const fn::FieldContext &context,
IndexMask UNUSED(mask),
ResourceScope &scope) const final
GVArray get_varray_for_context(const GeometryComponent &component,
const AttributeDomain domain,
IndexMask UNUSED(mask)) const final
{
if (const GeometryComponentFieldContext *geometry_context =
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
const GeometryComponent &component = geometry_context->geometry_component();
const AttributeDomain domain = geometry_context->domain();
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
return construct_spline_count_gvarray(curve_component, domain, scope);
}
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
return construct_spline_count_gvarray(curve_component, domain);
}
return {};
}

View File

@@ -85,8 +85,7 @@ static Array<float3> curve_tangent_point_domain(const CurveEval &curve)
}
static VArray<float3> construct_curve_tangent_gvarray(const CurveComponent &component,
const AttributeDomain domain,
ResourceScope &UNUSED(scope))
const AttributeDomain domain)
{
const CurveEval *curve = component.get_for_read();
if (curve == nullptr) {
@@ -118,27 +117,20 @@ static VArray<float3> construct_curve_tangent_gvarray(const CurveComponent &comp
return nullptr;
}
class TangentFieldInput final : public fn::FieldInput {
class TangentFieldInput final : public GeometryFieldInput {
public:
TangentFieldInput() : fn::FieldInput(CPPType::get<float3>(), "Tangent node")
TangentFieldInput() : GeometryFieldInput(CPPType::get<float3>(), "Tangent node")
{
category_ = Category::Generated;
}
GVArray get_varray_for_context(const fn::FieldContext &context,
IndexMask UNUSED(mask),
ResourceScope &scope) const final
GVArray get_varray_for_context(const GeometryComponent &component,
const AttributeDomain domain,
IndexMask UNUSED(mask)) const final
{
if (const GeometryComponentFieldContext *geometry_context =
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
const GeometryComponent &component = geometry_context->geometry_component();
const AttributeDomain domain = geometry_context->domain();
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
return construct_curve_tangent_gvarray(curve_component, domain, scope);
}
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
return construct_curve_tangent_gvarray(curve_component, domain);
}
return {};
}

View File

@@ -54,44 +54,39 @@ static void select_mesh_by_material(const Mesh &mesh,
});
}
class MaterialSelectionFieldInput final : public fn::FieldInput {
class MaterialSelectionFieldInput final : public GeometryFieldInput {
Material *material_;
public:
MaterialSelectionFieldInput(Material *material)
: fn::FieldInput(CPPType::get<bool>(), "Material Selection node"), material_(material)
: GeometryFieldInput(CPPType::get<bool>(), "Material Selection node"), material_(material)
{
category_ = Category::Generated;
}
GVArray get_varray_for_context(const fn::FieldContext &context,
IndexMask mask,
ResourceScope &UNUSED(scope)) const final
GVArray get_varray_for_context(const GeometryComponent &component,
const AttributeDomain domain,
IndexMask mask) const final
{
if (const GeometryComponentFieldContext *geometry_context =
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
const GeometryComponent &component = geometry_context->geometry_component();
const AttributeDomain domain = geometry_context->domain();
if (component.type() != GEO_COMPONENT_TYPE_MESH) {
return {};
}
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
const Mesh *mesh = mesh_component.get_for_read();
if (mesh == nullptr) {
return {};
}
if (domain == ATTR_DOMAIN_FACE) {
Array<bool> selection(mask.min_array_size());
select_mesh_by_material(*mesh, material_, mask, selection);
return VArray<bool>::ForContainer(std::move(selection));
}
Array<bool> selection(mesh->totpoly);
select_mesh_by_material(*mesh, material_, IndexMask(mesh->totpoly), selection);
return mesh_component.attribute_try_adapt_domain<bool>(
VArray<bool>::ForContainer(std::move(selection)), ATTR_DOMAIN_FACE, domain);
if (component.type() != GEO_COMPONENT_TYPE_MESH) {
return {};
}
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
const Mesh *mesh = mesh_component.get_for_read();
if (mesh == nullptr) {
return {};
}
if (domain == ATTR_DOMAIN_FACE) {
Array<bool> selection(mask.min_array_size());
select_mesh_by_material(*mesh, material_, mask, selection);
return VArray<bool>::ForContainer(std::move(selection));
}
Array<bool> selection(mesh->totpoly);
select_mesh_by_material(*mesh, material_, IndexMask(mesh->totpoly), selection);
return mesh_component.attribute_try_adapt_domain<bool>(
VArray<bool>::ForContainer(std::move(selection)), ATTR_DOMAIN_FACE, domain);
return nullptr;
}