ribi::foam::Files ribi::foam::Mesh::CreateFiles() const noexcept { boost::shared_ptr<BoundaryFile> boundary { CreateBoundary() }; assert(boundary); boost::shared_ptr<FacesFile> faces { CreateFaces() }; assert(faces); boost::shared_ptr<NeighbourFile> neighbour { CreateNeighbour() }; assert(neighbour); boost::shared_ptr<OwnerFile> owner { CreateOwner() }; assert(owner); boost::shared_ptr<PointsFile> points { CreatePoints() }; assert(points); const Files f( boundary, faces, neighbour, owner, points ); return f; }
static ON_Brep* MakeTrimmedPlane( ON_TextLog& error_log ) { // This example demonstrates how to construct a ON_Brep // with the topology shown below. // // // E-------C--------D // | /\ | // | / \ | // | / \ | // | e2 e1 | // | / \ | // | / \ | // | / \ | // A-----e0-------->B // // // Things need to be defined in a valid brep: // 1- Vertices // 2- 3D Curves (geometry) // 3- Edges (topology - reference curve geometry) // 4- Surface (geometry) // 5- Faces (topology - reference surface geometry) // 6- Loops (2D parameter space of faces) // 4- Trims and 2D curves (2D parameter space of edges) // ON_3dPoint point[5] = { ON_3dPoint( 0.0, 0.0, 0.0 ), // point A = geometry for vertex 0 (and surface SW corner) ON_3dPoint( 10.0, 0.0, 0.0 ), // point B = geometry for vertex 1 (and surface SE corner) ON_3dPoint( 5.0, 10.0, 0.0 ), // point C = geometry for vertex 2 ON_3dPoint( 10.0, 10.0, 0.0 ), // point D (surface NE corner) ON_3dPoint( 0.0, 10.0, 0.0 ), // point E (surface NW corner) }; ON_Brep* brep = new ON_Brep(); // create three vertices located at the three points int vi; for ( vi = 0; vi < 3; vi++ ) { ON_BrepVertex& v = brep->NewVertex(point[vi]); v.m_tolerance = 0.0; // this simple example is exact - for models with // non-exact data, set tolerance as explained in // definition of ON_BrepVertex. } // Create 3d curve geometry - the orientations are arbitrarily chosen // so that the end vertices are in alphabetical order. brep->m_C3.Append( CreateLinearCurve( point[A], point[B] ) ); // line AB brep->m_C3.Append( CreateLinearCurve( point[B], point[C] ) ); // line BC brep->m_C3.Append( CreateLinearCurve( point[A], point[C] ) ); // line CD // Create edge topology for each curve in the brep. CreateEdges( *brep ); // Create 3d surface geometry - the orientations are arbitrarily chosen so // that some normals point into the cube and others point out of the cube. brep->m_S.Append( CreatePlanarSurface( point[A], point[B], point[D], point[E] ) ); // ABDE // Create face topology and 2d parameter space loops and trims. CreateFaces( *brep ); //Make sure b-rep is valid if ( !brep->IsValid() ) { error_log.Print("Trimmed b-rep face is not valid.\n"); delete brep; brep = NULL; } return brep; }
//-------------------------------- Graphic Structures ------------------- // // CreateBox builds a triangle vertex list for a brick-like box from // two extreme points one face at a time with all faces having the same // attributes // iGraphic* CreateBox(float minx, float miny, float minz, float maxx, float maxy, float maxz) { return CreateFaces(minx, miny, minz, maxx, maxy, maxz, 1,1,1,1,1,1); }
ribi::trim::TriangleMeshBuilder::TriangleMeshBuilder( const std::vector<boost::shared_ptr<Cell>>& cells, const std::string& mesh_filename, const std::function<ribi::foam::PatchFieldType(const std::string&)> boundary_to_patch_field_type_function ) : m_cells(cells), m_faces(SortByBoundary(ExtractFaces(cells))), m_points(ExtractPoints(cells)) { #ifndef NDEBUG Test(); #endif TRACE_FUNC(); PROFILE_FUNC(); for (const std::string& folder: GetAllFolders()) { if (!ribi::fileio::IsFolder(folder)) { ribi::fileio::CreateFolder(folder); } assert(ribi::fileio::IsFolder(folder)); } //Remove cells with less than 8 faces or less than 8 faces with an owner m_cells.erase( std::remove_if(m_cells.begin(),m_cells.end(), [](const boost::shared_ptr<Cell> cell) { const std::vector<boost::shared_ptr<Face>> faces { cell->GetFaces() }; assert(faces.size() == 8); return std::count_if(faces.begin(),faces.end(), [](const boost::shared_ptr<Face> face) { assert(face); assert(face->GetOwner()); //Test: is this loop needed? return face->GetOwner(); } ) < 8; } ), m_cells.end() ); m_faces.erase( std::remove_if(m_faces.begin(),m_faces.end(), [](const boost::shared_ptr<const Face> face) { return !face->GetOwner(); } ), m_faces.end() ); //Remove cells with less than 8 faces or less than 8 faces with an owner m_cells.erase( std::remove_if(m_cells.begin(),m_cells.end(), [](const boost::shared_ptr<Cell> cell) { const std::vector<boost::shared_ptr<Face>> faces { cell->GetFaces() }; assert(faces.size() == 8); return std::count_if(faces.begin(),faces.end(), [](const boost::shared_ptr<Face> face) { assert(face); assert(face->GetOwner()); //Test: is this loop needed? return face->GetOwner(); } ) < 8; } ), m_cells.end() ); //Set all indices { const int n_cells = static_cast<int>(m_cells.size()); for (int i=0; i!=n_cells; ++i) { m_cells[i]->SetIndex(i); } const int n_faces = static_cast<int>(m_faces.size()); for (int i=0; i!=n_faces; ++i) { m_faces[i]->SetIndex(i); } const int n_points = static_cast<int>(m_points.size()); for (int i=0; i!=n_points; ++i) { m_points[i]->SetIndex(i); } } //Check #ifndef NDEBUG { const int cell_usecount = m_cells.empty() ? 0 : m_cells[0].use_count(); for (const auto& cell: m_cells) { assert(cell); //TRACE(cell_usecount); //TRACE(cell.use_count()); assert(cell.use_count() == cell_usecount && "Every Cell must have an equal use_count"); //All Cells must have existing indices assert(cell->GetIndex() >= 0); assert(cell->GetIndex() < static_cast<int>(m_cells.size())); //const int face_usecount = cell->GetFaces().empty() ? 0 : cell->GetFaces()[0].use_count(); for (const auto& face: cell->GetFaces()) { assert(face); //TRACE(face_usecount); //TRACE(face.use_count()); //assert(std::abs(face_usecount - face.use_count()) <= 1 && "Face are used once or twice"); //All Cells must exist of Faces with an existing index assert(face->GetIndex() >= 0); assert(face->GetIndex() < static_cast<int>(m_faces.size())); //All Faces must have a Cell that owns them with an existing index assert(face->GetOwner()->GetIndex() >= 0); assert(face->GetOwner()->GetIndex() < static_cast<int>(m_cells.size())); //All Faces must have either no Neighbout or a Neighbour with an existing index assert(!face->GetNeighbour() || face->GetNeighbour()->GetIndex() >= 0); assert(!face->GetNeighbour() || face->GetNeighbour()->GetIndex() < static_cast<int>(m_cells.size())); for (const auto point: face->GetPoints()) { assert(point); //All Faces must exists of Points with an existing index assert(point->GetIndex() >= 0); assert(point->GetIndex() < static_cast<int>(m_points.size())); } } } } #endif const bool verbose = false; if (verbose) std::cout << "Writing output...\n"; //Mesh { if (verbose) std::cout << "\tGenerating mesh (.ply)\n"; std::ofstream f(mesh_filename.c_str()); f << CreateHeader(); f << CreateNodes(); f << CreateFaces(); } { std::ofstream f(ribi::foam::Filenames().GetPoints().Get().c_str()); f << CreateOpenFoamHeader("vectorField","points","constant/polyMesh"); f << CreateOpenFoamNodes(); } { std::ofstream fp(ribi::foam::Filenames().GetFaces().Get().c_str()); fp << CreateOpenFoamHeader("faceList","faces","constant/polyMesh"); fp << CreateOpenFoamFaces(); } { const int n_cells = static_cast<int>(m_cells.size()); if (verbose) std::cout << "\tGenerating cells (" << n_cells << ")\n"; std::ofstream fo(ribi::foam::Filenames().GetOwner().Get().c_str()); std::ofstream fn(ribi::foam::Filenames().GetNeighbour().Get().c_str()); std::stringstream fs; fs << "nPoints: " << m_points.size() << " nCells: " << m_cells.size() << " nFaces: " << m_faces.size() ; fo << CreateOpenFoamHeader( "labelList", "owner", "constant/polyMesh", fs.str() ); fn << CreateOpenFoamHeader( "labelList", "neighbour", "constant/polyMesh", fs.str() ); const std::pair<std::string,std::string> p { CreateCells() }; const std::string& out_owner { p.first }; const std::string& out_neighbour { p.second}; fo << out_owner; fn << out_neighbour; } { std::ofstream f(ribi::foam::Filenames().GetBoundary().Get().c_str()); f << CreateBoundary(boundary_to_patch_field_type_function); } { std::ofstream f(ribi::foam::Filenames().GetCase().Get().c_str()); //Need nothing to stream } { //std::ofstream f(ribi::foam::Filenames().GetFvSchemes().Get().c_str()); //f << CreateOpenFoamFvSchemes(); } { //std::ofstream f(ribi::foam::Filenames().GetFvSolution().Get().c_str()); //f << CreateOpenFoamFvSolution(); } { std::ofstream f(ribi::foam::Filenames().GetVelocityField().Get().c_str()); f << CreateOpenFoamU(); } { //std::ofstream f(ribi::foam::Filenames().GetControlDict().Get().c_str()); //f << CreateOpenFoamControlDict(); } PROFILER_UPDATE(); }