[ros-geometric-shapes] 01/01: New upstream version 0.5.2

Jochen Sprickerhof jspricke at moszumanska.debian.org
Sun Oct 23 04:48:41 UTC 2016


This is an automated email from the git hooks/post-receive script.

jspricke pushed a commit to annotated tag upstream/0.5.2
in repository ros-geometric-shapes.

commit f923e28c41d071e29bca90fe515d3ac2edddedd1
Author: Jochen Sprickerhof <git at jochen.sprickerhof.de>
Date:   Fri Oct 21 17:21:38 2016 +0200

    New upstream version 0.5.2
---
 .travis.yml                         |   9 +-
 CHANGELOG.rst                       |   9 ++
 CMakeLists.txt                      |   2 +-
 README.md                           |   4 +-
 include/geometric_shapes/bodies.h   |  20 ++--
 include/geometric_shapes/shapes.h   |   5 +-
 package.xml                         |   2 +-
 src/bodies.cpp                      |  18 +--
 src/mesh_operations.cpp             |  38 +++++--
 test/CMakeLists.txt                 |   6 +
 test/resources/cube.stl             | Bin 0 -> 684 bytes
 test/resources/triangle.stl         |   9 ++
 test/resources/triangle_10m.dae     |  35 ++++++
 test/resources/triangle_1m.dae      |  35 ++++++
 test/resources/triangle_no_unit.dae |  34 ++++++
 test/resources/triangle_no_up.dae   |  35 ++++++
 test/resources/triangle_x_up.dae    |  36 ++++++
 test/resources/triangle_y_up.dae    |  36 ++++++
 test/resources/triangle_z_up.dae    |  36 ++++++
 test/test_create_mesh.cpp           | 117 ++++++++++++++++++++
 test/test_loaded_meshes.cpp         | 212 ++++++++++++++++++++++++++++++++++++
 test/test_point_inclusion.cpp       |   3 +-
 22 files changed, 662 insertions(+), 39 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 6d3937a..28d24b8 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,14 +9,11 @@ compiler:
 notifications:
   email:
     recipients:
-      - dave at dav.ee
+      - 130s at 2000.jukuin.keio.ac.jp
 env:
   matrix:
-    - ROS_DISTRO="kinetic"  ROS_REPOSITORY_PATH=http://packages.ros.org/ros/ubuntu
-    - ROS_DISTRO="kinetic"  ROS_REPOSITORY_PATH=http://packages.ros.org/ros-shadow-fixed/ubuntu
-#matrix:
-#   allow_failures:
-#     - env: ROS_DISTRO="kinetic" ROS_REPOSITORY_PATH=http://packages.ros.org/ros/ubuntu         UPSTREAM_WORKSPACE=https://raw.githubusercontent.com/ros-planning/moveit_docs/kinetic-devel/moveit.rosinstall
+    - ROS_DISTRO=kinetic  ROS_REPO=ros              UPSTREAM_WORKSPACE=https://raw.githubusercontent.com/ros-planning/moveit/kinetic-devel/moveit.rosinstall
+    - ROS_DISTRO=kinetic  ROS_REPO=ros-shadow-fixed UPSTREAM_WORKSPACE=https://raw.githubusercontent.com/ros-planning/moveit/kinetic-devel/moveit.rosinstall
 before_script:
   - git clone -q https://github.com/ros-planning/moveit_ci.git .moveit_ci
 script:
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 8825858..61475ed 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -2,6 +2,15 @@
 Changelog for package geometric_shapes
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+0.5.2 (2016-10-20)
+------------------
+* [fix] mesh with too many vertices (`#39 <https://github.com/ros-planning/geometric_shapes/issues/39>`_) (`#60 <https://github.com/ros-planning/geometric_shapes/issues/60>`_)
+* [fix] gcc6 build error (`#56 <https://github.com/ros-planning/geometric_shapes/issues/56>`_)
+* [fix] Clear root transformation on imported Collada meshes. `#52 <https://github.com/ros-planning/geometric_shapes/issues/52>`_
+* [improve] relax mesh containment test (`#58 <https://github.com/ros-planning/geometric_shapes/issues/58>`_)
+* [maintenance] Switch boost::shared_ptr to std::shared_ptr. `#57 <https://github.com/ros-planning/geometric_shapes/pull/57>`_
+* Contributors: Dave Coleman, Isaac I.Y. Saito, Lukas Bulwahn, Maarten de Vries, Michael Goerner
+
 0.5.1 (2016-08-23)
 ------------------
 * add c++11 safe-guards to the respective headers (`#51 <https://github.com/ros-planning/geometric_shapes/issues/51>`_)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1fab981..51065b8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -54,7 +54,7 @@ if (HAVE_QHULL_2011)
 endif()
 
 include_directories(include)
-include_directories(SYSTEM ${EIGEN3_INCLUDE_DIR} ${Boost_INCLUDE_DIR} ${ASSIMP_INCLUDE_DIRS} ${OCTOMAP_INCLUDE_DIRS})
+include_directories(${EIGEN3_INCLUDE_DIR} ${Boost_INCLUDE_DIR} ${ASSIMP_INCLUDE_DIRS} ${OCTOMAP_INCLUDE_DIRS})
 include_directories(${catkin_INCLUDE_DIRS} ${console_bridge_INCLUDE_DIRS})
 
 add_library(${PROJECT_NAME}
diff --git a/README.md b/README.md
index 95e6b30..83bb812 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,4 @@
-geometric_shapes
-================
+# Geometric Shapes
 
 This package contains generic definitions of geometric shapes and bodies, as well as tools for operating on shape messages.
 Shapes represent only the form of an object.
@@ -13,6 +12,7 @@ Supported shapes:
 - mesh
 
 Note: Bodies for meshes compute the convex hull of those meshes in order to provide the point containment / ray intersection routines.
+
 Note: [shape_tools](https://github.com/ros-planning/shape_tools) package was recently merged into this package
 
 ## Build Status
diff --git a/include/geometric_shapes/bodies.h b/include/geometric_shapes/bodies.h
index 8285fc7..fa66574 100644
--- a/include/geometric_shapes/bodies.h
+++ b/include/geometric_shapes/bodies.h
@@ -37,13 +37,17 @@
 #ifndef GEOMETRIC_SHAPES_BODIES_
 #define GEOMETRIC_SHAPES_BODIES_
 
+#if __cplusplus <= 199711L
+#error This header requires at least C++11
+#endif
+
 #include "geometric_shapes/shapes.h"
 #include <eigen_stl_containers/eigen_stl_containers.h>
-#include <boost/scoped_ptr.hpp>
 #include <random_numbers/random_numbers.h>
-#include <vector>
 #include <Eigen/Core>
 #include <Eigen/Geometry>
+#include <memory>
+#include <vector>
 
 /** \brief This set of classes allows quickly detecting whether a given point
    is inside an object or not. This capability is useful when removing
@@ -74,10 +78,10 @@ struct BoundingCylinder
 class Body;
 
 /** \brief Shared pointer to a Body */
-typedef boost::shared_ptr<Body> BodyPtr;
+typedef std::shared_ptr<Body> BodyPtr;
 
 /** \brief Shared pointer to a const Body */
-typedef boost::shared_ptr<const Body> BodyConstPtr;
+typedef std::shared_ptr<const Body> BodyConstPtr;
 
 /** \brief A body is a shape + its pose. Point inclusion, ray
     intersection can be tested, volumes and bounding spheres can
@@ -456,7 +460,7 @@ protected:
   };
 
   // shape-dependent data; keep this in one struct so that a cheap pointer copy can be done in cloneAt()
-  boost::shared_ptr<MeshData> mesh_data_;
+  std::shared_ptr<MeshData> mesh_data_;
 
   // pose/padding/scaling-dependent values & values computed for convenience and fast upcoming computations
   Eigen::Affine3d             i_pose_;
@@ -471,7 +475,7 @@ protected:
   EigenSTL::vector_Vector3d  *scaled_vertices_;
 
 private:
-  boost::scoped_ptr<EigenSTL::vector_Vector3d> scaled_vertices_storage_;
+  std::unique_ptr<EigenSTL::vector_Vector3d> scaled_vertices_storage_;
 
 public:
   EIGEN_MAKE_ALIGNED_OPERATOR_NEW
@@ -528,10 +532,10 @@ private:
 };
 
 /** \brief Shared pointer to a Body */
-typedef boost::shared_ptr<Body> BodyPtr;
+typedef std::shared_ptr<Body> BodyPtr;
 
 /** \brief Shared pointer to a const Body */
-typedef boost::shared_ptr<const Body> BodyConstPtr;
+typedef std::shared_ptr<const Body> BodyConstPtr;
 
 }
 
diff --git a/include/geometric_shapes/shapes.h b/include/geometric_shapes/shapes.h
index 3526e96..13d1c27 100644
--- a/include/geometric_shapes/shapes.h
+++ b/include/geometric_shapes/shapes.h
@@ -44,7 +44,6 @@
 #include <cstdlib>
 #include <vector>
 #include <iostream>
-#include <boost/shared_ptr.hpp>
 #include <memory>
 #include <string>
 
@@ -270,10 +269,10 @@ public:
 
 
 /** \brief Shared pointer to a Shape */
-typedef boost::shared_ptr<Shape> ShapePtr;
+typedef std::shared_ptr<Shape> ShapePtr;
 
 /** \brief Shared pointer to a const Shape */
-typedef boost::shared_ptr<const Shape> ShapeConstPtr;
+typedef std::shared_ptr<const Shape> ShapeConstPtr;
 
 }
 
diff --git a/package.xml b/package.xml
index 5b40bdd..b6b558c 100644
--- a/package.xml
+++ b/package.xml
@@ -1,6 +1,6 @@
 <package>
   <name>geometric_shapes</name>
-  <version>0.5.1</version>
+  <version>0.5.2</version>
   <description>This package contains generic definitions of geometric shapes and bodies.</description>
   <author email="isucan at google.com">Ioan Sucan</author>
   <author email="gjones at willowgarage.edu">Gil Jones</author>
diff --git a/src/bodies.cpp b/src/bodies.cpp
index 700e4f2..f706792 100644
--- a/src/bodies.cpp
+++ b/src/bodies.cpp
@@ -149,7 +149,7 @@ void bodies::Sphere::updateInternalData()
   center_ = pose_.translation();
 }
 
-boost::shared_ptr<bodies::Body> bodies::Sphere::cloneAt(const Eigen::Affine3d &pose, double padding, double scale) const
+std::shared_ptr<bodies::Body> bodies::Sphere::cloneAt(const Eigen::Affine3d &pose, double padding, double scale) const
 {
   Sphere *s = new Sphere();
   s->radius_ = radius_;
@@ -157,7 +157,7 @@ boost::shared_ptr<bodies::Body> bodies::Sphere::cloneAt(const Eigen::Affine3d &p
   s->scale_ = scale;
   s->pose_ = pose;
   s->updateInternalData();
-  return boost::shared_ptr<Body>(s);
+  return std::shared_ptr<Body>(s);
 }
 
 double bodies::Sphere::computeVolume() const
@@ -323,7 +323,7 @@ bool bodies::Cylinder::samplePointInside(random_numbers::RandomNumberGenerator &
   return true;
 }
 
-boost::shared_ptr<bodies::Body> bodies::Cylinder::cloneAt(const Eigen::Affine3d &pose, double padding, double scale) const
+std::shared_ptr<bodies::Body> bodies::Cylinder::cloneAt(const Eigen::Affine3d &pose, double padding, double scale) const
 {
   Cylinder *c = new Cylinder();
   c->length_ = length_;
@@ -332,7 +332,7 @@ boost::shared_ptr<bodies::Body> bodies::Cylinder::cloneAt(const Eigen::Affine3d
   c->scale_ = scale;
   c->pose_ = pose;
   c->updateInternalData();
-  return boost::shared_ptr<Body>(c);
+  return std::shared_ptr<Body>(c);
 }
 
 double bodies::Cylinder::computeVolume() const
@@ -521,7 +521,7 @@ void bodies::Box::updateInternalData()
   corner2_ = center_ + tmp;
 }
 
-boost::shared_ptr<bodies::Body> bodies::Box::cloneAt(const Eigen::Affine3d &pose, double padding, double scale) const
+std::shared_ptr<bodies::Body> bodies::Box::cloneAt(const Eigen::Affine3d &pose, double padding, double scale) const
 {
   Box *b = new Box();
   b->length_ = length_;
@@ -531,7 +531,7 @@ boost::shared_ptr<bodies::Body> bodies::Box::cloneAt(const Eigen::Affine3d &pose
   b->scale_ = scale;
   b->pose_ = pose;
   b->updateInternalData();
-  return boost::shared_ptr<Body>(b);
+  return std::shared_ptr<Body>(b);
 }
 
 double bodies::Box::computeVolume() const
@@ -922,7 +922,7 @@ void bodies::ConvexMesh::updateInternalData()
   Eigen::Affine3d pose = pose_;
   pose.translation() = Eigen::Vector3d(pose_ * mesh_data_->box_offset_);
 
-  boost::scoped_ptr<shapes::Box> box_shape(new shapes::Box(mesh_data_->box_size_.x(), mesh_data_->box_size_.y(), mesh_data_->box_size_.z()));
+  std::unique_ptr<shapes::Box> box_shape(new shapes::Box(mesh_data_->box_size_.x(), mesh_data_->box_size_.y(), mesh_data_->box_size_.z()));
   bounding_box_.setDimensions(box_shape.get());
   bounding_box_.setPose(pose);
   bounding_box_.setPadding(padding_);
@@ -967,7 +967,7 @@ const EigenSTL::vector_Vector3d& bodies::ConvexMesh::getScaledVertices() const
   return scaled_vertices_ ? *scaled_vertices_ : getVertices();
 }
 
-boost::shared_ptr<bodies::Body> bodies::ConvexMesh::cloneAt(const Eigen::Affine3d &pose, double padding, double scale) const
+std::shared_ptr<bodies::Body> bodies::ConvexMesh::cloneAt(const Eigen::Affine3d &pose, double padding, double scale) const
 {
   ConvexMesh *m = new ConvexMesh();
   m->mesh_data_ = mesh_data_;
@@ -975,7 +975,7 @@ boost::shared_ptr<bodies::Body> bodies::ConvexMesh::cloneAt(const Eigen::Affine3
   m->scale_ = scale;
   m->pose_ = pose;
   m->updateInternalData();
-  return boost::shared_ptr<Body>(m);
+  return std::shared_ptr<Body>(m);
 }
 
 void bodies::ConvexMesh::computeBoundingSphere(BoundingSphere &sphere) const
diff --git a/src/mesh_operations.cpp b/src/mesh_operations.cpp
index b0ec8d8..09350e0 100644
--- a/src/mesh_operations.cpp
+++ b/src/mesh_operations.cpp
@@ -238,19 +238,41 @@ Mesh* createMeshFromBinary(const char *buffer, std::size_t size, const Eigen::Ve
   // Create an instance of the Importer class
   Assimp::Importer importer;
 
-
-  // And have it read the given file with some postprocessing
+  // Issue #38 fix: as part of the post-processing, we remove all other components in file but
+  // the meshes, as anyway the resulting shapes:Mesh object just receives vertices and triangles.
+  importer.SetPropertyInteger(AI_CONFIG_PP_RVC_FLAGS,
+          aiComponent_NORMALS                  |
+          aiComponent_TANGENTS_AND_BITANGENTS  |
+          aiComponent_COLORS                   |
+          aiComponent_TEXCOORDS                |
+          aiComponent_BONEWEIGHTS              |
+          aiComponent_ANIMATIONS               |
+          aiComponent_TEXTURES                 |
+          aiComponent_LIGHTS                   |
+          aiComponent_CAMERAS                  |
+          aiComponent_MATERIALS);
+
+  // And have it read the given file with some post-processing
   const aiScene* scene = importer.ReadFileFromMemory(reinterpret_cast<const void*>(buffer), size,
                                                      aiProcess_Triangulate            |
                                                      aiProcess_JoinIdenticalVertices  |
                                                      aiProcess_SortByPType            |
-                                                     aiProcess_OptimizeGraph          |
-                                                     aiProcess_OptimizeMeshes,
-                                                     hint.c_str());
-  if (scene)
-    return createMeshFromAsset(scene, scale, hint);
-  else
+                                                     aiProcess_RemoveComponent, hint.c_str());
+  if (!scene)
     return NULL;
+
+  // Assimp enforces Y_UP convention by rotating models with different conventions.
+  // However, that behaviour is confusing and doesn't match the ROS convention
+  // where the Z axis is pointing up.
+  // Hopefully this doesn't undo legit use of the root node transformation...
+  // Note that this is also what RViz does internally.
+  scene->mRootNode->mTransformation = aiMatrix4x4();
+
+  // These post processing steps flatten the root node transformation into child nodes,
+  // so they must be delayed until after clearing the root node transform above.
+  importer.ApplyPostProcessing(aiProcess_OptimizeMeshes | aiProcess_OptimizeGraph);
+
+  return createMeshFromAsset(scene, scale, hint);
 }
 
 Mesh* createMeshFromResource(const std::string& resource, const Eigen::Vector3d &scale)
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 5af445e..32df435 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -11,3 +11,9 @@ target_link_libraries(test_point_inclusion ${PROJECT_NAME} ${catkin_LIBRARIES} $
 
 catkin_add_gtest(test_bounding_sphere test_bounding_sphere.cpp)
 target_link_libraries(test_bounding_sphere ${PROJECT_NAME} ${catkin_LIBRARIES} ${Boost_LIBRARIES})
+
+catkin_add_gtest(test_create_mesh test_create_mesh.cpp)
+target_link_libraries(test_create_mesh ${PROJECT_NAME} ${catkin_LIBRARIES} ${Boost_LIBRARIES})
+
+catkin_add_gtest(test_loaded_meshes test_loaded_meshes.cpp)
+target_link_libraries(test_loaded_meshes ${PROJECT_NAME} ${catkin_LIBRARIES} ${Boost_LIBRARIES})
diff --git a/test/resources/cube.stl b/test/resources/cube.stl
new file mode 100644
index 0000000..a9d729d
Binary files /dev/null and b/test/resources/cube.stl differ
diff --git a/test/resources/triangle.stl b/test/resources/triangle.stl
new file mode 100644
index 0000000..fee349b
--- /dev/null
+++ b/test/resources/triangle.stl
@@ -0,0 +1,9 @@
+solid
+facet normal -0.577350 -0.577350 -0.577350
+outer loop
+vertex 0.000000 0.000000 1.000000
+vertex 0.000000 1.000000 0.000000
+vertex 1.000000 0.000000 0.000000
+endloop
+endfacet
+endsolid
diff --git a/test/resources/triangle_10m.dae b/test/resources/triangle_10m.dae
new file mode 100644
index 0000000..9ef4993
--- /dev/null
+++ b/test/resources/triangle_10m.dae
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
+  <asset>
+    <created>2016-08-28T22:17:50</created>
+    <modified>2016-08-28T22:17:50</modified>
+    <unit name="decameter" meter="10"/>
+  </asset>
+  <library_images/>
+  <library_geometries>
+    <geometry id="triangle">
+      <mesh>
+        <source id="positions">
+          <float_array id="data" count="9">0 0 1 0 1 0 1 0 0</float_array>
+          <technique_common>
+            <accessor source="#data" count="3" stride="3">
+              <param name="X" type="float"/>
+              <param name="Y" type="float"/>
+              <param name="Z" type="float"/>
+            </accessor>
+          </technique_common>
+        </source>
+        <vertices id="vertices"><input semantic="POSITION" source="#positions"/></vertices>
+        <triangles count="1">
+          <input semantic="VERTEX" source="#vertices" offset="0"/>
+          <p>0 1 2</p>
+        </triangles>
+      </mesh>
+    </geometry>
+  </library_geometries>
+  <library_controllers/>
+  <library_visual_scenes>
+    <visual_scene id="scene"><node><instance_geometry url="#triangle"/></node></visual_scene>
+  </library_visual_scenes>
+  <scene><instance_visual_scene url="#scene"/></scene>
+</COLLADA>
diff --git a/test/resources/triangle_1m.dae b/test/resources/triangle_1m.dae
new file mode 100644
index 0000000..be392e6
--- /dev/null
+++ b/test/resources/triangle_1m.dae
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
+  <asset>
+    <created>2016-08-28T22:17:50</created>
+    <modified>2016-08-28T22:17:50</modified>
+    <unit name="meter" meter="1"/>
+  </asset>
+  <library_images/>
+  <library_geometries>
+    <geometry id="triangle">
+      <mesh>
+        <source id="positions">
+          <float_array id="data" count="9">0 0 1 0 1 0 1 0 0</float_array>
+          <technique_common>
+            <accessor source="#data" count="3" stride="3">
+              <param name="X" type="float"/>
+              <param name="Y" type="float"/>
+              <param name="Z" type="float"/>
+            </accessor>
+          </technique_common>
+        </source>
+        <vertices id="vertices"><input semantic="POSITION" source="#positions"/></vertices>
+        <triangles count="1">
+          <input semantic="VERTEX" source="#vertices" offset="0"/>
+          <p>0 1 2</p>
+        </triangles>
+      </mesh>
+    </geometry>
+  </library_geometries>
+  <library_controllers/>
+  <library_visual_scenes>
+    <visual_scene id="scene"><node><instance_geometry url="#triangle"/></node></visual_scene>
+  </library_visual_scenes>
+  <scene><instance_visual_scene url="#scene"/></scene>
+</COLLADA>
diff --git a/test/resources/triangle_no_unit.dae b/test/resources/triangle_no_unit.dae
new file mode 100644
index 0000000..195a6d1
--- /dev/null
+++ b/test/resources/triangle_no_unit.dae
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
+  <asset>
+    <created>2016-08-28T22:17:50</created>
+    <modified>2016-08-28T22:17:50</modified>
+  </asset>
+  <library_images/>
+  <library_geometries>
+    <geometry id="triangle">
+      <mesh>
+        <source id="positions">
+          <float_array id="data" count="9">0 0 1 0 1 0 1 0 0</float_array>
+          <technique_common>
+            <accessor source="#data" count="3" stride="3">
+              <param name="X" type="float"/>
+              <param name="Y" type="float"/>
+              <param name="Z" type="float"/>
+            </accessor>
+          </technique_common>
+        </source>
+        <vertices id="vertices"><input semantic="POSITION" source="#positions"/></vertices>
+        <triangles count="1">
+          <input semantic="VERTEX" source="#vertices" offset="0"/>
+          <p>0 1 2</p>
+        </triangles>
+      </mesh>
+    </geometry>
+  </library_geometries>
+  <library_controllers/>
+  <library_visual_scenes>
+    <visual_scene id="scene"><node><instance_geometry url="#triangle"/></node></visual_scene>
+  </library_visual_scenes>
+  <scene><instance_visual_scene url="#scene"/></scene>
+</COLLADA>
diff --git a/test/resources/triangle_no_up.dae b/test/resources/triangle_no_up.dae
new file mode 100644
index 0000000..be392e6
--- /dev/null
+++ b/test/resources/triangle_no_up.dae
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
+  <asset>
+    <created>2016-08-28T22:17:50</created>
+    <modified>2016-08-28T22:17:50</modified>
+    <unit name="meter" meter="1"/>
+  </asset>
+  <library_images/>
+  <library_geometries>
+    <geometry id="triangle">
+      <mesh>
+        <source id="positions">
+          <float_array id="data" count="9">0 0 1 0 1 0 1 0 0</float_array>
+          <technique_common>
+            <accessor source="#data" count="3" stride="3">
+              <param name="X" type="float"/>
+              <param name="Y" type="float"/>
+              <param name="Z" type="float"/>
+            </accessor>
+          </technique_common>
+        </source>
+        <vertices id="vertices"><input semantic="POSITION" source="#positions"/></vertices>
+        <triangles count="1">
+          <input semantic="VERTEX" source="#vertices" offset="0"/>
+          <p>0 1 2</p>
+        </triangles>
+      </mesh>
+    </geometry>
+  </library_geometries>
+  <library_controllers/>
+  <library_visual_scenes>
+    <visual_scene id="scene"><node><instance_geometry url="#triangle"/></node></visual_scene>
+  </library_visual_scenes>
+  <scene><instance_visual_scene url="#scene"/></scene>
+</COLLADA>
diff --git a/test/resources/triangle_x_up.dae b/test/resources/triangle_x_up.dae
new file mode 100644
index 0000000..4ee8c5d
--- /dev/null
+++ b/test/resources/triangle_x_up.dae
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
+  <asset>
+    <created>2016-08-28T22:17:50</created>
+    <modified>2016-08-28T22:17:50</modified>
+    <unit name="meter" meter="1"/>
+    <up_axis>X_UP</up_axis>
+  </asset>
+  <library_images/>
+  <library_geometries>
+    <geometry id="triangle">
+      <mesh>
+        <source id="positions">
+          <float_array id="data" count="9">0 0 1 0 1 0 1 0 0</float_array>
+          <technique_common>
+            <accessor source="#data" count="3" stride="3">
+              <param name="X" type="float"/>
+              <param name="Y" type="float"/>
+              <param name="Z" type="float"/>
+            </accessor>
+          </technique_common>
+        </source>
+        <vertices id="vertices"><input semantic="POSITION" source="#positions"/></vertices>
+        <triangles count="1">
+          <input semantic="VERTEX" source="#vertices" offset="0"/>
+          <p>0 1 2</p>
+        </triangles>
+      </mesh>
+    </geometry>
+  </library_geometries>
+  <library_controllers/>
+  <library_visual_scenes>
+    <visual_scene id="scene"><node><instance_geometry url="#triangle"/></node></visual_scene>
+  </library_visual_scenes>
+  <scene><instance_visual_scene url="#scene"/></scene>
+</COLLADA>
diff --git a/test/resources/triangle_y_up.dae b/test/resources/triangle_y_up.dae
new file mode 100644
index 0000000..cf3d0e6
--- /dev/null
+++ b/test/resources/triangle_y_up.dae
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
+  <asset>
+    <created>2016-08-28T22:17:50</created>
+    <modified>2016-08-28T22:17:50</modified>
+    <unit name="meter" meter="1"/>
+    <up_axis>Y_UP</up_axis>
+  </asset>
+  <library_images/>
+  <library_geometries>
+    <geometry id="triangle">
+      <mesh>
+        <source id="positions">
+          <float_array id="data" count="9">0 0 1 0 1 0 1 0 0</float_array>
+          <technique_common>
+            <accessor source="#data" count="3" stride="3">
+              <param name="X" type="float"/>
+              <param name="Y" type="float"/>
+              <param name="Z" type="float"/>
+            </accessor>
+          </technique_common>
+        </source>
+        <vertices id="vertices"><input semantic="POSITION" source="#positions"/></vertices>
+        <triangles count="1">
+          <input semantic="VERTEX" source="#vertices" offset="0"/>
+          <p>0 1 2</p>
+        </triangles>
+      </mesh>
+    </geometry>
+  </library_geometries>
+  <library_controllers/>
+  <library_visual_scenes>
+    <visual_scene id="scene"><node><instance_geometry url="#triangle"/></node></visual_scene>
+  </library_visual_scenes>
+  <scene><instance_visual_scene url="#scene"/></scene>
+</COLLADA>
diff --git a/test/resources/triangle_z_up.dae b/test/resources/triangle_z_up.dae
new file mode 100644
index 0000000..6343890
--- /dev/null
+++ b/test/resources/triangle_z_up.dae
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
+  <asset>
+    <created>2016-08-28T22:17:50</created>
+    <modified>2016-08-28T22:17:50</modified>
+    <unit name="meter" meter="1"/>
+    <up_axis>Z_UP</up_axis>
+  </asset>
+  <library_images/>
+  <library_geometries>
+    <geometry id="triangle">
+      <mesh>
+        <source id="positions">
+          <float_array id="data" count="9">0 0 1 0 1 0 1 0 0</float_array>
+          <technique_common>
+            <accessor source="#data" count="3" stride="3">
+              <param name="X" type="float"/>
+              <param name="Y" type="float"/>
+              <param name="Z" type="float"/>
+            </accessor>
+          </technique_common>
+        </source>
+        <vertices id="vertices"><input semantic="POSITION" source="#positions"/></vertices>
+        <triangles count="1">
+          <input semantic="VERTEX" source="#vertices" offset="0"/>
+          <p>0 1 2</p>
+        </triangles>
+      </mesh>
+    </geometry>
+  </library_geometries>
+  <library_controllers/>
+  <library_visual_scenes>
+    <visual_scene id="scene"><node><instance_geometry url="#triangle"/></node></visual_scene>
+  </library_visual_scenes>
+  <scene><instance_visual_scene url="#scene"/></scene>
+</COLLADA>
diff --git a/test/test_create_mesh.cpp b/test/test_create_mesh.cpp
new file mode 100644
index 0000000..b5f4536
--- /dev/null
+++ b/test/test_create_mesh.cpp
@@ -0,0 +1,117 @@
+/*********************************************************************
+* Software License Agreement (BSD License)
+*
+*  Copyright (c) 2016, Delft Robotics
+*  All rights reserved.
+*
+*  Redistribution and use in source and binary forms, with or without
+*  modification, are permitted provided that the following conditions
+*  are met:
+*
+*   * Redistributions of source code must retain the above copyright
+*     notice, this list of conditions and the following disclaimer.
+*   * Redistributions in binary form must reproduce the above
+*     copyright notice, this list of conditions and the following
+*     disclaimer in the documentation and/or other materials provided
+*     with the distribution.
+*   * Neither the name of the copyright holder nor the names of its
+*     contributors may be used to endorse or promote products derived
+*     from this software without specific prior written permission.
+*
+*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+*  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+*  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+*  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+*  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+*  POSSIBILITY OF SUCH DAMAGE.
+*********************************************************************/
+
+/** \Author Maarten de Vries <maarten at de-vri.es> */
+
+#include "resources/config.h"
+#include <geometric_shapes/mesh_operations.h>
+#include <gtest/gtest.h>
+#include <string>
+
+namespace {
+
+  void assertMesh(shapes::Mesh * mesh)
+  {
+    ASSERT_TRUE(mesh != NULL);
+    ASSERT_EQ(3, mesh->vertex_count);
+    ASSERT_EQ(1, mesh->triangle_count);
+
+    ASSERT_EQ(0, mesh->triangles[0]);
+    ASSERT_EQ(1, mesh->triangles[1]);
+    ASSERT_EQ(2, mesh->triangles[2]);
+
+    ASSERT_FLOAT_EQ(0, mesh->vertices[0 + 0]);
+    ASSERT_FLOAT_EQ(0, mesh->vertices[0 + 1]);
+    ASSERT_FLOAT_EQ(1, mesh->vertices[0 + 2]);
+    ASSERT_FLOAT_EQ(0, mesh->vertices[3 + 0]);
+    ASSERT_FLOAT_EQ(1, mesh->vertices[3 + 1]);
+    ASSERT_FLOAT_EQ(0, mesh->vertices[3 + 2]);
+    ASSERT_FLOAT_EQ(1, mesh->vertices[6 + 0]);
+    ASSERT_FLOAT_EQ(0, mesh->vertices[6 + 1]);
+    ASSERT_FLOAT_EQ(0, mesh->vertices[6 + 2]);
+  }
+
+  shapes::Mesh * loadMesh(const std::string & mesh)
+  {
+    std::string path = "file://" + std::string(TEST_RESOURCES_DIR) + "/" + mesh;
+    return shapes::createMeshFromResource(path);
+  }
+
+}
+
+TEST(CreateMesh, stl)
+{
+  assertMesh(loadMesh("triangle.stl"));
+}
+
+TEST(CreateMesh, daeNoUp)
+{
+  assertMesh(loadMesh("triangle_no_up.dae"));
+}
+
+TEST(CreateMesh, daeYUp)
+{
+  assertMesh(loadMesh("triangle_y_up.dae"));
+}
+
+TEST(CreateMesh, daeZUp)
+{
+  assertMesh(loadMesh("triangle_z_up.dae"));
+}
+
+TEST(CreateMesh, daeXUp)
+{
+  assertMesh(loadMesh("triangle_x_up.dae"));
+}
+
+TEST(CreateMesh, daeNoUnit)
+{
+  assertMesh(loadMesh("triangle_no_unit.dae"));
+}
+
+TEST(CreateMesh, dae1M)
+{
+  assertMesh(loadMesh("triangle_1m.dae"));
+}
+
+TEST(CreateMesh, dae10M)
+{
+  assertMesh(loadMesh("triangle_10m.dae"));
+}
+
+int main(int argc, char **argv)
+{
+  testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/test/test_loaded_meshes.cpp b/test/test_loaded_meshes.cpp
new file mode 100644
index 0000000..1b780ad
--- /dev/null
+++ b/test/test_loaded_meshes.cpp
@@ -0,0 +1,212 @@
+/*********************************************************************
+* Software License Agreement (BSD License)
+*
+*  Copyright (c) 2016, Jorge Santos
+*  All rights reserved.
+*
+*  Redistribution and use in source and binary forms, with or without
+*  modification, are permitted provided that the following conditions
+*  are met:
+*
+*   * Redistributions of source code must retain the above copyright
+*     notice, this list of conditions and the following disclaimer.
+*   * Redistributions in binary form must reproduce the above
+*     copyright notice, this list of conditions and the following
+*     disclaimer in the documentation and/or other materials provided
+*     with the distribution.
+*   * Neither the name of the Willow Garage nor the names of its
+*     contributors may be used to endorse or promote products derived
+*     from this software without specific prior written permission.
+*
+*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+*  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+*  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+*  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+*  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+*  POSSIBILITY OF SUCH DAMAGE.
+*********************************************************************/
+
+/** \Author Jorge Santos */
+
+#include <geometric_shapes/bodies.h>
+#include <geometric_shapes/shape_operations.h>
+#include <geometric_shapes/body_operations.h>
+#include <boost/filesystem.hpp>
+#include <gtest/gtest.h>
+#include "resources/config.h"
+
+
+/**
+ * Test fixture that generates meshes from the primitive shapes SPHERE, CYLINDER, CONE and BOX,
+ * and load their twins from STL files. All the following tests are intended to verify that both
+ * procedures produce equivalent meshes, and particularly that changes related to issue #38 don't
+ * break mesh loading.
+ */
+class CompareMeshVsPrimitive : public ::testing::Test
+{
+public:
+  CompareMeshVsPrimitive()
+  {
+  }
+
+  void SetUp()
+  {
+    // BOX
+    shapes::Box box(1.0, 1.0, 1.0);
+    shape_meshes.push_back(shapes::createMeshFromShape(&box));
+    loaded_meshes.push_back(shapes::createMeshFromResource(
+        "file://" + (boost::filesystem::path(TEST_RESOURCES_DIR) / "/cube.stl").string()));
+
+    shape_convex_meshes.push_back(new bodies::ConvexMesh(shape_meshes.back()));
+    loaded_convex_meshes.push_back(new bodies::ConvexMesh(loaded_meshes.back()));
+  }
+
+  void TearDown()
+  {
+    for (int i = 0; i < shape_meshes.size(); ++i)
+    {
+      delete shape_meshes[i];
+      delete loaded_meshes[i];
+
+      delete shape_convex_meshes[i];
+      delete loaded_convex_meshes[i];
+    }
+  }
+
+  ~CompareMeshVsPrimitive()
+  {
+  }
+
+protected:
+  random_numbers::RandomNumberGenerator rng;
+
+  std::vector<shapes::Mesh*> shape_meshes;
+  std::vector<shapes::Mesh*> loaded_meshes;
+
+  std::vector<bodies::Body*> shape_convex_meshes;
+  std::vector<bodies::Body*> loaded_convex_meshes;
+};
+
+TEST_F(CompareMeshVsPrimitive, ContainsPoint)
+{
+  // Any point inside a mesh must be inside the other too
+  for (int i = 0; i < shape_meshes.size(); ++i)
+  {
+    shapes::Mesh *shape_ms = shape_meshes[i];
+    shapes::Mesh *loaded_ms = loaded_meshes[i];
+
+    bodies::Body *shape_cms = shape_convex_meshes[i];
+    bodies::Body *loaded_cms = loaded_convex_meshes[i];
+
+    Eigen::Vector3d p;
+    bool found = false;
+    for (int i = 0; i < 100; ++i)
+    {
+      if ((shape_cms->samplePointInside(rng, 10000, p)) ||
+          (loaded_cms->samplePointInside(rng, 10000, p)))
+      {
+        found = true;
+        EXPECT_EQ(shape_cms->containsPoint(p), loaded_cms->containsPoint(p));
+      }
+    }
+    EXPECT_TRUE(found) << "No point inside the meshes was found (very unlikely)";
+  }
+}
+
+TEST_F(CompareMeshVsPrimitive, IntersectsRay)
+{
+  // Random rays must intersect both meshes nearly at the same points
+  for (int i = 0; i < shape_meshes.size(); ++i)
+  {
+    shapes::Mesh *shape_ms = shape_meshes[i];
+    shapes::Mesh *loaded_ms = loaded_meshes[i];
+
+    bodies::Body *shape_cms = shape_convex_meshes[i];
+    bodies::Body *loaded_cms = loaded_convex_meshes[i];
+
+    bool intersects = false;
+    for (int i = 0; i < 100; ++i)
+    {
+      Eigen::Vector3d ray_o(rng.uniformReal(-1.0, +1.0),
+                            rng.uniformReal(-1.0, +1.0),
+                            rng.uniformReal(-1.0, +1.0));
+      Eigen::Vector3d ray_d(rng.uniformReal(-1.0, +1.0),
+                            rng.uniformReal(-1.0, +1.0),
+                            rng.uniformReal(-1.0, +1.0));
+      EigenSTL::vector_Vector3d vi1, vi2;
+      shape_cms->intersectsRay(ray_o, ray_d, &vi1);
+      loaded_cms->intersectsRay(ray_o, ray_d, &vi2);
+
+  // DEBUG printing
+  //    if (vi1.size() != vi2.size() && vi1.size() > 0 && vi2.size() > 0)
+  //    {
+  //        std::cout << vi1.size() << "   " << vi2.size() << "\n";
+  //        std::cout << ray_o.x() << "  "<< ray_o.y() << "  "<< ray_o.z()
+  //          << "\n" << ray_d.x() << "  "<< ray_d.y() << "  "<< ray_d.z() << "\n";
+  //    }
+
+      EXPECT_EQ(vi1.size(), vi2.size());
+      if (vi1.size() > 0 && vi2.size() > 0)
+      {
+        EXPECT_NEAR(vi1[0].x(), vi2[0].x(), 0.01);
+        EXPECT_NEAR(vi1[0].y(), vi2[0].y(), 0.01);
+        EXPECT_NEAR(vi1[0].z(), vi2[0].z(), 0.01);
+
+        intersects = true;
+      }
+    }
+
+    EXPECT_TRUE(intersects) << "No ray intersects the meshes (very unlikely)";
+  }
+}
+
+TEST_F(CompareMeshVsPrimitive, BoundingSphere)
+{
+  // Bounding spheres must be nearly identical
+  for (int i = 0; i < shape_meshes.size(); ++i)
+  {
+    shapes::Mesh *shape_ms = shape_meshes[i];
+    shapes::Mesh *loaded_ms = loaded_meshes[i];
+
+    bodies::Body *shape_cms = shape_convex_meshes[i];
+    bodies::Body *loaded_cms = loaded_convex_meshes[i];
+
+    shapes::Sphere shape(1.0);
+    Eigen::Vector3d center1, center2;
+    double radius1, radius2;
+    computeShapeBoundingSphere(shape_ms, center1, radius1);
+    computeShapeBoundingSphere(loaded_ms, center2, radius2);
+
+    EXPECT_NEAR(radius1,     radius2,     0.001);
+    EXPECT_NEAR(center1.x(), center2.x(), 0.001);
+    EXPECT_NEAR(center1.y(), center2.y(), 0.001);
+    EXPECT_NEAR(center1.z(), center2.z(), 0.001);
+  }
+}
+
+TEST_F(CompareMeshVsPrimitive, BoxVertexCount)
+{
+  // For a simple shape as a cube, we expect that both meshes have the same number of vertex and triangles
+  // But that was not the case before fixing issue #38!
+  // These tests don't apply to curve shapes because the number of elements depends on how smooth they where
+  // created. So ensure that "back()" gives a pointer to box meshes!
+  EXPECT_EQ(shape_meshes.back()->vertex_count, loaded_meshes.back()->vertex_count);
+}
+
+TEST_F(CompareMeshVsPrimitive, BoxTriangleCount)
+{
+  EXPECT_EQ(shape_meshes.back()->triangle_count, loaded_meshes.back()->triangle_count);
+}
+
+
+int main(int argc, char **argv)
+{
+  testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/test/test_point_inclusion.cpp b/test/test_point_inclusion.cpp
index 02f803e..ebb2c00 100644
--- a/test/test_point_inclusion.cpp
+++ b/test/test_point_inclusion.cpp
@@ -260,8 +260,9 @@ TEST(CylinderPointContainment, CylinderPadding)
 TEST(MeshPointContainment, Pr2Forearm)
 {
     shapes::Mesh *ms = shapes::createMeshFromResource("file://" + (boost::filesystem::path(TEST_RESOURCES_DIR) / "/forearm_roll.stl").string());
-    EXPECT_EQ(ms->vertex_count, 2338);
+    ASSERT_TRUE(ms != NULL);
     bodies::Body *m = new bodies::ConvexMesh(ms);
+    ASSERT_TRUE(m != NULL);
     Eigen::Affine3d t(Eigen::Affine3d::Identity());
     t.translation().x() = 1.0;
     EXPECT_FALSE(m->cloneAt(t)->containsPoint(-1.0, 0.0, 0.0));

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/ros/ros-geometric-shapes.git



More information about the debian-science-commits mailing list