Welcome to mirror list, hosted at ThFree Co, Russian Federation.

node_geo_mesh_primitive_cube.cc « nodes « geometry « nodes « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 0029b547375defedbdaf38014278b7b1b5b7e3a6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/* SPDX-License-Identifier: GPL-2.0-or-later */

#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"

#include "BKE_material.h"
#include "BKE_mesh.h"

#include "GEO_mesh_primitive_cuboid.hh"

#include "node_geometry_util.hh"

namespace blender::nodes::node_geo_mesh_primitive_cube_cc {

static void node_declare(NodeDeclarationBuilder &b)
{
  b.add_input<decl::Vector>(N_("Size"))
      .default_value(float3(1))
      .min(0.0f)
      .subtype(PROP_TRANSLATION)
      .description(N_("Side length along each axis"));
  b.add_input<decl::Int>(N_("Vertices X"))
      .default_value(2)
      .min(2)
      .max(1000)
      .description(N_("Number of vertices for the X side of the shape"));
  b.add_input<decl::Int>(N_("Vertices Y"))
      .default_value(2)
      .min(2)
      .max(1000)
      .description(N_("Number of vertices for the Y side of the shape"));
  b.add_input<decl::Int>(N_("Vertices Z"))
      .default_value(2)
      .min(2)
      .max(1000)
      .description(N_("Number of vertices for the Z side of the shape"));
  b.add_output<decl::Geometry>(N_("Mesh"));
}

static Mesh *create_cuboid_mesh(const float3 &size,
                                const int verts_x,
                                const int verts_y,
                                const int verts_z)
{
  Mesh *mesh = geometry::create_cuboid_mesh(size, verts_x, verts_y, verts_z, "uv_map");
  BKE_id_material_eval_ensure_default_slot(&mesh->id);
  return mesh;
}

static Mesh *create_cube_mesh(const float3 size,
                              const int verts_x,
                              const int verts_y,
                              const int verts_z)
{
  const int dimensions = (verts_x - 1 > 0) + (verts_y - 1 > 0) + (verts_z - 1 > 0);
  if (dimensions == 0) {
    return create_line_mesh(float3(0), float3(0), 1);
  }
  if (dimensions == 1) {
    float3 start;
    float3 delta;
    if (verts_x > 1) {
      start = {-size.x / 2.0f, 0, 0};
      delta = {size.x / (verts_x - 1), 0, 0};
    }
    else if (verts_y > 1) {
      start = {0, -size.y / 2.0f, 0};
      delta = {0, size.y / (verts_y - 1), 0};
    }
    else {
      start = {0, 0, -size.z / 2.0f};
      delta = {0, 0, size.z / (verts_z - 1)};
    }

    return create_line_mesh(start, delta, verts_x * verts_y * verts_z);
  }
  if (dimensions == 2) {
    if (verts_z == 1) { /* XY plane. */
      return create_grid_mesh(verts_x, verts_y, size.x, size.y);
    }
    if (verts_y == 1) { /* XZ plane. */
      Mesh *mesh = create_grid_mesh(verts_x, verts_z, size.x, size.z);
      transform_mesh(*mesh, float3(0), float3(M_PI_2, 0.0f, 0.0f), float3(1));
      return mesh;
    }
    /* YZ plane. */
    Mesh *mesh = create_grid_mesh(verts_z, verts_y, size.z, size.y);
    transform_mesh(*mesh, float3(0), float3(0.0f, M_PI_2, 0.0f), float3(1));
    return mesh;
  }

  return create_cuboid_mesh(size, verts_x, verts_y, verts_z);
}

static void node_geo_exec(GeoNodeExecParams params)
{
  const float3 size = params.extract_input<float3>("Size");
  const int verts_x = params.extract_input<int>("Vertices X");
  const int verts_y = params.extract_input<int>("Vertices Y");
  const int verts_z = params.extract_input<int>("Vertices Z");
  if (verts_x < 1 || verts_y < 1 || verts_z < 1) {
    params.error_message_add(NodeWarningType::Info, TIP_("Vertices must be at least 1"));
    params.set_default_remaining_outputs();
    return;
  }

  Mesh *mesh = create_cube_mesh(size, verts_x, verts_y, verts_z);

  params.set_output("Mesh", GeometrySet::create_with_mesh(mesh));
}

}  // namespace blender::nodes::node_geo_mesh_primitive_cube_cc

void register_node_type_geo_mesh_primitive_cube()
{
  namespace file_ns = blender::nodes::node_geo_mesh_primitive_cube_cc;

  static bNodeType ntype;

  geo_node_type_base(&ntype, GEO_NODE_MESH_PRIMITIVE_CUBE, "Cube", NODE_CLASS_GEOMETRY);
  ntype.declare = file_ns::node_declare;
  ntype.geometry_node_execute = file_ns::node_geo_exec;
  nodeRegisterType(&ntype);
}