VisualizationObject.cpp
Go to the documentation of this file.
1 #include "VisualizationObject.h"
2 
4 
8 
9 #include <VirtualRobot/ManipulationObject.h>
10 #include <VirtualRobot/SceneObject.h>
11 #include <VirtualRobot/XML/RobotIO.h>
12 #include <VirtualRobot/XML/ObjectIO.h>
13 #include <VirtualRobot/Visualization/CoinVisualization/CoinVisualization.h>
14 #include <VirtualRobot/Import/MeshImport/AssimpReader.h>
15 
16 #include <SimoxUtility/algorithm/string/string_tools.h>
17 
18 namespace armarx::viz::coin
19 {
20 
21  namespace
22  {
23  std::string findObjectInArmarXObjects(const std::string& filename)
24  {
25  IceUtil::Time start = IceUtil::Time::now();
26  std::string objectName = std::filesystem::path(filename).filename().stem();
27  // ARMARX_INFO << "Trying to find object '" << objectName << "' in ArmarXObjects.";
28 
29  std::string fullFilename;
30  std::stringstream ss;
31 
32  armarx::ObjectFinder objectFinder;
33  if (std::optional<armarx::ObjectInfo> info = objectFinder.findObject("", objectName))
34  {
35  fullFilename = info->simoxXML().absolutePath;
36  ss << "Found '" << objectName << "' in ArmarXObjects as " << *info << " \nat '" << fullFilename << "'.";
37  }
38  else
39  {
40  ss << "Did not find '" << objectName << "' in ArmarXObjects.";
41  }
42  ss << "\n(Lookup took " << (IceUtil::Time::now() - start).toMilliSecondsDouble() << " ms.)";
43  ARMARX_INFO << ss.str();
44 
45  return fullFilename;
46  }
47 
48 
49  VirtualRobot::ManipulationObjectPtr loadObject(std::string const& project, std::string const& filename)
50  {
51  VirtualRobot::ManipulationObjectPtr result;
52 
53  if (filename.empty())
54  {
55  ARMARX_INFO << deactivateSpam() << "No filename provided for object";
56  return result;
57  }
58 
59  bool checkArmarXObjects = true;
60 
61 
62  // This check cannot be done here!
63  // filename is a relative path in the project
64  // Also the code below does check whether the file is readable!
65  // std::ifstream fs(filename);
66  // if (!fs.good())
67  // {
68 
69  // ARMARX_WARNING << "unable to read from file " << VAROUT(filename);
70  // return result;
71  // }
72 
74  std::string fullFilename;
75  if (!ArmarXDataPath::SearchReadableFile(filename, fullFilename))
76  {
77  fullFilename = "";
78  if (checkArmarXObjects)
79  {
80  fullFilename = findObjectInArmarXObjects(filename);
81  }
82  if (fullFilename.empty())
83  {
85  << "Unable to find readable file for name "
86  << filename;
87  return result;
88  }
89  }
90 
91  try
92  {
93  ARMARX_INFO << "Loading object from " << fullFilename;
94 
95  std::filesystem::path path{fullFilename};
96  const std::string ext = simox::alg::to_lower(path.extension());
97 
98  if (ext == ".wrl" || ext == ".iv")
99  {
100  VirtualRobot::VisualizationFactoryPtr factory = VirtualRobot::VisualizationFactory::fromName("inventor", nullptr);
101  VirtualRobot::VisualizationNodePtr vis = factory->getVisualizationFromFile(fullFilename);
102  result = VirtualRobot::ManipulationObjectPtr(new VirtualRobot::ManipulationObject(filename, vis));
103  }
104  else if (ext == ".xml" || ext == ".moxml")
105  {
106  result = VirtualRobot::ObjectIO::loadManipulationObject(fullFilename);
107 
108  }
109  else if (VirtualRobot::AssimpReader::can_load(fullFilename))
110  {
111  const auto& tri = VirtualRobot::AssimpReader{}.readFileAsTriMesh(fullFilename);
112  result = VirtualRobot::ManipulationObjectPtr(new VirtualRobot::ManipulationObject(filename, tri));
113  }
114  else
115  {
116  ARMARX_WARNING << "Could not load object from file: " << fullFilename
117  << "\nunknown extension '" << ext << "'";
118  }
119  }
120  catch (std::exception const& ex)
121  {
122  ARMARX_WARNING << "Could not load object from file: " << fullFilename
123  << "\nReason: " << ex.what();
124  }
125 
126  return result;
127  }
128 
129  static std::vector<LoadedObject> objectcache;
130 
131  LoadedObject getObjectFromCache(std::string const& project, std::string const& filename)
132  {
133  // We can use a global variable, since this code is only executed in the GUI thread
134 
135  LoadedObject result;
136 
137  for (LoadedObject const& loaded : objectcache)
138  {
139  if (loaded.project == project && loaded.filename == filename)
140  {
141  result = loaded;
142  result.object = loaded.object;
143  return result;
144  }
145  }
146 
147  result.project = project;
148  result.filename = filename;
149  result.object = loadObject(project, filename);
150 
151 
152  objectcache.push_back(result);
153 
154  return result;
155  }
156  }
157 
159  {
160  bool fileChanged = loaded.project != element.project || loaded.filename != element.filename;
161  if (fileChanged)
162  {
163  // The robot file changed, so reload the robot
164  loaded = getObjectFromCache(element.project, element.filename);
165  }
166  if (!loaded.object)
167  {
169  << "Object will not be visualized since it could not be loaded."
170  << "\nID: " << element.id
171  << "\nProject: " << element.project
172  << "\nFilename: " << element.filename;
173  return true;
174  }
175 
176  bool drawStyleChanged = loadedDrawStyle != element.drawStyle;
177  if (fileChanged || drawStyleChanged)
178  {
179  recreateVisualizationNodes(element.drawStyle);
180  loadedDrawStyle = element.drawStyle;
181  }
182 
183  if (loadedDrawStyle & data::ModelDrawStyle::OVERRIDE_COLOR)
184  {
185  int numChildren = node->getNumChildren();
186  for (int i = 0; i < numChildren; i++)
187  {
188  SoSeparator* nodeSep = static_cast<SoSeparator*>(node->getChild(i));
189  // The first entry must be a SoMaterial (see recreateVisualizationNodes)
190  SoMaterial* m = dynamic_cast<SoMaterial*>(nodeSep->getChild(0));
191  if (!m)
192  {
193  ARMARX_WARNING << "Error at node with index: " << i;
194  continue;
195  }
196 
197  auto color = element.color;
198  const float conv = 1.0f / 255.0f;
199  float a = color.a * conv;
200  SbColor coinColor(conv * color.r, conv * color.g, conv * color.b);
201  m->diffuseColor = coinColor;
202  m->ambientColor = coinColor;
203  m->transparency = 1.0f - a;
204  m->setOverride(true);
205  }
206  }
207 
208  return true;
209  }
210 
212  {
213  VirtualRobot::SceneObject::VisualizationType visuType = VirtualRobot::SceneObject::Full;
214  if (drawStyle & data::ModelDrawStyle::COLLISION)
215  {
216  visuType = VirtualRobot::SceneObject::Collision;
217  }
218 
219  node->removeAllChildren();
220 
221  VirtualRobot::ManipulationObject& object = *loaded.object;
222 
223  SoSeparator* nodeSep = new SoSeparator;
224 
225  // This material is used to color the nodes individually
226  // We require it to be the first node in the separator for updates
227  SoMaterial* nodeMat = new SoMaterial;
228  nodeMat->setOverride(false);
229  nodeSep->addChild(nodeMat);
230 
231  VirtualRobot::CoinVisualizationPtr nodeVisu = object.getVisualization<VirtualRobot::CoinVisualization>(visuType);
232  if (nodeVisu)
233  {
234  SoNode* sepRobNode = nodeVisu->getCoinVisualization();
235 
236  if (sepRobNode)
237  {
238  nodeSep->addChild(sepRobNode);
239  }
240  }
241 
242  node->addChild(nodeSep);
243  }
244 
246  {
247  objectcache.clear();
248  }
249 }
armarx::viz::coin::VisualizationObject::loaded
LoadedObject loaded
Definition: VisualizationObject.h:26
armarx::viz::coin::VisualizationObject::loadedDrawStyle
int loadedDrawStyle
Definition: VisualizationObject.h:27
armarx::viz::coin::VisualizationObject::ElementType
data::ElementObject ElementType
Definition: VisualizationObject.h:20
armarx::viz::coin::clearObjectCache
void clearObjectCache()
Definition: VisualizationObject.cpp:245
armarx::ArmarXDataPath::FindPackageAndAddDataPath
static bool FindPackageAndAddDataPath(const std::string &packageName)
Search for the package and add its data path if it was found.
Definition: ArmarXDataPath.cpp:829
project
std::string project
Definition: VisualizationRobot.cpp:83
armarx::viz::coin::LoadedObject::filename
std::string filename
Definition: VisualizationObject.h:14
deactivateSpam
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition: Logging.cpp:72
armarx::ObjectFinder
Used to find objects in the ArmarX objects repository [1] (formerly [2]).
Definition: ObjectFinder.h:23
armarx::ctrlutil::a
double a(double t, double a0, double j)
Definition: CtrlUtil.h:45
armarx::viz::coin::TypedElementVisualization< SoSeparator >::node
NodeType * node
Definition: ElementVisualizer.h:68
CoinVisualizationPtr
boost::shared_ptr< VirtualRobot::CoinVisualization > CoinVisualizationPtr
Definition: ManipulatorVisualization.h:52
armarx::viz::coin::VisualizationObject::recreateVisualizationNodes
void recreateVisualizationNodes(int drawStyle)
Definition: VisualizationObject.cpp:211
armarx::viz::coin::VisualizationObject::update
bool update(ElementType const &element)
Definition: VisualizationObject.cpp:158
armarx::viz::coin::LoadedObject::object
VirtualRobot::ManipulationObjectPtr object
Definition: VisualizationObject.h:15
filename
std::string filename
Definition: VisualizationRobot.cpp:84
armarx::armem::Time
armarx::core::time::DateTime Time
Definition: forward_declarations.h:13
armarx::ArmarXDataPath::SearchReadableFile
static bool SearchReadableFile(const std::string &querryFileName, std::string &resultFileName, bool verbose=true)
Definition: ArmarXDataPath.cpp:218
CMakePackageFinder.h
armarx::viz::coin::LoadedObject::project
std::string project
Definition: VisualizationObject.h:13
armarx::viz::coin
Definition: ElementVisualizer.cpp:11
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
armarx::ObjectFinder::findObject
std::optional< ObjectInfo > findObject(const std::string &dataset, const std::string &name) const
Definition: ObjectFinder.cpp:65
Logging.h
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:186
ArmarXDataPath.h
ObjectFinder.h
VisualizationObject.h