diff --git a/CMakeLists.txt b/CMakeLists.txt index 3033ff68..a25ee1f5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,8 +67,8 @@ endif() gz_find_package(FreeImage VERSION 3.9 REQUIRED_BY graphics PRIVATE_FOR graphics) -#------------------------------------ +#------------------------------------ # Find GDAL gz_find_package(GDAL VERSION 3.0 PKGCONFIG gdal diff --git a/Migration.md b/Migration.md index 3ee6a264..c93cf309 100644 --- a/Migration.md +++ b/Migration.md @@ -5,6 +5,22 @@ Deprecated code produces compile-time warnings. These warning serve as notification to users that their code should be upgraded. The next major release will remove the deprecated code. +## Gazebo Common 5.X to 6.X + +### Modifications + +1. Removed the `graphics` component's dependency on the GTS + (GNU Triangulated Surface) library which was used for doing triangulation + and CSG Boolean operation by the `MeshManager`. The Delaunay triangulation + function now uses the CDT (Constrained Delaunay Triangulation) library. + +### Deletions + +1. **MeshManager.hh** + + `void CreateBoolean(const std::string &_name, const Mesh *_m1, + const Mesh *_m2, const int _operation, + const gz::math::Pose3d &_offset = gz::math::Pose3d::Zero)` + ## Gazebo Common 4.X to 5.X ### Deprecations diff --git a/graphics/src/CDT/README.md b/graphics/src/CDT/README.md new file mode 100644 index 00000000..bb1e27e3 --- /dev/null +++ b/graphics/src/CDT/README.md @@ -0,0 +1,2 @@ +URL: https://github.com/artem-ogre/CDT +commit: 46f1ce1f495a97617d90e8c833d0d29406335fdf diff --git a/graphics/src/DelaunayTriangulation.cc b/graphics/src/DelaunayTriangulation.cc index d432f983..4c14bc73 100644 --- a/graphics/src/DelaunayTriangulation.cc +++ b/graphics/src/DelaunayTriangulation.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Open Source Robotics Foundation + * Copyright (C) 2024 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,25 +42,25 @@ bool gz::common::DelaunayTriangulation( return false; } - std::vector> cdt_verts; - std::vector cdt_edges; + std::vector> cdtVerts; + std::vector cdtEdges; - cdt_verts.reserve(_vertices.size()); - cdt_edges.reserve(_edges.size()); + cdtVerts.reserve(_vertices.size()); + cdtEdges.reserve(_edges.size()); for (const auto &vert : _vertices) { - cdt_verts.push_back({vert.X(), vert.Y()}); + cdtVerts.push_back({vert.X(), vert.Y()}); } for (const auto &edge : _edges) { - cdt_edges.emplace_back(edge.X(), edge.Y()); + cdtEdges.emplace_back(edge.X(), edge.Y()); } CDT::Triangulation cdt; - cdt.insertVertices(cdt_verts); - cdt.insertEdges(cdt_edges); + cdt.insertVertices(cdtVerts); + cdt.insertEdges(cdtEdges); cdt.eraseOuterTrianglesAndHoles(); for (const auto & vert : cdt.vertices) @@ -68,11 +68,14 @@ bool gz::common::DelaunayTriangulation( _subMesh->AddVertex(vert.x, vert.y, 0.0); } + // Resulting triangles are counter-clockwise winding + // Add the indices so that they are clockwise winding + // in the submesh for (const auto & tri : cdt.triangles) { - _subMesh->AddIndex(tri.vertices[0]); - _subMesh->AddIndex(tri.vertices[1]); _subMesh->AddIndex(tri.vertices[2]); + _subMesh->AddIndex(tri.vertices[1]); + _subMesh->AddIndex(tri.vertices[0]); } return true; diff --git a/graphics/src/DelaunayTriangulation_TEST.cc b/graphics/src/DelaunayTriangulation_TEST.cc index df919d39..ffe5c718 100644 --- a/graphics/src/DelaunayTriangulation_TEST.cc +++ b/graphics/src/DelaunayTriangulation_TEST.cc @@ -71,4 +71,25 @@ TEST_F(DelaunayTriangulation, DelaunayTriangulation) // there should be 8 triangles. EXPECT_EQ(subMesh.IndexCount() / 3u, 8u); + + // verify that triangles have clockwise winding + for (int t = 0; t < subMesh.IndexCount() / 3u; ++t) + { + int vertexIndex1 = subMesh.Index(t*3 + 0); + int vertexIndex2 = subMesh.Index(t*3 + 1); + int vertexIndex3 = subMesh.Index(t*3 + 2); + // compute displacement from vertex 1 to 2 + auto displacement12 = + subMesh.Vertex(vertexIndex2) - subMesh.Vertex(vertexIndex1); + // compute displacement from vertex 2 to 3 + auto displacement23 = + subMesh.Vertex(vertexIndex3) - subMesh.Vertex(vertexIndex2); + // compute cross product (v2-v1) x (v3 - v2) + auto crossProduct_12_23 = displacement12.Cross(displacement23); + // X and Y components should be zero + EXPECT_DOUBLE_EQ(0.0, crossProduct_12_23.X()); + EXPECT_DOUBLE_EQ(0.0, crossProduct_12_23.Y()); + // Z component should be negative for a clockwise winding + EXPECT_LT(crossProduct_12_23.Z(), 0.0); + } } diff --git a/graphics/src/MeshManager.cc b/graphics/src/MeshManager.cc index b7ac4414..157f3b18 100644 --- a/graphics/src/MeshManager.cc +++ b/graphics/src/MeshManager.cc @@ -1576,8 +1576,8 @@ void MeshManager::Tesselate2DMesh(SubMesh *sm, int meshWidth, int meshHeight, vInc = -vInc; } } -////////////////////////////////////////////////// +////////////////////////////////////////////////// size_t MeshManager::AddUniquePointToVerticesTable( std::vector &_vertices, const gz::math::Vector2d &_p,