Gazebo Rendering

API Reference

8.2.3
BaseVisual.hh
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015 Open Source Robotics Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 #ifndef GZ_RENDERING_BASE_BASEVISUAL_HH_
18 #define GZ_RENDERING_BASE_BASEVISUAL_HH_
19 
20 #include <map>
21 #include <string>
22 
23 #include <gz/math/AxisAlignedBox.hh>
24 
25 #include "gz/rendering/Visual.hh"
26 #include "gz/rendering/Storage.hh"
29 
30 namespace gz
31 {
32  namespace rendering
33  {
34  inline namespace GZ_RENDERING_VERSION_NAMESPACE {
35  //
36  template <class T>
37  class BaseVisual :
38  public virtual Visual,
39  public virtual T
40  {
41  protected: BaseVisual();
42 
43  public: virtual ~BaseVisual();
44 
45  public: virtual math::Pose3d LocalPose() const override;
46 
47  public: virtual void SetLocalPose(const math::Pose3d &_pose) override;
48 
49  public: virtual unsigned int GeometryCount() const override;
50 
51  public: virtual bool HasGeometry(ConstGeometryPtr _geometry) const
52  override;
53 
54  public: virtual GeometryPtr GeometryByIndex(unsigned int _index) const
55  override;
56 
57  public: virtual void AddGeometry(GeometryPtr _geometry) override;
58 
59  public: virtual GeometryPtr RemoveGeometry(GeometryPtr _geometry)
60  override;
61 
62  public: virtual GeometryPtr RemoveGeometryByIndex(unsigned int _index)
63  override;
64 
65  public: virtual void RemoveGeometries() override;
66 
67  public: virtual void SetMaterial(const std::string &_name,
68  bool _unique = true) override;
69 
70  public: virtual void SetMaterial(MaterialPtr _material,
71  bool _unique = true) override;
72 
73  public: virtual void SetChildMaterial(MaterialPtr _material,
74  bool _unique = true) override;
75 
76  public: virtual void SetGeometryMaterial(MaterialPtr _material,
77  bool _unique = true) override;
78 
79  // Documentation inherited.
80  public: virtual MaterialPtr Material() const override;
81 
82  // Documentation inherited.
83  public: virtual void SetWireframe(bool _show) override;
84 
85  // Documentation inherited.
86  public: virtual bool Wireframe() const override;
87 
88  // Documentation inherited.
89  public: virtual void SetVisible(bool _visible) override;
90 
91  // Documentation inherited.
92  public: virtual bool Static() const override;
93 
94  // Documentation inherited.
95  public: virtual void SetStatic(bool _static) override;
96 
97  // Documentation inherited.
98  public: virtual void SetVisibilityFlags(uint32_t _flags) override;
99 
100  // Documentation inherited.
101  public: virtual uint32_t VisibilityFlags() const override;
102 
103  // Documentation inherited.
104  public: virtual void AddVisibilityFlags(uint32_t _flags) override;
105 
106  // Documentation inherited.
107  public: virtual void RemoveVisibilityFlags(uint32_t _flags) override;
108 
109  // Documentation inherited.
110  public: virtual void PreRender() override;
111 
112  // Documentation inherited
113  public: virtual void Destroy() override;
114 
115  // Documentation inherited.
117  const override;
118 
119  // Documentation inherited.
121  const override;
122 
123  // Documentation inherited.
124  public: virtual VisualPtr Clone(const std::string &_name,
125  NodePtr _newParent) const override;
126 
127  protected: virtual void PreRenderChildren() override;
128 
129  protected: virtual void PreRenderGeometries();
130 
131  protected: virtual GeometryStorePtr Geometries() const = 0;
132 
133  protected: virtual bool AttachGeometry(GeometryPtr _geometry) = 0;
134 
135  protected: virtual bool DetachGeometry(GeometryPtr _geometry) = 0;
136 
138  protected: MaterialPtr material;
139 
141  protected: uint32_t visibilityFlags = GZ_VISIBILITY_ALL;
142 
145 
147  protected: bool wireframe = false;
148  };
149 
151  template <class T>
153  {
154  }
155 
157  template <class T>
159  {
160  }
161 
163  template <class T>
165  {
166  math::Pose3d rawPose = this->RawLocalPose();
167  math::Vector3d scale = this->LocalScale();
168  rawPose.Pos() += rawPose.Rot() * (scale * this->origin);
169  return rawPose;
170  }
171 
173  template <class T>
175  {
176  math::Pose3d rawPose = _pose;
177  math::Vector3d scale = this->LocalScale();
178  rawPose.Pos() -= rawPose.Rot() * (scale * this->origin);
179 
180  if (!rawPose.IsFinite())
181  {
182  gzerr << "Unable to set pose of a node: "
183  << "non-finite (nan, inf) values detected." << std::endl;
184  return;
185  }
186 
187  this->SetRawLocalPose(rawPose);
188  }
189 
191  template <class T>
192  unsigned int BaseVisual<T>::GeometryCount() const
193  {
194  return this->Geometries()->Size();
195  }
196 
198  template <class T>
200  {
201  return this->Geometries()->Contains(_geometry);
202  }
203 
205  template <class T>
206  GeometryPtr BaseVisual<T>::GeometryByIndex(unsigned int _index) const
207  {
208  return this->Geometries()->GetByIndex(_index);
209  }
210 
212  template <class T>
214  {
215  if (this->AttachGeometry(_geometry))
216  {
217  this->Geometries()->Add(_geometry);
218  }
219  }
220 
222  template <class T>
224  {
225  if (this->DetachGeometry(_geometry))
226  {
227  this->Geometries()->Remove(_geometry);
228  }
229  return _geometry;
230  }
231 
233  template <class T>
235  {
236  return this->RemoveGeometry(this->GeometryByIndex(_index));
237  }
238 
240  template <class T>
242  {
243  for (unsigned int i = this->GeometryCount(); i > 0; --i)
244  {
245  this->RemoveGeometryByIndex(i-1);
246  }
247  }
248 
250  template <class T>
251  void BaseVisual<T>::SetMaterial(const std::string &_name, bool _unique)
252  {
253  MaterialPtr mat = this->Scene()->Material(_name);
254  if (mat) this->SetMaterial(mat, _unique);
255  }
256 
258  template <class T>
259  void BaseVisual<T>::SetMaterial(MaterialPtr _material, bool _unique)
260  {
261  _material = (_unique) ? _material->Clone() : _material;
262  this->SetChildMaterial(_material, false);
263  this->SetGeometryMaterial(_material, false);
264  this->material = _material;
265  }
266 
268  template <class T>
269  void BaseVisual<T>::SetChildMaterial(MaterialPtr _material, bool _unique)
270  {
271  unsigned int count = this->ChildCount();
272  _material = (_unique && count > 0) ? _material->Clone() : _material;
273 
274  auto children_ =
275  std::dynamic_pointer_cast<BaseStore<gz::rendering::Node, T>>(
276  this->Children());
277  if (!children_)
278  {
279  gzerr << "Cast failed in BaseVisual::SetChildMaterial" << std::endl;
280  return;
281  }
282  for (auto it = children_->Begin(); it != children_->End(); ++it)
283  {
284  VisualPtr visual = std::dynamic_pointer_cast<Visual>(*it);
285  if (visual) visual->SetMaterial(_material, false);
286  }
287  }
288 
290  template <class T>
291  void BaseVisual<T>::SetGeometryMaterial(MaterialPtr _material, bool _unique)
292  {
293  unsigned int count = this->GeometryCount();
294  _material = (_unique && count > 0) ? _material->Clone() : _material;
295 
296  for (unsigned int i = 0; i < count; ++i)
297  {
298  GeometryPtr geometry = this->GeometryByIndex(i);
299  geometry->SetMaterial(_material, false);
300  }
301  }
302 
304  template <class T>
306  {
307  return this->material;
308  }
309 
311  template <class T>
313  {
314  // T::PreRender() resolves to BaseNode<T>::PreRender(), which already
315  // recurses into this visual's children through the virtual
316  // PreRenderChildren(). Calling PreRenderChildren() a second time here
317  // would pre-render every child twice, compounding to O(2^depth)
318  // redundant visits down the scene graph. Children are therefore
319  // pre-rendered exactly once, via T::PreRender().
320  T::PreRender();
321  this->PreRenderGeometries();
322  }
323 
325  template <class T>
327  {
328  this->Geometries()->DestroyAll();
329  this->Children()->RemoveAll();
330  this->material.reset();
331  T::Destroy();
332  }
333 
335  template <class T>
337  {
338  auto children_ =
339  std::dynamic_pointer_cast<BaseStore<gz::rendering::Node, T>>(
340  this->Children());
341  if (!children_)
342  {
343  gzerr << "Cast failed in BaseVisual::PreRenderChildren" << std::endl;
344  return;
345  }
346  for (auto it = children_->Begin(); it != children_->End(); ++it)
347  {
348  (*it)->PreRender();
349  }
350  }
351 
353  template <class T>
355  {
356  unsigned int count = this->GeometryCount();
357 
358  for (unsigned int i = 0; i < count; ++i)
359  {
360  GeometryPtr geometry = this->GeometryByIndex(i);
361  geometry->PreRender();
362  }
363  }
364 
366  template <class T>
368  {
369  return this->wireframe;
370  }
371 
373  template <class T>
375  {
376  gzerr << "SetWireframe(" << _show << ") not supported for "
377  << "render engine: " << this->Scene()->Engine()->Name()
378  << std::endl;
379  }
380 
382  template <class T>
383  void BaseVisual<T>::SetVisible(bool _visible)
384  {
385  gzerr << "SetVisible(" << _visible << ") not supported for "
386  << "render engine: " << this->Scene()->Engine()->Name()
387  << std::endl;
388  }
389 
391  template <class T>
393  {
394  return false;
395  }
396 
398  template <class T>
399  void BaseVisual<T>::SetStatic(bool _static)
400  {
401  gzerr << "SetStatic(" << _static << ") not supported for "
402  << "render engine: " << this->Scene()->Engine()->Name()
403  << std::endl;
404  }
405 
407  template <class T>
409  {
411 
412  // Recursively loop through child visuals
413  auto childNodes =
414  std::dynamic_pointer_cast<BaseStore<gz::rendering::Node, T>>(
415  this->Children());
416  if (!childNodes)
417  {
418  gzerr << "Cast failed in BaseVisual::LocalBoundingBox" << std::endl;
419  return box;
420  }
421  for (auto it = childNodes->Begin(); it != childNodes->End(); ++it)
422  {
423  VisualPtr visual = std::dynamic_pointer_cast<Visual>(*it);
424  if (visual)
425  {
426  gz::math::AxisAlignedBox aabb = visual->LocalBoundingBox();
427  if (aabb.Min().IsFinite() && aabb.Max().IsFinite())
428  box.Merge(aabb);
429  }
430  }
431  return box;
432  }
433 
435  template <class T>
437  {
439 
440  // Recursively loop through child visuals
441  auto childNodes =
442  std::dynamic_pointer_cast<BaseStore<gz::rendering::Node, T>>(
443  this->Children());
444  if (!childNodes)
445  {
446  gzerr << "Cast failed in BaseVisual::BoundingBox" << std::endl;
447  return box;
448  }
449  for (auto it = childNodes->Begin(); it != childNodes->End(); ++it)
450  {
451  VisualPtr visual = std::dynamic_pointer_cast<Visual>(*it);
452  if (visual)
453  box.Merge(visual->BoundingBox());
454  }
455  return box;
456  }
457 
459  template <class T>
460  void BaseVisual<T>::AddVisibilityFlags(uint32_t _flags)
461  {
462  this->SetVisibilityFlags(this->VisibilityFlags() | _flags);
463  }
464 
466  template <class T>
468  {
469  this->SetVisibilityFlags(this->VisibilityFlags() & ~(_flags));
470  }
471 
473  template <class T>
474  void BaseVisual<T>::SetVisibilityFlags(uint32_t _flags)
475  {
476  this->visibilityFlags = _flags;
477 
478  // recursively set child visuals' visibility flags
479  auto childNodes =
480  std::dynamic_pointer_cast<BaseStore<gz::rendering::Node, T>>(
481  this->Children());
482  if (!childNodes)
483  {
484  gzerr << "Cast failed in BaseVisual::SetVisibiltyFlags" << std::endl;
485  return;
486  }
487  for (auto it = childNodes->Begin(); it != childNodes->End(); ++it)
488  {
489  VisualPtr visual = std::dynamic_pointer_cast<Visual>(*it);
490  if (visual)
491  visual->SetVisibilityFlags(_flags);
492  }
493  }
494 
496  template <class T>
498  {
499  return this->visibilityFlags;
500  }
501 
503  template <class T>
505  NodePtr _newParent) const
506  {
507  ScenePtr scene_ = this->Scene();
508  if (nullptr == scene_)
509  {
510  gzerr << "Cloning a visual failed because the visual to be cloned is "
511  << "not attached to a scene.\n";
512  return nullptr;
513  }
514  VisualPtr result;
515  if (_name.empty())
516  result = scene_->CreateVisual();
517  else
518  result = scene_->CreateVisual(_name);
519 
520  if (nullptr != _newParent)
521  {
522  auto parentScene = _newParent->Scene();
523  if (nullptr != parentScene && parentScene->Id() != scene_->Id())
524  {
525  gzerr << "Cloning a visual failed because the desired parent of the "
526  << "cloned visual belongs to a different scene.\n";
527  scene_->DestroyVisual(result);
528  return nullptr;
529  }
530  _newParent->AddChild(result);
531  }
532 
533  result->SetOrigin(this->Origin());
534  result->SetInheritScale(this->InheritScale());
535  result->SetLocalScale(this->LocalScale());
536  result->SetLocalPose(this->LocalPose());
537  result->SetVisibilityFlags(this->VisibilityFlags());
538  result->SetWireframe(this->Wireframe());
539 
540  // if the visual that was cloned has child visuals, clone those as well
541  auto children_ =
542  std::dynamic_pointer_cast<BaseStore<gz::rendering::Node, T>>(
543  this->Children());
544  if (!children_)
545  {
546  gzerr << "Cast failed in BaseVisual::Clone\n";
547  scene_->DestroyVisual(result);
548  return nullptr;
549  }
550  for (auto it = children_->Begin(); it != children_->End(); ++it)
551  {
552  VisualPtr visual = std::dynamic_pointer_cast<Visual>(*it);
553  // recursively delete all cloned visuals if the child cannot be
554  // retrieved, or if cloning the child visual failed
555  if (!visual || !visual->Clone("", result))
556  {
557  gzerr << "Cloning a child visual failed.\n";
558  scene_->DestroyVisual(result, true);
559  return nullptr;
560  }
561  }
562 
563  for (unsigned int i = 0; i < this->GeometryCount(); ++i)
564  result->AddGeometry(this->GeometryByIndex(i)->Clone());
565 
566  if (this->Material())
567  result->SetMaterial(this->Material());
568 
569  for (const auto &[key, val] : this->userData)
570  result->SetUserData(key, val);
571 
572  // set static property after the geometry is added
573  result->SetStatic(this->Static());
574  return result;
575  }
576  }
577  }
578 }
579 #endif