const std::vector<boost::shared_ptr<ribi::foam::Face>> ribi::foam::Mesh::CreateFacesWithPoints( const Files& files, const std::vector<boost::shared_ptr<ribi::Coordinat3D>>& all_points) { const FaceIndex n_faces { files.GetFaces()->GetMaxFaceIndex() }; std::vector<boost::shared_ptr<Face>> faces; for (FaceIndex i = FaceIndex(0); i!=n_faces; ++i) { const std::vector<PointIndex> point_indices { files.GetFaces()->GetItem(i).GetPointIndices() }; std::vector<boost::shared_ptr<ribi::Coordinat3D>> points; for (const PointIndex& point_index: point_indices) { assert(point_index.Get() >= 0); assert(point_index.Get() < static_cast<int>(all_points.size())); points.push_back(all_points[point_index.Get() ]); } const boost::shared_ptr<Face> face( new Face( nullptr, nullptr, points ) ); assert(face); faces.push_back(face); } assert(faces.size() == files.GetFaces()->GetItems().size()); return faces; }
ribi::foam::Mesh::Mesh( const Files& files, const std::vector<boost::shared_ptr<ribi::Coordinat3D>>& points ) : m_boundaries{}, m_cells{CreateEmptyCells(files)}, m_faces{CreateFacesWithPoints(files,points)}, m_points(points) { #ifndef NDEBUG Test(); #endif //Add Cell owner to Faces { assert(!m_cells.empty()); const FaceIndex n_faces = files.GetFaces()->GetMaxFaceIndex(); for (FaceIndex i = FaceIndex(0); i!=n_faces; ++i) { const CellIndex owner_cell_index { files.GetOwner()->GetItem(i).GetCellIndex() }; #ifndef NDEBUG if (owner_cell_index.Get() >= static_cast<int>(m_cells.size())) { TRACE("ERROR"); TRACE(owner_cell_index); TRACE(m_cells.size()); } #endif assert(owner_cell_index.Get() >= 0); assert(owner_cell_index.Get() < static_cast<int>(m_cells.size())); assert(m_cells[ owner_cell_index.Get() ]); const boost::shared_ptr<Cell> owner { m_cells[ owner_cell_index.Get() ] }; assert(owner); assert(!m_faces[i.Get()]->GetOwner() ); m_faces[i.Get()]->AssignOwner(owner); assert( m_faces[i.Get()]->GetOwner() ); } } #ifndef NDEBUG for (const boost::shared_ptr<Face> face: m_faces) { assert(face); assert(face->GetOwner()); } #endif //Add owned Faces to Cells { std::map<boost::shared_ptr<Cell>,std::vector<boost::shared_ptr<Face>>> m; for (const boost::shared_ptr<Face> face: m_faces) { assert(face); const boost::shared_ptr<Cell> owner { face->GetOwner() }; assert(owner); //if (!owner) continue; if (m.find(owner) == m.end()) { m.insert(std::make_pair(owner, std::vector<boost::shared_ptr<Face>>() ) ); } assert(m.find(owner) != m.end()); (*m.find(owner)).second.push_back(face); } for (auto p: m) { p.first->AssignOwnedFaces(p.second); } } //Add neighbours to Faces { const int n_faces = static_cast<int>(m_faces.size()); for (int i=0; i!=n_faces; ++i) { const FaceIndex index(i); assert(files.GetNeighbour()); //Not all Faces have a neighbour if (!files.GetNeighbour()->CanGetItem(index)) continue; assert(files.GetNeighbour()->CanGetItem(index)); const CellIndex neighbour_index { files.GetNeighbour()->GetItem(index).GetCellIndex() }; assert(i >= 0); assert(i < static_cast<int>(m_faces.size())); assert(neighbour_index.Get() < static_cast<int>(m_cells.size())); assert(!m_faces[i]->GetNeighbour()); m_faces[i]->AssignNeighbour( m_cells[ neighbour_index.Get() ] ); assert(m_faces[i]->GetNeighbour()); } } //Assign boundaries m_boundaries = CreateBoundaries(files,m_faces); //Check #ifndef NDEBUG for (boost::shared_ptr<Cell> cell: m_cells) { assert(cell); //assert( (cell->GetNeighbour() || !cell->GetNeighbour()) // && "Not all cells have a neighbour, for example in a 1x1x1 mesh"); } if (GetNumberOfBoundaries() != files.GetBoundary()->GetMaxBoundaryIndex().Get()) { TRACE("ERROR"); TRACE(GetNumberOfBoundaries()); TRACE(files.GetBoundary()->GetMaxBoundaryIndex()); } #endif assert(GetNumberOfBoundaries() == files.GetBoundary()->GetMaxBoundaryIndex().Get()); assert(GetNumberOfFaces() == files.GetFaces()->GetMaxFaceIndex().Get()); }
const KHalfEdgeMesh::Face *KHalfEdgeMesh::unsafeFace(size_t idx) const { return face(FaceIndex(static_cast<IndexType::index_type>(idx))); }
const boost::shared_ptr<ribi::foam::BoundaryFile> ribi::foam::Mesh::CreateBoundary() const noexcept { std::vector<BoundaryFileItem> items; for (const boost::shared_ptr<Boundary> boundary: m_boundaries) { assert(!boundary->GetFaces().empty()); const int n_faces { static_cast<int>(boundary->GetFaces().size()) }; assert(n_faces > 0); //Determine the start face: at which indices are the Faces in m_faces? std::vector<int> indices; std::transform(boundary->GetFaces().begin(),boundary->GetFaces().end(),std::back_inserter(indices), [this](const boost::shared_ptr<Face> face) { const std::vector<boost::shared_ptr<Face>>::const_iterator iter { std::find(m_faces.begin(),m_faces.end(),face) }; assert(iter != m_faces.end()); const int index = std::distance(m_faces.begin(),iter); assert(index >= 0); assert(index < static_cast<int>(m_faces.size())); return index; } ); assert(!indices.empty()); assert(indices.size() == boundary->GetFaces().size()); std::sort(indices.begin(),indices.end()); #ifndef NDEBUG const std::size_t n_indices = indices.size(); if (n_indices > 1) { for (std::size_t i=1; i!=n_indices; ++i) { assert(indices[i-1] != indices[i] && "All face indices must be unique"); if (indices[i-1] + 1 != indices[i]) { TRACE("ERROR"); } assert(indices[i-1] + 1 == indices[i] && "All face indices must be adjacent"); } } #endif const FaceIndex n_start_face = FaceIndex(indices[0]); //TRACE(n_start_face); const BoundaryFileItem item( boundary->GetName(), boundary->GetType(), n_faces, n_start_face ); items.push_back(item); } boost::shared_ptr<BoundaryFile> f { new BoundaryFile( BoundaryFile::GetDefaultHeader(), items ) }; assert(f); return f; }
ribi::foam::FaceIndex ribi::foam::FacesFile::GetMaxFaceIndex() const noexcept { return FaceIndex(static_cast<int>(m_items.size())); }