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

Merge branch 'initial-development' into 'master'

Initial development

See merge request DennisGlaeser/frackit!1
parents 37274cde ad7fa7dc
add_subdirectory(common)
add_subdirectory(distance)
add_subdirectory(entitynetwork)
add_subdirectory(geometry) add_subdirectory(geometry)
add_subdirectory(intersection) add_subdirectory(intersection)
add_subdirectory(magnitude)
add_subdirectory(occ)
add_subdirectory(precision)
add_subdirectory(sampling)
install(FILES
extractctype.hh
extractdimension.hh
math.hh
promotedtype.hh
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/frackit/common)
// -*- 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 Type traits to extract the coordinate type of geometric objects.
*/
#ifndef FRACKIT_COMMON_COORDINATE_TYPE_HH
#define FRACKIT_COMMON_COORDINATE_TYPE_HH
#include <utility>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Wire.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Shell.hxx>
#include <TopoDS_Solid.hxx>
#include <Standard.hxx>
namespace Frackit {
/*!
* \brief Traits class to extract the coordinate type from a geometry.
* \note This is the specialization used for internal geometry types
* which carry the information of the coordinate type themselves.
*/
template<class Geom>
struct CoordinateTypeTraits
{ using type = typename Geom::ctype; };
/*!
* \brief Specialization for Brep shapes.
*/
template<>
struct CoordinateTypeTraits<TopoDS_Shape>
{ using type = Standard_Real; };
/*!
* \brief Specialization for Brep vertices.
*/
template<>
struct CoordinateTypeTraits<TopoDS_Vertex>
: public CoordinateTypeTraits<TopoDS_Shape>
{};
/*!
* \brief Specialization for Brep edges.
*/
template<>
struct CoordinateTypeTraits<TopoDS_Edge>
: public CoordinateTypeTraits<TopoDS_Shape>
{};
/*!
* \brief Specialization for Brep wires.
*/
template<>
struct CoordinateTypeTraits<TopoDS_Wire>
: public CoordinateTypeTraits<TopoDS_Shape>
{};
/*!
* \brief Specialization for Brep faces.
*/
template<>
struct CoordinateTypeTraits<TopoDS_Face>
: public CoordinateTypeTraits<TopoDS_Shape>
{};
/*!
* \brief Specialization for Brep shells.
*/
template<>
struct CoordinateTypeTraits<TopoDS_Shell>
: public CoordinateTypeTraits<TopoDS_Shape>
{};
/*!
* \brief Specialization for Brep solids.
*/
template<>
struct CoordinateTypeTraits<TopoDS_Solid>
: public CoordinateTypeTraits<TopoDS_Shape>
{};
} // end namespace Frackit
#endif // FRACKIT_COMMON_COORDINATE_TYPE_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 Type traits to extract the dimensionality of geometric objects.
*/
#ifndef FRACKIT_COMMON_EXTRACT_DIMENSION_HH
#define FRACKIT_COMMON_EXTRACT_DIMENSION_HH
#include <utility>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Wire.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Shell.hxx>
#include <TopoDS_Solid.hxx>
#include <Standard.hxx>
namespace Frackit {
/*!
* \brief Traits class to extract the dimensionalty of a geometry.
* \note This is the specialization used for internal geometry types
* which carry the information of the dimensions themselves.
*/
template<class Geom>
struct DimensionalityTraits
{
static constexpr int geomDim = Geom::myDimension();
static constexpr int worldDim = Geom::worldDimension();
};
/*!
* \brief Specialization for Brep shapes.
*/
template<>
struct DimensionalityTraits<TopoDS_Shape>
{
static constexpr int worldDim = 3;
};
/*!
* \brief Specialization for Brep vertices.
*/
template<>
struct DimensionalityTraits<TopoDS_Vertex>
: public DimensionalityTraits<TopoDS_Shape>
{
static constexpr int geomDim = 0;
};
/*!
* \brief Specialization for Brep edges.
*/
template<>
struct DimensionalityTraits<TopoDS_Edge>
: public DimensionalityTraits<TopoDS_Shape>
{
static constexpr int geomDim = 1;
};
/*!
* \brief Specialization for Brep wires.
*/
template<>
struct DimensionalityTraits<TopoDS_Wire>
: public DimensionalityTraits<TopoDS_Shape>
{
static constexpr int geomDim = 1;
};
/*!
* \brief Specialization for Brep faces.
*/
template<>
struct DimensionalityTraits<TopoDS_Face>
: public DimensionalityTraits<TopoDS_Shape>
{
static constexpr int geomDim = 2;
};
/*!
* \brief Specialization for Brep shells.
*/
template<>
struct DimensionalityTraits<TopoDS_Shell>
: public DimensionalityTraits<TopoDS_Shape>
{
static constexpr int geomDim = 2;
};
/*!
* \brief Specialization for Brep solids.
*/
template<>
struct DimensionalityTraits<TopoDS_Solid>
: public DimensionalityTraits<TopoDS_Shape>
{
static constexpr int geomDim = 3;
};
/*!
* \brief Free function to return the dimension of a geometry.
*/
template<class Geom>
constexpr int getDimension(const Geom& g)
{ return DimensionalityTraits<Geom>::geomDim; }
/*!
* \brief Free function to return the dimension of the space
* in which a geometry is described in.
*/
template<class Geom>
constexpr int getWorldDimension(const Geom& g)
{ return DimensionalityTraits<Geom>::worldDim; }
} // end namespace Frackit
#endif // FRACKIT_COMMON_EXTRACT_DIMENSION_HH
...@@ -23,8 +23,11 @@ ...@@ -23,8 +23,11 @@
#ifndef FRACKIT_MATH_HH #ifndef FRACKIT_MATH_HH
#define FRACKIT_MATH_HH #define FRACKIT_MATH_HH
#include <cmath>
#include <vector>
#include <frackit/geometry/vector.hh> #include <frackit/geometry/vector.hh>
#include <frackit/geometry/precision.hh> #include <frackit/precision/precision.hh>
namespace Frackit { namespace Frackit {
...@@ -40,6 +43,14 @@ Vector<ctype, 3> crossProduct(const Vector<ctype, 3>& v1, ...@@ -40,6 +43,14 @@ Vector<ctype, 3> crossProduct(const Vector<ctype, 3>& v1,
v1.x()*v2.y() - v1.y()*v2.x() }; v1.x()*v2.y() - v1.y()*v2.x() };
} }
/*!
* \todo TODO doc me.
*/
template <class ctype>
ctype crossProduct(const Vector<ctype, 2>& v1,
const Vector<ctype, 2>& v2)
{ return v1.x()*v2.y() - v1.y()*v2.x(); }
/*! /*!
* \brief \todo TODO doc me. * \brief \todo TODO doc me.
*/ */
...@@ -57,10 +68,80 @@ bool isRightHandSystem(const Vector<ctype, 3>& v1, ...@@ -57,10 +68,80 @@ bool isRightHandSystem(const Vector<ctype, 3>& v1,
const Vector<ctype, 3>& v2, const Vector<ctype, 3>& v2,
const Vector<ctype, 3>& v3) const Vector<ctype, 3>& v3)
{ {
assert(std::abs(boxProduct(v1, v2, v3)) > Precision<ctype>::confusion()); assert(std::abs(boxProduct(v1, v2, v3)) > v1.length()*Precision<ctype>::confusion()
*v2.length()*Precision<ctype>::confusion()
*v3.length()*Precision<ctype>::confusion());
return boxProduct(v1, v2, v3) > 0.0; return boxProduct(v1, v2, v3) > 0.0;
} }
/*!
* \brief \todo TODO doc me.
*/
template<class ctype>
ctype toDegrees(const ctype radians)
{ return radians*180.0/M_PI; }
/*!
* \brief \todo TODO doc me.
*/
template<class ctype>
ctype toRadians(const ctype degrees)
{ return degrees*M_PI/180.0; }
/*!
* \brief \todo TODO doc me. Cite Wiki entry.
*/
template<class ctype>
void rotate(Vector<ctype, 3>& v,
const Direction<ctype, 3>& axis,
const ctype angle)
{
using std::sin;
using std::cos;
const auto cosPhi = cos(angle);
const auto sinPhi = sin(angle);
Vector<ctype, 3> Rx(cosPhi + axis.x()*axis.x()*(1.0 - cosPhi),
axis.x()*axis.y()*(1.0 - cosPhi) - axis.z()*sinPhi,
axis.x()*axis.z()*(1.0 - cosPhi) - axis.y()*sinPhi);
Vector<ctype, 3> Ry(axis.y()*axis.x()*(1.0 - cosPhi) + axis.z()*sinPhi,
cosPhi + axis.y()*axis.y()*(1.0 - cosPhi),
axis.y()*axis.z()*(1.0 - cosPhi) - axis.x()*sinPhi);
Vector<ctype, 3> Rz(axis.z()*axis.x()*(1.0 - cosPhi) - axis.y()*sinPhi,
axis.z()*axis.y()*(1.0 - cosPhi) + axis.x()*sinPhi,
cosPhi + axis.z()*axis.z()*(1.0 - cosPhi));
v = Vector<ctype, 3>(Rx*v, Ry*v, Rz*v);
}
/*!
* \brief \todo TODO doc me. Cite Wiki entry.
*/
template<class ctype>
void rotate(std::vector<Vector<ctype, 3>>& vectors,
const Direction<ctype, 3>& axis,
const ctype angle)
{
using std::sin;
using std::cos;
const auto cosPhi = cos(angle);
const auto sinPhi = sin(angle);
Vector<ctype, 3> Rx(cosPhi + axis.x()*axis.x()*(1.0 - cosPhi),
axis.x()*axis.y()*(1.0 - cosPhi) - axis.z()*sinPhi,
axis.x()*axis.z()*(1.0 - cosPhi) - axis.y()*sinPhi);
Vector<ctype, 3> Ry(axis.y()*axis.x()*(1.0 - cosPhi) + axis.z()*sinPhi,
cosPhi + axis.y()*axis.y()*(1.0 - cosPhi),
axis.y()*axis.z()*(1.0 - cosPhi) - axis.x()*sinPhi);
Vector<ctype, 3> Rz(axis.z()*axis.x()*(1.0 - cosPhi) - axis.y()*sinPhi,
axis.z()*axis.y()*(1.0 - cosPhi) + axis.x()*sinPhi,
cosPhi + axis.z()*axis.z()*(1.0 - cosPhi));
for (auto& v : vectors)
v = Vector<ctype, 3>(Rx*v, Ry*v, Rz*v);
}
} // end namespace Frackit } // end namespace Frackit
#endif // FRACKIT_MATH_HH #endif // FRACKIT_MATH_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 Determines the type that results from arithmetic
* operations on two different number types.
*/
#ifndef FRACKIT_PROMOTED_TYPE_HH
#define FRACKIT_PROMOTED_TYPE_HH
#include <utility>
namespace Frackit {
/*!
* \brief Determines the type that results from arithmetic
* operations on two different number types.
*/
template<class T1, class T2>
struct PromotionTraits
{
typedef decltype(std::declval<T1>()+std::declval<T2>()) PromotedType;
};
// Specialization for the case of two equal types
template<class T1>
struct PromotionTraits<T1,T1> { typedef T1 PromotedType; };
/*!
* \brief Convenience alias to get the promoted type
*/
template<class T1, class T2>
using PromotedType = typename PromotionTraits<T1, T2>::PromotedType;
} // end namespace Frackit
#endif // FRACKIT_PROMOTED_TYPE_HH
install(FILES
distance.hh
distancetoboundary.hh
pointonboundary.hh
pointongeometry.hh
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/frackit/distance)
// -*- 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 Contains functionality for computing
* the distance between geometries.
*/
#ifndef FRACKIT_DISTANCE_HH
#define FRACKIT_DISTANCE_HH
#include <cmath>
#include <TopoDS_Shape.hxx>
#include <BRepExtrema_DistShapeShape.hxx>
#include <Extrema_ExtAlgo.hxx>
#include <Extrema_ExtFlag.hxx>
#include <frackit/precision/precision.hh>
#include <frackit/common/promotedtype.hh>
#include <frackit/occ/breputilities.hh>
#include <frackit/geometry/point.hh>
#include <frackit/geometry/vector.hh>
#include <frackit/geometry/line.hh>
#include <frackit/geometry/segment.hh>
namespace Frackit {
namespace Impl {
// Convenience alias to extract the promoted type
// of the types used for coordinates of two geometries.
// This makes the code below more readable in some places
template<class Geom1, class Geom2>
using PCT = PromotedType<typename Geom1::ctype,
typename Geom2::ctype>;
}
/*!
* \brief Computes the distance between two TopoDS_Shape objects.
* \param shape1 The first shape
* \param shape2 The second shape
* \param deflection The epsilon used in the BrepExtrema command
* \param extFlag The flag passed to the BrepExtrema command (MIN/MAX/MINMAX)
* \param extAlgo The algorithm passed to the BrepExtrema command (TREE/GRAD)
*/
template<class ctype = double>
ctype computeDistance(const TopoDS_Shape& shape1,
const TopoDS_Shape& shape2,
ctype deflection = Precision<ctype>::confusion(),
Extrema_ExtFlag extFlag = Extrema_ExtFlag_MINMAX,
Extrema_ExtAlgo extAlgo = Extrema_ExtAlgo_Grad)
{
BRepExtrema_DistShapeShape algo(shape1, shape2, deflection, extFlag, extAlgo);
if (!algo.IsDone())
throw std::runtime_error(std::string("Could not compute BRep distance"));
return algo.Value();
}
/*!
* \brief In the general case we compute the distance based on
* the basis of the BRep of the geometries. Overloads for
* geometries for which the distance can be computed more
* easily are provided below.
* \param geo1 The first geometry
* \param geo2 The second geometry
* \param deflection The epsilon used in the BrepExtrema command
* \param extFlag The flag passed to the BrepExtrema command (MIN/MAX/MINMAX)
* \param extAlgo The algorithm passed to the BrepExtrema command (TREE/GRAD)
*/
template<class Geom1, class Geom2>
Impl::PCT<Geom1, Geom2>
computeDistance(const Geom1& geo1,
const Geom2& geo2,
Impl::PCT<Geom1, Geom2> deflection = Precision<Impl::PCT<Geom1, Geom2>>::confusion(),
Extrema_ExtFlag extFlag = Extrema_ExtFlag_MINMAX,
Extrema_ExtAlgo extAlgo = Extrema_ExtAlgo_Grad)
{ return computeDistance(OCCUtilities::getShape(geo1), OCCUtilities::getShape(geo2)); }
/*!
* \brief Overload for one of the geometries being a shape object.
* \param shape The shape of one geometry
* \param geo The second geometry
* \param deflection The epsilon used in the BrepExtrema command
* \param extFlag The flag passed to the BrepExtrema command (MIN/MAX/MINMAX)
* \param extAlgo The algorithm passed to the BrepExtrema command (TREE/GRAD)
*/
template<class Geom>
typename Geom::ctype
computeDistance(const TopoDS_Shape& shape,
const Geom& geo,
typename Geom::ctype deflection = Precision<typename Geom::ctype>::confusion(),
Extrema_ExtFlag extFlag = Extrema_ExtFlag_MINMAX,
Extrema_ExtAlgo extAlgo = Extrema_ExtAlgo_Grad)
{ return computeDistance(shape, OCCUtilities::getShape(geo)); }
/*!
* \brief Overload for one of the geometries being a shape object.
* \param geo The second geometry
* \param shape The shape of one geometry
* \param deflection The epsilon used in the BrepExtrema command
* \param extFlag The flag passed to the BrepExtrema command (MIN/MAX/MINMAX)
* \param extAlgo The algorithm passed to the BrepExtrema command (TREE/GRAD)
*/
template<class Geom>
typename Geom::ctype
computeDistance(const Geom& geo,
const TopoDS_Shape& shape,
typename Geom::ctype deflection = Precision<typename Geom::ctype>::confusion(),
Extrema_ExtFlag extFlag = Extrema_ExtFlag_MINMAX,
Extrema_ExtAlgo extAlgo = Extrema_ExtAlgo_Grad)
{ return computeDistance(OCCUtilities::getShape(geo), shape); }
/*!
* \brief Returns the euclidian distance between two points.
*/
template<class ctype1, class ctype2, int worldDim>
PromotedType<ctype1, ctype2> computeDistance(const Point<ctype1, worldDim>& p1,
const Point<ctype2, worldDim>& p2)
{ return Vector<PromotedType<ctype1, ctype2>, worldDim>(p1, p2).length(); }
/*!
* \brief Returns the euclidian distance between a point and a line.
*/
template<class ctype1, class ctype2, int worldDim>
PromotedType<ctype1, ctype2> computeDistance(const Point<ctype1, worldDim>& p,
const Line<ctype2, worldDim>& line)
{ return Vector<PromotedType<ctype1, ctype2>, worldDim>(p, line.projection(p)).length(); }
/*!
* \brief Returns the euclidian distance between a line and a point.
*/
template<class ctype1, class ctype2, int worldDim>
PromotedType<ctype1, ctype2> computeDistance(const Line<ctype1, worldDim>& line,
const Point<ctype2, worldDim>& p)
{ return computeDistance(p, line); }
/*!
* \brief Returns the euclidian distance between a point and a segmennt.
*/
template<class ctype1, class ctype2, int worldDim>
PromotedType<ctype1, ctype2> computeDistance(const Point<ctype1, worldDim>& p,
const Segment<ctype2, worldDim>& seg)
{
using ctype = PromotedType<ctype1, ctype2>;
const auto proj = seg.supportingLine().projection(p);
if (seg.contains(proj))
return Vector<ctype, worldDim>(p, proj).length();
const auto d1 = Vector<ctype, worldDim>(p, seg.source()).length();
const auto d2 = Vector<ctype, worldDim>(p, seg.target()).length();