[bos #42002][EDF] (2024) Bodyfitting refactoring. Implement classes Hexahedron and Grid in independent sources, write c++ unit tests for those utility classes. Replace parallel iterator of TBB by std::thread implementation to have control on the number of threads implemented. Solve random behavior.

Add Hexahedron test to be run by ctest. Include CPP unit test headers and libs to we use testAsserts.
This commit is contained in:
cconopoima 2024-05-26 13:04:12 +01:00
parent cc09b83e05
commit 9f7d4a55e2
16 changed files with 7847 additions and 6634 deletions

73
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,73 @@
{
"C_Cpp.dimInactiveRegions": false,
"files.associations": {
"cctype": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"csignal": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"array": "cpp",
"atomic": "cpp",
"strstream": "cpp",
"bit": "cpp",
"*.tcc": "cpp",
"bitset": "cpp",
"chrono": "cpp",
"codecvt": "cpp",
"complex": "cpp",
"condition_variable": "cpp",
"cstdint": "cpp",
"deque": "cpp",
"list": "cpp",
"map": "cpp",
"set": "cpp",
"unordered_map": "cpp",
"vector": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"iterator": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"optional": "cpp",
"random": "cpp",
"ratio": "cpp",
"string": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"fstream": "cpp",
"future": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"mutex": "cpp",
"new": "cpp",
"ostream": "cpp",
"shared_mutex": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"thread": "cpp",
"cfenv": "cpp",
"cinttypes": "cpp",
"typeindex": "cpp",
"typeinfo": "cpp",
"valarray": "cpp",
"variant": "cpp",
"*.ipp": "cpp"
}
}

View File

@ -37,6 +37,7 @@ SET(SUBDIRS_COMMON
SMESHClient
SMESH_SWIG
StdMeshers
StdMeshers.test
StdMeshers_I
SMESH_PY
Tools

View File

@ -47,8 +47,12 @@ SMESH_Hypothesis::SMESH_Hypothesis(int hypId,
_type = PARAM_ALGO;
_shapeType = 0; // to be set by algo with TopAbs_Enum
_param_algo_dim = -1; // to be set by algo parameter
StudyContextStruct* myStudyContext = gen->GetStudyContext();
myStudyContext->mapHypothesis[hypId] = this;
if ( _gen )
{
StudyContextStruct* myStudyContext = gen->GetStudyContext();
myStudyContext->mapHypothesis[hypId] = this;
}
}
//=============================================================================
@ -107,15 +111,17 @@ int SMESH_Hypothesis::GetShapeType() const
void SMESH_Hypothesis::NotifySubMeshesHypothesisModification()
{
// for all meshes in study
StudyContextStruct* myStudyContext = _gen->GetStudyContext();
map<int, SMESH_Mesh*>::iterator itm;
for (itm = myStudyContext->mapMesh.begin();
itm != myStudyContext->mapMesh.end();
itm++)
if ( _gen )
{
SMESH_Mesh* mesh = (*itm).second;
mesh->NotifySubMeshesHypothesisModification( this );
StudyContextStruct* myStudyContext = _gen->GetStudyContext();
map<int, SMESH_Mesh*>::iterator itm;
for (itm = myStudyContext->mapMesh.begin();
itm != myStudyContext->mapMesh.end();
itm++)
{
SMESH_Mesh* mesh = (*itm).second;
mesh->NotifySubMeshesHypothesisModification( this );
}
}
}
@ -148,13 +154,16 @@ void SMESH_Hypothesis::SetLibName(const char* theLibName)
SMESH_Mesh* SMESH_Hypothesis::GetMeshByPersistentID(int id) const
{
StudyContextStruct* myStudyContext = _gen->GetStudyContext();
map<int, SMESH_Mesh*>::iterator itm = myStudyContext->mapMesh.begin();
for ( ; itm != myStudyContext->mapMesh.end(); itm++)
if ( _gen )
{
SMESH_Mesh* mesh = (*itm).second;
if ( mesh->GetMeshDS()->GetPersistentId() == id )
return mesh;
StudyContextStruct* myStudyContext = _gen->GetStudyContext();
map<int, SMESH_Mesh*>::iterator itm = myStudyContext->mapMesh.begin();
for ( ; itm != myStudyContext->mapMesh.end(); itm++)
{
SMESH_Mesh* mesh = (*itm).second;
if ( mesh->GetMeshDS()->GetPersistentId() == id )
return mesh;
}
}
return 0;
}

View File

@ -0,0 +1,73 @@
# Copyright (C) 2012-2024 CEA, EDF, OPEN CASCADE
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
INCLUDE(tests.set)
SALOME_GENERATE_TESTS_ENVIRONMENT(_test_env)
SET(TEST_INSTALL_DIRECTORY ${SMESH_TEST_DIR}/other)
INCLUDE_DIRECTORIES(
${OpenCASCADE_INCLUDE_DIR}
${Boost_INCLUDE_DIRS}
${MEDCOUPLING_INCLUDE_DIRS}
${CPPUNIT_INCLUDE_DIRS}
${PROJECT_SOURCE_DIR}/src/StdMeshers
${PROJECT_SOURCE_DIR}/src/SMESHUtils
${PROJECT_SOURCE_DIR}/src/SMESH
${PROJECT_SOURCE_DIR}/src/SMESHDS
${PROJECT_SOURCE_DIR}/src/SMDS
${PROJECT_SOURCE_DIR}/src/Controls
)
# additional preprocessor / compiler flags
ADD_DEFINITIONS(
${OpenCASCADE_DEFINITIONS}
${BOOST_DEFINITIONS}
${CPPUNIT_DEFINITIONS}
)
IF(SALOME_SMESH_USE_TBB)
SET(TBB_LIBS ${TBB_LIBRARIES})
ENDIF(SALOME_SMESH_USE_TBB)
FOREACH(_test ${UNIT_TESTS})
GET_FILENAME_COMPONENT(testname ${_test} NAME_WE)
SET(testname "TESTS_${testname}")
add_executable(${_test} ${_test}.cxx)
target_link_libraries(${_test} StdMeshers ${CPPUNIT_LIBRARIES} )
ADD_TEST(NAME ${testname}
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/${_test} )
SET_TESTS_PROPERTIES(${testname} PROPERTIES ENVIRONMENT "${tests_env}" LABELS "tests")
ENDFOREACH()
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${UNIT_TESTS} PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ DESTINATION ${TEST_INSTALL_DIRECTORY})
# IF(WIN32)
# FOREACH(_test ${UNIT_TESTS})
# INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/${_test}${CMAKE_EXECUTABLE_SUFFIX} PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ DESTINATION ${TEST_INSTALL_DIRECTORY})
# ENDFOREACH()
# ELSE()
# FOREACH(_test ${CPP_TESTS})
# INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${_test} PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ DESTINATION ${TEST_INSTALL_DIRECTORY})
# ENDFOREACH()
# ENDIF(WIN32)

View File

@ -0,0 +1,163 @@
// Copyright (C) 2016-2024 CEA, EDF
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
// File : HexahedronTest.cxx
// Module : SMESH
// Purpose: Implement unit tests for StdMeshers_Cartesian_3D_Hexahedron class to reproduce bugs that manifest in integration tests.
// The main difference between this unit test and integration tests is the fine grained control we have over the class methods and the hability to diagnose/solve bugs before the code goes into production enviroment.
// This test class can be used as reference for the development of future tests in other stdMesh algorithms
#include "StdMeshers_Cartesian_3D_Hexahedron.hxx"
#include "StdMeshers_CartesianParameters3D.hxx"
// CPP TEST
#include <cppunit/TestAssert.h>
// OCC
#include<BRep_Builder.hxx>
#include<BRepTools.hxx>
#include<iostream>
#include <memory>
// Helper functions!
// Build Grid
// Require building mesh
// Require building shape. For test load shapes from memory in .brep files seems the simplest
//
/*!
* \brief Mock mesh
*/
struct SMESH_Mesh_Test: public SMESH_Mesh
{
SMESH_Mesh_Test() {
_isShapeToMesh = (_id = 0);
_meshDS = new SMESHDS_Mesh( _id, true );
}
};
/*!
* \brief Mock Hypothesis
*/
struct CartesianHypo: public StdMeshers_CartesianParameters3D
{
CartesianHypo() : StdMeshers_CartesianParameters3D(0/*zero hypoId*/, nullptr/*NULL generator*/)
{
}
};
/*!
* \brief Shape loader
*/
void loadBrepShape( std::string shapeName, TopoDS_Shape & shape )
{
BRep_Builder b;
BRepTools::Read(shape, shapeName.c_str(), b);
}
// Initialize the grid and intesersectors of grid with the geometry
void GridInitAndInterserctWithShape( Grid& grid, double gridSpacing, TopoDS_Shape& theShape,
std::map< TGeomID, vector< TGeomID > >& edge2faceIDsMap, const int numOfThreads )
{
std::vector< TopoDS_Shape > faceVec;
TopTools_MapOfShape faceMap;
TopExp_Explorer fExp;
for ( fExp.Init( theShape, TopAbs_FACE ); fExp.More(); fExp.Next() )
{
bool isNewFace = faceMap.Add( fExp.Current() );
if ( !grid._toConsiderInternalFaces )
if ( !isNewFace || fExp.Current().Orientation() == TopAbs_INTERNAL )
// remove an internal face
faceMap.Remove( fExp.Current() );
}
faceVec.reserve( faceMap.Extent() );
faceVec.assign( faceMap.cbegin(), faceMap.cend() );
vector<FaceGridIntersector> facesItersectors( faceVec.size() );
Bnd_Box shapeBox;
for ( size_t i = 0; i < faceVec.size(); ++i )
{
facesItersectors[i]._face = TopoDS::Face( faceVec[i] );
facesItersectors[i]._faceID = grid.ShapeID( faceVec[i] );
facesItersectors[i]._grid = &grid;
shapeBox.Add( facesItersectors[i].GetFaceBndBox() );
}
// Canonical axes(i,j,k)
double axisDirs[9] = {1.,0.,0.,0.,1.,0.,0.,0.,1.};
Tools::GetExactBndBox( faceVec, axisDirs, shapeBox );
vector<double> xCoords, yCoords, zCoords;
std::unique_ptr<CartesianHypo> myHypo( new CartesianHypo() );
std::vector<std::string> grdSpace = { std::to_string(gridSpacing) };
std::vector<double> intPnts;
myHypo->SetGridSpacing(grdSpace, intPnts, 0 ); // Spacing in dir 0
myHypo->SetGridSpacing(grdSpace, intPnts, 1 ); // Spacing in dir 1
myHypo->SetGridSpacing(grdSpace, intPnts, 2 ); // Spacing in dir 2
myHypo->SetSizeThreshold(4.0); // set threshold
myHypo->GetCoordinates(xCoords, yCoords, zCoords, shapeBox);
grid.SetCoordinates( xCoords, yCoords, zCoords, axisDirs, shapeBox );
for ( size_t i = 0; i < facesItersectors.size(); ++i )
facesItersectors[i].Intersect();
for ( size_t i = 0; i < facesItersectors.size(); ++i )
facesItersectors[i].StoreIntersections();
grid.ComputeNodes( *grid._helper );
grid.GetEdgesToImplement( edge2faceIDsMap, theShape, faceVec );
}
// ADD test for parallel intersection of grid with solid
// Reproduce conditions of TBPERF_GRIDS_PERF_SMESH_M1 test to detect and solve segfault in unit test.
bool testNRTM1()
{
for (auto numOfThreads : {1, 2, 12, 16} )
{
for (size_t i = 0; i < 10; i++)
{
TopoDS_Shape myShape;
loadBrepShape( "data/HexahedronTest/NRTM1.brep", myShape );
CPPUNIT_ASSERT_MESSAGE( "Could not load the brep shape!", !myShape.IsNull() );
std::unique_ptr<SMESH_Mesh> myMesh( new SMESH_Mesh_Test() );
myMesh->ShapeToMesh( myShape );
SMESH_MesherHelper helper( *myMesh );
Grid grid;
grid._helper = &helper;
grid._toAddEdges = false; grid._toCreateFaces = false; grid._toConsiderInternalFaces = false; grid._toUseThresholdForInternalFaces = false; grid._toUseQuanta = false;
grid._sizeThreshold = 4.0;
grid.InitGeometry( myShape );
std::map< TGeomID, vector< TGeomID > > edge2faceIDsMap;
GridInitAndInterserctWithShape( grid, 1.0, myShape, edge2faceIDsMap, numOfThreads );
Hexahedron hex( &grid );
int nbAdded = hex.MakeElements( helper, edge2faceIDsMap, numOfThreads );
CPPUNIT_ASSERT_MESSAGE( "Number of computed elements does not match", nbAdded == 1024 );
}
}
return true;
}
// Entry point for test
int main()
{
auto t0 = testNRTM1();
return 0;
}

View File

@ -0,0 +1,27 @@
# Copyright (C) 2015-2024 CEA, EDF, OPEN CASCADE
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
# The following tests cannot be executed with 'make test' because they use
# external meshing plug-ins.
# On the other hand these tests can be executed with 'salome test'.
# ---------------------------------------------------------------------------
SET(UNIT_TESTS
HexahedronTest
)

View File

@ -119,6 +119,8 @@ SET(StdMeshers_HEADERS
StdMeshers_ViscousLayers2D.hxx
StdMeshers_Projection_1D2D.hxx
StdMeshers_CartesianParameters3D.hxx
StdMeshers_Cartesian_3D_Grid.hxx
StdMeshers_Cartesian_3D_Hexahedron.hxx
StdMeshers_Cartesian_3D.hxx
StdMeshers_Cartesian_VL.hxx
StdMeshers_QuadFromMedialAxis_1D2D.hxx
@ -184,6 +186,8 @@ SET(StdMeshers_SOURCES
StdMeshers_ViscousLayers2D.cxx
StdMeshers_Projection_1D2D.cxx
StdMeshers_CartesianParameters3D.cxx
StdMeshers_Cartesian_3D_Grid.cxx
StdMeshers_Cartesian_3D_Hexahedron.cxx
StdMeshers_Cartesian_3D.cxx
StdMeshers_Cartesian_VL.cxx
StdMeshers_Adaptive1D.cxx

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,991 @@
// Copyright (C) 2016-2024 CEA, EDF
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
// File : StdMeshers_Cartesian_3D_Grid.hxx
// Module : SMESH
// Purpose: Make BodyFitting mesh algorithm more modular and testable
//
#ifndef _SMESH_Cartesian_3D_GRID_HXX_
#define _SMESH_Cartesian_3D_GRID_HXX_
#ifdef WITH_TBB
#include <tbb/parallel_for.h>
#endif
#include <utilities.h>
// STD
#include <algorithm>
#include <vector>
#include <memory>
#include <mutex>
#include <thread>
// SMESH
#include "SMESH_StdMeshers.hxx"
#include "StdMeshers_FaceSide.hxx"
#include "StdMeshers_CartesianParameters3D.hxx"
#include <ObjectPool.hxx>
#include <SMDS_LinearEdge.hxx>
#include <SMDS_MeshNode.hxx>
#include <SMDS_VolumeOfNodes.hxx>
#include <SMDS_VolumeTool.hxx>
#include <SMESHDS_Mesh.hxx>
#include <SMESH_Block.hxx>
#include <SMESH_Comment.hxx>
#include <SMESH_ControlsDef.hxx>
#include <SMESH_Mesh.hxx>
#include <SMESH_MeshAlgos.hxx>
#include <SMESH_MeshEditor.hxx>
#include <SMESH_MesherHelper.hxx>
#include <SMESH_subMesh.hxx>
#include <SMESH_subMeshEventListener.hxx>
#include <utilities.h>
#include <Utils_ExceptHandlers.hxx>
#include <GEOMUtils.hxx>
//OCC
#include <BRepAdaptor_Curve.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <BRepBndLib.hxx>
#include <BRepBuilderAPI_Copy.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepTools.hxx>
#include <BRepTopAdaptor_FClass2d.hxx>
#include <BRep_Builder.hxx>
#include <BRep_Tool.hxx>
#include <Bnd_B3d.hxx>
#include <Bnd_Box.hxx>
#include <ElSLib.hxx>
#include <GCPnts_UniformDeflection.hxx>
#include <Geom2d_BSplineCurve.hxx>
#include <Geom2d_BezierCurve.hxx>
#include <Geom2d_TrimmedCurve.hxx>
#include <GeomAPI_ProjectPointOnSurf.hxx>
#include <GeomLib.hxx>
#include <Geom_BSplineCurve.hxx>
#include <Geom_BSplineSurface.hxx>
#include <Geom_BezierCurve.hxx>
#include <Geom_BezierSurface.hxx>
#include <Geom_RectangularTrimmedSurface.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <IntAna_IntConicQuad.hxx>
#include <IntAna_IntLinTorus.hxx>
#include <IntAna_Quadric.hxx>
#include <IntCurveSurface_TransitionOnCurve.hxx>
#include <IntCurvesFace_Intersector.hxx>
#include <Poly_Triangulation.hxx>
#include <Precision.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopLoc_Location.hxx>
#include <TopTools_DataMapOfShapeInteger.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_TShape.hxx>
#include <gp_Cone.hxx>
#include <gp_Cylinder.hxx>
#include <gp_Lin.hxx>
#include <gp_Pln.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Sphere.hxx>
#include <gp_Torus.hxx>
// All utility structs used in Grid and hexahedron class will be included here
// Ideally each one of this should define their own testable class
using namespace std;
using namespace SMESH;
namespace gridtools
{
typedef int TGeomID; // IDs of sub-shapes
typedef TopTools_ShapeMapHasher TShapeHasher; // non-oriented shape hasher
typedef std::array< int, 3 > TIJK;
const TGeomID theUndefID = 1e+9;
//=============================================================================
// Definitions of internal utils
// --------------------------------------------------------------------------
enum Transition {
Trans_TANGENT = IntCurveSurface_Tangent,
Trans_IN = IntCurveSurface_In,
Trans_OUT = IntCurveSurface_Out,
Trans_APEX,
Trans_INTERNAL // for INTERNAL FACE
};
// --------------------------------------------------------------------------
/*!
* \brief Sub-entities of a FACE neighboring its concave VERTEX.
* Help to avoid linking nodes on EDGEs that seem connected
* by the concave FACE but the link actually lies outside the FACE
*/
struct ConcaveFace
{
TGeomID _concaveFace;
TGeomID _edge1, _edge2;
TGeomID _v1, _v2;
ConcaveFace( int f=0, int e1=0, int e2=0, int v1=0, int v2=0 )
: _concaveFace(f), _edge1(e1), _edge2(e2), _v1(v1), _v2(v2) {}
bool HasEdge( TGeomID edge ) const { return edge == _edge1 || edge == _edge2; }
bool HasVertex( TGeomID v ) const { return v == _v1 || v == _v2; }
void SetEdge( TGeomID edge ) { ( _edge1 ? _edge2 : _edge1 ) = edge; }
void SetVertex( TGeomID v ) { ( _v1 ? _v2 : _v1 ) = v; }
};
typedef NCollection_DataMap< TGeomID, ConcaveFace > TConcaveVertex2Face;
// --------------------------------------------------------------------------
/*!
* \brief Container of IDs of SOLID sub-shapes
*/
class Solid // sole SOLID contains all sub-shapes
{
TGeomID _id; // SOLID id
bool _hasInternalFaces;
TConcaveVertex2Face _concaveVertex; // concave VERTEX -> ConcaveFace
public:
virtual ~Solid() {}
virtual bool Contains( TGeomID /*subID*/ ) const { return true; }
virtual bool ContainsAny( const vector< TGeomID>& /*subIDs*/ ) const { return true; }
virtual TopAbs_Orientation Orientation( const TopoDS_Shape& s ) const { return s.Orientation(); }
virtual bool IsOutsideOriented( TGeomID /*faceID*/ ) const { return true; }
void SetID( TGeomID id ) { _id = id; }
TGeomID ID() const { return _id; }
void SetHasInternalFaces( bool has ) { _hasInternalFaces = has; }
bool HasInternalFaces() const { return _hasInternalFaces; }
void SetConcave( TGeomID V, TGeomID F, TGeomID E1, TGeomID E2, TGeomID V1, TGeomID V2 )
{ _concaveVertex.Bind( V, ConcaveFace{ F, E1, E2, V1, V2 }); }
bool HasConcaveVertex() const { return !_concaveVertex.IsEmpty(); }
const ConcaveFace* GetConcave( TGeomID V ) const { return _concaveVertex.Seek( V ); }
};
// --------------------------------------------------------------------------
class OneOfSolids : public Solid
{
TColStd_MapOfInteger _subIDs;
TopTools_MapOfShape _faces; // keep FACE orientation
TColStd_MapOfInteger _outFaceIDs; // FACEs of shape_to_mesh oriented outside the SOLID
public:
void Init( const TopoDS_Shape& solid,
TopAbs_ShapeEnum subType,
const SMESHDS_Mesh* mesh );
virtual bool Contains( TGeomID i ) const { return i == ID() || _subIDs.Contains( i ); }
virtual bool ContainsAny( const vector< TGeomID>& subIDs ) const
{
for ( size_t i = 0; i < subIDs.size(); ++i ) if ( Contains( subIDs[ i ])) return true;
return false;
}
virtual TopAbs_Orientation Orientation( const TopoDS_Shape& face ) const
{
const TopoDS_Shape& sInMap = const_cast< OneOfSolids* >(this)->_faces.Added( face );
return sInMap.Orientation();
}
virtual bool IsOutsideOriented( TGeomID faceID ) const
{
return faceID == 0 || _outFaceIDs.Contains( faceID );
}
};
// --------------------------------------------------------------------------
/*!
* \brief Hold a vector of TGeomID and clear it at destruction
*/
class GeomIDVecHelder
{
typedef std::vector< TGeomID > TVector;
const TVector& myVec;
bool myOwn;
public:
GeomIDVecHelder( const TVector& idVec, bool isOwner ): myVec( idVec ), myOwn( isOwner ) {}
GeomIDVecHelder( const GeomIDVecHelder& holder ): myVec( holder.myVec ), myOwn( holder.myOwn )
{
const_cast< bool& >( holder.myOwn ) = false;
}
~GeomIDVecHelder() { if ( myOwn ) const_cast<TVector&>( myVec ).clear(); }
size_t size() const { return myVec.size(); }
TGeomID operator[]( size_t i ) const { return i < size() ? myVec[i] : theUndefID; }
bool operator==( const GeomIDVecHelder& other ) const { return myVec == other.myVec; }
bool contain( const TGeomID& id ) const {
return std::find( myVec.begin(), myVec.end(), id ) != myVec.end();
}
TGeomID otherThan( const TGeomID& id ) const {
for ( const TGeomID& id2 : myVec )
if ( id != id2 )
return id2;
return theUndefID;
}
TGeomID oneCommon( const GeomIDVecHelder& other ) const {
TGeomID common = theUndefID;
for ( const TGeomID& id : myVec )
if ( other.contain( id ))
{
if ( common != theUndefID )
return theUndefID;
common = id;
}
return common;
}
};
// --------------------------------------------------------------------------
/*!
* \brief Geom data
*/
struct Geometry
{
TopoDS_Shape _mainShape;
vector< vector< TGeomID > > _solidIDsByShapeID;// V/E/F ID -> SOLID IDs
Solid _soleSolid;
map< TGeomID, OneOfSolids > _solidByID;
TColStd_MapOfInteger _boundaryFaces; // FACEs on boundary of mesh->ShapeToMesh()
TColStd_MapOfInteger _strangeEdges; // EDGEs shared by strange FACEs
TGeomID _extIntFaceID; // pseudo FACE - extension of INTERNAL FACE
TopTools_DataMapOfShapeInteger _shape2NbNodes; // nb of pre-existing nodes on shapes
Controls::ElementsOnShape _edgeClassifier;
Controls::ElementsOnShape _vertexClassifier;
bool IsOneSolid() const { return _solidByID.size() < 2; }
GeomIDVecHelder GetSolidIDsByShapeID( const vector< TGeomID >& shapeIDs ) const;
};
// --------------------------------------------------------------------------
/*!
* \brief Common data of any intersection between a Grid and a shape
*/
struct B_IntersectPoint
{
// This two class members are being updated in a non thread safe way.
// See Add method modify _node and _faceIDs class members dinamicaly during execution
// of Hexahedron.compute() method.
// std::mutex _mutex;
mutable const SMDS_MeshNode* _node;
mutable vector< TGeomID > _faceIDs;
B_IntersectPoint(): _node(NULL) {}
bool Add( const vector< TGeomID >& fIDs, const SMDS_MeshNode* n=NULL ) const;
TGeomID HasCommonFace( const B_IntersectPoint * other, TGeomID avoidFace=-1 ) const;
size_t GetCommonFaces( const B_IntersectPoint * other, TGeomID * commonFaces ) const;
bool IsOnFace( TGeomID faceID ) const;
virtual ~B_IntersectPoint() {}
};
// --------------------------------------------------------------------------
/*!
* \brief Data of intersection between a GridLine and a TopoDS_Face
*/
struct F_IntersectPoint : public B_IntersectPoint
{
double _paramOnLine;
double _u, _v;
mutable Transition _transition;
mutable size_t _indexOnLine;
bool operator< ( const F_IntersectPoint& o ) const {
return _paramOnLine < o._paramOnLine;
}
};
// --------------------------------------------------------------------------
/*!
* \brief Data of intersection between GridPlanes and a TopoDS_EDGE
*/
struct E_IntersectPoint : public B_IntersectPoint
{
gp_Pnt _point;
double _uvw[3];
TGeomID _shapeID; // ID of EDGE or VERTEX
};
// --------------------------------------------------------------------------
/*!
* \brief A line of the grid and its intersections with 2D geometry
*/
struct GridLine
{
gp_Lin _line;
double _length; // line length
multiset< F_IntersectPoint > _intPoints;
void RemoveExcessIntPoints( const double tol );
TGeomID GetSolidIDBefore( multiset< F_IntersectPoint >::iterator ip,
const TGeomID prevID,
const Geometry& geom);
};
// --------------------------------------------------------------------------
/*!
* \brief Planes of the grid used to find intersections of an EDGE with a hexahedron
*/
struct GridPlanes
{
gp_XYZ _zNorm;
vector< gp_XYZ > _origins; // origin points of all planes in one direction
vector< double > _zProjs; // projections of origins to _zNorm
};
// --------------------------------------------------------------------------
/*!
* \brief Iterator on the parallel grid lines of one direction
*/
struct LineIndexer
{
size_t _size [3];
size_t _curInd[3];
size_t _iVar1, _iVar2, _iConst;
string _name1, _name2, _nameConst;
LineIndexer() {}
LineIndexer( size_t sz1, size_t sz2, size_t sz3,
size_t iv1, size_t iv2, size_t iConst,
const string& nv1, const string& nv2, const string& nConst )
{
_size[0] = sz1; _size[1] = sz2; _size[2] = sz3;
_curInd[0] = _curInd[1] = _curInd[2] = 0;
_iVar1 = iv1; _iVar2 = iv2; _iConst = iConst;
_name1 = nv1; _name2 = nv2; _nameConst = nConst;
}
size_t I() const { return _curInd[0]; }
size_t J() const { return _curInd[1]; }
size_t K() const { return _curInd[2]; }
void SetIJK( size_t i, size_t j, size_t k )
{
_curInd[0] = i; _curInd[1] = j; _curInd[2] = k;
}
void SetLineIndex(size_t i)
{
_curInd[_iVar2] = i / _size[_iVar1];
_curInd[_iVar1] = i % _size[_iVar1];
}
void operator++()
{
if ( ++_curInd[_iVar1] == _size[_iVar1] )
_curInd[_iVar1] = 0, ++_curInd[_iVar2];
}
bool More() const { return _curInd[_iVar2] < _size[_iVar2]; }
size_t LineIndex () const { return _curInd[_iVar1] + _curInd[_iVar2]* _size[_iVar1]; }
size_t LineIndex10 () const { return (_curInd[_iVar1] + 1 ) + _curInd[_iVar2]* _size[_iVar1]; }
size_t LineIndex01 () const { return _curInd[_iVar1] + (_curInd[_iVar2] + 1 )* _size[_iVar1]; }
size_t LineIndex11 () const { return (_curInd[_iVar1] + 1 ) + (_curInd[_iVar2] + 1 )* _size[_iVar1]; }
void SetIndexOnLine (size_t i) { _curInd[ _iConst ] = i; }
bool IsValidIndexOnLine (size_t i) const { return i < _size[ _iConst ]; }
size_t NbLines() const { return _size[_iVar1] * _size[_iVar2]; }
};
class Tools
{
public:
Tools() = delete;
//================================================================================
/*!
* \brief computes exact bounding box with axes parallel to given ones
*/
//================================================================================
static void GetExactBndBox( const vector< TopoDS_Shape >& faceVec, const double* axesDirs, Bnd_Box& shapeBox );
};
} // end namespace gridtools
using namespace gridtools;
class STDMESHERS_EXPORT Grid
{
public:
vector< double > _coords[3]; // coordinates of grid nodes
gp_XYZ _axes [3]; // axis directions
vector< GridLine > _lines [3]; // in 3 directions
double _tol, _minCellSize;
gp_XYZ _origin;
gp_Mat _invB; // inverted basis of _axes
// index shift within _nodes of nodes of a cell from the 1st node
int _nodeShift[8];
vector< const SMDS_MeshNode* > _nodes; // mesh nodes at grid nodes
vector< const SMDS_MeshNode* > _allBorderNodes; // mesh nodes between the bounding box and the geometry boundary
vector< const F_IntersectPoint* > _gridIntP; // grid node intersection with geometry
ObjectPool< E_IntersectPoint > _edgeIntPool; // intersections with EDGEs
ObjectPool< F_IntersectPoint > _extIntPool; // intersections with extended INTERNAL FACEs
//list< E_IntersectPoint > _edgeIntP; // intersections with EDGEs
Geometry _geometry;
bool _toAddEdges;
bool _toCreateFaces;
bool _toConsiderInternalFaces;
bool _toUseThresholdForInternalFaces;
double _sizeThreshold;
bool _toUseQuanta;
double _quanta;
SMESH_MesherHelper* _helper;
size_t CellIndex( size_t i, size_t j, size_t k ) const
{
return i + j*(_coords[0].size()-1) + k*(_coords[0].size()-1)*(_coords[1].size()-1);
}
size_t NodeIndex( size_t i, size_t j, size_t k ) const
{
return i + j*_coords[0].size() + k*_coords[0].size()*_coords[1].size();
}
size_t NodeIndex( const TIJK& ijk ) const
{
return NodeIndex( ijk[0], ijk[1], ijk[2] );
}
size_t NodeIndexDX() const { return 1; }
size_t NodeIndexDY() const { return _coords[0].size(); }
size_t NodeIndexDZ() const { return _coords[0].size() * _coords[1].size(); }
LineIndexer GetLineIndexer(size_t iDir) const;
size_t GetLineDir( const GridLine* line, size_t & index ) const;
E_IntersectPoint* Add( const E_IntersectPoint& ip )
{
E_IntersectPoint* eip = _edgeIntPool.getNew();
*eip = ip;
return eip;
}
void Remove( E_IntersectPoint* eip ) { _edgeIntPool.destroy( eip ); }
TGeomID ShapeID( const TopoDS_Shape& s ) const;
const TopoDS_Shape& Shape( TGeomID id ) const;
TopAbs_ShapeEnum ShapeType( TGeomID id ) const { return Shape(id).ShapeType(); }
void InitGeometry( const TopoDS_Shape& theShape );
void InitClassifier( const TopoDS_Shape& mainShape,
TopAbs_ShapeEnum shapeType,
Controls::ElementsOnShape& classifier );
void GetEdgesToImplement( map< TGeomID, vector< TGeomID > > & edge2faceMap,
const TopoDS_Shape& shape,
const vector< TopoDS_Shape >& faces );
void SetSolidFather( const TopoDS_Shape& s, const TopoDS_Shape& theShapeToMesh );
bool IsShared( TGeomID faceID ) const;
bool IsAnyShared( const std::vector< TGeomID >& faceIDs ) const;
bool IsInternal( TGeomID faceID ) const {
return ( faceID == PseudoIntExtFaceID() ||
Shape( faceID ).Orientation() == TopAbs_INTERNAL ); }
bool IsSolid( TGeomID shapeID ) const {
if ( _geometry.IsOneSolid() ) return _geometry._soleSolid.ID() == shapeID;
else return _geometry._solidByID.count( shapeID ); }
bool IsStrangeEdge( TGeomID id ) const { return _geometry._strangeEdges.Contains( id ); }
TGeomID PseudoIntExtFaceID() const { return _geometry._extIntFaceID; }
Solid* GetSolid( TGeomID solidID = 0 );
Solid* GetOneOfSolids( TGeomID solidID );
const vector< TGeomID > & GetSolidIDs( TGeomID subShapeID ) const;
bool IsCorrectTransition( TGeomID faceID, const Solid* solid );
bool IsBoundaryFace( TGeomID face ) const { return _geometry._boundaryFaces.Contains( face ); }
void SetOnShape( const SMDS_MeshNode* n, const F_IntersectPoint& ip,
TopoDS_Vertex* vertex = nullptr, bool unset = false );
void UpdateFacesOfVertex( const B_IntersectPoint& ip, const TopoDS_Vertex& vertex );
bool IsToCheckNodePos() const { return !_toAddEdges && _toCreateFaces; }
bool IsToRemoveExcessEntities() const { return !_toAddEdges; }
void SetCoordinates(const vector<double>& xCoords,
const vector<double>& yCoords,
const vector<double>& zCoords,
const double* axesDirs,
const Bnd_Box& bndBox );
void ComputeUVW(const gp_XYZ& p, double uvw[3]);
void ComputeNodes(SMESH_MesherHelper& helper);
bool GridInitAndInterserctWithShape( const TopoDS_Shape& theShape, std::map< TGeomID, vector< TGeomID > >& edge2faceIDsMap,
const StdMeshers_CartesianParameters3D* hyp, const int numOfThreads, bool computeCanceled );
};
namespace
{
// Implement parallel computation of Hexa with c++ thread implementation
template<typename Iterator, class Function>
void parallel_for(const Iterator& first, const Iterator& last, Function&& f, const int nthreads = 1)
{
const unsigned int group = ((last-first))/std::abs(nthreads);
std::vector<std::thread> threads;
threads.reserve(nthreads);
Iterator it = first;
for (; it < last-group; it += group) {
// to create a thread
// Pass iterators by value and the function by reference!
auto lambda = [=,&f](){ std::for_each(it, std::min(it+group, last), f);};
// stack the threads
threads.push_back( std::thread( lambda ) );
}
std::for_each(it, last, f); // last steps while we wait for other threads
std::for_each(threads.begin(), threads.end(), [](std::thread& x){x.join();});
}
// --------------------------------------------------------------------------
/*!
* \brief Intersector of TopoDS_Face with all GridLine's
*/
struct FaceGridIntersector
{
TopoDS_Face _face;
TGeomID _faceID;
Grid* _grid;
Bnd_Box _bndBox;
IntCurvesFace_Intersector* _surfaceInt;
vector< std::pair< GridLine*, F_IntersectPoint > > _intersections;
FaceGridIntersector(): _grid(0), _surfaceInt(0) {}
void Intersect();
void StoreIntersections()
{
for ( size_t i = 0; i < _intersections.size(); ++i )
{
multiset< F_IntersectPoint >::iterator ip =
_intersections[i].first->_intPoints.insert( _intersections[i].second );
ip->_faceIDs.reserve( 1 );
ip->_faceIDs.push_back( _faceID );
}
}
const Bnd_Box& GetFaceBndBox()
{
GetCurveFaceIntersector();
return _bndBox;
}
IntCurvesFace_Intersector* GetCurveFaceIntersector()
{
if ( !_surfaceInt )
{
_surfaceInt = new IntCurvesFace_Intersector( _face, Precision::PConfusion() );
_bndBox = _surfaceInt->Bounding();
if ( _bndBox.IsVoid() )
BRepBndLib::Add (_face, _bndBox);
}
return _surfaceInt;
}
#ifdef WITH_TBB
bool IsThreadSafe(set< const Standard_Transient* >& noSafeTShapes) const;
#endif
};
#ifdef WITH_TBB
// --------------------------------------------------------------------------
/*!
* \brief Structure intersecting certain nb of faces with GridLine's in one thread
*/
struct ParallelIntersector
{
vector< FaceGridIntersector >& _faceVec;
ParallelIntersector( vector< FaceGridIntersector >& faceVec): _faceVec(faceVec){}
void operator() ( const tbb::blocked_range<size_t>& r ) const
{
for ( size_t i = r.begin(); i != r.end(); ++i )
_faceVec[i].Intersect();
}
};
#endif
template<typename Type>
void computeGridIntersection( Type faceGridIntersector )
{
faceGridIntersector.Intersect();
}
// --------------------------------------------------------------------------
/*!
* \brief Intersector of a surface with a GridLine
*/
struct FaceLineIntersector
{
double _tol;
double _u, _v, _w; // params on the face and the line
Transition _transition; // transition at intersection (see IntCurveSurface.cdl)
Transition _transIn, _transOut; // IN and OUT transitions depending of face orientation
gp_Pln _plane;
gp_Cylinder _cylinder;
gp_Cone _cone;
gp_Sphere _sphere;
gp_Torus _torus;
IntCurvesFace_Intersector* _surfaceInt;
vector< F_IntersectPoint > _intPoints;
void IntersectWithPlane (const GridLine& gridLine);
void IntersectWithCylinder(const GridLine& gridLine);
void IntersectWithCone (const GridLine& gridLine);
void IntersectWithSphere (const GridLine& gridLine);
void IntersectWithTorus (const GridLine& gridLine);
void IntersectWithSurface (const GridLine& gridLine);
bool UVIsOnFace() const;
void addIntPoint(const bool toClassify=true);
bool isParamOnLineOK( const double linLength )
{
return -_tol < _w && _w < linLength + _tol;
}
FaceLineIntersector():_surfaceInt(0) {}
~FaceLineIntersector() { if (_surfaceInt ) delete _surfaceInt; _surfaceInt = 0; }
};
//=============================================================================
/*
* Intersects TopoDS_Face with all GridLine's
*/
void FaceGridIntersector::Intersect()
{
FaceLineIntersector intersector;
intersector._surfaceInt = GetCurveFaceIntersector();
intersector._tol = _grid->_tol;
intersector._transOut = _face.Orientation() == TopAbs_REVERSED ? Trans_IN : Trans_OUT;
intersector._transIn = _face.Orientation() == TopAbs_REVERSED ? Trans_OUT : Trans_IN;
typedef void (FaceLineIntersector::* PIntFun )(const GridLine& gridLine);
PIntFun interFunction;
bool isDirect = true;
BRepAdaptor_Surface surf( _face );
switch ( surf.GetType() ) {
case GeomAbs_Plane:
intersector._plane = surf.Plane();
interFunction = &FaceLineIntersector::IntersectWithPlane;
isDirect = intersector._plane.Direct();
break;
case GeomAbs_Cylinder:
intersector._cylinder = surf.Cylinder();
interFunction = &FaceLineIntersector::IntersectWithCylinder;
isDirect = intersector._cylinder.Direct();
break;
case GeomAbs_Cone:
intersector._cone = surf.Cone();
interFunction = &FaceLineIntersector::IntersectWithCone;
//isDirect = intersector._cone.Direct();
break;
case GeomAbs_Sphere:
intersector._sphere = surf.Sphere();
interFunction = &FaceLineIntersector::IntersectWithSphere;
isDirect = intersector._sphere.Direct();
break;
case GeomAbs_Torus:
intersector._torus = surf.Torus();
interFunction = &FaceLineIntersector::IntersectWithTorus;
//isDirect = intersector._torus.Direct();
break;
default:
interFunction = &FaceLineIntersector::IntersectWithSurface;
}
if ( !isDirect )
std::swap( intersector._transOut, intersector._transIn );
_intersections.clear();
for ( int iDir = 0; iDir < 3; ++iDir ) // loop on 3 line directions
{
if ( surf.GetType() == GeomAbs_Plane )
{
// check if all lines in this direction are parallel to a plane
if ( intersector._plane.Axis().IsNormal( _grid->_lines[iDir][0]._line.Position(),
Precision::Angular()))
continue;
// find out a transition, that is the same for all lines of a direction
gp_Dir plnNorm = intersector._plane.Axis().Direction();
gp_Dir lineDir = _grid->_lines[iDir][0]._line.Direction();
intersector._transition =
( plnNorm * lineDir < 0 ) ? intersector._transIn : intersector._transOut;
}
if ( surf.GetType() == GeomAbs_Cylinder )
{
// check if all lines in this direction are parallel to a cylinder
if ( intersector._cylinder.Axis().IsParallel( _grid->_lines[iDir][0]._line.Position(),
Precision::Angular()))
continue;
}
// intersect the grid lines with the face
for ( size_t iL = 0; iL < _grid->_lines[iDir].size(); ++iL )
{
GridLine& gridLine = _grid->_lines[iDir][iL];
if ( _bndBox.IsOut( gridLine._line )) continue;
intersector._intPoints.clear();
(intersector.*interFunction)( gridLine ); // <- intersection with gridLine
for ( size_t i = 0; i < intersector._intPoints.size(); ++i )
_intersections.push_back( make_pair( &gridLine, intersector._intPoints[i] ));
}
}
if ( _face.Orientation() == TopAbs_INTERNAL )
{
for ( size_t i = 0; i < _intersections.size(); ++i )
if ( _intersections[i].second._transition == Trans_IN ||
_intersections[i].second._transition == Trans_OUT )
{
_intersections[i].second._transition = Trans_INTERNAL;
}
}
return;
}
//================================================================================
/*
* Return true if (_u,_v) is on the face
*/
bool FaceLineIntersector::UVIsOnFace() const
{
TopAbs_State state = _surfaceInt->ClassifyUVPoint(gp_Pnt2d( _u,_v ));
return ( state == TopAbs_IN || state == TopAbs_ON );
}
//================================================================================
/*
* Store an intersection if it is IN or ON the face
*/
void FaceLineIntersector::addIntPoint(const bool toClassify)
{
if ( !toClassify || UVIsOnFace() )
{
F_IntersectPoint p;
p._paramOnLine = _w;
p._u = _u;
p._v = _v;
p._transition = _transition;
_intPoints.push_back( p );
}
}
//================================================================================
/*
* Intersect a line with a plane
*/
void FaceLineIntersector::IntersectWithPlane(const GridLine& gridLine)
{
IntAna_IntConicQuad linPlane( gridLine._line, _plane, Precision::Angular());
_w = linPlane.ParamOnConic(1);
if ( isParamOnLineOK( gridLine._length ))
{
ElSLib::Parameters(_plane, linPlane.Point(1) ,_u,_v);
addIntPoint();
}
}
//================================================================================
/*
* Intersect a line with a cylinder
*/
void FaceLineIntersector::IntersectWithCylinder(const GridLine& gridLine)
{
IntAna_IntConicQuad linCylinder( gridLine._line, _cylinder );
if ( linCylinder.IsDone() && linCylinder.NbPoints() > 0 )
{
_w = linCylinder.ParamOnConic(1);
if ( linCylinder.NbPoints() == 1 )
_transition = Trans_TANGENT;
else
_transition = _w < linCylinder.ParamOnConic(2) ? _transIn : _transOut;
if ( isParamOnLineOK( gridLine._length ))
{
ElSLib::Parameters(_cylinder, linCylinder.Point(1) ,_u,_v);
addIntPoint();
}
if ( linCylinder.NbPoints() > 1 )
{
_w = linCylinder.ParamOnConic(2);
if ( isParamOnLineOK( gridLine._length ))
{
ElSLib::Parameters(_cylinder, linCylinder.Point(2) ,_u,_v);
_transition = ( _transition == Trans_OUT ) ? Trans_IN : Trans_OUT;
addIntPoint();
}
}
}
}
//================================================================================
/*
* Intersect a line with a cone
*/
void FaceLineIntersector::IntersectWithCone (const GridLine& gridLine)
{
IntAna_IntConicQuad linCone(gridLine._line,_cone);
if ( !linCone.IsDone() ) return;
gp_Pnt P;
gp_Vec du, dv, norm;
for ( int i = 1; i <= linCone.NbPoints(); ++i )
{
_w = linCone.ParamOnConic( i );
if ( !isParamOnLineOK( gridLine._length )) continue;
ElSLib::Parameters(_cone, linCone.Point(i) ,_u,_v);
if ( UVIsOnFace() )
{
ElSLib::D1( _u, _v, _cone, P, du, dv );
norm = du ^ dv;
double normSize2 = norm.SquareMagnitude();
if ( normSize2 > Precision::Angular() * Precision::Angular() )
{
double cos = norm.XYZ() * gridLine._line.Direction().XYZ();
cos /= sqrt( normSize2 );
if ( cos < -Precision::Angular() )
_transition = _transIn;
else if ( cos > Precision::Angular() )
_transition = _transOut;
else
_transition = Trans_TANGENT;
}
else
{
_transition = Trans_APEX;
}
addIntPoint( /*toClassify=*/false);
}
}
}
//================================================================================
/*
* Intersect a line with a sphere
*/
void FaceLineIntersector::IntersectWithSphere (const GridLine& gridLine)
{
IntAna_IntConicQuad linSphere(gridLine._line,_sphere);
if ( linSphere.IsDone() && linSphere.NbPoints() > 0 )
{
_w = linSphere.ParamOnConic(1);
if ( linSphere.NbPoints() == 1 )
_transition = Trans_TANGENT;
else
_transition = _w < linSphere.ParamOnConic(2) ? _transIn : _transOut;
if ( isParamOnLineOK( gridLine._length ))
{
ElSLib::Parameters(_sphere, linSphere.Point(1) ,_u,_v);
addIntPoint();
}
if ( linSphere.NbPoints() > 1 )
{
_w = linSphere.ParamOnConic(2);
if ( isParamOnLineOK( gridLine._length ))
{
ElSLib::Parameters(_sphere, linSphere.Point(2) ,_u,_v);
_transition = ( _transition == Trans_OUT ) ? Trans_IN : Trans_OUT;
addIntPoint();
}
}
}
}
//================================================================================
/*
* Intersect a line with a torus
*/
void FaceLineIntersector::IntersectWithTorus (const GridLine& gridLine)
{
IntAna_IntLinTorus linTorus(gridLine._line,_torus);
if ( !linTorus.IsDone()) return;
gp_Pnt P;
gp_Vec du, dv, norm;
for ( int i = 1; i <= linTorus.NbPoints(); ++i )
{
_w = linTorus.ParamOnLine( i );
if ( !isParamOnLineOK( gridLine._length )) continue;
linTorus.ParamOnTorus( i, _u,_v );
if ( UVIsOnFace() )
{
ElSLib::D1( _u, _v, _torus, P, du, dv );
norm = du ^ dv;
double normSize = norm.Magnitude();
double cos = norm.XYZ() * gridLine._line.Direction().XYZ();
cos /= normSize;
if ( cos < -Precision::Angular() )
_transition = _transIn;
else if ( cos > Precision::Angular() )
_transition = _transOut;
else
_transition = Trans_TANGENT;
addIntPoint( /*toClassify=*/false);
}
}
}
//================================================================================
/*
* Intersect a line with a non-analytical surface
*/
void FaceLineIntersector::IntersectWithSurface (const GridLine& gridLine)
{
_surfaceInt->Perform( gridLine._line, 0.0, gridLine._length );
if ( !_surfaceInt->IsDone() ) return;
for ( int i = 1; i <= _surfaceInt->NbPnt(); ++i )
{
_transition = Transition( _surfaceInt->Transition( i ) );
_w = _surfaceInt->WParameter( i );
addIntPoint(/*toClassify=*/false);
}
}
#ifdef WITH_TBB
//================================================================================
/*
* check if its face can be safely intersected in a thread
*/
bool FaceGridIntersector::IsThreadSafe(set< const Standard_Transient* >& noSafeTShapes) const
{
bool isSafe = true;
// check surface
TopLoc_Location loc;
Handle(Geom_Surface) surf = BRep_Tool::Surface( _face, loc );
Handle(Geom_RectangularTrimmedSurface) ts =
Handle(Geom_RectangularTrimmedSurface)::DownCast( surf );
while( !ts.IsNull() ) {
surf = ts->BasisSurface();
ts = Handle(Geom_RectangularTrimmedSurface)::DownCast(surf);
}
if ( surf->IsKind( STANDARD_TYPE(Geom_BSplineSurface )) ||
surf->IsKind( STANDARD_TYPE(Geom_BezierSurface )))
if ( !noSafeTShapes.insert( _face.TShape().get() ).second )
isSafe = false;
double f, l;
TopExp_Explorer exp( _face, TopAbs_EDGE );
for ( ; exp.More(); exp.Next() )
{
bool edgeIsSafe = true;
const TopoDS_Edge& e = TopoDS::Edge( exp.Current() );
// check 3d curve
{
Handle(Geom_Curve) c = BRep_Tool::Curve( e, loc, f, l);
if ( !c.IsNull() )
{
Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(c);
while( !tc.IsNull() ) {
c = tc->BasisCurve();
tc = Handle(Geom_TrimmedCurve)::DownCast(c);
}
if ( c->IsKind( STANDARD_TYPE(Geom_BSplineCurve )) ||
c->IsKind( STANDARD_TYPE(Geom_BezierCurve )))
edgeIsSafe = false;
}
}
// check 2d curve
if ( edgeIsSafe )
{
Handle(Geom2d_Curve) c2 = BRep_Tool::CurveOnSurface( e, surf, loc, f, l);
if ( !c2.IsNull() )
{
Handle(Geom2d_TrimmedCurve) tc = Handle(Geom2d_TrimmedCurve)::DownCast(c2);
while( !tc.IsNull() ) {
c2 = tc->BasisCurve();
tc = Handle(Geom2d_TrimmedCurve)::DownCast(c2);
}
if ( c2->IsKind( STANDARD_TYPE(Geom2d_BSplineCurve )) ||
c2->IsKind( STANDARD_TYPE(Geom2d_BezierCurve )))
edgeIsSafe = false;
}
}
if ( !edgeIsSafe && !noSafeTShapes.insert( e.TShape().get() ).second )
isSafe = false;
}
return isSafe;
}
#endif
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,503 @@
// Copyright (C) 2016-2024 CEA, EDF
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
// File : StdMeshers_Cartesian_3D_Hexahedron.hxx
// Module : SMESH
// Purpose: Make BodyFitting mesh algorithm more modular and testable
//
#ifndef _SMESH_Cartesian_3D_HEXAHEDRON_HXX_
#define _SMESH_Cartesian_3D_HEXAHEDRON_HXX_
// BOOST
#include <boost/container/flat_map.hpp>
// STD
#include <utilities.h>
#include <vector>
// SMESH
#include "SMESH_StdMeshers.hxx"
#include "StdMeshers_Cartesian_3D_Grid.hxx"
using namespace std;
using namespace SMESH;
namespace
{
// --------------------------------------------------------------------------
/*!
* \brief Return cells sharing a link
*/
struct CellsAroundLink
{
int _iDir;
int _dInd[4][3];
size_t _nbCells[3];
int _i,_j,_k;
Grid* _grid;
CellsAroundLink( Grid* grid, int iDir ):
_iDir( iDir ),
_dInd{ {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0} },
_nbCells{ grid->_coords[0].size() - 1,
grid->_coords[1].size() - 1,
grid->_coords[2].size() - 1 },
_grid( grid )
{
const int iDirOther[3][2] = {{ 1,2 },{ 0,2 },{ 0,1 }};
_dInd[1][ iDirOther[iDir][0] ] = -1;
_dInd[2][ iDirOther[iDir][1] ] = -1;
_dInd[3][ iDirOther[iDir][0] ] = -1; _dInd[3][ iDirOther[iDir][1] ] = -1;
}
void Init( int i, int j, int k, int link12 = 0 )
{
int iL = link12 % 4;
_i = i - _dInd[iL][0];
_j = j - _dInd[iL][1];
_k = k - _dInd[iL][2];
}
bool GetCell( int iL, int& i, int& j, int& k, int& cellIndex, int& linkIndex )
{
i = _i + _dInd[iL][0];
j = _j + _dInd[iL][1];
k = _k + _dInd[iL][2];
if ( i < 0 || i >= (int)_nbCells[0] ||
j < 0 || j >= (int)_nbCells[1] ||
k < 0 || k >= (int)_nbCells[2] )
return false;
cellIndex = _grid->CellIndex( i,j,k );
linkIndex = iL + _iDir * 4;
return true;
}
};
}
// --------------------------------------------------------------------------
/*!
* \brief Class representing topology of the hexahedron and creating a mesh
* volume basing on analysis of hexahedron intersection with geometry
*/
class STDMESHERS_EXPORT Hexahedron
{
// --------------------------------------------------------------------------------
struct _Face;
struct _Link;
enum IsInternalFlag { IS_NOT_INTERNAL, IS_INTERNAL, IS_CUT_BY_INTERNAL_FACE };
// --------------------------------------------------------------------------------
struct _Node //!< node either at a hexahedron corner or at intersection
{
const SMDS_MeshNode* _node; // mesh node at hexahedron corner
const SMDS_MeshNode* _boundaryCornerNode; // missing mesh node due to hex truncation on the boundary
const B_IntersectPoint* _intPoint;
const _Face* _usedInFace;
char _isInternalFlags;
_Node(const SMDS_MeshNode* n=0, const B_IntersectPoint* ip=0)
:_node(n), _intPoint(ip), _usedInFace(0), _isInternalFlags(0) {}
const SMDS_MeshNode* Node() const
{ return ( _intPoint && _intPoint->_node ) ? _intPoint->_node : _node; }
const SMDS_MeshNode* BoundaryNode() const
{ return _node ? _node : _boundaryCornerNode; }
const E_IntersectPoint* EdgeIntPnt() const
{ return static_cast< const E_IntersectPoint* >( _intPoint ); }
const F_IntersectPoint* FaceIntPnt() const
{ return static_cast< const F_IntersectPoint* >( _intPoint ); }
const vector< TGeomID >& faces() const { return _intPoint->_faceIDs; }
TGeomID face(size_t i) const { return _intPoint->_faceIDs[ i ]; }
void SetInternal( IsInternalFlag intFlag ) { _isInternalFlags |= intFlag; }
bool IsCutByInternal() const { return _isInternalFlags & IS_CUT_BY_INTERNAL_FACE; }
bool IsUsedInFace( const _Face* polygon = 0 )
{
return polygon ? ( _usedInFace == polygon ) : bool( _usedInFace );
}
TGeomID IsLinked( const B_IntersectPoint* other,
TGeomID avoidFace=-1 ) const // returns id of a common face
{
return _intPoint ? _intPoint->HasCommonFace( other, avoidFace ) : 0;
}
bool IsOnFace( TGeomID faceID ) const // returns true if faceID is found
{
return _intPoint ? _intPoint->IsOnFace( faceID ) : false;
}
size_t GetCommonFaces( const B_IntersectPoint * other, TGeomID* common ) const
{
return _intPoint && other ? _intPoint->GetCommonFaces( other, common ) : 0;
}
gp_Pnt Point() const
{
if ( const SMDS_MeshNode* n = Node() )
return SMESH_NodeXYZ( n );
if ( const E_IntersectPoint* eip =
dynamic_cast< const E_IntersectPoint* >( _intPoint ))
return eip->_point;
return gp_Pnt( 1e100, 0, 0 );
}
TGeomID ShapeID() const
{
if ( const E_IntersectPoint* eip = dynamic_cast< const E_IntersectPoint* >( _intPoint ))
return eip->_shapeID;
return 0;
}
void Add( const E_IntersectPoint* ip );
};
// --------------------------------------------------------------------------------
struct _Link // link connecting two _Node's
{
_Node* _nodes[2];
_Face* _faces[2]; // polygons sharing a link
vector< const F_IntersectPoint* > _fIntPoints; // GridLine intersections with FACEs
vector< _Node* > _fIntNodes; // _Node's at _fIntPoints
vector< _Link > _splits;
_Link(): _faces{ 0, 0 } {}
};
// --------------------------------------------------------------------------------
struct _OrientedLink
{
_Link* _link;
bool _reverse;
_OrientedLink( _Link* link=0, bool reverse=false ): _link(link), _reverse(reverse) {}
void Reverse() { _reverse = !_reverse; }
size_t NbResultLinks() const { return _link->_splits.size(); }
_OrientedLink ResultLink(int i) const
{
return _OrientedLink(&_link->_splits[_reverse ? NbResultLinks()-i-1 : i],_reverse);
}
_Node* FirstNode() const { return _link->_nodes[ _reverse ]; }
_Node* LastNode() const { return _link->_nodes[ !_reverse ]; }
operator bool() const { return _link; }
vector< TGeomID > GetNotUsedFace(const set<TGeomID>& usedIDs ) const // returns supporting FACEs
{
vector< TGeomID > faces;
const B_IntersectPoint *ip0, *ip1;
if (( ip0 = _link->_nodes[0]->_intPoint ) &&
( ip1 = _link->_nodes[1]->_intPoint ))
{
for ( size_t i = 0; i < ip0->_faceIDs.size(); ++i )
if ( ip1->IsOnFace ( ip0->_faceIDs[i] ) &&
!usedIDs.count( ip0->_faceIDs[i] ) )
faces.push_back( ip0->_faceIDs[i] );
}
return faces;
}
bool HasEdgeNodes() const
{
return ( dynamic_cast< const E_IntersectPoint* >( _link->_nodes[0]->_intPoint ) ||
dynamic_cast< const E_IntersectPoint* >( _link->_nodes[1]->_intPoint ));
}
int NbFaces() const
{
return !_link->_faces[0] ? 0 : 1 + bool( _link->_faces[1] );
}
void AddFace( _Face* f )
{
if ( _link->_faces[0] )
{
_link->_faces[1] = f;
}
else
{
_link->_faces[0] = f;
_link->_faces[1] = 0;
}
}
void RemoveFace( _Face* f )
{
if ( !_link->_faces[0] ) return;
if ( _link->_faces[1] == f )
{
_link->_faces[1] = 0;
}
else if ( _link->_faces[0] == f )
{
_link->_faces[0] = 0;
if ( _link->_faces[1] )
{
_link->_faces[0] = _link->_faces[1];
_link->_faces[1] = 0;
}
}
}
};
// --------------------------------------------------------------------------------
struct _SplitIterator //! set to _hexLinks splits on one side of INTERNAL FACEs
{
struct _Split // data of a link split
{
int _linkID; // hex link ID
_Node* _nodes[2];
int _iCheckIteration; // iteration where split is tried as Hexahedron split
_Link* _checkedSplit; // split set to hex links
bool _isUsed; // used in a volume
_Split( _Link & split, int iLink ):
_linkID( iLink ), _nodes{ split._nodes[0], split._nodes[1] },
_iCheckIteration( 0 ), _isUsed( false )
{}
bool IsCheckedOrUsed( bool used ) const { return used ? _isUsed : _iCheckIteration > 0; }
};
_Link* _hexLinks;
std::vector< _Split > _splits;
int _iterationNb;
size_t _nbChecked;
size_t _nbUsed;
std::vector< _Node* > _freeNodes; // nodes reached while composing a split set
_SplitIterator( _Link* hexLinks ):
_hexLinks( hexLinks ), _iterationNb(0), _nbChecked(0), _nbUsed(0)
{
_freeNodes.reserve( 12 );
_splits.reserve( 24 );
for ( int iL = 0; iL < 12; ++iL )
for ( size_t iS = 0; iS < _hexLinks[ iL ]._splits.size(); ++iS )
_splits.emplace_back( _hexLinks[ iL ]._splits[ iS ], iL );
Next();
}
bool More() const { return _nbUsed < _splits.size(); }
bool Next();
};
// --------------------------------------------------------------------------------
struct _Face
{
SMESH_Block::TShapeID _name;
vector< _OrientedLink > _links; // links on GridLine's
vector< _Link > _polyLinks; // links added to close a polygonal face
vector< _Node* > _eIntNodes; // nodes at intersection with EDGEs
_Face():_name( SMESH_Block::ID_NONE )
{}
bool IsPolyLink( const _OrientedLink& ol )
{
return _polyLinks.empty() ? false :
( &_polyLinks[0] <= ol._link && ol._link <= &_polyLinks.back() );
}
void AddPolyLink(_Node* n0, _Node* n1, _Face* faceToFindEqual=0)
{
if ( faceToFindEqual && faceToFindEqual != this ) {
for ( size_t iL = 0; iL < faceToFindEqual->_polyLinks.size(); ++iL )
if ( faceToFindEqual->_polyLinks[iL]._nodes[0] == n1 &&
faceToFindEqual->_polyLinks[iL]._nodes[1] == n0 )
{
_links.push_back
( _OrientedLink( & faceToFindEqual->_polyLinks[iL], /*reverse=*/true ));
return;
}
}
_Link l;
l._nodes[0] = n0;
l._nodes[1] = n1;
_polyLinks.push_back( l );
_links.push_back( _OrientedLink( &_polyLinks.back() ));
}
};
// --------------------------------------------------------------------------------
struct _volumeDef // holder of nodes of a volume mesh element
{
typedef void* _ptr;
struct _nodeDef
{
const SMDS_MeshNode* _node; // mesh node at hexahedron corner
const B_IntersectPoint* _intPoint;
_nodeDef(): _node(0), _intPoint(0) {}
_nodeDef( _Node* n ): _node( n->_node), _intPoint( n->_intPoint ) {}
const SMDS_MeshNode* Node() const
{ return ( _intPoint && _intPoint->_node ) ? _intPoint->_node : _node; }
const E_IntersectPoint* EdgeIntPnt() const
{ return static_cast< const E_IntersectPoint* >( _intPoint ); }
_ptr Ptr() const { return Node() ? (_ptr) Node() : (_ptr) EdgeIntPnt(); }
bool operator==(const _nodeDef& other ) const { return Ptr() == other.Ptr(); }
};
vector< _nodeDef > _nodes;
vector< int > _quantities;
_volumeDef* _next; // to store several _volumeDefs in a chain
TGeomID _solidID;
double _size;
const SMDS_MeshElement* _volume; // new volume
std::vector<const SMDS_MeshElement*> _brotherVolume; // produced due to poly split
vector< SMESH_Block::TShapeID > _names; // name of side a polygon originates from
_volumeDef(): _next(0), _solidID(0), _size(0), _volume(0) {}
~_volumeDef() { delete _next; }
_volumeDef( _volumeDef& other ):
_next(0), _solidID( other._solidID ), _size( other._size ), _volume( other._volume )
{ _nodes.swap( other._nodes ); _quantities.swap( other._quantities ); other._volume = 0;
_names.swap( other._names ); }
size_t size() const { return 1 + ( _next ? _next->size() : 0 ); } // nb _volumeDef in a chain
_volumeDef* at(int index)
{ return index == 0 ? this : ( _next ? _next->at(index-1) : _next ); }
void Set( _Node** nodes, int nb )
{ _nodes.assign( nodes, nodes + nb ); }
void SetNext( _volumeDef* vd )
{ if ( _next ) { _next->SetNext( vd ); } else { _next = vd; }}
bool IsEmpty() const { return (( _nodes.empty() ) &&
( !_next || _next->IsEmpty() )); }
bool IsPolyhedron() const { return ( !_quantities.empty() ||
( _next && !_next->_quantities.empty() )); }
struct _linkDef: public std::pair<_ptr,_ptr> // to join polygons in removeExcessSideDivision()
{
_nodeDef _node1;//, _node2;
mutable /*const */_linkDef *_prev, *_next;
size_t _loopIndex;
_linkDef():_prev(0), _next(0) {}
void init( const _nodeDef& n1, const _nodeDef& n2, size_t iLoop )
{
_node1 = n1; //_node2 = n2;
_loopIndex = iLoop;
first = n1.Ptr();
second = n2.Ptr();
if ( first > second ) std::swap( first, second );
}
void setNext( _linkDef* next )
{
_next = next;
next->_prev = this;
}
};
};
// topology of a hexahedron
_Node _hexNodes [8];
_Link _hexLinks [12];
_Face _hexQuads [6];
// faces resulted from hexahedron intersection
vector< _Face > _polygons;
// intresections with EDGEs
vector< const E_IntersectPoint* > _eIntPoints;
// additional nodes created at intersection points
vector< _Node > _intNodes;
// nodes inside the hexahedron (at VERTEXes) refer to _intNodes
vector< _Node* > _vIntNodes;
// computed volume elements
_volumeDef _volumeDefs;
Grid* _grid;
double _sideLength[3];
int _nbCornerNodes, _nbFaceIntNodes, _nbBndNodes;
int _origNodeInd; // index of _hexNodes[0] node within the _grid
size_t _i,_j,_k;
bool _hasTooSmall;
int _cellID;
public:
Hexahedron(Grid* grid);
int MakeElements(SMESH_MesherHelper& helper,
const map< TGeomID, vector< TGeomID > >& edge2faceIDsMap, const int numOfThreads = 1 );
void computeElements( const Solid* solid = 0, int solidIndex = -1 );
private:
Hexahedron(const Hexahedron& other, size_t i, size_t j, size_t k, int cellID );
void init( size_t i, size_t j, size_t k, const Solid* solid=0 );
void init( size_t i );
void setIJK( size_t i );
/*Auxiliary methods to extract operations from monolitic compute method*/
void defineHexahedralFaces( std::vector< _OrientedLink >& splits, std::vector<_Node*>& chainNodes, std::set< TGeomID >& concaveFaces, bool toCheckSideDivision );
bool compute( const Solid* solid, const IsInternalFlag intFlag );
size_t getSolids( TGeomID ids[] );
bool isCutByInternalFace( IsInternalFlag & maxFlag );
void addEdges(SMESH_MesherHelper& helper,
vector< Hexahedron* >& intersectedHex,
const map< TGeomID, vector< TGeomID > >& edge2faceIDsMap);
gp_Pnt findIntPoint( double u1, double proj1, double u2, double proj2,
double proj, BRepAdaptor_Curve& curve,
const gp_XYZ& axis, const gp_XYZ& origin );
int getEntity( const E_IntersectPoint* ip, int* facets, int& sub );
bool addIntersection( const E_IntersectPoint* ip,
vector< Hexahedron* >& hexes,
int ijk[], int dIJK[] );
bool isQuadOnFace( const size_t iQuad );
bool findChain( _Node* n1, _Node* n2, _Face& quad, vector<_Node*>& chainNodes );
bool closePolygon( _Face* polygon, vector<_Node*>& chainNodes ) const;
bool findChainOnEdge( const vector< _OrientedLink >& splits,
const _OrientedLink& prevSplit,
const _OrientedLink& avoidSplit,
const std::set< TGeomID > & concaveFaces,
size_t & iS,
_Face& quad,
vector<_Node*>& chn);
int addVolumes(SMESH_MesherHelper& helper );
void addFaces( SMESH_MesherHelper& helper,
const vector< const SMDS_MeshElement* > & boundaryVolumes );
void addSegments( SMESH_MesherHelper& helper,
const map< TGeomID, vector< TGeomID > >& edge2faceIDsMap );
void getVolumes( vector< const SMDS_MeshElement* > & volumes );
void getBoundaryElems( vector< const SMDS_MeshElement* > & boundaryVolumes );
void removeExcessSideDivision(const vector< Hexahedron* >& allHexa);
void removeExcessNodes(vector< Hexahedron* >& allHexa);
void preventVolumesOverlapping();
TGeomID getAnyFace() const;
void cutByExtendedInternal( std::vector< Hexahedron* >& hexes,
const TColStd_MapOfInteger& intEdgeIDs );
gp_Pnt mostDistantInternalPnt( int hexIndex, const gp_Pnt& p1, const gp_Pnt& p2 );
bool isOutPoint( _Link& link, int iP, SMESH_MesherHelper& helper, const Solid* solid ) const;
void sortVertexNodes(vector<_Node*>& nodes, _Node* curNode, TGeomID face);
bool isInHole() const;
bool hasStrangeEdge() const;
bool checkPolyhedronSize( bool isCutByInternalFace, double & volSize ) const;
int checkPolyhedronValidity( _volumeDef* volDef, std::vector<std::vector<int>>& splitQuantities,
std::vector<std::vector<const SMDS_MeshNode*>>& splitNodes );
const SMDS_MeshElement* addPolyhedronToMesh( _volumeDef* volDef, SMESH_MesherHelper& helper, const std::vector<const SMDS_MeshNode*>& nodes,
const std::vector<int>& quantities );
bool addHexa ();
bool addTetra();
bool addPenta();
bool addPyra ();
bool debugDumpLink( _Link* link );
_Node* findEqualNode( vector< _Node* >& nodes,
const E_IntersectPoint* ip,
const double tol2 )
{
for ( size_t i = 0; i < nodes.size(); ++i )
if ( nodes[i]->EdgeIntPnt() == ip ||
nodes[i]->Point().SquareDistance( ip->_point ) <= tol2 )
return nodes[i];
return 0;
}
bool isCorner( const _Node* node ) const { return ( node >= &_hexNodes[0] &&
node - &_hexNodes[0] < 8 ); }
bool hasEdgesAround( const ConcaveFace* cf ) const;
bool isImplementEdges() const { return _grid->_edgeIntPool.nbElements(); }
bool isOutParam(const double uvw[3]) const;
typedef boost::container::flat_map< TGeomID, size_t > TID2Nb;
static void insertAndIncrement( TGeomID id, TID2Nb& id2nbMap )
{
TID2Nb::value_type s0( id, 0 );
TID2Nb::iterator id2nb = id2nbMap.insert( s0 ).first;
id2nb->second++;
}
}; // class Hexahedron
#endif

View File

@ -41,3 +41,10 @@ FOREACH(tfile ${CPP_TESTS})
ADD_TEST(${TEST_NAME} ${BASE_NAME} )
SET_TESTS_PROPERTIES(${TEST_NAME} PROPERTIES LABELS "${COMPONENT_NAME};${COMPONENT_NAME}_tests")
ENDFOREACH()
FOREACH(tfile ${UNIT_TESTS})
GET_FILENAME_COMPONENT(BASE_NAME ${tfile} NAME_WE)
SET(TEST_NAME SMESH_${BASE_NAME})
ADD_TEST(${TEST_NAME} ${BASE_NAME} )
SET_TESTS_PROPERTIES(${TEST_NAME} PROPERTIES LABELS "${COMPONENT_NAME};${COMPONENT_NAME}_tests")
ENDFOREACH()

View File

@ -0,0 +1,558 @@
DBRep_DrawableShape
CASCADE Topology V3, (c) Open Cascade
Locations 0
Curve2ds 32
1 0 0 1 0
1 0 0 1 0
1 10 0 0 -1
1 0 0 0 1
1 0 -10 1 0
1 0 0 1 0
1 0 0 0 -1
1 0 0 0 1
1 0 0 0 1
1 0 0 1 0
1 0 0 1 0
1 0 10 1 0
1 10 0 0 1
1 0 0 1 0
1 10 0 0 1
1 0 10 1 0
1 10 0 0 -1
1 10 0 0 1
1 0 0 0 1
1 0 10 1 0
1 0 -10 1 0
1 0 10 1 0
1 0 0 0 -1
1 10 0 0 1
2 5 5 1 0 -0 1 1
1 0 6 1 0
1 6.2831853071795862 -0 0 1
1 0 -0 0 1
1 0 9 1 0
2 0 0 1 0 -0 1 1
1 0 0 1 0
2 0 0 1 0 -0 1 1
Curves 16
1 -5 -5 0 0 0 1
1 -5 -5 10 -0 1 0
1 -5 5 0 0 0 1
1 -5 -5 0 -0 1 0
1 -5 -5 0 1 0 -0
1 5 -5 0 0 0 1
1 -5 -5 10 1 0 -0
1 -5 5 10 1 0 -0
1 5 -5 10 -0 1 0
1 -5 5 0 1 0 -0
1 5 5 0 0 0 1
1 5 -5 0 -0 1 0
2 0 0 0 0 0 1 1 0 -0 -0 1 0 1
1 1 -2.4492935982947064e-16 -6 0 0 1
2 0 0 3 0 0 1 1 0 -0 -0 1 0 1
2 0 0 -6 0 0 1 1 0 -0 -0 1 0 1
Polygon3D 0
PolygonOnTriangulations 36
2 1 2
p 0.0640000008 1 0 10
2 1 3
p 0.0640000008 1 0 10
2 2 4
p 0.0640000008 1 0 10
2 1 2
p 0.0640000008 1 0 10
2 3 4
p 0.0640000008 1 0 10
2 1 3
p 0.0640000008 1 0 10
2 1 3
p 0.0640000008 1 0 10
2 1 2
p 0.0640000008 1 0 10
2 1 2
p 0.0640000008 1 0 10
2 1 3
p 0.0640000008 1 0 10
2 2 4
p 0.0640000008 1 0 10
2 1 2
p 0.0640000008 1 0 10
2 3 4
p 0.0640000008 1 0 10
2 1 3
p 0.0640000008 1 0 10
2 2 4
p 0.0640000008 1 0 10
2 3 4
p 0.0640000008 1 0 10
2 3 4
p 0.0640000008 1 0 10
2 2 4
p 0.0640000008 1 0 10
2 1 2
p 0.0640000008 1 0 10
2 2 4
p 0.0640000008 1 0 10
2 2 4
p 0.0640000008 1 0 10
2 3 4
p 0.0640000008 1 0 10
2 3 4
p 0.0640000008 1 0 10
2 1 3
p 0.0640000008 1 0 10
37 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 1
p 0.0640000008 1 0 0.174532925199433 0.349065850398866 0.523598775598299 0.698131700797732 0.872664625997165 1.0471975511966 1.22173047639603 1.39626340159546 1.5707963267949 1.74532925199433 1.91986217719376 2.0943951023932 2.26892802759263 2.44346095279206 2.61799387799149 2.79252680319093 2.96705972839036 3.14159265358979 3.31612557878922 3.49065850398866 3.66519142918809 3.83972435438752 4.01425727958696 4.18879020478639 4.36332312998582 4.53785605518525 4.71238898038469 4.88692190558412 5.06145483078355 5.23598775598299 5.41052068118242 5.58505360638185 5.75958653158128 5.93411945678072 6.10865238198015 6.28318530717959
37 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
p 0.0640000008 1 0 0.174532925199433 0.349065850398866 0.523598775598299 0.698131700797732 0.872664625997165 1.0471975511966 1.22173047639603 1.39626340159546 1.5707963267949 1.74532925199433 1.91986217719376 2.0943951023932 2.26892802759263 2.44346095279206 2.61799387799149 2.79252680319093 2.96705972839036 3.14159265358979 3.31612557878922 3.49065850398866 3.66519142918809 3.83972435438752 4.01425727958696 4.18879020478639 4.36332312998582 4.53785605518525 4.71238898038469 4.88692190558412 5.06145483078355 5.23598775598299 5.41052068118242 5.58505360638185 5.75958653158128 5.93411945678072 6.10865238198015 6.28318530717959
37 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 5
p 0.0640000008 1 0 0.174532925199433 0.349065850398866 0.523598775598299 0.698131700797732 0.872664625997165 1.0471975511966 1.22173047639603 1.39626340159546 1.5707963267949 1.74532925199433 1.91986217719376 2.0943951023932 2.26892802759263 2.44346095279206 2.61799387799149 2.79252680319093 2.96705972839036 3.14159265358979 3.31612557878922 3.49065850398866 3.66519142918809 3.83972435438752 4.01425727958696 4.18879020478639 4.36332312998582 4.53785605518525 4.71238898038469 4.88692190558412 5.06145483078355 5.23598775598299 5.41052068118242 5.58505360638185 5.75958653158128 5.93411945678072 6.10865238198015 6.28318530717959
37 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 1
p 0.0640000008 1 0 0.174532925199433 0.349065850398866 0.523598775598299 0.698131700797732 0.872664625997165 1.0471975511966 1.22173047639603 1.39626340159546 1.5707963267949 1.74532925199433 1.91986217719376 2.0943951023932 2.26892802759263 2.44346095279206 2.61799387799149 2.79252680319093 2.96705972839036 3.14159265358979 3.31612557878922 3.49065850398866 3.66519142918809 3.83972435438752 4.01425727958696 4.18879020478639 4.36332312998582 4.53785605518525 4.71238898038469 4.88692190558412 5.06145483078355 5.23598775598299 5.41052068118242 5.58505360638185 5.75958653158128 5.93411945678072 6.10865238198015 6.28318530717959
2 1 2
p 0.0640000008 1 6 9
2 39 3
p 0.0640000008 1 6 9
37 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 2
p 0.0640000008 1 0 0.174532925199433 0.349065850398866 0.523598775598299 0.698131700797732 0.872664625997165 1.0471975511966 1.22173047639603 1.39626340159546 1.5707963267949 1.74532925199433 1.91986217719376 2.0943951023932 2.26892802759263 2.44346095279206 2.61799387799149 2.79252680319093 2.96705972839036 3.14159265358979 3.31612557878922 3.49065850398866 3.66519142918809 3.83972435438752 4.01425727958696 4.18879020478639 4.36332312998582 4.53785605518525 4.71238898038469 4.88692190558412 5.06145483078355 5.23598775598299 5.41052068118242 5.58505360638185 5.75958653158128 5.93411945678072 6.10865238198015 6.28318530717959
37 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 1
p 0.0640000008 1 0 0.174532925199433 0.349065850398866 0.523598775598299 0.698131700797732 0.872664625997165 1.0471975511966 1.22173047639603 1.39626340159546 1.5707963267949 1.74532925199433 1.91986217719376 2.0943951023932 2.26892802759263 2.44346095279206 2.61799387799149 2.79252680319093 2.96705972839036 3.14159265358979 3.31612557878922 3.49065850398866 3.66519142918809 3.83972435438752 4.01425727958696 4.18879020478639 4.36332312998582 4.53785605518525 4.71238898038469 4.88692190558412 5.06145483078355 5.23598775598299 5.41052068118242 5.58505360638185 5.75958653158128 5.93411945678072 6.10865238198015 6.28318530717959
2 38 1
p 0.0640000008 1 0 6
2 74 37
p 0.0640000008 1 0 6
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
p 0.0640000008 1 0 0.174532925199433 0.349065850398866 0.523598775598299 0.698131700797732 0.872664625997165 1.0471975511966 1.22173047639603 1.39626340159546 1.5707963267949 1.74532925199433 1.91986217719376 2.0943951023932 2.26892802759263 2.44346095279206 2.61799387799149 2.79252680319093 2.96705972839036 3.14159265358979 3.31612557878922 3.49065850398866 3.66519142918809 3.83972435438752 4.01425727958696 4.18879020478639 4.36332312998582 4.53785605518525 4.71238898038469 4.88692190558412 5.06145483078355 5.23598775598299 5.41052068118242 5.58505360638185 5.75958653158128 5.93411945678072 6.10865238198015 6.28318530717959
37 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 1
p 0.0640000008 1 0 0.174532925199433 0.349065850398866 0.523598775598299 0.698131700797732 0.872664625997165 1.0471975511966 1.22173047639603 1.39626340159546 1.5707963267949 1.74532925199433 1.91986217719376 2.0943951023932 2.26892802759263 2.44346095279206 2.61799387799149 2.79252680319093 2.96705972839036 3.14159265358979 3.31612557878922 3.49065850398866 3.66519142918809 3.83972435438752 4.01425727958696 4.18879020478639 4.36332312998582 4.53785605518525 4.71238898038469 4.88692190558412 5.06145483078355 5.23598775598299 5.41052068118242 5.58505360638185 5.75958653158128 5.93411945678072 6.10865238198015 6.28318530717959
Surfaces 9
1 -5 -5 0 1 0 -0 0 0 1 0 -1 0
1 -5 -5 0 -0 1 0 0 0 1 1 0 -0
1 -5 -5 10 0 0 1 1 0 -0 -0 1 0
1 -5 5 0 -0 1 0 0 0 1 1 0 -0
1 -5 -5 0 0 0 1 1 0 -0 -0 1 0
1 5 -5 0 1 0 -0 0 0 1 0 -1 0
2 0 0 -6 0 0 1 1 0 -0 -0 1 0 1
1 0 0 3 0 0 1 1 0 -0 -0 1 0
1 0 0 -6 0 0 1 1 0 -0 -0 1 0
Triangulations 11
4 2 1 0 2.22044604925031e-16
-5 -5 0 -5 -5 10 -5 5 0 -5 5 10 0 0 10 0 0 -10 10 -10 2 1 3 2 3 4
4 2 1 0 2.22044604925031e-16
-5 -5 0 5 -5 0 -5 -5 10 5 -5 10 0 0 0 10 10 0 10 10 4 2 1 4 1 3
4 2 1 0 3.14018491736755e-16
-5 -5 10 -5 5 10 5 -5 10 5 5 10 0 0 0 10 10 0 10 10 4 2 1 4 1 3
4 2 1 0 2.22044604925031e-16
-5 5 0 5 5 0 -5 5 10 5 5 10 0 0 0 10 10 0 10 10 4 2 1 4 1 3
40 40 1 0 9.93013661298909e-16
-5 -5 0 -5 5 0 5 -5 0 5 5 0 1 -2.44929359829471e-16 0 0.984807753012208 0.17364817766693 0 0.939692620785908 0.342020143325669 0 0.866025403784439 0.5 0 0.766044443118978 0.642787609686539 0 0.642787609686539 0.766044443118978 0 0.5 0.866025403784439 0 0.342020143325669 0.939692620785908 0 0.17364817766693 0.984807753012208 0 6.12323399573677e-17 1 0 -0.17364817766693 0.984807753012208 0 -0.342020143325669 0.939692620785908 0 -0.5 0.866025403784439 0 -0.642787609686539 0.766044443118978 0 -0.766044443118978 0.64278760968654 0 -0.866025403784438 0.500000000000001 0 -0.939692620785908 0.34202014332567 0 -0.984807753012208 0.173648177666932 0 -1 1.45473230946492e-15 0 -0.984807753012208 -0.173648177666929 0 -0.939692620785909 -0.342020143325667 0 -0.86602540378444 -0.499999999999998 0 -0.766044443118979 -0.642787609686538 0 -0.642787609686541 -0.766044443118977 0 -0.500000000000002 -0.866025403784437 0 -0.342020143325671 -0.939692620785908 0 -0.173648177666933 -0.984807753012208 0 -2.84823227897248e-15 -1 0 0.173648177666927 -0.984807753012209 0 0.342020143325666 -0.93969262078591 0 0.499999999999997 -0.86602540378444 0 0.642787609686536 -0.76604444311898 0 0.766044443118976 -0.642787609686542 0 0.866025403784437 -0.500000000000004 0 0.939692620785907 -0.342020143325673 0 0.984807753012207 -0.173648177666935 0 0 0 0 10 10 0 10 10 6 5 5.98480775301221 5.17364817766693 5.93969262078591 5.34202014332567 5.86602540378444 5.5 5.76604444311898 5.64278760968654 5.64278760968654 5.76604444311898 5.5 5.86602540378444 5.34202014332567 5.93969262078591 5.17364817766693 5.98480775301221 5 6 4.82635182233307 5.98480775301221 4.65797985667433 5.93969262078591 4.5 5.86602540378444 4.35721239031346 5.76604444311898 4.23395555688102 5.64278760968654 4.13397459621556 5.5 4.06030737921409 5.34202014332567 4.01519224698779 5.17364817766693 4 5 4.01519224698779 4.82635182233307 4.06030737921409 4.65797985667433 4.13397459621556 4.5 4.23395555688102 4.35721239031346 4.35721239031346 4.23395555688102 4.5 4.13397459621556 4.65797985667433 4.06030737921409 4.82635182233307 4.01519224698779 5 4 5.17364817766693 4.01519224698779 5.34202014332567 4.06030737921409 5.5 4.13397459621556 5.64278760968654 4.23395555688102 5.76604444311898 4.35721239031346 5.86602540378444 4.5 5.93969262078591 4.65797985667433 5.98480775301221 4.82635182233307 27 1 28 29 28 1 26 1 27 30 29 1 25 1 26 31 30 1 24 1 25 32 31 1 23 1 24 2 20 19 2 21 20 2 22 21 2 23 22 2 1 23 3 33 32 3 34 33 3 35 34 3 36 35 3 32 1 37 36 3 18 2 19 38 37 3 17 2 18 39 38 3 16 2 17 40 39 3 15 2 16 5 40 3 14 2 15 4 5 3 4 6 5 4 7 6 4 8 7 4 9 8 4 10 9 4 11 10 4 12 11 4 13 12 4 14 13 4 2 14
4 2 1 0 2.22044604925031e-16
5 -5 0 5 -5 10 5 5 0 5 5 10 0 0 10 0 0 -10 10 -10 2 1 3 2 3 4
74 72 1 0 0.00380530190825463
1 -2.44929359829471e-16 0 1 -2.44929359829471e-16 3 1 -2.44929359829471e-16 3 0.984807753012208 0.17364817766693 3 0.939692620785908 0.342020143325669 3 0.866025403784439 0.5 3 0.766044443118978 0.642787609686539 3 0.642787609686539 0.766044443118978 3 0.5 0.866025403784439 3 0.342020143325669 0.939692620785908 3 0.17364817766693 0.984807753012208 3 6.12323399573677e-17 1 3 -0.17364817766693 0.984807753012208 3 -0.342020143325669 0.939692620785908 3 -0.5 0.866025403784439 3 -0.642787609686539 0.766044443118978 3 -0.766044443118978 0.64278760968654 3 -0.866025403784438 0.500000000000001 3 -0.939692620785908 0.34202014332567 3 -0.984807753012208 0.173648177666932 3 -1 1.45473230946492e-15 3 -0.984807753012208 -0.173648177666929 3 -0.939692620785909 -0.342020143325667 3 -0.86602540378444 -0.499999999999998 3 -0.766044443118979 -0.642787609686538 3 -0.642787609686541 -0.766044443118977 3 -0.500000000000002 -0.866025403784437 3 -0.342020143325671 -0.939692620785908 3 -0.173648177666933 -0.984807753012208 3 -2.84823227897248e-15 -1 3 0.173648177666927 -0.984807753012209 3 0.342020143325666 -0.93969262078591 3 0.499999999999997 -0.86602540378444 3 0.642787609686536 -0.76604444311898 3 0.766044443118976 -0.642787609686542 3 0.866025403784437 -0.500000000000004 3 0.939692620785907 -0.342020143325673 3 0.984807753012207 -0.173648177666935 3 1 -2.44929359829471e-16 0 0.984807753012208 0.17364817766693 0 0.939692620785908 0.342020143325669 0 0.866025403784439 0.5 0 0.766044443118978 0.642787609686539 0 0.642787609686539 0.766044443118978 0 0.5 0.866025403784439 0 0.342020143325669 0.939692620785908 0 0.17364817766693 0.984807753012208 0 6.12323399573677e-17 1 0 -0.17364817766693 0.984807753012208 0 -0.342020143325669 0.939692620785908 0 -0.5 0.866025403784439 0 -0.642787609686539 0.766044443118978 0 -0.766044443118978 0.64278760968654 0 -0.866025403784438 0.500000000000001 0 -0.939692620785908 0.34202014332567 0 -0.984807753012208 0.173648177666932 0 -1 1.45473230946492e-15 0 -0.984807753012208 -0.173648177666929 0 -0.939692620785909 -0.342020143325667 0 -0.86602540378444 -0.499999999999998 0 -0.766044443118979 -0.642787609686538 0 -0.642787609686541 -0.766044443118977 0 -0.500000000000002 -0.866025403784437 0 -0.342020143325671 -0.939692620785908 0 -0.173648177666933 -0.984807753012208 0 -2.84823227897248e-15 -1 0 0.173648177666927 -0.984807753012209 0 0.342020143325666 -0.93969262078591 0 0.499999999999997 -0.86602540378444 0 0.642787609686536 -0.76604444311898 0 0.766044443118976 -0.642787609686542 0 0.866025403784437 -0.500000000000004 0 0.939692620785907 -0.342020143325673 0 0.984807753012207 -0.173648177666935 0 6.28318530717959 6 6.28318530717959 9 0 9 0.174532925199433 9 0.349065850398866 9 0.523598775598299 9 0.698131700797732 9 0.872664625997165 9 1.0471975511966 9 1.22173047639603 9 1.39626340159546 9 1.5707963267949 9 1.74532925199433 9 1.91986217719376 9 2.0943951023932 9 2.26892802759263 9 2.44346095279206 9 2.61799387799149 9 2.79252680319093 9 2.96705972839036 9 3.14159265358979 9 3.31612557878922 9 3.49065850398866 9 3.66519142918809 9 3.83972435438752 9 4.01425727958696 9 4.18879020478639 9 4.36332312998582 9 4.53785605518525 9 4.71238898038469 9 4.88692190558412 9 5.06145483078355 9 5.23598775598299 9 5.41052068118242 9 5.58505360638185 9 5.75958653158128 9 5.93411945678072 9 6.10865238198015 9 0 6 0.174532925199433 6 0.349065850398866 6 0.523598775598299 6 0.698131700797732 6 0.872664625997165 6 1.0471975511966 6 1.22173047639603 6 1.39626340159546 6 1.5707963267949 6 1.74532925199433 6 1.91986217719376 6 2.0943951023932 6 2.26892802759263 6 2.44346095279206 6 2.61799387799149 6 2.79252680319093 6 2.96705972839036 6 3.14159265358979 6 3.31612557878922 6 3.49065850398866 6 3.66519142918809 6 3.83972435438752 6 4.01425727958696 6 4.18879020478639 6 4.36332312998582 6 4.53785605518525 6 4.71238898038469 6 4.88692190558412 6 5.06145483078355 6 5.23598775598299 6 5.41052068118242 6 5.58505360638185 6 5.75958653158128 6 5.93411945678072 6 6.10865238198015 6 4 3 39 4 39 40 5 40 41 5 4 40 6 41 42 6 5 41 7 42 43 7 43 44 7 6 42 8 44 45 8 7 44 9 8 45 10 9 45 10 45 46 10 46 47 11 10 47 11 47 48 12 11 48 13 12 48 13 48 49 14 13 49 14 49 50 14 50 51 15 14 51 16 15 51 16 51 52 16 52 53 17 16 53 18 17 53 18 53 54 19 18 54 19 54 55 20 19 55 20 55 56 21 20 56 21 56 57 22 21 57 22 57 58 22 58 59 23 22 59 24 59 60 24 23 59 25 60 61 25 61 62 25 24 60 26 25 62 27 62 63 27 26 62 28 63 64 28 27 63 29 64 65 29 28 64 30 65 66 30 29 65 31 66 67 31 30 66 32 67 68 32 31 67 33 68 69 33 32 68 34 33 69 34 69 70 34 70 71 35 34 71 36 35 71 36 71 72 37 36 72 37 72 73 38 37 73 38 73 74 2 38 74 2 74 1
74 72 1 0 0.00380530190825463
1 -2.44929359829471e-16 0 0.984807753012208 0.17364817766693 0 0.939692620785908 0.342020143325669 0 0.866025403784439 0.5 0 0.766044443118978 0.642787609686539 0 0.642787609686539 0.766044443118978 0 0.5 0.866025403784439 0 0.342020143325669 0.939692620785908 0 0.17364817766693 0.984807753012208 0 6.12323399573677e-17 1 0 -0.17364817766693 0.984807753012208 0 -0.342020143325669 0.939692620785908 0 -0.5 0.866025403784439 0 -0.642787609686539 0.766044443118978 0 -0.766044443118978 0.64278760968654 0 -0.866025403784438 0.500000000000001 0 -0.939692620785908 0.34202014332567 0 -0.984807753012208 0.173648177666932 0 -1 1.45473230946492e-15 0 -0.984807753012208 -0.173648177666929 0 -0.939692620785909 -0.342020143325667 0 -0.86602540378444 -0.499999999999998 0 -0.766044443118979 -0.642787609686538 0 -0.642787609686541 -0.766044443118977 0 -0.500000000000002 -0.866025403784437 0 -0.342020143325671 -0.939692620785908 0 -0.173648177666933 -0.984807753012208 0 -2.84823227897248e-15 -1 0 0.173648177666927 -0.984807753012209 0 0.342020143325666 -0.93969262078591 0 0.499999999999997 -0.86602540378444 0 0.642787609686536 -0.76604444311898 0 0.766044443118976 -0.642787609686542 0 0.866025403784437 -0.500000000000004 0 0.939692620785907 -0.342020143325673 0 0.984807753012207 -0.173648177666935 0 1 -2.44929359829471e-16 0 1 -2.44929359829471e-16 -6 0.984807753012208 0.17364817766693 -6 0.939692620785908 0.342020143325669 -6 0.866025403784439 0.5 -6 0.766044443118978 0.642787609686539 -6 0.642787609686539 0.766044443118978 -6 0.5 0.866025403784439 -6 0.342020143325669 0.939692620785908 -6 0.17364817766693 0.984807753012208 -6 6.12323399573677e-17 1 -6 -0.17364817766693 0.984807753012208 -6 -0.342020143325669 0.939692620785908 -6 -0.5 0.866025403784439 -6 -0.642787609686539 0.766044443118978 -6 -0.766044443118978 0.64278760968654 -6 -0.866025403784438 0.500000000000001 -6 -0.939692620785908 0.34202014332567 -6 -0.984807753012208 0.173648177666932 -6 -1 1.45473230946492e-15 -6 -0.984807753012208 -0.173648177666929 -6 -0.939692620785909 -0.342020143325667 -6 -0.86602540378444 -0.499999999999998 -6 -0.766044443118979 -0.642787609686538 -6 -0.642787609686541 -0.766044443118977 -6 -0.500000000000002 -0.866025403784437 -6 -0.342020143325671 -0.939692620785908 -6 -0.173648177666933 -0.984807753012208 -6 -2.84823227897248e-15 -1 -6 0.173648177666927 -0.984807753012209 -6 0.342020143325666 -0.93969262078591 -6 0.499999999999997 -0.86602540378444 -6 0.642787609686536 -0.76604444311898 -6 0.766044443118976 -0.642787609686542 -6 0.866025403784437 -0.500000000000004 -6 0.939692620785907 -0.342020143325673 -6 0.984807753012207 -0.173648177666935 -6 1 -2.44929359829471e-16 -6 0 6 0.174532925199433 6 0.349065850398866 6 0.523598775598299 6 0.698131700797732 6 0.872664625997165 6 1.0471975511966 6 1.22173047639603 6 1.39626340159546 6 1.5707963267949 6 1.74532925199433 6 1.91986217719376 6 2.0943951023932 6 2.26892802759263 6 2.44346095279206 6 2.61799387799149 6 2.79252680319093 6 2.96705972839036 6 3.14159265358979 6 3.31612557878922 6 3.49065850398866 6 3.66519142918809 6 3.83972435438752 6 4.01425727958696 6 4.18879020478639 6 4.36332312998582 6 4.53785605518525 6 4.71238898038469 6 4.88692190558412 6 5.06145483078355 6 5.23598775598299 6 5.41052068118242 6 5.58505360638185 6 5.75958653158128 6 5.93411945678072 6 6.10865238198015 6 6.28318530717959 6 0 0 0.174532925199433 0 0.349065850398866 0 0.523598775598299 0 0.698131700797732 0 0.872664625997165 0 1.0471975511966 0 1.22173047639603 0 1.39626340159546 0 1.5707963267949 0 1.74532925199433 0 1.91986217719376 0 2.0943951023932 0 2.26892802759263 0 2.44346095279206 0 2.61799387799149 0 2.79252680319093 0 2.96705972839036 0 3.14159265358979 0 3.31612557878922 0 3.49065850398866 0 3.66519142918809 0 3.83972435438752 0 4.01425727958696 0 4.18879020478639 0 4.36332312998582 0 4.53785605518525 0 4.71238898038469 0 4.88692190558412 0 5.06145483078355 0 5.23598775598299 0 5.41052068118242 0 5.58505360638185 0 5.75958653158128 0 5.93411945678072 0 6.10865238198015 0 6.28318530717959 0 2 1 38 2 38 39 3 39 40 3 2 39 4 40 41 4 3 40 5 41 42 5 4 41 6 42 43 6 5 42 7 6 43 7 43 44 8 7 44 8 44 45 9 8 45 9 45 46 10 9 46 10 46 47 11 10 47 11 47 48 12 11 48 12 48 49 13 12 49 13 49 50 14 13 50 14 50 51 15 14 51 15 51 52 16 15 52 16 52 53 17 16 53 17 53 54 17 54 55 18 17 55 19 18 55 19 55 56 20 56 57 20 19 56 21 57 58 21 20 57 22 58 59 22 21 58 23 59 60 23 22 59 24 60 61 24 23 60 25 61 62 25 24 61 26 62 63 26 25 62 27 63 64 27 26 63 28 64 65 28 27 64 29 65 66 29 28 65 30 66 67 30 29 66 31 67 68 31 30 67 32 31 68 32 68 69 33 32 69 33 69 70 34 33 70 34 70 71 35 34 71 35 71 72 36 35 72 36 72 73 36 73 74 37 36 74
36 34 1 0 1.38026443154486e-15
1 -2.44929359829471e-16 0 0.984807753012208 0.17364817766693 0 0.939692620785908 0.342020143325669 0 0.866025403784439 0.5 0 0.766044443118978 0.642787609686539 0 0.642787609686539 0.766044443118978 0 0.5 0.866025403784439 0 0.342020143325669 0.939692620785908 0 0.17364817766693 0.984807753012208 0 6.12323399573677e-17 1 0 -0.17364817766693 0.984807753012208 0 -0.342020143325669 0.939692620785908 0 -0.5 0.866025403784439 0 -0.642787609686539 0.766044443118978 0 -0.766044443118978 0.64278760968654 0 -0.866025403784438 0.500000000000001 0 -0.939692620785908 0.34202014332567 0 -0.984807753012208 0.173648177666932 0 -1 1.45473230946492e-15 0 -0.984807753012208 -0.173648177666929 0 -0.939692620785909 -0.342020143325667 0 -0.86602540378444 -0.499999999999998 0 -0.766044443118979 -0.642787609686538 0 -0.642787609686541 -0.766044443118977 0 -0.500000000000002 -0.866025403784437 0 -0.342020143325671 -0.939692620785908 0 -0.173648177666933 -0.984807753012208 0 -2.84823227897248e-15 -1 0 0.173648177666927 -0.984807753012209 0 0.342020143325666 -0.93969262078591 0 0.499999999999997 -0.86602540378444 0 0.642787609686536 -0.76604444311898 0 0.766044443118976 -0.642787609686542 0 0.866025403784437 -0.500000000000004 0 0.939692620785907 -0.342020143325673 0 0.984807753012207 -0.173648177666935 0 6 5 5.98480775301221 5.17364817766693 5.93969262078591 5.34202014332567 5.86602540378444 5.5 5.76604444311898 5.64278760968654 5.64278760968654 5.76604444311898 5.5 5.86602540378444 5.34202014332567 5.93969262078591 5.17364817766693 5.98480775301221 5 6 4.82635182233307 5.98480775301221 4.65797985667433 5.93969262078591 4.5 5.86602540378444 4.35721239031346 5.76604444311898 4.23395555688102 5.64278760968654 4.13397459621556 5.5 4.06030737921409 5.34202014332567 4.01519224698779 5.17364817766693 4 5 4.01519224698779 4.82635182233307 4.06030737921409 4.65797985667433 4.13397459621556 4.5 4.23395555688102 4.35721239031346 4.35721239031346 4.23395555688102 4.5 4.13397459621556 4.65797985667433 4.06030737921409 4.82635182233307 4.01519224698779 5 4 5.17364817766693 4.01519224698779 5.34202014332567 4.06030737921409 5.5 4.13397459621556 5.64278760968654 4.23395555688102 5.76604444311898 4.35721239031346 5.86602540378444 4.5 5.93969262078591 4.65797985667433 5.98480775301221 4.82635182233307 22 23 24 27 24 25 27 25 26 27 22 24 17 18 19 31 27 28 31 28 29 31 29 30 15 16 17 33 31 32 33 27 31 13 14 15 13 19 20 13 17 19 13 15 17 35 33 34 11 12 13 8 9 10 8 10 11 8 11 13 4 1 2 4 2 3 4 35 36 4 36 1 4 33 35 6 8 13 6 4 5 6 33 4 6 7 8 6 20 21 6 21 22 6 22 27 6 27 33 6 13 20
36 34 1 0 1.57009245868378e-16
1 -2.44929359829471e-16 3 0.984807753012208 0.17364817766693 3 0.939692620785908 0.342020143325669 3 0.866025403784439 0.5 3 0.766044443118978 0.642787609686539 3 0.642787609686539 0.766044443118978 3 0.5 0.866025403784439 3 0.342020143325669 0.939692620785908 3 0.17364817766693 0.984807753012208 3 6.12323399573677e-17 1 3 -0.17364817766693 0.984807753012208 3 -0.342020143325669 0.939692620785908 3 -0.5 0.866025403784439 3 -0.642787609686539 0.766044443118978 3 -0.766044443118978 0.64278760968654 3 -0.866025403784438 0.500000000000001 3 -0.939692620785908 0.34202014332567 3 -0.984807753012208 0.173648177666932 3 -1 1.45473230946492e-15 3 -0.984807753012208 -0.173648177666929 3 -0.939692620785909 -0.342020143325667 3 -0.86602540378444 -0.499999999999998 3 -0.766044443118979 -0.642787609686538 3 -0.642787609686541 -0.766044443118977 3 -0.500000000000002 -0.866025403784437 3 -0.342020143325671 -0.939692620785908 3 -0.173648177666933 -0.984807753012208 3 -2.84823227897248e-15 -1 3 0.173648177666927 -0.984807753012209 3 0.342020143325666 -0.93969262078591 3 0.499999999999997 -0.86602540378444 3 0.642787609686536 -0.76604444311898 3 0.766044443118976 -0.642787609686542 3 0.866025403784437 -0.500000000000004 3 0.939692620785907 -0.342020143325673 3 0.984807753012207 -0.173648177666935 3 1 -2.22044604925031e-16 0.984807753012208 0.17364817766693 0.939692620785908 0.342020143325669 0.866025403784439 0.5 0.766044443118978 0.642787609686539 0.642787609686539 0.766044443118978 0.5 0.866025403784439 0.342020143325669 0.939692620785908 0.173648177666931 0.984807753012208 0 1 -0.17364817766693 0.984807753012208 -0.342020143325669 0.939692620785908 -0.5 0.866025403784439 -0.642787609686539 0.766044443118978 -0.766044443118978 0.64278760968654 -0.866025403784438 0.500000000000001 -0.939692620785908 0.34202014332567 -0.984807753012208 0.173648177666932 -1 1.55431223447522e-15 -0.984807753012208 -0.173648177666929 -0.939692620785909 -0.342020143325667 -0.86602540378444 -0.499999999999998 -0.766044443118979 -0.642787609686538 -0.642787609686541 -0.766044443118977 -0.500000000000002 -0.866025403784437 -0.342020143325671 -0.939692620785908 -0.173648177666933 -0.984807753012208 -2.88657986402541e-15 -1 0.173648177666927 -0.984807753012209 0.342020143325666 -0.93969262078591 0.499999999999997 -0.86602540378444 0.642787609686537 -0.76604444311898 0.766044443118976 -0.642787609686542 0.866025403784437 -0.500000000000004 0.939692620785907 -0.342020143325673 0.984807753012207 -0.173648177666935 21 22 23 27 25 26 15 16 17 33 31 32 13 14 15 1 30 31 1 33 34 1 34 35 1 35 36 1 31 33 8 9 10 8 10 11 7 8 11 4 1 2 4 2 3 6 4 5 6 11 12 6 12 13 6 17 18 6 18 19 6 19 20 6 20 21 6 23 24 6 24 25 6 27 28 6 28 29 6 29 30 6 25 27 6 21 23 6 15 17 6 13 15 6 30 1 6 1 4 6 7 11
36 34 1 0 1.57009245868378e-16
1 -2.44929359829471e-16 -6 0.984807753012208 0.17364817766693 -6 0.939692620785908 0.342020143325669 -6 0.866025403784439 0.5 -6 0.766044443118978 0.642787609686539 -6 0.642787609686539 0.766044443118978 -6 0.5 0.866025403784439 -6 0.342020143325669 0.939692620785908 -6 0.17364817766693 0.984807753012208 -6 6.12323399573677e-17 1 -6 -0.17364817766693 0.984807753012208 -6 -0.342020143325669 0.939692620785908 -6 -0.5 0.866025403784439 -6 -0.642787609686539 0.766044443118978 -6 -0.766044443118978 0.64278760968654 -6 -0.866025403784438 0.500000000000001 -6 -0.939692620785908 0.34202014332567 -6 -0.984807753012208 0.173648177666932 -6 -1 1.45473230946492e-15 -6 -0.984807753012208 -0.173648177666929 -6 -0.939692620785909 -0.342020143325667 -6 -0.86602540378444 -0.499999999999998 -6 -0.766044443118979 -0.642787609686538 -6 -0.642787609686541 -0.766044443118977 -6 -0.500000000000002 -0.866025403784437 -6 -0.342020143325671 -0.939692620785908 -6 -0.173648177666933 -0.984807753012208 -6 -2.84823227897248e-15 -1 -6 0.173648177666927 -0.984807753012209 -6 0.342020143325666 -0.93969262078591 -6 0.499999999999997 -0.86602540378444 -6 0.642787609686536 -0.76604444311898 -6 0.766044443118976 -0.642787609686542 -6 0.866025403784437 -0.500000000000004 -6 0.939692620785907 -0.342020143325673 -6 0.984807753012207 -0.173648177666935 -6 1 -2.22044604925031e-16 0.984807753012208 0.17364817766693 0.939692620785908 0.342020143325669 0.866025403784439 0.5 0.766044443118978 0.642787609686539 0.642787609686539 0.766044443118978 0.5 0.866025403784439 0.342020143325669 0.939692620785908 0.173648177666931 0.984807753012208 0 1 -0.17364817766693 0.984807753012208 -0.342020143325669 0.939692620785908 -0.5 0.866025403784439 -0.642787609686539 0.766044443118978 -0.766044443118978 0.64278760968654 -0.866025403784438 0.500000000000001 -0.939692620785908 0.34202014332567 -0.984807753012208 0.173648177666932 -1 1.55431223447522e-15 -0.984807753012208 -0.173648177666929 -0.939692620785909 -0.342020143325667 -0.86602540378444 -0.499999999999998 -0.766044443118979 -0.642787609686538 -0.642787609686541 -0.766044443118977 -0.500000000000002 -0.866025403784437 -0.342020143325671 -0.939692620785908 -0.173648177666933 -0.984807753012208 -2.88657986402541e-15 -1 0.173648177666927 -0.984807753012209 0.342020143325666 -0.93969262078591 0.499999999999997 -0.86602540378444 0.642787609686537 -0.76604444311898 0.766044443118976 -0.642787609686542 0.866025403784437 -0.500000000000004 0.939692620785907 -0.342020143325673 0.984807753012207 -0.173648177666935 21 22 23 27 25 26 15 16 17 33 31 32 13 14 15 1 30 31 1 33 34 1 34 35 1 35 36 1 31 33 8 9 10 8 10 11 7 8 11 4 1 2 4 2 3 6 4 5 6 11 12 6 12 13 6 17 18 6 18 19 6 19 20 6 20 21 6 23 24 6 24 25 6 27 28 6 28 29 6 29 30 6 25 27 6 21 23 6 15 17 6 13 15 6 30 1 6 1 4 6 7 11
TShapes 58
Ve
1e-07
-5 -5 10
0 0
0101101
*
Ve
1e-07
-5 -5 0
0 0
0101101
*
Ed
1e-07 1 1 0
1 1 0 0 10
2 1 1 0 0 10
2 2 2 0 0 10
6 1 1 0
6 2 2 0
0
0101000
-58 0 +57 0 *
Ve
1e-07
-5 5 10
0 0
0101101
*
Ed
1e-07 1 1 0
1 2 0 0 10
2 3 1 0 0 10
2 4 3 0 0 10
6 3 1 0
6 4 3 0
0
0101000
-55 0 +58 0 *
Ve
1e-07
-5 5 0
0 0
0101101
*
Ed
1e-07 1 1 0
1 3 0 0 10
2 5 1 0 0 10
2 6 4 0 0 10
6 5 1 0
6 6 4 0
0
0101000
-55 0 +53 0 *
Ed
1e-07 1 1 0
1 4 0 0 10
2 7 1 0 0 10
2 8 5 0 0 10
6 7 1 0
6 8 5 0
0
0101000
-53 0 +57 0 *
Wi
0101100
-56 0 -54 0 +52 0 +51 0 *
Fa
0 1e-07 1 0
2 1
0101000
+50 0 *
Ve
1e-07
5 -5 0
0 0
0101101
*
Ed
1e-07 1 1 0
1 5 0 0 10
2 9 2 0 0 10
2 10 5 0 0 10
6 9 2 0
6 10 5 0
0
0101000
-48 0 +57 0 *
Ve
1e-07
5 -5 10
0 0
0101101
*
Ed
1e-07 1 1 0
1 6 0 0 10
2 11 6 0 0 10
2 12 2 0 0 10
6 11 2 0
6 12 6 0
0
0101000
-46 0 +48 0 *
Ed
1e-07 1 1 0
1 7 0 0 10
2 13 2 0 0 10
2 14 3 0 0 10
6 13 2 0
6 14 3 0
0
0101000
-46 0 +58 0 *
Wi
0101100
-47 0 -45 0 +44 0 +56 0 *
Fa
0 1e-07 2 0
2 2
0101000
+43 0 *
Ve
1e-07
5 5 10
0 0
0101101
*
Ed
1e-07 1 1 0
1 8 0 0 10
2 15 4 0 0 10
2 16 3 0 0 10
6 15 3 0
6 16 4 0
0
0101000
-41 0 +55 0 *
Ed
1e-07 1 1 0
1 9 0 0 10
2 17 6 0 0 10
2 18 3 0 0 10
6 17 3 0
6 18 6 0
0
0101000
-41 0 +46 0 *
Wi
0101100
-54 0 -40 0 +39 0 +44 0 *
Fa
0 1e-07 3 0
2 3
0101000
+38 0 *
Ve
1e-07
5 5 0
0 0
0101101
*
Ed
1e-07 1 1 0
1 10 0 0 10
2 19 4 0 0 10
2 20 5 0 0 10
6 19 4 0
6 20 5 0
0
0101000
-36 0 +53 0 *
Ed
1e-07 1 1 0
1 11 0 0 10
2 21 6 0 0 10
2 22 4 0 0 10
6 21 4 0
6 22 6 0
0
0101000
-41 0 +36 0 *
Wi
0101100
-35 0 -34 0 +40 0 +52 0 *
Fa
0 1e-07 4 0
2 4
0101000
+33 0 *
Ed
1e-07 1 1 0
1 12 0 0 10
2 23 6 0 0 10
2 24 5 0 0 10
6 23 5 0
6 24 6 0
0
0101000
-36 0 +48 0 *
Wi
0101100
-51 0 -35 0 +47 0 +31 0 *
Ve
1.00000000244929e-07
1 -2.44929359829471e-16 0
0 0
0101101
*
Ed
1e-07 1 1 0
1 13 0 0 6.28318530717959
2 25 5 0 0 6.28318530717959
2 26 7 0 0 6.28318530717959
6 25 7 0
6 26 8 0
6 27 5 0
6 28 9 0
0
0101000
+29 0 -29 0 *
Wi
0101100
-28 0 *
Fa
0 1e-07 5 0
2 5
0101000
+30 0 +27 0 *
Wi
0101100
-45 0 -39 0 +34 0 +31 0 *
Fa
0 1e-07 6 0
2 6
0101000
+25 0 *
Ve
1e-07
1 -2.44929359829471e-16 3
0 0
0101101
*
Ed
1e-07 1 1 0
1 14 0 6 9
3 27 28CN 7 0 6 9
7 29 30 7 0
0
0101000
+29 0 -23 0 *
Ed
1e-07 1 1 0
1 15 0 0 6.28318530717959
2 29 7 0 0 6.28318530717959
2 30 8 0 0 6.28318530717959
6 31 7 0
6 32 10 0
0
0101000
+23 0 -23 0 *
Wi
0101100
+22 0 +28 0 -22 0 -21 0 *
Fa
0 1e-07 7 0
2 7
0101000
+20 0 *
Wi
0101100
+21 0 *
Fa
0 1e-07 8 0
2 10
0101000
+18 0 *
Sh
0101100
-49 0 -42 0 +37 0 +32 0 -26 0 +24 0 -19 0 -17 0 *
So
0100000
+16 0 *
Wi
0101100
+28 0 *
Fa
0 1e-07 5 0
2 9
0101000
+14 0 *
Sh
0101100
-13 0 +19 0 +17 0 *
So
0100000
+12 0 *
Ve
1e-07
1 -2.44929359829471e-16 -6
0 0
0101101
*
Ed
1e-07 1 1 0
1 14 0 0 6
3 27 28CN 7 0 0 6
7 33 34 8 0
0
0101000
+10 0 -29 0 *
Ed
1e-07 1 1 0
1 16 0 0 6.28318530717959
2 31 7 0 0 6.28318530717959
2 32 9 0 0 6.28318530717959
6 35 8 0
6 36 11 0
0
0101000
+10 0 -10 0 *
Wi
0101100
-28 0 +9 0 +8 0 -9 0 *
Fa
0 1e-07 7 0
2 8
0101000
+7 0 *
Wi
0101100
-8 0 *
Fa
0 1e-07 9 0
2 11
0101000
-5 0 *
Sh
0101100
+6 0 +13 0 -4 0 *
So
0100000
+3 0 *
Co
1100000
+15 0 +11 0 +2 0 *
+1 0

View File

@ -0,0 +1,73 @@
DBRep_DrawableShape
CASCADE Topology V3, (c) Open Cascade
Locations 0
Curve2ds 4
1 0 1.5707963267948966 1 0
1 6.2831853071795862 -6.2831853071795862 0 1
1 0 -6.2831853071795862 0 1
1 0 -1.5707963267948966 1 0
Curves 1
2 0 0 0 -2.4492935982947064e-16 -1 0 1 -2.4492935982947064e-16 0 0 0 1 100
Polygon3D 0
PolygonOnTriangulations 0
Surfaces 1
4 0 0 0 0 0 1 1 0 -0 -0 1 0 100
Triangulations 0
TShapes 9
Ve
1e-07
6.12323399573677e-15 -1.49975978266186e-30 100
0 0
0101101
*
Ed
1e-07 1 1 1
2 1 1 0 0 6.28318530717959
0
0101000
+9 0 -9 0 *
Ve
1e-07
6.12323399573677e-15 -1.49975978266186e-30 -100
0 0
0101101
*
Ed
1e-07 1 1 0
1 1 0 4.71238898038469 7.85398163397448
3 2 3CN 1 0 4.71238898038469 7.85398163397448
0
0101000
-9 0 +7 0 *
Ed
1e-07 1 1 1
2 4 1 0 0 6.28318530717959
0
0101000
+7 0 -7 0 *
Wi
0101100
-8 0 +6 0 +5 0 -6 0 *
Fa
0 1e-07 1 0
0111000
+4 0 *
Sh
0101100
+3 0 *
So
1100000
+2 0 *
+1 0

View File

@ -127,6 +127,10 @@ SET(CPP_TESTS
SMESH_RegularGridTest
)
SET(UNIT_TESTS # Any unit test add in src names space should be added here
HexahedronTest
)
# The following tests can be executed without driver, just by python.
# ----------------------------------------------------------------------------