diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..605cc630 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,9 @@ +{ + "files.associations": { + "string": "cpp", + "array": "cpp", + "string_view": "cpp", + "initializer_list": "cpp", + "utility": "cpp" + } +} \ No newline at end of file diff --git a/ChildClass.cpp b/ChildClass.cpp new file mode 100644 index 00000000..837594ac --- /dev/null +++ b/ChildClass.cpp @@ -0,0 +1,15 @@ +#include "ChildClass.h" + +using namespace GlobalContextClassNameSpace; + +ChildClass::ChildClass() +: ParentClass() +{ + +} + +ChildClass::~ChildClass() +{ + +} + diff --git a/ChildClass.h b/ChildClass.h new file mode 100644 index 00000000..9820dc6f --- /dev/null +++ b/ChildClass.h @@ -0,0 +1,29 @@ +#ifndef CHILD_CLASS_CONTEXT_MODEL_H +#define CHILD_CLASS_CONTEXT_MODEL_H + +#include "ParentClass.h" + +namespace GlobalContextClassNameSpace +{ + + // only use this context when defined + class ChildClass: public ParentClass + { + public: + ChildClass(); + virtual ~ChildClass(){}; + + virtual int getValue() const override; + }; + +inline int ChildClass::getValue() const +{ + return 3; +} + + +} // GlobalContextClassNameSpace + + + +#endif \ No newline at end of file diff --git a/ParentClass.cpp b/ParentClass.cpp new file mode 100644 index 00000000..87236131 --- /dev/null +++ b/ParentClass.cpp @@ -0,0 +1,17 @@ +#include "ParentClass.h" + +using namespace GlobalContextClassNameSpace; + +ParentClass::ParentClass() +: m_A(0) +, m_B(0.0) +, m_name("hello") +{ + std::cout << "ParentClass:" << m_name << std::endl; +} + +ParentClass::~ParentClass() +{ + +} + diff --git a/ParentClass.h b/ParentClass.h new file mode 100644 index 00000000..c6216cfd --- /dev/null +++ b/ParentClass.h @@ -0,0 +1,26 @@ +#ifndef PARENT_CLASS_CONTEXT_MODEL_H +#define PARENT_CLASS_CONTEXT_MODEL_H + + +namespace GlobalContextClassNameSpace +{ + class ParentClass + { + public: + ParentClass(); + virtual ~ParentClass(); + + virtual int getValue() const = 0; + + protected: + int m_A = 0; + double m_B = 0.0; + + private: + std::string m_name = ""; + }; +} // GlobalContextClassNameSpace + + + +#endif \ No newline at end of file diff --git a/diff_output.txt b/diff_output.txt new file mode 100644 index 00000000..1c7479ec --- /dev/null +++ b/diff_output.txt @@ -0,0 +1,33 @@ +diff --git a/sample_code.cpp b/sample_code.cpp +index 1cfa8b8..3e6c7bd 100644 +--- a/sample_code.cpp ++++ b/sample_code.cpp +@@ -8,7 +8,7 @@ int functionA() + int num = 5; + while (num < 10) { + std::cout << num << std::endl; +- num++; ++ num--; + } + return 0; + } +@@ -16,7 +16,7 @@ int functionA() + int sum(std::list lst) + { + int total = 0; +- for (auto it = lst.begin(); it != lst.end(); it++) ++ for (auto it = lst.begin(); it != --lst.end(); it++) + { + total += *it; + } +@@ -28,8 +28,8 @@ double average(int arr[], int size) { + for (int i = 0; i < size; i++) { + sum += arr[i]; + } +- int num = size; +- return sum / double(num); ++ int num = rand() % 10 + 1; ++ return sum / num; + } + + int main() { diff --git a/extract_git_diff.py b/extract_git_diff.py new file mode 100644 index 00000000..91a5e191 --- /dev/null +++ b/extract_git_diff.py @@ -0,0 +1,56 @@ + +#!/usr/bin/python3 + +import os +import shutil +import subprocess +import pandas as pd +import numpy as np +import string +import enum +from typing import List, Optional + + +THIS_DIR = os.path.abspath(os.path.dirname(__file__)) +FILE_DIR = THIS_DIR + '/mesh/' +DST_FOLDER_OUTPUT = THIS_DIR + '/git_diff_output/' + +def git_diff_per_file(in_list: list): + numb = len(in_list) + print(f'Number of files: {numb}') + data = pd.DataFrame(columns=['code_files','size'], index=range(numb)) + + index = 0 + for item in in_list: + if not os.path.isfile(item): + continue + print(f'{index}: {item}') + + source = FILE_DIR + item + output = DST_FOLDER_OUTPUT + item + ".gitdiff.txt" + cmd = ( + "git diff master 2e7237f " + f"{source} " + f"> {output} " + ) + os.system(cmd) + + +def main(): + print(f'directory {FILE_DIR}') + if not os.path.exists(FILE_DIR): + print('File structure not as expected!\n') + return + + dst = os.path.join(THIS_DIR, DST_FOLDER_OUTPUT ) + if not os.path.exists(dst): + os.makedirs(DST_FOLDER_OUTPUT) + + os.chdir(FILE_DIR) + git_diff_per_file(os.listdir(os.curdir)) + + + exit(0) + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/git_diff_output/AnalysisInfo.h.gitdiff.txt b/git_diff_output/AnalysisInfo.h.gitdiff.txt new file mode 100644 index 00000000..a01aa056 --- /dev/null +++ b/git_diff_output/AnalysisInfo.h.gitdiff.txt @@ -0,0 +1,12 @@ +diff --git a/mesh/AnalysisInfo.h b/mesh/AnalysisInfo.h +index a48c431..6f8142b 100644 +--- a/mesh/AnalysisInfo.h ++++ b/mesh/AnalysisInfo.h +@@ -190,6 +190,7 @@ class MeshAnalysisInfo : public AnalysisInfo + double dOccGeometryVolume = 0; + double dSurfaceArea = 0; + double dMeshingDuration = 0; // time in seconds to tet mesh ++ double dPrimeFileIODuration = 0; // time in seconds to read/write prime files + double dTetVolume = 0; // tet volume before projection + double dTetVolumeAfterProjection = 0; // tet volume after projection + double dVolumeDiffPercent = 0; diff --git a/git_diff_output/CMakeLists.txt.gitdiff.txt b/git_diff_output/CMakeLists.txt.gitdiff.txt new file mode 100644 index 00000000..af2bf556 --- /dev/null +++ b/git_diff_output/CMakeLists.txt.gitdiff.txt @@ -0,0 +1,44 @@ +diff --git a/mesh/CMakeLists.txt b/mesh/CMakeLists.txt +index 4c3c187..51bda9d 100644 +--- a/mesh/CMakeLists.txt ++++ b/mesh/CMakeLists.txt +@@ -215,6 +215,21 @@ if(NOT CadEx_FOUND OR CAD_FORCE_DATAKIT) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DCAD_HAS_DATAKIT") + endif() + ++if(DEFINED ENV{PRIME_MESHER_VER}) ++ set(PRIME_VER "20.01.23-centos_7_2.7") ++ message(STATUS "Found PRIME Version at: ${PRIME_VER}") ++ set(PRIME_SOURCE_LIB /opt/onscale/pyprimemesh-v${PRIME_VER}/pyprimemesh-v${PRIME_VER}.tar) ++ message(STATUS "Found PRIME_SOURCE_LIB: ${PRIME_SOURCE_LIB}") ++ set(PRIME_TARGET_LIB ${CMAKE_BINARY_DIR}/lib/pyprimemesh.tar) ++ set(PRIME_TARGET_DES ${CMAKE_BINARY_DIR}/lib) ++ message(STATUS "PRIME_TARGET_LIB: ${PRIME_TARGET_LIB}") ++ file(COPY ${PRIME_SOURCE_LIB} DESTINATION ${PRIME_TARGET_DES}) ++ set(PRIME_LIB ${CMAKE_BINARY_DIR}/lib/pyprimemesh-v${PRIME_VER}.tar) ++ file(RENAME ${PRIME_LIB} ${PRIME_TARGET_LIB}) ++else() ++ message(STATUS "No PRIME_MESHER_VER defined") ++endif() ++ + # add CM2 mesher library + if(DEFINED ENV{CM2_VER}) + message(STATUS "Use cm2 version: " $ENV{CM2_VER}) +@@ -305,7 +320,7 @@ find_library(LIB_ANSYS_PRIME_MESH_DIR PrimeMesh PATHS "$ENV{ANSYS_PRIME_MESH_DIR + find_path(INC_ANSYS_PRIME_MESH PrimeModel PATHS "$ENV{ANSYS_PRIME_MESH_DIR}/include") + + if(NOT LIB_ANSYS_PRIME_MESH_DIR) +- message(STATUS "OnScale::CAD -> Won't use Ansys Prime Mesher.") ++ message(STATUS "OnScale::CAD -> Won't use Ansys Prime Mesher dlls.") + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DCAD_HAS_ANSYS_PRIME") + +@@ -463,6 +478,8 @@ if(NOT ${OnScale_CAD_LITE}) + Cm2Construction3D.h + Cm2ConstructionTet3D.cpp + Cm2ConstructionTet3D.h ++ PrimeFileIO.h ++ PrimeFileIO.cpp + PrimeConstructionTet3D.cpp + PrimeConstructionTet3D.h + AnsysConstruction3D.cpp diff --git a/git_diff_output/Cm2Construction3D.cpp.gitdiff.txt b/git_diff_output/Cm2Construction3D.cpp.gitdiff.txt new file mode 100644 index 00000000..dd0b1f0c --- /dev/null +++ b/git_diff_output/Cm2Construction3D.cpp.gitdiff.txt @@ -0,0 +1,27 @@ +diff --git a/mesh/Cm2Construction3D.cpp b/mesh/Cm2Construction3D.cpp +index e7e347a..bb59f67 100644 +--- a/mesh/Cm2Construction3D.cpp ++++ b/mesh/Cm2Construction3D.cpp +@@ -154,6 +154,13 @@ bool Cm2Construction3D::build() + { + iNumberOfMesherRestart++; + ++ //[TODO] remove following msg stmts ++ m_occData->addMsg("Remesher Error Code: " + std::to_string(m_iRemesherErrorCode)); ++ m_occData->addMsg("Tetmesher Error Code: " + std::to_string(m_iTetmesherErrorCode)); ++ m_occData->addMsg("Tetmesher Warning Code: " + std::to_string(m_iTetmesherWarningCode)); ++ m_occData->addMsg("Number of Tets: " + std::to_string(numberOfElements())); ++ m_occData->addMsg("PartIDs with No Elements: " + std::to_string(m_meshInfo.partListWithNoElements.size())); ++ + // CM2_BOUNDARY_WARNING = -15 + // CM2_FACE_DISCARDED = -14 + // CM2_NODE_DISCARDED = -12 +@@ -169,7 +176,7 @@ bool Cm2Construction3D::build() + (m_iTetmesherWarningCode == cm2::tetramesh_iso::mesher::data_type::CM2_FACE_DISCARDED && + m_meshInfo.partListWithNoElements.size() != 0) || + (m_iTetmesherWarningCode == cm2::tetramesh_iso::mesher::data_type::CM2_NODE_DISCARDED && +- m_meshInfo.partListWithNoElements.size() != 0) ) ++ m_meshInfo.partListWithNoElements.size() != 0)) + { + // We are in a situation, where the default fix intersection tolerance doesn't work. + // So, we try to use a smaller fix intersection tolerance and restart the meshing process. diff --git a/git_diff_output/Cm2Construction3D.h.gitdiff.txt b/git_diff_output/Cm2Construction3D.h.gitdiff.txt new file mode 100644 index 00000000..ec54553f --- /dev/null +++ b/git_diff_output/Cm2Construction3D.h.gitdiff.txt @@ -0,0 +1,13 @@ +diff --git a/mesh/Cm2Construction3D.h b/mesh/Cm2Construction3D.h +index f8f56ad..ce2ba7a 100644 +--- a/mesh/Cm2Construction3D.h ++++ b/mesh/Cm2Construction3D.h +@@ -125,6 +125,8 @@ class Cm2Construction3D : public Cgal3DPolyhedronConstruction + double m_dBondingDurationUntilNow = 0; + bool m_bModelTooComplexForBonding = false; + ++ double m_dPrimeFileIODuration = 0; ++ + cm2::element_type m_feType; // CM2_TETRA4 or CM2_HEXA8 + + cm2::DoubleMat m_pos; // mesh coordinates diff --git a/git_diff_output/Cm2ConstructionTet3D.cpp.gitdiff.txt b/git_diff_output/Cm2ConstructionTet3D.cpp.gitdiff.txt new file mode 100644 index 00000000..fa482313 --- /dev/null +++ b/git_diff_output/Cm2ConstructionTet3D.cpp.gitdiff.txt @@ -0,0 +1,75 @@ +diff --git a/mesh/Cm2ConstructionTet3D.cpp b/mesh/Cm2ConstructionTet3D.cpp +index 1580e15..8aad957 100644 +--- a/mesh/Cm2ConstructionTet3D.cpp ++++ b/mesh/Cm2ConstructionTet3D.cpp +@@ -7,6 +7,8 @@ + #include "Cm2ConstructionTet3D.h" + #include "DistanceTetMeshToCad.h" + ++#include "PrimeFileIO.h" ++ + #include "OccFileReader.h" + #include "OccFileWriter.h" + +@@ -262,7 +264,7 @@ void Cm2ConstructionTet3D::generateTetMesh(cm2::intersect_t3::mesher::data_type + dataAll.colors = secondAll.colors; + } + } +- m_iNumberOfRemesherIterations = iCount -1; ++ m_iNumberOfRemesherIterations = iCount - 1; + m_occData->addMsg("Number of remeshing iterations: " + std::to_string(m_iNumberOfRemesherIterations)); + + if (m_bRemesherFailed) +@@ -294,6 +296,12 @@ void Cm2ConstructionTet3D::generateTetMesh(cm2::intersect_t3::mesher::data_type + return; + } + ++ if (m_occData->isAddDebugInfoFlag() >= 5) ++ { ++ PrimeFileIO fileio(this); ++ fileio.writeBoundaryMesh(secondAll); ++ } ++ + // tetra meshing + if (!createTetMesh(secondAll)) + return; +@@ -312,6 +320,7 @@ void Cm2ConstructionTet3D::generateTetMesh(cm2::intersect_t3::mesher::data_type + + m_cellColors = m_tetData.colors; + m_connectM = m_tetData.connectM; ++ m_connectB = m_tetData.connectB; + m_pos = m_tetData.pos; + m_shape_qualities = m_tetData.shape_qualities; + +@@ -326,6 +335,7 @@ void Cm2ConstructionTet3D::generateTetMesh(cm2::intersect_t3::mesher::data_type + Standard_Real rVolDiff2 = std::fabs(rVolTest3 - rVolTest2); + + meshInfo.dMeshingDuration = m_tetData.total_time; ++ meshInfo.dPrimeFileIODuration = m_dPrimeFileIODuration; + m_meshInfo.dOccGeometryVolume = rVolTest3; + m_meshInfo.dSurfaceArea = m_dSurfaceArea; + m_meshInfo.dTetVolume = rVolTest2; +@@ -348,18 +358,17 @@ void Cm2ConstructionTet3D::generateTetMesh(cm2::intersect_t3::mesher::data_type + meshInfo.dJacobianMin = dMinJacobian; + meshInfo.dJacobianMax = dMaxJacobian; + +- const cm2::misc::histogram &histo_Qs = m_tetData.histo_Qs; +- meshInfo.dAverageCellQuality = histo_Qs.mean_value(); +- meshInfo.dWorstCellQuality = histo_Qs.min_value(); ++ meshInfo.dAverageCellQuality = getAverageCellQuality(); ++ meshInfo.dWorstCellQuality = getWorstCellQuality(); + +- size_t numberOfBins = histo_Qs.bins(); +- const cm2::DoubleVec &bin_boundaries = histo_Qs.bin_boundaries(); ++ size_t numberOfBins = m_tetData.histo_Qs.bins(); ++ const cm2::DoubleVec &bin_boundaries = m_tetData.histo_Qs.bin_boundaries(); + + for (size_t i = 0; i < numberOfBins; ++i) + { + const double lower = bin_boundaries.at(i); + const double upper = bin_boundaries.at(i + 1); +- const unsigned int hits = histo_Qs.hits(i); ++ const unsigned int hits = m_tetData.histo_Qs.hits(i); + meshInfo.cellQualities.push_back(std::make_tuple(lower, upper, hits)); + } + diff --git a/git_diff_output/Cm2ConstructionTet3D.h.gitdiff.txt b/git_diff_output/Cm2ConstructionTet3D.h.gitdiff.txt new file mode 100644 index 00000000..48d47125 --- /dev/null +++ b/git_diff_output/Cm2ConstructionTet3D.h.gitdiff.txt @@ -0,0 +1,15 @@ +diff --git a/mesh/Cm2ConstructionTet3D.h b/mesh/Cm2ConstructionTet3D.h +index 1b0a890..c5e9ae7 100644 +--- a/mesh/Cm2ConstructionTet3D.h ++++ b/mesh/Cm2ConstructionTet3D.h +@@ -54,6 +54,9 @@ class Cm2ConstructionTet3D : public Cm2Construction3D + void checkMeshToCadFit(); + + void cellCenter(int iE, double &dX, double &dY, double &dZ) override; ++ ++ virtual double getAverageCellQuality() { return m_tetData.histo_Qs.mean_value(); } ++ virtual double getWorstCellQuality() { return m_tetData.histo_Qs.min_value(); } + }; + + #endif +\ No newline at end of file diff --git a/git_diff_output/OccDataStructure.cpp.gitdiff.txt b/git_diff_output/OccDataStructure.cpp.gitdiff.txt new file mode 100644 index 00000000..06650b80 --- /dev/null +++ b/git_diff_output/OccDataStructure.cpp.gitdiff.txt @@ -0,0 +1,26 @@ +diff --git a/mesh/OccDataStructure.cpp b/mesh/OccDataStructure.cpp +index bb35688..71bde7c 100644 +--- a/mesh/OccDataStructure.cpp ++++ b/mesh/OccDataStructure.cpp +@@ -684,12 +684,20 @@ bool OccDataStructure::getPointOnFace(const TopoDS_Face &faceShape, double &fX, + + Handle(Geom_Surface) aSurface = BRep_Tool::Surface(faceShape); + ++ BRepAdaptor_Surface Adaptor; ++ Adaptor.Initialize(faceShape); ++ GeomAbs_SurfaceType surfaceType = Adaptor.GetType(); ++ + GeomAPI_ProjectPointOnSurf proj; + try + { + OCC_CATCH_SIGNALS + +- proj.Init(point, aSurface); ++ // due to a segmentation fault in OCCT, we use the Extrema_ExtAlgo_Tree instead of the default ++ if (surfaceType == GeomAbs_OffsetSurface) ++ proj.Init(point, aSurface, Extrema_ExtAlgo_Tree); ++ else ++ proj.Init(point, aSurface); + } + catch (...) + { diff --git a/git_diff_output/OccDataStructureBase.cpp.gitdiff.txt b/git_diff_output/OccDataStructureBase.cpp.gitdiff.txt new file mode 100644 index 00000000..2e83d8d7 --- /dev/null +++ b/git_diff_output/OccDataStructureBase.cpp.gitdiff.txt @@ -0,0 +1,16 @@ +diff --git a/mesh/OccDataStructureBase.cpp b/mesh/OccDataStructureBase.cpp +index 32a710b..48c5fdb 100644 +--- a/mesh/OccDataStructureBase.cpp ++++ b/mesh/OccDataStructureBase.cpp +@@ -289,9 +289,9 @@ void OccDataStructureBase::setOriginalFileName(const std::string &fileName) + + std::string OccDataStructureBase::getAbsoluteDebugOutputPath() + { +- std::filesystem::path p = std::filesystem::path(getOriginalFileName()); ++ std::filesystem::path p2 = std::filesystem::current_path(); + +- auto absPath = std::filesystem::path(getOriginalFileName()).parent_path().generic_string(); ++ auto absPath = p2.generic_string(); + + return absPath; + } diff --git a/git_diff_output/PrimeConstructionTet3D.cpp.gitdiff.txt b/git_diff_output/PrimeConstructionTet3D.cpp.gitdiff.txt new file mode 100644 index 00000000..19f3e1db --- /dev/null +++ b/git_diff_output/PrimeConstructionTet3D.cpp.gitdiff.txt @@ -0,0 +1,183 @@ +diff --git a/mesh/PrimeConstructionTet3D.cpp b/mesh/PrimeConstructionTet3D.cpp +index b721d40..2b7d510 100644 +--- a/mesh/PrimeConstructionTet3D.cpp ++++ b/mesh/PrimeConstructionTet3D.cpp +@@ -1,9 +1,13 @@ ++#include "PrimeConstructionTet3D.h" ++#include "PrimeFileIO.h" ++#include ++#include + +-// © 2022 ANSYS, Inc. and/or its affiliated companies. +-// All rights reserved. +-// Unauthorized use, distribution, or reproduction is prohibited. ++#define SUCCESS 0 ++#define MAX_NAME_LENGTH 100 ++#define NULLP(p) ((p) == NULL) + +-#include "PrimeConstructionTet3D.h" ++/*REQUIRED FUNCTIONS END*/ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + PrimeConstructionTet3D::PrimeConstructionTet3D(std::shared_ptr occDataStruct) + : Cm2ConstructionTet3D(occDataStruct) +@@ -13,6 +17,44 @@ PrimeConstructionTet3D::PrimeConstructionTet3D(std::shared_ptr + + PrimeConstructionTet3D::~PrimeConstructionTet3D() {} + ++void PrimeConstructionTet3D::updateShapeQualities() ++{ ++ int ret_tet = cm2::meshtools::shape_qualities(m_tetData.pos, m_tetData.connectM, cm2::element_type::CM2_TETRA4, m_tetData.shape_qualities); ++ if (ret_tet == 0) ++ { ++ int iNumbOfElems = m_tetData.shape_qualities.size(); ++ cm2::DoubleVec useShapeQualities(iNumbOfElems + 2); ++ useShapeQualities[iNumbOfElems] = 0.0; ++ useShapeQualities[iNumbOfElems + 1] = 1.0; ++ for (int i = 0; i < iNumbOfElems; i++) ++ { ++ m_tetData.shape_qualities[i] = std::fabs(m_tetData.shape_qualities[i]); ++ useShapeQualities[i] = std::fabs(m_tetData.shape_qualities[i]); ++ } ++ ++ size_t binSize = 10; ++ m_tetData.histo_Qs.reinit(binSize, m_tetData.shape_qualities); ++ m_dAverageCellQuality = m_tetData.histo_Qs.mean_value(); ++ m_dWorstCellQuality = m_tetData.histo_Qs.min_value(); ++ ++ m_tetData.histo_Qs.reinit(binSize, useShapeQualities); ++ } ++} ++ ++void PrimeConstructionTet3D::updateAncestorsAndNeighbours() ++{ ++ m_tetData.ancestors.clear(); // fucntionalize them ++ int ret = cm2::meshtools::get_ancestors(m_tetData.connectM, m_tetData.ancestors); ++ if (ret != 0) ++ m_occData->addMsg("get_ancestors: The " + std::to_string(ret) + " -th argument had an illegal value ", CADErrorHandler::GetAncestors); ++ ++ m_tetData.neighbors.clear(); ++ bool accept_multiple_neighbors = false; ++ int ret1 = cm2::meshtools::get_neighbors(m_tetData.connectM, cm2::CM2_TETRA4, accept_multiple_neighbors, m_tetData.neighbors); ++ if (ret1 != 0) ++ m_occData->addMsg("get_neighbors: The " + std::to_string(ret1) + " -th argument had an illegal value )", CADErrorHandler::GetNeighbors); ++} ++ + bool PrimeConstructionTet3D::createTetMesh(cm2::intersect_t3::mesher::data_type &dataAllRemeshed) + { + // access dataAllRemeshed: Here you find the data for the boundary mesh +@@ -34,26 +76,99 @@ bool PrimeConstructionTet3D::createTetMesh(cm2::intersect_t3::mesher::data_type + // m_tetData.total_time : need to be discussed - time in seconds + + // Note: The nodal ids stored in connectM and connectB must be using the same nodal ids ++ // re-create ancestors and neighbors from tetData + +- // re create ancestors and neighbors from tetData +- m_ancestors.clear(); +- int ret = cm2::meshtools::get_ancestors(m_tetData.connectM, m_ancestors); +- if (ret != 0) +- m_occData->addMsg("get_ancestors: The " + std::to_string(ret) + " -th argument had an illegal value ", CADErrorHandler::GetAncestors); ++ PrimeFileIO fileio(this); ++ bool foundDiscardedFaces = false; + +- m_neighbors.clear(); +- bool accept_multiple_neighbors = false; +- int ret1 = cm2::meshtools::get_neighbors(m_tetData.connectM, cm2::CM2_TETRA4, accept_multiple_neighbors, m_neighbors); +- if (ret1 != 0) +- m_occData->addMsg("get_neighbors: The " + std::to_string(ret1) + " -th argument had an illegal value )", CADErrorHandler::GetNeighbors); ++ std::string absPath = m_occData->getAbsoluteDebugOutputPath(); ++ std::string unique_name = m_occData->getOriginalFileBaseName() + "_" + std::to_string(uniqueBaseIdentifier()); ++ ++ /*create a prime directory to store all the debug file in it*/ ++ int ret_d = fileio.CreateDirectory("prime"); ++ if (ret_d) ++ std::cout << "the prime directory has been successfully created -> " << std::endl; ++ ++ /*The code to write the boundary mesh file in the directory*/ ++ CGAL::Real_timer fileWriterTime; ++ fileWriterTime.start(); ++ fileio.writeBoundaryMesh(dataAllRemeshed); ++ m_dPrimeFileIODuration += fileWriterTime.time(); ++ fileWriterTime.stop(); ++ ++ /*The code for placing the Generate_vol.py file in prime debug folder*/ ++ fileio.GenerateVolumePyFile(); ++ ++ /*The code for generating the run Prime sh file */ ++ fileio.CreatePrimeShellScript(); ++ ++ /*Running the shell script to kick off prime container */ ++ CGAL::Real_timer tetMeshDuration; ++ tetMeshDuration.start(); ++ fileio.RunPrimeShellScript(m_occData); ++ m_tetData.total_time = tetMeshDuration.time(); ++ tetMeshDuration.stop(); ++ ++ /*Now that the shell script has been used, Read the volumeMesh file */ ++ CGAL::Real_timer fileReaderTime; ++ fileReaderTime.start(); ++ int ret_1 = fileio.ReadVolumeMesh( ++ m_tetData, m_occData, foundDiscardedFaces); // ReadPrimeData(f , m_tetData.pos, m_tetData.connectM , ~m_tetData.connectB , m_tetData.colors ) ++ m_dPrimeFileIODuration += fileReaderTime.time(); ++ fileReaderTime.stop(); ++ if (!ret_1) ++ { ++ std::cout << "failed to read the Volume mesh" << std::endl; ++ return false; ++ } ++ ++ /*Check whether discarderd faces are there */ ++ if (foundDiscardedFaces) ++ { ++ m_iTetmesherWarningCode = cm2::tetramesh_iso::mesher::data_type::CM2_FACE_DISCARDED; ++ m_occData->addMsg("found discarded faces after prime volume meshing"); ++ } ++ ++ /*Updating the shape qualities feature*/ ++ updateShapeQualities(); ++ ++ /*Updating the ancestors and neighbours features */ ++ updateAncestorsAndNeighbours(); + +- // you can use this to check that the tet mesh data have been properly transferred back +- if (m_occData->isAddDebugInfoFlag() >= 4) ++ /*Filling the connectB alternative way*/ ++ m_tetData.connectB.clear(); ++ int ret2 = cm2::meshtools::get_colors_boundaries(m_tetData.connectM, m_tetData.neighbors, m_tetData.colors, cm2::element_type::CM2_TETRA4, true, ++ m_tetData.connectB); ++ ++ if (ret2 != 0) + { ++ m_occData->addMsg("get_mesh_boundaries : The " + std::to_string(ret2) + "-th argument had an illegal value"); ++ } ++ ++ if (m_occData->isAddDebugInfoFlag() >= 5) ++ { ++ /*generating output for the tet mesh */ + std::stringstream ss; +- ss << m_occData->getDebugOutputPath() << "/" << getBaseName() << ".tetMesh" +- << ".vtk"; +- m_occData->addMsg("Writing vtk debug file: " + ss.str()); ++ ss << m_occData->getDebugOutputPath() << "/debug.prime.tetMesh." << unique_name << ".vtk"; ++ m_occData->addMsg("Writing vtk debug file for volume mesh : " + ss.str()); + cm2::meshtools::vtk_output(ss.str().c_str(), m_tetData.pos, m_tetData.connectM, cm2::element_type::CM2_TETRA4); ++ ++ /*generating output for the boundary mesh */ ++ std::stringstream ss_; ++ ss_ << m_occData->getDebugOutputPath() << "/debug.prime.boundaryMesh." << unique_name << ".vtk"; ++ m_occData->addMsg("Writing vtk debug file for boundary mesh : " + ss_.str()); ++ cm2::meshtools::vtk_output(ss_.str().c_str(), m_tetData.pos, m_tetData.connectB, cm2::element_type::CM2_FACET3); ++ ++ std::stringstream ss3; ++ ss3 << m_occData->getDebugOutputPath() << "/debug.prime.tetMesh." << unique_name << ".bdf"; ++ cm2::IntVec fe_types; // The types of element stored in each block ++ cm2::UIntVec xConnect; // The block indices. The i-th block in connect starts at xConnect[i] and ends at xConnect[i+1] ++ fe_types.push_back(cm2::element_type::CM2_TETRA4); ++ xConnect.push_back(0); ++ xConnect.push_back((int)m_tetData.connectM.cols()); ++ ++ cm2::meshtools::NASTRAN_output(ss3.str().c_str(), m_tetData.pos, m_tetData.connectM, xConnect, fe_types, m_tetData.colors); + } ++ ++ return true; + } +\ No newline at end of file diff --git a/git_diff_output/PrimeConstructionTet3D.h.gitdiff.txt b/git_diff_output/PrimeConstructionTet3D.h.gitdiff.txt new file mode 100644 index 00000000..1d883e80 --- /dev/null +++ b/git_diff_output/PrimeConstructionTet3D.h.gitdiff.txt @@ -0,0 +1,21 @@ +diff --git a/mesh/PrimeConstructionTet3D.h b/mesh/PrimeConstructionTet3D.h +index 11eadc6..ee02c44 100644 +--- a/mesh/PrimeConstructionTet3D.h ++++ b/mesh/PrimeConstructionTet3D.h +@@ -22,7 +22,15 @@ class PrimeConstructionTet3D : public Cm2ConstructionTet3D + protected: + virtual bool createTetMesh(cm2::intersect_t3::mesher::data_type &dataAllRemeshed) override; + ++ virtual double getAverageCellQuality() override { return m_dAverageCellQuality; } ++ virtual double getWorstCellQuality() override { return m_dWorstCellQuality; } ++ ++ void updateShapeQualities(); ++ void updateAncestorsAndNeighbours(); ++ + private: ++ double m_dAverageCellQuality; ++ double m_dWorstCellQuality; + }; + + #endif +\ No newline at end of file diff --git a/git_diff_output/PrimeFileIO.cpp.gitdiff.txt b/git_diff_output/PrimeFileIO.cpp.gitdiff.txt new file mode 100644 index 00000000..4b12d2ce --- /dev/null +++ b/git_diff_output/PrimeFileIO.cpp.gitdiff.txt @@ -0,0 +1,1054 @@ +diff --git a/mesh/PrimeFileIO.cpp b/mesh/PrimeFileIO.cpp +new file mode 100644 +index 0000000..95d076c +--- /dev/null ++++ b/mesh/PrimeFileIO.cpp +@@ -0,0 +1,1047 @@ ++#include "PrimeFileIO.h" ++#include ++#include ++ ++//#define EOF -1 ++#define MAX_NAME_LENGTH 1024 ++#if USE_INT64 ++#if _NT ++#define PRIME_ELM_TYPE long long ++#else ++#define PRIME_ELM_TYPE long ++#endif ++#else ++#define PRIME_ELM_TYPE int ++#endif ++ ++/* RCELL=3 then LCELL=4 ++ ++ | ++ | ++ *1 ++ /| \ ++ / | \ ++ | \ ++ / |3 \ 0 ++ *---------*--- ++ / / _- ++ / _- ++ / / - ++ *2 ++ ++ CM2_TETRA4 ++ ++ F0 = {1 2 3} ++ F1 = {2 0 3} ++ F2 = {1 3 0} ++ F3 = {2 1 0} ++ ++*/ ++#define RCELL 3 ++#define LCELL 4 ++ ++#define NULLP(p) ((p) == NULL) ++ ++PrimeFileIO::PrimeFileIO(Cm2Construction3D *meshConstruction) ++ : m_meshConstruction(meshConstruction) ++{ ++ // init to zero ++ m_numberOfNodes = 0; ++ m_numberOfEdges = 0; ++ m_numberOfCells = 0; ++ m_numberOfFaces = 0; ++} ++ ++void PrimeFileIO::writeBoundaryMesh(const cm2::intersect_t3::mesher::data_type &dataAllRemeshed) ++{ ++ /*std::string unique_name = m_meshConstruction->occData()->getOriginalFileBaseName() ++ + "_" + std::to_string(m_meshConstruction->uniqueBaseIdentifier());*/ ++ ++ /*Name the boundaryMeshFile & volumeMeshFile */ ++ std::string path = m_meshConstruction->occData()->getDebugOutputPath(); // /local/data/singleBox_/mesh1 ++ m_boundaryMeshFileName = "boundaryMesh_" + std::to_string(m_meshConstruction->uniqueBaseIdentifier()) + "_toPrime" + ".cas"; ++ ++ FILE *fw = fopen((primeFolderPath() + "/" + m_boundaryMeshFileName).c_str(), "w"); ++ WritePrimeData(fw, dataAllRemeshed); ++ ++ int checkBoundaryFile = access((primeFolderPath() + "/" + m_boundaryMeshFileName).c_str(), F_OK); ++ if (checkBoundaryFile == -1) ++ { ++ m_meshConstruction->occData()->addMsg("The Boundary Mesh Prime File do not exists", CADErrorHandler::TetMeshDidNotWork); ++ } ++} ++ ++int PrimeFileIO::ReadVolumeMesh(cm2::tetramesh_iso::mesher::data_type &tetData, std::shared_ptr m_occData, ++ bool &foundDiscardedFaces) ++{ ++ std::string path = m_meshConstruction->occData()->getDebugOutputPath(); ++ m_volumeMeshFileName = "volumeMesh_" + std::to_string(m_meshConstruction->uniqueBaseIdentifier()) + "_fromPrime.pmdat"; ++ ++ FILE *fVol = fopen((primeFolderPath() + "/" + m_volumeMeshFileName).c_str(), "r"); ++ int checkVolumeFile = access((primeFolderPath() + "/" + m_volumeMeshFileName).c_str(), F_OK); ++ if (checkVolumeFile == -1) ++ { ++ m_meshConstruction->occData()->addMsg("The Volume Mesh Prime File do not exists", CADErrorHandler::TetMeshDidNotWork); ++ return 0; ++ } ++ ReadPrimeData(fVol, tetData, m_occData, foundDiscardedFaces); ++ ++ if (m_occData->isAddDebugInfoFlag() >= 5) ++ { ++ /*Debug file to view the connectB matrix*/ ++ std::string debug_file = primeFolderPath() + "/remesherData_" + std::to_string(m_meshConstruction->uniqueBaseIdentifier()) + ".dat"; ++ debug_file = m_occData->getDebugOutputPath() + "/afterConnectBFilled.debugFile." + ".dat"; ++ tetData.save(debug_file.c_str()); ++ } ++ ++ return 1; ++} ++ ++void PrimeFileIO::RunPrimeShellScript(std::shared_ptr m_occData) ++{ ++ std::string command_name = "sh prime/runPrimeImage_" + std::to_string(m_meshConstruction->uniqueBaseIdentifier()) + ".sh"; ++ int returnValue = std::system(command_name.c_str()); ++ if (m_occData->isAddDebugInfoFlag() >= 5) ++ m_occData->addMsg("########################################## The prime mesher returned status: " + std::to_string(returnValue)); ++} ++ ++std::string PrimeFileIO::primeFolderPath() ++{ ++ // here you can add the "prime" subfolder logic, ++ // and when you call this function in all places where you require the "path" in which the prime files are stored, ++ // then we can easy change this path to whatever we like and it will still work. ++ /*create a prime directory to store all the debug file in it*/ ++ int ret_d = CreateDirectory("prime"); ++ if (ret_d) ++ std::cout << "########################################## the prime debug directory has been successfully created -> " << std::endl; ++ ++ CreateDirectory("prime"); ++ ++ std::string prime_path = m_meshConstruction->occData()->getDebugOutputPath() + "/prime"; ++ ++ return prime_path; ++} ++ ++std::string PrimeFileIO::dockerWorkDir() ++{ ++ if (const char *used_dood_env = std::getenv("USE_DOOD")) // Docker outside of Docker ++ { ++ bool bUseDood; ++ std::stringstream ss(used_dood_env); ++ ss >> std::boolalpha >> bUseDood; ++ if (bUseDood) ++ return m_meshConstruction->occData()->getAbsoluteDebugOutputPath() + "/prime"; ++ } ++ ++ return "/local/workdir"; ++} ++ ++bool PrimeFileIO::isDOOD() ++{ ++ // returns true when we are running a Docker outside docker environment ++ bool bUseDood = false; ++ if (const char *used_dood_env = std::getenv("USE_DOOD")) // Docker outside of Docker ++ { ++ ++ std::stringstream ss(used_dood_env); ++ ss >> std::boolalpha >> bUseDood; ++ } ++ ++ return bUseDood; ++} ++ ++bool PrimeFileIO::CreateDirectory(const std::string &dirName) ++{ ++ std::error_code err; ++ if (!std::filesystem::create_directories(dirName, err)) ++ { ++ if (std::filesystem::exists(dirName)) ++ { ++ return true; // the folder probably already existed ++ } ++ ++ std::cout << "createDirectory: failed to create [" << dirName.c_str() << "], err:" << err.message().c_str() << std::endl; ++ return false; ++ } ++ ++ return true; ++} ++ ++/*FlushString*/ ++void PrimeFileIO::FlushString(FILE *f) ++{ ++ int i; ++ /*TGEnv env = m_model->GetTGEnv();*/ ++ ++ while ((i = getc(f)) != EOF) ++ { ++ if ((char)i == '"') ++ return; ++ else if ((char)i == '\\') ++ if (getc(f) == EOF) ++ break; ++ } ++ ++ return; ++} ++ ++/*ReadStringLarge*/ ++char *PrimeFileIO::ReadStringLarge(FILE *f, char *token, int *max_len) ++{ ++ /*TGEnv env = m_model->GetTGEnv();*/ ++ int curr_len = 0; ++ int i; ++ ++ while ((i = getc(f)) != EOF) ++ { ++ if (!NULLP(max_len) && (curr_len == *max_len)) ++ { ++ *max_len = 2 * (*max_len); ++ token = (char *)malloc((*max_len) * sizeof(char)); ++ } ++ if ((char)i == '"') ++ { ++ token[curr_len] = '\0'; ++ return token; ++ } ++ if ((char)i == '\\' && getc(f) == EOF) ++ { ++ break; ++ } ++ token[curr_len] = (char)i; ++ curr_len++; ++ } ++ // how to error out things ++ // EOF_Error(env); ++ return token; ++} ++ ++/*ReadString*/ ++void PrimeFileIO::ReadString(FILE *f, char *token) ++{ ++ /*TGEnv env = m_model->GetTGEnv();*/ ++ int i; ++ ++ while ((i = getc(f)) != EOF) ++ { ++ if ((char)i == '"') ++ { ++ *token = '\0'; ++ return; ++ } ++ if ((char)i == '\\' && getc(f) == EOF) ++ { ++ break; ++ } ++ *token = (char)i; ++ token++; ++ } ++ // EOF_Error(env); ++ return; ++} ++ ++/*ReadToken*/ ++void PrimeFileIO::ReadToken(FILE *f, char *token) ++{ ++ int i; ++ while ((i = getc(f)) != EOF) ++ { ++ switch ((char)i) ++ { ++ case '(': ++ case ')': ++ *token = '\0'; ++ ungetc((char)i, f); ++ return; ++ case ' ': ++ *token = '\0'; ++ return; ++ default: ++ *token = (char)i; ++ token++; ++ break; ++ } ++ } ++ return; ++} ++ ++/*ReadNextToken*/ ++char *PrimeFileIO::ReadNextToken(FILE *f, char *token, int *max_len) ++{ ++ int i; ++ // Assert(m_model->GetTGEnv(), NULLP(max_len) || (*max_len) > 0); ++ while ((i = getc(f)) != EOF) ++ { ++ switch ((char)i) ++ { ++ case ' ': ++ break; ++ case '(': ++ case ')': ++ token[0] = (char)i; ++ token[1] = '\0'; ++ return token; ++ case EOF: ++ token[0] = '\0'; ++ return token; ++ case '.': ++ break; ++ case '\'': ++ break; ++ case '"': ++ if (!NULLP(max_len) && *max_len > 0) ++ { ++ return ReadStringLarge(f, token, max_len); ++ } ++ else ++ { ++ ReadString(f, token); ++ return token; ++ } ++ default: ++ if (isprint((char)i)) ++ { ++ token[0] = (char)i; ++ ReadToken(f, token + 1); ++ return token; ++ } ++ } ++ } ++ return token; ++ /* not reached */ ++} ++ ++bool PrimeFileIO::CheckNextChar(FILE *f, char c) ++{ ++ int i; ++ while ((i = getc(f)) != EOF) ++ { ++ if ((char)i == ' ' || (char)i == '.' || (char)i == '\n') ++ continue; ++ ungetc((char)i, f); ++ return ((char)i == c); ++ } ++ return false; ++} ++ ++bool PrimeFileIO::IsNextTokenString(FILE *f) { return CheckNextChar(f, '"'); } ++ ++bool PrimeFileIO::IsNextTokenListEnd(FILE *f) { return CheckNextChar(f, ')'); } ++ ++void PrimeFileIO::ReadNextToken(FILE *f, char *token) { ReadNextToken(f, token, NULL); } ++ ++void PrimeFileIO::NreadNextToken(FILE *f, char *token, int n) ++{ ++ for (int i = 0; i < n; i++) ++ { ++ ReadNextToken(f, token); ++ } ++} ++ ++char *PrimeFileIO::ReadNextTokenLarge(FILE *f, char *token, int *max_len) { return ReadNextToken(f, token, max_len); } ++ ++/* move file pointer just past next opening paren */ ++void PrimeFileIO::ReadStartList(FILE *f, char *token) ++{ ++ ReadNextToken(f, token); ++ ++ if (token[0] == '(') ++ return; ++ // else if (token[0] == EOF) ++ // EOF_Error(env); //error out things in onscale way ++ // else ++ // Error(env, "unexpected character read.\n"); ++} ++ ++/* move file pointer just past closing paren of current list */ ++void PrimeFileIO::FlushReadList(FILE *f) ++{ ++ // TGEnv env = m_model->GetTGEnv(); ++ int i; ++ ++ while ((i = getc(f)) != EOF) ++ { ++ if ((char)i == ')') ++ return; ++ else if ((char)i == '(') ++ FlushReadList(f); ++ else if ((char)i == '"') ++ FlushString(f); ++ } ++ // EOF_Error(env); ++ return; ++} ++ ++void PrimeFileIO::Cdr(FILE *f, char *token) ++{ ++ ReadNextToken(f, token); ++ if (token[0] == '(') ++ { ++ FlushReadList(f); ++ } ++ return; ++} ++ ++/* f format is 1 2 3 4)*/ ++void PrimeFileIO::ReadOpenedList(FILE *f, char *token, std::vector &list) ++{ ++ ReadNextToken(f, token); ++ while (token[0] != ')') ++ { ++ list.push_back(atoi(token)); ++ ReadNextToken(f, token); ++ } ++ ++ return; ++} ++ ++/* f format is str1 str2 str3)*/ ++void PrimeFileIO::ReadOpenedList(FILE *f, char *token, std::vector &list) ++{ ++ ReadNextToken(f, token); ++ while (token[0] != ')') ++ { ++ list.push_back(std::string(token)); ++ ReadNextToken(f, token); ++ } ++ ++ return; ++} ++ ++/* f format is 1.0 2.0 0.3 0.4)*/ ++void PrimeFileIO::ReadOpenedList(FILE *f, char *token, std::vector &list) ++{ ++ ReadNextToken(f, token); ++ while (token[0] != ')') ++ { ++ list.push_back((double)atof(token)); ++ ReadNextToken(f, token); ++ } ++ ++ return; ++} ++ ++double PrimeFileIO::ReadDouble(FILE *f) ++{ ++ // TGEnv env = m_model->GetTGEnv(); ++ ++ double val = 0; ++ // Prime_Protect_Read_Double(env, f, &val); ++ return val; ++} ++ ++int PrimeFileIO::ReadInt(FILE *f) ++{ ++ // TGEnv env = m_model->GetTGEnv(); ++ ++ int val = 0; ++ // Prime_Protect_Read_Dint(env, f, &val); ++ return val; ++} ++ ++bool PrimeFileIO::ReadNextTokenAndCheckStartList(FILE *f, char *token) ++{ ++ ReadNextToken(f, token); ++ if (token[0] == '(') ++ { ++ return true; ++ } ++ return false; ++} ++ ++/* f format is (1 2 3 4)*/ ++void PrimeFileIO::ReadList(FILE *f, char *token, std::vector &list) ++{ ++ if (!ReadNextTokenAndCheckStartList(f, token)) ++ return; ++ ReadOpenedList(f, token, list); ++} ++ ++/* f format is (1 2 3 4)*/ ++void PrimeFileIO::ReadList(FILE *f, char *token, std::vector &list) ++{ ++ if (!ReadNextTokenAndCheckStartList(f, token)) ++ return; ++ ReadOpenedList(f, token, list); ++} ++ ++/* f format is (1.0 2.0 0.3 0.4)*/ ++void PrimeFileIO::ReadList(FILE *f, char *token, std::vector &list) ++{ ++ if (!ReadNextTokenAndCheckStartList(f, token)) ++ return; ++ ReadOpenedList(f, token, list); ++} ++ ++static void fillConnectForCell(size_t iCell, bool right_cell, cm2::UIntMat &connectM, const cm2::UIntMat &facePrimeData, size_t iFace, ++ std::vector &cellCount) ++{ ++ ++ if (cellCount[iCell] == 0) ++ { ++ if (right_cell) ++ { ++ for (size_t j = 0; j < 3; j++) ++ { ++ connectM(j, iCell) = facePrimeData(j, iFace); ++ } ++ cellCount[iCell] = 3; ++ } ++ else ++ { ++ for (size_t j = 1; j <= 3; j++) ++ { ++ connectM(j, iCell) = facePrimeData(j - 1, iFace); ++ } ++ cellCount[iCell] = -3; ++ } ++ } ++ else if (cellCount[iCell] == 3) ++ { ++ for (size_t j = 0; j < 3; j++) ++ { ++ bool found = false; ++ for (size_t k = 0; k < 3; k++) ++ { ++ if (facePrimeData(j, iFace) == connectM(k, iCell)) ++ { ++ found = true; ++ break; ++ } ++ } ++ if (!found) ++ { ++ /*if (iCell == 0) ++ { ++ printf("alreay cell ids %d %d %d and new node %d\n", connectM(0, iCell), connectM(1, iCell), connectM(2, iCell), facePrimeData(j, ++ iFace)); ++ }*/ ++ connectM(3, iCell) = facePrimeData(j, iFace); ++ cellCount[iCell] = 4; ++ /*if (iCell == 0) ++ { ++ printf("alreay cell ids %d %d %d and new node %d\n", connectM(0, iCell), connectM(1, iCell), connectM(2, iCell), connectM(3, ++ iCell)); ++ }*/ ++ break; ++ } ++ } ++ } ++ else if (cellCount[iCell] == -3) ++ { ++ for (size_t j = 0; j < 3; j++) ++ { ++ bool found = false; ++ for (size_t k = 1; k <= 3; k++) ++ { ++ if (facePrimeData(j, iFace) == connectM(k, iCell)) ++ { ++ found = true; ++ break; ++ } ++ } ++ if (!found) ++ { ++ /*if (iCell == 0) ++ { ++ printf("alreay cell ids %d %d %d and new node %d\n", connectM(0, iCell), connectM(1, iCell), connectM(2, iCell), facePrimeData(j, ++ iFace)); ++ }*/ ++ connectM(0, iCell) = facePrimeData(j, iFace); ++ cellCount[iCell] = 4; ++ break; ++ } ++ } ++ } ++} ++ ++static void flushBinInts(FILE *f, int n, int size_of_bin_int, int *tmp_data) ++{ ++ for (int i = 0; i < n; i++) ++ { ++ int ret_ = fread(tmp_data, size_of_bin_int, 1, f); ++ std::ignore = ret_; ++ } ++} ++ ++static void flushBinDoubles(FILE *f, int n, int size_of_bin_double, double *tmp_data) ++{ ++ for (int i = 0; i < n; i++) ++ { ++ int ret_ = fread(tmp_data, size_of_bin_double, 1, f); ++ std::ignore = ret_; ++ } ++} ++ ++void PrimeFileIO::ReadStatshBinData(FILE *f, char *token, int size_of_bin_int, int size_of_bin_double) ++{ ++ NreadNextToken(f, token, 1); ++ ++ /*fscanf(f, "%d %d %s %d %d %d %d %d %d %d", ++ &k, <->id, lt->name, <->order, ++ <->klass, <->type, <->etype, <->ntv, ++ &curvature_data, &periodic_data);*/ ++ ++ NreadNextToken(f, token, 3); /*k, id, name*/ ++ int order; ++ int ret_ = fscanf(f, "%d", &order); ++ NreadNextToken(f, token, 3); /* <->klass, <->type, <->etype*/ ++ int ntv, curvature_data, periodic_data; ++ ret_ = fscanf(f, "%d %d %d", &ntv, &curvature_data, &periodic_data); ++ ++ FlushReadList(f); ++ NreadNextToken(f, token, 1); /* to read "(""*/ ++ ++ int *tmp_int_data = (int *)malloc(size_of_bin_int); ++ double *tmp_double_data = (double *)malloc(size_of_bin_double); ++ ++ flushBinInts(f, ntv, size_of_bin_int, tmp_int_data); ++ ++ /*reading twice is correct*/ ++ flushBinInts(f, ntv, size_of_bin_int, tmp_int_data); ++ int nn; ++ ret_ = fread(&nn, size_of_bin_int, 1, f); ++ ++ flushBinDoubles(f, 3 * nn, size_of_bin_double, tmp_double_data); ++ ++ if (curvature_data) ++ { ++ flushBinDoubles(f, nn, size_of_bin_double, tmp_double_data); ++ } ++ ++ flushBinInts(f, nn, size_of_bin_int, tmp_int_data); ++ ++ int nel; ++ ret_ = fread(&nel, size_of_bin_int, 1, f); ++ flushBinInts(f, nel, size_of_bin_int, tmp_int_data); ++ ++ int ne; ++ ret_ = fread(&ne, size_of_bin_int, 1, f); ++ flushBinInts(f, ne, size_of_bin_int, tmp_int_data); ++ ++ if (order == 2 && periodic_data) /* 2 == ENTITY_FACE */ ++ { ++ flushBinInts(f, ne, size_of_bin_int, tmp_int_data); ++ } ++ FlushReadList(f); ++ free(tmp_int_data); ++ free(tmp_double_data); ++ std::ignore = ret_; ++} ++ ++int PrimeFileIO::ReadPrimeData(FILE *f, cm2::tetramesh_iso::mesher::data_type &tetData, std::shared_ptr m_occData, ++ bool &foundDiscardedFaces) ++{ ++ // reading the pmdat file f and populating the data to empty tetData->cm2 structure ++ ++ char token[MAX_NAME_LENGTH]; ++ std::string line; ++ cm2::UIntMat facePrimeData; ++ int ret_; ++ m_numberOfBoundaryFaces = 0; ++ int sizeof_prime_real = -1; ++ int sizeof_prime_elm_index = -1; ++ ++ int sectionid; ++ ++ ReadNextToken(f, token); ++ while (token[0] == '(') ++ { ++ ++ NreadNextToken(f, token, 1); ++ sectionid = atoi(token); ++ bool binary = false; ++ ++ if (sectionid > 1000) ++ { ++ binary = true; ++ // printf("we reading binary...\n"); ++ sectionid = sectionid % 1000; ++ } ++ if (sectionid == 10) ++ { ++ NreadNextToken(f, token, 2); ++ int primeColorId = std::stoi(token, 0, 16); ++ ++ if (primeColorId == 0) ++ { ++ NreadNextToken(f, token, 2); ++ m_numberOfNodes = std::stoi(token, 0, 16); ++ FlushReadList(f); ++ ++ tetData.pos.reserve(3, m_numberOfNodes); ++ printf("the number of node : %d\n", m_numberOfNodes); ++ } ++ else ++ { ++ /*CODE FOR ACCESSING NODE THREAD DETAILS*/ ++ cm2::DoubleVec coord(3); ++ threadInfo.id = primeColorId; ++ ++ ret_ = fscanf(f, "%x%x%d%d", &threadInfo.start, &threadInfo.end, &threadInfo.type, &threadInfo.etype); ++ nodeInfoVector.push_back(threadInfo); ++ ++ FlushReadList(f); ++ printf("node->id : %d node->start : %d node->end : %d \n", threadInfo.id, threadInfo.start, threadInfo.end); ++ ++ if (ReadNextTokenAndCheckStartList(f, token)) ++ { ++ for (unsigned int i = threadInfo.start; i <= threadInfo.end; i++) ++ { ++ if (!binary) ++ { ++ ret_ = fscanf(f, "%lf%lf%lf", coord.data(), coord.data() + 1, coord.data() + 2); // look into google for assert ++ } ++ else ++ { ++ ret_ = fread(coord.data(), sizeof_prime_real, 3, f); ++ } ++ ++ tetData.pos.push_back(coord); ++ } ++ ++ FlushReadList(f); ++ } ++ } ++ } ++ else if (sectionid == 11) ++ { ++ NreadNextToken(f, token, 2); ++ ++ if (std::stoi(token, 0, 16) == 0) ++ { ++ ++ NreadNextToken(f, token, 2); ++ m_numberOfEdges = std::stoi(token, 0, 16); ++ FlushReadList(f); ++ printf("the number of edges : %d\n", m_numberOfEdges); ++ } ++ } ++ else if (sectionid == 12) ++ { ++ NreadNextToken(f, token, 2); ++ ++ if (std::stoi(token, 0, 16) == 0) ++ { ++ NreadNextToken(f, token, 2); ++ m_numberOfCells = std::stoi(token, 0, 16); ++ ++ FlushReadList(f); ++ printf("the number of cells : %d\n", m_numberOfCells); ++ } ++ else ++ { ++ /*CODE FOR ACCESSING CELL THREAD DETAILS*/ ++ ++ threadInfo.id = std::stoi(token, 0, 16); ++ ++ ret_ = fscanf(f, "%x%x%d%d", &threadInfo.start, &threadInfo.end, &threadInfo.type, &threadInfo.etype); ++ cellInfoVector.push_back(threadInfo); ++ printf("the cell id is %d\n", threadInfo.id); ++ ++ for (unsigned int i = threadInfo.start; i <= threadInfo.end; i++) ++ { ++ tetData.colors.push_back(threadInfo.id); ++ } ++ FlushReadList(f); ++ } ++ } ++ else if (sectionid == 13) ++ { ++ NreadNextToken(f, token, 2); ++ ++ if (std::stoi(token, 0, 16) == 0) ++ { ++ ++ NreadNextToken(f, token, 2); ++ m_numberOfFaces = std::stoi(token, 0, 16); ++ ++ FlushReadList(f); ++ facePrimeData.reserve(5, m_numberOfFaces); ++ printf("the number of faces : %d\n", m_numberOfFaces); ++ } ++ else ++ { ++ /*CODE FOR ACCESSING FACE THREAD DETAILS*/ ++ ++ cm2::UIntVec faceData(5); ++ threadInfo.id = std::stoi(token, 0, 16); ++ ++ ret_ = fscanf(f, "%x%x%d%d", &threadInfo.start, &threadInfo.end, &threadInfo.type, &threadInfo.etype); ++ faceInfoVector.push_back(threadInfo); ++ FlushReadList(f); ++ ++ ReadNextToken(f, token); ++ for (unsigned int i = threadInfo.start; i <= threadInfo.end; i++) ++ { ++ if (!binary) ++ { ++ ret_ = fscanf(f, "%x%x%x%x%x", faceData.data(), faceData.data() + 1, faceData.data() + 2, faceData.data() + 3, ++ faceData.data() + 4); ++ } ++ else ++ { ++ for (unsigned int k = 0; k < 5; k++) ++ { ++ ret_ = fread(faceData.data() + k, sizeof_prime_elm_index, 1, f); // 12th element of arrray ++ } ++ } ++ ++ for (unsigned int k = 0; k < 5; k++) ++ { ++ if (faceData[k] == 0) ++ { ++ faceData[k] = m_numberOfCells + 10; ++ } ++ else ++ { ++ faceData[k] = faceData[k] - 1; ++ } ++ } ++ for (unsigned int k = 0; k < 5; k++) ++ { ++ if (faceData[k] > m_numberOfCells + 10 && faceData[k] > m_numberOfNodes) ++ { ++ printf("We have a problem with data read at %d\n", i); ++ } ++ } ++ facePrimeData.push_back(faceData); ++ if (threadInfo.type > 2) ++ { ++ m_numberOfBoundaryFaces++; ++ } ++ } ++ ++ FlushReadList(f); ++ } ++ } ++ else if (sectionid == 4) ++ { ++ NreadNextToken(f, token, 11); ++ sizeof_prime_real = atoi(token); ++ NreadNextToken(f, token, 2); ++ sizeof_prime_elm_index = atoi(token); ++ ++ printf(" the size of prime_real is : %d, and the size of prime_elm_index : %d", sizeof_prime_real, sizeof_prime_elm_index); ++ FlushReadList(f); ++ } ++ else if (sectionid == 71) ++ { ++ if (binary) ++ { ++ ReadStatshBinData(f, token, sizeof_prime_elm_index, sizeof_prime_real); ++ } ++ /*if not binary, FlushReadList at end will take care of the stash data read */ ++ } ++ /*else if(sectionid == 60) ++ { ++ float min_h, max_h, default1, default2; ++ NreadNextToken(f, token, 3); ++ if(token == "size-func/global-params") ++ { ++ NreadNextToken(f,token,1); ++ fscanf(f,"%f%f%f%f", &min_h , &max_h, &default1, &default2); ++ printf(" min_h : %f max_h : %f ", min_h, max_h); ++ } ++ else ++ { ++ FlushReadList(f); ++ } ++ }*/ ++ ++ FlushReadList(f); ++ ReadNextToken(f, token); ++ } ++ ++ /*Creating connectM & connectB */ ++ cm2::UIntMat connectM(4, m_numberOfCells); ++ cm2::UIntMat connectB(3, m_numberOfBoundaryFaces); ++ ++ /*Creating a cellCount Vector and intiating all to zero */ ++ std::vector cellCount(m_numberOfCells, 0); ++ ++ /*Debug prints*/ ++ cout << " number of faces : " << m_numberOfFaces << " number of cells : " << m_numberOfCells << " number of nodes : " << m_numberOfNodes ++ << " number of boundary faces : " << m_numberOfBoundaryFaces << endl; ++ /* ++ std::string debug_file = occData->getDebugOutputPath() + "/afterConnectBFilled" + ".dat"; ++ tetData.save(debug_file.c_str()); ++ FILE* faceDataF = fopen( (occData->getDebugOutputPath() + "/" + "face_data.txt").c_str() , "w"); ++ for (unsigned int i = 0; i < m_numberOfFaces; i++) ++ { ++ fprintf(faceDataF, "face data %d %d %d %d %d\n", (int)facePrimeData(0,i), (int)facePrimeData(1,i), (int)facePrimeData(2,i), ++ (int)facePrimeData(3,i), (int)facePrimeData(4,i)); ++ } ++ fprintf(faceDataF, "done\n"); ++ */ ++ ++ foundDiscardedFaces = false; ++ ++ /*CURRENT CODE FOR CONNECT M >*/ ++ for (unsigned int i = 0; i < m_numberOfFaces; i++) ++ { ++ unsigned int iRCell = facePrimeData(RCELL, i); ++ unsigned int iLCell = facePrimeData(LCELL, i); ++ if (iRCell > m_numberOfCells && iLCell > m_numberOfCells) ++ { ++ foundDiscardedFaces = true; ++ continue; ++ } ++ if (iRCell < m_numberOfCells) ++ { ++ fillConnectForCell(iRCell, true, connectM, facePrimeData, i, cellCount); ++ } ++ if (iLCell < m_numberOfCells) ++ { ++ fillConnectForCell(iLCell, false, connectM, facePrimeData, i, cellCount); ++ } ++ } ++ ++ tetData.connectM.copy(connectM); ++ ++ /*Debug file to check the status of connect B and compare it with cm2 mesher*/ ++ if (m_occData->isAddDebugInfoFlag() >= 5) ++ { ++ std::string debug_file_M = m_occData->getDebugOutputPath() + "/afterConnectMFilled.debugFile" + ".dat"; ++ tetData.save(debug_file_M.c_str()); ++ } ++ ++ std::ignore = ret_; ++ return 1; ++} ++ ++void PrimeFileIO::WritePrimeData(FILE *fw, const cm2::intersect_t3::mesher::data_type &dataAllRemeshed) ++{ ++ /*WRITE CELLS AND EDGES*/ ++ int iN = (int)dataAllRemeshed.pos.cols(); ++ int iT = (int)dataAllRemeshed.connectM.cols(); ++ ++ /*COLOR INFORMATION PROCESSING */ ++ int iC = (int)dataAllRemeshed.colors.size(); ++ // printf( "the iC value is : %d & the iT value is : %d", iC, iT); //iC and iT remains the same and we can proceed ++ ++ /*map creation for reverse mapping triangle id's for specific colors*/ ++ std::map> color2section; ++ ++ /*the loop will populate the map*/ ++ for (int i = 0; i < iC; i++) ++ { ++ color2section[dataAllRemeshed.colors(i)].push_back(i); ++ } ++ ++ /*proposed id for node thread*/ ++ int node_id = color2section.size() + 1; ++ ++ /*check for proposed id to be unique*/ ++ while (color2section.find(node_id) != color2section.end()) ++ { ++ node_id++; ++ } ++ ++ /*writing them into the pmdat file*/ ++ unsigned int count = 1, vSize; ++ ++ /*PMDAT FILE*/ ++ fprintf(fw, "(10 (0 1 %x 0))\n(13 (0 1 %x 0))\n(12 (0 0 0 0))\n", iN, iT); ++ fprintf(fw, "(10 (%d 1 %x 2 3)\n(\n", node_id, iN); ++ for (int i = 0; i < iN; i++) ++ { ++ ++ fprintf(fw, "%f %f %f\n", dataAllRemeshed.pos(0, i), dataAllRemeshed.pos(1, i), dataAllRemeshed.pos(2, i)); ++ } ++ fprintf(fw, "))\n"); ++ ++ /*Writing individual sections for colors*/ ++ for (auto c2s = color2section.begin(); c2s != color2section.end(); c2s++) ++ { ++ ++ vSize = c2s->second.size(); ++ fprintf(fw, "(13 (%d %x %x 3 3)\n(\n", c2s->first + 1, count, count - 1 + vSize); ++ for (unsigned int i = 0; i < vSize; i++) ++ { ++ fprintf(fw, "%x %x %x 0 0\n", dataAllRemeshed.connectM(0, c2s->second[i]) + 1, dataAllRemeshed.connectM(1, c2s->second[i]) + 1, ++ dataAllRemeshed.connectM(2, c2s->second[i]) + 1); ++ } ++ fprintf(fw, "))\n"); ++ count += vSize; ++ } ++ ++ /*Defining the min_size , max_size and growth_rate */ ++ double min_size = m_meshConstruction->getMinEdgeLength(); ++ double max_size = m_meshConstruction->cm2TetmeshSettings().target_metric; ++ double growth_rate = 1 + m_meshConstruction->cm2TetmeshSettings().max_gradation; ++ ++ /*Appending them to the pmdat */ ++ fprintf(fw, "\n(60 (\n(size-func/global-params (%lf %lf %lf 2.0))\n ))\n", min_size, max_size, growth_rate); ++ ++ /*closing the file */ ++ fclose(fw); ++} ++ ++void PrimeFileIO::GenerateVolumePyFile() ++{ ++ std::stringstream ss; ++ ss << primeFolderPath() << "/generateVolume_" << m_meshConstruction->uniqueBaseIdentifier() << ".py"; ++ std::ofstream out(ss.str()); ++ // prime config finalize api: prime.finalize() ++ // push it once it is working for me.. ++ // It should be called in the end..of py script ++ ++ /*Import all the PRIME meshing functionality*/ ++ out << "import ansys.meshing.prime as prime" << std::endl; ++ out << "import PrimePyAnsysPrimeServer" << std::endl; ++ out << "import os\n" ++ << "model = prime.local_model()\n" ++ << "fileIO = prime.FileIO(model)" << std::endl; ++ ++ /*Read the boundary file and use the prime.AutoMesh()... to mesh it*/ ++ out << "fileIO.import_fluent_case(os.path.join(\"" << dockerWorkDir().c_str() << "\",\"" << m_boundaryMeshFileName.c_str() ++ << "\"), prime.ImportFluentCaseParams(model = model))" << std::endl; ++ out << "results = prime.AutoMesh(model=model).mesh(part_id=model.parts[0].id, automesh_params=prime.AutoMeshParams(model=model))" << std::endl; ++ ++ /*Write them into the pmdat file using prime.write_pmdat()... */ ++ out << "fileIO.write_pmdat(os.path.join(\"" << dockerWorkDir().c_str() << "\",\"" ++ << "volumeMesh_" << m_meshConstruction->uniqueBaseIdentifier() << "_fromPrime.pmdat" ++ << "\"), prime.FileWriteParams(model))" << std::endl; ++ ++ /*calling Prime.Finalize()*/ ++ out << "PrimePyAnsysPrimeServer.Finalize()" << std::endl; ++} ++ ++void PrimeFileIO::CreatePrimeShellScript() ++{ ++ ++ /* OLD CODE ++ std::stringstream ss; ++ ss << m_meshConstruction->occData()->getDebugOutputPath() << "/runPrimeImage_" << unique_name << ".sh"; ++ */ ++ ++ // NEW CODE ++ std::stringstream ss; ++ ss << primeFolderPath() << "/runPrimeImage_" << m_meshConstruction->uniqueBaseIdentifier() << ".sh"; ++ std::ofstream out(ss.str()); ++ std::string unique_name = ++ m_meshConstruction->occData()->getOriginalFileBaseName() + "_" + std::to_string(m_meshConstruction->uniqueBaseIdentifier()); ++ ++ out << "#!/bin/bash\n" << std::endl; ++ out << "# Run the Docker command inside the container" << std::endl; ++ ++ out << "docker run --rm --name running_prime_container_" << unique_name << " -v " << m_meshConstruction->occData()->getAbsoluteDebugOutputPath() ++ << "/prime" ++ << ":" ++ << "/local/workdir"; ++ ++ // if PRIME DOCKER is running outside the DOCKER ENV... ++ if (isDOOD()) ++ out << " --volumes-from Linux "; ++ ++ // out << " -e ANSYSLMD_LICENSE_FILE=1055@milflexlm1.ansys.com" ++ out << " -e ANSYS_ELASTIC_CLS=M3HAH4PTNKVK:623041" ++ << " --entrypoint /prime/meshing/Prime/runPrime.sh local_prime " << dockerWorkDir() << "/generateVolume_" ++ << m_meshConstruction->uniqueBaseIdentifier() << ".py"; ++ ++ out << " > " << m_meshConstruction->occData()->getAbsoluteDebugOutputPath() << "/prime/primeLog.txt 2>&1"; ++ out << std::endl; ++} ++ ++PrimeFileIO::~PrimeFileIO() {} +\ No newline at end of file diff --git a/git_diff_output/PrimeFileIO.h.gitdiff.txt b/git_diff_output/PrimeFileIO.h.gitdiff.txt new file mode 100644 index 00000000..a70ab16c --- /dev/null +++ b/git_diff_output/PrimeFileIO.h.gitdiff.txt @@ -0,0 +1,102 @@ +diff --git a/mesh/PrimeFileIO.h b/mesh/PrimeFileIO.h +new file mode 100644 +index 0000000..190aebf +--- /dev/null ++++ b/mesh/PrimeFileIO.h +@@ -0,0 +1,95 @@ ++#ifndef PRIME_FILEIO_H ++#define PRIME_FILEIO_H ++ ++#include "Cm2Construction3D.h" ++#include "Cm2ConstructionTet3D.h" ++ ++////////////////////////////////////////////////////////////////////////////////////////////////////////////// ++// PrimeFileIO ++// Utility Functions for PrimeConstructionTet3D ++////////////////////////////////////////////////////////////////////////////////////////////////////////////// ++ ++class PrimeFileIO ++{ ++ private: ++ unsigned int m_numberOfNodes, m_numberOfEdges, m_numberOfCells, m_numberOfFaces, m_numberOfBoundaryFaces; ++ ++ struct threadInfo ++ { ++ int id; ++ unsigned int start, end; ++ int type, etype; ++ } threadInfo; ++ ++ std::vector nodeInfoVector, faceInfoVector, cellInfoVector; ++ ++ public: ++ PrimeFileIO(Cm2Construction3D *meshConstruction); ++ virtual ~PrimeFileIO(); ++ ++ void writeBoundaryMesh(const cm2::intersect_t3::mesher::data_type &dataAllRemeshed); ++ int ReadVolumeMesh(cm2::tetramesh_iso::mesher::data_type &tetData, std::shared_ptr m_occData, bool &foundDiscardedFaces); ++ ++ // void GenerateVolumePyFile(FILE* fPy, std::string& volumeMeshFileName); ++ void GenerateVolumePyFile(); ++ void CreatePrimeShellScript(); ++ void RunPrimeShellScript(std::shared_ptr m_occData); ++ bool CreateDirectory(const std::string &dirName); ++ ++ // public for the time being, should be moved in a similar manner into the protected region ++ // as done with the writeBoundaryMesh ++ // int ReadPrimeData(FILE* f, cm2::tetramesh_iso::mesher::data_type& tetData, std::shared_ptr m_occData, bool& ++ // foundDiscardedFaces); ++ int ReadPrimeData(FILE *f, cm2::tetramesh_iso::mesher::data_type &tetData, std::shared_ptr m_occData, ++ bool &foundDiscardedFaces); ++ ++ protected: ++ std::string primeFolderPath(); ++ ++ void FlushString(FILE *f); ++ char *ReadStringLarge(FILE *f, char *token, int *max_len); ++ void ReadString(FILE *f, char *token); ++ void ReadToken(FILE *f, char *token); ++ ++ bool CheckNextChar(FILE *f, char c); ++ bool IsNextTokenString(FILE *f); ++ bool IsNextTokenListEnd(FILE *f); ++ ++ char *ReadNextToken(FILE *f, char *token, int *max_len); ++ void ReadNextToken(FILE *f, char *token); ++ void NreadNextToken(FILE *f, char *token, int n); ++ ++ char *ReadNextTokenLarge(FILE *f, char *token, int *max_len); ++ void ReadStartList(FILE *f, char *token); ++ void FlushReadList(FILE *f); ++ ++ void Cdr(FILE *f, char *token); ++ bool ReadNextTokenAndCheckStartList(FILE *f, char *token); ++ void ReadOpenedList(FILE *f, char *token, std::vector &list); ++ void ReadOpenedList(FILE *f, char *token, std::vector &list); ++ void ReadOpenedList(FILE *f, char *token, std::vector &list); ++ double ReadDouble(FILE *f); ++ int ReadInt(FILE *f); ++ ++ void ReadList(FILE *f, char *token, std::vector &list); ++ void ReadList(FILE *f, char *token, std::vector &list); ++ void ReadList(FILE *f, char *token, std::vector &list); ++ ++ void ReadStatshBinData(FILE *f, char *token, int size_of_bin_int, int size_of_bin_double); ++ ++ void WritePrimeData(FILE *fw, const cm2::intersect_t3::mesher::data_type &dataAllRemeshed); ++ // void fileOpen(FILE* fopen, ) ++ ++ /*Create a getter and setter for nodeInfoVector and nodeDataVector vectors..*/ ++ ++ private: ++ Cm2Construction3D *m_meshConstruction; ++ ++ std::string m_boundaryMeshFileName = ""; ++ std::string m_volumeMeshFileName = ""; ++ ++ bool isDOOD(); ++ std::string dockerWorkDir(); ++}; ++ ++#endif +\ No newline at end of file diff --git a/git_diff_output/diff_output.txt b/git_diff_output/diff_output.txt new file mode 100644 index 00000000..1c7479ec --- /dev/null +++ b/git_diff_output/diff_output.txt @@ -0,0 +1,33 @@ +diff --git a/sample_code.cpp b/sample_code.cpp +index 1cfa8b8..3e6c7bd 100644 +--- a/sample_code.cpp ++++ b/sample_code.cpp +@@ -8,7 +8,7 @@ int functionA() + int num = 5; + while (num < 10) { + std::cout << num << std::endl; +- num++; ++ num--; + } + return 0; + } +@@ -16,7 +16,7 @@ int functionA() + int sum(std::list lst) + { + int total = 0; +- for (auto it = lst.begin(); it != lst.end(); it++) ++ for (auto it = lst.begin(); it != --lst.end(); it++) + { + total += *it; + } +@@ -28,8 +28,8 @@ double average(int arr[], int size) { + for (int i = 0; i < size; i++) { + sum += arr[i]; + } +- int num = size; +- return sum / double(num); ++ int num = rand() % 10 + 1; ++ return sum / num; + } + + int main() { diff --git a/global_cplus_context.py b/global_cplus_context.py new file mode 100644 index 00000000..0e4c59e6 --- /dev/null +++ b/global_cplus_context.py @@ -0,0 +1,143 @@ +""" +This example script demonstrates how to use the OpenAI chat API. + +GPT-4 model: +https://platform.openai.com/docs/models/gpt-4 + +Chat completion API: +https://platform.openai.com/docs/guides/chat + +""" + +import secrets +import os +import sys +import openai + +THIS_DIR = os.path.abspath(os.path.dirname(__file__)) +DST_FOLDER_OUTPUT = THIS_DIR + '/git_diff_output/' + +if not os.environ.get('TOKEN'): + print('TOKEN environment variable is not defined.') + sys.exit(0) + +# CSEBU token +token = os.environ.get('TOKEN') + +openai.api_key = token + + +prompt_query1 = """" + Review the sample_code for logical errors and only comment on these and don't output any readability suggestions. Don't comment on anything else. + Add the line number where you found the error + """ + +os.chdir(DST_FOLDER_OUTPUT) +file_list = os.listdir(os.curdir) + +# file_list = ['PrimeFileIO.cpp.gitdiff.txt'] +MAX_FILE_SIZE = 8000 # 8000 + +def generate_prompt(prompt_query: str, file: str) -> str: + prompt = prompt_query + + prompt += "sample_code:" + with open(file, 'r') as file: + data = file.read().replace('\n', '') + prompt += data + + #prompt += "some basic rules to check:" + #prompt += "comments" + #prompt += "public in front of constructor" + + return prompt + +def call_openai(prompt: str): + response = openai.ChatCompletion.create( + model="gpt-4", + messages=[ + {"role": "system", "content": "You are a c and c++ reviewer giving very short answers."}, + {"role": "user", "content": prompt}, + # {"role": "assistant", "content": init_response}, + # {"role": "user", "content": elab} + ] + ) + + text = response['choices'][0].message.content + print(text) + print("\n") + + +print("---------------------------------------- LOGICAL ISSUES: ----------------------------------------") + +index = 0 +for item in file_list: + if not os.path.isfile(item): + continue + index = index + 1 + #if index > 1: + # continue + + file_size = os.path.getsize(item) + print("----------------------------------------------------------------------------------------------------") + print(f'{item}: {file_size}') + + substring = ".h" + if substring in item: + print(f'ChatGPT cannot analyse logical issues in Header files') + continue + + source_file = DST_FOLDER_OUTPUT + item + + list_small_files = list() + + if os.stat(source_file).st_size > MAX_FILE_SIZE: + print(f'{item}: BIG FILE') + lines_per_file = 50 + smallfile = None + split_file = source_file + closeOnNextOccation = False + smallFileClosed = False + base_line_count = 0 + with open(split_file) as bigfile: + for lineno, line in enumerate(bigfile): + lenline = len(line) + #print(f'{lenline} - {base_line_count}------- {lineno}: {line}') + if base_line_count % lines_per_file == 0 or closeOnNextOccation: + closeOnNextOccation = True + if not ("+}" in line and lenline == 3) and smallfile: + base_line_count = base_line_count + 1 + smallfile.write(line) + continue + closeOnNextOccation = False + base_line_count = 0 + if smallfile: + smallfile.write(line) # add last line + smallfile.close() + smallFileClosed = True + small_filename = item + '_split_file_{}.txt'.format(lineno + lines_per_file) + smallfile = open(small_filename, "w") + #chatGPTInstruction = "chatGPTInstruction:" + str(lineno) + #smallfile.write(chatGPTInstruction) + list_small_files.append(small_filename) + if not smallFileClosed: + smallfile.write(line) + base_line_count = base_line_count + 1 + if smallfile: + smallfile.close() + + elif os.stat(source_file).st_size == 0: + continue + + if len(list_small_files) == 0: + prompt = generate_prompt(prompt_query1, source_file) + call_openai(prompt) + else: + for small_source_file in list_small_files: + print(f'split_file {item}: {small_source_file}') + prompt = generate_prompt(prompt_query1, small_source_file) + call_openai(prompt) + # os.remove(small_source_file) + + + diff --git a/sample_code.cpp b/sample_code.cpp new file mode 100644 index 00000000..1cfa8b8e --- /dev/null +++ b/sample_code.cpp @@ -0,0 +1,49 @@ +"""sample code""" + +#include +#include + +int functionA() +{ + int num = 5; + while (num < 10) { + std::cout << num << std::endl; + num++; + } + return 0; +} + +int sum(std::list lst) +{ + int total = 0; + for (auto it = lst.begin(); it != lst.end(); it++) + { + total += *it; + } + return total; +} + +double average(int arr[], int size) { + int sum = 0; + for (int i = 0; i < size; i++) { + sum += arr[i]; + } + int num = size; + return sum / double(num); +} + +int main() { + + std::list lst = {1, 2, 3, 4, 5}; + int total = sum(lst); + std::cout << "Total: " << total << std::endl; + + int arr[] = {1, 2, 3, 4, 5}; + int size = sizeof(arr) / sizeof(arr[0]); + double avg = average(arr, size); + std::cout << "Average: " << avg << std::endl; + + functionA(); + + return 0; +} \ No newline at end of file