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

Merge branch 'feature/improve-entity-networks' into 'master'

Feature/improve entity networks

See merge request tools/frackit!200
parents 00c15719 2d907608
Pipeline #2767 passed with stages
in 12 minutes and 20 seconds
install(FILES
id.hh
idpair.hh
iteratorfacades.hh
iteratorrange.hh
math.hh
promotedtype.hh
typetraits.hh
......
......@@ -61,6 +61,12 @@ public:
bool operator== (const Id& otherId) const
{ return id_ == otherId.get(); }
/*!
* \brief Inequality 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 3 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
* \ingroup Common
* \brief Base class for stl conformant forward iterators.
* The implementations are strongly inspired by Dune, see
* https://gitlab.dune-project.org/core/dune-common/-/blob/master/dune/common/iteratorfacades.hh
*
*/
#ifndef FRACKIT_COMMON_ITERATORFACADES_HH
#define FRACKIT_COMMON_ITERATORFACADES_HH
#include <cstddef>
#include <iterator>
#include <type_traits>
namespace Frackit {
/*!
* \ingroup Common
* \brief Base class for stl conformant forward iterators.
* The implementation is strongly inspired by the one in Dune, see
* https://gitlab.dune-project.org/core/dune-common/-/blob/master/dune/common/iteratorfacades.hh
*
* Implementations must define following functions:
*
* \code
*
* // Access the value referred to.
* reference dereference() const;
*
* // Compare for equality with iterator j
* bool equals(j);
*
* // position the iterator at the next element.
* void increment()
*
* \endcode
*
* See the above link to dune-common for more information.
*
* \tparam IT Iterator implementation
* \tparam VT The value type
* \tparam RT The reference type
* \tparam DT The type for differences between two iterators
*/
template<class IT, class VT, class RT = VT&, class DT = std::ptrdiff_t>
class ForwardIteratorFacade
{
using Implementation = IT;
template<class OtherIt>
static constexpr bool isInteroperable = std::is_convertible_v<Implementation, OtherIt>
|| std::is_convertible_v<OtherIt, Implementation>;
public:
// type aliases required by C++ for iterators
using iterator_category = std::forward_iterator_tag;
using value_type = typename std::remove_const<VT>::type;
using difference_type = DT;
using pointer = VT*;
using reference = RT;
//! dereferencing operator
reference operator*() const
{ return static_cast<Implementation const*>(this)->dereference(); }
//! dereferencing operator
pointer operator->() const
{ return &(static_cast<const Implementation *>(this)->dereference()); }
//! Preincrement operator
Implementation& operator++()
{
static_cast<Implementation *>(this)->increment();
return *static_cast<Implementation *>(this);
}
//! Postincrement operator
Implementation operator++(int)
{
Implementation tmp(static_cast<Implementation const&>(*this));
this->operator++();
return tmp;
}
//! equality operator
template<class OtherIt, std::enable_if_t<isInteroperable<OtherIt>, int> = 0>
friend inline bool operator==(const Implementation& it, const OtherIt& otherIt)
{ return it.equals(otherIt); }
template<class OtherIt, std::enable_if_t<isInteroperable<OtherIt>
&& !std::is_same_v<OtherIt, Implementation>, int> = 0>
friend inline bool operator==(const OtherIt& otherIt, const Implementation& it)
{ return it.equals(otherIt); }
//! inequality operator
template<class OtherIt, std::enable_if_t<isInteroperable<OtherIt>, int> = 0>
friend inline bool operator!=(const Implementation& it, const OtherIt& otherIt)
{ return !it.equals(otherIt); }
template<class OtherIt, std::enable_if_t<isInteroperable<OtherIt>
&& !std::is_same_v<OtherIt, Implementation>, int> = 0>
friend inline bool operator!=(const OtherIt& otherIt, const Implementation& it)
{ return !it.equals(otherIt); }
};
/*!
* \brief Iterator facade for a random-access container, of which
* one wants to iterate over a set of elements by means of
* a list of indices.
*/
template<class Container, class IndexList>
class RandomAccessContainerIndexedIterator
: public ForwardIteratorFacade< RandomAccessContainerIndexedIterator<Container, IndexList>,
typename Container::value_type,
const typename Container::value_type& >
{
using ThisType = RandomAccessContainerIndexedIterator<Container, IndexList>;
using IndexIterator = typename IndexList::const_iterator;
using ValueType = typename Container::value_type;
public:
RandomAccessContainerIndexedIterator()
: it_(IndexIterator())
, c_(nullptr)
{}
RandomAccessContainerIndexedIterator(const IndexIterator& it,
const Container& c)
: it_(it)
, c_(&c)
{}
const ValueType& dereference() const { return (*c_)[*it_]; }
bool equals(const ThisType& other) const { return it_ == other.it_; }
void increment() { ++it_; }
private:
IndexIterator it_;
const Container* c_;
};
} // end namespace Frackit
#endif // FRACKIT_COMMON_ITERATORFACADES_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 3 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
* \ingroup Common
* \brief Simple range between begin and end iterators
* that can be used to support range-based for loops.
* The implementation is strongly inspired by the one provided in Dune, see
* https://gitlab.dune-project.org/core/dune-common/-/blob/master/dune/common/iteratorrange.hh
*/
#ifndef FRACKIT_COMMON_ITERATORRANGE_HH
#define FRACKIT_COMMON_ITERATORRANGE_HH
namespace Frackit {
/*!
* \ingroup Common
* \brief Simple range between begin and end iterators
* that can be used to support range-based for loops.
* The implementation is strongly inspired by the one provided in Dune, see
* https://gitlab.dune-project.org/core/dune-common/-/blob/master/dune/common/iteratorrange.hh
*
* \tparam Iterator The type of iterator
*/
template<typename Iterator>
class IteratorRange
{
public:
///@{
//! The iterators belonging to this range.
using iterator = Iterator;
using const_iterator = Iterator;
///@}
//! Constructs an iterator range on [begin, end).
IteratorRange(const Iterator& begin, const Iterator& end)
: begin_(begin)
, end_(end)
{}
//! Default constructor
IteratorRange() = default;
//! Returns an iterator pointing to the begin of the range.
Iterator begin() const { return begin_; }
//! Returns an iterator pointing past the end of the range.
Iterator end() const { return end_; }
private:
Iterator begin_;
Iterator end_;
};
} // end namespace Frackit
#endif // FRACKIT_COMMON_ITERATORRANGE_HH
install(FILES
constituents.hh
constraints.hh
constraintsmatrix.hh
containedentitynetwork.hh
containedentitynetworkinterface.hh
entitynetwork.hh
entitynetworkinterface.hh
multigeometryentityset.hh
networkbuilder.hh
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/frackit/entitynetwork)
......@@ -19,85 +19,46 @@
/*!
* \file
* \ingroup EntityNetwork
* \brief Interface defining networks of entities contained
* in (possibly multiple) sub-domains.
* \brief Types that can be used to represent fragments of the different
* constituents of an entity network, that is, the network entities,
* their intersections, junctions of intersections as well as embedding
* domains.
*/
#ifndef FRACKIT_CONTAINED_ENTITY_NETWORK_INTERFACE_HH
#define FRACKIT_CONTAINED_ENTITY_NETWORK_INTERFACE_HH
#ifndef FRACKIT_ENTITY_NETWORK_CONSTITUENTS_HH
#define FRACKIT_ENTITY_NETWORK_CONSTITUENTS_HH
#include <vector>
#include <TopTools_DataMapOfShapeInteger.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopoDS_Shape.hxx>
#include <frackit/common/id.hh>
namespace Frackit {
namespace Frackit::EntityNetworkConstituents {
/*!
* \ingroup EntityNetwork
* \brief Interface defining networks of entities contained
* in (possibly multiple) sub-domains.
* \brief Base class to represent constituents of entity networks.
* Consists of a shape that describes a fragment of some primary
* entity, and a unique index within the set of fragments of the
* same sort.
*/
class ContainedEntityNetworkInterface
class Constituent
{
public:
//! Abstract base classes need virtual destructors
virtual ~ContainedEntityNetworkInterface() {}
/*!
* \brief Constructor.
* \param entityDim Dimension of the network entities
* \param domainDim Dimension of the domain in
* which entities are embedded
*/
ContainedEntityNetworkInterface(int entityDim, int domainDim)
: entityDimension_(entityDim)
, domainDimension_(domainDim)
{}
/*!
* \brief Returns the dimension of the network entities.
*/
int entityDimension() const
{ return entityDimension_; }
using Shape = TopoDS_Shape;
/*!
* \brief Returns the dimension of the (sub-)domains.
*/
int domainDimension() const
{ return domainDimension_; }
Constituent(const Shape& s, std::size_t idx) : shape_(s) , index_(idx) {}
Constituent(Shape&& s, std::size_t idx) : shape_(std::move(s)) , index_(idx) {}
/*!
* \brief Returns the ids of defined the sub-domains
*/
virtual const std::vector<Id>& subDomainIds() const = 0;
/*!
* \brief Returns the fragments of a sub-domain
* \param subDomainId The id of the sub-domain
*/
virtual const TopTools_ListOfShape& subDomainFragments(Id subDomainId) const = 0;
/*!
* \brief Returns the entity fragments of the network defined for a sub-domain
* \param subDomainId The id of the sub-domain
*/
virtual const TopTools_ListOfShape& subDomainEntityFragments(Id subDomainId) const = 0;
/*!
* \brief Returns the map which maps each fragment the network of a sub-domain to its primary entity index.
* \param subDomainId The id of the sub-domain
*/
virtual const TopTools_DataMapOfShapeInteger& subDomainEntityFragmentsIndexMap(Id subDomainId) const = 0;
const Shape& shape() const { return shape_; }
std::size_t index() const { return index_; }
private:
int entityDimension_;
int domainDimension_;
Shape shape_;
std::size_t index_;
};
} // end namespace Frackit
class SubDomainFragment : public Constituent { public: using Constituent::Constituent; };
class EntityFragment : public Constituent { public: using Constituent::Constituent; };
class IntersectionFragment : public Constituent { public: using Constituent::Constituent; };
class IntersectionJunction : public Constituent { public: using Constituent::Constituent; };
} // end namespace Frackit::EntityNetworkConstituents
#endif // FRACKIT_CONTAINED_ENTITY_NETWORK_INTERFACE_HH
#endif // FRACKIT_ENTITY_NETWORK_CONSTITUENTS_HH
......@@ -16,98 +16,27 @@
* 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
* \ingroup EntityNetwork
* \brief Class representing a network of entities, contained
* in (possibly multiple) sub-domains. Sub-networks might
* be defined on each sub-domain.
*/
/*!
* \file
* \ingroup EntityNetwork
* \brief Class representing a network of entities contained in
* one or multiple embedding subdomains.
*/
#ifndef FRACKIT_CONTAINED_ENTITY_NETWORK_HH
#define FRACKIT_CONTAINED_ENTITY_NETWORK_HH
#include <vector>
#include <unordered_map>
#include <TopTools_DataMapOfShapeInteger.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopoDS_Shape.hxx>
#include <frackit/common/id.hh>
#include "containedentitynetworkinterface.hh"
#include "entitynetwork.hh"
namespace Frackit {
/*!
* \ingroup EntityNetwork
* \relates ContainedEntityNetworkBuilder
* \brief Class representing a network of entities, contained
* in (possibly multiple) sub-domains. Sub-networks might
* be defined on each sub-domain.
* \note Use the class ContainedEntityNetworkBuilder for construction.
* \brief Class representing a network of entities contained in
* one or multiple embedding subdomains.
* \deprecated Use EntityNetwork instead
*/
class ContainedEntityNetwork
: public ContainedEntityNetworkInterface
{
public:
/*!
* \brief Constructor.
* \param entityDim Dimension of the network entities
* \param sdFragments The sub-domains, split into fragments by the entities
* \param entityFragments Contains the entity fragments of each sub-domain
* \param entityFragmentMaps Map containing the fragments of the sub-domains,
* where each fragment is mapped to the index of the
* primary entity of the network from which is was created.
*/
ContainedEntityNetwork(int entityDim,
int domainDim,
std::unordered_map<std::size_t, TopTools_ListOfShape>&& sdFragments,
std::unordered_map<std::size_t, TopTools_ListOfShape>&& entityFragments,
std::unordered_map<std::size_t, TopTools_DataMapOfShapeInteger>&& entityFragmentMaps)
: ContainedEntityNetworkInterface(entityDim, domainDim)
, subDomainFragments_(std::move(sdFragments))
, subDomainEntityFragments_(std::move(entityFragments))
, subDomainEntityFragmentIndexMap_(std::move(entityFragmentMaps))
{
subDomainIds_.reserve(subDomainFragments_.size());
for (const auto& sdDataPair : subDomainFragments_)
subDomainIds_.emplace_back(sdDataPair.first);
}
/*!
* \brief Returns the ids of defined the sub-domains
*/
const std::vector<Id>& subDomainIds() const override
{ return subDomainIds_; }
/*!
* \brief Returns the fragments of a sub-domain
* \param subDomainId The id of the sub-domain
*/
const TopTools_ListOfShape& subDomainFragments(Id subDomainId) const override
{ return subDomainFragments_.at(subDomainId.get()); }
/*!
* \brief Returns the entity fragments of the network defined for a sub-domain
* \param subDomainId The id of the sub-domain
*/
const TopTools_ListOfShape& subDomainEntityFragments(Id subDomainId) const override
{ return subDomainEntityFragments_.at(subDomainId.get()); }
/*!
* \brief Returns the map which maps each fragment the network of a sub-domain to its primary entity index.
* \param subDomainId The id of the sub-domain
*/
const TopTools_DataMapOfShapeInteger& subDomainEntityFragmentsIndexMap(Id subDomainId) const override
{ return subDomainEntityFragmentIndexMap_.at(subDomainId.get()); }
private:
std::unordered_map<std::size_t, TopTools_ListOfShape> subDomainFragments_;
std::unordered_map<std::size_t, TopTools_ListOfShape> subDomainEntityFragments_;
std::unordered_map<std::size_t, TopTools_DataMapOfShapeInteger> subDomainEntityFragmentIndexMap_;
std::vector<Id> subDomainIds_;
};
using ContainedEntityNetwork [[deprecated("Use EntityNetwork instead")]]
= EntityNetwork<>;
} // end namespace Frackit
......
This diff is collapsed.
This diff is collapsed.
......@@ -32,18 +32,18 @@
#include <BRep_Builder.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopTools_DataMapOfShapeInteger.hxx>
#include <TopTools_ListOfShape.hxx>
#include <Standard_TypeDef.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS.hxx>
#include <frackit/occ/breputilities.hh>
#include <frackit/entitynetwork/entitynetwork.hh>
#include <frackit/entitynetwork/containedentitynetwork.hh>
// include all used shapes explicitly
#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 <TopoDS_Compound.hxx>
namespace Frackit {
......@@ -60,29 +60,15 @@ public:
/*!
* \brief Construction from an entity network.
*/
template<class EntityNetwork>
BRepWriter(const EntityNetwork& network)
{
if (network.entityDimension() != 2)
throw std::runtime_error("BRepWriter only implemented for 2d networks so far");
if (network.entityDimension() < 1)
throw std::runtime_error("Entity dimension < 1 is not supported");
if (network.isContained())
if (network.domainDimension() <= network.entityDimension())
throw std::runtime_error("Domain dimension must be greater than entity dimension");
makeEntityMap_(network);
findEntityIntersectionShapes_();
makeSubShapeMaps_(network);
makeCompound_();
}
/*!
* \brief Construction from a contained entity network.
*/
BRepWriter(const ContainedEntityNetwork& network)
{
if (network.entityDimension() != 2)
throw std::runtime_error("BRepWriter only implemented for 2d networks so far");
if (network.domainDimension() != network.entityDimension() + 1)
throw std::runtime_error("BRepWriter expects entityDim = domainDim - 1");
makeEntityMap_(network);
findEntityIntersectionShapes_();
makeSubShapeMaps_(network);
makeCompound_();
}
......@@ -97,258 +83,228 @@ public:
}
protected:
using IndexList = std::vector<std::size_t>;
using IndexMapType = std::unordered_map<std::size_t, IndexList>;
/*!
* \brief Returns the map that maps a primary entity index to the list
* of fragment indices that were inserted to the compound for
* that primary entity index. The indices refer to the indices
* within the compound.
*/
const std::unordered_map<std::size_t, std::vector<std::size_t>>& entityToFragmentsMap() const
{ return entityToFragmentsMap_; }
const IndexMapType& entityToFragmentsMap() const
{ return entityMap_; }
/*!
* \brief Returns the map that maps a primary entity intersectionindex to the
* list of intersection fragments that were inserted to the compound for
* that intersection. The indices refer to the indices within the compound.
*/
const std::unordered_map<std::size_t, std::vector<std::size_t>>& entityIntersectionsToFragmentsMap() const
{ return entityIntersectionsToFragmentsMap_; }
const IndexMapType& entityIntersectionsToFragmentsMap() const
{ return intersectionMap_; }
/*!
* \brief Returns the map that maps to each primary sub-domain index the list
* of domain fragment indices that were inserted to the compound for
* that sub-domain. The indices refer to the indices within the compound.
*/
const std::unordered_map<std::size_t, std::vector<std::size_t>>& domainToFragmentsMap() const
{ return domainToFragmentsMap_; }
const IndexMapType& domainToFragmentsMap() const
{ return domainMap_; }
private: