Compare commits
16 Commits
temp-node-
...
soc-2021-p
Author | SHA1 | Date | |
---|---|---|---|
6dda3a7f2e | |||
4a5d913d1d | |||
038b87b8b2 | |||
9887dac2fb | |||
33c35c9340 | |||
fad55ce70b | |||
c54bdc7fb6 | |||
a28e518917 | |||
a7dc3d1e90 | |||
6fd836f53b | |||
991f6b15f3 | |||
aef45a4ef2 | |||
504e3c563f | |||
b5573bfbf4 | |||
ba9561ab0d | |||
c659af0c13 |
@@ -553,6 +553,7 @@ geometry_node_categories = [
|
||||
NodeItem("GeometryNodeEdgeSplit"),
|
||||
NodeItem("GeometryNodeSubdivisionSurface"),
|
||||
NodeItem("GeometryNodeMeshSubdivide"),
|
||||
NodeItem("GeometryNodeMeshExtrude"),
|
||||
]),
|
||||
GeometryNodeCategory("GEO_PRIMITIVES_MESH", "Mesh Primitives", items=[
|
||||
NodeItem("GeometryNodeMeshCircle"),
|
||||
|
@@ -1477,6 +1477,7 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
|
||||
#define GEO_NODE_CURVE_SET_HANDLES 1072
|
||||
#define GEO_NODE_CURVE_SPLINE_TYPE 1073
|
||||
#define GEO_NODE_CURVE_SELECT_HANDLES 1074
|
||||
#define GEO_NODE_MESH_EXTRUDE 1075
|
||||
|
||||
/** \} */
|
||||
|
||||
|
@@ -5157,6 +5157,7 @@ static void registerGeometryNodes()
|
||||
register_node_type_geo_curve_trim();
|
||||
register_node_type_geo_delete_geometry();
|
||||
register_node_type_geo_edge_split();
|
||||
register_node_type_geo_mesh_extrude();
|
||||
register_node_type_geo_input_material();
|
||||
register_node_type_geo_is_viewport();
|
||||
register_node_type_geo_join_geometry();
|
||||
|
@@ -1446,4 +1446,120 @@ void BM_mesh_vert_coords_apply_with_mat4(BMesh *bm,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use to select bmesh vertex data based on an array of bool.
|
||||
*/
|
||||
void BM_select_vertices(BMesh *bm, const bool *mask)
|
||||
{
|
||||
BMIter iter;
|
||||
BMVert *v;
|
||||
int i;
|
||||
BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
|
||||
BM_elem_flag_set(v, BM_ELEM_SELECT, mask[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use to select bmesh edge data based on an array of bool.
|
||||
*/
|
||||
void BM_select_edges(BMesh *bm, const bool *mask)
|
||||
{
|
||||
BMIter iter;
|
||||
BMEdge *e;
|
||||
int i;
|
||||
BM_ITER_MESH_INDEX (e, &iter, bm, BM_EDGES_OF_MESH, i) {
|
||||
BM_elem_flag_set(e, BM_ELEM_SELECT, mask[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use to select bmesh face data based on an array of bool.
|
||||
*/
|
||||
void BM_select_faces(BMesh *bm, const bool *mask)
|
||||
{
|
||||
BMIter iter;
|
||||
BMFace *f;
|
||||
int i = 0;
|
||||
BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, i) {
|
||||
BM_elem_flag_set(f, BM_ELEM_SELECT, mask[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void BM_get_selected_vertices(BMesh *bm, bool *selection)
|
||||
{
|
||||
BMIter iter;
|
||||
BMVert *v;
|
||||
int i;
|
||||
BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
|
||||
selection[i] = BM_elem_flag_test(v, BM_ELEM_SELECT);
|
||||
}
|
||||
}
|
||||
|
||||
void BM_get_tagged_faces(BMesh *bm, bool *selection)
|
||||
{
|
||||
BMIter iter;
|
||||
BMFace *f;
|
||||
int i;
|
||||
BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, i) {
|
||||
selection[i] = BM_elem_flag_test(f, BM_ELEM_TAG);
|
||||
}
|
||||
}
|
||||
|
||||
void BM_tag_new_faces(BMesh *bm, BMOperator *b_mesh_operator)
|
||||
{
|
||||
BMIter iter;
|
||||
BMFace *f;
|
||||
BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, false);
|
||||
BMO_ITER (f, &iter, b_mesh_operator->slots_out, "faces.out", BM_FACE) {
|
||||
BM_elem_flag_enable(f, BM_ELEM_TAG);
|
||||
}
|
||||
}
|
||||
|
||||
void BM_tag_vertices(BMesh *bm, const bool *mask)
|
||||
{
|
||||
BMIter iter;
|
||||
BMVert *v;
|
||||
int i;
|
||||
BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
|
||||
BM_elem_flag_set(v, BM_ELEM_TAG, mask[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use to temporary tag bmesh edge data based on an array of bool.
|
||||
*/
|
||||
void BM_tag_edges(BMesh *bm, const bool *mask)
|
||||
{
|
||||
BMIter iter;
|
||||
BMEdge *e;
|
||||
int i;
|
||||
BM_ITER_MESH_INDEX (e, &iter, bm, BM_EDGES_OF_MESH, i) {
|
||||
BM_elem_flag_set(e, BM_ELEM_TAG, mask[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use to temporary tag bmesh face data based on an array of bool.
|
||||
*/
|
||||
void BM_tag_faces(BMesh *bm, const bool *mask)
|
||||
{
|
||||
BMIter iter;
|
||||
BMFace *f;
|
||||
int i;
|
||||
BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, i) {
|
||||
BM_elem_flag_set(f, BM_ELEM_TAG, mask[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void BM_untag_faces_by_tag(BMesh *bm, int tag)
|
||||
{
|
||||
BMIter iter;
|
||||
BMFace *f;
|
||||
int i;
|
||||
BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, i) {
|
||||
if (BM_elem_flag_test(f, tag)) {
|
||||
BM_elem_flag_disable(f, BM_ELEM_TAG);
|
||||
}
|
||||
}
|
||||
}
|
||||
/** \} */
|
||||
|
@@ -134,3 +134,14 @@ void BM_mesh_vert_coords_apply(BMesh *bm, const float (*vert_coords)[3]);
|
||||
void BM_mesh_vert_coords_apply_with_mat4(BMesh *bm,
|
||||
const float (*vert_coords)[3],
|
||||
const float mat[4][4]);
|
||||
|
||||
void BM_select_vertices(BMesh *bm, const bool *mask);
|
||||
void BM_select_edges(BMesh *bm, const bool *mask);
|
||||
void BM_select_faces(BMesh *bm, const bool *mask);
|
||||
void BM_get_selected_vertices(BMesh *bm, bool *selection);
|
||||
void BM_tag_vertices(BMesh *bm, const bool *mask);
|
||||
void BM_tag_edges(BMesh *bm, const bool *mask);
|
||||
void BM_tag_faces(BMesh *bm, const bool *mask);
|
||||
void BM_untag_faces_by_tag(BMesh *bm, int tag);
|
||||
void BM_get_tagged_faces(BMesh *bm, bool *selection);
|
||||
void BM_tag_new_faces(BMesh *bm, BMOperator *b_mesh_operator);
|
||||
|
@@ -10178,6 +10178,25 @@ static void def_geo_attribute_transfer(StructRNA *srna)
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||
}
|
||||
|
||||
static void def_geo_mesh_extrude(StructRNA *srna)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
static const EnumPropertyItem rna_node_geometry_extrude_domain_items[] = {
|
||||
{0, "VERTEX", 0, "Vertex", "Extrude Vertices"},
|
||||
{1, "EDGE", 0, "Edge", "Extrude Edges"},
|
||||
{2, "FACE", 0, "Face", "Extrude Faces"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
prop = RNA_def_property(srna, "extrude_mode", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "custom1");
|
||||
RNA_def_property_enum_items(prop, rna_node_geometry_extrude_domain_items);
|
||||
RNA_def_property_enum_default(prop, GEO_NODE_POINT_DISTRIBUTE_RANDOM);
|
||||
RNA_def_property_ui_text(prop, "Extrude Mode", "Select mesh domain to extrude");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
|
||||
}
|
||||
|
||||
static void def_geo_input_material(StructRNA *srna)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
@@ -184,6 +184,7 @@ set(SRC
|
||||
geometry/nodes/node_geo_curve_trim.cc
|
||||
geometry/nodes/node_geo_delete_geometry.cc
|
||||
geometry/nodes/node_geo_edge_split.cc
|
||||
geometry/nodes/node_geo_mesh_extrude.cc
|
||||
geometry/nodes/node_geo_input_material.cc
|
||||
geometry/nodes/node_geo_is_viewport.cc
|
||||
geometry/nodes/node_geo_join_geometry.cc
|
||||
|
@@ -70,6 +70,7 @@ void register_node_type_geo_curve_to_points(void);
|
||||
void register_node_type_geo_curve_trim(void);
|
||||
void register_node_type_geo_delete_geometry(void);
|
||||
void register_node_type_geo_edge_split(void);
|
||||
void register_node_type_geo_mesh_extrude(void);
|
||||
void register_node_type_geo_input_material(void);
|
||||
void register_node_type_geo_is_viewport(void);
|
||||
void register_node_type_geo_join_geometry(void);
|
||||
|
@@ -311,6 +311,7 @@ DefNode(GeometryNode, GEO_NODE_CURVE_TO_POINTS, def_geo_curve_to_points, "CURVE_
|
||||
DefNode(GeometryNode, GEO_NODE_CURVE_TRIM, def_geo_curve_trim, "CURVE_TRIM", CurveTrim, "Curve Trim", "")
|
||||
DefNode(GeometryNode, GEO_NODE_DELETE_GEOMETRY, 0, "DELETE_GEOMETRY", DeleteGeometry, "Delete Geometry", "")
|
||||
DefNode(GeometryNode, GEO_NODE_EDGE_SPLIT, 0, "EDGE_SPLIT", EdgeSplit, "Edge Split", "")
|
||||
DefNode(GeometryNode, GEO_NODE_MESH_EXTRUDE, def_geo_mesh_extrude, "MESH_EXTRUDE", MeshExtrude, "Mesh Extrude", "")
|
||||
DefNode(GeometryNode, GEO_NODE_INPUT_MATERIAL, def_geo_input_material, "INPUT_MATERIAL", InputMaterial, "Material", "")
|
||||
DefNode(GeometryNode, GEO_NODE_IS_VIEWPORT, 0, "IS_VIEWPORT", IsViewport, "Is Viewport", "")
|
||||
DefNode(GeometryNode, GEO_NODE_JOIN_GEOMETRY, 0, "JOIN_GEOMETRY", JoinGeometry, "Join Geometry", "")
|
||||
|
253
source/blender/nodes/geometry/nodes/node_geo_mesh_extrude.cc
Normal file
253
source/blender/nodes/geometry/nodes/node_geo_mesh_extrude.cc
Normal file
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_node.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "bmesh.h"
|
||||
|
||||
#include "node_geometry_util.hh"
|
||||
|
||||
static bNodeSocketTemplate geo_node_mesh_extrude_in[] = {
|
||||
{SOCK_GEOMETRY, N_("Geometry")},
|
||||
{SOCK_VECTOR, N_("Offset"), 0.0f, 0.0f, 1.0f, 0.0f, -FLT_MAX, FLT_MAX, PROP_TRANSLATION},
|
||||
{SOCK_STRING, N_("Selection")},
|
||||
{SOCK_STRING, N_("Out Selection")},
|
||||
|
||||
{-1, ""},
|
||||
};
|
||||
|
||||
static bNodeSocketTemplate geo_node_mesh_extrude_out[] = {
|
||||
{SOCK_GEOMETRY, N_("Geometry")},
|
||||
{-1, ""},
|
||||
};
|
||||
|
||||
static void geo_node_mesh_extrude_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
|
||||
{
|
||||
uiItemR(layout, ptr, "extrude_mode", 0, "", ICON_NONE);
|
||||
}
|
||||
|
||||
static void geo_node_mesh_extrude_init(bNodeTree *UNUSED(ntree), bNode *node)
|
||||
{
|
||||
node->custom1 = 0;
|
||||
}
|
||||
|
||||
namespace blender::nodes {
|
||||
|
||||
static void SetOutputSelection(const std::string &selection_out_attribute_name,
|
||||
BMesh *bm,
|
||||
Mesh *result)
|
||||
{
|
||||
MeshComponent component;
|
||||
component.replace(result, GeometryOwnershipType::Editable);
|
||||
|
||||
if (!selection_out_attribute_name.empty()) {
|
||||
bke::OutputAttribute_Typed<bool> attribute = component.attribute_try_get_for_output_only<bool>(
|
||||
selection_out_attribute_name, ATTR_DOMAIN_POINT);
|
||||
BM_get_selected_vertices(bm, attribute.as_span().data());
|
||||
attribute.save();
|
||||
}
|
||||
}
|
||||
|
||||
static Mesh *extrude_vertices(const Mesh *mesh,
|
||||
const Span<bool> selection,
|
||||
const float3 offset,
|
||||
const std::string selection_out_attribute_name)
|
||||
{
|
||||
const BMeshCreateParams bmesh_create_params = {true};
|
||||
const BMeshFromMeshParams bmesh_from_mesh_params = {
|
||||
true, 0, 0, 0, {CD_MASK_ORIGINDEX, CD_MASK_ORIGINDEX, CD_MASK_ORIGINDEX}};
|
||||
|
||||
BMesh *bm = BKE_mesh_to_bmesh_ex(mesh, &bmesh_create_params, &bmesh_from_mesh_params);
|
||||
|
||||
BM_select_vertices(bm, selection.data());
|
||||
|
||||
BMOperator extrude_op;
|
||||
BMO_op_initf(bm, &extrude_op, 0, "extrude_vert_indiv verts=%hv", BM_ELEM_SELECT);
|
||||
BMO_op_exec(bm, &extrude_op);
|
||||
|
||||
float _offset[3] = {offset.x, offset.y, offset.z};
|
||||
BMOperator move_op;
|
||||
|
||||
BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_SELECT, false);
|
||||
BMO_slot_buffer_hflag_enable(
|
||||
bm, extrude_op.slots_out, "verts.out", BM_VERT, BM_ELEM_SELECT, false);
|
||||
|
||||
BMO_op_initf(bm, &move_op, 0, "translate vec=%v verts=%hv", _offset, BM_ELEM_SELECT);
|
||||
|
||||
BMO_op_exec(bm, &move_op);
|
||||
BMO_op_finish(bm, &move_op);
|
||||
BMO_op_finish(bm, &extrude_op);
|
||||
|
||||
CustomData_MeshMasks cd_mask_extra = {CD_MASK_ORIGINDEX, CD_MASK_ORIGINDEX, CD_MASK_ORIGINDEX};
|
||||
Mesh *result = BKE_mesh_from_bmesh_for_eval_nomain(bm, &cd_mask_extra, mesh);
|
||||
|
||||
SetOutputSelection(selection_out_attribute_name, bm, result);
|
||||
|
||||
BM_mesh_free(bm);
|
||||
BKE_mesh_normals_tag_dirty(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static Mesh *extrude_edges(const Mesh *mesh,
|
||||
const Span<bool> selection,
|
||||
const float3 offset,
|
||||
const std::string selection_out_attribute_name)
|
||||
{
|
||||
const BMeshCreateParams bmesh_create_params = {true};
|
||||
const BMeshFromMeshParams bmesh_from_mesh_params = {
|
||||
true, 0, 0, 0, {CD_MASK_ORIGINDEX, CD_MASK_ORIGINDEX, CD_MASK_ORIGINDEX}};
|
||||
|
||||
BMesh *bm = BKE_mesh_to_bmesh_ex(mesh, &bmesh_create_params, &bmesh_from_mesh_params);
|
||||
|
||||
BM_select_edges(bm, selection.data());
|
||||
|
||||
BMOperator extrude_op;
|
||||
BMO_op_initf(bm,
|
||||
&extrude_op,
|
||||
0,
|
||||
"extrude_edge_only edges=%he use_select_history=%b",
|
||||
BM_ELEM_SELECT,
|
||||
true);
|
||||
BMO_op_exec(bm, &extrude_op);
|
||||
|
||||
float _offset[3] = {offset.x, offset.y, offset.z};
|
||||
BMOperator move_op;
|
||||
|
||||
BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_SELECT, false);
|
||||
BMO_slot_buffer_hflag_enable(
|
||||
bm, extrude_op.slots_out, "geom.out", BM_VERT, BM_ELEM_SELECT, false);
|
||||
|
||||
BMO_op_initf(bm, &move_op, 0, "translate vec=%v verts=%hv", _offset, BM_ELEM_SELECT);
|
||||
|
||||
BMO_op_exec(bm, &move_op);
|
||||
BMO_op_finish(bm, &move_op);
|
||||
BMO_op_finish(bm, &extrude_op);
|
||||
|
||||
CustomData_MeshMasks cd_mask_extra = {CD_MASK_ORIGINDEX, CD_MASK_ORIGINDEX, CD_MASK_ORIGINDEX};
|
||||
Mesh *result = BKE_mesh_from_bmesh_for_eval_nomain(bm, &cd_mask_extra, mesh);
|
||||
|
||||
SetOutputSelection(selection_out_attribute_name, bm, result);
|
||||
|
||||
BM_mesh_free(bm);
|
||||
BKE_mesh_normals_tag_dirty(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static Mesh *extrude_faces(const Mesh *mesh,
|
||||
const Span<bool> selection,
|
||||
const float3 offset,
|
||||
std::string selection_out_attribute_name)
|
||||
{
|
||||
const BMeshCreateParams bmesh_create_params = {true};
|
||||
const BMeshFromMeshParams bmesh_from_mesh_params = {
|
||||
true, 0, 0, 0, {CD_MASK_ORIGINDEX, CD_MASK_ORIGINDEX, CD_MASK_ORIGINDEX}};
|
||||
|
||||
BMesh *bm = BKE_mesh_to_bmesh_ex(mesh, &bmesh_create_params, &bmesh_from_mesh_params);
|
||||
|
||||
BM_select_faces(bm, selection.data());
|
||||
|
||||
BMOperator extrude_op;
|
||||
BMO_op_initf(bm, &extrude_op, 0, "extrude_face_region geom=%hf", BM_ELEM_SELECT);
|
||||
BMO_op_exec(bm, &extrude_op);
|
||||
|
||||
float o[3] = {offset.x, offset.y, offset.z};
|
||||
BMOperator move_op;
|
||||
|
||||
BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_SELECT, false);
|
||||
BMO_slot_buffer_hflag_enable(
|
||||
bm, extrude_op.slots_out, "geom.out", BM_VERT, BM_ELEM_SELECT, false);
|
||||
|
||||
BMO_op_initf(bm, &move_op, 0, "translate vec=%v verts=%hv", o, BM_ELEM_SELECT);
|
||||
|
||||
BMO_op_exec(bm, &move_op);
|
||||
BMO_op_finish(bm, &move_op);
|
||||
BMO_op_finish(bm, &extrude_op);
|
||||
|
||||
CustomData_MeshMasks cd_mask_extra = {CD_MASK_ORIGINDEX, CD_MASK_ORIGINDEX, CD_MASK_ORIGINDEX};
|
||||
Mesh *result = BKE_mesh_from_bmesh_for_eval_nomain(bm, &cd_mask_extra, mesh);
|
||||
|
||||
SetOutputSelection(selection_out_attribute_name, bm, result);
|
||||
|
||||
BM_mesh_free(bm);
|
||||
BKE_mesh_normals_tag_dirty(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void geo_node_mesh_extrude_exec(GeoNodeExecParams params)
|
||||
{
|
||||
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
|
||||
|
||||
geometry_set = bke::geometry_set_realize_instances(geometry_set);
|
||||
MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
|
||||
|
||||
const float3 offset = params.extract_input<float3>("Offset");
|
||||
|
||||
if (offset.length() > 0 && mesh_component.has_mesh()) {
|
||||
const Mesh *input_mesh = mesh_component.get_for_read();
|
||||
|
||||
AttributeDomain domain = ATTR_DOMAIN_POINT;
|
||||
if (params.node().custom1 == 1) {
|
||||
domain = ATTR_DOMAIN_EDGE;
|
||||
}
|
||||
else if (params.node().custom1 == 2) {
|
||||
domain = ATTR_DOMAIN_FACE;
|
||||
}
|
||||
|
||||
const bool default_selection = true;
|
||||
GVArray_Typed<bool> selection_attribute = params.get_input_attribute<bool>(
|
||||
"Selection", mesh_component, domain, default_selection);
|
||||
VArray_Span<bool> selection{selection_attribute};
|
||||
|
||||
std::string out_selection_attribute_name = params.get_input<std::string>("Out Selection");
|
||||
|
||||
Mesh *result;
|
||||
if (params.node().custom1 == 1) {
|
||||
result = extrude_edges(input_mesh, selection, offset, out_selection_attribute_name);
|
||||
}
|
||||
else if (params.node().custom1 == 2) {
|
||||
result = extrude_faces(input_mesh, selection, offset, out_selection_attribute_name);
|
||||
}
|
||||
else {
|
||||
result = extrude_vertices(input_mesh, selection, offset, out_selection_attribute_name);
|
||||
}
|
||||
geometry_set.replace_mesh(result);
|
||||
}
|
||||
|
||||
params.set_output("Geometry", std::move(geometry_set));
|
||||
}
|
||||
} // namespace blender::nodes
|
||||
|
||||
void register_node_type_geo_mesh_extrude()
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
geo_node_type_base(&ntype, GEO_NODE_MESH_EXTRUDE, "Mesh Extrude", NODE_CLASS_GEOMETRY, 0);
|
||||
node_type_socket_templates(&ntype, geo_node_mesh_extrude_in, geo_node_mesh_extrude_out);
|
||||
node_type_init(&ntype, geo_node_mesh_extrude_init);
|
||||
ntype.geometry_node_execute = blender::nodes::geo_node_mesh_extrude_exec;
|
||||
ntype.draw_buttons = geo_node_mesh_extrude_layout;
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
Reference in New Issue
Block a user