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

[networkbuilder] return entity ids after insertion

parent bccabdad
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <TopoDS_Shape.hxx> #include <TopoDS_Shape.hxx>
#include <frackit/common/id.hh> #include <frackit/common/id.hh>
#include <frackit/common/idpair.hh>
#include <frackit/geometry/dimension.hh> #include <frackit/geometry/dimension.hh>
#include <frackit/precision/defaultepsilon.hh> #include <frackit/precision/defaultepsilon.hh>
...@@ -62,6 +63,7 @@ class ContainedEntityNetworkBuilder; ...@@ -62,6 +63,7 @@ class ContainedEntityNetworkBuilder;
template<class ctype = double> template<class ctype = double>
class EntityNetworkBuilderBase class EntityNetworkBuilderBase
{ {
using ShapeIdMapIterator = TopTools_DataMapIteratorOfDataMapOfShapeInteger;
public: public:
/*! /*!
...@@ -105,10 +107,12 @@ public: ...@@ -105,10 +107,12 @@ public:
if (!subDomains_.empty()) if (!subDomains_.empty())
for (const auto& sdPair : subDomains_) for (const auto& sdPair : subDomains_)
eps_ = min(eps_, defaultEpsilon(sdPair.second)); eps_ = min(eps_, defaultEpsilon(sdPair.second));
else if (!networks_.empty()) else
for (const auto& netPair : networks_) {
for (const auto& entity : netPair.second) for (const auto& idNetworkPair : networks_)
eps_ = min(eps_, defaultEpsilon(entity)); for (ShapeIdMapIterator it(idNetworkPair.second); it.More(); it.Next())
eps_ = min(eps_, defaultEpsilon(it.Key()));
}
} }
epsilonIsSet_ = true; epsilonIsSet_ = true;
...@@ -165,12 +169,13 @@ public: ...@@ -165,12 +169,13 @@ public:
/*! /*!
* \brief Adds an entity to the network embedded in * \brief Adds an entity to the network embedded in
* the sub-domain with index subDomainIndex. * the sub-domain with id subDomainId.
* \param entity The entity geometry * \param entity The entity geometry
* \param subDomainId The identifier (index) to be used for this sub-domain * \param subDomainId The identifier (index) to be used for this sub-domain
* \return The id given to the inserted entity.
*/ */
template<class Entity> template<class Entity>
void addSubDomainEntity(const Entity& entity, Id subDomainId) Id addSubDomainEntity(const Entity& entity, Id subDomainId)
{ {
const auto entityDim = getDimension(entity); const auto entityDim = getDimension(entity);
if (!networks_.empty() && getDimension(entity) != entityDimension_) if (!networks_.empty() && getDimension(entity) != entityDimension_)
...@@ -179,20 +184,34 @@ public: ...@@ -179,20 +184,34 @@ public:
throw std::runtime_error("Entity dimension must be smaller than domain dimension"); throw std::runtime_error("Entity dimension must be smaller than domain dimension");
entityDimension_ = entityDim; entityDimension_ = entityDim;
networks_[subDomainId.get()].Append(OCCUtilities::getShape(entity)); return Id{bindEntity_(subDomainId.get(), OCCUtilities::getShape(entity))};
} }
/*! /*!
* \brief Adds a set of entities to the network * \brief Adds a set of entities to the network
* embedded in sub-domain with index subDomainIndex. * embedded in sub-domain with the id subDomainId.
* \param entities The set of entities * \param entities The set of entities
* \param subDomainId The identifier (index) to be used for this sub-domain * \param subDomainId The identifier (index) to be used for this sub-domain
* \return The range of ids given to the inserted entities
* in form of an id pair, containing the first
* and last used entity ids.
* \note If the provided range is empty, the id of the previously inserted
* entity is returned. If no entity had been inserted before, the id
* is 0, and thus, no valid id (we start counting at 1). In general,
* passing empty ranges should be avoided.
*/ */
template<class EntityNetwork> template<class EntityNetwork>
void addSubDomainEntities(const EntityNetwork& entities, Id subDomainId) IdPair addSubDomainEntities(const EntityNetwork& entities, Id subDomainId)
{ {
const auto firstIdx = curEntityIdx_;
if (std::empty(entities))
return IdPair{firstIdx-1, firstIdx-1};
IdPair idPair{firstIdx, firstIdx};
for (const auto& entity : entities) for (const auto& entity : entities)
addSubDomainEntity(entity, subDomainId); idPair = IdPair(Id{firstIdx}, addSubDomainEntity(entity, subDomainId));
return idPair;
} }
/*! /*!
...@@ -208,6 +227,13 @@ public: ...@@ -208,6 +227,13 @@ public:
protected: protected:
// bind entity to the given network & return the new entity index
std::size_t bindEntity_(std::size_t sdId, const TopoDS_Shape& s)
{
networks_[sdId].Bind(s, curEntityIdx_);
return curEntityIdx_++;
}
/*! /*!
* \brief Confines the networks to the * \brief Confines the networks to the
* (sub-)domains they are embedded in. * (sub-)domains they are embedded in.
...@@ -217,8 +243,6 @@ protected: ...@@ -217,8 +243,6 @@ protected:
for (const auto& indexNetworkPair : networks_) for (const auto& indexNetworkPair : networks_)
{ {
const auto subDomainIndex = indexNetworkPair.first; const auto subDomainIndex = indexNetworkPair.first;
const auto& network = indexNetworkPair.second;
auto& fragmentList = networkFragmentLists_[subDomainIndex]; auto& fragmentList = networkFragmentLists_[subDomainIndex];
auto& fragmentMap = networkFragmentMaps_[subDomainIndex]; auto& fragmentMap = networkFragmentMaps_[subDomainIndex];
...@@ -236,7 +260,7 @@ protected: ...@@ -236,7 +260,7 @@ protected:
continue; continue;
BRepAlgoAPI_Common intersection; BRepAlgoAPI_Common intersection;
intersection.SetArguments(network); intersection.SetArguments(fragmentList);
intersection.SetTools(domainShapeList); intersection.SetTools(domainShapeList);
intersection.SetRunParallel(false); intersection.SetRunParallel(false);
intersection.SetFuzzyValue(getEpsilon_()); intersection.SetFuzzyValue(getEpsilon_());
...@@ -247,7 +271,7 @@ protected: ...@@ -247,7 +271,7 @@ protected:
// keep track of original entity indices // keep track of original entity indices
TopTools_ListOfShape newList; TopTools_ListOfShape newList;
TopTools_DataMapOfShapeInteger newIndexMap; TopTools_DataMapOfShapeInteger newIndexMap;
for (const auto& entityShape : network) for (const auto& entityShape : fragmentList)
{ {
int entityIdx; int entityIdx;
if (!fragmentMap.Find(entityShape, entityIdx)) if (!fragmentMap.Find(entityShape, entityIdx))
...@@ -433,21 +457,15 @@ protected: ...@@ -433,21 +457,15 @@ protected:
networkFragmentMaps_[sdDataPair.first] = TopTools_DataMapOfShapeInteger(); networkFragmentMaps_[sdDataPair.first] = TopTools_DataMapOfShapeInteger();
} }
// then, add the fragments to the lists // then, add the fragments to the lists & initialize fragment maps
for (const auto& indexNetworkPair : networks_) for (const auto& indexNetworkPair : networks_)
{ {
const auto subDomainIndex = indexNetworkPair.first; const auto subDomainIndex = indexNetworkPair.first;
const auto& network = indexNetworkPair.second; const auto& entityIdxPairs = indexNetworkPair.second;
// initialize index map with network entities networkFragmentMaps_[subDomainIndex] = entityIdxPairs;
std::size_t idx = 1; for (ShapeIdMapIterator it(entityIdxPairs); it.More(); it.Next())
auto& fragmentList = networkFragmentLists_[subDomainIndex]; networkFragmentLists_[subDomainIndex].Append(it.Key());
auto& fragmentMap = networkFragmentMaps_[subDomainIndex];
for (const auto& entityShape : network)
{
fragmentList.Append(entityShape);
fragmentMap.Bind(entityShape, idx++);
}
} }
} }
...@@ -475,7 +493,10 @@ protected: ...@@ -475,7 +493,10 @@ protected:
// User-defined sub-domains and entity networks // User-defined sub-domains and entity networks
std::unordered_map<std::size_t, TopoDS_Shape> subDomains_; std::unordered_map<std::size_t, TopoDS_Shape> subDomains_;
std::unordered_map<std::size_t, bool> subDomainBoundsNetwork_; std::unordered_map<std::size_t, bool> subDomainBoundsNetwork_;
std::unordered_map<std::size_t, TopTools_ListOfShape> networks_; std::unordered_map<std::size_t, TopTools_DataMapOfShapeInteger> networks_;
// keep track of registered entity ids
std::size_t curEntityIdx_ = 1;
// dimensionalities // dimensionalities
int domainDimension_; int domainDimension_;
...@@ -511,6 +532,7 @@ template<class ctype> ...@@ -511,6 +532,7 @@ template<class ctype>
class EntityNetworkBuilder class EntityNetworkBuilder
: public EntityNetworkBuilderBase<ctype> : public EntityNetworkBuilderBase<ctype>
{ {
using ShapeIdMapIterator = TopTools_DataMapIteratorOfDataMapOfShapeInteger;
public: public:
//! Export network type to be built //! Export network type to be built
...@@ -521,9 +543,10 @@ public: ...@@ -521,9 +543,10 @@ public:
* This function can be used when no sub-domain * This function can be used when no sub-domain
* specifications are made. Internally, the entity * specifications are made. Internally, the entity
* is added to the sub-domain with index 0. * is added to the sub-domain with index 0.
* \return The id of the newly added entity
*/ */
template<class Entity> template<class Entity>
void addEntity(const Entity& entity) Id addEntity(const Entity& entity)
{ {
const auto entityDim = getDimension(entity); const auto entityDim = getDimension(entity);
if (!this->networks_.empty() && getDimension(entity) != this->entityDimension_) if (!this->networks_.empty() && getDimension(entity) != this->entityDimension_)
...@@ -532,17 +555,31 @@ public: ...@@ -532,17 +555,31 @@ public:
throw std::runtime_error("Entity dimension must be smaller than domain dimension"); throw std::runtime_error("Entity dimension must be smaller than domain dimension");
this->entityDimension_ = entityDim; this->entityDimension_ = entityDim;
this->networks_[0].Append(OCCUtilities::getShape(entity)); return Id{this->bindEntity_(0, OCCUtilities::getShape(entity))};
} }
/*! /*!
* \brief Adds a set of entities to the network. * \brief Adds a set of entities to the network.
* \return The range of ids given to the inserted entities
* in form of an id pair, containing the first
* and last used entity ids.
* \note If the provided range is empty, the id of the previously inserted
* entity is returned. If no entity had been inserted before, the id
* is 0, and thus, no valid id (we start counting at 1). In general,
* passing empty ranges should be avoided.
*/ */
template<class EntityNetwork> template<class EntityNetwork>
void addEntities(const EntityNetwork& entities) IdPair addEntities(const EntityNetwork& entities)
{ {
const auto firstIdx = this->curEntityIdx_;
if (std::empty(entities))
return IdPair{firstIdx-1, firstIdx-1};
IdPair idPair{firstIdx, firstIdx};
for (const auto& entity : entities) for (const auto& entity : entities)
addEntity(entity); idPair = IdPair(Id{firstIdx}, addEntity(entity));
return idPair;
} }
/*! /*!
...@@ -566,14 +603,12 @@ public: ...@@ -566,14 +603,12 @@ public:
fragmentList.Append(sdFragmentDataPair.second); fragmentList.Append(sdFragmentDataPair.second);
// merge all index maps into one // merge all index maps into one
std::size_t entityIndexOffset = 0;
TopTools_DataMapOfShapeInteger fragmentIndexMap; TopTools_DataMapOfShapeInteger fragmentIndexMap;
for (auto& dataPair : this->networkFragmentMaps_) for (auto& dataPair : this->networkFragmentMaps_)
{ {
const auto& indexMap = dataPair.second; const auto& shapeIndexMap = dataPair.second;
for (TopTools_DataMapIteratorOfDataMapOfShapeInteger it(indexMap); it.More(); it.Next()) for (ShapeIdMapIterator it(shapeIndexMap); it.More(); it.Next())
fragmentIndexMap.Bind(it.Key(), it.Value() + entityIndexOffset); fragmentIndexMap.Bind(it.Key(), it.Value());
entityIndexOffset += indexMap.Extent();
} }
// create the network // create the network
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment