2 * This program is free software: you can redistribute it and/or modify
3 * it under the terms of the GNU Lesser General Public License as
4 * published by the Free Software Foundation, either version 3 of the
5 * License, or (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 * @file PolyscopeViewer.ih
18 * @author Bastien Doignies <bastien.doignies@liris.cnrs.fr>
22 * Implementation file for 3D Polyscope Viewer
24 * This file is part of the DGtal library.
29 glm::vec3 toglm(const DGtal::Color& col) {
30 return glm::vec3{col.r(), col.g(), col.b()};
33 std::vector<glm::vec3> toglm(const std::vector<DGtal::Color>& col) {
34 std::vector<glm::vec3> colors(col.size());
35 for (size_t i = 0; i < colors.size(); ++i) {
36 colors[i] = toglm(col[i]);
41 glm::mat4 toglm(const Eigen::Affine3d& transform) {
42 glm::mat4 glmmat(1.f);
43 Eigen::Matrix4d mat = transform.matrix();
45 for (int i = 0; i < 4; ++i)
46 for (int j = 0; j < 4; ++j)
47 glmmat[i][j] = static_cast<float>(mat(j, i));
52 template <typename Space, typename KSpace>
53 void PolyscopeViewer<Space, KSpace>::setCallback(typename Display3D<Space, KSpace>::Callback* callback) {
54 Display3D<Space, KSpace>::setCallback(callback);
55 if (this->myCallback != nullptr) {
56 polyscope::state::userCallback = [this]() { this->polyscopeCallback(); };
58 polyscope::state::userCallback = nullptr; // Remove callback
62 template <typename Space, typename KSpace>
63 void PolyscopeViewer<Space, KSpace>::renderClippingPlanes() {
64 using namespace drawutils;
66 // Draw clipping planes
67 for (const auto& plane : this->planes) {
68 const glm::vec3 normal { plane.a, plane.b, plane.c };
69 glm::vec3 pos {0, 0, 0};
71 if (plane.a != 0) { pos.x = -plane.d / plane.a; }
72 else if (plane.b != 0) { pos.y = -plane.d / plane.b; }
73 else if (plane.c != 0) { pos.z = -plane.d / plane.c; }
76 polyscope::SlicePlane* ps = polyscope::addSceneSlicePlane();
77 if (!plane.style.useDefaultColors)
78 ps->setColor(toglm(plane.style.color));
80 //TODO: Keep this as default ?
81 ps->setDrawPlane(true);
82 ps->setPose(pos, normal);
86 template <typename Space, typename KSpace>
87 void PolyscopeViewer<Space, KSpace>::setGeneralProperties(polyscope::Structure* structure, const DisplayData<typename Space::RealPoint>& data) {
88 using namespace drawutils;
90 structure->setTransform(toglm(data.transform));
91 structure->setTransparency(data.style.color.a());
94 template <typename Space, typename KSpace>
95 void PolyscopeViewer<Space, KSpace>::registerPointCloud(const std::string& name, const DisplayData<typename Space::RealPoint>& data) {
96 using namespace drawutils;
98 auto* pCloud = polyscope::registerPointCloud(name, data.vertices);
100 setGeneralProperties(pCloud, data);
101 if (!data.style.useDefaultColors) {
102 pCloud->setPointColor(toglm(data.style.color));
105 for (const auto& [name, vals] : data.scalarQuantities[QuantityScale::VERTEX]) {
106 pCloud->addScalarQuantity(name, vals)->setEnabled(true);
109 for (const auto& [name, vals] : data.vectorQuantities[QuantityScale::VERTEX]) {
110 auto* q = pCloud->addVectorQuantity(name, vals);
112 q->setVectorLengthScale(VectorScale);
115 for (const auto& [name, vals] : data.colorQuantities[QuantityScale::VERTEX]) {
116 pCloud->addColorQuantity(name, toglm(vals))->setEnabled(true);
118 pCloud->setPointRadius(data.style.width * BallToCubeRatio);
121 template <typename Space, typename KSpace>
122 void PolyscopeViewer<Space, KSpace>::registerLineNetwork(const std::string& name, const DisplayData<typename Space::RealPoint>& data) {
123 using namespace drawutils;
125 auto* cNetwork = polyscope::registerCurveNetwork(name, data.vertices, makeIndices<2>(data.vertices.size() / 2));
127 setGeneralProperties(cNetwork, data);
128 if (!data.style.useDefaultColors) {
129 cNetwork->setColor(toglm(data.style.color));
132 for (const auto& [name, vals] : data.scalarQuantities[QuantityScale::VERTEX]) {
133 cNetwork->addNodeScalarQuantity(name, vals)->setEnabled(true);
135 for (const auto& [name, vals] : data.scalarQuantities[QuantityScale::EDGE]) {
136 cNetwork->addEdgeScalarQuantity(name, vals)->setEnabled(true);
139 for (const auto& [name, vals] : data.vectorQuantities[QuantityScale::VERTEX]) {
140 auto* q = cNetwork->addNodeVectorQuantity(name, vals);
141 q->setVectorLengthScale(VectorScale);
144 for (const auto& [name, vals] : data.vectorQuantities[QuantityScale::EDGE]) {
145 auto* q = cNetwork->addEdgeVectorQuantity(name, vals);
146 q->setVectorLengthScale(VectorScale);
150 for (const auto& [name, vals] : data.colorQuantities[QuantityScale::VERTEX]) {
151 cNetwork->addEdgeColorQuantity(name, toglm(vals))->setEnabled(true);
153 for (const auto& [name, vals] : data.colorQuantities[QuantityScale::EDGE]) {
154 cNetwork->addEdgeColorQuantity(name, toglm(vals))->setEnabled(true);
158 template <typename Space, typename KSpace>
159 void PolyscopeViewer<Space, KSpace>::registerSurfaceMesh(const std::string& name, const DisplayData<typename Space::RealPoint>& data) {
160 using namespace drawutils;
162 polyscope::SurfaceMesh* mesh = nullptr;
163 if (data.elementSize == 3) {
164 mesh = polyscope::registerSurfaceMesh(name, data.vertices, makeIndices<3>(data.vertices.size() / 3));
165 } else if (data.elementSize == 4) {
166 mesh = polyscope::registerSurfaceMesh(name, data.vertices, makeIndices<4>(data.vertices.size() / 4));
168 mesh = polyscope::registerSurfaceMesh(name, data.vertices, data.indices);
171 setGeneralProperties(mesh, data);
172 if (!data.style.useDefaultColors) {
173 mesh->setSurfaceColor(toglm(data.style.color));
176 for (const auto& [name, vals] : data.scalarQuantities[QuantityScale::VERTEX]) {
177 mesh->addVertexScalarQuantity(name, vals)->setEnabled(true);
179 for (const auto& [name, vals] : data.scalarQuantities[QuantityScale::EDGE]) {
180 mesh->addEdgeScalarQuantity(name, vals)->setEnabled(true);
182 for (const auto& [name, vals] : data.scalarQuantities[QuantityScale::FACE]) {
183 mesh->addFaceScalarQuantity(name, vals)->setEnabled(true);
186 for (const auto& [name, vals] : data.vectorQuantities[QuantityScale::VERTEX]) {
187 auto* q = mesh->addVertexVectorQuantity(name, vals);
188 q->setVectorLengthScale(VectorScale);
191 for (const auto& [name, vals] : data.vectorQuantities[QuantityScale::FACE]) {
192 auto* q = mesh->addFaceVectorQuantity(name, vals);
193 q->setVectorLengthScale(VectorScale);
197 for (const auto& [name, vals] : data.colorQuantities[QuantityScale::VERTEX]) {
198 mesh->addVertexColorQuantity(name, toglm(vals))->setEnabled(true);
200 for (const auto& [name, vals] : data.colorQuantities[QuantityScale::FACE]) {
201 mesh->addFaceColorQuantity(name, toglm(vals))->setEnabled(true);
205 template <typename Space, typename KSpace>
206 void PolyscopeViewer<Space, KSpace>::registerVolumeMesh(const std::string& name, const DisplayData<typename Space::RealPoint>& data) {
207 using namespace drawutils;
209 polyscope::VolumeMesh* mesh = polyscope::registerVolumeMesh(name, data.vertices, makeIndices<8>(data.vertices.size() / 8));
211 setGeneralProperties(mesh, data);
212 if (!data.style.useDefaultColors) {
213 mesh->setColor(toglm(data.style.color));
216 for (const auto& [name, vals] : data.scalarQuantities[QuantityScale::VERTEX]) {
217 mesh->addVertexScalarQuantity(name, vals)->setEnabled(true);
219 for (const auto& [name, vals] : data.scalarQuantities[QuantityScale::CELL]) {
220 mesh->addCellScalarQuantity(name, vals)->setEnabled(true);
223 for (const auto& [name, vals] : data.vectorQuantities[QuantityScale::VERTEX]) {
224 auto* q = mesh->addVertexVectorQuantity(name, vals);
225 q->setVectorLengthScale(VectorScale);
228 for (const auto& [name, vals] : data.vectorQuantities[QuantityScale::CELL]) {
229 auto* q = mesh->addCellVectorQuantity(name, vals);
230 q->setVectorLengthScale(VectorScale);
234 for (const auto& [name, vals] : data.colorQuantities[QuantityScale::VERTEX]) {
235 mesh->addVertexColorQuantity(name, toglm(vals))->setEnabled(true);
237 for (const auto& [name, vals] : data.colorQuantities[QuantityScale::CELL]) {
238 mesh->addCellColorQuantity(name, toglm(vals))->setEnabled(true);
242 template <typename Space, typename KSpace>
243 void PolyscopeViewer<Space, KSpace>::renderNewData() {
244 using namespace drawutils;
246 for (const std::string& name : this->myToRender) {
247 auto it = this->data.find(name);
248 if (it == this->data.end()) continue;
250 const auto& data = it->second;
251 const auto& vertices = data.vertices;
253 if (vertices.size() == 0) continue;
255 switch(data.elementSize) {
256 case 1: registerPointCloud(name, data); break;
257 case 2: registerLineNetwork(name, data); break;
260 case 4: registerSurfaceMesh(name, data); break;
261 case 8: registerVolumeMesh(name, data); break;
269 template <typename Space, typename KSpace>
270 void PolyscopeViewer<Space, KSpace>::polyscopeCallback() {
271 this->myCallback->OnUI(nullptr);
273 ImGuiIO& io = ImGui::GetIO();
274 if (io.MouseClicked[0])
276 glm::vec2 screenCoords{io.MousePos.x, io.MousePos.y};
277 auto [structure, index] =
278 polyscope::pick::pickAtScreenCoords(screenCoords);
280 if (structure != nullptr) {
281 void* viewerData = structure;
282 std::string name = structure->getName();
284 auto& data = this->data[name];
285 this->myCallback->OnClick(name, index, data, viewerData);