/**************************************************************************** ** Copyright (c) 2017, Fougue Ltd. ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions ** are met: ** ** 1. Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** ** 2. Redistributions in binary form must reproduce the above ** copyright notice, this list of conditions and the following ** disclaimer in the documentation and/or other materials provided ** with the distribution. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../commons/benchmark_tools.h" #include #include #include #include namespace BmkBRep { TopoDS_Shape inputShape; class ProgressIndicator : public Message_ProgressIndicator { public: Standard_Boolean Show(const Standard_Boolean /*force*/) override { const Standard_Real pc = this->GetPosition(); // Always within [0,1] const int val = static_cast(1 + pc * (100 - 1)); if (val > m_val) { std::cout << val; if (val < 100) std::cout << "-"; else std::cout << "%"; std::cout.flush(); m_val = val; } return Standard_True; } Standard_Boolean UserBreak() override { return Standard_False; } private: int m_val = 0; }; template TopoDS_Shape loadShapeFromFile( const char* fileName, Handle_Message_ProgressIndicator indicator) { TopoDS_Shape result; if (!indicator.IsNull()) indicator->NewScope(30, "Loading file"); READER reader; const int status = reader.ReadFile(const_cast(fileName)); if (!indicator.IsNull()) indicator->EndScope(); if (status == IFSelect_RetDone) { if (!indicator.IsNull()) { reader.WS()->MapReader()->SetProgress(indicator); indicator->NewScope(70, "Translating file"); } reader.NbRootsForTransfer(); reader.TransferRoots(); result = reader.OneShape(); if (!indicator.IsNull()) { indicator->EndScope(); reader.WS()->MapReader()->SetProgress(NULL); } } return result; } void readInputIgesShape(const char* filepath) { Handle_Message_ProgressIndicator indicator = new ProgressIndicator; inputShape = loadShapeFromFile(filepath, indicator); } void readInputStepShape(const char* filepath) { Handle_Message_ProgressIndicator indicator = new ProgressIndicator; inputShape = loadShapeFromFile(filepath, indicator); } } // namespace BmkBRep namespace BmkOcc { Handle_StlMesh_Mesh stlMesh; static void RWStl_ReadFile(const void* filepath) { stlMesh = RWStl::ReadFile(OSD_Path(static_cast(filepath))); if (stlMesh.IsNull()) std::cerr << "RWStl::ReadFile(): null mesh" << std::endl; } static void RWStl_WriteAscii(const void* filepath) { if (!RWStl::WriteAscii(stlMesh, OSD_Path(static_cast(filepath)))) std::cerr << "RWStl::WriteAscii() failure" << std::endl; } static void RWStl_WriteBinary(const void* filepath) { if (!RWStl::WriteBinary(stlMesh, OSD_Path(static_cast(filepath)))) std::cerr << "RWStl::WriteBinary() failure" << std::endl; } static void StlAPI_WriteAscii(const void* filepath) { if (!BmkBRep::inputShape.IsNull()) { StlAPI_Writer writer; writer.ASCIIMode() = Standard_True; const char* cfilepath = static_cast(filepath); #if OCC_VERSION_HEX >= 0x060900 const StlAPI_ErrorStatus err = writer.Write(BmkBRep::inputShape, cfilepath); if (err != StlAPI_StatusOK) std::cerr << "StlAPI_Writer::Write() error: " << err << std::endl; #else writer.Write(BmkBRep::inputShape, cfilepath); #endif } } static void StlAPI_WriteBinary(const void* filepath) { if (!BmkBRep::inputShape.IsNull()) { StlAPI_Writer writer; writer.ASCIIMode() = Standard_False; const char* cfilepath = static_cast(filepath); #if OCC_VERSION_HEX >= 0x060900 const StlAPI_ErrorStatus err = writer.Write(BmkBRep::inputShape, cfilepath); if (err != StlAPI_StatusOK) std::cerr << "StlAPI_Writer::Write() error: " << err << std::endl; #else writer.Write(BmkBRep::inputShape, cfilepath); #endif } } } // namespace BmkOcc namespace BmkGmio { Handle_StlMesh_Mesh stlMesh; static void stl_read(const void* filepath) { stlMesh = new StlMesh_Mesh; gmio_stl_mesh_creator_occmesh mesh_creator(stlMesh); const int error = gmio_stl_read_file( static_cast(filepath), &mesh_creator, NULL); if (error != GMIO_ERROR_OK) std::cerr << "gmio error: 0x" << std::hex << error << std::endl; } static void stl_write( const char* filepath, gmio_stl_format format, const gmio_stl_mesh& mesh) { gmio_stl_write_options options = {}; //options.stla_float32_format = GMIO_FLOAT_TEXT_FORMAT_SHORTEST_UPPERCASE; options.stla_float32_format = GMIO_FLOAT_TEXT_FORMAT_SCIENTIFIC_LOWERCASE; options.stla_float32_prec = 6; const int error = gmio_stl_write_file(format, filepath, &mesh, &options); if (error != GMIO_ERROR_OK) std::cerr << "gmio error: 0x" << std::hex << error << std::endl; } static void stl_mesh_write(const char* filepath, gmio_stl_format format) { const gmio_stl_mesh_occmesh mesh(stlMesh); stl_write(filepath, format, mesh); } static void stl_brep_write(const char* filepath, gmio_stl_format format) { const gmio_stl_mesh_occshape mesh(BmkBRep::inputShape); stl_write(filepath, format, mesh); } static void stla_mesh_write(const void* filepath) { stl_mesh_write(static_cast(filepath), GMIO_STL_FORMAT_ASCII); } static void stlb_mesh_write_le(const void* filepath) { stl_mesh_write(static_cast(filepath), GMIO_STL_FORMAT_BINARY_LE); } static void stlb_mesh_write_be(const void* filepath) { stl_mesh_write(static_cast(filepath), GMIO_STL_FORMAT_BINARY_BE); } static void stla_brep_write(const void* filepath) { stl_brep_write(static_cast(filepath), GMIO_STL_FORMAT_ASCII); } static void stlb_brep_write_le(const void* filepath) { stl_brep_write(static_cast(filepath), GMIO_STL_FORMAT_BINARY_LE); } static void stlb_brep_write_be(const void* filepath) { stl_brep_write(static_cast(filepath), GMIO_STL_FORMAT_BINARY_BE); } } // namespace BmkGmio int main(int argc, char** argv) { const char* stl_filepath = nullptr; const char* igs_filepath = nullptr; const char* stp_filepath = nullptr; double linear_deflection = 0.1; int iarg = 1; while (iarg < argc) { if (std::strcmp(argv[iarg], "--iges") == 0) igs_filepath = argv[++iarg]; else if (std::strcmp(argv[iarg], "--step") == 0) stp_filepath = argv[++iarg]; else if (std::strcmp(argv[iarg], "--linear-deflection") == 0) linear_deflection = std::atof(argv[++iarg]); else stl_filepath = argv[iarg]; ++iarg; } if (stl_filepath != nullptr) { std::cout << std::endl << "gmio v" << GMIO_VERSION_STR << std::endl << "OpenCascade v" << OCC_VERSION_COMPLETE << std::endl << std::endl << "STL input file: " << stl_filepath << std::endl; if (igs_filepath != nullptr) { std::cout << "IGES input file: " << igs_filepath << std::endl; BmkBRep::readInputIgesShape(igs_filepath); } else if (stp_filepath != nullptr) { std::cout << "STEP input file: " << stp_filepath << std::endl; BmkBRep::readInputStepShape(stp_filepath); } std::cout << std::endl << "Meshing with linear deflection=" << linear_deflection << " ..." << std::endl; for (TopExp_Explorer expl(BmkBRep::inputShape, TopAbs_FACE); expl.More(); expl.Next()) { const TopoDS_Face& face = TopoDS::Face(expl.Current()); TopLoc_Location location; const auto& poly = BRep_Tool::Triangulation(face, location); if (poly.IsNull() || poly->Triangles().Length() <= 0) BRepMesh_IncrementalMesh(face, linear_deflection); } std::cout << std::endl << "Meshing done" << std::endl; /* Declare benchmarks */ const benchmark_cmp_arg cmp_args[] = { { "read", BmkGmio::stl_read, stl_filepath, BmkOcc::RWStl_ReadFile, stl_filepath }, { "meshwrite(ascii)", BmkGmio::stla_mesh_write, "__bmk_occ_gmio_mesh.stla", BmkOcc::RWStl_WriteAscii, "__bmk_occ_mesh.stla" }, { "meshwrite(binary/le)", BmkGmio::stlb_mesh_write_le, "__bmk_occ_gmio_mesh.stlb_le", BmkOcc::RWStl_WriteBinary, "__bmk_occ_mesh.stlb_le" }, { "meshwrite(binary/be)", BmkGmio::stlb_mesh_write_be, "__bmk_occ_gmio_mesh.stlb_be", NULL, NULL }, { "brepwrite(ascii)", BmkGmio::stla_brep_write, "__bmk_occ_gmio_brep.stla", BmkOcc::StlAPI_WriteAscii, "__bmk_occ_brep.stla" }, { "brepwrite(binary/le)", BmkGmio::stlb_brep_write_le, "__bmk_occ_gmio_brep.stlb_le", BmkOcc::StlAPI_WriteBinary, "__bmk_occ_brep.stlb_le" }, { "brepwrite(binary/be)", BmkGmio::stlb_brep_write_be, "__bmk_occ_gmio_brep.stlb_be", NULL, NULL }, {} }; /* Execute benchmarks */ std::vector cmp_res_vec; cmp_res_vec.resize(GMIO_ARRAY_SIZE(cmp_args) - 1); benchmark_cmp_batch(5, cmp_args, &cmp_res_vec[0], NULL, NULL); /* Print results */ const benchmark_cmp_result_array res_array = { &cmp_res_vec.at(0), cmp_res_vec.size() }; const benchmark_cmp_result_header header = { "gmio", "OpenCascade" }; benchmark_print_results( BENCHMARK_PRINT_FORMAT_MARKDOWN, header, res_array); } return 0; }