Cut Tool: Cut off the top of frustum connectors

This commit is contained in:
YuSanka 2023-03-06 15:46:25 +01:00
parent f038eca52c
commit efb6b747cb
4 changed files with 51 additions and 2 deletions

View File

@ -1309,7 +1309,7 @@ indexed_triangle_set ModelObject::get_connector_mesh(CutConnectorAttributes conn
if (connector_attributes.style == CutConnectorStyle::Prism) if (connector_attributes.style == CutConnectorStyle::Prism)
connector_mesh = its_make_cylinder(1.0, 1.0, (2 * PI / sectorCount)); connector_mesh = its_make_cylinder(1.0, 1.0, (2 * PI / sectorCount));
else if (connector_attributes.type == CutConnectorType::Plug) else if (connector_attributes.type == CutConnectorType::Plug)
connector_mesh = its_make_cone(1.0, 1.0, (2 * PI / sectorCount)); connector_mesh = its_make_frustum(1.0, 1.0, (2 * PI / sectorCount));
else else
connector_mesh = its_make_frustum_dowel(1.0, 1.0, sectorCount); connector_mesh = its_make_frustum_dowel(1.0, 1.0, sectorCount);

View File

@ -965,6 +965,51 @@ indexed_triangle_set its_make_cylinder(double r, double h, double fa)
return mesh; return mesh;
} }
indexed_triangle_set its_make_frustum(double r, double h, double fa)
{
indexed_triangle_set mesh;
size_t n_steps = (size_t)ceil(2. * PI / fa);
double angle_step = 2. * PI / n_steps;
auto &vertices = mesh.vertices;
auto &facets = mesh.indices;
vertices.reserve(2 * n_steps + 2);
facets.reserve(4 * n_steps);
// 2 special vertices, top and bottom center, rest are relative to this
vertices.emplace_back(Vec3f(0.f, 0.f, 0.f));
vertices.emplace_back(Vec3f(0.f, 0.f, float(h)));
// for each line along the polygon approximating the top/bottom of the
// circle, generate four points and four facets (2 for the wall, 2 for the
// top and bottom.
// Special case: Last line shares 2 vertices with the first line.
Vec2f vec_top = Eigen::Rotation2Df(0.f) * Eigen::Vector2f(0, 0.5f*r);
Vec2f vec_botton = Eigen::Rotation2Df(0.f) * Eigen::Vector2f(0, r);
vertices.emplace_back(Vec3f(vec_botton(0), vec_botton(1), 0.f));
vertices.emplace_back(Vec3f(vec_top(0), vec_top(1), float(h)));
for (size_t i = 1; i < n_steps; ++i) {
vec_top = Eigen::Rotation2Df(angle_step * i) * Eigen::Vector2f(0, 0.5f*float(r));
vec_botton = Eigen::Rotation2Df(angle_step * i) * Eigen::Vector2f(0, float(r));
vertices.emplace_back(Vec3f(vec_botton(0), vec_botton(1), 0.f));
vertices.emplace_back(Vec3f(vec_top(0), vec_top(1), float(h)));
int id = (int)vertices.size() - 1;
facets.emplace_back( 0, id - 1, id - 3); // top
facets.emplace_back(id, 1, id - 2); // bottom
facets.emplace_back(id, id - 2, id - 3); // upper-right of side
facets.emplace_back(id, id - 3, id - 1); // bottom-left of side
}
// Connect the last set of vertices with the first.
int id = (int)vertices.size() - 1;
facets.emplace_back( 0, 2, id - 1);
facets.emplace_back( 3, 1, id);
facets.emplace_back(id, 2, 3);
facets.emplace_back(id, id - 1, 2);
return mesh;
}
indexed_triangle_set its_make_cone(double r, double h, double fa) indexed_triangle_set its_make_cone(double r, double h, double fa)
{ {
indexed_triangle_set mesh; indexed_triangle_set mesh;

View File

@ -317,6 +317,7 @@ indexed_triangle_set its_make_cube(double x, double y, double z);
indexed_triangle_set its_make_prism(float width, float length, float height); indexed_triangle_set its_make_prism(float width, float length, float height);
indexed_triangle_set its_make_cylinder(double r, double h, double fa=(2*PI/360)); indexed_triangle_set its_make_cylinder(double r, double h, double fa=(2*PI/360));
indexed_triangle_set its_make_cone(double r, double h, double fa=(2*PI/360)); indexed_triangle_set its_make_cone(double r, double h, double fa=(2*PI/360));
indexed_triangle_set its_make_frustum(double r, double h, double fa=(2*PI/360));
indexed_triangle_set its_make_frustum_dowel(double r, double h, int sectorCount); indexed_triangle_set its_make_frustum_dowel(double r, double h, int sectorCount);
indexed_triangle_set its_make_pyramid(float base, float height); indexed_triangle_set its_make_pyramid(float base, float height);
indexed_triangle_set its_make_sphere(double radius, double fa); indexed_triangle_set its_make_sphere(double radius, double fa);

View File

@ -2274,13 +2274,16 @@ void GLGizmoCut3D::reset_connectors()
void GLGizmoCut3D::init_connector_shapes() void GLGizmoCut3D::init_connector_shapes()
{ {
for (const CutConnectorType& type : {CutConnectorType::Dowel, CutConnectorType::Plug}) for (const CutConnectorType& type : {CutConnectorType::Dowel, CutConnectorType::Plug})
for (const CutConnectorStyle& style : {CutConnectorStyle::Frustum, CutConnectorStyle::Prism}) for (const CutConnectorStyle& style : {CutConnectorStyle::Frustum, CutConnectorStyle::Prism}) {
if (type == CutConnectorType::Dowel && style == CutConnectorStyle::Frustum)
continue;
for (const CutConnectorShape& shape : {CutConnectorShape::Circle, CutConnectorShape::Hexagon, CutConnectorShape::Square, CutConnectorShape::Triangle}) { for (const CutConnectorShape& shape : {CutConnectorShape::Circle, CutConnectorShape::Hexagon, CutConnectorShape::Square, CutConnectorShape::Triangle}) {
const CutConnectorAttributes attribs = { type, style, shape }; const CutConnectorAttributes attribs = { type, style, shape };
const indexed_triangle_set its = ModelObject::get_connector_mesh(attribs); const indexed_triangle_set its = ModelObject::get_connector_mesh(attribs);
m_shapes[attribs].model.init_from(its); m_shapes[attribs].model.init_from(its);
m_shapes[attribs].mesh_raycaster = std::make_unique<MeshRaycaster>(std::make_shared<const TriangleMesh>(std::move(its))); m_shapes[attribs].mesh_raycaster = std::make_unique<MeshRaycaster>(std::make_shared<const TriangleMesh>(std::move(its)));
} }
}
} }
void GLGizmoCut3D::update_connector_shape() void GLGizmoCut3D::update_connector_shape()