LoadObjectsIntoMemoryWidgetController.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * ArmarX is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * ArmarX is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * \package ARCHES::gui-plugins::LoadObjectsIntoMemoryWidgetController
17  * \author Raphael Grimm ( raphael dot grimm at kit dot edu )
18  * \date 2018
19  * \copyright http://www.gnu.org/licenses/gpl-2.0.txt
20  * GNU General Public License
21  */
22 
23 
24 #include <string>
25 #include <chrono>
26 
27 #include <filesystem>
28 
29 #include <VirtualRobot/Visualization/TriMeshUtils.h>
30 #include <VirtualRobot/Visualization/VisualizationNode.h>
31 
33 
36 
38 
39 using namespace armarx;
40 
42 {
43  widget.setupUi(getWidget());
44  connect(widget.pushButtonAddObjects, SIGNAL(clicked()), this, SLOT(addObjects()));
45 }
46 
48 {
49  priorPrx = getProxy<memoryx::PriorKnowledgeInterfacePrx>(dialog->getProxyName("PriorKnowledge"));
50  classesSegmentPrx = priorPrx->getObjectClassesSegment();
51 
52  databasePrx = priorPrx->getCommonStorage();
53  fileManager.reset(new memoryx::GridFileManager(databasePrx));
54  QMetaObject::invokeMethod(this, "updateDBs", Qt::QueuedConnection);
55 }
56 
58 {
59  if (!dialog)
60  {
61  dialog = new SimpleConfigDialog(parent);
62  dialog->addProxyFinder<memoryx::PriorKnowledgeInterfacePrx>({"PriorKnowledge", "PriorKnowledge", "PriorKnowledge*"});
63  }
64  return qobject_cast<SimpleConfigDialog*>(dialog);
65 }
66 
68 {
69  const NameList dbNames = databasePrx->getDBNames();
70  widget.comboBoxDBs->clear();
71  for (const auto& db : dbNames)
72  {
73  widget.comboBoxDBs->addItem(QString::fromStdString(db));
74  }
75  ARMARX_INFO << "setting list of DBs to: " << dbNames;
76 }
77 
79 {
80  namespace fs = std::filesystem;
81 
82  const std::string dir = widget.lineEditDir->text().toStdString();
83  const std::string collection = widget.lineEditCollection->text().toStdString();
84  const std::string db = widget.comboBoxDBs->currentText().toStdString();
85  const std::string tmpdir = "/tmp/LoadObjectsIntoMemoryWidget/" + std::to_string(std::chrono::high_resolution_clock::now().time_since_epoch().count()) + "/";
86 
87  fs::create_directories(tmpdir);
88 
89  ARMARX_CHECK_EXPRESSION(!dir.empty());
90  ARMARX_CHECK_EXPRESSION(fs::exists(dir));
91  ARMARX_CHECK_EQUAL(collection.empty(), db.empty());
92 
93  //set write collection
94  if (!collection.empty())
95  {
96  const std::string fullCollectionName = db + "." + collection;
97  ARMARX_INFO << "setting write collection to: " << fullCollectionName;
98  memoryx::CollectionInterfacePrx coll = databasePrx->requestCollection(fullCollectionName);
100  classesSegmentPrx->setWriteCollection(coll);
101  ARMARX_INFO << "setting write collection done";
102  }
103 
104  for (fs::directory_iterator dit{dir}; dit != fs::directory_iterator{}; ++dit)
105  {
106  const fs::path p = *dit;
107  if (!fs::is_regular_file(p))
108  {
109  ARMARX_INFO << "skipping non file " << p;
110  continue;
111  }
112  const std::string fname = p.filename().string();
113  const std::string fpath = p.string();
114  const auto endswith = [&](const std::string & suff)
115  {
116  const auto pos = fname.rfind(suff);
117  return pos != std::string::npos && pos == (fname.size() - suff.size());
118  };
119  std::string className = fname;
120 
121 
122  //trim name
123  {
124  if (widget.radioButtonWRL->isChecked())
125  {
126  if (endswith(".wrl"))
127  {
128  className = className.substr(0, className.size() - 4);
129  }
130  else if (endswith(".iv"))
131  {
132  className = className.substr(0, className.size() - 3);
133  }
134  else
135  {
136  ARMARX_INFO << "skipping non wrl/iv file " << p;
137  continue;
138  }
139  }
140  else
141  {
142  if (endswith(".xml"))
143  {
144  className = className.substr(0, className.size() - 4);
145  }
146  else
147  {
148  ARMARX_INFO << "skipping non xml file " << p;
149  continue;
150  }
151  }
152  ARMARX_INFO << "processing file " << p;
153  }
154 
155  memoryx::ObjectClassPtr objectClass;
156  const bool isNewClass = !classesSegmentPrx->hasEntityByName(className);
157  {
158  if (!isNewClass)
159  {
160  if (!widget.checkBoxOverride->isChecked())
161  {
162  ARMARX_INFO << "object class " << className << " already exists in memory";
163  continue;
164  }
165  objectClass = memoryx::ObjectClassPtr::dynamicCast(classesSegmentPrx->getEntityByName(className));
166  ARMARX_CHECK_NOT_NULL(objectClass);
167  }
168  else
169  {
170  objectClass = new memoryx::ObjectClass();
171  }
172  }
173 
174  //wrappers
175  objectClass->addWrapper(new memoryx::EntityWrappers::SimoxObjectWrapper(fileManager));
176 
177  //set attributes
178  {
179  objectClass->setName(className);
180  objectClass->clearParentClasses();
181  {
182  const std::string parentClass = widget.lineEditParentClass->text().toStdString();
183  if (!parentClass.empty())
184  {
185  objectClass->addParentClass(parentClass);
186  }
187  }
188  objectClass->setInstanceable(true);
189  }
190 
191  //update simox data
192  {
193  // VirtualRobot::ManipulationObject
194 
196  if (widget.radioButtonWRL->isChecked())
197  {
198  ARMARX_INFO << "setting wrl as model";
199  simoxWrapper->setAndStoreModelIVFiles(fpath, fpath, getFilesDBName());
200  }
201  else
202  {
203  ARMARX_INFO << "reading simox xml";
204  simoxWrapper->setAndStoreManipulationFile(fpath, getFilesDBName());
205  }
206  if (widget.checkBoxScale->isChecked() || widget.checkBoxBBDensity->isChecked())
207  {
208  bool change = false;
209  Eigen::Vector3f bbmin;
210  Eigen::Vector3f bbmax;
211  auto mo = simoxWrapper->getManipulationObject();
212  auto col = mo->getCollisionModel();
213  ARMARX_CHECK_EXPRESSION(col->getTriMeshModel()->getSize(bbmin, bbmax));
214  Eigen::Vector3f bbsz = bbmax - bbmin;
215 
216  if (widget.checkBoxBBDensity->isChecked())
217  {
218  const float vol = bbsz(0) * bbsz(1) * bbsz(2);
219  const float mass = vol * widget.doubleSpinBoxBBDensity->value();
220  if (mo->getMass() == mass)
221  {
222  change = true;
223  mo->setMass(mass);
224  }
225  }
226  if (widget.checkBoxScale->isChecked())
227  {
228  const double sidesz = bbsz(widget.spinBoxScaleDim->value());
229  bool doScale = false;
230  float factor = 1;
231  if (sidesz > widget.doubleSpinBoxScaleMax->value())
232  {
233  change = true;
234  doScale = true;
235  factor = widget.doubleSpinBoxScaleMax->value() / sidesz;
236  }
237  else if (sidesz < widget.doubleSpinBoxScaleMin->value())
238  {
239  change = true;
240  doScale = true;
241  factor = widget.doubleSpinBoxScaleMin->value() / sidesz;
242  }
243  if (doScale)
244  {
245  ARMARX_INFO << "scaling mesh with factor " << factor;
246  const Eigen::Vector3f scalev {factor, factor, factor};
247  auto triNew = col->getTriMeshModel()->clone(scalev);
248  auto moNew = VirtualRobot::ManipulationObject::createFromMesh(triNew);
249  moNew->setMass(mo->getMass());
250  moNew->setInertiaMatrix(mo->getInertiaMatrix());
251  moNew->setCoMLocal(mo->getCoMLocal());
252  const std::string meshName = tmpdir + className + ".wrl";
253  moNew->getVisualization()->setFilename(meshName, false);
254  moNew->getCollisionModel()->getVisualization()->setFilename(meshName, false);
255  mo = moNew;
256  }
257  }
258  if (change)
259  {
260  mo->setName(className);
261  mo->saveModelFiles(tmpdir, false);
262  const std::string tmpxml = tmpdir + className + ".xml";
263  std::ofstream{tmpxml} << mo->toXML(tmpdir);
264 
265  ARMARX_INFO << "reading generated xml";
266  simoxWrapper->setAndStoreManipulationFile(tmpxml, getFilesDBName());
267  }
268  }
269  }
270 
271  //add or update
272  if (!widget.checkBoxDryRun->isChecked())
273  {
274  if (isNewClass)
275  {
276  ARMARX_INFO << "adding " << className;
277  const std::string id = classesSegmentPrx->addEntity(objectClass);
278  ARMARX_IMPORTANT << "added class " << objectClass << " with id " << id;
279  }
280  else
281  {
282  ARMARX_INFO << "updating " << className;
283  const std::string id = objectClass->getId();
284  classesSegmentPrx->updateEntity(id, objectClass);
285  ARMARX_IMPORTANT << "updated class " << objectClass << " with id " << id;
286  }
287  }
288  }
289 }
LoadObjectsIntoMemoryWidgetController.h
ARMARX_IMPORTANT
#define ARMARX_IMPORTANT
Definition: Logging.h:183
ARMARX_CHECK_NOT_NULL
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
Definition: ExpressionException.h:206
armarx::LoadObjectsIntoMemoryWidgetController::getConfigDialog
virtual QPointer< QDialog > getConfigDialog(QWidget *parent) override
getConfigDialog returns a pointer to the a configuration widget of this controller.
Definition: LoadObjectsIntoMemoryWidgetController.cpp:57
IceInternal::Handle< ObjectClass >
armarx::LoadObjectsIntoMemoryWidgetController::updateDBs
void updateDBs()
Definition: LoadObjectsIntoMemoryWidgetController.cpp:67
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:926
armarx::LoadObjectsIntoMemoryWidgetController::LoadObjectsIntoMemoryWidgetController
LoadObjectsIntoMemoryWidgetController()
Controller Constructor.
Definition: LoadObjectsIntoMemoryWidgetController.cpp:41
MemoryXCoreObjectFactories.h
memoryx::ObjectClass
Definition: ObjectClass.h:37
memoryx::EntityWrappers::SimoxObjectWrapper
SimoxObjectWrapper offers a simplified access to the Simox ManipulationObject (i.e visualization,...
Definition: SimoxObjectWrapper.h:46
armarx::to_string
const std::string & to_string(const std::string &s)
Definition: StringHelpers.h:40
ExpressionException.h
SimoxObjectWrapper.h
ARMARX_CHECK_EXPRESSION
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
Definition: ExpressionException.h:73
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
memoryx::GridFileManager
GridFileManager provides utility functions for working with files in Mongo GridFS and links to them s...
Definition: GridFileManager.h:42
armarx::LoadObjectsIntoMemoryWidgetController::onConnectComponent
void onConnectComponent() override
Definition: LoadObjectsIntoMemoryWidgetController.cpp:47
armarx::ArmarXWidgetController::getWidget
virtual QPointer< QWidget > getWidget()
getWidget returns a pointer to the a widget of this controller.
Definition: ArmarXWidgetController.cpp:54
ARMARX_CHECK_EQUAL
#define ARMARX_CHECK_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
Definition: ExpressionException.h:130
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
armarx::SimpleConfigDialog
A config-dialog containing one (or multiple) proxy finders.
Definition: SimpleConfigDialog.h:84
armarx::LoadObjectsIntoMemoryWidgetController::addObjects
void addObjects()
Definition: LoadObjectsIntoMemoryWidgetController.cpp:78