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 @@
#include <TopoDS_Shape.hxx>
#include <frackit/common/id.hh>
#include <frackit/common/idpair.hh>
#include <frackit/geometry/dimension.hh>
#include <frackit/precision/defaultepsilon.hh>
......@@ -62,6 +63,7 @@ class ContainedEntityNetworkBuilder;
template<class ctype = double>
class EntityNetworkBuilderBase
{
using ShapeIdMapIterator = TopTools_DataMapIteratorOfDataMapOfShapeInteger;
public:
/*!
......@@ -105,10 +107,12 @@ public:
if (!subDomains_.empty())
for (const auto& sdPair : subDomains_)
eps_ = min(eps_, defaultEpsilon(sdPair.second));
else if (!networks_.empty())
for (const auto& netPair : networks_)
for (const auto& entity : netPair.second)
eps_ = min(eps_, defaultEpsilon(entity));
else
{
for (const auto& idNetworkPair : networks_)
for (ShapeIdMapIterator it(idNetworkPair.second); it.More(); it.Next())
eps_ = min(eps_, defaultEpsilon(it.Key()));
}
}
epsilonIsSet_ = true;
......@@ -165,12 +169,13 @@ public:
/*!
* \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 subDomainId The identifier (index) to be used for this sub-domain
* \return The id given to the inserted entity.
*/
template<class Entity>
void addSubDomainEntity(const Entity& entity, Id subDomainId)
Id addSubDomainEntity(const Entity& entity, Id subDomainId)
{
const auto entityDim = getDimension(entity);
if (!networks_.empty() && getDimension(entity) != entityDimension_)
......@@ -179,20 +184,34 @@ public:
throw std::runtime_error("Entity dimension must be smaller than domain dimension");
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
* embedded in sub-domain with index subDomainIndex.
* embedded in sub-domain with the id subDomainId.
* \param entities The set of entities
* \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>
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)
addSubDomainEntity(entity, subDomainId);
idPair = IdPair(Id{firstIdx}, addSubDomainEntity(entity, subDomainId));
return idPair;
}
/*!
......@@ -208,6 +227,13 @@ public:
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
* (sub-)domains they are embedded in.
......@@ -217,8 +243,6 @@ protected:
for (const auto& indexNetworkPair : networks_)
{
const auto subDomainIndex = indexNetworkPair.first;
const auto& network = indexNetworkPair.second;
auto& fragmentList = networkFragmentLists_[subDomainIndex];
auto& fragmentMap = networkFragmentMaps_[subDomainIndex];
......@@ -236,7 +260,7 @@ protected:
continue;
BRepAlgoAPI_Common intersection;
intersection.SetArguments(network);
intersection.SetArguments(fragmentList);
intersection.SetTools(domainShapeList);
intersection.SetRunParallel(false);
intersection.SetFuzzyValue(getEpsilon_());
......@@ -247,7 +271,7 @@ protected:
// keep track of original entity indices
TopTools_ListOfShape newList;
TopTools_DataMapOfShapeInteger newIndexMap;
for (const auto& entityShape : network)
for (const auto& entityShape : fragmentList)
{
int entityIdx;
if (!fragmentMap.Find(entityShape, entityIdx))
......@@ -433,21 +457,15 @@ protected:
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_)
{
const auto subDomainIndex = indexNetworkPair.first;
const auto& network = indexNetworkPair.second;
const auto& entityIdxPairs = indexNetworkPair.second;
// initialize index map with network entities
std::size_t idx = 1;
auto& fragmentList = networkFragmentLists_[subDomainIndex];
auto& fragmentMap = networkFragmentMaps_[subDomainIndex];
for (const auto& entityShape : network)
{
fragmentList.Append(entityShape);
fragmentMap.Bind(entityShape, idx++);
}
networkFragmentMaps_[subDomainIndex] = entityIdxPairs;
for (ShapeIdMapIterator it(entityIdxPairs); it.More(); it.Next())
networkFragmentLists_[subDomainIndex].Append(it.Key());
}
}
......@@ -475,7 +493,10 @@ protected:
// User-defined sub-domains and entity networks
std::unordered_map<std::size_t, TopoDS_Shape> subDomains_;
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
int domainDimension_;
......@@ -511,6 +532,7 @@ template<class ctype>
class EntityNetworkBuilder
: public EntityNetworkBuilderBase<ctype>
{
using ShapeIdMapIterator = TopTools_DataMapIteratorOfDataMapOfShapeInteger;
public:
//! Export network type to be built
......@@ -521,9 +543,10 @@ public:
* This function can be used when no sub-domain
* specifications are made. Internally, the entity
* is added to the sub-domain with index 0.
* \return The id of the newly added entity
*/
template<class Entity>
void addEntity(const Entity& entity)
Id addEntity(const Entity& entity)
{
const auto entityDim = getDimension(entity);
if (!this->networks_.empty() && getDimension(entity) != this->entityDimension_)
......@@ -532,17 +555,31 @@ public:
throw std::runtime_error("Entity dimension must be smaller than domain dimension");
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.
* \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>
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)
addEntity(entity);
idPair = IdPair(Id{firstIdx}, addEntity(entity));
return idPair;
}
/*!
......@@ -566,14 +603,12 @@ public:
fragmentList.Append(sdFragmentDataPair.second);
// merge all index maps into one
std::size_t entityIndexOffset = 0;
TopTools_DataMapOfShapeInteger fragmentIndexMap;
for (auto& dataPair : this->networkFragmentMaps_)
{
const auto& indexMap = dataPair.second;
for (TopTools_DataMapIteratorOfDataMapOfShapeInteger it(indexMap); it.More(); it.Next())
fragmentIndexMap.Bind(it.Key(), it.Value() + entityIndexOffset);
entityIndexOffset += indexMap.Extent();
const auto& shapeIndexMap = dataPair.second;
for (ShapeIdMapIterator it(shapeIndexMap); it.More(); it.Next())
fragmentIndexMap.Bind(it.Key(), it.Value());
}
// 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