Page MenuHome

Geometry Nodes: Add initial version of mesh primitives
ClosedPublic

Authored by Hans Goudey (HooglyBoogly) on Mar 13 2021, 11:47 PM.
Tokens
"Love" token, awarded by Rafafcdk."Like" token, awarded by hitrpr."Love" token, awarded by damian."Love" token, awarded by Zino."Love" token, awarded by charlie."Love" token, awarded by Bit."Love" token, awarded by kursadk."Love" token, awarded by someuser."Love" token, awarded by franMarz."Love" token, awarded by kenziemac130."Love" token, awarded by Erindale."Love" token, awarded by ace_dragon."Love" token, awarded by monio.

Details

Summary

This patch includes nodes to build the following primitives:

  • Cone
  • Cylinder
  • Circle
  • Cube
  • UV Sphere
  • Ico Sphere
  • Line
  • Plane/Grid

In general the inputs are the same as the corresponding operators in the 3D view.

For the line primitive there are two options-- adding vertices between two end points,
or adding vertices each at an offset from the start point. For the former mode, there
is a choice between a vertex count and a distance between each point.

For the plane/grid primitive I combined the two into one node. Here's the thinking:
Generally primitives are named after the simpler form of the shape they create
(i.e. "Cone" can make some more complex shapes). Also, generally you want to tweak
the number of subdivisions anyway, so defaulting to plane is not an inconvenience.
And generally having fewer redundant base primitives is better.

Diff Detail

Repository
rB Blender
Branch
geometry-nodes-mesh-primitives
Build Status
Buildable 13504
Build 13504: arc lint + arc unit

Event Timeline

Hans Goudey (HooglyBoogly) requested review of this revision.Mar 13 2021, 11:47 PM
Hans Goudey (HooglyBoogly) created this revision.

Nice work!!! I like how the cone is able to handle varying base and top sizes which is far more useful than the existing add cone operator.

On the cylinder it says "vertices" which is a little bit misleading considering there are twice as many vertices actually produced. Also in practice a cylinder often needs the long strips of faces to be divided with edge loops in order to be useful for subdiv and displacement. Maybe the cylinder primitive could be made similarly to the UV sphere and have "segments" and "rings" as well?

Nice work!!! I like how the cone is able to handle varying base and top sizes which is far more useful than the existing add cone operator.

On the cylinder it says "vertices" which is a little bit misleading considering there are twice as many vertices actually produced. Also in practice a cylinder often needs the long strips of faces to be divided with edge loops in order to be useful for subdiv and displacement. Maybe the cylinder primitive could be made similarly to the UV sphere and have "segments" and "rings" as well?

I believe on a cylinder verts should be called meridians and horizontal cuts should be parallels

  • Cleanup: Remove unused includes, change switch to if
  • Add line primitive node

Nice work!!! I like how the cone is able to handle varying base and top sizes which is far more useful than the existing add cone operator.

On the cylinder it says "vertices" which is a little bit misleading considering there are twice as many vertices actually produced. Also in practice a cylinder often needs the long strips of faces to be divided with edge loops in order to be useful for subdiv and displacement. Maybe the cylinder primitive could be made similarly to the UV sphere and have "segments" and "rings" as well?

That gives me an idea-- the topology of the UV sphere and a cylinder / cone with rings would be very similar. I wonder if I could share the topology generation between the UV sphere, the cone, and the cylinder. Interesting! I'll have to think about that when I'm more awake.

  • Remove extra assert
  • Add plane primitive node
  • Remove unecessary checks for zero
This comment was removed by Kenzie (kenziemac130).
  • Use "Location" consistently
  • Add UVs to sphere primitive
  • Add UV attribute creation to cone node
  • Add UVs to plane primitive

The "UVs" added are a generic float2 attribute named uv.

  • Fix off-by-one error in the line node
  • Use BMesh for cone, cylinder, and sphere

This version will be up to 2000 times slower in some cases (the BMesh version of a high resolution sphere takes 40 seconds while
the version I had implemented before takes about 20ms). However, this will provide a simpler initial patch to simplify review for Bcon2.
I will post the speedups as a separate patch.

Hans Goudey (HooglyBoogly) retitled this revision from Geometry Nodes: Add initial mesh primitives to Geometry Nodes: Add initial mesh version of primitives.Mar 15 2021, 11:19 PM
Hans Goudey (HooglyBoogly) edited the summary of this revision. (Show Details)
Hans Goudey (HooglyBoogly) retitled this revision from Geometry Nodes: Add initial mesh version of primitives to Geometry Nodes: Add initial version of mesh primitives.Mar 15 2021, 11:22 PM
Hans Goudey (HooglyBoogly) edited the summary of this revision. (Show Details)

Just FYI this was brought to my attention as something related to that: D10093

source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc
231

nullptr

source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc
57

nullptr

source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc
62

nullptr

source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc
96

nullptr

On the UV Sphere, when Rings or Segments are less than 3 it returns no Geometry. I suppose this is partly a UI issue but would it be better to clamp using min(x, 3)?

I'm not done with the review yet.

I think returning no geometry in the case when the number of vertices is too low is better. One can always add a clamp node before, but the opposite would not be easily possible.

source/blender/nodes/CMakeLists.txt
170

sort alphabetically

source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc
125

Can be shortened to

MutableSpan<MVert> verts{mesh->mvert, mesh->totvert};
MutableSpan<MLoop> loops{mesh->mloop, mesh->totloop};
MutableSpan<MEdge> edges{mesh->medge, mesh->totedge};
MutableSpan<MPoly> polys{mesh->mpoly, mesh->totpoly};

One could even remove the MVert part, but I think it help readability here.

141

const

source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc
69

use_top does not make much sense to me. A better name might be top_is_single_point.

216

Compare with enum values instead of magic numbers.

source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc
54

The ico-sphere node generates wrong geometry when the radius is negative.

72

8 is a bit low imo. The hardmax in MESH_OT_primitive_ico_sphere_add is 10.

  • Merge branch 'master' into geometry-nodes-mesh-primitives-slow
  • Simplify span constructors, use nullptr
  • Sort alphabetically, use const
  • Rename variables
  • Don't set fourth component of SOCK_VECTOR to 1.0f
source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc
43

I think it would be good if the End Location and Offset are (0, 0, 1).

131

Please test this for count <= 1.

source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_plane.cc
73

Can be simplified the same way as mentioned in the other comment.

85

I think it might be cleaner to just assign x, y, and z separately here.

93

const

Hans Goudey (HooglyBoogly) marked 16 inline comments as done.
  • Don't use magic values
  • Change ico sphere max subdivisions, use absolute value of radius
  • Line: Use the same socket for end and offset, improve handling of low resolutions and 0 count
  • Assign x, y, and z separately, use const
source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc
69

I used top_is_point which is just a bit shorter than what you suggested.

source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc
72

Okay, I'll stick with that then. It's very slow though!

source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc
43

So the line goes upward, sure.

This revision is now accepted and ready to land.Mar 16 2021, 5:15 PM

Great, now, at least we can generate exact amount of points!
I hope indexes will be exposed as attribute.

Already tested.
IMO primitives and mesh operations (like subdivide etc.) should be separated. Now they all mixed and it is confusing a bit, if you are new user and use menu.

Great, now, at least we can generate exact amount of points!
I hope indexes will be exposed as attribute.

Already tested.
IMO primitives and mesh operations (like subdivide etc.) should be separated. Now they all mixed and it is confusing a bit, if you are new user and use menu.

IMO primitives and mesh operations (like subdivide etc.) should be separated.

Yes, definitely, like the comment in nodeitems_builtins.py says, we'll need to do some refactoring of the add menu before adding these to a sub-menu. But I hope to do that for 2.93.