ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
ccGuiPythonInstance.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #include "ccGuiPythonInstance.h"
9 
10 #define slots Q_SLOTS
11 #define signals Q_SIGNALS
12 
13 #include <ecvDisplayTools.h>
14 #include <ecvMainAppInterface.h>
15 #include <ecvPointCloud.h>
16 
17 #include <QMainWindow>
18 
19 #include <stdexcept>
20 
21 #undef slots
22 #include <pybind11/pybind11.h>
23 #include <pybind11/stl.h>
24 #include <pybind11/stl_bind.h>
25 
26 #include "../../wrapper/pycc/src/casters.h"
27 
28 namespace py = pybind11;
29 using namespace pybind11::literals;
30 
32 {
33  switch (error)
34  {
35  case CC_FERR_NO_ERROR:
36  break;
38  throw std::runtime_error("Bad argument");
40  throw std::runtime_error("Unknown file");
42  throw std::runtime_error("Wrong file type");
43  case CC_FERR_WRITING:
44  throw std::runtime_error("Error when writing");
45  case CC_FERR_READING:
46  throw std::runtime_error("Error when reading");
47  case CC_FERR_NO_SAVE:
48  throw std::runtime_error("Nothing to save");
49  case CC_FERR_NO_LOAD:
50  throw std::runtime_error("Nothing to load");
52  throw std::runtime_error("Bad entity type");
54  throw std::runtime_error("Canceled by user");
56  throw std::runtime_error("Not enough memory");
58  throw std::runtime_error("Malformed File");
60  throw std::runtime_error("The error has been logged in the console");
62  throw std::runtime_error("Broken dependency");
64  throw std::runtime_error("File was written by unknown plugin");
66  throw std::runtime_error("Third party lib failure");
68  throw std::runtime_error("Third party lib exception");
69  case CC_FERR_INTERNAL:
70  throw std::runtime_error("Internal error");
72  throw std::runtime_error("Not implemented");
73  }
74 }
75 
77 {
78  if (m_app == nullptr)
79  {
80  throw std::invalid_argument("nullptr received for the app");
81  }
82 }
83 
85 {
86  return m_app->getMainWindow();
87 }
88 
90 {
91  return m_app->haveSelection();
92 }
93 
95 {
96  return m_app->haveOneSelection();
97 }
98 
100 {
101  return m_app->getSelectedEntities();
102 }
103 
104 void ccGuiPythonInstance::setSelectedInDB(ccHObject *obj, const bool selected)
105 {
106  m_app->setSelectedInDB(obj, selected);
107 }
108 
110  FileIOFilter::LoadParameters &parameters)
111 {
113  ccHObject *newGroup = FileIOFilter::LoadFromFile(filename, parameters, result);
115 
116  if (newGroup)
117  {
118  m_app->addToDB(newGroup);
119  m_app->refreshAll();
120  m_app->updateUI();
121  }
122  return newGroup;
123 }
124 
125 void ccGuiPythonInstance::addToDB(pybind11::object &obj,
126  bool updateZoom,
127  bool autoExpandDBTree,
128  bool checkDimensions,
129  bool autoRedraw)
130 {
131  try
132  {
133  auto *const hobj = obj.cast<ccHObject *>();
134  m_app->addToDB(hobj, updateZoom, autoExpandDBTree, checkDimensions, autoRedraw);
135  obj.inc_ref();
136  }
137  catch (const pybind11::cast_error &)
138  {
139  throw std::runtime_error("Cannot add to the DB a type that does not sub class ccHObject");
140  }
141 }
142 
143 void ccGuiPythonInstance::removeFromDB(pybind11::object &obj)
144 {
145  try
146  {
147  auto *const hobj = obj.cast<ccHObject *>();
148  // Python side will take care of deleting it
149  // because if we do delete it now and user tries to use the obj
150  // it'll be a use after free.
151  m_app->removeFromDB(hobj, false /*delete*/);
152  Q_ASSERT(obj.ref_count() >= 2);
153  obj.dec_ref();
154  }
155  catch (const pybind11::cast_error &)
156  {
157  throw std::runtime_error(
158  "Cannot remove from the DB a type that does not sub class ccHObject");
159  }
160 }
161 
163 {
164  return m_app->dbRootObject();
165 }
166 
168 {
169  m_app->redrawAll(only2D);
170 }
171 
173 {
174  m_app->refreshAll(only2D);
175 }
176 
178 {
179  m_app->enableAll();
180 }
181 
183 {
184  m_app->disableAll();
185 }
186 
188 {
189  m_app->updateUI();
190 }
191 
193 {
194  m_app->freezeUI(state);
195 }
197 {
198  return m_app;
199 }
200 
201 void define_ccGUIPythonInstance(py::module &m)
202 {
203  py::class_<ccGuiPythonInstance>(m,
204  "ccPythonInstance",
205  R"(
206  Class to interact with the running GUI of ACloudViewer.
207 
208  The methods allow you to get/add objects to GUI DB Tree.
209  Refresh/freeze/update the UI and display.
210  Get selected objects, deselect/set selected state for entities...
211 )")
212  .def("getMainWindow",
214  py::return_value_policy::reference)
215  .def("haveSelection",
217  R"(Returns true if at least one entity is selected in the GUI DB Tree)")
218  .def("haveOneSelection",
220  R"(Returns True if exactly one entity is selected in the GUI DB Tree)")
221  .def("getSelectedEntities",
223  py::return_value_policy::reference,
224  R"(Returns the list of selected entities in the GUI DB Tree)")
225  .def("setSelectedInDB",
227  "obj"_a,
228  "selected"_a,
229  R"(Set the selection state of the object in the GUI DB Tree)")
230  .def("dbRootObject",
232  py::return_value_policy::reference,
233  R"(Returns the root of the GUI DB Tree)")
234  .def("addToDB",
236  // py::call_guard<py::gil_scoped_release>(),
237  "obj"_a,
238  "updateZoom"_a = false,
239  "autoExpandDBTree"_a = true,
240  "checkDimensions"_a = false,
241  "autoRedraw"_a = true,
242  R"(Adds the object to the GUI DB Tree)")
243  .def("removeFromDB", &ccGuiPythonInstance::removeFromDB, "entity"_a)
244  .def("redrawAll", &ccGuiPythonInstance::redrawAll, "only2D"_a = false)
245  .def("refreshAll", &ccGuiPythonInstance::refreshAll, "only2D"_a = false)
246  .def("enableAll", &ccGuiPythonInstance::enableAll)
247  .def("disableAll", &ccGuiPythonInstance::disableAll)
248  .def("updateUI", &ccGuiPythonInstance::updateUI)
249  .def("freezeUI", &ccGuiPythonInstance::freezeUI, "state"_a)
250  .def("app", &ccGuiPythonInstance::app)
251  .def("loadFile",
253  py::return_value_policy::reference,
254  "filepath"_a,
255  "loadParameters"_a,
256  R"(
257  Loads the file located at the filepath.
258 
259  Adds the file content of the file into the DBTree
260  and then returns loaded object handle.
261 
262  raises RuntimeError in case of error)");
263 }
std::string filename
CC_FILE_ERROR
Typical I/O filter errors.
Definition: FileIOFilter.h:20
@ CC_FERR_CONSOLE_ERROR
Definition: FileIOFilter.h:33
@ CC_FERR_CANCELED_BY_USER
Definition: FileIOFilter.h:30
@ CC_FERR_THIRD_PARTY_LIB_FAILURE
Definition: FileIOFilter.h:36
@ CC_FERR_NO_LOAD
Definition: FileIOFilter.h:28
@ CC_FERR_WRITING
Definition: FileIOFilter.h:25
@ CC_FERR_THIRD_PARTY_LIB_EXCEPTION
Definition: FileIOFilter.h:37
@ CC_FERR_MALFORMED_FILE
Definition: FileIOFilter.h:32
@ CC_FERR_BAD_ARGUMENT
Definition: FileIOFilter.h:22
@ CC_FERR_UNKNOWN_FILE
Definition: FileIOFilter.h:23
@ CC_FERR_NO_SAVE
Definition: FileIOFilter.h:27
@ CC_FERR_NO_ERROR
Definition: FileIOFilter.h:21
@ CC_FERR_NOT_IMPLEMENTED
Definition: FileIOFilter.h:38
@ CC_FERR_BROKEN_DEPENDENCY_ERROR
Definition: FileIOFilter.h:34
@ CC_FERR_BAD_ENTITY_TYPE
Definition: FileIOFilter.h:29
@ CC_FERR_INTERNAL
Definition: FileIOFilter.h:39
@ CC_FERR_READING
Definition: FileIOFilter.h:26
@ CC_FERR_FILE_WAS_WRITTEN_BY_UNKNOWN_PLUGIN
Definition: FileIOFilter.h:35
@ CC_FERR_NOT_ENOUGH_MEMORY
Definition: FileIOFilter.h:31
@ CC_FERR_WRONG_FILE_TYPE
Definition: FileIOFilter.h:24
core::Tensor result
Definition: VtkUtils.cpp:76
void define_ccGUIPythonInstance(py::module &m)
static void ThrowForFileError(CC_FILE_ERROR error)
static ccHObject * LoadFromFile(const QString &filename, LoadParameters &parameters, Shared filter, CC_FILE_ERROR &result)
Loads one or more entities from a file with a known filter.
ecvMainAppInterface * app()
void removeFromDB(pybind11::object &obj)
QMainWindow * getMainWindow()
void redrawAll(bool only2D=false)
void setSelectedInDB(ccHObject *obj, bool selected)
ccGuiPythonInstance(ecvMainAppInterface *app) noexcept(false)
void refreshAll(bool only2D=false)
ccHObject * loadFile(const char *filename, FileIOFilter::LoadParameters &parameters)
void addToDB(pybind11::object &obj, bool updateZoom=false, bool autoExpandDBTree=true, bool checkDimensions=false, bool autoRedraw=true)
const ccHObject::Container & getSelectedEntities() const
Hierarchical CLOUDVIEWER Object.
Definition: ecvHObject.h:25
std::vector< ccHObject * > Container
Standard instances container (for children, etc.)
Definition: ecvHObject.h:337
Main application interface (for plugins)
static void error(char *msg)
Definition: lsd.c:159
Generic loading parameters.
Definition: FileIOFilter.h:51