Skip to content

Instantly share code, notes, and snippets.

@eliemichel
Last active May 30, 2022 11:47
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eliemichel/49ae7aad5f74979635c968f15ea29091 to your computer and use it in GitHub Desktop.
Save eliemichel/49ae7aad5f74979635c968f15ea29091 to your computer and use it in GitHub Desktop.
// [...]
/**
* Create a new Mesh representing a simple pizza (really just a disc with
* a few quads on top of it).
* olive_count is the number of olives topping the pizza
* radius is the radius of the pizza
* base_polys is filled with the range of polygons belonging to the base
* olive_polys is filled with the range of polygons representing the olives
*/
static Mesh *create_pizza_mesh(const int olive_count,
const float radius,
IndexRange &base_polys,
IndexRange &olives_polys)
{
// (i) Compute element counts
int vert_count = 32 + olive_count * 4;
int edge_count = 32 + olive_count * 4;
int corner_count = 32 + olive_count * 4;
int face_count = 1 + olive_count;
// (ii) Allocate memory
Mesh *mesh = BKE_mesh_new_nomain(vert_count, edge_count, 0, corner_count, face_count);
// (iii) Fill in element buffers
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};
base_polys = IndexRange{0, 1};
olives_polys = IndexRange{1, olive_count};
// (iii.a) Base
const float angle_delta = 2 * M_PI / 32;
for (const int i : IndexRange(32)) {
// Vertex coordinates
const float angle = i * angle_delta;
copy_v3_v3(verts[i].co, float3(std::cos(angle) * radius, std::sin(angle) * radius, 0.0f));
// Edge
MEdge &edge = edges[i];
edge.v1 = i;
edge.v2 = (i + 1) % 32;
edge.flag = ME_EDGEDRAW | ME_EDGERENDER;
// Corner
MLoop &loop = loops[i];
loop.e = i;
loop.v = i;
}
// Face
MPoly &poly = polys[0];
poly.loopstart = 0;
poly.totloop = 32;
// (iii.b) Olives
const float angle_delta_olive = 2.0f * (M_PI / static_cast<float>(olive_count - 1));
for (const int i : IndexRange(olive_count)) {
const int offset = 32 + 4 * i;
// Vertex coordinates
float cx = 0, cy = 0;
if (i > 0) { // (the olive #0 is at the center)
const float angle = (i - 1) * angle_delta_olive;
cx = std::cos(angle) * radius / 2;
cy = std::sin(angle) * radius / 2;
}
copy_v3_v3(verts[offset + 0].co, float3(cx + 0.05f, cy + 0.05f, 0.01f));
copy_v3_v3(verts[offset + 1].co, float3(cx - 0.05f, cy + 0.05f, 0.01f));
copy_v3_v3(verts[offset + 2].co, float3(cx - 0.05f, cy - 0.05f, 0.01f));
copy_v3_v3(verts[offset + 3].co, float3(cx + 0.05f, cy - 0.05f, 0.01f));
for (const int k : IndexRange(4)) {
// Edge
MEdge &edge = edges[offset + k];
edge.v1 = offset + k;
edge.v2 = offset + (k + 1) % 4;
edge.flag = ME_EDGEDRAW | ME_EDGERENDER;
// Corner
MLoop &loop = loops[offset + k];
loop.e = offset + k;
loop.v = offset + k;
}
// Face
MPoly &poly = polys[1 + i];
poly.loopstart = offset;
poly.totloop = 4;
}
BLI_assert(BKE_mesh_is_valid(mesh));
return mesh;
}
// [...]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment