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 
25 
26 #include <chrono>
27 #include <filesystem>
28 #include <string>
29 
30 #include <VirtualRobot/CollisionDetection/CollisionModel.h>
31 #include <VirtualRobot/Visualization/TriMeshUtils.h>
32 #include <VirtualRobot/Visualization/VisualizationNode.h>
33 
35 
38 
39 using namespace armarx;
40 
42 {
43  widget.setupUi(getWidget());
44  connect(widget.pushButtonAddObjects, SIGNAL(clicked()), this, SLOT(addObjects()));
45 }
46 
47 void
49 {
50  priorPrx =
51  getProxy<memoryx::PriorKnowledgeInterfacePrx>(dialog->getProxyName("PriorKnowledge"));
52  classesSegmentPrx = priorPrx->getObjectClassesSegment();
53 
54  databasePrx = priorPrx->getCommonStorage();
55  fileManager.reset(new memoryx::GridFileManager(databasePrx));
56  QMetaObject::invokeMethod(this, "updateDBs", Qt::QueuedConnection);
57 }
58 
59 QPointer<QDialog>
61 {
62  if (!dialog)
63  {
64  dialog = new SimpleConfigDialog(parent);
65  dialog->addProxyFinder<memoryx::PriorKnowledgeInterfacePrx>(
66  {"PriorKnowledge", "PriorKnowledge", "PriorKnowledge*"});
67  }
68  return qobject_cast<SimpleConfigDialog*>(dialog);
69 }
70 
71 void
73 {
74  const NameList dbNames = databasePrx->getDBNames();
75  widget.comboBoxDBs->clear();
76  for (const auto& db : dbNames)
77  {
78  widget.comboBoxDBs->addItem(QString::fromStdString(db));
79  }
80  ARMARX_INFO << "setting list of DBs to: " << dbNames;
81 }
82 
83 void
85 {
86  namespace fs = std::filesystem;
87 
88  const std::string dir = widget.lineEditDir->text().toStdString();
89  const std::string collection = widget.lineEditCollection->text().toStdString();
90  const std::string db = widget.comboBoxDBs->currentText().toStdString();
91  const std::string tmpdir =
92  "/tmp/LoadObjectsIntoMemoryWidget/" +
93  std::to_string(std::chrono::high_resolution_clock::now().time_since_epoch().count()) + "/";
94 
95  fs::create_directories(tmpdir);
96 
97  ARMARX_CHECK_EXPRESSION(!dir.empty());
98  ARMARX_CHECK_EXPRESSION(fs::exists(dir));
99  ARMARX_CHECK_EQUAL(collection.empty(), db.empty());
100 
101  //set write collection
102  if (!collection.empty())
103  {
104  const std::string fullCollectionName = db + "." + collection;
105  ARMARX_INFO << "setting write collection to: " << fullCollectionName;
106  memoryx::CollectionInterfacePrx coll = databasePrx->requestCollection(fullCollectionName);
107  ARMARX_CHECK_NOT_NULL(coll);
108  classesSegmentPrx->setWriteCollection(coll);
109  ARMARX_INFO << "setting write collection done";
110  }
111 
112  for (fs::directory_iterator dit{dir}; dit != fs::directory_iterator{}; ++dit)
113  {
114  const fs::path p = *dit;
115  if (!fs::is_regular_file(p))
116  {
117  ARMARX_INFO << "skipping non file " << p;
118  continue;
119  }
120  const std::string fname = p.filename().string();
121  const std::string fpath = p.string();
122  const auto endswith = [&](const std::string& suff)
123  {
124  const auto pos = fname.rfind(suff);
125  return pos != std::string::npos && pos == (fname.size() - suff.size());
126  };
127  std::string className = fname;
128 
129 
130  //trim name
131  {
132  if (widget.radioButtonWRL->isChecked())
133  {
134  if (endswith(".wrl"))
135  {
136  className = className.substr(0, className.size() - 4);
137  }
138  else if (endswith(".iv"))
139  {
140  className = className.substr(0, className.size() - 3);
141  }
142  else
143  {
144  ARMARX_INFO << "skipping non wrl/iv file " << p;
145  continue;
146  }
147  }
148  else
149  {
150  if (endswith(".xml"))
151  {
152  className = className.substr(0, className.size() - 4);
153  }
154  else
155  {
156  ARMARX_INFO << "skipping non xml file " << p;
157  continue;
158  }
159  }
160  ARMARX_INFO << "processing file " << p;
161  }
162 
163  memoryx::ObjectClassPtr objectClass;
164  const bool isNewClass = !classesSegmentPrx->hasEntityByName(className);
165  {
166  if (!isNewClass)
167  {
168  if (!widget.checkBoxOverride->isChecked())
169  {
170  ARMARX_INFO << "object class " << className << " already exists in memory";
171  continue;
172  }
173  objectClass = memoryx::ObjectClassPtr::dynamicCast(
174  classesSegmentPrx->getEntityByName(className));
175  ARMARX_CHECK_NOT_NULL(objectClass);
176  }
177  else
178  {
179  objectClass = new memoryx::ObjectClass();
180  }
181  }
182 
183  //wrappers
184  objectClass->addWrapper(new memoryx::EntityWrappers::SimoxObjectWrapper(fileManager));
185 
186  //set attributes
187  {
188  objectClass->setName(className);
189  objectClass->clearParentClasses();
190  {
191  const std::string parentClass = widget.lineEditParentClass->text().toStdString();
192  if (!parentClass.empty())
193  {
194  objectClass->addParentClass(parentClass);
195  }
196  }
197  objectClass->setInstanceable(true);
198  }
199 
200  //update simox data
201  {
202  // VirtualRobot::ManipulationObject
203 
205  objectClass->getWrapper<memoryx::EntityWrappers::SimoxObjectWrapper>();
206  if (widget.radioButtonWRL->isChecked())
207  {
208  ARMARX_INFO << "setting wrl as model";
209  simoxWrapper->setAndStoreModelIVFiles(fpath, fpath, getFilesDBName());
210  }
211  else
212  {
213  ARMARX_INFO << "reading simox xml";
214  simoxWrapper->setAndStoreManipulationFile(fpath, getFilesDBName());
215  }
216  if (widget.checkBoxScale->isChecked() || widget.checkBoxBBDensity->isChecked())
217  {
218  bool change = false;
219  Eigen::Vector3f bbmin;
220  Eigen::Vector3f bbmax;
221  auto mo = simoxWrapper->getManipulationObject();
222  auto col = mo->getCollisionModel();
223  ARMARX_CHECK_EXPRESSION(col->getTriMeshModel()->getSize(bbmin, bbmax));
224  Eigen::Vector3f bbsz = bbmax - bbmin;
225 
226  if (widget.checkBoxBBDensity->isChecked())
227  {
228  const float vol = bbsz(0) * bbsz(1) * bbsz(2);
229  const float mass = vol * widget.doubleSpinBoxBBDensity->value();
230  if (mo->getMass() == mass)
231  {
232  change = true;
233  mo->setMass(mass);
234  }
235  }
236  if (widget.checkBoxScale->isChecked())
237  {
238  const double sidesz = bbsz(widget.spinBoxScaleDim->value());
239  bool doScale = false;
240  float factor = 1;
241  if (sidesz > widget.doubleSpinBoxScaleMax->value())
242  {
243  change = true;
244  doScale = true;
245  factor = widget.doubleSpinBoxScaleMax->value() / sidesz;
246  }
247  else if (sidesz < widget.doubleSpinBoxScaleMin->value())
248  {
249  change = true;
250  doScale = true;
251  factor = widget.doubleSpinBoxScaleMin->value() / sidesz;
252  }
253  if (doScale)
254  {
255  ARMARX_INFO << "scaling mesh with factor " << factor;
256  const Eigen::Vector3f scalev{factor, factor, factor};
257  auto triNew = col->getTriMeshModel()->clone(scalev);
258  auto moNew = VirtualRobot::ManipulationObject::createFromMesh(triNew);
259  moNew->setMass(mo->getMass());
260  moNew->setInertiaMatrix(mo->getInertiaMatrix());
261  moNew->setCoMLocal(mo->getCoMLocal());
262  const std::string meshName = tmpdir + className + ".wrl";
263  moNew->getVisualization()->setFilename(meshName, false);
264  moNew->getCollisionModel()->getVisualization()->setFilename(meshName,
265  false);
266  mo = moNew;
267  }
268  }
269  if (change)
270  {
271  mo->setName(className);
272  mo->saveModelFiles(tmpdir, false);
273  const std::string tmpxml = tmpdir + className + ".xml";
274  std::ofstream{tmpxml} << mo->toXML(tmpdir);
275 
276  ARMARX_INFO << "reading generated xml";
277  simoxWrapper->setAndStoreManipulationFile(tmpxml, getFilesDBName());
278  }
279  }
280  }
281 
282  //add or update
283  if (!widget.checkBoxDryRun->isChecked())
284  {
285  if (isNewClass)
286  {
287  ARMARX_INFO << "adding " << className;
288  const std::string id = classesSegmentPrx->addEntity(objectClass);
289  ARMARX_IMPORTANT << "added class " << objectClass << " with id " << id;
290  }
291  else
292  {
293  ARMARX_INFO << "updating " << className;
294  const std::string id = objectClass->getId();
295  classesSegmentPrx->updateEntity(id, objectClass);
296  ARMARX_IMPORTANT << "updated class " << objectClass << " with id " << id;
297  }
298  }
299  }
300 }
LoadObjectsIntoMemoryWidgetController.h
ARMARX_IMPORTANT
#define ARMARX_IMPORTANT
Definition: Logging.h:190
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:60
IceInternal::Handle< ObjectClass >
armarx::LoadObjectsIntoMemoryWidgetController::updateDBs
void updateDBs()
Definition: LoadObjectsIntoMemoryWidgetController.cpp:72
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:855
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:41
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:181
memoryx::GridFileManager
GridFileManager provides utility functions for working with files in Mongo GridFS and links to them s...
Definition: GridFileManager.h:41
armarx::LoadObjectsIntoMemoryWidgetController::onConnectComponent
void onConnectComponent() override
Definition: LoadObjectsIntoMemoryWidgetController.cpp:48
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:27
armarx::SimpleConfigDialog
A config-dialog containing one (or multiple) proxy finders.
Definition: SimpleConfigDialog.h:84
armarx::LoadObjectsIntoMemoryWidgetController::addObjects
void addObjects()
Definition: LoadObjectsIntoMemoryWidgetController.cpp:84