예제 #1
0
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;
}
예제 #3
0
//-------------------------------- 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();
}