Blender V4.3
node_geo_triangulate.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "BKE_customdata.hh"
6#include "BKE_mesh.hh"
7
8#include "bmesh.hh"
9#include "bmesh_tools.hh"
10
11#include "DNA_mesh_types.h"
12
13#include "NOD_rna_define.hh"
14
15#include "UI_interface.hh"
16#include "UI_resources.hh"
17
18#include "GEO_randomize.hh"
19
20#include "node_geometry_util.hh"
21
23
25{
26 b.add_input<decl::Geometry>("Mesh").supported_type(GeometryComponent::Type::Mesh);
27 b.add_input<decl::Bool>("Selection").default_value(true).field_on_all().hide_value();
28 b.add_input<decl::Int>("Minimum Vertices").default_value(4).min(4).max(10000);
29 b.add_output<decl::Geometry>("Mesh").propagate_all();
30}
31
32static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
33{
34 uiItemR(layout, ptr, "quad_method", UI_ITEM_NONE, "", ICON_NONE);
35 uiItemR(layout, ptr, "ngon_method", UI_ITEM_NONE, "", ICON_NONE);
36}
37
38static void geo_triangulate_init(bNodeTree * /*tree*/, bNode *node)
39{
42}
43
45 const int quad_method,
46 const int ngon_method,
47 const IndexMask &selection,
48 const int min_vertices)
49{
50 CustomData_MeshMasks cd_mask_extra = {
52 BMeshCreateParams create_params{false};
53 BMeshFromMeshParams from_mesh_params{};
54 from_mesh_params.calc_face_normal = true;
55 from_mesh_params.calc_vert_normal = true;
56 from_mesh_params.cd_mask_extra = cd_mask_extra;
57 BMesh *bm = BKE_mesh_to_bmesh_ex(&mesh, &create_params, &from_mesh_params);
58
59 /* Tag faces to be triangulated from the selection mask. */
61 selection.foreach_index([&](const int i_face) {
63 });
64
65 BM_mesh_triangulate(bm, quad_method, ngon_method, min_vertices, true, nullptr, nullptr, nullptr);
66 Mesh *result = BKE_mesh_from_bmesh_for_eval_nomain(bm, &cd_mask_extra, &mesh);
68
69 /* Positions are not changed by the triangulation operation, so the bounds are the same. */
70 result->runtime->bounds_cache = mesh.runtime->bounds_cache;
71
72 /* Vertex order is not affected. */
75
76 return result;
77}
78
80{
81 GeometrySet geometry_set = params.extract_input<GeometrySet>("Mesh");
82 Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
83 const int min_vertices = std::max(params.extract_input<int>("Minimum Vertices"), 4);
84
87
88 geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
89 if (!geometry_set.has_mesh()) {
90 return;
91 }
92 const Mesh &mesh_in = *geometry_set.get_mesh();
93
94 const bke::MeshFieldContext context{mesh_in, AttrDomain::Face};
95 FieldEvaluator evaluator{context, mesh_in.faces_num};
96 evaluator.add(selection_field);
97 evaluator.evaluate();
98 const IndexMask selection = evaluator.get_evaluated_as_mask(0);
99
101 mesh_in, quad_method, ngon_method, selection, min_vertices);
102 geometry_set.replace_mesh(mesh_out);
103 });
104
105 params.set_output("Mesh", std::move(geometry_set));
106}
107
108static void node_rna(StructRNA *srna)
109{
110 static const EnumPropertyItem rna_node_geometry_triangulate_quad_method_items[] = {
112 "BEAUTY",
113 0,
114 "Beauty",
115 "Split the quads in nice triangles, slower method"},
117 "FIXED",
118 0,
119 "Fixed",
120 "Split the quads on the first and third vertices"},
122 "FIXED_ALTERNATE",
123 0,
124 "Fixed Alternate",
125 "Split the quads on the 2nd and 4th vertices"},
127 "SHORTEST_DIAGONAL",
128 0,
129 "Shortest Diagonal",
130 "Split the quads along their shortest diagonal"},
132 "LONGEST_DIAGONAL",
133 0,
134 "Longest Diagonal",
135 "Split the quads along their longest diagonal"},
136 {0, nullptr, 0, nullptr, nullptr},
137 };
138
139 static const EnumPropertyItem rna_node_geometry_triangulate_ngon_method_items[] = {
141 "BEAUTY",
142 0,
143 "Beauty",
144 "Arrange the new triangles evenly (slow)"},
146 "CLIP",
147 0,
148 "Clip",
149 "Split the polygons with an ear clipping algorithm"},
150 {0, nullptr, 0, nullptr, nullptr},
151 };
152
154 "quad_method",
155 "Quad Method",
156 "Method for splitting the quads into triangles",
157 rna_node_geometry_triangulate_quad_method_items,
160 nullptr,
161 true);
162
164 "ngon_method",
165 "N-gon Method",
166 "Method for splitting the n-gons into triangles",
167 rna_node_geometry_triangulate_ngon_method_items,
170 nullptr,
171 true);
172}
173
174static void node_register()
175{
176 static blender::bke::bNodeType ntype;
177
178 geo_node_type_base(&ntype, GEO_NODE_TRIANGULATE, "Triangulate", NODE_CLASS_GEOMETRY);
179 ntype.declare = node_declare;
184
185 node_rna(ntype.rna_ext.srna);
186}
188
189} // namespace blender::nodes::node_geo_triangulate_cc
CustomData interface, see also DNA_customdata_types.h.
Mesh * BKE_mesh_from_bmesh_for_eval_nomain(BMesh *bm, const CustomData_MeshMasks *cd_mask_extra, const Mesh *me_settings)
BMesh * BKE_mesh_to_bmesh_ex(const Mesh *mesh, const BMeshCreateParams *create_params, const BMeshFromMeshParams *convert_params)
#define NODE_CLASS_GEOMETRY
Definition BKE_node.hh:418
#define CD_MASK_ORIGINDEX
GeometryNodeTriangulateQuads
@ GEO_NODE_TRIANGULATE_QUAD_SHORTEDGE
@ GEO_NODE_TRIANGULATE_QUAD_BEAUTY
@ GEO_NODE_TRIANGULATE_QUAD_ALTERNATE
@ GEO_NODE_TRIANGULATE_QUAD_LONGEDGE
@ GEO_NODE_TRIANGULATE_QUAD_FIXED
GeometryNodeTriangulateNGons
@ GEO_NODE_TRIANGULATE_NGON_EARCLIP
@ GEO_NODE_TRIANGULATE_NGON_BEAUTY
@ GEO_NODE_POINTS_TO_VOLUME_RESOLUTION_MODE_AMOUNT
#define NOD_REGISTER_NODE(REGISTER_FUNC)
#define NOD_inline_enum_accessors(member)
#define UI_ITEM_NONE
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
@ BM_ELEM_TAG
#define BM_elem_flag_set(ele, hflag, val)
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_mesh_free(BMesh *bm)
BMesh Free Mesh.
void BM_mesh_elem_table_ensure(BMesh *bm, const char htype)
BLI_INLINE BMFace * BM_face_at_index(BMesh *bm, const int index)
#define BM_FACE
void BM_mesh_triangulate(BMesh *bm, const int quad_method, const int ngon_method, const int min_vertices, const bool tag_only, BMOperator *op, BMOpSlot *slot_facemap_out, BMOpSlot *slot_facemap_double_out)
int add(GField field, GVArray *varray_ptr)
Definition field.cc:756
local_group_size(16, 16) .push_constant(Type b
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void node_register_type(bNodeType *ntype)
Definition node.cc:1708
void debug_randomize_edge_order(Mesh *mesh)
Definition randomize.cc:108
void debug_randomize_face_order(Mesh *mesh)
Definition randomize.cc:158
static Mesh * triangulate_mesh_selection(const Mesh &mesh, const int quad_method, const int ngon_method, const IndexMask &selection, const int min_vertices)
static void geo_triangulate_init(bNodeTree *, bNode *node)
static void node_layout(uiLayout *layout, bContext *, PointerRNA *ptr)
static void node_declare(NodeDeclarationBuilder &b)
static void node_geo_exec(GeoNodeExecParams params)
PropertyRNA * RNA_def_node_enum(StructRNA *srna, const char *identifier, const char *ui_name, const char *ui_description, const EnumPropertyItem *static_items, const EnumRNAAccessors accessors, std::optional< int > default_value, const EnumPropertyItemFunc item_func, const bool allow_animation)
void geo_node_type_base(blender::bke::bNodeType *ntype, int type, const char *name, short nclass)
StructRNA * srna
Definition RNA_types.hh:780
const Mesh * get_mesh() const
void modify_geometry_sets(ForeachSubGeometryCallback callback)
void replace_mesh(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
Defines a node type.
Definition BKE_node.hh:218
void(* initfunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:267
NodeGeometryExecFunction geometry_node_execute
Definition BKE_node.hh:339
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
Definition BKE_node.hh:238
NodeDeclareFunction declare
Definition BKE_node.hh:347
PointerRNA * ptr
Definition wm_files.cc:4126