410 : wxPanel(parent, wxID_ANY)
411{
412
413
414 wxStopWatch build_clock;
415 long build_mark = 0;
416 auto build_phase = [&build_clock, &build_mark](const char* phase) {
417 const long now = build_clock.Time();
418 BOOST_LOG_TRIVIAL(info) << "Design tab build: " << phase << " " << now - build_mark << " ms";
419 build_mark = now;
420 };
421
422
423
424 auto* body_panel = new wxPanel(this, wxID_ANY);
425 m_form =
new wxScrolledWindow(body_panel, wxID_ANY);
426
427
431
432 auto* root = new wxBoxSizer(wxVERTICAL);
433 {
436 root->Add(hdr, 0, wxLEFT | wxRIGHT | wxTOP, 12);
437 root->AddSpacer(2);
438 }
439
440
441
442
443
444
445
446 m_toolbar =
new wxScrolledWindow(
this, wxID_ANY);
448 m_toolbar->ShowScrollbars(wxSHOW_SB_DEFAULT, wxSHOW_SB_NEVER);
449
450
452
453 auto icon_btn = [this](const char* icon, const wxString& tip) {
454
455
456 auto* b =
new ScalableButton(
m_toolbar, wxID_ANY, icon,
"", FromDIP(wxSize(40, 40)),
457 wxDefaultPosition, wxBU_EXACTFIT | wxBORDER_NONE, false, 34);
458 b->SetToolTip(tip);
461
462 b->Bind(wxEVT_ENTER_WINDOW, [
this, b](
wxMouseEvent& e) {
464 b->Refresh(); e.Skip(); });
465 b->Bind(wxEVT_LEAVE_WINDOW, [
this, b](
wxMouseEvent& e) {
467 b->Refresh(); e.Skip(); });
468
469
472 return b;
473 };
474
475 auto caption = [this](const wxString& t) {
480 return s;
481 };
482 auto add_sep = [this](wxSizer* row) {
483 row->AddSpacer(5);
484 row->Add(
new wxStaticLine(
m_toolbar, wxID_ANY, wxDefaultPosition, FromDIP(wxSize(1, 22)), wxLI_VERTICAL),
485 0, wxALIGN_CENTER_VERTICAL);
486 row->AddSpacer(5);
487 };
488
489
490
491
496
497
503 : wxString::Format(
_L(
"%s · plane: %s"), hint,
m_sketch_on));
504 };
505
506
507
508
510 m_keys_sketch[ch] = [select_tool, m, h] { select_tool(m, h); };
511 };
527
531 }
533 };
534
535
536
537
538
539
540
541
542
545 set_status(
_L(
"Nothing here has a value to type — pick a line, an arc, a circle, or two entities"));
546 };
548
549
550
554 }
555 };
557
558
559
561 m_viewport->toggle_sketch_construction_selection() > 0) {
562 set_status(
_L(
"Converted the selection between construction and real geometry"));
563 return;
564 }
569 }
570 };
571
572
573
575
576
577
578 auto status_flag = [this](const wxString& on_msg, const wxString& off_msg, bool on) {
580 };
582 if (
m_viewport) status_flag(
_L(
"Origin planes shown"),
_L(
"Origin planes hidden"),
584 };
586 if (
m_viewport) status_flag(
_L(
"World axes shown"),
_L(
"World axes hidden"),
588 };
590
591
593
594
595
596
597
598
599
600
601
602
603
604
609 };
610
611
612
613
614
615
620 };
624 };
625
626
627
628
629
631
632
633
634 std::map<std::string, std::vector<wxWindow*>> tb_slot;
635
636
637
638
639
640
641
642
643 static const std::set<std::string> kBarKeep = { "place", "section", "flip" };
644 auto fadd = [&tb_slot](const char* id, wxWindow* w) {
645 if (kBarKeep.count(id) == 0) { w->Hide(); return; }
646 tb_slot[id].push_back(w);
647 };
648 {
649
650
651
652 struct FeatVar { const char* icon; wxString tip; wxString hint; std::function<void()> action; int key = 0; };
653 struct FeatFlyout {
654 std::vector<DropDown::Item> items;
655 std::vector<std::function<void()>> actions;
656 std::vector<std::string> icon_names;
657 ScalableButton* btn = nullptr;
658 DropDown drop;
659 FeatFlyout() : drop(items) {}
660 };
661 auto feat_dropdown = [&](const char* id, const char* def_icon, const wxString& grp, std::vector<FeatVar> vars) {
662
663
664
665
666
667
668
669
670
671 for (size_t i = 0; i < vars.size(); ++i) {
673 m_verb_actions[
"fly:" + std::string(
id) +
"#" + std::to_string(i)] = vars[i].action;
674 }
675 if (kBarKeep.count(id) == 0)
676 return;
677 auto* b = icon_btn(def_icon, grp);
679 auto fo = std::make_shared<FeatFlyout>();
680 for (auto& v : vars) {
681 DropDown::Item it;
685 fo->items.push_back(it);
686 fo->actions.push_back(std::move(v.action));
687 fo->icon_names.emplace_back(v.icon);
688 }
689 fo->btn = b;
690 fo->drop.Create(b);
692 for (size_t i = 0; i < fp->items.size(); ++i)
693 fp->items[i].icon = create_scaled_bitmap(fp->icon_names[i], m_form, 18);
694 fp->drop.Invalidate(true);
695 });
696 fo->drop.SetUseContentWidth(true, false);
697 fo->drop.Invalidate(true);
698 FeatFlyout* fp = fo.get();
699 fo->drop.Bind(wxEVT_COMBOBOX, [this, fp](wxCommandEvent& e) {
700 int i = e.GetInt();
701 if (i >= 0 && i < (int) fp->actions.size()) {
702 fp->btn->SetBitmap_(fp->icon_names[i]);
703 fp->actions[i]();
705 }
706 });
707 b->Bind(wxEVT_BUTTON, [b, fp](wxCommandEvent&) {
708
709
710 fp->drop.Invalidate(true);
711 fp->drop.SetUseContentWidth(false, false);
712 fp->drop.SetUseContentWidth(true, false);
713 wxPoint
pos = b->ClientToScreen(wxPoint(0, -6));
714 fp->drop.Position(pos, wxSize(0, b->GetSize().y + b->FromDIP(12)));
715 fp->drop.Popup();
716 });
718 fadd(id, b);
722 fadd(id, chev);
723 };
724
725
726
727
729
730
731 feat_dropdown(
"material",
"design_extrude",
_L(
"Add material (extrude / revolve / sweep / loft / thicken / rib)"), {
732 {
"design_extrude",
_L_CONTEXT(
"Extrude",
"Design"),
_L(
"Extrude a sketch profile, or push/pull a picked face"),
733 [this] {
734
735
736
742 return;
743 }
748 return;
749 }
752 {
"design_revolve",
_L(
"Revolve"),
_L(
"Revolve a profile about an axis"),
753 [this] {
757 return;
758 }
762 {
"design_sweep",
_L(
"Sweep"),
_L(
"Sweep a profile along a path"),
763 [this] {
768 return;
769 }
772 {
"design_loft",
_L(
"Loft"),
_L(
"Loft (skin) between two or more profiles"),
773 [this] {
774
775 int n = 0;
776 for (
const auto&
f :
m_doc.features)
778 if (n < 2) {
780 return;
781 }
785 {
"design_thicken",
_L(
"Thicken"),
_L(
"Offset a solid face into a thin plate (new body)"),
786 [this] {
787 if (
m_doc.bodies.empty()) {
789 return;
790 }
791 {
793 for (
size_t i = 0; i <
m_doc.bodies.size(); ++i) {
794 const std::string& n =
m_doc.bodies[i].name;
795 m_thicken_body->Append(n.empty() ? wxString::Format(
_L(
"Body %zu"), i + 1) : wxString::FromUTF8(n));
796 }
800 }
801
802
803
804
805
806
807
808
812 }, 0},
813 {
"design_rib",
_L_CONTEXT(
"Rib",
"Design"),
_L(
"Grow a thin wall from an open sketch line, fused to a body"),
814 [this] {
815 if (
m_doc.bodies.empty()) {
817 return;
818 }
819 {
821 for (
size_t i = 0; i <
m_doc.bodies.size(); ++i) {
822 const std::string& n =
m_doc.bodies[i].name;
823 m_rib_body->Append(n.empty() ? wxString::Format(
_L(
"Body %zu"), i + 1) : wxString::FromUTF8(n));
824 }
828 }
829 {
831 for (
int i = 0; i < int(
m_doc.features.size()); ++i) {
832
833
834
835
839 }
841 else {
843 return;
844 }
845 }
847 }, 'R'},
848
849
850
851 });
852
853 auto* b_pattern = icon_btn(
"design_pattern",
_L_CONTEXT(
"Pattern",
"Design"));
854 std::function<void()> act_pattern = [this] {
855
856 if (
m_doc.bodies.empty()) {
858 return;
859 }
861 };
862 b_pattern->Bind(wxEVT_BUTTON, [act_pattern](wxCommandEvent&) { act_pattern(); });
864 fadd("pattern", b_pattern);
865 m_body_gates.push_back({b_pattern, 1, b_pattern->GetToolTipText(),
866 _L(
"Pattern — needs a solid body to replicate")});
867
868
869
870
871
872 feat_dropdown(
"surface",
"design_surface",
_L(
"Surface (extrude / revolve / loft / fill / offset / thicken)"), {
873 {
"design_extrude",
_L(
"Surface Extrude"),
_L(
"Extrude a sketch into a sheet body (no end caps)"),
874 [this] {
878 return;
879 }
882 {
"design_revolve",
_L(
"Surface Revolve"),
_L(
"Revolve a sketch profile into a sheet body"),
883 [this] {
887 return;
888 }
892 {
"design_loft",
_L(
"Surface Loft"),
_L(
"Loft (skin) between 2+ profiles, open (no end caps)"),
893 [this] {
894 int n = 0;
895 for (
const auto&
f :
m_doc.features)
897 if (n < 2) {
899 return;
900 }
904 {
"design_surface",
_L(
"Surface Fill"),
_L(
"Fill a sketch boundary with a smooth face"),
905 [this] {
909 return;
910 }
913 {
"design_offset",
_L(
"Surface Offset"),
_L(
"Offset a sheet body's shell by a signed distance"),
914 [this] {
918 return;
919 }
922 {
"design_thicken",
_L(
"Thicken Surface"),
_L(
"Thicken a sheet body into a solid"),
923 [this] {
927 return;
928 }
931 });
932
933 feat_dropdown(
"plane",
"design_plane",
_L(
"Datum / Curve (plane / axis / coord sys / helix / project)"), {
934 {
"design_plane",
_L_CONTEXT(
"Plane",
"Design"),
_L(
"Reference plane (offset / tilt / midplane / tangent / two edges / coincident)"),
935 [this] {
940 {
"design_line",
_L(
"Axis"),
_L(
"Datum axis (two points, face normal, cylinder centerline, two planes, along edge)"),
941 [this] {
947 {
"design_point",
_L(
"Coordinate system"),
_L(
"Datum coordinate system (world point, or face + direction edge)"),
948 [this] {
952 {
"design_thread",
_L(
"Helix"),
_L(
"Helical curve (spring path) — use as a sweep path for coils / springs / augers"),
953 [this] {
956 }, 0},
957
958
959 {
"design_sketch",
_L_CONTEXT(
"Project",
"Design"),
_L(
"Project body edges onto a plane as sketch entities"),
960 [this] {
961 if (
m_doc.bodies.empty()) {
963 return;
964 }
965 {
967 for (
size_t i = 0; i <
m_doc.bodies.size(); ++i) {
968 const std::string& n =
m_doc.bodies[i].name;
969 m_proj_source_body->Append(n.empty() ? wxString::Format(
_L(
"Body %zu"), i + 1) : wxString::FromUTF8(n));
970 }
974 }
976
977
978
983 :
_L(
"(all edges)"));
985 }, 0},
986 });
987
988
989
990
991
992
993
994
995 feat_dropdown(
"placement",
"design_move",
_L(
"Placement (transform / mirror / mate)"), {
996 {
"design_move",
_L(
"Transform"),
_L(
"Move and/or rotate an existing body"),
997 [this] {
998 if (
m_doc.bodies.empty()) {
1000 return;
1001 }
1002 {
1004 for (
size_t i = 0; i <
m_doc.bodies.size(); ++i) {
1005 const std::string& n =
m_doc.bodies[i].name;
1006 m_xf_body->Append(n.empty() ? wxString::Format(
_L(
"Body %zu"), i + 1) : wxString::FromUTF8(n));
1007 }
1011 }
1014 {
"design_mirror",
_L_CONTEXT(
"Mirror",
"Design"),
_L(
"Reflect a body about a plane"),
1015 [this] {
1016 if (
m_doc.bodies.empty()) {
1018 return;
1019 }
1020 {
1022 for (
size_t i = 0; i <
m_doc.bodies.size(); ++i) {
1023 const std::string& n =
m_doc.bodies[i].name;
1024 m_mirror_body->Append(n.empty() ? wxString::Format(
_L(
"Body %zu"), i + 1) : wxString::FromUTF8(n));
1025 }
1029 }
1033 {
"design_c_coincident",
_L(
"Mate"),
_L(
"Assembly: align two coordinate systems (fastened, planar, revolute, slider, cylindrical)"),
1034 [this] {
1036 }, 0},
1037 });
1038
1039 auto* b_boolean = icon_btn(
"design_boolean",
_L(
"Boolean (combine bodies)"));
1041 b_boolean->Bind(wxEVT_BUTTON, [act_boolean](wxCommandEvent&) { act_boolean(); });
1043 fadd("boolean", b_boolean);
1044 m_body_gates.push_back({b_boolean, 2, b_boolean->GetToolTipText(),
1045 _L(
"Boolean — needs two solid bodies to combine")});
1046
1047 auto* b_cut = icon_btn(
"design_cut",
_L(
"Cut (split a body with a plane)"));
1048 std::function<void()> act_cut = [this] {
1049
1050 if (
m_doc.bodies.empty()) {
1052 return;
1053 }
1057 };
1058 b_cut->Bind(wxEVT_BUTTON, [act_cut](wxCommandEvent&) { act_cut(); });
1060 fadd("cut", b_cut);
1061 m_body_gates.push_back({b_cut, 1, b_cut->GetToolTipText(),
1062 _L(
"Cut — needs a solid body to slice")});
1063
1064
1065 auto* b_color = icon_btn(
"color_palette",
_L(
"Color — set the selected body's display color"));
1067 fadd("color", b_color);
1071
1072
1073
1074 auto rename_feature = [this] {
1075
1076
1077
1078
1083 else
1084 set_status(
_L(
"Select a feature, or a body, first — then rename it"));
1085 };
1088
1089
1090
1093 m_viewport->delete_selected_sketch_entities();
1094 else
1096 };
1097
1102
1103
1104
1105
1106
1111 };
1112
1113
1114
1115 feat_dropdown(
"dressup",
"design_dressup",
_L(
"Fillet / chamfer / draft / shell / delete face"), {
1116 {
"design_dressup",
_L(
"Fillet / Chamfer"),
_L(
"Round or bevel a picked edge"),
1118 {
"design_draft",
_L(
"Draft (taper a face)"),
_L(
"Tilt a picked face by a draft angle"),
1120 {
"design_shell",
_L_CONTEXT(
"Shell",
"Design"),
_L(
"Hollow the body to a wall thickness, opening a picked face"),
1122 {
"design_delete",
_L(
"Delete Face"),
_L(
"Remove faces from a body and heal the solid"),
1123 [this] {
1124 if (
m_doc.bodies.empty()) {
1126 return;
1127 }
1128 {
1130 for (
size_t i = 0; i <
m_doc.bodies.size(); ++i) {
1131 const std::string& n =
m_doc.bodies[i].name;
1132 m_del_face_body->Append(n.empty() ? wxString::Format(
_L(
"Body %zu"), i + 1) : wxString::FromUTF8(n));
1133 }
1137 }
1141 }, 0},
1142 });
1143
1144
1145 feat_dropdown(
"hole",
"design_hole",
_L(
"Hole / thread"), {
1146 {
"design_hole",
_L_CONTEXT(
"Hole",
"Design"),
_L(
"Drill a hole, centered on a picked face or placed on a plane"),
1147 [this] {
1148
1149
1150
1155
1156
1157
1159 if (hf < 0 || hb < 0 || hb >=
int(
m_doc.bodies.size())) {
1161 return;
1162 }
1163 if (hf >= 0 && hb >= 0 && hb <
int(
m_doc.bodies.size())) {
1165 m_doc.bodies[hb].shape, hf);
1166 if (!face.IsNull()) {
1171
1177
1178
1181 }
1182 }
1185 {
"design_thread",
_L(
"Thread"),
_L(
"Thread a cylindrical surface (inner bore / outer) or a circular edge"),
1186 [this] {
1187
1188
1189
1193 GeometryEngine::CylinderFace cf;
1194 bool from_face = false;
1199 from_face = cf.ok;
1202 }
1203 if (cf.ok) {
1204 SketchPlane p;
1205 p.origin = cf.base;
1206 p.normal = cf.axis;
1207 const Vec3d ref = std::abs(cf.axis.z()) < 0.9 ?
Vec3d(0, 0, 1) :
Vec3d(1, 0, 0);
1208 p.x_axis = ref.cross(cf.axis).normalized();
1209 p.y_axis = cf.axis.cross(p.x_axis).normalized();
1221
1222
1224 return;
1225 }
1228 });
1229
1230
1231 auto* b_constrain = icon_btn(
"design_constrain",
_L(
"Constrain selected sketch"));
1232 b_constrain->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) {
1236 });
1237 fadd("constrain", b_constrain);
1238 }
1239
1240
1242
1243
1244
1245
1246 auto sadd = [](wxWindow* w) { w->Hide(); };
1247 auto sadd_bar = [
this](wxWindow* w) {
m_tb_sketch->Add(w, 0, wxALIGN_CENTER_VERTICAL); };
1248 m_tb_sketch->Add(caption(
_L(
"SKETCH")), 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 8);
1249 {
1250
1251
1253 const wxString& tip, const wxString& hint) {
1254 auto* b = icon_btn(icon, tip);
1255 b->Bind(wxEVT_BUTTON, [select_tool, mode, hint](wxCommandEvent&) { select_tool(mode, hint); });
1256 sadd(b);
1257 };
1258
1259
1260
1261
1262 struct SkVar { const char* icon; DesignSketchTool::Mode mode; wxString tip; wxString hint; };
1263 struct ToolFlyout {
1264 std::vector<DropDown::Item> items;
1265 std::vector<DesignSketchTool::Mode> modes;
1266 std::vector<wxString> hints;
1267 std::vector<std::string> icon_names;
1268 ScalableButton* btn = nullptr;
1269 DropDown drop;
1270 ToolFlyout() : drop(items) {}
1271 };
1272 auto dropdown = [&](const char* def_icon, const wxString& grp, std::vector<SkVar> vars) {
1273
1274
1275
1276
1277
1278 for (size_t i = 0; i < vars.size(); ++i) {
1280 const wxString hint = vars[i].hint;
1281 m_verb_actions[
"fly:" + std::string(def_icon) +
"#" + std::to_string(i)] =
1282 [mode, hint, select_tool] { select_tool(mode, hint); };
1283 }
1284 if (kBarKeep.count(def_icon) == 0)
1285 return;
1286 auto* b = icon_btn(def_icon, grp);
1287
1288
1289
1290
1292 auto fo = std::make_shared<ToolFlyout>();
1293 for (auto& v : vars) {
1294 DropDown::Item it;
1298 fo->items.push_back(it);
1299 fo->modes.push_back(v.mode);
1300 fo->hints.push_back(v.hint);
1301 fo->icon_names.emplace_back(v.icon);
1302 }
1303 fo->btn = b;
1304 fo->drop.Create(b);
1306 for (size_t i = 0; i < fp->items.size(); ++i)
1307 fp->items[i].icon = create_scaled_bitmap(fp->icon_names[i], m_form, 18);
1308 fp->drop.Invalidate(true);
1309 });
1310 fo->drop.SetUseContentWidth(true, false);
1311 fo->drop.Invalidate(true);
1312 ToolFlyout* fp = fo.get();
1313 fo->drop.Bind(wxEVT_COMBOBOX, [this, fp, select_tool](wxCommandEvent& e) {
1314 int i = e.GetInt();
1315 if (i >= 0 && i < (int) fp->modes.size()) {
1316 fp->btn->SetBitmap_(fp->icon_names[i]);
1317 select_tool(fp->modes[i], fp->hints[i]);
1319 }
1320 });
1321 b->Bind(wxEVT_BUTTON, [b, fp](wxCommandEvent&) {
1322
1323
1324
1325
1326
1327 fp->drop.Invalidate(true);
1328 fp->drop.SetUseContentWidth(false, false);
1329 fp->drop.SetUseContentWidth(true, false);
1330 wxPoint
pos = b->ClientToScreen(wxPoint(0, -6));
1331 fp->drop.Position(pos, wxSize(0, b->GetSize().y + b->FromDIP(12)));
1332 fp->drop.Popup();
1333 });
1335 sadd(b);
1339 sadd(chev);
1340 };
1342 _L(
"Click to select; Shift to add; double-click for a whole loop"));
1344 _L(
"Click 2 points or a line / circle / arc to place a dimension"));
1345
1346 dropdown(
"design_line",
_L(
"Line / polyline"), {
1349 dropdown(
"design_rect",
_L(
"Rectangle"), {
1354 dropdown(
"design_circle",
_L(
"Circle"), {
1358 dropdown(
"design_arc3pt",
_L(
"Arc"), {
1362 dropdown(
"design_slot",
_L(
"Slot"), {
1365 dropdown(
"design_ellipse",
_L(
"Ellipse"), {
1369 _L(
"Click control points; double-click, right-click or Enter to finish"));
1371 _L(
"Click to place a point"));
1372
1373
1374
1375
1376 {
1377
1378
1379
1380
1381
1382 auto ensure_sketch = [this, select_tool] {
1385 _L(
"Select — click to select; Shift to add"));
1386 };
1387 auto* b_text = icon_btn(
"design_text",
_L(
"Text — emboss text as a profile"));
1388 b_text->Bind(wxEVT_BUTTON, [this, ensure_sketch](wxCommandEvent&) {
1390 sadd(b_text);
1391 auto* b_svg = icon_btn(
"design_svg",
_L(
"SVG — import an outline as a profile"));
1392 b_svg->Bind(wxEVT_BUTTON, [this, ensure_sketch](wxCommandEvent&) {
1394 sadd(b_svg);
1395
1396
1397
1398
1399
1402 }
1403
1404
1405 dropdown(
"design_filletedge",
_L(
"Fillet / chamfer"), {
1409 _L(
"Pick an entity, then drag the arrow or click the distance; click empty to apply"));
1411 _L(
"Pick a mirror-axis line, then the entities to mirror; click empty to apply"));
1412
1413
1415 _L(
"Click a segment to trim it back to its nearest intersection; Esc exits"));
1417 _L(
"Click a line or arc to extend it to the nearest entity; Esc exits"));
1418
1419
1420
1421 auto* b_constrain_sk = icon_btn("design_constrain",
1422 _L(
"Constrain — add geometric/dimensional relations"));
1424 sadd(b_constrain_sk);
1425 dropdown(
"design_move",
_L(
"Move / rotate / scale"), {
1426 {
"design_move",
DesignSketchTool::Mode::Move,
_L(
"Move (translate)"),
_L(
"Pick entities, then drag the handle or click the distance; click empty to apply")},
1427 {
"design_rotate",
DesignSketchTool::Mode::Rotate,
_L(
"Rotate (about centroid)"),
_L(
"Pick entities, then drag around the pivot or click the angle; click empty to apply")},
1428 {
"design_scale",
DesignSketchTool::Mode::Scale,
_L(
"Scale (about centroid)"),
_L(
"Pick entities, then drag the handle or click the factor; click empty to apply")} });
1429 dropdown(
"design_array",
_L(
"Linear / polar array"), {
1432
1433
1434
1435
1436
1437
1438 auto arm_polygon = [this, select_tool] {
1442 ?
_L_PLURAL(
"Click center then a vertex — %d side, circumscribed",
1443 "Click center then a vertex — %d sides, circumscribed",
m_poly_sides)
1444 :
_L_PLURAL(
"Click center then a vertex — %d side, inscribed",
1445 "Click center then a vertex — %d sides, inscribed",
m_poly_sides),
1447 };
1448 for (int n : {3, 4, 5, 6, 8, 12})
1450 [
this, arm_polygon, n] {
m_poly_sides = n; arm_polygon(); };
1451 for (int c : {0, 1})
1454
1455
1456
1457
1458
1459
1460
1461
1462 auto open_feature = [this](int key) {
1465 };
1466
1467
1468 const int k_dress =
SHIFT(
'F'), k_bool =
SHIFT(
'B'), k_pat =
SHIFT(
'N');
1469
1470
1471
1476
1477
1478
1479 for (int op = 0; op < 3; ++op)
1480 m_verb_actions[
"btn:bool#" + std::to_string(op)] = [
this, open_feature, op] {
1482 open_feature(k_bool); };
1483 for (int t = 0; t < 2; ++t)
1484 m_verb_actions[
"btn:pat#" + std::to_string(t)] = [
this, open_feature, t] {
1486 open_feature(k_pat); };
1487
1488 auto* b_poly = icon_btn(
"design_polygon",
_L(
"Polygon"));
1489 b_poly->Bind(wxEVT_BUTTON, [arm_polygon](wxCommandEvent&) { arm_polygon(); });
1490 sadd(b_poly);
1491
1492
1493
1494
1495
1496
1497
1498
1501 return;
1502
1503
1504
1505
1506
1507
1508
1509 const int n =
m_viewport->sketch_is_selecting()
1510 ?
m_viewport->toggle_sketch_construction_selection() : 0;
1511 if (n > 0) {
1514 _L_PLURAL(
"Converted %d entity between construction and real geometry",
1515 "Converted %d entities between construction and real geometry", n),
1516 n));
1517 return;
1518 }
1520
1521
1522
1523
1524
1527 auto* b_del = icon_btn(
"design_delete",
_L(
"Delete selected"));
1528 b_del->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) {
1530 sadd_bar(b_del);
1531
1532 }
1533
1534
1535
1536
1537
1539 auto cadd = [
this](wxWindow* w) {
m_tb_relations->Add(w, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 2); };
1540 m_tb_relations->Add(caption(
_L(
"CONSTRAIN")), 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 8);
1541 {
1543 auto* b = icon_btn(icon, tip);
1544 b->Bind(wxEVT_BUTTON, [
this, type](wxCommandEvent&) {
apply_constraint(type); });
1545 cadd(b);
1546 };
1567
1568
1569
1570 }
1571
1572
1573
1574
1576 {
1577 auto* ok = new ::Button(
m_toolbar,
_L(
"Confirm"));
1579 ok->Bind(wxEVT_BUTTON, [
this](wxCommandEvent&) {
tool_confirm(); });
1583 no->Bind(wxEVT_BUTTON, [
this](wxCommandEvent&) {
tool_cancel(); });
1584 m_tb_action->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 6);
1585 m_tb_action->Add(no, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 10);
1586 }
1587
1588
1589
1590 m_tb_doc =
new wxBoxSizer(wxHORIZONTAL);
1591 {
1592
1593
1594
1595 auto doc_btn = [this](const char* icon, const wxString& tip, bool has_dark_twin = false,
1596 int cell_w = 40, int icon_px = 34) {
1597 const std::string name(icon);
1598 auto themed = [name, has_dark_twin] {
return has_dark_twin &&
dp_dark() ? name +
"_dark" : name; };
1599 auto* b =
new ScalableButton(
m_toolbar, wxID_ANY, themed(),
"", FromDIP(wxSize(cell_w, 40)),
1600 wxDefaultPosition, wxBU_EXACTFIT | wxBORDER_NONE, false, icon_px);
1601 if (has_dark_twin)
1602 m_icon_refresh.push_back([b, themed] { b->SetBitmap_(themed()); });
1603 b->SetToolTip(tip);
1606 if (b->IsEnabled()) { b->SetBackgroundColour(
dp_ribbon_hover()); b->Refresh(); } e.Skip(); });
1608 b->SetBackgroundColour(
dp_ribbon_bg()); b->Refresh(); e.Skip(); });
1609 return b;
1610 };
1611 auto add_doc = [this](ScalableButton* b) {
1612 m_tb_doc->Add(b, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 4); };
1613
1614 auto* b_new = doc_btn(
"design_new",
_L(
"New Design — clear the feature tree"));
1615 b_new->Bind(wxEVT_BUTTON, [
this](wxCommandEvent&) {
on_new_design(); });
1616 add_doc(b_new);
1617
1618 auto* b_step = doc_btn(
"design_step",
_L(
"Import STEP (editable B-rep solid)"));
1619 b_step->Bind(wxEVT_BUTTON, [
this](wxCommandEvent&) {
on_import_step(); });
1621 add_doc(b_step);
1622
1623
1624 auto* b_mesh = doc_btn(
"design_import_mesh",
_L(
"Import mesh (STL/OBJ) as an editable B-rep solid"));
1625 b_mesh->Bind(wxEVT_BUTTON, [
this](wxCommandEvent&) {
on_import_mesh(); });
1627 add_doc(b_mesh);
1628 auto* b_export = doc_btn(
"design_export",
_L(
"Export STEP…"));
1629 b_export->Bind(wxEVT_BUTTON, [
this](wxCommandEvent&) {
on_export_step(); });
1630 add_doc(b_export);
1631
1632
1633
1634 auto* b_sketch = doc_btn(
"design_new_sketch",
_L(
"Create a new sketch"));
1635 b_sketch->Bind(wxEVT_BUTTON, [
this](wxCommandEvent&) {
start_sketch(); });
1636 tb_slot["sketch"].push_back(b_sketch);
1637
1638
1639
1640 auto* b_place = doc_btn(
"toolbar_flatten",
_L(
"Place on Face (F) — lay the picked face on the bed"),
1641 true);
1642 b_place->Bind(wxEVT_BUTTON, [
this](wxCommandEvent&) {
place_on_face(); });
1643 tb_slot["place"].push_back(b_place);
1644
1645 auto* b_section = doc_btn(
"split_parts",
_L(
"Section View — hide part of the model to see inside. "
1646 "PageUp/PageDown move the plane; Delete removes it."),
1647 true);
1649 tb_slot["section"].push_back(b_section);
1650
1655
1656
1657
1658
1660 m_commit_btn = doc_btn(
"toolbar_add_plate", wxEmptyString);
1662 auto* b_mode = doc_btn(
"drop_down",
_L(
"Choose how Commit to Plate sends the bodies"),
false, 16, 16);
1664 m_tb_commit->Add(b_mode, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 4);
1665
1666
1667 struct CommitFlyout {
1668 std::vector<DropDown::Item> items;
1669 wxLongLong closed_ms;
1670 DropDown drop;
1671 CommitFlyout() : drop(items) {}
1672 };
1673 auto cf = std::make_shared<CommitFlyout>();
1674 cf->items.resize(2);
1677 "keeping their relative positions");
1679 cf->items[int(
CommitMode::Bodies)].tip =
_L(
"Each body becomes its own object, placed on its own");
1680 CommitFlyout* cp = cf.get();
1681 auto refresh_rows = [this, cp] {
1682 for (size_t i = 0; i < cp->items.size(); ++i)
1684 };
1685 refresh_rows();
1687 cp->drop.SetUseContentWidth(true, false);
1688 cp->drop.Invalidate(true);
1690 cp->drop.Bind(wxEVT_COMBOBOX, [this](wxCommandEvent& e) {
1693 wxGetApp().app_config->set("design_commit_mode", bodies ? "bodies" : "assembly");
1694 });
1695 cp->drop.Bind(EVT_DISMISS, [cp](wxCommandEvent&) { cp->closed_ms = wxGetLocalTimeMillis(); });
1696 b_mode->Bind(wxEVT_BUTTON, [this, b_mode, cp](wxCommandEvent&) {
1697
1698
1699
1700 if (cp->drop.IsShown() || wxGetLocalTimeMillis() - cp->closed_ms < 300)
1701 return;
1702
1703
1708
1709 wxPoint
pos = b_mode->ClientToScreen(wxPoint(b_mode->GetSize().x, -6));
1711 m_commit_drop->Position(pos, wxSize(0, b_mode->GetSize().y + b_mode->FromDIP(12)));
1713 });
1715 refresh_rows();
1718 });
1720
1723 }
1724
1725
1726 {
1727 auto put = [&](const char* id) {
1728 auto it = tb_slot.find(id);
1729 if (it == tb_slot.end()) return;
1730 for (size_t i = 0; i < it->second.size(); ++i)
1732 i == 0 ? (wxALIGN_CENTER_VERTICAL | wxRIGHT)
1733 : (wxALIGN_BOTTOM | wxBOTTOM | wxRIGHT),
1734 i == 0 ? 4 : 5);
1735 };
1736 put("sketch"); put("constrain");
1738 put("material"); put("place"); put("placement"); put("plane");
1739 put("dressup"); put("section");
1740 put("hole"); put("boolean"); put("cut");
1741 put("surface"); put("color"); put("flip");
1742 put("pattern");
1743 }
1744
1745 auto* tbrow = new wxBoxSizer(wxHORIZONTAL);
1746 tbrow->AddSpacer(8);
1747 tbrow->Add(
m_tb_doc, 0, wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM, 5);
1748 add_sep(tbrow);
1749 tbrow->Add(
m_tb_feature, 0, wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM, 5);
1750 tbrow->Add(
m_tb_sketch, 0, wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM, 5);
1751 tbrow->Add(
m_tb_relations, 0, wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM, 5);
1752 tbrow->AddStretchSpacer();
1753 tbrow->Add(
m_tb_commit, 0, wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM, 5);
1754 tbrow->Add(
m_tb_action, 0, wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM, 5);
1755 tbrow->AddSpacer(8);
1757 build_phase("toolbar");
1758
1759
1761
1762
1763
1764 auto card_header = [
this](wxWindow* card,
const char* icon,
const wxString& title,
wxStaticText*& out) -> wxSizer* {
1765 auto* h = new wxBoxSizer(wxHORIZONTAL);
1771 h->Add(ic, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 8);
1772 h->Add(out, 0, wxALIGN_CENTER_VERTICAL);
1773 return h;
1774 };
1775
1776
1777
1778
1780 auto* cards = new wxBoxSizer(wxVERTICAL);
1782 root->Add(
m_cards, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 8);
1783
1784
1786
1792 form->Add(
m_shape, 0, wxEXPAND);
1793
1794
1795
1796
1797
1798
1802
1806
1810
1816
1817
1818 {
1829
1837
1841
1843 sp->Bind(wxEVT_SPINCTRLDOUBLE, [this](wxSpinDoubleEvent& e) { apply_move_card(); e.Skip(); });
1845
1848 wxLEFT | wxRIGHT | wxTOP, 12);
1850 m_box_move->Add(mform, 0, wxEXPAND | wxALL, 12);
1852 }
1853
1854
1855 {
1856
1857
1858
1859
1860
1861 }
1862
1863
1869 {
1871
1872
1873
1874
1875
1879
1880
1881
1883 for (
const char* s : {
L(
"Blind"),
L(
"Symmetric"),
L(
"Two-sided"),
L(
"Through all"),
1884 L(
"Up to face"),
L(
"Up to vertex") })
1889
1893
1897
1899
1900
1907 eform->Add(
m_mode, 0, wxEXPAND);
1908
1911 eform->Add(
m_flip, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
1912
1913 m_box_extrude->Add(eform, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
1914 }
1916
1917
1919
1926
1927
1928
1929
1930
1931
1935
1939
1945
1949
1953 m_box_dressup->Add(dform, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
1955
1956
1958
1964
1965
1966
1967 m_hole_plane->Bind(wxEVT_COMBOBOX, [
this](wxCommandEvent& e) {
1973 e.Skip();
1974 });
1977
1981
1985
1989
1993
1997 hform->Add(
m_hole_through, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
1998
2002
2006 m_box_hole->Add(hform, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
2008
2009
2011
2019
2020
2021
2030
2031
2032
2036
2040
2044
2048
2052
2056
2059
2060
2061
2064 e.Skip();
2065 });
2068
2072
2076 m_box_thread->Add(tform, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
2078
2079
2085 {
2087
2091
2098
2107
2110 rform->Add(
m_revolve_flip, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
2111
2112 m_box_revolve->Add(rform, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
2113 }
2115
2116
2122 {
2124
2128
2137
2138 m_box_sweep->Add(sform, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
2139 }
2141
2142
2146 {
2148
2155
2159
2163
2170
2174
2175 m_box_pattern->Add(pform, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
2176 }
2178
2179
2183 {
2185
2194
2199
2204
2205
2206
2207
2212
2213 m_box_boolean->Add(bform, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
2214
2217 auto* keeprow = new wxBoxSizer(wxHORIZONTAL);
2218 keeprow->Add(
new wxStaticText(
m_cards, wxID_ANY,
_L(
"Keep tool body")), 0, wxALIGN_CENTER_VERTICAL);
2219 keeprow->AddStretchSpacer();
2220 keeprow->Add(
m_bool_keep, 0, wxALIGN_CENTER_VERTICAL);
2221 m_box_boolean->Add(keeprow, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
2222 }
2224
2225
2229 {
2231
2236
2241
2246
2247 m_box_cut->Add(cform, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
2248
2249
2250 }
2252
2253
2258 _L(
"Drag a corner to size, the center to move.\nConfirm or Cancel in the toolbar above.")),
2259 0, wxLEFT | wxRIGHT | wxBOTTOM, 12);
2261
2262
2266 {
2267
2268
2269
2270
2271
2272
2273
2275 for (
const wxString& t : {
_L(
"Offset"),
_L(
"Angle"),
_L(
"Midplane"),
2276 _L(
"Tangent"),
_L(
"Two edges"),
_L(
"Coincident") })
2281
2283
2286
2289
2293
2297
2304
2305
2307 btn = new ::Button(
m_cards, label);
2310 btn->Bind(wxEVT_BUTTON, [
this, target](wxCommandEvent&) {
arm_plane_pick(target); });
2311 plform->Add(btn);
2312 plform->Add(lbl, 0, wxALIGN_CENTER_VERTICAL);
2313 };
2318
2325
2326 m_box_plane->Add(plform, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
2327 }
2329
2330
2335 0, wxLEFT | wxRIGHT | wxTOP, 12);
2336 m_loft_list =
new wxCheckListBox(
m_cards, wxID_ANY, wxDefaultPosition, FromDIP(wxSize(-1, 120)));
2339 {
2341
2350
2351 m_box_loft->Add(lform, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
2352 }
2354 {
2355 auto* lrow = new wxBoxSizer(wxHORIZONTAL);
2356 lrow->Add(
new wxStaticText(
m_cards, wxID_ANY,
_L(
"Ruled (straight) sections")), 0, wxALIGN_CENTER_VERTICAL);
2357 lrow->AddStretchSpacer();
2359 m_box_loft->Add(lrow, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
2360 }
2362
2363
2369 {
2375 }
2377
2378
2384 {
2399 }
2401
2402
2407 0, wxLEFT | wxRIGHT | wxTOP, 12);
2412 {
2413 auto* lrow = new wxBoxSizer(wxHORIZONTAL);
2414 lrow->Add(
new wxStaticText(
m_cards, wxID_ANY,
_L(
"Ruled (straight) sections")), 0, wxALIGN_CENTER_VERTICAL);
2415 lrow->AddStretchSpacer();
2417 m_box_surf_loft->Add(lrow, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
2418 }
2420
2421
2428 _L(
"Fills the sketch's closed boundary with a smooth face.")),
2429 0, wxLEFT | wxRIGHT, 12);
2431
2432
2436 {
2448 _L(
"Offsets a sheet body's shell. Positive = outward, negative = inward.")),
2449 0, wxLEFT | wxRIGHT, 12);
2450 }
2452
2453
2457 {
2473 _L(
"Thickens a sheet body into a solid. Flip reverses the direction.")),
2474 0, wxLEFT | wxRIGHT, 12);
2475 }
2477
2478
2486
2491 _L(
"Pick a solid face to open it, then set the wall thickness.")),
2492 0, wxLEFT | wxRIGHT, 12);
2493 m_box_shell->Add(sform, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
2495
2496
2504
2509 _L(
"Pick a side face, then set the draft angle. The face pivots about the body base.")),
2510 0, wxLEFT | wxRIGHT, 12);
2511 m_box_draft->Add(drform, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
2513
2514
2518 {
2560 m_box_transform->Add(xform, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
2563 auto* cpro = new wxBoxSizer(wxHORIZONTAL);
2564 cpro->Add(
new wxStaticText(
m_cards, wxID_ANY,
_L(
"Keep original (make a copy)")), 0, wxALIGN_CENTER_VERTICAL);
2565 cpro->AddStretchSpacer();
2566 cpro->Add(
m_xf_copy, 0, wxALIGN_CENTER_VERTICAL);
2567 m_box_transform->Add(cpro, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
2569 _L(
"Translate and/or rotate the selected body. Rotation is applied about the pivot, then translation follows.")),
2570 0, wxLEFT | wxRIGHT, 12);
2571 }
2573
2574
2578 {
2588 m_box_mirror->Add(mform, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
2592 auto* mkrow = new wxBoxSizer(wxHORIZONTAL);
2594 mkrow->AddStretchSpacer();
2596 m_box_mirror->Add(mkrow, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
2598 _L(
"Reflect the selected body about a plane. The mirror is always a new body; keeping the original gives you both.")),
2599 0, wxLEFT | wxRIGHT, 12);
2600 }
2602
2603
2607 {
2620 m_box_thicken->Add(tform, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
2623 auto* trow = new wxBoxSizer(wxHORIZONTAL);
2625 trow->AddStretchSpacer();
2627 m_box_thicken->Add(trow, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
2629 _L(
"Pick a solid face and offset it into a new thin body. Not for sheet bodies — use Thicken Surface for those.")),
2630 0, wxLEFT | wxRIGHT, 12);
2631 }
2633
2634
2638 {
2648 m_rib_entity =
new wxSpinCtrl(
m_cards, wxID_ANY,
"", wxDefaultPosition, FromDIP(wxSize(90, -1)),
2649 wxSP_ARROW_KEYS | wxBORDER_SIMPLE);
2663 m_box_rib->Add(rform, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
2665 _L(
"Grow a thin wall from an open sketch Line entity, fused to the target body. Entity index is the position of the open Line in the sketch.")),
2666 0, wxLEFT | wxRIGHT, 12);
2667 }
2669
2670
2674 {
2688 m_box_project->Add(pform, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
2690 _L(
"Project the edges of a body onto a plane as sketch entities. Pick a face to project only its edges, or leave the face empty to project the whole body.")),
2691 0, wxLEFT | wxRIGHT, 12);
2692 }
2694
2695
2699 {
2708
2709
2712 return;
2713 }
2714
2715
2718 return;
2719 }
2720 {
2722 wxString s;
2724 if (i > 0) s += ", ";
2726 }
2731 }
2732 });
2736 dform->Add(0, 0);
2740 _L(
"Pick a solid face, then click 'Add picked face' to accumulate faces. Confirm to remove all listed faces and heal the solid.")),
2741 0, wxLEFT | wxRIGHT, 12);
2742 }
2744
2745
2749 {
2768 m_box_helix->Add(hform, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
2771 auto* hrow = new wxBoxSizer(wxHORIZONTAL);
2773 hrow->AddStretchSpacer();
2775 m_box_helix->Add(hrow, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
2781 m_box_helix->Add(tvalform, 0, wxEXPAND | wxLEFT | wxRIGHT, 12);
2783 _L(
"A helical curve (spring path). Use as a sweep path to build springs, coils, or augers.")),
2784 0, wxLEFT | wxRIGHT, 12);
2785 }
2787
2788
2792 {
2794 for (
const wxString& t : {
_L(
"Two points"),
_L(
"Face normal"),
_L(
"Cylinder centerline"),
2795 _L(
"Plane intersection"),
_L(
"Along edge") })
2800
2802
2803 auto ax_pick = [&](
const wxString& label, ::Button*& btn,
wxStaticText*& lbl,
AxisPick target) {
2804 btn = new ::Button(
m_cards, label);
2807 btn->Bind(wxEVT_BUTTON, [
this, target](wxCommandEvent&) {
arm_axis_pick(target); });
2808 axform->Add(btn);
2809 axform->Add(lbl, 0, wxALIGN_CENTER_VERTICAL);
2810 };
2813
2822
2832
2842
2843 m_box_axis->Add(axform, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
2844 }
2846
2847
2851 {
2853 for (
const wxString& t : {
_L(
"Point (world)"),
_L(
"Face + direction") })
2858
2862 m_cs_body->Bind(wxEVT_COMBOBOX, [
this](wxCommandEvent&) {
2864 });
2868 _L(
"Restrict picking to one body — the others go see-through and stop catching clicks"));
2871
2873
2883
2885 btn = new ::Button(
m_cards, label);
2888 btn->Bind(wxEVT_BUTTON, [
this, target](wxCommandEvent&) {
arm_coordsys_pick(target); });
2889 csform->Add(btn);
2890 csform->Add(lbl, 0, wxALIGN_CENTER_VERTICAL);
2891 };
2893
2894
2902 _L(
"Without an edge the frame takes X from the face's first edge — pick one to choose it yourself"));
2904 csform->Add(0, 0);
2905 csform->Add(edge_hint, 0, wxALIGN_CENTER_VERTICAL);
2906
2916
2917 m_box_coordsys->Add(csform, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
2918 }
2920
2921
2925 {
2927
2929 m_mate_kind->Append(
_L(
"Fastened — 6 DOF locked, B driven onto A exactly"));
2930 m_mate_kind->Append(
_L(
"Planar — z aligned, offset distance; free in-plane slide"));
2931 m_mate_kind->Append(
_L(
"Revolute — axes collinear; free rotation about z"));
2932 m_mate_kind->Append(
_L(
"Slider — orientation locked; free axial slide"));
2933 m_mate_kind->Append(
_L(
"Cylindrical — axes collinear; free spin + axial slide"));
2937
2938
2942
2946
2951
2956
2958 auto* frow = new wxBoxSizer(wxHORIZONTAL);
2959 frow->Add(
new wxStaticText(
m_cards, wxID_ANY,
_L(
"Flip (oppose z axes)")), 0, wxALIGN_CENTER_VERTICAL);
2960 frow->AddStretchSpacer();
2961 frow->Add(
m_mate_flip, 0, wxALIGN_CENTER_VERTICAL);
2962 mform->Add(0, 0);
2963 mform->Add(frow, 0, wxEXPAND);
2964
2965
2966 m_mate_kind->Bind(wxEVT_COMBOBOX, [
this](wxCommandEvent& e) {
2968 switch (kind) {
2969 case 0:
2972 break;
2973 case 1:
2976 break;
2977 case 2:
2980 break;
2981 case 3:
2984 break;
2985 case 4:
2988 break;
2989 }
2992 e.Skip();
2993 });
2994
2995 m_box_mate->Add(mform, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
2996 }
2998
3004
3005
3006
3007
3008
3010 {
3013 wxLEFT | wxRIGHT | wxTOP, 12);
3015
3017
3018
3019
3020
3021
3022
3023
3025 wxSize(FromDIP(90), FromDIP(24)), 0, nullptr, 0);
3026 m_expr_field->SetMinSize(wxSize(FromDIP(90), FromDIP(24)));
3029
3031 wxSize(FromDIP(120), FromDIP(24)),
3032 wxTE_PROCESS_ENTER | wxBORDER_SIMPLE);
3036
3037 m_box_expr->Add(eform, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
3038
3039 auto* brow = new wxBoxSizer(wxHORIZONTAL);
3046 brow->Add(
m_expr_set_btn, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 6);
3048 brow->AddStretchSpacer();
3049 m_box_expr->Add(brow, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 12);
3050
3054 }
3056
3057
3059 {
3060
3063 auto* vrow = new wxBoxSizer(wxHORIZONTAL);
3064
3065
3066
3067
3068
3070 FromDIP(wxSize(90, -1)), wxTE_PROCESS_ENTER);
3072 vrow->Add(
new wxStaticText(
m_cards, wxID_ANY,
_L(
"Value")), 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 8);
3074 m_box_value->Add(vrow, 0, wxLEFT | wxRIGHT | wxTOP, 12);
3075 }
3077
3078
3079
3082 0, wxLEFT | wxRIGHT | wxTOP, 12);
3084 {
3085
3086
3087
3088
3089
3090
3091
3095 }
3097
3098
3099
3100
3103 0, wxLEFT | wxRIGHT | wxTOP, 12);
3108
3109
3110
3111
3112
3113
3114
3115
3116 for (wxWindow* w :
m_cards->GetChildren())
3118 t->Wrap(240);
3119
3120
3121
3122
3124 auto* tree_inner = new wxBoxSizer(wxVERTICAL);
3126 root->Add(
m_tree_box, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 8);
3127
3130 wxALIGN_CENTER_VERTICAL);
3132 tree_inner->Add(
m_hdr_tree_row, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP,
3134 tree_inner->Add(
new wxStaticLine(
m_tree_box), 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP,
3136
3137
3138
3139
3142 tree_inner->Add(
m_pinned, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 13);
3143
3146 tree_inner->Add(
m_tree, 0, wxEXPAND | wxALL, 12);
3147
3148 m_pinned->on_action = [
this](
int row, int) {
3153 };
3154
3155 m_pinned->on_menu = [
this](
int row,
const wxPoint& screen) {
3156 const bool bed = (row ==
kBedRow);
3157 wxMenu menu;
3158 const int id_toggle = wxWindow::NewControlId();
3162 };
3163
3164
3165
3166 m_tree->on_select = [
this] {
3168
3169
3170
3171
3174
3175
3179
3180
3181
3182
3185 }
else if (sel >= 0 && sel <
int(
m_doc.features.size())) {
3186
3188 _L(
"%s selected — F2 or right-click renames it, double-click edits it"),
3189 wxString::FromUTF8(
m_doc.features[sel].name)));
3190 }
3191 };
3192
3193
3194 m_tree->on_activate = [
this] {
3196 };
3197
3198
3199
3200
3201 m_tree->on_action = [
this](
int row,
int id) {
3203 switch (id) {
3208 }
3209 };
3210
3211
3212
3213
3214 m_tree->on_menu = [
this](
int row,
const wxPoint& screen) {
3215
3216
3217
3218
3219 wxMenu menu;
3220 const int id_rename = wxWindow::NewControlId();
3221 const int id_edit = wxWindow::NewControlId();
3222 const int id_up = wxWindow::NewControlId();
3223 const int id_down = wxWindow::NewControlId();
3224 const int id_vis = wxWindow::NewControlId();
3225 const int id_zoom = wxWindow::NewControlId();
3226 const int id_art = wxWindow::NewControlId();
3227 const int id_del = wxWindow::NewControlId();
3228 menu.Append(id_rename,
_L(
"Rename\tF2"));
3229 menu.Append(id_edit,
_L(
"Edit"));
3230
3231
3232
3233 const bool art = row < int(
m_doc.features.size()) &&
3234 !
m_doc.features[row].imported_regions.empty();
3235 if (art) menu.Append(id_art,
_L(
"Scale artwork"));
3236 menu.AppendSeparator();
3237 menu.Append(id_up,
_L(
"Move up"));
3238 menu.Append(id_down,
_L(
"Move down"));
3239 menu.Append(id_vis,
_L(
"Show / hide"));
3240
3242 if (zoom) menu.Append(id_zoom,
_L(
"Zoom to selection"));
3243 menu.AppendSeparator();
3244 menu.Append(id_del,
_L(
"Delete"));
3245 menu.Bind(wxEVT_MENU, [
this](wxCommandEvent&) {
m_verb_actions[
"btn:rename"](); }, id_rename);
3246 menu.Bind(wxEVT_MENU, [
this](wxCommandEvent&) {
on_edit_feature(); }, id_edit);
3247 menu.Bind(wxEVT_MENU, [
this](wxCommandEvent&) {
on_move_feature(-1); }, id_up);
3248 menu.Bind(wxEVT_MENU, [
this](wxCommandEvent&) {
on_move_feature(+1); }, id_down);
3250 menu.Bind(wxEVT_MENU, [
this](wxCommandEvent&) {
on_delete_feature(); }, id_del);
3251 if (art)
3253 if (zoom)
3254 menu.Bind(wxEVT_MENU, [
this, row](wxCommandEvent&) {
zoom_to_feature(row); }, id_zoom);
3255 m_tree->PopupMenu(&menu,
m_tree->ScreenToClient(screen));
3256 };
3257
3258
3259
3260
3261
3262 m_tree->on_rename = [
this](
int row,
const wxString& name) {
3263 if (row < 0 || row >=
int(
m_doc.features.size()))
return;
3264 m_doc.features[row].name = std::string(name.ToUTF8().data());
3266 };
3267
3268
3269
3270 {
3272
3273
3274
3275
3276
3284 trow->Add(up, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, gap);
3285 trow->Add(down, 0, wxALIGN_CENTER_VERTICAL);
3286
3287 trow->AddSpacer(8);
3288 trow->Add(
new wxStaticLine(
m_tree_box, wxID_ANY, wxDefaultPosition, FromDIP(wxSize(1, 22)), wxLI_VERTICAL),
3289 0, wxALIGN_CENTER_VERTICAL);
3290 trow->AddSpacer(8);
3292
3293 }
3294
3295
3296
3297
3299 auto* parts_inner = new wxBoxSizer(wxVERTICAL);
3301 root->Add(
m_parts_box, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 8);
3302
3305 wxALIGN_CENTER_VERTICAL);
3306
3307
3308
3309
3310 {
3311
3312
3314 bbool->Bind(wxEVT_BUTTON, [
this](wxCommandEvent&) {
on_boolean_tool(); });
3319 m_parts_hdr->Add(bbool, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, bgap);
3320 m_parts_hdr->Add(bcol, 0, wxALIGN_CENTER_VERTICAL);
3321 }
3322 parts_inner->Add(
m_parts_hdr, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP,
3325 parts_inner->Add(
m_parts_rule, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP,
3331 parts_inner->Add(
m_parts, 0, wxEXPAND | wxALL, 12);
3332
3333
3336
3337
3338
3339
3340
3341
3342
3343 auto apply_body_row = [this](int b) {
3345
3346
3354 };
3356
3357
3358
3359
3360 m_parts->on_action = [
this, apply_body_row](
int row,
int id) {
3361 apply_body_row(row);
3362 switch (id) {
3367 }
3368 };
3369
3370
3371
3372
3373
3374 m_parts->on_menu = [
this, apply_body_row](
int row,
const wxPoint& screen) {
3375 apply_body_row(row);
3376
3377
3378
3380 };
3381
3382
3383
3384
3385
3386 m_parts->on_rename = [
this](
int b,
const wxString& name) {
3387 if (b < 0 || b >=
int(
m_doc.bodies.size()))
return;
3388 m_doc.bodies[b].has_user_name =
true;
3389 m_doc.bodies[b].user_name = std::string(name.ToUTF8().data());
3392 };
3393
3394
3395
3396
3397
3399 auto* var_inner = new wxBoxSizer(wxVERTICAL);
3401 {
3402 auto* var_hdr = new wxBoxSizer(wxHORIZONTAL);
3404 var_hdr->Add(card_header(
m_var_box,
"design_constrain",
_L(
"Variables"), var_hdr_title), 0,
3405 wxALIGN_CENTER_VERTICAL);
3406 var_hdr->AddStretchSpacer();
3407
3415 var_hdr->Add(
m_btn_add_var, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, vhgap);
3416 var_hdr->Add(
m_btn_edit_var, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, vhgap);
3418 var_inner->Add(var_hdr, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP,
3420 var_inner->Add(
new wxStaticLine(
m_var_box), 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP,
3422
3424 wxSize(-1, FromDIP(64)), wxLC_REPORT | wxLC_SINGLE_SEL);
3426 m_var_list->AppendColumn(
_L(
"Name"), wxLIST_FORMAT_LEFT, FromDIP(90));
3427 m_var_list->AppendColumn(
_L(
"Expression"), wxLIST_FORMAT_LEFT, FromDIP(120));
3429 }
3430 root->Add(
m_var_box, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 8);
3431
3432
3433
3435
3438 root->Add(
m_status, 0, wxLEFT | wxRIGHT | wxBOTTOM, 12);
3439
3440
3441
3443 {
3445 f.SetWeight(wxFONTWEIGHT_BOLD);
3447 }
3448 root->Add(
m_dof_status, 0, wxLEFT | wxRIGHT | wxBOTTOM, 12);
3449
3450
3453
3454
3455
3460
3462
3463
3465 root->Show(
m_cards,
false,
false);
3494
3495
3496
3497
3506
3508 m_form->SetScrollRate(0, FromDIP(20));
3509 m_form->SetMinSize(FromDIP(wxSize(264, -1)));
3510
3511 build_phase("sidebar and tool cards");
3512
3513
3514 auto* view_col = new wxPanel(body_panel, wxID_ANY);
3517 build_phase("3D canvas");
3518
3519 m_viewport->set_on_sketch_commit([
this](
const SketchProfile& prof,
const SketchPlane& plane) {
3526 });
3527
3529 [this](const std::vector<SketchEntity>& ents,
3530 const std::vector<SketchEntityConstraintDef>& cons,
3531 const SketchPlane& plane) {
3532 if (ents.empty()) {
3534 return;
3535 }
3537
3538
3542 edited.entities = ents;
3543 edited.entity_constraints = cons;
3544 edited.plane = plane;
3552 }
3553 return;
3554 }
3556 const int sk =
m_doc.add_sketch_entities(ents, plane,
3558 if (!cons.empty())
m_doc.solve_sketch_feature(sk);
3561 ?
_L(
"Sketch created — select it, then right-click to Extrude")
3562 : wxString::Format(
_L_PLURAL(
"Sketch created (%zu driving dim) — select it, then right-click to Extrude",
3563 "Sketch created (%zu driving dims) — select it, then right-click to Extrude",
3564 unsigned(cons.size())),
3565 cons.size()));
3568 });
3569
3570
3571 m_viewport->set_on_cursor_metrics([
this](
double len,
double ang_deg,
bool locked) {
3572 double a = ang_deg; if (a < 0.0) a += 360.0;
3573
3574
3575
3576 wxString metrics = wxString::Format(
_L(
"Length %.2f mm, angle %.1f°"), len, a);
3577 if (locked) metrics +=
" " +
_L(
"(locked)");
3581 });
3582
3583
3586 });
3587
3588
3589
3590
3591
3592 m_viewport->set_on_sketch_constraints_changed([
this]() {
3594 });
3595
3596
3597
3598 m_viewport->set_on_solve_state([
this](
int dof,
bool ok,
bool has_constraints) {
3599
3600
3601
3605 });
3606
3607
3608
3609
3610
3611
3612
3613
3614 m_viewport->set_on_sketch_face_selected([
this](
int region) {
3620 return;
3621 }
3624
3625
3630 });
3631
3632
3633
3634
3635 m_viewport->set_on_display_sketch_selected([
this](
int feat,
int region,
int entity) {
3636 if (feat < 0 || feat >=
int(
m_doc.features.size()))
return;
3637
3638
3641
3642
3643
3644
3645
3646
3647
3650 for (
unsigned i = 0; i <
m_rib_sketch->GetCount(); ++i)
3651 if (
int(
reinterpret_cast<intptr_t
>(
m_rib_sketch->GetClientData(i))) == feat) {
3653 break;
3654 }
3657 }
3658
3659
3660
3661
3662
3664 for (
unsigned i = 0; i <
m_sweep_path->GetCount(); ++i) {
3665 if (
int(
reinterpret_cast<intptr_t
>(
m_sweep_path->GetClientData(i))) != feat)
continue;
3669 break;
3670 }
3671 }
3672
3673
3674
3675
3677 for (
size_t i = 0; i <
m_loft_sketch_idx.size() && i < m_loft_list->GetCount(); ++i) {
3681 break;
3682 }
3683 }
3686
3687
3688 ?
_L(
"Region selected — right-click to Extrude, or double-click to edit")
3689 :
_L(
"Sketch selected — right-click to Extrude, or double-click to edit"));
3690 });
3691
3692
3693
3694
3695
3696
3697 m_viewport->set_on_display_sketch_activated([
this](
int feat) {
3698 if (feat < 0 || feat >=
int(
m_doc.features.size()))
return;
3701 });
3702
3703
3704
3705
3706
3707
3708
3709 m_viewport->set_on_solid_selection_changed([
this](
int level,
int body,
int face,
int edge) {
3710
3711
3713
3719
3720
3723
3724
3725
3726
3727 if (level >= 1) {
3730 }
3731
3732
3733
3734
3736 wxString on;
3739 return;
3740 }
3742 ?
_L(
"That face is not flat — click a flat face or a reference plane")
3745 return;
3746 }
3747
3748
3749
3750
3751
3752
3753
3754
3755
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3774 if (dst !=
nullptr && row <
int(dst->
GetCount())) {
3777 if (other !=
nullptr && other->
GetSelection() == row && prev >= 0 && prev != row)
3781 }
3782 }
3783
3784
3785
3790 }
3791
3792
3796 :
_L(
"(all faces — closed hollow)"));
3798 }
3799
3800
3801
3802
3806 :
_L(
"(pick a solid face)"));
3808 }
3809
3813 :
_L(
"(pick a side face)"));
3815 }
3816
3817
3818
3819
3822 if (!fc.IsNull()) {
3834 }
3835 }
3836
3838 const TopoDS_Shape& shape =
m_doc.bodies[body].shape;
3839 GeometryEngine::CylinderFace cf;
3840 if (face >= 0)
3842 const bool from_face = cf.ok;
3843 if (!cf.ok && edge >= 0)
3845 if (cf.ok) {
3846 SketchPlane p; p.origin = cf.base; p.normal = cf.axis;
3847 const Vec3d ref = std::abs(cf.axis.z()) < 0.9 ?
Vec3d(0, 0, 1) :
Vec3d(1, 0, 0);
3848 p.x_axis = ref.cross(cf.axis).normalized();
3849 p.y_axis = cf.axis.cross(p.x_axis).normalized();
3858 }
3859 }
3860
3861
3863 bool got = false;
3869 default: break;
3870 }
3873 }
3874
3876 bool got = false;
3880 default: break;
3881 }
3884 }
3885
3887 bool got = false;
3891 default: break;
3892 }
3893 if (got) {
3894
3895
3896
3897
3898
3899
3900
3905 }
3907 }
3908 const int nb = int(
m_doc.bodies.size());
3909 const bool bodytag = nb > 1;
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921 set_status(level == 4 ? (bodytag ? wxString::Format(
_L(
"Body %d: vertex selected — click again for the whole body"), body + 1)
3922 :
_L(
"Vertex selected — click again for the whole body"))
3923 : level == 1 ? (bodytag ? wxString::Format(
_L(
"Body %d selected (whole body) — right-click for what applies to it"), body + 1)
3924 :
_L(
"Whole body selected — right-click for what applies to it"))
3925 : level == 2 ? (bodytag ? wxString::Format(
_L(
"Body %d: face %d selected — right-click to push/pull it, or click again for the whole body"), body + 1, face)
3926 : wxString::Format(
_L(
"Face %d selected — right-click to push/pull it, or click again for the whole body"), face))
3928 ? (bodytag ? wxString::Format(
_L_PLURAL(
"Body %d: %zu edge selected — Shift+click adds or removes one, Fillet/Chamfer dresses them all",
3929 "Body %d: %zu edges selected — Shift+click adds or removes one, Fillet/Chamfer dresses them all",
3931 : wxString::Format(
_L_PLURAL(
"%zu edge selected — Shift+click adds or removes one, Fillet/Chamfer dresses them all",
3932 "%zu edges selected — Shift+click adds or removes one, Fillet/Chamfer dresses them all",
3934 : level == 3 ? (bodytag ? wxString::Format(
_L(
"Body %d: edge %d selected — Shift+click to add edges, or click again for the whole body"), body + 1, edge)
3935 : wxString::Format(
_L(
"Edge %d selected — Shift+click to add edges, or click again for the whole body"), edge))
3936 :
_L(
"Nothing selected"));
3938 });
3939
3940
3946 });
3947
3948
3949
3950 m_viewport->set_on_extrude_depth_changed([
this](
double depth,
bool second) {
3951
3952
3953
3967 });
3968
3969
3970
3971
3972 m_viewport->set_on_datum_size_changed([
this](
double u,
double v) {
3980 }
3982 });
3983
3984
3985 m_viewport->set_on_datum_offset_changed([
this](
double off) {
3991 }
3993 });
3994
3995
3996
3997 m_viewport->set_on_helix_changed([
this](
double radius,
double pitch,
double height) {
4003 });
4004
4005
4006 m_viewport->set_on_rib_thickness_changed([
this](
double thickness) {
4009 });
4010
4011
4012
4013 m_viewport->set_on_datum_base_picked([
this](
int base) {
4015
4021 } else {
4022
4023
4024
4025
4026 if (base >= 0) {
4030 }
4033 return;
4034 }
4036
4037
4039 wxString::Format(
_L(
"%s plane selected — right-click to sketch on it, "
4040 "or click an object to select it"), nm));
4042 }
4043 });
4044
4045
4046
4052 });
4053
4054
4055
4056
4059 if (body < 0 || body >=
int(
m_body_xform.size()))
return;
4062
4063
4066 const Vec3d t = d.translation();
4070 const Eigen::AngleAxisd aa(Eigen::Quaterniond(d.linear()).normalized());
4071
4072
4073
4074
4075 int ax = 0; double best = std::abs(aa.axis().x());
4076 if (std::abs(aa.axis().y()) > best) { ax = 1; best = std::abs(aa.axis().y()); }
4077 if (std::abs(aa.axis().z()) > best) { ax = 2; best = std::abs(aa.axis().z()); }
4078 const double sign = (aa.axis()[ax] < 0.0) ? -1.0 : 1.0;
4081 }
4082 const int nb = int(
m_doc.bodies.size());
4083 const Vec3d t = xform.translation();
4085 ? wxString::Format(
_L(
"Body %d placed at (%.1f, %.1f, %.1f) mm — drag arrows to move, rings to rotate"),
4086 body + 1, t.x(), t.y(), t.z())
4087 : wxString::Format(
_L(
"Placed at (%.1f, %.1f, %.1f) mm — drag arrows to move, rings to rotate"),
4088 t.x(), t.y(), t.z()));
4089 });
4090
4091
4092
4093 m_viewport->set_on_fillet_radius_changed([
this](
double radius) {
4096 });
4097
4098
4099
4100 m_viewport->set_on_hole_changed([
this](
double x,
double y,
double diameter,
double depth) {
4106 });
4107
4108
4109
4110 m_viewport->set_on_thread_changed([
this](
double x,
double y,
double radius,
double height) {
4116 });
4117
4118
4119
4120 m_viewport->set_on_shell_thickness_changed([
this](
double thickness) {
4123 });
4124
4128 });
4129
4133 });
4134
4135
4136 m_viewport->set_on_cut_offset_changed([
this](
double v) {
4139 });
4140
4141 m_viewport->set_on_pattern_changed([
this](
double value) {
4142
4147 }
4149 });
4150
4151
4152
4153
4154
4156
4157
4165 });
4166
4167
4168
4169
4170
4171 m_viewport->set_on_sketch_notice([
this](
const std::string& msg,
bool error) {
4173 });
4174 m_viewport->set_on_sketch_exit_refused([
this]() {
4176 });
4177
4178
4179
4180
4181
4182
4183
4184 Bind(wxEVT_CHAR_HOOK, [this](wxKeyEvent& e) {
4185 const int key = e.GetKeyCode();
4186 const bool ctrl = e.ControlDown() || e.CmdDown();
4188
4189
4191
4192
4193 const bool in_text = (dynamic_cast<wxTextCtrl*>(wxWindow::FindFocus()) != nullptr)
4195 if (getenv("ORCA_CAD_KEYTRACE")) {
4196 wxWindow* fw = wxWindow::FindFocus();
4197 fprintf(stderr, "[KEYTRACE] key=%d ui_mode=%d is_sketching=%d in_text=%d inline_busy=%d focus=%s\n",
4200
4201
4202
4203
4204
4205
4206
4207 fw ? wxString(fw->GetClassInfo()->GetClassName()).utf8_str().data() : "(none)");
4208 fflush(stderr);
4209 }
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4224 if (key == WXK_RETURN || key == WXK_NUMPAD_ENTER || key == WXK_TAB) {
4226 return;
4227 }
4228
4229
4230
4231
4232
4233
4234
4235 }
4236
4237
4238
4239
4240
4241
4242
4243
4244 if (key == WXK_ESCAPE) {
escape();
return; }
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254 if (!in_text && !ctrl && (key == WXK_RETURN || key == WXK_NUMPAD_ENTER)) {
4258 }
4260 }
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270 if (!in_text && !ctrl
4271 && (key == WXK_MENU || key == WXK_WINDOWS_MENU || (key == WXK_F10 && e.ShiftDown()))) {
4273 return;
4274 }
4275
4276
4277
4278 if (!in_text && ctrl && (key == 'Z' || key == 'z' || key == WXK_CONTROL_Z ||
4279 key == 'Y' || key == 'y' || key == WXK_CONTROL_Y)) {
4280 const bool redo = (key == 'Y' || key == 'y' || key == WXK_CONTROL_Y) || e.ShiftDown();
4282 return;
4283 }
4284
4285
4286
4287
4288
4289
4290 if (!in_text && (key == WXK_DELETE || (key == WXK_BACK && sketching))) {
4291 if (sketching) {
4292 if (!
m_viewport->delete_selected_sketch_entities())
4294 return;
4295 }
4298 }
4299
4300
4301
4303 if (key == WXK_PAGEUP || key == WXK_PAGEDOWN) {
4306 return;
4307 }
4309 }
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322 const bool inline_field_only = (dynamic_cast<wxTextCtrl*>(wxWindow::FindFocus()) == nullptr)
4324 if (in_text && inline_field_only && sketch_mode && !ctrl) {
4325 const int up2 = (key >= 'a' && key <= 'z') ? key - 'a' + 'A' : key;
4328 }
4329
4330
4331 if (!in_text && ctrl && e.ShiftDown()) {
4332 const int up = (key >=
'a' && key <=
'z') ? key -
'a' +
'A' : key;
4335 }
4336 if (!in_text && !ctrl) {
4337 const int up = (key >=
'a' && key <=
'z') ? key -
'a' +
'A' : key;
4338 if (sketch_mode) {
4341 } else {
4344 }
4345 }
4346 e.Skip();
4347 });
4348
4349
4350
4352
4353
4354
4355
4356
4357
4358
4359 m_viewport->set_on_imported_transform([
this](
int feat,
Vec2d off,
double sx,
double sy) {
4360 if (feat < 0 || feat >=
int(
m_doc.features.size()))
return;
4361 CadFeature&
f =
m_doc.features[feat];
4362 if (
f.imported_regions.empty())
return;
4363 f.import_offset = off;
4364 f.import_scale_x = sx;
4365 f.import_scale_y = sy;
4368 });
4369
4370 auto* vcol = new wxBoxSizer(wxVERTICAL);
4371
4372
4373
4378 {
4380 f.SetWeight(wxFONTWEIGHT_BOLD);
4382 auto* bs = new wxBoxSizer(wxHORIZONTAL);
4385 }
4388
4389
4391 view_col->SetSizer(vcol);
4392
4393
4394
4395
4396 m_aui.init(body_panel);
4398 m_aui.AddPane(view_col, wxAuiPaneInfo().
Name(
"main").CenterPane().PaneBorder(
false));
4402
4403
4405 [this] {
4406 const wxAuiPaneInfo& sidebar =
m_aui.GetPane(
m_form);
4407 if (!sidebar.IsOk() || sidebar.IsFloating())
4410 },
4413
4414 auto* outer = new wxBoxSizer(wxVERTICAL);
4416 outer->Add(new wxStaticLine(this, wxID_ANY), 0, wxEXPAND);
4417 outer->Add(body_panel, 1, wxEXPAND);
4418 SetSizer(outer);
4419
4420
4421
4422
4423
4424
4425
4426 {
4427 std::vector<std::string> dead;
4430 if (v.action == nullptr || *v.action == '\0')
4431 continue;
4432 const std::string a(v.action);
4433 bool ok = false;
4434 if (a.rfind("key:", 0) == 0) {
4435 const std::string k = a.substr(4);
4436 if (k.size() >= 3 && k[0] == 'S' && k[1] == '+') {
4439 } else if (!k.empty()) {
4442 }
4443 } else {
4446 }
4447 if (!ok)
4448 dead.emplace_back(std::string(v.id) + " -> " + a);
4449 }
4450 for (const std::string& d : dead)
4451 BOOST_LOG_TRIVIAL(error) << "Design offer: wired verb has no action: " << d;
4452 assert(dead.empty());
4453 }
4454
4455 m_show_origin = wxGetApp().app_config->get_bool(
"design_show_origin");
4456 m_show_bed = wxGetApp().app_config->get_bool(
"design_show_bed");
4459
4460
4462 build_phase("wiring");
4463 BOOST_LOG_TRIVIAL(info) << "Design tab build: total " << build_clock.Time() << " ms";
4464}
#define L(s)
Definition ExtrusionEntity.cpp:25
#define M_PI
Definition ExtrusionSimulator.cpp:31
#define _L(s)
Definition OBJ.cpp:34
class WXDLLIMPEXP_FWD_CORE wxStaticText
Definition ProgressDialog.hpp:30
int GetSelection() const override
Definition ComboBox.cpp:98
void SetSelection(int n) override
Definition ComboBox.cpp:102
unsigned int GetCount() const override
Definition ComboBox.cpp:311
wxString text
Definition DropDown.hpp:38
wxString tip
Definition DropDown.hpp:47
wxBitmap icon
Definition DropDown.hpp:40
static wxFont Body_9
Definition Label.hpp:58
static wxFont Head_14
Definition Label.hpp:45
static wxFont Head_16
Definition Label.hpp:43
static wxFont Body_12
Definition Label.hpp:55
static wxFont Body_14
Definition Label.hpp:53
static wxAuiPaneInfo sidebar_pane_info()
Definition AuiMgr.cpp:68
ComboBox * m_sweep_path
Definition DesignPanel.hpp:622
bool m_dof_last_has
Definition DesignPanel.hpp:1028
wxSizer * m_box_draft
Definition DesignPanel.hpp:437
CheckBox * m_surf_revolve_flip
Definition DesignPanel.hpp:650
wxSizer * m_tb_relations
Definition DesignPanel.hpp:550
wxSpinCtrlDouble * m_xf_pivot_z
Definition DesignPanel.hpp:681
wxStaticText * m_hole_target_label
Definition DesignPanel.hpp:879
CheckBox * m_surf_thicken_flip
Definition DesignPanel.hpp:670
wxSpinCtrlDouble * m_cs_hx
Definition DesignPanel.hpp:922
StaticBox * m_tree_box
Definition DesignPanel.hpp:413
void sync_recipe_to_model()
Definition DesignPanel.cpp:4911
::Button * m_btn_add_var
Definition DesignPanel.hpp:744
ComboBox * m_mode
Definition DesignPanel.hpp:597
StaticBox * m_cards
Definition DesignPanel.hpp:415
wxSpinCtrlDouble * m_mate_angle
Definition DesignPanel.hpp:726
DesignRowList * m_tree
Definition DesignPanel.hpp:942
wxStaticText * m_hdr_project
Definition DesignPanel.hpp:515
std::vector< int > m_sel_solid_edges
Definition DesignPanel.hpp:803
wxSizer * m_constraint_rows
Definition DesignPanel.hpp:1046
bool m_dof_last_ok
Definition DesignPanel.hpp:1027
StaticBox * m_parts_box
Definition DesignPanel.hpp:414
ScalableButton * m_active_tool_btn
Definition DesignPanel.hpp:556
ComboBox * m_extrude_end
Definition DesignPanel.hpp:602
wxSpinCtrlDouble * m_taper
Definition DesignPanel.hpp:604
wxSpinCtrlDouble * m_surf_offset_distance
Definition DesignPanel.hpp:665
void on_shape_changed()
Definition DesignPanel.cpp:4583
wxSizer * m_box_hole
Definition DesignPanel.hpp:429
wxScrolledWindow * m_toolbar
Definition DesignPanel.hpp:545
ComboBox * m_rib_sketch
Definition DesignPanel.hpp:697
CoordSysPick m_coordsys_pick
Definition DesignPanel.hpp:925
void refresh_plane_labels()
Definition DesignPanel.cpp:7011
double m_section_cut_z
Definition DesignPanel.hpp:974
wxStaticText * m_axis_edge_lbl
Definition DesignPanel.hpp:907
wxString ref_plane_name(int row) const
Definition DesignPanel.cpp:6158
wxCheckBox * m_construction
Definition DesignPanel.hpp:564
wxString m_sketch_on
Definition DesignPanel.hpp:813
void refresh_pinned()
Definition DesignPanel.cpp:11269
int m_ref_plane
Definition DesignPanel.hpp:580
AxisPick
Definition DesignPanel.hpp:126
@ None
Definition DesignPanel.hpp:126
@ Face
Definition DesignPanel.hpp:126
@ Edge
Definition DesignPanel.hpp:126
wxSpinCtrlDouble * m_axis_p2x
Definition DesignPanel.hpp:911
void apply_thread_standard()
Definition DesignPanel.cpp:5417
wxStaticText * m_hdr_coordsys
Definition DesignPanel.hpp:504
void on_delete_body()
Definition DesignPanel.cpp:8215
void on_edit_variable()
Definition DesignPanel.cpp:12387
int m_cs_face
Definition DesignPanel.hpp:923
wxStaticText * m_angle_label
Definition DesignPanel.hpp:729
double m_hole_umax
Definition DesignPanel.hpp:875
CheckBox * m_helix_left_handed
Definition DesignPanel.hpp:718
wxSpinCtrlDouble * m_xf_dz
Definition DesignPanel.hpp:676
int m_surf_revolve_sketch_ref
Definition DesignPanel.hpp:651
void on_toggle_visibility()
Definition DesignPanel.cpp:8256
wxSizer * m_box_helix
Definition DesignPanel.hpp:454
int m_extrude_sketch_ref
Definition DesignPanel.hpp:608
wxStaticText * m_hdr_mate
Definition DesignPanel.hpp:518
void set_hole_target_label(int face)
Definition DesignPanel.cpp:5356
wxStaticText * m_hdr_move
Definition DesignPanel.hpp:483
@ Feature
Definition DesignPanel.hpp:132
@ Sketch
Definition DesignPanel.hpp:132
@ Constrain
Definition DesignPanel.hpp:132
wxSpinCtrlDouble * m_xf_pivot_y
Definition DesignPanel.hpp:680
ComboBox * m_loft_mode
Definition DesignPanel.hpp:630
bool place_on_face()
Definition DesignPanel.cpp:8059
void arm_axis_pick(AxisPick target)
Definition DesignPanel.cpp:7073
wxSizer * m_box_mate
Definition DesignPanel.hpp:455
@ Info
Definition DesignPanel.hpp:825
@ Error
Definition DesignPanel.hpp:825
@ Ok
Definition DesignPanel.hpp:825
wxSizer * m_box_move
Definition DesignPanel.hpp:425
ComboBox * m_del_face_body
Definition DesignPanel.hpp:708
wxTextCtrl * m_value_input
Definition DesignPanel.hpp:930
wxStaticText * m_hdr_surf_thicken
Definition DesignPanel.hpp:510
ComboBox * m_proj_source_body
Definition DesignPanel.hpp:703
int m_dof_last
Definition DesignPanel.hpp:1026
wxStaticText * m_offset_label
Definition DesignPanel.hpp:728
wxSpinCtrlDouble * m_plane_vsize
Definition DesignPanel.hpp:789
wxSpinCtrlDouble * m_mate_offset
Definition DesignPanel.hpp:725
wxSizer * m_box_surf_fill
Definition DesignPanel.hpp:445
int m_sel_solid_face
Definition DesignPanel.hpp:798
wxSizer * m_box_sketch_session
Definition DesignPanel.hpp:487
wxSpinCtrlDouble * m_distance
Definition DesignPanel.hpp:601
std::vector< int > m_loft_sketch_idx
Definition DesignPanel.hpp:631
void on_edit_feature()
Definition DesignPanel.cpp:9959
ComboBox * m_rib_body
Definition DesignPanel.hpp:696
ComboBox * m_cs_body
Definition DesignPanel.hpp:918
wxStaticText * m_hdr_constraints
Definition DesignPanel.hpp:1045
std::string feature_name(const wxString &kind) const
Definition DesignPanel.cpp:5259
wxSpinCtrlDouble * m_height
Definition DesignPanel.hpp:599
void update_fillet_gizmo()
Definition DesignPanel.cpp:10633
wxSizer * m_box_surf_extrude
Definition DesignPanel.hpp:442
ComboBox * m_hole_plane
Definition DesignPanel.hpp:860
wxSizer * m_box_delete_face
Definition DesignPanel.hpp:453
bool m_section_on
Definition DesignPanel.hpp:973
ComboBox * m_xf_axis
Definition DesignPanel.hpp:677
ComboBox * m_pattern_dir
Definition DesignPanel.hpp:759
void reset_plane_refs()
Definition DesignPanel.cpp:7020
static constexpr int SC_SHIFT
Definition DesignPanel.hpp:405
::Button * m_btn_interfere
Definition DesignPanel.hpp:753
wxStaticText * m_hdr_surf_fill
Definition DesignPanel.hpp:508
ComboBox * m_move_axis
Definition DesignPanel.hpp:568
std::vector< std::function< void()> > m_icon_refresh
Definition DesignPanel.hpp:562
void zoom_to_body(int b)
Definition DesignPanel.cpp:7887
wxSpinCtrlDouble * m_helix_pitch
Definition DesignPanel.hpp:716
wxStaticText * m_plane_edgeB_lbl
Definition DesignPanel.hpp:787
int m_ax_face
Definition DesignPanel.hpp:912
CheckBox * m_loft_ruled
Definition DesignPanel.hpp:629
ComboBox * m_face_group
Definition DesignPanel.hpp:856
void request_feature_highlight()
Definition DesignPanel.cpp:7790
CheckBox * m_thicken_flip
Definition DesignPanel.hpp:693
wxStaticText * m_del_face_list
Definition DesignPanel.hpp:710
wxSizer * m_box_constraints
Definition DesignPanel.hpp:1044
AxisPick m_axis_pick
Definition DesignPanel.hpp:914
void rebuild_constraint_list()
Definition DesignPanel.cpp:8674
wxSpinCtrlDouble * m_thread_height
Definition DesignPanel.hpp:885
ComboBox * m_mate_cs_b
Definition DesignPanel.hpp:724
void tool_cancel()
Definition DesignPanel.cpp:12053
wxStaticText * m_hdr_revolve
Definition DesignPanel.hpp:495
ComboBox * m_bool_op
Definition DesignPanel.hpp:762
wxStaticText * m_expr_status
Definition DesignPanel.hpp:736
wxSizer * m_box_revolve
Definition DesignPanel.hpp:432
wxSizer * m_box_surf_revolve
Definition DesignPanel.hpp:443
wxSizer * m_box_surf_loft
Definition DesignPanel.hpp:444
wxCheckListBox * m_surf_loft_list
Definition DesignPanel.hpp:654
bool m_sidebar_collapsed
Definition DesignPanel.hpp:529
wxSpinCtrlDouble * m_axis_p1x
Definition DesignPanel.hpp:910
wxStaticText * m_hdr_mirror
Definition DesignPanel.hpp:512
wxSpinCtrlDouble * m_plane_tilt
Definition DesignPanel.hpp:780
CommitMode m_commit_mode
Definition DesignPanel.hpp:421
int m_hole_face_body
Definition DesignPanel.hpp:871
ComboBox * m_surf_revolve_axis
Definition DesignPanel.hpp:642
wxSpinCtrlDouble * m_thicken_thickness
Definition DesignPanel.hpp:692
wxSpinCtrlDouble * m_distance2
Definition DesignPanel.hpp:603
ComboBox * m_plane_base
Definition DesignPanel.hpp:778
bool m_sel_solid_vertex
Definition DesignPanel.hpp:804
void on_commit()
Definition DesignPanel.cpp:10219
CheckBox * m_thread_internal
Definition DesignPanel.hpp:887
wxStaticText * m_dressup_edge_label
Definition DesignPanel.hpp:858
std::map< std::string, std::function< void()> > m_verb_actions
Definition DesignPanel.hpp:819
void start_sketch_on_target(bool offer_tools)
Definition DesignPanel.cpp:11304
double m_hole_vmax
Definition DesignPanel.hpp:875
wxSizer * m_box_coordsys
Definition DesignPanel.hpp:441
int m_pl_edgeB
Definition DesignPanel.hpp:794
int m_poly_sides
Definition DesignPanel.hpp:574
wxStaticText * m_hdr_surf_offset
Definition DesignPanel.hpp:509
void update_body_gates()
Definition DesignPanel.cpp:10661
void toggle_origin()
Definition DesignPanel.cpp:11248
wxStaticText * m_hdr_loft
Definition DesignPanel.hpp:499
wxSpinCtrlDouble * m_helix_height
Definition DesignPanel.hpp:717
ComboBox * m_surf_thicken_body
Definition DesignPanel.hpp:668
wxSizer * m_box_insert
Definition DesignPanel.hpp:456
wxBoxSizer * m_parts_hdr
Definition DesignPanel.hpp:962
void feed_bodies()
Definition DesignPanel.cpp:7772
void refresh_axis_labels()
Definition DesignPanel.cpp:7057
std::map< int, std::function< void()> > m_keys_sketch
Definition DesignPanel.hpp:410
void refresh_preview()
Definition DesignPanel.cpp:11387
ComboBox * m_revolve_mode
Definition DesignPanel.hpp:616
void on_add_text()
Definition DesignPanel.cpp:4695
int m_ax_face_body
Definition DesignPanel.hpp:912
double m_hole_umin
Definition DesignPanel.hpp:875
int m_pl_edgeB_body
Definition DesignPanel.hpp:794
wxStaticText * m_sketch_hint
Definition DesignPanel.hpp:489
ComboBox * m_mate_kind
Definition DesignPanel.hpp:722
void push_polygon_params()
Definition DesignPanel.cpp:11595
wxSpinCtrlDouble * m_move_dz
Definition DesignPanel.hpp:567
void reset_coordsys_refs()
Definition DesignPanel.cpp:7124
ComboBox * m_bool_target
Definition DesignPanel.hpp:763
wxStaticText * m_sweep_profile_label
Definition DesignPanel.hpp:621
wxStaticText * m_hdr_transform
Definition DesignPanel.hpp:511
ComboBox * m_revolve_axis
Definition DesignPanel.hpp:614
DesignRowList * m_parts
Definition DesignPanel.hpp:960
int m_feature_counter
Definition DesignPanel.hpp:1029
wxSizer * m_box_transform
Definition DesignPanel.hpp:448
void on_transform_imported(int feat_idx)
Definition DesignPanel.cpp:5215
ComboBox * m_shape
Definition DesignPanel.hpp:596
int m_pl_faceB
Definition DesignPanel.hpp:792
wxSpinCtrlDouble * m_surf_thicken_thickness
Definition DesignPanel.hpp:669
void escape()
Definition DesignPanel.cpp:12141
wxSpinCtrlDouble * m_dressup_size
Definition DesignPanel.hpp:857
CoordSysPick
Definition DesignPanel.hpp:127
@ None
Definition DesignPanel.hpp:127
@ Face
Definition DesignPanel.hpp:127
@ Edge
Definition DesignPanel.hpp:127
wxStaticText * m_plane_faceB_lbl
Definition DesignPanel.hpp:785
bool m_hole_has_bounds
Definition DesignPanel.hpp:874
void refresh_datum_planes()
Definition DesignPanel.cpp:11063
std::vector< int > m_surf_revolve_axis_ents
Definition DesignPanel.hpp:643
wxSpinCtrlDouble * m_draft_angle
Definition DesignPanel.hpp:901
bool can_zoom_to_feature(int f) const
Definition DesignPanel.cpp:7838
wxSizer * m_box_plane
Definition DesignPanel.hpp:435
wxStaticText * m_sketch_banner_txt
Definition DesignPanel.hpp:544
wxSpinCtrlDouble * m_revolve_angle
Definition DesignPanel.hpp:613
wxSpinCtrlDouble * m_helix_taper
Definition DesignPanel.hpp:719
void sync_body_xform()
Definition DesignPanel.cpp:7735
void on_export_step()
Definition DesignPanel.cpp:10183
::Button * m_axis_pick_face
Definition DesignPanel.hpp:906
PlanePick m_plane_pick
Definition DesignPanel.hpp:795
ComboBox * m_proj_plane
Definition DesignPanel.hpp:705
::Button * m_plane_pick_faceB
Definition DesignPanel.hpp:785
ScalableButton * m_section_flip_btn
Definition DesignPanel.hpp:976
int selected_body_default() const
Definition DesignPanel.cpp:6047
void finalize_insert()
Definition DesignPanel.cpp:5189
int m_pick_face_body
Definition DesignPanel.hpp:809
wxSpinCtrlDouble * m_radius
Definition DesignPanel.hpp:600
std::vector< int > m_del_faces
Definition DesignPanel.hpp:711
int m_pl_edgeA_body
Definition DesignPanel.hpp:793
ScalableButton * m_commit_btn
Definition DesignPanel.hpp:422
wxSizer * m_box_thicken
Definition DesignPanel.hpp:450
wxStaticText * m_value_label
Definition DesignPanel.hpp:929
int m_bool_next_slot
Definition DesignPanel.hpp:768
::Button * m_axis_pick_edge
Definition DesignPanel.hpp:907
wxSizer * m_box_surf_thicken
Definition DesignPanel.hpp:447
wxSpinCtrlDouble * m_cs_hy
Definition DesignPanel.hpp:922
wxSpinCtrlDouble * m_thread_pitch
Definition DesignPanel.hpp:884
CheckBox * m_flip
Definition DesignPanel.hpp:605
wxPoint offer_anchor() const
Definition DesignPanel.cpp:6341
DropDown * m_commit_drop
Definition DesignPanel.hpp:423
wxSpinCtrlDouble * m_surf_revolve_angle
Definition DesignPanel.hpp:641
::Button * m_expr_set_btn
Definition DesignPanel.hpp:734
int resolve_extrude_sketch() const
Definition DesignPanel.cpp:9618
wxSizer * m_tb_commit
Definition DesignPanel.hpp:420
ComboBox * m_mate_cs_a
Definition DesignPanel.hpp:723
std::vector< int > m_loft_refs
Definition DesignPanel.hpp:632
ComboBox * m_thread_plane
Definition DesignPanel.hpp:881
void on_import_svg()
Definition DesignPanel.cpp:4834
static constexpr int SC_CTRL
Definition DesignPanel.hpp:409
wxSizer * m_tb_feature
Definition DesignPanel.hpp:546
void on_move_body()
Definition DesignPanel.cpp:7927
int m_sel_solid_edge
Definition DesignPanel.hpp:799
wxSizer * m_box_value
Definition DesignPanel.hpp:928
void tool_confirm()
Definition DesignPanel.cpp:12024
ComboBox * m_sweep_mode
Definition DesignPanel.hpp:623
wxStaticText * m_revolve_sketch_label
Definition DesignPanel.hpp:612
wxStaticText * m_plane_faceA_lbl
Definition DesignPanel.hpp:784
void reset_axis_refs()
Definition DesignPanel.cpp:7064
::Button * m_plane_pick_edgeB
Definition DesignPanel.hpp:787
wxSizer * m_box_extrude
Definition DesignPanel.hpp:427
wxSizer * m_box_pattern
Definition DesignPanel.hpp:434
wxStaticText * m_cs_edge_lbl
Definition DesignPanel.hpp:921
void sync_sketch_display()
Definition DesignPanel.cpp:4614
bool m_show_bed
Definition DesignPanel.hpp:595
wxSpinCtrlDouble * m_thread_depth
Definition DesignPanel.hpp:886
wxSpinCtrlDouble * m_cut_offset
Definition DesignPanel.hpp:776
wxSpinCtrlDouble * m_hole_depth
Definition DesignPanel.hpp:862
void toggle_bed()
Definition DesignPanel.cpp:11259
wxSizer * m_box_surf_offset
Definition DesignPanel.hpp:446
ComboBox * m_axis_type
Definition DesignPanel.hpp:905
wxSpinCtrlDouble * m_plane_usize
Definition DesignPanel.hpp:788
@ Plane
Definition DesignPanel.hpp:118
@ Mirror
Definition DesignPanel.hpp:118
@ Boolean
Definition DesignPanel.hpp:118
@ Transform
Definition DesignPanel.hpp:118
@ Rib
Definition DesignPanel.hpp:118
@ SurfaceOffset
Definition DesignPanel.hpp:118
@ Axis
Definition DesignPanel.hpp:118
@ DeleteFace
Definition DesignPanel.hpp:118
@ Pattern
Definition DesignPanel.hpp:118
@ Hole
Definition DesignPanel.hpp:118
@ None
Definition DesignPanel.hpp:118
@ SurfaceFill
Definition DesignPanel.hpp:118
@ SurfaceLoft
Definition DesignPanel.hpp:118
@ Helix
Definition DesignPanel.hpp:118
@ Sweep
Definition DesignPanel.hpp:118
@ Thicken
Definition DesignPanel.hpp:118
@ Revolve
Definition DesignPanel.hpp:118
@ Project
Definition DesignPanel.hpp:118
@ Mate
Definition DesignPanel.hpp:118
@ Insert
Definition DesignPanel.hpp:118
@ SurfaceExtrude
Definition DesignPanel.hpp:118
@ Loft
Definition DesignPanel.hpp:118
@ CoordSys
Definition DesignPanel.hpp:118
@ Thread
Definition DesignPanel.hpp:118
@ SurfaceRevolve
Definition DesignPanel.hpp:118
@ Dressup
Definition DesignPanel.hpp:118
@ Shell
Definition DesignPanel.hpp:118
@ Cut
Definition DesignPanel.hpp:118
@ Draft
Definition DesignPanel.hpp:118
@ Extrude
Definition DesignPanel.hpp:118
@ ThickenSurface
Definition DesignPanel.hpp:118
std::vector< BodyGate > m_body_gates
Definition DesignPanel.hpp:372
ComboBox * m_mirror_plane
Definition DesignPanel.hpp:686
wxStaticText * m_thicken_face_label
Definition DesignPanel.hpp:691
int m_pl_faceA_body
Definition DesignPanel.hpp:791
std::map< int, std::function< void()> > m_keys_feature
Definition DesignPanel.hpp:411
wxSpinCtrlDouble * m_shell_thickness
Definition DesignPanel.hpp:897
ComboBox * m_cut_target
Definition DesignPanel.hpp:775
SketchPlane m_thread_face_plane
Definition DesignPanel.hpp:893
ComboBox * m_coordsys_type
Definition DesignPanel.hpp:917
wxSpinCtrlDouble * m_xf_dy
Definition DesignPanel.hpp:675
::Button * m_cs_pick_face
Definition DesignPanel.hpp:920
wxStaticText * m_hdr_plane
Definition DesignPanel.hpp:498
int m_surf_extrude_sketch_ref
Definition DesignPanel.hpp:637
wxStaticText * m_hdr_draft
Definition DesignPanel.hpp:500
ComboBox * m_dressup_type
Definition DesignPanel.hpp:855
int m_sweep_profile_ref
Definition DesignPanel.hpp:624
bool m_section_upper
Definition DesignPanel.hpp:975
ComboBox * m_thicken_body
Definition DesignPanel.hpp:690
wxSpinCtrlDouble * m_axis_p1y
Definition DesignPanel.hpp:910
::Button * m_btn_del_var
Definition DesignPanel.hpp:746
ComboBox * m_bool_tool
Definition DesignPanel.hpp:764
wxStaticText * m_proj_face_label
Definition DesignPanel.hpp:704
void set_tree_selection(int row)
Definition DesignPanel.cpp:8095
void set_commit_mode(CommitMode mode)
Definition DesignPanel.cpp:10206
wxTextCtrl * m_expr_text
Definition DesignPanel.hpp:733
DesignRowList * m_pinned
Definition DesignPanel.hpp:941
wxSpinCtrlDouble * m_bool_tol
Definition DesignPanel.hpp:770
int m_xf_gizmo_body
Definition DesignPanel.hpp:474
void arm_coordsys_pick(CoordSysPick target)
Definition DesignPanel.cpp:7136
@ Bodies
Definition DesignPanel.hpp:246
@ Assembly
Definition DesignPanel.hpp:246
PlanePick
Definition DesignPanel.hpp:125
@ EdgeB
Definition DesignPanel.hpp:125
@ EdgeA
Definition DesignPanel.hpp:125
@ None
Definition DesignPanel.hpp:125
@ FaceB
Definition DesignPanel.hpp:125
@ FaceA
Definition DesignPanel.hpp:125
wxSpinCtrlDouble * m_surf_extrude_distance
Definition DesignPanel.hpp:636
wxSizer * m_box_cut
Definition DesignPanel.hpp:439
wxSizer * m_box_mirror
Definition DesignPanel.hpp:449
ComboBox * m_surf_offset_body
Definition DesignPanel.hpp:664
wxSpinCtrlDouble * m_cs_hz
Definition DesignPanel.hpp:922
void on_import_step()
Definition DesignPanel.cpp:4946
wxSizer * m_box_shell
Definition DesignPanel.hpp:431
void on_clear_expr()
Definition DesignPanel.cpp:12544
AuiMgr m_aui
Definition DesignPanel.hpp:527
void on_set_body_color()
Definition DesignPanel.cpp:8026
wxStaticText * m_draft_face_label
Definition DesignPanel.hpp:902
void open_tool(Tool t)
Definition DesignPanel.cpp:11602
wxSpinCtrlDouble * m_rib_depth
Definition DesignPanel.hpp:700
std::vector< Transform3d > m_body_xform
Definition DesignPanel.hpp:987
wxSizer * m_tb_sketch
Definition DesignPanel.hpp:547
void refresh_tree()
Definition DesignPanel.cpp:7552
wxStaticText * m_hdr_pattern
Definition DesignPanel.hpp:497
wxSpinCtrlDouble * m_pattern_angle
Definition DesignPanel.hpp:760
wxStaticText * m_surf_fill_sketch_label
Definition DesignPanel.hpp:660
wxSpinCtrlDouble * m_move_angle
Definition DesignPanel.hpp:569
void update_helix_gizmo()
Definition DesignPanel.cpp:11178
void arm_plane_pick(PlanePick target)
Definition DesignPanel.cpp:7029
wxSpinCtrlDouble * m_move_dx
Definition DesignPanel.hpp:565
::Button * m_plane_pick_edgeA
Definition DesignPanel.hpp:786
wxStaticText * m_hdr_dressup
Definition DesignPanel.hpp:491
int tree_selection() const
Definition DesignPanel.cpp:8090
wxSpinCtrlDouble * m_cs_z
Definition DesignPanel.hpp:919
const std::string * mate_conflict_reason(int feature) const
Definition DesignPanel.cpp:7300
void on_sketch_step(int mode, int step, int picks)
Definition DesignPanel.cpp:6590
wxSizer * m_box_axis
Definition DesignPanel.hpp:440
void drop_solid_pick()
Definition DesignPanel.cpp:8111
void on_remove_variable()
Definition DesignPanel.cpp:12415
wxStaticText * m_dof_status
Definition DesignPanel.hpp:1024
wxSpinCtrlDouble * m_axis_p2y
Definition DesignPanel.hpp:911
void on_import_mesh()
Definition DesignPanel.cpp:5007
int m_pl_edgeA
Definition DesignPanel.hpp:793
wxSpinCtrl * m_rib_entity
Definition DesignPanel.hpp:698
wxSizer * m_tb_action
Definition DesignPanel.hpp:553
wxSizer * m_box_project
Definition DesignPanel.hpp:452
int m_pl_faceB_body
Definition DesignPanel.hpp:792
wxSizer * m_box_thread
Definition DesignPanel.hpp:430
bool m_hole_on_face
Definition DesignPanel.hpp:869
int m_pick_face
Definition DesignPanel.hpp:810
wxSpinCtrlDouble * m_hole_diameter
Definition DesignPanel.hpp:861
wxStaticText * m_hdr_thread
Definition DesignPanel.hpp:493
wxScrolledWindow * m_form
Definition DesignPanel.hpp:521
wxSpinCtrlDouble * m_xf_angle
Definition DesignPanel.hpp:678
ComboBox * m_xf_body
Definition DesignPanel.hpp:673
wxStaticText * m_axis_face_lbl
Definition DesignPanel.hpp:906
void on_set_expr()
Definition DesignPanel.cpp:12499
CheckBox * m_mate_flip
Definition DesignPanel.hpp:727
wxStaticText * m_hdr_surf_extrude
Definition DesignPanel.hpp:505
wxSpinCtrlDouble * m_rib_thickness
Definition DesignPanel.hpp:699
void sync_dressup_target()
Definition DesignPanel.cpp:10621
wxSpinCtrlDouble * m_thread_radius
Definition DesignPanel.hpp:883
CheckBox * m_xf_copy
Definition DesignPanel.hpp:682
wxStaticText * m_thread_target_label
Definition DesignPanel.hpp:895
wxPanel * m_sketch_banner
Definition DesignPanel.hpp:543
void set_status(StatusKind kind, const wxString &text)
Definition DesignPanel.cpp:6393
void zoom_to_selection()
Definition DesignPanel.cpp:7900
void apply_move_card()
Definition DesignPanel.cpp:11558
wxSpinCtrlDouble * m_plane_offset
Definition DesignPanel.hpp:779
std::vector< ScalableButton * > m_tool_btns
Definition DesignPanel.hpp:555
wxStaticText * m_cs_face_lbl
Definition DesignPanel.hpp:920
void show_offer_menu(const wxPoint &screen_pos)
Definition DesignPanel.cpp:6677
wxStaticText * m_hdr_extrude
Definition DesignPanel.hpp:490
std::vector< std::shared_ptr< void > > m_flyout_keepalive
Definition DesignPanel.hpp:559
void refresh_coordsys_labels()
Definition DesignPanel.cpp:7093
int m_pl_faceA
Definition DesignPanel.hpp:791
wxSizer * m_box_sweep
Definition DesignPanel.hpp:433
int m_surf_fill_sketch_ref
Definition DesignPanel.hpp:661
void toggle_section_view()
Definition DesignPanel.cpp:7701
ComboBox * m_helix_plane
Definition DesignPanel.hpp:714
wxStaticText * m_surf_revolve_sketch_label
Definition DesignPanel.hpp:640
void fill_revolve_axes(ComboBox *combo, std::vector< int > &ents, int sketch_ref, int axis, int entity)
Definition DesignPanel.cpp:10722
wxStaticText * m_parts_label
Definition DesignPanel.hpp:961
wxSizer * m_box_sketch
Definition DesignPanel.hpp:426
wxListCtrl * m_var_list
Definition DesignPanel.hpp:743
wxStaticText * m_plane_edgeA_lbl
Definition DesignPanel.hpp:786
bool m_plane_picked
Definition DesignPanel.hpp:584
wxStaticText * m_hdr_helix
Definition DesignPanel.hpp:517
wxSpinCtrlDouble * m_thread_x
Definition DesignPanel.hpp:888
wxSpinCtrlDouble * m_cs_x
Definition DesignPanel.hpp:919
wxStaticText * m_hdr_hole
Definition DesignPanel.hpp:492
wxStaticLine * m_parts_rule
Definition DesignPanel.hpp:963
ComboBox * m_expr_field
Definition DesignPanel.hpp:732
wxSpinCtrlDouble * m_helix_radius
Definition DesignPanel.hpp:715
int m_sweep_path_ref
Definition DesignPanel.hpp:625
bool drop_plane_pick()
Definition DesignPanel.cpp:7688
wxSizer * m_box_rib
Definition DesignPanel.hpp:451
wxCheckListBox * m_loft_list
Definition DesignPanel.hpp:628
wxSpinCtrlDouble * m_cs_y
Definition DesignPanel.hpp:919
wxStaticText * m_hdr_shell
Definition DesignPanel.hpp:494
::Button * m_btn_edit_var
Definition DesignPanel.hpp:745
wxSpinCtrlDouble * m_xf_dx
Definition DesignPanel.hpp:674
UiMode m_ui_mode
Definition DesignPanel.hpp:537
SketchPlane m_hole_face_plane
Definition DesignPanel.hpp:870
void update_undo_redo_buttons()
Definition DesignPanel.cpp:12211
void on_add_variable()
Definition DesignPanel.cpp:12362
wxSizer * m_box_expr
Definition DesignPanel.hpp:457
int m_cs_edge
Definition DesignPanel.hpp:924
Transform3d m_xf_gizmo_base
Definition DesignPanel.hpp:475
bool m_poly_circumscribed
Definition DesignPanel.hpp:575
wxStaticText * m_hdr_delete_face
Definition DesignPanel.hpp:516
ComboBox * m_mirror_body
Definition DesignPanel.hpp:685
void populate_body_choices(int as_of_feature=-1)
Definition DesignPanel.cpp:6054
ComboBox * m_axis_plane_b
Definition DesignPanel.hpp:909
wxSpinCtrlDouble * m_axis_p1z
Definition DesignPanel.hpp:910
ComboBox * m_plane_tilt_axis
Definition DesignPanel.hpp:781
ComboBox * m_axis_plane_a
Definition DesignPanel.hpp:908
wxSpinCtrlDouble * m_hole_y
Definition DesignPanel.hpp:865
void on_delete_feature()
Definition DesignPanel.cpp:8239
wxStaticText * m_hdr_thicken
Definition DesignPanel.hpp:513
wxStaticText * m_hdr_surf_revolve
Definition DesignPanel.hpp:506
void on_mass_properties()
Definition DesignPanel.cpp:5958
wxSpinCtrlDouble * m_hole_x
Definition DesignPanel.hpp:864
wxStaticText * m_hdr_cut
Definition DesignPanel.hpp:502
::Button * m_del_face_add_btn
Definition DesignPanel.hpp:709
void apply_dof_status(int dof, bool ok, bool has_constraints)
Definition DesignPanel.cpp:4481
wxStaticText * m_shell_face_label
Definition DesignPanel.hpp:898
CheckBox * m_mirror_keep
Definition DesignPanel.hpp:687
wxStaticText * m_hdr_sketch
Definition DesignPanel.hpp:484
std::vector< int > m_surf_loft_refs
Definition DesignPanel.hpp:657
void on_begin_constrain(int sel_override=-1)
Definition DesignPanel.cpp:8362
int m_revolve_sketch_ref
Definition DesignPanel.hpp:618
wxStaticText * m_hdr_tree
Definition DesignPanel.hpp:965
void load_window_layout()
Definition DesignPanel.cpp:7473
wxStaticText * m_surf_extrude_sketch_label
Definition DesignPanel.hpp:635
void do_undo_redo(bool redo)
Definition DesignPanel.cpp:12253
ComboBox * m_cut_plane
Definition DesignPanel.hpp:774
wxStaticText * m_status
Definition DesignPanel.hpp:1012
std::vector< int > m_revolve_axis_ents
Definition DesignPanel.hpp:615
int m_thread_face_body
Definition DesignPanel.hpp:894
bool m_thread_on_face
Definition DesignPanel.hpp:892
void on_move_feature(int delta)
Definition DesignPanel.cpp:8323
StaticBox * m_var_box
Definition DesignPanel.hpp:742
wxSizer * m_box_loft
Definition DesignPanel.hpp:436
wxSpinCtrlDouble * m_pattern_spacing
Definition DesignPanel.hpp:758
wxSizer * m_box_boolean
Definition DesignPanel.hpp:438
void set_thread_target_label(int face, int edge)
Definition DesignPanel.cpp:5364
wxStaticText * m_hdr_surf_loft
Definition DesignPanel.hpp:507
int m_cs_face_body
Definition DesignPanel.hpp:923
void on_boolean_tool()
Definition DesignPanel.cpp:7917
wxStaticText * m_hdr_sweep
Definition DesignPanel.hpp:496
void confirm_value()
Definition DesignPanel.cpp:9522
bool deselect_rows()
Definition DesignPanel.cpp:7678
wxStaticText * m_hdr_sketch_session
Definition DesignPanel.hpp:488
int m_sel_solid_body
Definition DesignPanel.hpp:797
wxSpinCtrlDouble * m_xf_pivot_x
Definition DesignPanel.hpp:679
CheckBox * m_bool_keep
Definition DesignPanel.hpp:769
ComboBox * m_plane_type
Definition DesignPanel.hpp:783
double m_hole_vmin
Definition DesignPanel.hpp:875
ComboBox * m_pattern_type
Definition DesignPanel.hpp:756
ComboBox * m_thread_std
Definition DesignPanel.hpp:882
wxString m_sketch_step
Definition DesignPanel.hpp:1020
void update_hole_gizmo()
Definition DesignPanel.cpp:10673
int m_edit_index
Definition DesignPanel.hpp:1038
wxSpinCtrlDouble * m_width
Definition DesignPanel.hpp:598
CheckBox * m_surf_loft_ruled
Definition DesignPanel.hpp:655
void populate_plane_choices(ComboBox *c) const
Definition DesignPanel.cpp:6147
Tool m_active
Definition DesignPanel.hpp:399
bool enter_constrain_inline()
Definition DesignPanel.cpp:8345
void start_sketch()
Definition DesignPanel.cpp:11284
wxString m_default_layout
Definition DesignPanel.hpp:528
wxSpinCtrlDouble * m_pattern_count
Definition DesignPanel.hpp:757
bool confirm_enabled() const
Definition DesignPanel.cpp:12099
void set_active_tool_btn(ScalableButton *b)
Definition DesignPanel.cpp:4466
void refresh_parts()
Definition DesignPanel.cpp:7619
void on_check_interference()
Definition DesignPanel.cpp:5924
void apply_constraint(SketchConstraintType type)
Definition DesignPanel.cpp:9554
wxBoxSizer * m_hdr_tree_row
Definition DesignPanel.hpp:964
void on_new_design()
Definition DesignPanel.cpp:8179
wxSpinCtrlDouble * m_thread_y
Definition DesignPanel.hpp:889
wxSpinCtrlDouble * m_move_dy
Definition DesignPanel.hpp:566
bool sketch_plane_pick_live() const
Definition DesignPanel.cpp:11343
int m_extrude_face_src
Definition DesignPanel.hpp:853
::Button * m_plane_pick_faceA
Definition DesignPanel.hpp:784
wxStaticText * m_hdr_boolean
Definition DesignPanel.hpp:501
void zoom_to_feature(int f)
Definition DesignPanel.cpp:7846
wxStaticText * m_hdr_axis
Definition DesignPanel.hpp:503
wxStaticText * m_hdr_insert
Definition DesignPanel.hpp:519
void collapse_sidebar(bool collapse)
Definition DesignPanel.cpp:7505
bool sketch_plane_target(wxString &what) const
Definition DesignPanel.cpp:6213
int tree_body_selection() const
Definition DesignPanel.cpp:7671
DesignCanvas * m_viewport
Definition DesignPanel.hpp:522
void set_ui_mode(UiMode m)
Definition DesignPanel.cpp:4503
void infer_thread_spec(double diameter, bool internal)
Definition DesignPanel.cpp:5440
wxSizer * m_tb_doc
Definition DesignPanel.hpp:424
void flip_section_view()
Definition DesignPanel.cpp:7719
CadDocument m_doc
Definition DesignPanel.hpp:397
bool m_show_origin
Definition DesignPanel.hpp:592
wxSizer * m_box_dressup
Definition DesignPanel.hpp:428
wxStaticText * m_extrude_sketch_label
Definition DesignPanel.hpp:607
wxSpinCtrlDouble * m_axis_p2z
Definition DesignPanel.hpp:911
::Button * m_cs_pick_edge
Definition DesignPanel.hpp:921
int m_ax_edge
Definition DesignPanel.hpp:913
CheckBox * m_revolve_flip
Definition DesignPanel.hpp:617
std::vector<::Button * > m_confirm_btns
Definition DesignPanel.hpp:1031
void populate_sheet_body_choices(ComboBox *c) const
Definition DesignPanel.cpp:5989
::Button * m_expr_clear_btn
Definition DesignPanel.hpp:735
wxStaticText * m_hdr_rib
Definition DesignPanel.hpp:514
CheckBox * m_hole_through
Definition DesignPanel.hpp:863
static TopoDS_Face face_by_index(const TopoDS_Shape &shape, int index)
Definition GeometryEngine.cpp:534
static TopoDS_Edge edge_by_index(const TopoDS_Shape &shape, int index)
Definition GeometryEngine.cpp:717
static CylinderFace circle_of_edge(const TopoDS_Edge &edge)
Definition GeometryEngine.cpp:675
static bool face_plane_bounds(const TopoDS_Face &face, const Vec3d &origin, const Vec3d &x_axis, const Vec3d &y_axis, double &umin, double &umax, double &vmin, double &vmax)
Definition GeometryEngine.cpp:692
static CylinderFace cylinder_of_face(const TopoDS_Face &face)
Definition GeometryEngine.cpp:639
constexpr int SHIFT
Definition Shortcuts.cpp:30
::Button * sidebar_icon_btn(wxWindow *parent, const char *icon, const wxString &tip, int px=20)
Definition DesignPanel.cpp:257
static wxWindow * spin_frame(wxWindow *spin)
Definition DesignPanel.cpp:343
static ComboBox * make_combo(wxWindow *parent)
Definition DesignPanel.cpp:142
wxMouseEvent
Definition CameraPopup.cpp:47
static wxFlexGridSizer * two_col_form()
Definition DesignPanel.cpp:131
static constexpr int kBedRow
Definition DesignPanel.cpp:281
static wxString bed_toggle_text(bool shown)
Definition DesignPanel.cpp:296
static wxColour dp_ctl_text()
Definition DesignPanel.cpp:215
static wxColour dp_panel_bg()
Definition DesignPanel.cpp:213
@ RowMove
Definition DesignPanel.cpp:279
@ RowZoom
Definition DesignPanel.cpp:279
@ RowEdit
Definition DesignPanel.cpp:279
@ RowDelete
Definition DesignPanel.cpp:279
@ RowVisibility
Definition DesignPanel.cpp:279
static std::string commit_icon(bool bodies)
Definition DesignPanel.cpp:272
static constexpr int kOriginRow
Definition DesignPanel.cpp:281
static SketchPlane face_plane_inward(const TopoDS_Face &face)
Definition DesignPanel.cpp:384
static wxColour dp_ribbon_hover()
Definition DesignPanel.cpp:212
static const int kOfferVerbCount
Definition DesignOffer.hpp:208
@ None
Definition GLToolbar.hpp:462
@ Right
Definition GLToolbar.hpp:462
@ Left
Definition GLToolbar.hpp:462
static wxColour dp_ribbon_bg()
Definition DesignPanel.cpp:211
static wxColour dp_sec_text()
Definition DesignPanel.cpp:214
static wxString sketch_plane_prompt()
Definition DesignPanel.cpp:303
static const OfferVerb kOfferVerbs[]
Definition DesignOffer.hpp:104
@ Name
Definition CalibrationWizardSavePage.cpp:126
static int index_from_plane(const SketchPlane &p)
Definition DesignPanel.cpp:356
static StaticBox * make_card(wxWindow *parent)
Definition DesignPanel.cpp:231
static bool dp_dark()
Definition DesignPanel.cpp:209
static wxSpinCtrlDouble * make_spin(wxWindow *parent, double val, double mn=0.1, double mx=1000.0)
Definition DesignPanel.cpp:313
static wxString origin_toggle_text(bool shown)
Definition DesignPanel.cpp:290
static int combo_append_index(ComboBox *c, const wxString &label, int index)
Definition DesignPanel.cpp:164
Vec3d pos(const Pt &p)
Definition ReprojectPointsOnMesh.hpp:16
const std::vector< ThreadSpec > & thread_standards()
Definition ThreadStandards.cpp:11
SketchConstraintType
Definition SketchEngine.hpp:100
@ Vertical
Definition SketchEngine.hpp:101
@ Fix
Definition SketchEngine.hpp:101
@ SymmetricAboutY
Definition SketchEngine.hpp:114
@ Angle
Definition SketchEngine.hpp:104
@ DistanceY
Definition SketchEngine.hpp:113
@ Tangent
Definition SketchEngine.hpp:104
@ EqualLength
Definition SketchEngine.hpp:102
@ Midpoint
Definition SketchEngine.hpp:104
@ Coincident
Definition SketchEngine.hpp:101
@ Collinear
Definition SketchEngine.hpp:111
@ Parallel
Definition SketchEngine.hpp:102
@ Diameter
Definition SketchEngine.hpp:105
@ EqualRadius
Definition SketchEngine.hpp:110
@ Horizontal
Definition SketchEngine.hpp:101
@ DistanceX
Definition SketchEngine.hpp:112
@ Perpendicular
Definition SketchEngine.hpp:102
@ SymmetricAboutX
Definition SketchEngine.hpp:115
@ Radius
Definition SketchEngine.hpp:105
@ Concentric
Definition SketchEngine.hpp:103
@ Symmetric
Definition SketchEngine.hpp:104
@ FaceAndDirection
Definition CadDocument.hpp:30
Eigen::Matrix< double, 3, 1, Eigen::DontAlign > Vec3d
Definition Point.hpp:68
Eigen::Transform< double, 3, Eigen::Affine, Eigen::DontAlign > Transform3d
Definition Point.hpp:96
double angle(const Eigen::MatrixBase< Derived > &v1, const Eigen::MatrixBase< Derived2 > &v2)
Definition Point.hpp:138
static double f(double x, double z_sin, double z_cos, bool vertical, bool flip)
Definition FillGyroid.cpp:124
Eigen::Matrix< double, 2, 1, Eigen::DontAlign > Vec2d
Definition Point.hpp:67
@ Project
Definition CadDocument.hpp:26
@ up
Definition MarchingSquares.hpp:192
@ down
Definition MarchingSquares.hpp:189
#define _L_PLURAL(s, plural, n)
Definition I18N.hpp:96
#define _L_CONTEXT(s, ctx)
Definition I18N.hpp:15
wxBitmap create_scaled_bitmap(const std::string &bmp_name_in, wxWindow *win, const int px_cnt, const bool grayscale, const std::string &new_color, const bool menu_bitmap, const bool resize, const bool bitmap2, const std::vector< std::string > &array_new_color)
Definition wxExtensions.cpp:448