Blender  V3.3
node_geo_curve_fill.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include "BLI_array.hh"
4 #include "BLI_delaunay_2d.h"
5 #include "BLI_math_vec_types.hh"
6 
7 #include "DNA_mesh_types.h"
8 #include "DNA_meshdata_types.h"
9 
10 #include "BKE_curves.hh"
11 #include "BKE_mesh.h"
12 
13 #include "BLI_task.hh"
14 
15 #include "UI_interface.h"
16 #include "UI_resources.h"
17 
18 #include "node_geometry_util.hh"
19 
21 
23 
25 {
26  b.add_input<decl::Geometry>(N_("Curve")).supported_type(GEO_COMPONENT_TYPE_CURVE);
27  b.add_output<decl::Geometry>(N_("Mesh"));
28 }
29 
30 static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
31 {
32  uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
33 }
34 
36 {
37  NodeGeometryCurveFill *data = MEM_cnew<NodeGeometryCurveFill>(__func__);
38 
40  node->storage = data;
41 }
42 
43 static meshintersect::CDT_result<double> do_cdt(const bke::CurvesGeometry &curves,
44  const CDT_output_type output_type)
45 {
46  meshintersect::CDT_input<double> input;
47  input.need_ids = false;
48  input.vert.reinitialize(curves.evaluated_points_num());
49  input.face.reinitialize(curves.curves_num());
50 
51  Span<float3> positions = curves.evaluated_positions();
52 
53  for (const int i_curve : curves.curves_range()) {
54  const IndexRange points = curves.evaluated_points_for_curve(i_curve);
55 
56  for (const int i : points) {
57  input.vert[i] = double2(positions[i].x, positions[i].y);
58  }
59 
60  input.face[i_curve].resize(points.size());
61  MutableSpan<int> face_verts = input.face[i_curve];
62  for (const int i : face_verts.index_range()) {
63  face_verts[i] = points[i];
64  }
65  }
66  meshintersect::CDT_result<double> result = delaunay_2d_calc(input, output_type);
67  return result;
68 }
69 
70 /* Converts the CDT result into a Mesh. */
71 static Mesh *cdt_to_mesh(const meshintersect::CDT_result<double> &result)
72 {
73  const int vert_len = result.vert.size();
74  const int edge_len = result.edge.size();
75  const int poly_len = result.face.size();
76  int loop_len = 0;
77  for (const Vector<int> &face : result.face) {
78  loop_len += face.size();
79  }
80 
81  Mesh *mesh = BKE_mesh_new_nomain(vert_len, edge_len, 0, loop_len, poly_len);
86 
87  for (const int i : IndexRange(result.vert.size())) {
88  copy_v3_v3(verts[i].co, float3((float)result.vert[i].x, (float)result.vert[i].y, 0.0f));
89  }
90  for (const int i : IndexRange(result.edge.size())) {
91  edges[i].v1 = result.edge[i].first;
92  edges[i].v2 = result.edge[i].second;
93  edges[i].flag = ME_EDGEDRAW | ME_EDGERENDER;
94  }
95  int i_loop = 0;
96  for (const int i : IndexRange(result.face.size())) {
97  polys[i].loopstart = i_loop;
98  polys[i].totloop = result.face[i].size();
99  for (const int j : result.face[i].index_range()) {
100  loops[i_loop].v = result.face[i][j];
101  i_loop++;
102  }
103  }
104 
105  /* The delaunay triangulation doesn't seem to return all of the necessary edges, even in
106  * triangulation mode. */
107  BKE_mesh_calc_edges(mesh, true, false);
108  return mesh;
109 }
110 
111 static void curve_fill_calculate(GeometrySet &geometry_set, const GeometryNodeCurveFillMode mode)
112 {
113  if (!geometry_set.has_curves()) {
114  return;
115  }
116 
117  const Curves &curves_id = *geometry_set.get_curves_for_read();
119  if (curves.curves_num() == 0) {
120  geometry_set.replace_curves(nullptr);
121  return;
122  }
123 
124  const CDT_output_type output_type = (mode == GEO_NODE_CURVE_FILL_MODE_NGONS) ?
127 
128  const meshintersect::CDT_result<double> results = do_cdt(curves, output_type);
129  Mesh *mesh = cdt_to_mesh(results);
130 
131  geometry_set.replace_mesh(mesh);
132  geometry_set.replace_curves(nullptr);
133 }
134 
136 {
137  GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
138 
139  const NodeGeometryCurveFill &storage = node_storage(params.node());
140  const GeometryNodeCurveFillMode mode = (GeometryNodeCurveFillMode)storage.mode;
141 
142  geometry_set.modify_geometry_sets(
143  [&](GeometrySet &geometry_set) { curve_fill_calculate(geometry_set, mode); });
144 
145  params.set_output("Mesh", std::move(geometry_set));
146 }
147 
148 } // namespace blender::nodes::node_geo_curve_fill_cc
149 
151 {
152  namespace file_ns = blender::nodes::node_geo_curve_fill_cc;
153 
154  static bNodeType ntype;
155 
157 
160  &ntype, "NodeGeometryCurveFill", node_free_standard_storage, node_copy_standard_storage);
164  nodeRegisterType(&ntype);
165 }
Low-level operations for curves.
@ GEO_COMPONENT_TYPE_CURVE
struct Mesh * BKE_mesh_new_nomain(int verts_len, int edges_len, int tessface_len, int loops_len, int polys_len)
Definition: mesh.cc:991
void BKE_mesh_calc_edges(struct Mesh *mesh, bool keep_existing_edges, bool select_new_edges)
#define NODE_STORAGE_FUNCS(StorageT)
Definition: BKE_node.h:1563
void node_type_init(struct bNodeType *ntype, void(*initfunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4390
#define NODE_CLASS_GEOMETRY
Definition: BKE_node.h:359
void node_type_storage(struct bNodeType *ntype, const char *storagename, void(*freefunc)(struct bNode *node), void(*copyfunc)(struct bNodeTree *dest_ntree, struct bNode *dest_node, const struct bNode *src_node))
Definition: node.cc:4426
#define GEO_NODE_FILL_CURVE
Definition: BKE_node.h:1417
void nodeRegisterType(struct bNodeType *ntype)
Definition: node.cc:1357
CDT_output_type
@ CDT_CONSTRAINTS_VALID_BMESH_WITH_HOLES
@ CDT_INSIDE_WITH_HOLES
MINLINE void copy_v3_v3(float r[3], const float a[3])
#define UNUSED(x)
@ ME_EDGEDRAW
@ ME_EDGERENDER
GeometryNodeCurveFillMode
@ GEO_NODE_CURVE_FILL_MODE_TRIANGULATED
@ GEO_NODE_CURVE_FILL_MODE_NGONS
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to curves
@ UI_ITEM_R_EXPAND
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
constexpr int64_t size() const
constexpr IndexRange index_range() const
Definition: BLI_span.hh:661
int64_t size() const
Definition: BLI_vector.hh:694
static CurvesGeometry & wrap(::CurvesGeometry &dna_struct)
Definition: BKE_curves.hh:138
OperationNode * node
blender::meshintersect::CDT_result< double > delaunay_2d_calc(const CDT_input< double > &input, CDT_output_type output_type)
bNodeTree * ntree
static float verts[][3]
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
ccl_global KernelShaderEvalInput * input
static void curve_fill_calculate(GeometrySet &geometry_set, const GeometryNodeCurveFillMode mode)
static void node_geo_exec(GeoNodeExecParams params)
static void node_declare(NodeDeclarationBuilder &b)
static Mesh * cdt_to_mesh(const meshintersect::CDT_result< double > &result)
static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
static meshintersect::CDT_result< double > do_cdt(const bke::CurvesGeometry &curves, const CDT_output_type output_type)
static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
vec_base< double, 2 > double2
vec_base< float, 3 > float3
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
static void node_init(const struct bContext *C, bNodeTree *ntree, bNode *node)
Definition: node.cc:1082
void register_node_type_geo_curve_fill()
MutableSpan< float3 > positions
void geo_node_type_base(bNodeType *ntype, int type, const char *name, short nclass)
void node_copy_standard_storage(bNodeTree *UNUSED(dest_ntree), bNode *dest_node, const bNode *src_node)
Definition: node_util.c:55
void node_free_standard_storage(bNode *node)
Definition: node_util.c:43
CurvesGeometry geometry
void replace_mesh(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
void replace_curves(Curves *curves, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
const Curves * get_curves_for_read() const
void modify_geometry_sets(ForeachSubGeometryCallback callback)
bool has_curves() const
struct MEdge * medge
struct MVert * mvert
int totedge
int totvert
struct MLoop * mloop
int totpoly
int totloop
struct MPoly * mpoly
Defines a node type.
Definition: BKE_node.h:226
NodeGeometryExecFunction geometry_node_execute
Definition: BKE_node.h:316
void(* draw_buttons)(struct uiLayout *, struct bContext *C, struct PointerRNA *ptr)
Definition: BKE_node.h:244
NodeDeclareFunction declare
Definition: BKE_node.h:324
#define N_(msgid)
PointerRNA * ptr
Definition: wm_files.c:3480