void ribi::trim::CellFactory::Test() noexcept { { static bool is_tested = false; if (is_tested) return; is_tested = true; } TRACE("Starting ribi::trim::CellFactory::Test"); //Create prism { const boost::shared_ptr<Cell> prism { CellFactory().CreateTestPrism() }; assert(prism->GetFaces().size() == 8 && "A prism has 8 faces (as the vertical faces are split into 2 triangle)"); } //Create cube { const std::vector<boost::shared_ptr<Cell>> cube { CellFactory().CreateTestCube() }; assert(cube.size() == 2 && "A cube consists of two prisms"); assert(cube[0]->GetFaces().size() == 8 && "A prism has 8 faces (as the vertical faces are split into 2 triangle)"); assert(cube[1]->GetFaces().size() == 8 && "A prism has 8 faces (as the vertical faces are split into 2 triangle)"); } TRACE("Finished ribi::trim::CellFactory::Test successfully"); }
const boost::shared_ptr<ribi::trim::Cell> ribi::trim::CellFactory::CreateTestPrism() const noexcept { const std::vector<boost::shared_ptr<Face> > faces { FaceFactory().CreateTestPrism() }; const boost::shared_ptr<Cell> prism { CellFactory().Create(faces) }; assert(prism); return prism; }
void ribi::trim::CellsCreator::Test() noexcept { { static bool is_tested{false}; if (is_tested) return; is_tested = true; } CellFactory(); FaceFactory(); const TestTimer test_timer(__func__,__FILE__,1.0); const bool verbose{false}; /* if (testing_depth > 1) { if (verbose) { TRACE("Trying out to build cells from the hardest testing templates"); } { //This is the longest test by far //const TestTimer test_timer(boost::lexical_cast<std::string>(__LINE__),__FILE__,1.0); for (CreateVerticalFacesStrategy strategy: CreateVerticalFacesStrategies().GetAll()) { const boost::shared_ptr<Template> my_template { Template::CreateTest(3) }; const int n_cell_layers = 2; const boost::shared_ptr<CellsCreator> cells_creator { CellsCreatorFactory().Create( my_template, n_cell_layers, 1.0 * boost::units::si::meter, strategy, verbose ) }; const std::vector<boost::shared_ptr<Cell>> cells { cells_creator->GetCells() }; assert(cells.size() > 0); } } } */ if (verbose) { TRACE("Specific: check if a Face really loses its neighbour: remove a prism from a cube"); } { //const TestTimer test_timer(boost::lexical_cast<std::string>(__LINE__),__FILE__,1.0); for (CreateVerticalFacesStrategy strategy: CreateVerticalFacesStrategies().GetAll()) { //Create a 2x1 cell block const boost::shared_ptr<Template> my_template { Template::CreateTest(1) }; assert(my_template->CountFaces() == 2); const int n_cell_layers = 1; const boost::shared_ptr<CellsCreator> cells_creator { CellsCreatorFactory().Create( my_template, n_cell_layers, 1.0 * boost::units::si::meter, strategy, verbose ) }; const std::vector<boost::shared_ptr<Cell>> cells { cells_creator->GetCells() }; assert(cells.size() == 2); const std::vector<boost::shared_ptr<Face>> faces_1 { cells[0]->GetFaces() }; const std::vector<boost::shared_ptr<Face>> faces_2 { cells[1]->GetFaces() }; //Find the one/two Faces that have a neighbour { const int n_faces_with_neighbour { static_cast<int>( std::count_if(faces_1.begin(),faces_1.end(), [](const boost::shared_ptr<Face> face) { return face->GetNeighbour().get(); } ) ) }; assert( (strategy == CreateVerticalFacesStrategy::one_face_per_square && n_faces_with_neighbour == 1) || (strategy == CreateVerticalFacesStrategy::two_faces_per_square && n_faces_with_neighbour == 2) ); } { const int n_faces_with_neighbour { static_cast<int>( std::count_if(faces_2.begin(),faces_2.end(), [](const boost::shared_ptr<Face> face) { return face->GetNeighbour().get(); } ) ) }; assert( (strategy == CreateVerticalFacesStrategy::one_face_per_square && n_faces_with_neighbour == 1) || (strategy == CreateVerticalFacesStrategy::two_faces_per_square && n_faces_with_neighbour == 2) ); } if (verbose) { TRACE("Creating internal faces 1"); } Helper::FaceSet internal_faces_1 = Helper().CreateEmptyFaceSet(); if (verbose) { TRACE("Creating internal faces 1, std::copy_if"); } std::copy_if( faces_1.begin(),faces_1.end(), std::inserter(internal_faces_1,internal_faces_1.begin()), [](const boost::shared_ptr<Face> face) { assert(face); const bool do_copy = face->GetNeighbour().get(); return do_copy; } ); if (verbose) { TRACE("Creating internal faces 2"); } Helper::FaceSet internal_faces_2 = Helper().CreateEmptyFaceSet(); std::copy_if(faces_2.begin(),faces_2.end(),std::inserter(internal_faces_2,internal_faces_2.begin()), [](const boost::shared_ptr<Face> face) { return face->GetNeighbour().get(); } ); if (verbose) { TRACE("Creating internal faces 1"); } assert( std::equal( internal_faces_1.begin(),internal_faces_1.end(), internal_faces_2.begin(), [](boost::shared_ptr<Face> lhs, boost::shared_ptr<Face> rhs) { return *lhs == *rhs; } ) ); } } if (verbose) { TRACE("Create Face, from bug"); } { //const TestTimer test_timer(boost::lexical_cast<std::string>(__LINE__),__FILE__,1.0); /* (1.17557,2.35781,5.0) (2.35114,3.23607,5.0) (1.17557,2.35781,6.0) (2.35114,3.23607,6.0) */ //Ordering cannot be known for sure to be convex from these indices typedef boost::geometry::model::d2::point_xy<double> Coordinat2D; std::vector<boost::shared_ptr<Point>> face_points { PointFactory().Create(boost::make_shared<Coordinat2D>(1.17557,2.35781)), PointFactory().Create(boost::make_shared<Coordinat2D>(2.35114,3.23607)), PointFactory().Create(boost::make_shared<Coordinat2D>(1.17557,2.35781)), PointFactory().Create(boost::make_shared<Coordinat2D>(2.35114,3.23607)) }; face_points[0]->SetZ(5.0 * boost::units::si::meter); face_points[1]->SetZ(5.0 * boost::units::si::meter); face_points[2]->SetZ(6.0 * boost::units::si::meter); face_points[3]->SetZ(6.0 * boost::units::si::meter); //Order face_points if (!Helper().IsConvex(face_points)) { Helper().MakeConvex(face_points); } #ifndef NDEBUG if (!Helper().IsConvex(face_points)) { TRACE("ERROR"); for (const auto& p: face_points) { TRACE(*p); } TRACE("BREAK"); } #endif assert(Helper().IsConvex(face_points)); //Cannot order face winding yet, need Cells for this const boost::shared_ptr<Face> face { FaceFactory().Create( face_points, FaceOrientation::vertical, verbose ) }; } //From bug { //const TestTimer test_timer(boost::lexical_cast<std::string>(__LINE__),__FILE__,1.0); typedef boost::geometry::model::d2::point_xy<double> Coordinat2D; const double x1 = 0.0004035051226622692510832834944523028752882964909076690673828125; const double y1 = 0.00023296416881187433805568132161312178141088224947452545166015625; const double z1 = 0; //left out the '.0' intentionally const double x2 = 0.000403505141811931846741734464245610070065595209598541259765625; const double y2 = 0.00023296414405748076185791173298156309101614169776439666748046875; const double z2 = 0; //left out the '.0' intentionally const double x3 = 0.0004035051226622692510832834944523028752882964909076690673828125; const double y3 = 0.00023296416881187433805568132161312178141088224947452545166015625; const double z3 = 0.00025000000000000000520417042793042128323577344417572021484375; const double x4 = 0.000403505141811931846741734464245610070065595209598541259765625; const double y4 = 0.00023296414405748076185791173298156309101614169776439666748046875; const double z4 = 0.00025000000000000000520417042793042128323577344417572021484375; const auto c1 = boost::make_shared<Coordinat2D>(x1,y1); const auto c2 = boost::make_shared<Coordinat2D>(x2,y2); const auto c3 = boost::make_shared<Coordinat2D>(x3,y3); const auto c4 = boost::make_shared<Coordinat2D>(x4,y4); const auto p1 = PointFactory().Create(c1); const auto p2 = PointFactory().Create(c2); const auto p3 = PointFactory().Create(c3); const auto p4 = PointFactory().Create(c4); p1->SetZ(z1 * boost::units::si::meter); p2->SetZ(z2 * boost::units::si::meter); p3->SetZ(z3 * boost::units::si::meter); p4->SetZ(z4 * boost::units::si::meter); std::vector<boost::shared_ptr<Point>> face_points; face_points.push_back(p1); face_points.push_back(p2); face_points.push_back(p3); face_points.push_back(p4); assert(IsPlane(face_points)); } }
std::vector<boost::shared_ptr<ribi::trim::Cell>> ribi::trim::CellsCreator::CreateCells( const boost::shared_ptr<const Template> t, const int n_face_layers, const boost::units::quantity<boost::units::si::length> layer_height, const CreateVerticalFacesStrategy strategy, const bool verbose ) noexcept { assert(t); if (n_face_layers < 2 || t->GetPoints().empty() ) { std::vector<boost::shared_ptr<ribi::trim::Cell>> no_cells; return no_cells; } assert(n_face_layers >= 2); if (verbose) { std::clog << __FILE__ << "(" << (__LINE__) << ") : " << "Create points" << std::endl ; } const std::vector<boost::shared_ptr<Point>> all_points = CreatePoints(t,n_face_layers,layer_height); if (verbose) { std::clog << __FILE__ << "(" << (__LINE__) << ") : " << "Create horizontal faces" << std::endl ; } const std::vector<boost::shared_ptr<Face>> hor_faces = CreateHorizontalFaces(t,all_points,n_face_layers); if (verbose) { std::clog << __FILE__ << "(" << (__LINE__) << ") : " << "Create vertical faces" << std::endl ; } const std::vector<boost::shared_ptr<Face>> ver_faces = CreateVerticalFaces(t,all_points,n_face_layers,layer_height,strategy,verbose); if (verbose) { std::clog << __FILE__ << "(" << (__LINE__) << ") : " << "Created " << ver_faces.size() << " vertical faces" << std::endl ; } if (ver_faces.empty()) { std::vector<boost::shared_ptr<ribi::trim::Cell>> no_cells; return no_cells; } #ifndef NDEBUG for(const auto f:ver_faces) { assert(f); } #endif const int n_hor_faces_per_layer = static_cast<int>(t->GetFaces().size()); const int n_cells_per_layer = n_hor_faces_per_layer; if (verbose) { std::clog << __FILE__ << "(" << (__LINE__) << ") : " << "Creating cells" << std::endl ; } std::vector<boost::shared_ptr<Cell>> cells; for (int layer=0; layer!=n_face_layers-1; ++layer) //-1 because there are no points above the top layer { if (verbose) { std::clog << "."; } for (int i=0; i!=n_cells_per_layer; ++i) { const int bottom_face_index = ((layer + 0) * n_hor_faces_per_layer) + i; const int top_face_index = ((layer + 1) * n_hor_faces_per_layer) + i; assert(bottom_face_index >= 0); assert(top_face_index >= 0); assert(bottom_face_index < static_cast<int>(hor_faces.size())); assert(top_face_index < static_cast<int>(hor_faces.size())); const std::vector<boost::shared_ptr<Face>> these_ver_faces { FindKnownFacesBetween( hor_faces[bottom_face_index], hor_faces[top_face_index] ) }; if (strategy == CreateVerticalFacesStrategy::one_face_per_square ) { #ifndef NDEBUG if (these_ver_faces.size() != 3) { TRACE("BREAK"); } #endif assert(these_ver_faces.size() == 3); assert(hor_faces[bottom_face_index]); assert(hor_faces[top_face_index]); assert(these_ver_faces[0]); assert(these_ver_faces[1]); assert(these_ver_faces[2]); const boost::shared_ptr<Cell> cell( CellFactory().Create( { hor_faces[bottom_face_index], hor_faces[top_face_index], these_ver_faces[0], these_ver_faces[1], these_ver_faces[2] }, strategy ) ); assert(hor_faces[bottom_face_index]); assert(hor_faces[top_face_index]); assert(Helper().IsHorizontal(*hor_faces[bottom_face_index])); assert(Helper().IsHorizontal(*hor_faces[top_face_index])); assert(Helper().IsVertical(*these_ver_faces[0])); assert(Helper().IsVertical(*these_ver_faces[1])); assert(Helper().IsVertical(*these_ver_faces[2])); cells.push_back(cell); } else { assert(these_ver_faces.size() == 6); const boost::shared_ptr<Cell> cell { CellFactory().Create( { hor_faces[bottom_face_index], hor_faces[top_face_index], these_ver_faces[0], these_ver_faces[1], these_ver_faces[2], these_ver_faces[3], these_ver_faces[4], these_ver_faces[5] }, strategy ) }; assert(hor_faces[bottom_face_index]); assert(hor_faces[top_face_index]); assert(Helper().IsHorizontal(*hor_faces[bottom_face_index])); assert(Helper().IsHorizontal(*hor_faces[top_face_index])); assert(Helper().IsVertical(*these_ver_faces[0])); assert(Helper().IsVertical(*these_ver_faces[1])); assert(Helper().IsVertical(*these_ver_faces[2])); assert(Helper().IsVertical(*these_ver_faces[3])); assert(Helper().IsVertical(*these_ver_faces[4])); assert(Helper().IsVertical(*these_ver_faces[5])); cells.push_back(cell); } } } #ifndef NDEBUG if (verbose) { std::clog << __FILE__ << "(" << (__LINE__) << ") : " << "Checking cells" << std::endl ; } CheckCells(cells); #endif // NDEBUG if (verbose) { std::clog << __FILE__ << "(" << (__LINE__) << ") : " << "Done creating cells" << std::endl ; } return cells; }