From 6ed42844009b2e117064c6d7f96f93035fefbaa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Csik=C3=B3s=20Attila?= Date: Thu, 7 Mar 2024 22:33:08 +0100 Subject: [PATCH] Issue: #23 CGAL adapter --- adaptor.cgal.h | 210 ++++++++++++++++++++++ adaptortests/adaptortests.vcxproj | 1 + adaptortests/adaptortests.vcxproj.filters | 3 + adaptortests/test.cpp | 63 +++++++ adaptortests/vcpkg.json | 1 + 5 files changed, 278 insertions(+) create mode 100644 adaptor.cgal.h diff --git a/adaptor.cgal.h b/adaptor.cgal.h new file mode 100644 index 0000000..cb6af1d --- /dev/null +++ b/adaptor.cgal.h @@ -0,0 +1,210 @@ +#pragma once +/* +MIT License + +Copyright (c) 2021 Attila Csikós + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "octree.h" +/* Required headers +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +*/ +namespace CGAL +{ + // 2d Hyperplane + struct Plane_2 + { + double offset; // n1*x + n2*y + offset = 0 + Point_2> normal; + }; +} // namespace CGAL + + +namespace OrthoTree +{ + namespace CGALAdaptor + { + struct AdaptorGeneralBasics2D + { + using TGeometry = double; + using TVector = CGAL::Point_2>; + using TBox = CGAL::Bbox_2; + using TRay = CGAL::Ray_2>; + using TPlane = CGAL::Plane_2; + + static inline TGeometry GetPointC(TVector const& point, dim_t dimensionID) noexcept { return point[dimensionID]; } + static inline void SetPointC(TVector& point, dim_t dimensionID, TGeometry value) noexcept + { + if (dimensionID == 0) + point = TVector(value, point.y()); + else + point = TVector(point.x(), value); + } + + static inline TGeometry GetBoxMinC(TBox const& box, dim_t dimensionID) noexcept { return box.min(dimensionID); } + static inline TGeometry GetBoxMaxC(TBox const& box, dim_t dimensionID) noexcept { return box.max(dimensionID); } + static inline void SetBoxMinC(TBox& box, dim_t dimensionID, TGeometry value) noexcept + { + if (dimensionID == 0) + box = TBox(value, box.ymin(), box.xmax(), box.ymax()); + else + box = TBox(box.xmin(), value, box.xmax(), box.ymax()); + } + static inline void SetBoxMaxC(TBox& box, dim_t dimensionID, TGeometry value) noexcept + { + if (dimensionID == 0) + box = TBox(box.xmin(), box.ymin(), value, box.ymax()); + else + box = TBox(box.xmin(), box.ymin(), box.xmax(), value); + } + + static inline TVector GetRayDirection(TRay const& ray) noexcept + { + auto const direction = ray.to_vector(); + return TVector(direction.x(), direction.y()); + } + static inline TVector GetRayOrigin(TRay const& ray) noexcept { return ray.source(); } + + static inline TVector const& GetPlaneNormal(TPlane const& plane) noexcept { return plane.normal; } + static inline TGeometry GetPlaneOrigoDistance(TPlane const& plane) noexcept { return -plane.offset; } + }; + + using CGALAdaptorGeneral2D = + AdaptorGeneralBase<2, CGAL::Point_2>, CGAL::Bbox_2, CGAL::Ray_2>, CGAL::Plane_2, double, AdaptorGeneralBasics2D>; + + + struct AdaptorGeneralBasics3D + { + using TGeometry = double; + using TVector = CGAL::Point_3>; + using TBox = CGAL::Bbox_3; + using TRay = CGAL::Ray_3>; + using TPlane = CGAL::Plane_3>; + + static inline TGeometry GetPointC(TVector const& point, dim_t dimensionID) noexcept { return point[dimensionID]; } + static inline void SetPointC(TVector& point, dim_t dimensionID, TGeometry value) noexcept + { + switch (dimensionID) + { + case 0: point = TVector(value, point.y(), point.z()); return; + case 1: point = TVector(point.x(), value, point.z()); return; + case 2: point = TVector(point.x(), point.y(), value); return; + } + assert(false); + std::terminate(); + } + + static inline TGeometry GetBoxMinC(TBox const& box, dim_t dimensionID) noexcept { return box.min(dimensionID); } + static inline TGeometry GetBoxMaxC(TBox const& box, dim_t dimensionID) noexcept { return box.max(dimensionID); } + static inline void SetBoxMinC(TBox& box, dim_t dimensionID, TGeometry value) noexcept + { + switch (dimensionID) + { + case 0: box = TBox(value, box.ymin(), box.zmin(), box.xmax(), box.ymax(), box.zmax()); return; + case 1: box = TBox(box.xmin(), value, box.zmin(), box.xmax(), box.ymax(), box.zmax()); return; + case 2: box = TBox(box.xmin(), box.ymin(), value, box.xmax(), box.ymax(), box.zmax()); return; + } + assert(false); + std::terminate(); + } + + static inline void SetBoxMaxC(TBox& box, dim_t dimensionID, TGeometry value) noexcept + { + switch (dimensionID) + { + case 0: box = TBox(box.xmin(), box.ymin(), box.zmin(), value, box.ymax(), box.zmax()); return; + case 1: box = TBox(box.xmin(), box.ymin(), box.zmin(), box.xmax(), value, box.zmax()); return; + case 2: box = TBox(box.xmin(), box.ymin(), box.zmin(), box.xmax(), box.ymax(), value); return; + } + assert(false); + std::terminate(); + } + + static inline TVector GetRayDirection(TRay const& ray) noexcept + { + auto const direction = ray.to_vector(); + return TVector(direction.x(), direction.y(), direction.z()); + } + static inline TVector GetRayOrigin(TRay const& ray) noexcept { return ray.source(); } + + static inline TVector GetPlaneNormal(TPlane const& plane) noexcept { return TVector(plane.a(), plane.b(), plane.c()); } + static inline TGeometry GetPlaneOrigoDistance(TPlane const& plane) noexcept { return -plane.d(); } + }; + using CGALAdaptorGeneral3D = + AdaptorGeneralBase<3, CGAL::Point_3>, CGAL::Bbox_3, CGAL::Ray_3>, CGAL::Plane_3>, double, AdaptorGeneralBasics3D>; + + + } // namespace CGALAdaptor +} // namespace OrthoTree + +namespace CGAL +{ + using namespace OrthoTree::CGALAdaptor; + + // Core types + using QuadtreePoint = + OrthoTree::OrthoTreePoint<2, CGAL::Point_2>, CGAL::Bbox_2, CGAL::Ray_2>, CGAL::Plane_2, double, CGALAdaptorGeneral2D>; + + using OctreePoint = OrthoTree:: + OrthoTreePoint<3, CGAL::Point_3>, CGAL::Bbox_3, CGAL::Ray_3>, CGAL::Plane_3>, double, CGALAdaptorGeneral3D>; + + template + using QuadtreeBoxs = + OrthoTree::OrthoTreeBoundingBox<2, CGAL::Point_2>, CGAL::Bbox_2, CGAL::Ray_2>, CGAL::Plane_2, double, SPLIT_DEPTH_INCREASEMENT, CGALAdaptorGeneral2D>; + + using QuadtreeBox = QuadtreeBoxs<2>; + + template + using OctreeBoxs = OrthoTree::OrthoTreeBoundingBox< + 3, + CGAL::Point_3>, + CGAL::Bbox_3, + CGAL::Ray_3>, + CGAL::Plane_3>, + double, + SPLIT_DEPTH_INCREASEMENT, + CGALAdaptorGeneral3D>; + + using OctreeBox = OctreeBoxs<2>; + + + // Container types + + using QuadtreePointC = OrthoTree::OrthoTreeContainerPoint>>; + using OctreePointC = OrthoTree::OrthoTreeContainerPoint>>; + + template + using QuadtreeBoxCs = OrthoTree::OrthoTreeContainerBox, Bbox_2>; + using QuadtreeBoxC = QuadtreeBoxCs<2>; + template + using OctreeBoxCs = OrthoTree::OrthoTreeContainerBox, Bbox_3>; + using OctreeBoxC = OctreeBoxCs<2>; +} // namespace CGAL \ No newline at end of file diff --git a/adaptortests/adaptortests.vcxproj b/adaptortests/adaptortests.vcxproj index 9728eb9..588af4a 100644 --- a/adaptortests/adaptortests.vcxproj +++ b/adaptortests/adaptortests.vcxproj @@ -107,6 +107,7 @@ + diff --git a/adaptortests/adaptortests.vcxproj.filters b/adaptortests/adaptortests.vcxproj.filters index b9f2e33..6c48c7d 100644 --- a/adaptortests/adaptortests.vcxproj.filters +++ b/adaptortests/adaptortests.vcxproj.filters @@ -9,6 +9,9 @@ Adapters + + Adapters + diff --git a/adaptortests/test.cpp b/adaptortests/test.cpp index e1de97e..3acce81 100644 --- a/adaptortests/test.cpp +++ b/adaptortests/test.cpp @@ -8,6 +8,20 @@ #include #include "../adaptor.boost.h" +// CGAL +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../adaptor.cgal.h" + // Eigen #include #include @@ -66,6 +80,7 @@ namespace } } + // Boost template @@ -82,6 +97,41 @@ namespace planeA.origo_distance = typename TOrthoTreeA::TGeometry(planeO.OrigoDistance); } + + // CGAL + + template + void rayConv(TRay const& rayO, CGAL::Ray_2>& rayA) + { + using namespace CGAL; + + auto const s = Point_2>(rayO.Origin[0], rayO.Origin[1]); + auto const v = Vector_2>(rayO.Direction[0], rayO.Direction[1]); + rayA = Ray_2>(s, v); + } + + template + void planeConv(TPlane const& planeO, CGAL::Plane_2& planeA) + { + vectorConv<2, TVector, TOrthoTreeA>(planeO.Normal, planeA.normal); + planeA.offset = -typename TOrthoTreeA::TGeometry(planeO.OrigoDistance); + } + + template + void rayConv(TRay const& rayO, CGAL::Ray_3>& rayA) + { + using namespace CGAL; + + auto const s = Point_3>(rayO.origin[0], rayO.origin[1], rayO.origin[2]); + auto const v = Vector_3>(rayO.direction[0], rayO.direction[1], rayO.direction[2]); + rayA = Ray_2>(s, v); + } + + template + void planeConv(TPlane const& planeO, CGAL::Plane_3>& planeA) + { + planeA = CGAL::Plane_3>(planeO.Normal[0], planeO.Normal[1], planeO.Normal[2], -planeO.OrigoDistance); + } // Eigen @@ -502,6 +552,19 @@ namespace BoostAdapter } } // namespace BoostAdapter +namespace CGALAdapter +{ + TEST(CGAL_CoreTest, Point3D) + { + corePointTest3D(); + } + + TEST(CGAL_ContainerTest, Box2D) + { + containerBoxTest2D(); + } +} // namespace CGALAdapter + namespace EigenAdapter { TEST(Eigen_CoreTest, Point3D) diff --git a/adaptortests/vcpkg.json b/adaptortests/vcpkg.json index ec6d79e..b5bbf14 100644 --- a/adaptortests/vcpkg.json +++ b/adaptortests/vcpkg.json @@ -1,6 +1,7 @@ { "dependencies": [ "boost", + "cgal", "eigen3", "gtest", "glm"