WIP: Add new connector - "Rivet"

* Improves for UI
* Implemented Rivet mesh
This commit is contained in:
YuSanka 2023-06-29 10:02:18 +02:00
parent 92c7a31f42
commit 6a2afc9153
8 changed files with 217 additions and 14 deletions

13
resources/icons/rivet.svg Normal file
View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="16px" height="16px" viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
<g>
<path fill="#ED6B21" d="M9,15H7c-0.5522847,0-1-0.4477148-1-1V5c0-0.5522847,0.4477153-1,1-1h2c0.5522852,0,1,0.4477153,1,1v9
C10,14.5522852,9.5522852,15,9,15z"/>
</g>
<g>
<path fill="none" stroke="#808080" stroke-linecap="round" stroke-miterlimit="5" d="M1.5,11.5h2v-8c0-1.1045694,0.8954306-2,2-2h5c1.1045694,0,2,0.8954306,2,2v8h2"/>
</g>
<line fill="none" stroke="#ED6B21" stroke-linecap="round" stroke-miterlimit="10" x1="1.5" y1="14.5" x2="14.5" y2="14.5"/>
</svg>

After

Width:  |  Height:  |  Size: 846 B

View File

@ -152,6 +152,7 @@ namespace ImGui
// const wchar_t MmuSegmentationMarker = 0x1F;
const wchar_t PlugMarker = 0x1C;
const wchar_t DowelMarker = 0x1D;
const wchar_t RivetMarker = 0x1E;
// Do not forget use following letters only in wstring
const wchar_t DocumentationButton = 0x2600;
const wchar_t DocumentationHoverButton = 0x2601;

View File

@ -1302,7 +1302,9 @@ indexed_triangle_set ModelObject::get_connector_mesh(CutConnectorAttributes conn
break;
}
if (connector_attributes.style == CutConnectorStyle::Prism)
if (connector_attributes.type == CutConnectorType::Rivet)
connector_mesh = its_make_rivet(1.0, 1.0, (2 * PI / /*sectorCount*/10));
else if (connector_attributes.style == CutConnectorStyle::Prism)
connector_mesh = its_make_cylinder(1.0, 1.0, (2 * PI / sectorCount));
else if (connector_attributes.type == CutConnectorType::Plug)
connector_mesh = its_make_frustum(1.0, 1.0, (2 * PI / sectorCount));

View File

@ -224,6 +224,7 @@ private:
enum class CutConnectorType : int {
Plug
, Dowel
, Rivet
, Undef
};

View File

@ -1262,6 +1262,181 @@ indexed_triangle_set its_make_frustum_dowel(double radius, double h, int sectorC
return mesh;
}
indexed_triangle_set its_make_rivet(double r, double h, double fa)
{
const float radius = (float)r;
const float height = (float)h;
const size_t sectors_cnt = 10;//(float)fa;
const float halfPI = 0.5f * (float)PI;
const float space_len = 0.2f * radius;
const float b_len = 0.75f * radius;
const float m_len = radius;
const float t_len = 0.5f * radius;
const float b_height = 0.f;
const float m_height = 0.5f * height;
const float t_height = height;
const float b_angle = acos(space_len/b_len);
const float m_angle = acos(space_len/m_len);
const float t_angle = acos(space_len/t_len);
const float b_angle_step = b_angle / (float)sectors_cnt;
const float m_angle_step = m_angle / (float)sectors_cnt;
const float t_angle_step = t_angle / (float)sectors_cnt;
const Vec2f b_vec = Eigen::Vector2f(0, b_len);
const Vec2f m_vec = Eigen::Vector2f(0, m_len);
const Vec2f t_vec = Eigen::Vector2f(0, t_len);
const Vec2f space_vec = Eigen::Vector2f(0, space_len);
Vec2f b_pt = Eigen::Rotation2Df(halfPI) * space_vec;
indexed_triangle_set mesh;
auto& vertices = mesh.vertices;
auto& facets = mesh.indices;
vertices.reserve(2 * 3 * sectors_cnt + 2);
facets.reserve(2 * 6 * sectors_cnt);
float b_angle_start = halfPI - b_angle;
float m_angle_start = halfPI - m_angle;
float t_angle_start = halfPI - t_angle;
float b_angle_stop = halfPI + b_angle;
// 2 special vertices, top and bottom center, rest are relative to this
vertices.emplace_back(Vec3f(-space_len, 0.f, b_height));
vertices.emplace_back(Vec3f(-space_len, 0.f, t_height));
int frst_id = 0;
int scnd_id = 1;
auto add_side_vertices = [b_vec, m_vec, t_vec, b_height, m_height, t_height](std::vector<stl_vertex>& vertices, float b_angle, float m_angle, float t_angle) {
Vec2f b_pt = Eigen::Rotation2Df(b_angle) * b_vec;
Vec2f m_pt = Eigen::Rotation2Df(m_angle) * m_vec;
Vec2f t_pt = Eigen::Rotation2Df(t_angle) * t_vec;
vertices.emplace_back(Vec3f(b_pt(0), b_pt(1), b_height));
vertices.emplace_back(Vec3f(m_pt(0), m_pt(1), m_height));
vertices.emplace_back(Vec3f(t_pt(0), t_pt(1), t_height));
};
// add first vertices and facets
{
add_side_vertices(vertices, b_angle_start, m_angle_start, t_angle_start);
int id = (int)vertices.size() - 1;
facets.emplace_back(id - 4, id - 2, id - 1);
facets.emplace_back(id - 4, id - 1, id);
facets.emplace_back(id - 4, id, id - 3);
}
while (b_angle_start < b_angle_stop) {
b_angle_start += b_angle_step;
m_angle_start += m_angle_step;
t_angle_start += t_angle_step;
add_side_vertices(vertices, b_angle_start, m_angle_start, t_angle_start);
int id = (int)vertices.size() - 1;
facets.emplace_back(frst_id, id - 2, id - 5);
facets.emplace_back(id - 2, id - 1, id - 5);
facets.emplace_back(id - 1, id - 4, id - 5);
facets.emplace_back(id - 4, id - 1, id);
facets.emplace_back(id, id - 3, id - 4);
facets.emplace_back(id, scnd_id, id - 3);
}
// add facets to close the mesh
{
int id = (int)vertices.size() - 1;
facets.emplace_back(frst_id, scnd_id, id);
facets.emplace_back(frst_id, id, id - 1);
facets.emplace_back(frst_id, id - 1, id - 2);
}
b_angle_start = 3 * halfPI - b_angle;
m_angle_start = 3 * halfPI - m_angle;
t_angle_start = 3 * halfPI - t_angle;
b_angle_stop = 3 * halfPI + b_angle;
frst_id = (int)vertices.size();
scnd_id = frst_id+1;
// 2 special vertices, top and bottom center, rest are relative to this
vertices.emplace_back(Vec3f(space_len, 0.f, b_height));
vertices.emplace_back(Vec3f(space_len, 0.f, t_height));
// add first vertices and facets
{
Vec2f b_pt = Eigen::Rotation2Df(b_angle_start) * b_vec;
Vec2f m_pt = Eigen::Rotation2Df(m_angle_start) * m_vec;
Vec2f t_pt = Eigen::Rotation2Df(t_angle_start) * t_vec;
vertices.emplace_back(Vec3f(b_pt(0), b_pt(1), b_height));
vertices.emplace_back(Vec3f(m_pt(0), m_pt(1), m_height));
vertices.emplace_back(Vec3f(t_pt(0), t_pt(1), t_height));
int id = (int)vertices.size() - 1;
facets.emplace_back(id - 4, id - 2, id - 1);
facets.emplace_back(id - 4, id - 1, id);
facets.emplace_back(id - 4, id , id - 3);
}
while (b_angle_start < b_angle_stop) {
b_angle_start += b_angle_step;
m_angle_start += m_angle_step;
t_angle_start += t_angle_step;
Vec2f b_pt = Eigen::Rotation2Df(b_angle_start) * b_vec;
Vec2f m_pt = Eigen::Rotation2Df(m_angle_start) * m_vec;
Vec2f t_pt = Eigen::Rotation2Df(t_angle_start) * t_vec;
vertices.emplace_back(Vec3f(b_pt(0), b_pt(1), b_height));
vertices.emplace_back(Vec3f(m_pt(0), m_pt(1), m_height));
vertices.emplace_back(Vec3f(t_pt(0), t_pt(1), t_height));
int id = (int)vertices.size() - 1;
facets.emplace_back(frst_id, id - 2, id - 5);
facets.emplace_back(id - 2, id - 1, id - 5);
facets.emplace_back(id - 1, id - 4, id - 5);
facets.emplace_back(id - 4, id - 1, id);
facets.emplace_back(id, id - 3, id - 4);
facets.emplace_back(id, scnd_id, id - 3);
}
// add facets to close the mesh
{
int id = (int)vertices.size() - 1;
facets.emplace_back(frst_id, scnd_id, id);
facets.emplace_back(frst_id, id, id - 1);
facets.emplace_back(frst_id, id - 1, id - 2);
}
return mesh;
}
indexed_triangle_set its_convex_hull(const std::vector<Vec3f> &pts)
{
std::vector<Vec3f> dst_vertices;

View File

@ -321,6 +321,7 @@ 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_pyramid(float base, float height);
indexed_triangle_set its_make_sphere(double radius, double fa);
indexed_triangle_set its_make_rivet(double r, double h, double fa=(2*PI/360));
indexed_triangle_set its_convex_hull(const std::vector<Vec3f> &pts);
inline indexed_triangle_set its_convex_hull(const indexed_triangle_set &its) { return its_convex_hull(its.vertices); }

View File

@ -186,8 +186,7 @@ GLGizmoCut3D::GLGizmoCut3D(GLCanvas3D& parent, const std::string& icon_filename,
, m_connector_style (int(CutConnectorStyle::Prism))
, m_connector_shape_id (int(CutConnectorShape::Circle))
{
m_mode = size_t(CutMode::cutTongueAndGroove);
m_contour_width = .0f;
m_connector_type = CutConnectorType::Rivet;
m_modes = { _u8L("Planar"), _u8L("Tongue and Groove")//, _u8L("Grid")
// , _u8L("Radial"), _u8L("Modular")
@ -197,7 +196,8 @@ GLGizmoCut3D::GLGizmoCut3D(GLCanvas3D& parent, const std::string& icon_filename,
std::map<const wchar_t, std::string> connetor_types = {
{ImGui::PlugMarker , _u8L("Plug") },
{ImGui::DowelMarker, _u8L("Dowel") },
{ImGui::DowelMarker, _u8L("Dowel") },
{ImGui::RivetMarker, _u8L("Rivet") },
};
for (auto connector : connetor_types) {
std::string type_label = " " + connector.second + " ";
@ -1986,20 +1986,27 @@ void GLGizmoCut3D::render_connectors_input_window(CutConnectors &connectors)
m_imgui->text(m_labels_map["Type"]);
bool type_changed = render_connect_type_radio_button(CutConnectorType::Plug);
type_changed |= render_connect_type_radio_button(CutConnectorType::Dowel);
type_changed |= render_connect_type_radio_button(CutConnectorType::Rivet);
if (type_changed)
apply_selected_connectors([this, &connectors] (size_t idx) { connectors[idx].attribs.type = CutConnectorType(m_connector_type); });
m_imgui->disabled_begin(m_connector_type == CutConnectorType::Dowel);
if (type_changed && m_connector_type == CutConnectorType::Dowel) {
m_connector_style = int(CutConnectorStyle::Prism);
apply_selected_connectors([this, &connectors](size_t idx) { connectors[idx].attribs.style = CutConnectorStyle(m_connector_style); });
}
if (render_combo(m_labels_map["Style"], m_connector_styles, m_connector_style))
apply_selected_connectors([this, &connectors](size_t idx) { connectors[idx].attribs.style = CutConnectorStyle(m_connector_style); });
m_imgui->disabled_begin(m_connector_type != CutConnectorType::Plug);
if (type_changed && m_connector_type == CutConnectorType::Dowel) {
m_connector_style = int(CutConnectorStyle::Prism);
apply_selected_connectors([this, &connectors](size_t idx) { connectors[idx].attribs.style = CutConnectorStyle(m_connector_style); });
}
if (render_combo(m_labels_map["Style"], m_connector_styles, m_connector_style))
apply_selected_connectors([this, &connectors](size_t idx) { connectors[idx].attribs.style = CutConnectorStyle(m_connector_style); });
m_imgui->disabled_end();
if (render_combo(m_labels_map["Shape"], m_connector_shapes, m_connector_shape_id))
apply_selected_connectors([this, &connectors](size_t idx) { connectors[idx].attribs.shape = CutConnectorShape(m_connector_shape_id); });
m_imgui->disabled_begin(m_connector_type == CutConnectorType::Rivet);
if (type_changed && m_connector_type == CutConnectorType::Rivet) {
m_connector_shape_id = int(CutConnectorShape::Circle);
apply_selected_connectors([this, &connectors](size_t idx) { connectors[idx].attribs.shape = CutConnectorShape(m_connector_shape_id); });
}
if (render_combo(m_labels_map["Shape"], m_connector_shapes, m_connector_shape_id))
apply_selected_connectors([this, &connectors](size_t idx) { connectors[idx].attribs.shape = CutConnectorShape(m_connector_shape_id); });
m_imgui->disabled_end();
if (render_slider_double_input(m_labels_map["Depth"], m_connector_depth_ratio, m_connector_depth_ratio_tolerance))
apply_selected_connectors([this, &connectors](size_t idx) {
@ -3232,11 +3239,13 @@ void GLGizmoCut3D::reset_connectors()
void GLGizmoCut3D::init_connector_shapes()
{
for (const CutConnectorType& type : {CutConnectorType::Dowel, CutConnectorType::Plug})
for (const CutConnectorType& type : {CutConnectorType::Dowel, CutConnectorType::Plug, CutConnectorType::Rivet})
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}) {
if (type == CutConnectorType::Rivet && shape != CutConnectorShape::Circle)
continue;
const CutConnectorAttributes attribs = { type, style, shape };
indexed_triangle_set its = ModelObject::get_connector_mesh(attribs);
m_shapes[attribs].model.init_from(its);

View File

@ -67,6 +67,7 @@ static const std::map<const wchar_t, std::string> font_icons = {
{ImGui::InfoMarkerSmall , "notification_info" },
{ImGui::PlugMarker , "plug" },
{ImGui::DowelMarker , "dowel" },
{ImGui::RivetMarker , "rivet" },
};
static const std::map<const wchar_t, std::string> font_icons_large = {