Commit b0052dbb authored by Dennis Gläser's avatar Dennis Gläser
Browse files

Merge branch 'feature/multi-geometry-sampler' into 'master'

Feature/multi geometry sampler

See merge request DennisGlaeser/frackit!38
parents 7f4c4e6b 6d1ab57f
......@@ -2,6 +2,7 @@ add_subdirectory(common)
add_subdirectory(distance)
add_subdirectory(entitynetwork)
add_subdirectory(geometry)
add_subdirectory(geometryutilities)
add_subdirectory(intersection)
add_subdirectory(io)
add_subdirectory(magnitude)
......
......@@ -4,4 +4,5 @@ extractdimension.hh
id.hh
math.hh
promotedtype.hh
typetraits.hh
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/frackit/common)
......@@ -34,6 +34,9 @@ namespace Frackit {
class Id
{
public:
//! Default constructor
Id() = default;
/*!
* \brief Construction from an index.
*/
......@@ -47,6 +50,12 @@ public:
std::size_t get() const
{ return id_; }
/*!
* \brief Equality check.
*/
bool operator== (const Id& otherId) const
{ return id_ == otherId.get(); }
private:
std::size_t id_;
};
......
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*****************************************************************************
* See the file COPYING for full copying permissions. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*****************************************************************************/
/*!
* \file
* \brief Defines classes to obtain type information at compile-time.
*/
#ifndef FRACKIT_COMMON_TYPE_TRAITS_HH
#define FRACKIT_COMMON_TYPE_TRAITS_HH
#include <type_traits>
namespace Frackit {
/*!
* \brief Helper struct to detect if a type T
* is contained in a parameter pack Ts
* \tparam T The type of which an ocurrence in the pack is to be checked
* \tparam Ts The parameter pack
*/
template<class T, class... Ts>
struct Contains : std::disjunction<std::is_same<T, Ts>...> {};
} // end namespace Frackit
#endif // FRACKIT_COMMON_TYPE_TRAITS_HH
......@@ -36,7 +36,8 @@
#include <frackit/geometry/disk.hh>
#include <frackit/geometry/quadrilateral.hh>
#include <frackit/geometry/cylindersurface.hh>
#include <frackit/geometry/name.hh>
#include <frackit/geometryutilities/name.hh>
#include "distance.hh"
......
......@@ -35,7 +35,8 @@
#include <frackit/geometry/point.hh>
#include <frackit/geometry/disk.hh>
#include <frackit/geometry/cylindersurface.hh>
#include <frackit/geometry/name.hh>
#include <frackit/geometryutilities/name.hh>
#include "pointongeometry.hh"
......
......@@ -31,6 +31,8 @@
#include <frackit/distance/distance.hh>
#include <frackit/magnitude/magnitude.hh>
#include <frackit/geometryutilities/applyongeometry.hh>
#include <frackit/intersection/intersect.hh>
#include <frackit/intersection/emptyintersection.hh>
......@@ -81,6 +83,13 @@ EntityNetworkConstraints<ST> makeDefaultConstraints()
template<class ST, class AE>
class EntityNetworkConstraints
{
// Helper struct to determine if something is a shared_ptr
template<class T>
struct IsSharedPtr : public std::false_type {};
// Specialization for shared_ptr
template<class T>
struct IsSharedPtr<std::shared_ptr<T>> : public std::true_type {};
public:
//! Export type used for constraints
......@@ -98,7 +107,7 @@ public:
{
static_assert(std::is_default_constructible<AE>::value,
"Angle computation engine not default constructible. "
"Use constructor taking the engines as arguments instead");
"Use constructor taking the engine as argument instead");
}
/*!
......@@ -174,21 +183,17 @@ public:
void allowEquiDimensionalIntersections(bool value)
{ allowEquiDimIS_ = value; }
/*!
* \brief Set the engine used for angle computations
* \param angleEngine An instance of the engine
*/
void setAngleComputationEngine(const AngleComputationEngine& angleEngine)
{ angleEngine_ = angleEngine; }
/*!
* \brief Check if a pair of geometries fulfills the constraints
* \param geo1 The first geometry
* \param geo2 The second geometry
* \returns True if all constraints are fulfilled, false otherwise
* \note The enable_if here is it avoid overload ambiguity with the
* overloads receiving a shared pointer as on of the arguments.
*/
template<class Geo1, class Geo2>
bool evaluate(const Geo1& geo1, const Geo2& geo2)
template<class Geo1, class Geo2,
std::enable_if_t< (!IsSharedPtr<Geo1>::value && !IsSharedPtr<Geo2>::value), int> = 0>
bool evaluate(const Geo1& geo1, const Geo2& geo2) const
{
static constexpr int dim = DimensionalityTraits<Geo1>::geometryDimension();
static_assert(dim == DimensionalityTraits<Geo2>::geometryDimension(),
......@@ -240,15 +245,47 @@ public:
* \param entitySet An entity network
* \param entity The geometry of the entity to be checked
* \returns True if all constraints are fulfilled, false otherwise
* \note The enable_if here is it avoid overload ambiguity with the
* overload receiving a shared pointer as second argument.
*/
template<class Geo1, class Geo2>
bool evaluate(const std::vector<Geo1>& entitySet, const Geo2& entity)
template<class Geo1, class Geo2, std::enable_if_t<!IsSharedPtr<Geo2>::value, int> = 0>
bool evaluate(const std::vector<Geo1>& entitySet, const Geo2& entity) const
{
return std::all_of(entitySet.begin(),
entitySet.end(),
[&] (const auto& e) { return evaluate(e, entity); });
}
/*!
* \brief Overload for one of the arguments being a shared_ptr
* to a generic geometry. This requires parsing the
* pointer to its original geometry type.
* \tparam T either a entity type or an entity set
* \param entityOrSet An entity or an entity set
* \param geo2 Pointer to a generic geometry type
* \returns True if all constraints are fulfilled, false otherwise
*/
template<class T>
bool evaluate(const T& entityOrSet, std::shared_ptr<Geometry> geo2Ptr) const
{
// encapsulate the constraint evaluation in a lambda
auto eval = [&] (const auto& actualGeo2) { return evaluate(entityOrSet, actualGeo2); };
return applyOnGeometry(eval, geo2Ptr);
}
/*!
* \brief Overload for one of the arguments being a shared_ptr
* to a generic geometry. Unfortunately, this requires
* parsing the pointer to its original geometry type.
* \tparam T either a entity type or an entity set
* \param geo1 Pointer to a generic geometry type
* \param entityOrSet An entity or an entity set
* \returns True if all constraints are fulfilled, false otherwise
*/
template<class T>
bool evaluate(std::shared_ptr<Geometry> geo1Ptr, const T& entityOrSet) const
{ return evaluate(entityOrSet, geo1Ptr); }
private:
AngleComputationEngine angleEngine_; //! Algorithms to compute angles between intersecting geometries
......@@ -266,7 +303,6 @@ private:
Scalar intersectionEps_; //! Tolerance value to be used for intersections
bool useIntersectionEps_; //! Stores wether or not a user-defined epsilon value was set
};
} // end namespace Frackit
......
......@@ -41,7 +41,8 @@
#include <frackit/geometry/segment.hh>
#include <frackit/geometry/ellipsearc.hh>
#include <frackit/geometry/ellipse.hh>
#include <frackit/geometry/name.hh>
#include <frackit/geometryutilities/name.hh>
namespace Frackit {
namespace ConstraintImpl {
......
......@@ -11,7 +11,6 @@ ellipse.hh
ellipticalgeometry.hh
geometry.hh
line.hh
name.hh
plane.hh
point.hh
quadrilateral.hh
......
install(FILES
applyongeometry.hh
assign.hh
name.hh
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/frackit/geometryutilities)
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*****************************************************************************
* See the file COPYING for full copying permissions. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*****************************************************************************/
/*!
* \file
* \brief Utility functionality to apply functions on
* geometrical objects of which only the pointer
* to the virtual base class is available. In a
* first step, the geometry is cast into ist actual
* implementation and then the provided lambda function
* is evaluated on the actual geometry.
*/
#ifndef FRACKIT_GEOMETRY_UTILITY_APPLY_ON_GEOMETRY_HH
#define FRACKIT_GEOMETRY_UTILITY_APPLY_ON_GEOMETRY_HH
#include <memory>
#include <string>
#include <stdexcept>
#include <type_traits>
#include <frackit/geometry/geometry.hh>
#include <frackit/geometryutilities/name.hh>
// The supported geometry types.
// If a new geometry is added, it has to be included here and the
// implementation in the applyOnGeometry() function has to be extended.
#include <frackit/geometry/disk.hh>
#include <frackit/geometry/quadrilateral.hh>
#include "assign.hh"
namespace Frackit {
/*!
* \brief Apply a function to the geometry referenced
* to by the given pointer on the geometry interface.
* \param geoPtr Pointer to an object of the geometry interface
* \param applyFunc The function to be executed on the geometry
* \note All possible geometry types must be hardcoded here
*/
template<class ApplyFunc, class ctype = double>
auto applyOnGeometry(ApplyFunc&& applyFunc, Geometry* geoPtr)
{
if (geoPtr->name() == "Disk")
{
Disk<ctype> disk;
if (!assign(geoPtr, disk))
throw std::runtime_error("applyOnGeometry(): could not assign disk");
return applyFunc(disk);
}
else if (geoPtr->name() == "Quadrilateral_3d")
{
Quadrilateral<ctype, 3> quad;
if (!assign(geoPtr, quad))
throw std::runtime_error("applyOnGeometry(): could not assign 3d quadrilateral");
return applyFunc(quad);
}
std::string msg = "applyOnGeometry() function not implemented ";
msg += "for geometry with name \"";
msg += geoPtr->name();
msg += "\"\n";
throw std::runtime_error(msg);
}
/*!
* \brief Overload for std::shared_ptr.
*/
template<class ApplyFunc, class ctype = double>
auto applyOnGeometry(ApplyFunc&& applyFunc, std::shared_ptr<Geometry> geoPtr)
{ return applyOnGeometry<ApplyFunc, ctype>(applyFunc, geoPtr.get()); }
/*!
* \brief Overload for std::unique_ptr.
*/
template<class ApplyFunc, class ctype = double>
auto applyOnGeometry(std::unique_ptr<Geometry> geoPtr, ApplyFunc& applyFunc)
{ return applyOnGeometry<ApplyFunc, ctype>(applyFunc, geoPtr.get()); }
} // end namespace Frackit
#endif // FRACKIT_GEOMETRY_UTILITY_APPLY_ON_GEOMETRY_HH
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*****************************************************************************
* See the file COPYING for full copying permissions. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*****************************************************************************/
/*!
* \file
* \brief Utility functionality to cast pointers on objects of
* the geometry interface into the corresponding geometry type.
*/
#ifndef FRACKIT_GEOMETRY_UTILITY_ASSIGN_HH
#define FRACKIT_GEOMETRY_UTILITY_ASSIGN_HH
#include <memory>
#include <type_traits>
#include <frackit/geometry/geometry.hh>
#include <frackit/geometryutilities/name.hh>
namespace Frackit {
/*!
* \brief Try to cast a pointer on a geometrical object
* into the provided instance of a geometry.
* \param geoPtr Pointer to an object of the geometry interface
* \param geo The geometry object in which it should be casted
*/
template<class GeoType>
bool assign(Geometry* geoPtr, GeoType& geo)
{
static_assert(std::is_base_of<Geometry, GeoType>::value,
"Provided geometry does not inherit from the geometry interface");
if (geometryName(geo) == geoPtr->name())
{
GeoType* actualGeoPtr = dynamic_cast<GeoType*>(geoPtr);
geo = GeoType(*actualGeoPtr);
return true;
}
return false;
}
/*!
* \brief Overload for std::shared_ptr.
*/
template<class GeoType>
bool assign(std::shared_ptr<Geometry> geoPtr, GeoType& geo)
{ return assign(geoPtr.get(), geo); }
/*!
* \brief Overload for std::unique_ptr.
*/
template<class GeoType>
bool assign(std::unique_ptr<Geometry> geoPtr, GeoType& geo)
{ return assign(geoPtr.get(), geo); }
} // end namespace Frackit
#endif // FRACKIT_GEOMETRY_UTILITY_ASSIGN_HH
......@@ -50,7 +50,7 @@
#include <frackit/geometry/line.hh>
#include <frackit/geometry/cylindersurface.hh>
#include <frackit/geometry/name.hh>
#include <frackit/geometryutilities/name.hh>
#include <frackit/common/extractdimension.hh>
#include <frackit/occ/gputilities.hh>
......@@ -89,7 +89,7 @@ public:
template<class Geo1, class Geo2, class IsGeometry>
ctype operator() (const Geo1& geo1,
const Geo2& geo2,
const IsGeometry& isGeom)
const IsGeometry& isGeom) const
{
std::string msg = "Intersection angle not implemented for ";
msg += "\"" + geometryName(geo1) + "\"";
......@@ -108,7 +108,7 @@ public:
template<int wd>
ctype operator() (const Plane<ctype, wd>& plane1,
const Plane<ctype, wd>& plane2,
const Line<ctype, wd>& isLine)
const Line<ctype, wd>& isLine) const
{
using std::abs;
using std::acos;
......@@ -125,7 +125,7 @@ public:
*/
template<int wd>
ctype operator() (const Plane<ctype, wd>& plane1,
const Plane<ctype, wd>& plane2)
const Plane<ctype, wd>& plane2) const
{
assert( !isEmptyIntersection(intersect(plane1, plane2)) );
......@@ -147,7 +147,7 @@ public:
&& IsPlanarGeometry<Geo2>::value, int> = 0>
ctype operator() (const Geo1& geo1,
const Geo2& geo2,
const Point<ctype, 3>& isPoint)
const Point<ctype, 3>& isPoint) const
{ return (*this)(geo1.supportingPlane(), geo2.supportingPlane()); }
/*!
......@@ -162,7 +162,7 @@ public:
&& IsPlanarGeometry<Geo2>::value, int> = 0>
ctype operator() (const Geo1& geo1,
const Geo2& geo2,
const Segment<ctype, 3>& isSeg)
const Segment<ctype, 3>& isSeg) const
{ return (*this)(geo1.supportingPlane(), geo2.supportingPlane()); }
/*!
......@@ -176,7 +176,7 @@ public:
template<class Geo, std::enable_if_t<IsPlanarGeometry<Geo>::value, int> = 0>
ctype operator() (const Geo& geo,
const CylinderSurface<ctype>& cylSurface,
const Point<ctype, 3>& isPoint)
const Point<ctype, 3>& isPoint) const
{ return (*this)(geo.supportingPlane(), cylSurface.getTangentPlane(isPoint)); }
/*!
......@@ -190,7 +190,7 @@ public:
template<class Geo, std::enable_if_t<IsPlanarGeometry<Geo>::value, int> = 0>
ctype operator() (const CylinderSurface<ctype>& cylSurface,
const Geo& geo,
const Point<ctype, 3>& isPoint)
const Point<ctype, 3>& isPoint) const
{ return(*this)(geo, cylSurface, isPoint); }
/*!
......@@ -208,7 +208,7 @@ public:
template<class Geo, std::enable_if_t<IsPlanarGeometry<Geo>::value, int> = 0>
ctype operator() (const Geo& geo,
const CylinderSurface<ctype>& cylSurface,
const Segment<ctype, 3>& isSeg)
const Segment<ctype, 3>& isSeg) const
{ return (*this)(geo.supportingPlane(), cylSurface.getTangentPlane(isSeg.source())); }
/*!
......@@ -226,7 +226,7 @@ public:
template<class Geo, std::enable_if_t<IsPlanarGeometry<Geo>::value, int> = 0>
ctype operator() (const CylinderSurface<ctype>& cylSurface,
const Geo& geo,
const Segment<ctype, 3>& isSeg)
const Segment<ctype, 3>& isSeg) const
{ return (*this)(geo, cylSurface, isSeg); }
/*!
......@@ -239,7 +239,7 @@ public:
template<class Geo, std::enable_if_t<IsPlanarGeometry<Geo>::value, int> = 0>
ctype operator() (const Geo& geo,
const CylinderSurface<ctype>& cylSurface,
const EllipseArc<ctype, 3>& isArc)
const EllipseArc<ctype, 3>& isArc) const
{
// use the minimum angle between the geometry plane and the
// tangent plane on the surface at four sample points
......@@ -268,7 +268,7 @@ public:
template<class Geo, std::enable_if_t<IsPlanarGeometry<Geo>::value, int> = 0>
ctype operator() (const CylinderSurface<ctype>& cylSurface,
const Geo& geo,
const EllipseArc<ctype, 3>& isArc)
const EllipseArc<ctype, 3>& isArc) const
{ return (*this)(geo, cylSurface, isArc); }
/*!
......@@ -281,7 +281,7 @@ public:
template<class Geo, std::enable_if_t<IsPlanarGeometry<Geo>::value, int> = 0>
ctype operator() (const Geo& geo,
const CylinderSurface<ctype>& cylSurface,
const Ellipse<ctype, 3>& isEllipse)
const Ellipse<ctype, 3>& isEllipse) const
{
// use the minimum angle between the geometry plane and the
// tangent plane on the surface at eight sample points
......@@ -312,7 +312,7 @@ public:
template<class Geo, std::enable_if_t<IsPlanarGeometry<Geo>::value, int> = 0>
ctype operator() (const CylinderSurface<ctype>& cylSurface,
const Geo& geo,
const Ellipse<ctype, 3>& isEllipse)
const Ellipse<ctype, 3>& isEllipse) const
{ return (*this)(geo, cylSurface, isEllipse); }
/*!
......@@ -325,7 +325,7 @@ public:
template<class Geo, std::enable_if_t<IsPlanarGeometry<Geo>::value, int> = 0>
ctype operator() (const Geo& geo,
const TopoDS_Face& face,
const Point<ctype, 3>& isPoint)
const Point<ctype, 3>& isPoint) const
{
// get the parameters of this point on the face via orthogonal projection
const auto geomSurface = OCCUtilities::getGeomHandle(face);
......@@ -359,7 +359,7 @@ public:
template<class Geo, std::enable_if_t<IsPlanarGeometry<Geo>::value, int> = 0>
ctype operator() (const TopoDS_Face& face,
const Geo& geo,
const Point<ctype, 3>& isPoint)
const Point<ctype, 3>& isPoint) const
{ return (*this)(geo, face, isPoint); }
/*!
......@@ -372,7 +372,7 @@ public:
template<class Geo, std::enable_if_t<IsPlanarGeometry<Geo>::value, int> = 0>
ctype operator() (const Geo& geo,
const TopoDS_Face& face,
const TopoDS_Edge& isEdge)
const TopoDS_Edge& isEdge) const
{
// compute the angle at several sample points along the edge and take minimum
const auto edgeHandle = OCCUtilities::getGeomHandle(isEdge);
......@@ -402,7 +402,7 @@ public:
template<class Geo, std::enable_if_t<IsPlanarGeometry<Geo>::value, int> = 0>
ctype operator() (const TopoDS_Face& face,
const Geo& geo,
const TopoDS_Edge& isEdge)
const TopoDS_Edge& isEdge) const
{ return (*this)(geo, face, isEdge); }
/*!
......@@ -415,7 +415,7 @@ public:
template<class Geo, std::enable_if_t<IsPlanarGeometry<Geo>::value, int> = 0>
ctype operator() (const Geo& geo,
const TopoDS_Face& face,
const TopoDS_Face& isFace)
const TopoDS_Face& isFace) const
{ return 0.0; }
/*!
......@@ -428,7 +428,7 @@ public:
template<class Geo, std::enable_if_t<IsPlanarGeometry<Geo>::value, int> = 0>
ctype operator() (const TopoDS_Face& face,
const Geo& geo,
const TopoDS_Face& isFace)
const TopoDS_Face& isFace) const
{ return (*this)(geo, face, isFace); }
/*!
......@@ -440,7 +440,7 @@ public:
template<class Geo1, class Geo2, class... T>
ctype operator() (const Geo1& geo1,
const Geo2& geo2,
const std::variant<T...>& intersection)
const std::variant<T...>& intersection) const
{ return std::visit([&] (auto&& is) { return (*this)(geo1, geo2, is); }, intersection); }
/*!
......@@ -451,7 +451,7 @@ public:
template<class Geo1, class Geo2, class T>
ctype operator() (const Geo1& geo1,
const Geo2& geo2,
const std::vector<T>& intersections)
const std::vector<T>& intersections) const
{
using std::min;
ctype result = std::numeric_limits<ctype>::max();
......
......@@ -84,7 +84,8 @@
#include <frackit/geometry/cylinder.hh>