Visual Computing Library  devel
Loading...
Searching...
No Matches
mesh_viewer_imgui_drawer.h
1/*****************************************************************************
2 * VCLib *
3 * Visual Computing Library *
4 * *
5 * Copyright(C) 2021-2026 *
6 * Visual Computing Lab *
7 * ISTI - Italian National Research Council *
8 * *
9 * All rights reserved. *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the Mozilla Public License Version 2.0 as published *
13 * by the Mozilla Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * Mozilla Public License Version 2.0 *
20 * (https://www.mozilla.org/en-US/MPL/2.0/) for more details. *
21 ****************************************************************************/
22
23#ifndef VCL_IMGUI_MESH_VIEWER_IMGUI_DRAWER_H
24#define VCL_IMGUI_MESH_VIEWER_IMGUI_DRAWER_H
25
26#include "imgui_helpers.h"
27
28#include <vclib/render/concepts/pbr_viewer.h>
29#include <vclib/render/drawable/drawable_mesh.h>
30#include <vclib/render/drawers/trackball_viewer_drawer.h>
31#include <vclib/render/settings/pbr_viewer_settings.h>
32
33#include <imgui.h>
34
35#include <algorithm>
36#include <iterator>
37
38namespace vcl::imgui {
39
40template<typename DerivedRenderApp>
42 public vcl::TrackBallViewerDrawer<DerivedRenderApp>
43{
45
46 // selected mesh index
47 int mMeshIndex = 0;
48
49public:
50 using Base::Base;
51
52 virtual void onDraw(vcl::uint viewId) override
53 {
54 // draw parent
55 Base::onDraw(viewId);
56
57 // draw imgui
58 ImGui::Begin("Meshes");
59
60 // mesh table
61 {
64 ImGui::BeginChild(
65 "##ListContainer",
66 ImVec2(ImGui::GetContentRegionAvail().x, 260),
69 drawMeshList();
70 ImGui::EndChild();
71 }
72
73 // drawable mesh info and settings for selected mesh
74 if (mMeshIndex >= 0 && mMeshIndex < Base::mDrawList->size()) {
75 auto drawable =
76 std::dynamic_pointer_cast<vcl::AbstractDrawableMesh>(
77 Base::mDrawList->at(mMeshIndex));
78 if (drawable) {
79 drawMeshSettings(*drawable);
80 }
81 }
82
83 if constexpr (PBRViewerConcept<Base>) {
84 // combo box for pbr mode
85 ImGui::Separator();
86 ImGui::Text("Render Mode:");
87 ImGui::SameLine();
88
89 PBRViewerSettings pbrSettings = Base::pbrSettings();
90
91 const char* renderModeNames[] = {"Classic", "PBR"};
92 bool pbrMode = pbrSettings.pbrMode;
93 ImGui::SetNextItemWidth(80);
94 if (ImGui::BeginCombo(
95 "##ComboRenderMode",
96 pbrMode ? renderModeNames[1] : renderModeNames[0])) {
97 for (int n = 0; n < IM_ARRAYSIZE(renderModeNames); n++) {
98 bool isSelected =
99 (pbrMode && n == 1) || (!pbrMode && n == 0);
100 if (ImGui::Selectable(renderModeNames[n], isSelected)) {
101 pbrSettings.pbrMode = (n == 1);
102 }
103 if (isSelected)
104 ImGui::SetItemDefaultFocus();
105 }
106 ImGui::EndCombo();
107 }
108
109 ImGui::BeginDisabled(!pbrMode);
110 {
111 // exposure slider
112 ImGui::Separator();
113 ImGui::Text("Exposure:");
114 ImGui::SameLine();
115 float exposure = pbrSettings.exposure;
116 if (ImGui::SliderFloat(
117 "##Exposure",
118 &exposure,
119 0.001f,
120 64.0f,
121 "%.3f",
123 pbrSettings.exposure = exposure;
124
125 // tone mapping combo box
126 ImGui::Text("Tone mapping:");
127 ImGui::SameLine();
128 uint toneMapping = toUnderlying(pbrSettings.toneMapping);
129
130 const auto* toneMappingNames =
131 PBRViewerSettings::TONE_MAPPING_STRINGS;
132 if (ImGui::BeginCombo(
133 "##ComboToneMapping", toneMappingNames[toneMapping])) {
134 const uint CNT =
135 toUnderlying(PBRViewerSettings::ToneMapping::COUNT);
136 for (uint n = 0; n < CNT; n++) {
137 bool isSelected = toneMapping == n;
138 if (ImGui::Selectable(
139 toneMappingNames[n], isSelected)) {
140 pbrSettings.toneMapping =
141 static_cast<PBRViewerSettings::ToneMapping>(n);
142 }
143 if (isSelected)
144 ImGui::SetItemDefaultFocus();
145 }
146 ImGui::EndCombo();
147 }
148
149 // image based lighting
150 ImGui::Checkbox(
151 "Image Based Lighting",
152 [&]() {
153 return pbrSettings.imageBasedLighting;
154 },
155 [&](bool ibl) {
156 pbrSettings.imageBasedLighting = ibl;
157 });
158
159 // draw background checkbox
160 ImGui::Checkbox(
161 "Render Background Panorama",
162 [&]() {
163 return pbrSettings.renderBackgroundPanorama;
164 },
165 [&](bool renderBg) {
166 pbrSettings.renderBackgroundPanorama = renderBg;
167 });
168 }
169 ImGui::EndDisabled();
170 if (pbrSettings.pbrMode) {
171 Base::setPbrSettings(pbrSettings);
172 }
173 }
174
175 ImGui::End();
176 }
177
178 void onMousePress(
179 MouseButton::Enum button,
180 double x,
181 double y,
182 const KeyModifiers& modifiers) override
183 {
184 if (button == MouseButton::RIGHT) {
185 this->readIdRequest(x, y, [&](uint id) {
186 if (id == UINT_NULL)
187 return;
188
189 mMeshIndex = id;
190 std::cout << "Selected ID: " << id << std::endl;
191 });
192 }
193
194 Base::onMousePress(button, x, y, modifiers);
195 }
196
197private:
198 void drawMeshList()
199 {
200 if (!Base::mDrawList || Base::mDrawList->empty()) {
201 ImGui::Text("No objects loaded");
202 return;
203 }
204
205 int meshId = 0;
207 if (ImGui::BeginTable("meshtable", 2, meshTableFlags)) {
208 ImGui::TableSetupColumn(
210 ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthStretch);
211 for (auto& d : *(Base::mDrawList)) {
212 auto& drawable = *d;
213 ImGui::TableNextRow();
214
215 ImGui::PushID(meshId++);
216
217 ImGui::TableSetColumnIndex(0);
218
219 // visibility checkbox
220 ImGui::Checkbox(
221 "##Visible",
222 [&] {
223 return drawable.isVisible();
224 },
225 [&](bool vis) {
226 drawable.setVisibility(vis);
227 });
228
229 ImGui::TableSetColumnIndex(1);
230
231 // row selection
232 bool isSelected = (mMeshIndex == meshId - 1);
233 if (ImGui::Selectable(
234 drawable.name().c_str(),
235 isSelected,
237 mMeshIndex = meshId - 1;
238 }
239 // tooltip with info
240 if (!drawable.info().empty() &&
241 ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip)) {
242 ImGui::BeginTooltip();
243 ImGui::Text("%s", drawable.info().c_str());
244 ImGui::EndTooltip();
245 }
246 ImGui::PopID();
247 }
248 ImGui::EndTable();
249 }
250 }
251
252 static void drawMeshPointSettings(
254 vcl::MeshRenderSettings& settings)
255 {
257
258 ImGui::BeginDisabled(!settings.canPoints(VISIBLE));
259
260 // visibility
261 ImGui::Checkbox(
262 "Visible",
263 [&] {
264 return settings.isPoints(VISIBLE);
265 },
266 [&](bool vis) {
267 settings.setPoints(VISIBLE, vis);
268 });
269
270 // shape
271 ImGui::Text("Shape:");
272 ImGui::SameLine();
273 ImGui::RadioButton(
274 "Circle",
275 [&] {
276 return settings.isPoints(SHAPE_CIRCLE);
277 },
278 [&](bool v) {
279 if (v)
280 settings.setPoints(SHAPE_CIRCLE);
281 });
282 ImGui::SameLine();
283 ImGui::RadioButton(
284 "Pixel",
285 [&] {
286 return settings.isPoints(SHAPE_PIXEL);
287 },
288 [&](bool v) {
289 if (v)
290 settings.setPoints(SHAPE_PIXEL);
291 });
292
293 // shading
294 ImGui::Text("Shading:");
295 ImGui::SameLine();
296 ImGui::BeginDisabled(!settings.canPoints(SHADING_VERT));
297 ImGui::RadioButton(
298 "Vertex",
299 [&] {
300 return settings.isPoints(SHADING_VERT);
301 },
302 [&](bool v) {
303 if (v)
304 settings.setPoints(SHADING_VERT);
305 });
306 ImGui::SameLine();
307 ImGui::EndDisabled();
308 ImGui::RadioButton(
309 "None",
310 [&] {
311 return settings.isPoints(SHADING_NONE);
312 },
313 [&](bool vis) {
314 if (vis)
315 settings.setPoints(SHADING_NONE);
316 });
317
318 // color
319 ImGui::Text("Color:");
320 ImGui::SameLine();
321 const char* pointColorNames[] = {"Vertex", "Mesh", "User"};
322 const std::array<bool, 3> colorSelected = {
323 settings.isPoints(COLOR_VERTEX),
324 settings.isPoints(COLOR_MESH),
325 settings.isPoints(COLOR_USER)};
326
327 assert(
328 std::accumulate(
329 std::begin(colorSelected), std::end(colorSelected), 0) == 1);
330 int idx = std::distance(
331 std::begin(colorSelected),
332 std::find(
333 std::begin(colorSelected), std::end(colorSelected), true));
334 assert(idx >= 0 && idx < 3);
335
336 ImGui::SetNextItemWidth(-40);
337 if (ImGui::BeginCombo("##ComboPointColor", pointColorNames[idx])) {
338 for (int n = 0; n < IM_ARRAYSIZE(pointColorNames); n++) {
339 const bool selected = (n == idx);
340
341 switch (n) {
342 case 0:
343 ImGui::BeginDisabled(!settings.canPoints(COLOR_VERTEX));
344 if (ImGui::Selectable(pointColorNames[n], selected))
345 settings.setPoints(COLOR_VERTEX);
346 ImGui::EndDisabled();
347 break;
348 case 1:
349 ImGui::BeginDisabled(!settings.canPoints(COLOR_MESH));
350 if (ImGui::Selectable(pointColorNames[n], selected))
351 settings.setPoints(COLOR_MESH);
352 ImGui::EndDisabled();
353 break;
354 case 2:
355 if (ImGui::Selectable(pointColorNames[n], selected))
356 settings.setPoints(COLOR_USER);
357 break;
358 default: assert(false); break;
359 }
360 if (selected)
361 ImGui::SetItemDefaultFocus();
362 }
363 ImGui::EndCombo();
364 }
365 // user color picker
366 ImGui::SameLine();
367 ImGui::BeginDisabled(!settings.isPoints(COLOR_USER));
368 ImGui::ColorEdit4(
369 "##PointColor",
370 [&] {
371 return settings.pointUserColor();
372 },
373 [&](vcl::Color c) {
374 settings.setPointsUserColor(c);
375 },
377 ImGui::EndDisabled();
378
379 // point size
380 ImGui::Text("Size:");
381 // set the width of the window minus the width of the label
382 ImGui::SameLine();
383 ImGui::SetNextItemWidth(-10);
384 ImGui::SliderFloat(
385 "##PointSize",
386 [&] {
387 return settings.pointWidth();
388 },
389 [&](float v) {
390 settings.setPointsWidth(v);
391 },
392 1.0f,
393 32.0f);
394
395 ImGui::EndDisabled();
396 }
397
398 static void drawMeshSurfaceSettings(
400 vcl::MeshRenderSettings& settings)
401 {
403
404 ImGui::BeginDisabled(!settings.canSurface(VISIBLE));
405
406 // visibility
407 ImGui::Checkbox(
408 "Visible",
409 [&] {
410 return settings.isSurface(VISIBLE);
411 },
412 [&](bool vis) {
413 settings.setSurface(VISIBLE, vis);
414 });
415
416 // shading
417 assert(
418 (settings.isSurface(SHADING_SMOOTH) +
419 settings.isSurface(SHADING_FLAT) +
420 settings.isSurface(SHADING_NONE)) == 1);
421 ImGui::Text("Shading:");
422 ImGui::SameLine();
423 ImGui::RadioButton(
424 "Smooth",
425 [&] {
426 return settings.isSurface(SHADING_SMOOTH);
427 },
428 [&](bool vis) {
429 if (vis)
430 settings.setSurface(SHADING_SMOOTH);
431 });
432 ImGui::SameLine();
433 ImGui::RadioButton(
434 "Flat",
435 [&] {
436 return settings.isSurface(SHADING_FLAT);
437 },
438 [&](bool vis) {
439 if (vis)
440 settings.setSurface(SHADING_FLAT);
441 });
442 ImGui::SameLine();
443 ImGui::RadioButton(
444 "None",
445 [&] {
446 return settings.isSurface(SHADING_NONE);
447 },
448 [&](bool vis) {
449 if (vis)
450 settings.setSurface(SHADING_NONE);
451 });
452
453 // color
454 const uint CS_COUNT =
455 toUnderlying(COUNT) - 4; // exclude shading options
456
457 ImGui::Text("Color:");
458 ImGui::SameLine();
459 const char* surfColorNames[CS_COUNT] = {
460 "Vertex", "Face", "Mesh", "PerVertexTex", "PerWedgeTex", "User"};
461
462 const std::array<bool, CS_COUNT> colorSelected = {
463 settings.isSurface(COLOR_VERTEX),
464 settings.isSurface(COLOR_FACE),
465 settings.isSurface(COLOR_MESH),
466 settings.isSurface(COLOR_VERTEX_TEX),
467 settings.isSurface(COLOR_WEDGE_TEX),
468 settings.isSurface(COLOR_USER)};
469 assert(
470 std::accumulate(
471 std::begin(colorSelected), std::end(colorSelected), 0) == 1);
472 int idx = std::distance(
473 std::begin(colorSelected),
474 std::find(
475 std::begin(colorSelected), std::end(colorSelected), true));
476 assert(idx >= 0 && idx < CS_COUNT);
477 ImGui::SetNextItemWidth(-40);
478 if (ImGui::BeginCombo("##ComboSurfColor", surfColorNames[idx])) {
479 for (int n = 0; n < CS_COUNT; n++) {
480 const bool selected = (n == idx);
481
482 switch (n) {
483 case 0:
484 ImGui::BeginDisabled(!settings.canSurface(COLOR_VERTEX));
485 if (ImGui::Selectable(surfColorNames[n], selected))
486 settings.setSurface(COLOR_VERTEX);
487 ImGui::EndDisabled();
488 break;
489 case 1:
490 ImGui::BeginDisabled(!settings.canSurface(COLOR_FACE));
491 if (ImGui::Selectable(surfColorNames[n], selected))
492 settings.setSurface(COLOR_FACE);
493 ImGui::EndDisabled();
494 break;
495 case 2:
496 ImGui::BeginDisabled(!settings.canSurface(COLOR_MESH));
497 if (ImGui::Selectable(surfColorNames[n], selected))
498 settings.setSurface(COLOR_MESH);
499 ImGui::EndDisabled();
500 break;
501 case 3:
502 ImGui::BeginDisabled(
503 !settings.canSurface(COLOR_VERTEX_TEX));
504 if (ImGui::Selectable(surfColorNames[n], selected))
505 settings.setSurface(COLOR_VERTEX_TEX);
506 ImGui::EndDisabled();
507 break;
508 case 4:
509 ImGui::BeginDisabled(!settings.canSurface(COLOR_WEDGE_TEX));
510 if (ImGui::Selectable(surfColorNames[n], selected))
511 settings.setSurface(COLOR_WEDGE_TEX);
512 ImGui::EndDisabled();
513 break;
514 case 5:
515 if (ImGui::Selectable(surfColorNames[n], selected))
516 settings.setSurface(COLOR_USER);
517 break;
518 default: assert(false); break;
519 }
520 if (selected)
521 ImGui::SetItemDefaultFocus();
522 }
523 ImGui::EndCombo();
524 }
525 // user color picker
526 ImGui::SameLine();
527 ImGui::BeginDisabled(!settings.isSurface(COLOR_USER));
528 ImGui::ColorEdit4(
529 "##SurfUserColor",
530 [&] {
531 return settings.surfaceUserColor();
532 },
533 [&](vcl::Color c) {
534 settings.setSurfaceUserColor(c);
535 },
537 ImGui::EndDisabled();
538
539 ImGui::EndDisabled();
540 }
541
542 static void drawMeshWireframeSettings(
544 vcl::MeshRenderSettings& settings)
545 {
547
548 ImGui::BeginDisabled(!settings.canWireframe(VISIBLE));
549
550 // visibility
551 ImGui::Checkbox(
552 "Visible",
553 [&] {
554 return settings.isWireframe(VISIBLE);
555 },
556 [&](bool v) {
557 settings.setWireframe(VISIBLE, v);
558 });
559
560 // shading
561 assert(
562 settings.isWireframe(SHADING_VERT) !=
563 settings.isWireframe(SHADING_NONE));
564 ImGui::Text("Shading:");
565 ImGui::SameLine();
566 ImGui::RadioButton(
567 "Vertex",
568 [&] {
569 return settings.isWireframe(SHADING_VERT);
570 },
571 [&](bool vis) {
572 if (vis)
573 settings.setWireframe(SHADING_VERT);
574 });
575 ImGui::SameLine();
576 ImGui::RadioButton(
577 "None",
578 [&] {
579 return settings.isWireframe(SHADING_NONE);
580 },
581 [&](bool vis) {
582 if (vis)
583 settings.setWireframe(SHADING_NONE);
584 });
585
586 // color
587 ImGui::Text("Color:");
588 ImGui::SameLine();
589 const char* wireColorNames[] = {"Vertex", "Mesh", "User"};
590 const std::array<bool, 3> colorSelected = {
591 settings.isWireframe(COLOR_VERTEX),
592 settings.isWireframe(COLOR_MESH),
593 settings.isWireframe(COLOR_USER)};
594 assert(
595 std::accumulate(
596 std::begin(colorSelected), std::end(colorSelected), 0) == 1);
597 int idx = std::distance(
598 std::begin(colorSelected),
599 std::find(
600 std::begin(colorSelected), std::end(colorSelected), true));
601 assert(idx >= 0 && idx < 3);
602 ImGui::SetNextItemWidth(-40);
603 if (ImGui::BeginCombo("##ComboWireColor", wireColorNames[idx])) {
604 for (int n = 0; n < IM_ARRAYSIZE(wireColorNames); n++) {
605 const bool selected = (n == idx);
606
607 switch (n) {
608 case 0:
609 ImGui::BeginDisabled(!settings.canWireframe(COLOR_VERTEX));
610 if (ImGui::Selectable(wireColorNames[n], selected))
611 settings.setWireframe(COLOR_VERTEX);
612 ImGui::EndDisabled();
613 break;
614 case 1:
615 ImGui::BeginDisabled(!settings.canWireframe(COLOR_MESH));
616 if (ImGui::Selectable(wireColorNames[n], selected))
617 settings.setWireframe(COLOR_MESH);
618 ImGui::EndDisabled();
619 break;
620 case 2:
621 if (ImGui::Selectable(wireColorNames[n], selected))
622 settings.setWireframe(COLOR_USER);
623 break;
624 default: assert(false); break;
625 }
626 if (selected)
627 ImGui::SetItemDefaultFocus();
628 }
629 ImGui::EndCombo();
630 }
631 // user color picker
632 ImGui::SameLine();
633 ImGui::BeginDisabled(!settings.isWireframe(COLOR_USER));
634 ImGui::ColorEdit4(
635 "##WireUserColor",
636 [&] {
637 return settings.wireframeUserColor();
638 },
639 [&](vcl::Color c) {
640 settings.setWireframeUserColor(c);
641 },
643 ImGui::EndDisabled();
644
645 // wireframe size
646 ImGui::Text("Size:");
647 // set the width of the window minus the width of the label
648 ImGui::SameLine();
649 ImGui::SetNextItemWidth(-10);
650 ImGui::SliderFloat(
651 "##WireframeSize",
652 [&] {
653 return settings.wireframeWidth();
654 },
655 [&](float v) {
656 settings.setWireframeWidth(v);
657 },
658 1.0f,
659 32.0f);
660
661 ImGui::EndDisabled();
662 }
663
664 static void drawMeshEdgeSettings(
666 vcl::MeshRenderSettings& settings)
667 {
669
670 ImGui::BeginDisabled(!settings.canEdges(VISIBLE));
671
672 // visibility
673 ImGui::Checkbox(
674 "Visible",
675 [&] {
676 return settings.isEdges(VISIBLE);
677 },
678 [&](bool v) {
679 settings.setEdges(VISIBLE, v);
680 });
681
682 // shading
683 assert(
684 (settings.isEdges(SHADING_SMOOTH) + settings.isEdges(SHADING_FLAT) +
685 settings.isEdges(SHADING_NONE)) == 1);
686 ImGui::Text("Shading:");
687 ImGui::SameLine();
688 ImGui::BeginDisabled(!settings.canEdges(SHADING_SMOOTH));
689 ImGui::RadioButton(
690 "Smooth",
691 [&] {
692 return settings.isEdges(SHADING_SMOOTH);
693 },
694 [&](bool v) {
695 if (v)
696 settings.setEdges(SHADING_SMOOTH);
697 });
698 ImGui::EndDisabled();
699 ImGui::SameLine();
700 ImGui::BeginDisabled(!settings.canEdges(SHADING_FLAT));
701 ImGui::RadioButton(
702 "Flat",
703 [&] {
704 return settings.isEdges(SHADING_FLAT);
705 },
706 [&](bool v) {
707 if (v)
708 settings.setEdges(SHADING_FLAT);
709 });
710 ImGui::EndDisabled();
711 ImGui::SameLine();
712 ImGui::BeginDisabled(!settings.canEdges(SHADING_NONE));
713 ImGui::RadioButton(
714 "None",
715 [&] {
716 return settings.isEdges(SHADING_NONE);
717 },
718 [&](bool vis) {
719 if (vis)
720 settings.setEdges(SHADING_NONE);
721 });
722 ImGui::EndDisabled();
723
724 // color
725 ImGui::Text("Color:");
726 ImGui::SameLine();
727 const char* edgeColorNames[] = {"Vertex", "Edge", "Mesh", "User"};
728 const std::array<bool, 4> colorSelected = {
729 settings.isEdges(COLOR_VERTEX),
730 settings.isEdges(COLOR_EDGE),
731 settings.isEdges(COLOR_MESH),
732 settings.isEdges(COLOR_USER)};
733 assert(
734 std::accumulate(
735 std::begin(colorSelected), std::end(colorSelected), 0) == 1);
736 int idx = std::distance(
737 std::begin(colorSelected),
738 std::find(
739 std::begin(colorSelected), std::end(colorSelected), true));
740 assert(idx >= 0 && idx < 4);
741 ImGui::SetNextItemWidth(-40);
742 if (ImGui::BeginCombo("##ComboEdgeColor", edgeColorNames[idx])) {
743 for (int n = 0; n < IM_ARRAYSIZE(edgeColorNames); n++) {
744 const bool selected = (n == idx);
745
746 switch (n) {
747 case 0:
748 ImGui::BeginDisabled(!settings.canEdges(COLOR_VERTEX));
749 if (ImGui::Selectable(edgeColorNames[n], selected))
750 settings.setEdges(COLOR_VERTEX);
751 ImGui::EndDisabled();
752 break;
753 case 1:
754 ImGui::BeginDisabled(!settings.canEdges(COLOR_EDGE));
755 if (ImGui::Selectable(edgeColorNames[n], selected))
756 settings.setEdges(COLOR_EDGE);
757 ImGui::EndDisabled();
758 break;
759 case 2:
760 ImGui::BeginDisabled(!settings.canEdges(COLOR_MESH));
761 if (ImGui::Selectable(edgeColorNames[n], selected))
762 settings.setEdges(COLOR_MESH);
763 ImGui::EndDisabled();
764 break;
765 case 3:
766 if (ImGui::Selectable(edgeColorNames[n], selected))
767 settings.setEdges(COLOR_USER);
768 break;
769 default: assert(false); break;
770 }
771 if (selected)
772 ImGui::SetItemDefaultFocus();
773 }
774 ImGui::EndCombo();
775 }
776 // user color picker
777 ImGui::SameLine();
778 ImGui::BeginDisabled(!settings.isEdges(COLOR_USER));
779 ImGui::ColorEdit4(
780 "##EdgeUserColor",
781 [&] {
782 return settings.edgesUserColor();
783 },
784 [&](vcl::Color c) {
785 settings.setEdgesUserColor(c);
786 },
788 ImGui::EndDisabled();
789
790 // edge size
791 ImGui::Text("Size:");
792 // set the width of the window minus the width of the label
793 ImGui::SameLine();
794 ImGui::SetNextItemWidth(-10);
795 ImGui::SliderFloat(
796 "##EdgeSize",
797 [&] {
798 return settings.edgesWidth();
799 },
800 [&](float v) {
801 settings.setEdgesWidth(v);
802 },
803 1.0f,
804 32.0f);
805
806 ImGui::EndDisabled();
807 }
808
809 static void drawMeshSettings(vcl::AbstractDrawableMesh& drawable)
810 {
811 using MRI = vcl::MeshRenderInfo;
812
813 ImGui::Separator();
814 // mesh settings
815 const auto settings = drawable.renderSettings();
816 auto newSettings = settings;
817
818 // points
820 if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags)) {
821 // points
822 if (newSettings.canPoints(MRI::Points::VISIBLE) &&
823 ImGui::BeginTabItem("Points")) {
824 drawMeshPointSettings(drawable, newSettings);
825 ImGui::EndTabItem();
826 }
827
828 // surface + wireframe
829 if (newSettings.canSurface(MRI::Surface::VISIBLE)) {
830 if (ImGui::BeginTabItem("Surface")) {
831 drawMeshSurfaceSettings(drawable, newSettings);
832 ImGui::EndTabItem();
833 }
834 if (ImGui::BeginTabItem("Wireframe")) {
835 drawMeshWireframeSettings(drawable, newSettings);
836 ImGui::EndTabItem();
837 }
838 }
839
840 // edges
841 if (newSettings.canEdges(MRI::Edges::VISIBLE) &&
842 ImGui::BeginTabItem("Edges")) {
843 drawMeshEdgeSettings(drawable, newSettings);
844 ImGui::EndTabItem();
845 }
846
847 ImGui::EndTabBar();
848 }
849
850 if (newSettings != settings) {
851 drawable.setRenderSettings(newSettings);
852 }
853 }
854};
855
856} // namespace vcl::imgui
857
858#endif // VCL_IMGUI_MESH_VIEWER_IMGUI_DRAWER_H
The AbstractDrawableMesh class is the base class for all the drawable meshes in the VCLib render syst...
Definition abstract_drawable_mesh.h:41
The Color class represents a 32 bit color.
Definition color.h:48
The MeshRenderInfo class is a collection of rendering settings for a Mesh.
Definition mesh_render_info.h:61
Wireframe
List of possible settings for the wireframe primitive.
Definition mesh_render_info.h:166
Surface
List of possible settings for the surface primitive.
Definition mesh_render_info.h:148
Edges
List of possible settings for the edges primitive.
Definition mesh_render_info.h:180
Points
List of possible settings for the points primitive.
Definition mesh_render_info.h:131
The MeshRenderSettings class allows an easy management of render settings of a Mesh....
Definition mesh_render_settings.h:70
bool isPoints(MeshRenderInfo::Points p) const
Returns whether the given points option is set.
Definition mesh_render_settings.h:225
bool canWireframe(MeshRenderInfo::Wireframe w) const
Returns the capability of a given option for the wireframe primitive.
Definition mesh_render_settings.h:177
bool setSurface(MeshRenderInfo::Surface s, bool b=true)
Sets the given shading option of the surface.
Definition mesh_render_settings.h:458
bool setEdges(MeshRenderInfo::Edges e, bool b=true)
Sets the given shading option of the edges.
Definition mesh_render_settings.h:568
bool setPoints(MeshRenderInfo::Points p, bool b=true)
Sets the given shading option of the points.
Definition mesh_render_settings.h:397
bool canSurface(MeshRenderInfo::Surface s) const
Returns the capability of a given option for the surface primitive.
Definition mesh_render_settings.h:165
bool canPoints(MeshRenderInfo::Points p) const
Returns the capability of a given option for the points primitive.
Definition mesh_render_settings.h:153
bool canEdges(MeshRenderInfo::Edges e) const
Returns the capability of a given option for the edges primitive.
Definition mesh_render_settings.h:188
bool isSurface(MeshRenderInfo::Surface s) const
Returns whether the given surface option is set.
Definition mesh_render_settings.h:250
bool isWireframe(MeshRenderInfo::Wireframe w) const
Returns whether the given wireframe option is set.
Definition mesh_render_settings.h:270
bool setWireframe(MeshRenderInfo::Wireframe w, bool b=true)
Sets the given shading option of the wireframe.
Definition mesh_render_settings.h:507
bool isEdges(MeshRenderInfo::Edges e) const
Returns whether the given edges option is set.
Definition mesh_render_settings.h:295
A class representing a line segment in n-dimensional space. The class is parameterized by a PointConc...
Definition segment.h:41
Definition mesh_viewer_imgui_drawer.h:43
Definition pbr_viewer.h:33
constexpr uint UINT_NULL
The UINT_NULL value represent a null value of uint that is the maximum value that can be represented ...
Definition base.h:49
Definition pbr_viewer_settings.h:31