OverviewFilesCommitsIssuesDocsReleasesPeers

proc-nodes / src / nodes / mesh_ops_nodes.h

226 lines · c ref:
#ifndef PROC_NODES_MESH_OPS_NODES_H
#define PROC_NODES_MESH_OPS_NODES_H

#include "../graph/proc_node.h"

namespace godot {

// Flip Faces — reverse triangle winding
class FlipFacesNode : public ProcNode {
	GDCLASS(FlipFacesNode, ProcNode);

protected:
	static void _bind_methods();

public:
	StringName get_node_type() const override { return "FlipFaces"; }
	String get_node_title() const override { return "Flip Faces"; }
	String get_node_category() const override { return "Mesh Operations"; }

	void execute(ProcEvalContext &p_ctx, int p_node_idx) override;
	FlipFacesNode();
};

// Set Shade Smooth — toggle between flat/smooth normals
class SetShadeSmoothNode : public ProcNode {
	GDCLASS(SetShadeSmoothNode, ProcNode);

protected:
	static void _bind_methods();

public:
	StringName get_node_type() const override { return "SetShadeSmooth"; }
	String get_node_title() const override { return "Set Shade Smooth"; }
	String get_node_category() const override { return "Mesh Operations"; }

	void execute(ProcEvalContext &p_ctx, int p_node_idx) override;
	SetShadeSmoothNode();
};

// Subdivide Mesh — split each triangle into 4
class SubdivideMeshNode : public ProcNode {
	GDCLASS(SubdivideMeshNode, ProcNode);

protected:
	static void _bind_methods();

public:
	StringName get_node_type() const override { return "SubdivideMesh"; }
	String get_node_title() const override { return "Subdivide Mesh"; }
	String get_node_category() const override { return "Mesh Operations"; }

	void execute(ProcEvalContext &p_ctx, int p_node_idx) override;
	SubdivideMeshNode();
};

// Scale Elements — scale mesh around centroid
class ScaleElementsNode : public ProcNode {
	GDCLASS(ScaleElementsNode, ProcNode);

protected:
	static void _bind_methods();

public:
	StringName get_node_type() const override { return "ScaleElements"; }
	String get_node_title() const override { return "Scale Elements"; }
	String get_node_category() const override { return "Mesh Operations"; }

	void execute(ProcEvalContext &p_ctx, int p_node_idx) override;
	ScaleElementsNode();
};

// Extrude Mesh — extrude faces along normals
class ExtrudeMeshNode : public ProcNode {
	GDCLASS(ExtrudeMeshNode, ProcNode);

protected:
	static void _bind_methods();

	int mode = 2; // Blender's VERTICES 0, EDGES 1, FACES 2

public:
	StringName get_node_type() const override { return "ExtrudeMesh"; }
	String get_node_title() const override { return "Extrude Mesh"; }
	String get_node_category() const override { return "Mesh Operations"; }

	void set_mode(int p) { mode = p; }
	int get_mode() const { return mode; }

	void execute(ProcEvalContext &p_ctx, int p_node_idx) override;
	ExtrudeMeshNode();
};

// Merge by Distance — weld vertices closer than threshold
class MergeByDistanceNode : public ProcNode {
	GDCLASS(MergeByDistanceNode, ProcNode);

protected:
	static void _bind_methods();

public:
	StringName get_node_type() const override { return "MergeByDistance"; }
	String get_node_title() const override { return "Merge by Distance"; }
	String get_node_category() const override { return "Mesh Operations"; }

	void execute(ProcEvalContext &p_ctx, int p_node_idx) override;
	MergeByDistanceNode();
};

// Dual Mesh — replace faces with vertices and vice versa
class DualMeshNode : public ProcNode {
	GDCLASS(DualMeshNode, ProcNode);

protected:
	static void _bind_methods();

public:
	StringName get_node_type() const override { return "DualMesh"; }
	String get_node_title() const override { return "Dual Mesh"; }
	String get_node_category() const override { return "Mesh Operations"; }

	void execute(ProcEvalContext &p_ctx, int p_node_idx) override;
	DualMeshNode();
};

// Duplicate Elements — duplicate mesh elements N times
class DuplicateElementsNode : public ProcNode {
	GDCLASS(DuplicateElementsNode, ProcNode);

protected:
	static void _bind_methods();

public:
	StringName get_node_type() const override { return "DuplicateElements"; }
	String get_node_title() const override { return "Duplicate Elements"; }
	String get_node_category() const override { return "Mesh Operations"; }

	void execute(ProcEvalContext &p_ctx, int p_node_idx) override;
	DuplicateElementsNode();
};

// Mesh Boolean — boolean operations on meshes (union, intersect, subtract)
class MeshBooleanNode : public ProcNode {
	GDCLASS(MeshBooleanNode, ProcNode);

public:
	// BLENDER'S NUMBERING, not one of our own. The old enum had UNION 0,
	// INTERSECT 1, SUBTRACT 2 -- so every bridged operation arrived as a
	// DIFFERENT one, the same class of bug as the hand-numbered math
	// operations #62 replaced with Blender's DNA values.
	enum BooleanOp {
		OP_INTERSECT = 0,
		OP_UNION = 1,
		OP_DIFFERENCE = 2,
	};

protected:
	static void _bind_methods();

	int operation = OP_INTERSECT; // Blender's default

public:
	StringName get_node_type() const override { return "MeshBoolean"; }
	String get_node_title() const override { return "Mesh Boolean"; }
	String get_node_category() const override { return "Mesh Operations"; }

	void set_operation(int p_op) { operation = p_op; }
	int get_operation() const { return operation; }

	void execute(ProcEvalContext &p_ctx, int p_node_idx) override;
	MeshBooleanNode();
};

// Split Edges — disconnect faces at sharp edges
class SplitEdgesNode : public ProcNode {
	GDCLASS(SplitEdgesNode, ProcNode);

protected:
	static void _bind_methods();

public:
	StringName get_node_type() const override { return "SplitEdges"; }
	String get_node_title() const override { return "Split Edges"; }
	String get_node_category() const override { return "Mesh Operations"; }

	void execute(ProcEvalContext &p_ctx, int p_node_idx) override;
	SplitEdgesNode();
};

// Triangulate — ensure all faces are triangles
class TriangulateNode : public ProcNode {
	GDCLASS(TriangulateNode, ProcNode);

protected:
	static void _bind_methods();

public:
	StringName get_node_type() const override { return "Triangulate"; }
	String get_node_title() const override { return "Triangulate"; }
	String get_node_category() const override { return "Mesh Operations"; }

	void execute(ProcEvalContext &p_ctx, int p_node_idx) override;
	TriangulateNode();
};

// Edge Paths to Curves — extract edge paths as curves
class EdgePathsToCurvesNode : public ProcNode {
	GDCLASS(EdgePathsToCurvesNode, ProcNode);

protected:
	static void _bind_methods();

public:
	StringName get_node_type() const override { return "EdgePathsToCurves"; }
	String get_node_title() const override { return "Edge Paths to Curves"; }
	String get_node_category() const override { return "Mesh Operations"; }

	void execute(ProcEvalContext &p_ctx, int p_node_idx) override;
	EdgePathsToCurvesNode();
};

} // namespace godot

VARIANT_ENUM_CAST(godot::MeshBooleanNode::BooleanOp);

#endif // PROC_NODES_MESH_OPS_NODES_H