Visual Computing Library  devel
Loading...
Searching...
No Matches
abstract_viewer_drawer.h
1/*****************************************************************************
2 * VCLib *
3 * Visual Computing Library *
4 * *
5 * Copyright(C) 2021-2025 *
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_RENDER_DRAWERS_ABSTRACT_VIEWER_DRAWER_H
24#define VCL_RENDER_DRAWERS_ABSTRACT_VIEWER_DRAWER_H
25
26#include <vclib/render/concepts/view_projection_event_drawer.h>
27#include <vclib/render/drawable/drawable_object_vector.h>
28#include <vclib/render/drawers/event_drawer.h>
29#include <vclib/render/read_buffer_types.h>
30#include <vclib/space/core/color.h>
31
32#include <memory>
33
34namespace vcl {
35
44template<typename ViewProjEventDrawer>
45class AbstractViewerDrawer : public ViewProjEventDrawer
46{
47 using Base = ViewProjEventDrawer;
48 using DRA = ViewProjEventDrawer::DRA;
49
50 bool mReadRequested = false;
51
52 // the default id for the viewer drawer is 0
53 uint mId = 0;
54
55protected:
56 // the list of drawable objects
57 // it could be owned by the viewer, or it could be shared with other
58 // objects (e.g. the window that contains the viewer along with other
59 // widgets)
60 std::shared_ptr<DrawableObjectVector> mDrawList =
61 std::make_shared<DrawableObjectVector>();
62
63 // the drawer id
64 uint& id() { return mId; }
65
66public:
67 AbstractViewerDrawer(uint width = 1024, uint height = 768) :
68 Base(width, height)
69 {
70 static_assert(
72 "AbstractViewerDrawer requires a ViewProjectionEventDrawer as a "
73 "base class");
74 }
75
76 ~AbstractViewerDrawer() = default;
77
78 const DrawableObjectVector& drawableObjectVector() const
79 {
80 return *mDrawList;
81 }
82
83 void setDrawableObjectVector(const std::shared_ptr<DrawableObjectVector>& v)
84 {
85 mDrawList = v;
86
87 for (auto obj : *mDrawList) {
88 obj->init();
89 }
90 fitScene();
91 }
92
93 uint pushDrawableObject(const DrawableObject& obj)
94 {
95 mDrawList->pushBack(obj);
96 mDrawList->back()->init();
97 return mDrawList->size() - 1;
98 }
99
100 uint pushDrawableObject(DrawableObject&& obj)
101 {
102 mDrawList->pushBack(std::move(obj));
103 mDrawList->back()->init();
104 return mDrawList->size() - 1;
105 }
106
107 void fitScene()
108 {
110 float sceneRadius = 1;
111
112 Box3d bb = mDrawList->boundingBox();
113
114 if (!bb.isNull()) {
115 sceneCenter = bb.center().cast<float>();
117 }
118
119 Base::fitScene(sceneCenter, sceneRadius);
120 }
121
122 // events
123 void onInit(uint) override
124 {
125 DRA::DRW::setCanvasDefaultClearColor(derived(), Color::DarkGray);
126 }
127
128 void onKeyPress(Key::Enum key, const KeyModifiers& modifiers) override
129 {
130 Base::onKeyPress(key, modifiers);
131
132 switch (key) {
133 case Key::S:
134 if (modifiers[KeyModifier::CONTROL])
135 DRA::DRW::screenshot(derived(), "viewer_screenshot.png");
136 break;
137
138 default: break;
139 }
140 }
141
142protected:
143 void readDepthRequest(double x, double y, bool homogeneousNDC = true)
144 {
145 using ReadData = ReadBufferTypes::ReadData;
146 using FloatData = ReadBufferTypes::FloatData;
147 using MatrixType = Base::MatrixType;
148
149 if (mReadRequested)
150 return;
151
152 // get point
153 const Point2d p(x, y);
154
155 // create the callback
156 const auto proj = Base::projectionMatrix();
157 const auto view = Base::viewMatrix();
158 // viewport
159 auto size = DRA::DRW::canvasSize(derived());
160
161 const Point4f vp = {.0f, .0f, float(size.x()), float(size.y())};
162
163 auto callback = [=, this](const ReadData& dt) {
164 const auto& data = std::get<FloatData>(dt);
165 assert(data.size() == 1);
166 const float depth = data[0];
167
168 mReadRequested = false;
169
170 // if the depth is 1.0, the point is not in the scene
171 if (depth == 1.0f) {
172 return;
173 }
174
175 // unproject the point
176 const Point3f p2d(p.x(), vp[3] - p.y(), depth);
177 auto unproj =
178 unproject(p2d, MatrixType(proj * view), vp, homogeneousNDC);
179
180 this->focus(unproj);
181 derived()->update();
182 };
183
184 mReadRequested =
185 DRA::DRW::readDepth(derived(), Point2i(p.x(), p.y()), callback);
186 if (mReadRequested)
187 derived()->update();
188 }
189
190 void readIdRequest(double x, double y, std::function<void(uint)> idCallback)
191 {
192 using ReadData = ReadBufferTypes::ReadData;
193
194 if (mReadRequested)
195 return;
196
197 // get point
198 const Point2d p(x, y);
199
200 // create the callback
201 auto callback = [=, this](const ReadData& dt) {
202 const auto& data = std::get<ReadBufferTypes::ByteData>(dt);
203 assert(data.size() == 4);
204 // TODO: check how to do this properly
205 const uint id = *(uint32_t*) &data[0];
206
207 mReadRequested = false;
208
209 idCallback(id);
210 derived()->update();
211 };
212
213 mReadRequested =
214 DRA::DRW::readId(derived(), Point2i(p.x(), p.y()), callback);
215 if (mReadRequested)
216 derived()->update();
217 }
218
219private:
220 auto* derived() { return static_cast<DRA*>(this); }
221
222 const auto* derived() const { return static_cast<const DRA*>(this); }
223};
224
225} // namespace vcl
226
227#endif // VCL_RENDER_DRAWERS_ABSTRACT_VIEWER_DRAWER_H
The AbstractViewerDrawer class is a base class for all viewer drawers implementations.
Definition abstract_viewer_drawer.h:46
A class representing a box in N-dimensional space.
Definition box.h:46
auto diagonal() const
Calculates the diagonal length of the box.
Definition box.h:246
PointT center() const
Calculates the center point of the box.
Definition box.h:259
bool isNull() const
Checks whether the box is null or not.
Definition box.h:133
Definition drawable_object_vector.h:36
The DrawableObject class is the base class for all the objects that can be drawn in a 3D viewer.
Definition drawable_object.h:55
The Point class represents an N-dimensional point containing N scalar values.
Definition point.h:55
Definition view_projection_event_drawer.h:32
Point2< int > Point2i
A convenience alias for a 2-dimensional Point with integer components.
Definition point.h:706