mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2025-01-14 22:00:33 +05:00
To compute mesh in SALOME_TESTS/Grids/geom/bugs_15/R7
and other tests of "Extrusion 3D" mesher
This commit is contained in:
parent
d6b7cb735f
commit
3ddacb9798
@ -941,7 +941,7 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge& E,
|
|||||||
int shapeID = n->getshapeId();
|
int shapeID = n->getshapeId();
|
||||||
bool infinit = Precision::IsInfinite( u );
|
bool infinit = Precision::IsInfinite( u );
|
||||||
bool zero = ( u == 0. );
|
bool zero = ( u == 0. );
|
||||||
if ( force || toCheckPosOnShape( shapeID ) || infinit || zero )
|
if ( force || infinit || zero || toCheckPosOnShape( shapeID ))
|
||||||
{
|
{
|
||||||
TopLoc_Location loc; double f,l;
|
TopLoc_Location loc; double f,l;
|
||||||
Handle(Geom_Curve) curve = BRep_Tool::Curve( E,loc,f,l );
|
Handle(Geom_Curve) curve = BRep_Tool::Curve( E,loc,f,l );
|
||||||
@ -958,7 +958,7 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge& E,
|
|||||||
gp_Pnt nodePnt = SMESH_TNodeXYZ( n );
|
gp_Pnt nodePnt = SMESH_TNodeXYZ( n );
|
||||||
if ( !loc.IsIdentity() ) nodePnt.Transform( loc.Transformation().Inverted() );
|
if ( !loc.IsIdentity() ) nodePnt.Transform( loc.Transformation().Inverted() );
|
||||||
gp_Pnt curvPnt;
|
gp_Pnt curvPnt;
|
||||||
double dist = u;
|
double dist = 2*tol;
|
||||||
if ( !infinit )
|
if ( !infinit )
|
||||||
{
|
{
|
||||||
curvPnt = curve->Value( u );
|
curvPnt = curve->Value( u );
|
||||||
@ -2559,7 +2559,8 @@ bool SMESH_MesherHelper::IsStructured( SMESH_subMesh* faceSM )
|
|||||||
//purpose : Return true if 2D mesh on FACE is ditorted
|
//purpose : Return true if 2D mesh on FACE is ditorted
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
|
||||||
bool SMESH_MesherHelper::IsDistorted2D( SMESH_subMesh* faceSM )
|
bool SMESH_MesherHelper::IsDistorted2D( SMESH_subMesh* faceSM,
|
||||||
|
bool checkUV)
|
||||||
{
|
{
|
||||||
if ( !faceSM || faceSM->GetSubShape().ShapeType() != TopAbs_FACE )
|
if ( !faceSM || faceSM->GetSubShape().ShapeType() != TopAbs_FACE )
|
||||||
return false;
|
return false;
|
||||||
@ -2577,6 +2578,7 @@ bool SMESH_MesherHelper::IsDistorted2D( SMESH_subMesh* faceSM )
|
|||||||
double prevArea2D = 0;
|
double prevArea2D = 0;
|
||||||
vector< const SMDS_MeshNode* > nodes;
|
vector< const SMDS_MeshNode* > nodes;
|
||||||
vector< gp_XY > uv;
|
vector< gp_XY > uv;
|
||||||
|
bool* toCheckUV = checkUV ? & checkUV : 0;
|
||||||
while ( faceIt->more() && !haveBadFaces )
|
while ( faceIt->more() && !haveBadFaces )
|
||||||
{
|
{
|
||||||
const SMDS_MeshElement* face = faceIt->next();
|
const SMDS_MeshElement* face = faceIt->next();
|
||||||
@ -2608,7 +2610,7 @@ bool SMESH_MesherHelper::IsDistorted2D( SMESH_subMesh* faceSM )
|
|||||||
// get UVs
|
// get UVs
|
||||||
uv.resize( nodes.size() );
|
uv.resize( nodes.size() );
|
||||||
for ( size_t i = 0; i < nodes.size(); ++i )
|
for ( size_t i = 0; i < nodes.size(); ++i )
|
||||||
uv[ i ] = helper.GetNodeUV( F, nodes[ i ], inFaceNode );
|
uv[ i ] = helper.GetNodeUV( F, nodes[ i ], inFaceNode, toCheckUV );
|
||||||
|
|
||||||
// compare orientation of triangles
|
// compare orientation of triangles
|
||||||
for ( int iT = 0, nbT = nodes.size()-2; iT < nbT; ++iT )
|
for ( int iT = 0, nbT = nodes.size()-2; iT < nbT; ++iT )
|
||||||
|
@ -120,7 +120,7 @@ class SMESH_EXPORT SMESH_MesherHelper
|
|||||||
/*!
|
/*!
|
||||||
* \brief Return true if 2D mesh on FACE is distored
|
* \brief Return true if 2D mesh on FACE is distored
|
||||||
*/
|
*/
|
||||||
static bool IsDistorted2D( SMESH_subMesh* faceSM );
|
static bool IsDistorted2D( SMESH_subMesh* faceSM, bool checkUV=false );
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns true if given node is medium
|
* \brief Returns true if given node is medium
|
||||||
|
@ -689,6 +689,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
|
|||||||
list< Prism_3D::TPrismTopo > meshedPrism;
|
list< Prism_3D::TPrismTopo > meshedPrism;
|
||||||
list< TopoDS_Face > suspectSourceFaces;
|
list< TopoDS_Face > suspectSourceFaces;
|
||||||
TopTools_ListIteratorOfListOfShape solidIt;
|
TopTools_ListIteratorOfListOfShape solidIt;
|
||||||
|
bool selectBottom = false;
|
||||||
|
|
||||||
while ( meshedSolids.Extent() < nbSolids )
|
while ( meshedSolids.Extent() < nbSolids )
|
||||||
{
|
{
|
||||||
@ -709,7 +710,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
|
|||||||
{
|
{
|
||||||
prism.Clear();
|
prism.Clear();
|
||||||
prism.myBottom = face;
|
prism.myBottom = face;
|
||||||
if ( !initPrism( prism, solid ) ||
|
if ( !initPrism( prism, solid, selectBottom ) ||
|
||||||
!compute( prism ))
|
!compute( prism ))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -762,15 +763,24 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
|
|||||||
while ( const TopoDS_Shape* f = faceIt->next() )
|
while ( const TopoDS_Shape* f = faceIt->next() )
|
||||||
{
|
{
|
||||||
const TopoDS_Face& candidateF = TopoDS::Face( *f );
|
const TopoDS_Face& candidateF = TopoDS::Face( *f );
|
||||||
|
if ( candidateF.IsSame( wFace )) continue;
|
||||||
|
// select a source FACE: prismIt->myBottom or prismIt->myTop
|
||||||
|
TopoDS_Face sourceF = prismIt->myBottom;
|
||||||
|
for ( TopExp_Explorer v( prismIt->myTop, TopAbs_VERTEX ); v.More(); v.Next() )
|
||||||
|
if ( myHelper->IsSubShape( v.Current(), candidateF )) {
|
||||||
|
sourceF = prismIt->myTop;
|
||||||
|
break;
|
||||||
|
}
|
||||||
prism.Clear();
|
prism.Clear();
|
||||||
prism.myBottom = candidateF;
|
prism.myBottom = candidateF;
|
||||||
mySetErrorToSM = false;
|
mySetErrorToSM = false;
|
||||||
if ( !myHelper->IsSubShape( candidateF, prismIt->myShape3D ) &&
|
if ( !myHelper->IsSubShape( candidateF, prismIt->myShape3D ) &&
|
||||||
myHelper->IsSubShape( candidateF, solid ) &&
|
myHelper ->IsSubShape( candidateF, solid ) &&
|
||||||
!myHelper->GetMesh()->GetSubMesh( candidateF )->IsMeshComputed() &&
|
!myHelper->GetMesh()->GetSubMesh( candidateF )->IsMeshComputed() &&
|
||||||
initPrism( prism, solid ) &&
|
initPrism( prism, solid, /*selectBottom=*/false ) &&
|
||||||
!myHelper->GetMesh()->GetSubMesh( prism.myTop )->IsMeshComputed() &&
|
!myHelper->GetMesh()->GetSubMesh( prism.myTop )->IsMeshComputed() &&
|
||||||
project2dMesh( prismIt->myBottom, candidateF))
|
!myHelper->GetMesh()->GetSubMesh( prism.myBottom )->IsMeshComputed() &&
|
||||||
|
project2dMesh( sourceF, prism.myBottom ))
|
||||||
{
|
{
|
||||||
mySetErrorToSM = true;
|
mySetErrorToSM = true;
|
||||||
if ( !compute( prism ))
|
if ( !compute( prism ))
|
||||||
@ -780,6 +790,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
|
|||||||
{
|
{
|
||||||
meshedFaces.push_front( prism.myTop );
|
meshedFaces.push_front( prism.myTop );
|
||||||
meshedFaces.push_front( prism.myBottom );
|
meshedFaces.push_front( prism.myBottom );
|
||||||
|
selectBottom = false;
|
||||||
}
|
}
|
||||||
meshedPrism.push_back( prism );
|
meshedPrism.push_back( prism );
|
||||||
meshedSolids.Add( solid );
|
meshedSolids.Add( solid );
|
||||||
@ -802,6 +813,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
|
|||||||
if ( meshedFaces.empty() )
|
if ( meshedFaces.empty() )
|
||||||
{
|
{
|
||||||
meshedFaces.splice( meshedFaces.end(), suspectSourceFaces );
|
meshedFaces.splice( meshedFaces.end(), suspectSourceFaces );
|
||||||
|
selectBottom = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// find FACEs with local 1D hyps, which has to be computed by now,
|
// find FACEs with local 1D hyps, which has to be computed by now,
|
||||||
@ -822,6 +834,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
|
|||||||
{
|
{
|
||||||
if ( !meshedFaces.empty() ) meshedFaces.pop_back();
|
if ( !meshedFaces.empty() ) meshedFaces.pop_back();
|
||||||
meshedFaces.push_back( face ); // lower priority
|
meshedFaces.push_back( face ); // lower priority
|
||||||
|
selectBottom = true;
|
||||||
prevNbFaces = nbFaces;
|
prevNbFaces = nbFaces;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -836,6 +849,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
|
|||||||
faceSM->ComputeStateEngine( SMESH_subMesh::COMPUTE );
|
faceSM->ComputeStateEngine( SMESH_subMesh::COMPUTE );
|
||||||
if ( !faceSM->IsEmpty() ) {
|
if ( !faceSM->IsEmpty() ) {
|
||||||
meshedFaces.push_front( face ); // higher priority
|
meshedFaces.push_front( face ); // higher priority
|
||||||
|
selectBottom = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -867,6 +881,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
|
|||||||
meshedFaces.push_front( prism.myBottom );
|
meshedFaces.push_front( prism.myBottom );
|
||||||
meshedPrism.push_back( prism );
|
meshedPrism.push_back( prism );
|
||||||
meshedSolids.Add( solid.Current() );
|
meshedSolids.Add( solid.Current() );
|
||||||
|
selectBottom = true;
|
||||||
}
|
}
|
||||||
mySetErrorToSM = true;
|
mySetErrorToSM = true;
|
||||||
}
|
}
|
||||||
@ -1071,7 +1086,7 @@ bool StdMeshers_Prism_3D::getWallFaces( Prism_3D::TPrismTopo & thePrism,
|
|||||||
StdMeshers_FaceSidePtr topSide = thePrism.myWallQuads[i].back()->side[ QUAD_TOP_SIDE ];
|
StdMeshers_FaceSidePtr topSide = thePrism.myWallQuads[i].back()->side[ QUAD_TOP_SIDE ];
|
||||||
const TopoDS_Edge & topE = topSide->Edge( 0 );
|
const TopoDS_Edge & topE = topSide->Edge( 0 );
|
||||||
if ( !myHelper->IsSubShape( topE, thePrism.myTop ))
|
if ( !myHelper->IsSubShape( topE, thePrism.myTop ))
|
||||||
return toSM( error( TCom("Wrong source face (#") << shapeID( thePrism.myBottom )));
|
return toSM( error( TCom("Wrong source face: #") << shapeID( thePrism.myBottom )));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -1088,13 +1103,21 @@ bool StdMeshers_Prism_3D::compute(const Prism_3D::TPrismTopo& thePrism)
|
|||||||
if ( _computeCanceled )
|
if ( _computeCanceled )
|
||||||
return toSM( error( SMESH_ComputeError::New(COMPERR_CANCELED)));
|
return toSM( error( SMESH_ComputeError::New(COMPERR_CANCELED)));
|
||||||
|
|
||||||
|
// Assure the bottom is meshed
|
||||||
|
SMESH_subMesh * botSM = myHelper->GetMesh()->GetSubMesh( thePrism.myBottom );
|
||||||
|
if ( ! NSProjUtils::MakeComputed( botSM ))
|
||||||
|
return error( COMPERR_BAD_INPUT_MESH,
|
||||||
|
TCom( "No mesher defined to compute the face #")
|
||||||
|
<< shapeID( thePrism.myBottom ));
|
||||||
|
|
||||||
// Make all side FACEs of thePrism meshed with quads
|
// Make all side FACEs of thePrism meshed with quads
|
||||||
if ( !computeWalls( thePrism ))
|
if ( !computeWalls( thePrism ))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Analyse mesh and geometry to find all block sub-shapes and submeshes
|
// Analyse mesh and geometry to find all block sub-shapes and submeshes
|
||||||
// (after fixing IPAL52499 myBlock is used only as a holder of boundary nodes
|
// (after fixing IPAL52499 myBlock is used as a holder of boundary nodes
|
||||||
// and location of internal nodes is computed by StdMeshers_Sweeper)
|
// and for 2D projection in hard cases where StdMeshers_Projection_2D fails;
|
||||||
|
// location of internal nodes is usually computed by StdMeshers_Sweeper)
|
||||||
if ( !myBlock.Init( myHelper, thePrism ))
|
if ( !myBlock.Init( myHelper, thePrism ))
|
||||||
return toSM( error( myBlock.GetError()));
|
return toSM( error( myBlock.GetError()));
|
||||||
|
|
||||||
@ -1123,6 +1146,7 @@ bool StdMeshers_Prism_3D::compute(const Prism_3D::TPrismTopo& thePrism)
|
|||||||
|
|
||||||
// Projections on the top and bottom faces are taken from nodes existing
|
// Projections on the top and bottom faces are taken from nodes existing
|
||||||
// on these faces; find correspondence between bottom and top nodes
|
// on these faces; find correspondence between bottom and top nodes
|
||||||
|
myUseBlock = false;
|
||||||
myBotToColumnMap.clear();
|
myBotToColumnMap.clear();
|
||||||
if ( !assocOrProjBottom2Top( bottomToTopTrsf, thePrism ) ) // it also fills myBotToColumnMap
|
if ( !assocOrProjBottom2Top( bottomToTopTrsf, thePrism ) ) // it also fills myBotToColumnMap
|
||||||
return false;
|
return false;
|
||||||
@ -1132,8 +1156,11 @@ bool StdMeshers_Prism_3D::compute(const Prism_3D::TPrismTopo& thePrism)
|
|||||||
|
|
||||||
// use transformation (issue 0020680, IPAL0052499)
|
// use transformation (issue 0020680, IPAL0052499)
|
||||||
StdMeshers_Sweeper sweeper;
|
StdMeshers_Sweeper sweeper;
|
||||||
|
double tol;
|
||||||
|
|
||||||
// load boundary nodes
|
if ( !myUseBlock )
|
||||||
|
{
|
||||||
|
// load boundary nodes into sweeper
|
||||||
bool dummy;
|
bool dummy;
|
||||||
list< TopoDS_Edge >::const_iterator edge = thePrism.myBottomEdges.begin();
|
list< TopoDS_Edge >::const_iterator edge = thePrism.myBottomEdges.begin();
|
||||||
for ( ; edge != thePrism.myBottomEdges.end(); ++edge )
|
for ( ; edge != thePrism.myBottomEdges.end(); ++edge )
|
||||||
@ -1150,9 +1177,10 @@ bool StdMeshers_Prism_3D::compute(const Prism_3D::TPrismTopo& thePrism)
|
|||||||
for ( ; bot_column != myBotToColumnMap.end(); ++bot_column )
|
for ( ; bot_column != myBotToColumnMap.end(); ++bot_column )
|
||||||
sweeper.myIntColumns.push_back( & bot_column->second );
|
sweeper.myIntColumns.push_back( & bot_column->second );
|
||||||
|
|
||||||
const double tol = getSweepTolerance( thePrism );
|
tol = getSweepTolerance( thePrism );
|
||||||
|
}
|
||||||
|
|
||||||
if ( sweeper.ComputeNodes( *myHelper, tol ))
|
if ( !myUseBlock && sweeper.ComputeNodes( *myHelper, tol ))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
else // use block approach
|
else // use block approach
|
||||||
@ -2038,6 +2066,11 @@ bool StdMeshers_Prism_3D::projectBottomToTop( const gp_Trsf & bottom
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
NSProjUtils::TNodeNodeMap& n2nMap =
|
||||||
|
(NSProjUtils::TNodeNodeMap&) TProjction2dAlgo::instance( this )->GetNodesMap();
|
||||||
|
n2nMap.clear();
|
||||||
|
|
||||||
|
myUseBlock = true;
|
||||||
|
|
||||||
SMESHDS_Mesh* meshDS = myHelper->GetMeshDS();
|
SMESHDS_Mesh* meshDS = myHelper->GetMeshDS();
|
||||||
SMESH_subMesh * botSM = myHelper->GetMesh()->GetSubMesh( thePrism.myBottom );
|
SMESH_subMesh * botSM = myHelper->GetMesh()->GetSubMesh( thePrism.myBottom );
|
||||||
@ -2047,7 +2080,13 @@ bool StdMeshers_Prism_3D::projectBottomToTop( const gp_Trsf & bottom
|
|||||||
SMESHDS_SubMesh * topSMDS = topSM->GetSubMeshDS();
|
SMESHDS_SubMesh * topSMDS = topSM->GetSubMeshDS();
|
||||||
|
|
||||||
if ( topSMDS && topSMDS->NbElements() > 0 )
|
if ( topSMDS && topSMDS->NbElements() > 0 )
|
||||||
topSM->ComputeStateEngine( SMESH_subMesh::CLEAN );
|
{
|
||||||
|
//topSM->ComputeStateEngine( SMESH_subMesh::CLEAN ); -- avoid propagation of events
|
||||||
|
for ( SMDS_ElemIteratorPtr eIt = topSMDS->GetElements(); eIt->more(); )
|
||||||
|
meshDS->RemoveFreeElement( eIt->next(), topSMDS, /*fromGroups=*/false );
|
||||||
|
for ( SMDS_NodeIteratorPtr nIt = topSMDS->GetNodes(); nIt->more(); )
|
||||||
|
meshDS->RemoveFreeNode( nIt->next(), topSMDS, /*fromGroups=*/false );
|
||||||
|
}
|
||||||
|
|
||||||
const TopoDS_Face& botFace = thePrism.myBottom; // oriented within
|
const TopoDS_Face& botFace = thePrism.myBottom; // oriented within
|
||||||
const TopoDS_Face& topFace = thePrism.myTop; // the 3D SHAPE
|
const TopoDS_Face& topFace = thePrism.myTop; // the 3D SHAPE
|
||||||
@ -2119,6 +2158,8 @@ bool StdMeshers_Prism_3D::projectBottomToTop( const gp_Trsf & bottom
|
|||||||
column.front() = botNode;
|
column.front() = botNode;
|
||||||
column.back() = topNode;
|
column.back() = topNode;
|
||||||
|
|
||||||
|
n2nMap.insert( n2nMap.end(), make_pair( botNode, topNode ));
|
||||||
|
|
||||||
if ( _computeCanceled )
|
if ( _computeCanceled )
|
||||||
return toSM( error( SMESH_ComputeError::New(COMPERR_CANCELED)));
|
return toSM( error( SMESH_ComputeError::New(COMPERR_CANCELED)));
|
||||||
}
|
}
|
||||||
@ -2270,6 +2311,15 @@ bool StdMeshers_Prism_3D::project2dMesh(const TopoDS_Face& theSrcFace,
|
|||||||
bool ok = projector2D->Compute( *myHelper->GetMesh(), theTgtFace );
|
bool ok = projector2D->Compute( *myHelper->GetMesh(), theTgtFace );
|
||||||
|
|
||||||
SMESH_subMesh* tgtSM = myHelper->GetMesh()->GetSubMesh( theTgtFace );
|
SMESH_subMesh* tgtSM = myHelper->GetMesh()->GetSubMesh( theTgtFace );
|
||||||
|
if ( !ok && tgtSM->GetSubMeshDS() ) {
|
||||||
|
//tgtSM->ComputeStateEngine( SMESH_subMesh::CLEAN ); -- avoid propagation of events
|
||||||
|
SMESHDS_Mesh* meshDS = myHelper->GetMeshDS();
|
||||||
|
SMESHDS_SubMesh* tgtSMDS = tgtSM->GetSubMeshDS();
|
||||||
|
for ( SMDS_ElemIteratorPtr eIt = tgtSMDS->GetElements(); eIt->more(); )
|
||||||
|
meshDS->RemoveFreeElement( eIt->next(), tgtSMDS, /*fromGroups=*/false );
|
||||||
|
for ( SMDS_NodeIteratorPtr nIt = tgtSMDS->GetNodes(); nIt->more(); )
|
||||||
|
meshDS->RemoveFreeNode( nIt->next(), tgtSMDS, /*fromGroups=*/false );
|
||||||
|
}
|
||||||
tgtSM->ComputeStateEngine ( SMESH_subMesh::CHECK_COMPUTE_STATE );
|
tgtSM->ComputeStateEngine ( SMESH_subMesh::CHECK_COMPUTE_STATE );
|
||||||
tgtSM->ComputeSubMeshStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
|
tgtSM->ComputeSubMeshStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
|
||||||
|
|
||||||
@ -2785,7 +2835,8 @@ void StdMeshers_PrismAsBlock::Clear()
|
|||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
|
||||||
bool StdMeshers_Prism_3D::initPrism(Prism_3D::TPrismTopo& thePrism,
|
bool StdMeshers_Prism_3D::initPrism(Prism_3D::TPrismTopo& thePrism,
|
||||||
const TopoDS_Shape& shape3D)
|
const TopoDS_Shape& shape3D,
|
||||||
|
const bool selectBottom)
|
||||||
{
|
{
|
||||||
myHelper->SetSubShape( shape3D );
|
myHelper->SetSubShape( shape3D );
|
||||||
|
|
||||||
@ -2884,19 +2935,23 @@ bool StdMeshers_Prism_3D::initPrism(Prism_3D::TPrismTopo& thePrism,
|
|||||||
// use thePrism.myBottom
|
// use thePrism.myBottom
|
||||||
if ( !thePrism.myBottom.IsNull() )
|
if ( !thePrism.myBottom.IsNull() )
|
||||||
{
|
{
|
||||||
if ( botSM ) {
|
if ( botSM ) { // <-- not quad geom or mesh on botSM
|
||||||
if ( ! botSM->GetSubShape().IsSame( thePrism.myBottom )) {
|
if ( ! botSM->GetSubShape().IsSame( thePrism.myBottom )) {
|
||||||
std::swap( botSM, topSM );
|
std::swap( botSM, topSM );
|
||||||
if ( !botSM || ! botSM->GetSubShape().IsSame( thePrism.myBottom ))
|
if ( !botSM || ! botSM->GetSubShape().IsSame( thePrism.myBottom )) {
|
||||||
|
if ( !selectBottom )
|
||||||
return toSM( error( COMPERR_BAD_INPUT_MESH,
|
return toSM( error( COMPERR_BAD_INPUT_MESH,
|
||||||
"Incompatible non-structured sub-meshes"));
|
"Incompatible non-structured sub-meshes"));
|
||||||
|
std::swap( botSM, topSM );
|
||||||
|
thePrism.myBottom = TopoDS::Face( botSM->GetSubShape() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
|
else if ( !selectBottom ) {
|
||||||
botSM = myHelper->GetMesh()->GetSubMesh( thePrism.myBottom );
|
botSM = myHelper->GetMesh()->GetSubMesh( thePrism.myBottom );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( !botSM ) // find a proper bottom
|
if ( !botSM ) // find a proper bottom
|
||||||
{
|
{
|
||||||
// composite walls or not prism shape
|
// composite walls or not prism shape
|
||||||
for ( TopExp_Explorer f( shape3D, TopAbs_FACE ); f.More(); f.Next() )
|
for ( TopExp_Explorer f( shape3D, TopAbs_FACE ); f.More(); f.Next() )
|
||||||
@ -2906,12 +2961,18 @@ bool StdMeshers_Prism_3D::initPrism(Prism_3D::TPrismTopo& thePrism,
|
|||||||
{
|
{
|
||||||
thePrism.Clear();
|
thePrism.Clear();
|
||||||
thePrism.myBottom = TopoDS::Face( f.Current() );
|
thePrism.myBottom = TopoDS::Face( f.Current() );
|
||||||
if ( initPrism( thePrism, shape3D ))
|
if ( initPrism( thePrism, shape3D, /*selectBottom=*/false ))
|
||||||
|
{
|
||||||
|
botSM = myHelper->GetMesh()->GetSubMesh( thePrism.myBottom );
|
||||||
|
topSM = myHelper->GetMesh()->GetSubMesh( thePrism.myTop );
|
||||||
|
if ( botSM->IsEmpty() && !topSM->IsEmpty() )
|
||||||
|
thePrism.SetUpsideDown();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return toSM( error( COMPERR_BAD_SHAPE ));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return toSM( error( COMPERR_BAD_SHAPE ));
|
||||||
|
}
|
||||||
|
|
||||||
// find vertex 000 - the one with smallest coordinates (for easy DEBUG :-)
|
// find vertex 000 - the one with smallest coordinates (for easy DEBUG :-)
|
||||||
TopoDS_Vertex V000;
|
TopoDS_Vertex V000;
|
||||||
@ -2943,7 +3004,7 @@ bool StdMeshers_Prism_3D::initPrism(Prism_3D::TPrismTopo& thePrism,
|
|||||||
thePrism.myNbEdgesInWires, V000 );
|
thePrism.myNbEdgesInWires, V000 );
|
||||||
|
|
||||||
// Get Wall faces corresponding to the ordered bottom edges and the top FACE
|
// Get Wall faces corresponding to the ordered bottom edges and the top FACE
|
||||||
if ( !getWallFaces( thePrism, nbFaces ))
|
if ( !getWallFaces( thePrism, nbFaces )) // it also sets thePrism.myTop
|
||||||
return false; //toSM( error(COMPERR_BAD_SHAPE, "Can't find side faces"));
|
return false; //toSM( error(COMPERR_BAD_SHAPE, "Can't find side faces"));
|
||||||
|
|
||||||
if ( topSM )
|
if ( topSM )
|
||||||
@ -3887,7 +3948,7 @@ gp_Pnt StdMeshers_PrismAsBlock::TSideFace::Value(const Standard_Real U,
|
|||||||
TopoDS_Shape s = myHelper.GetSubShapeByNode( nn[0], myHelper.GetMeshDS() );
|
TopoDS_Shape s = myHelper.GetSubShapeByNode( nn[0], myHelper.GetMeshDS() );
|
||||||
if ( s.ShapeType() != TopAbs_EDGE )
|
if ( s.ShapeType() != TopAbs_EDGE )
|
||||||
s = myHelper.GetSubShapeByNode( nn[2], myHelper.GetMeshDS() );
|
s = myHelper.GetSubShapeByNode( nn[2], myHelper.GetMeshDS() );
|
||||||
if ( s.ShapeType() == TopAbs_EDGE )
|
if ( !s.IsNull() && s.ShapeType() == TopAbs_EDGE )
|
||||||
edge = TopoDS::Edge( s );
|
edge = TopoDS::Edge( s );
|
||||||
}
|
}
|
||||||
if ( !edge.IsNull() )
|
if ( !edge.IsNull() )
|
||||||
|
@ -482,7 +482,9 @@ public:
|
|||||||
* \brief Analyse shape geometry and mesh.
|
* \brief Analyse shape geometry and mesh.
|
||||||
* If there are triangles on one of faces, it becomes 'bottom'
|
* If there are triangles on one of faces, it becomes 'bottom'
|
||||||
*/
|
*/
|
||||||
bool initPrism(Prism_3D::TPrismTopo& thePrism, const TopoDS_Shape& theSolid);
|
bool initPrism(Prism_3D::TPrismTopo& thePrism,
|
||||||
|
const TopoDS_Shape& theSolid,
|
||||||
|
const bool selectBottom = true);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Fill thePrism.myWallQuads and thePrism.myTopEdges
|
* \brief Fill thePrism.myWallQuads and thePrism.myTopEdges
|
||||||
@ -556,6 +558,7 @@ private:
|
|||||||
|
|
||||||
bool myProjectTriangles;
|
bool myProjectTriangles;
|
||||||
bool mySetErrorToSM;
|
bool mySetErrorToSM;
|
||||||
|
bool myUseBlock;
|
||||||
|
|
||||||
StdMeshers_PrismAsBlock myBlock;
|
StdMeshers_PrismAsBlock myBlock;
|
||||||
SMESH_MesherHelper* myHelper;
|
SMESH_MesherHelper* myHelper;
|
||||||
|
@ -1942,6 +1942,9 @@ FindMatchingNodesOnFaces( const TopoDS_Face& face1,
|
|||||||
|
|
||||||
// 2. face sets
|
// 2. face sets
|
||||||
|
|
||||||
|
int assocRes;
|
||||||
|
for ( int iAttempt = 0; iAttempt < 2; ++iAttempt )
|
||||||
|
{
|
||||||
set<const SMDS_MeshElement*> Elems1, Elems2;
|
set<const SMDS_MeshElement*> Elems1, Elems2;
|
||||||
for ( int is2 = 0; is2 < 2; ++is2 )
|
for ( int is2 = 0; is2 < 2; ++is2 )
|
||||||
{
|
{
|
||||||
@ -1953,7 +1956,7 @@ FindMatchingNodesOnFaces( const TopoDS_Face& face1,
|
|||||||
|
|
||||||
if ( !helper->IsRealSeam( is2 ? edge2 : edge1 ))
|
if ( !helper->IsRealSeam( is2 ? edge2 : edge1 ))
|
||||||
{
|
{
|
||||||
while ( eIt->more() ) elems.insert( eIt->next() );
|
while ( eIt->more() ) elems.insert( elems.end(), eIt->next() );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2024,15 +2027,24 @@ FindMatchingNodesOnFaces( const TopoDS_Face& face1,
|
|||||||
} // case on a sphere
|
} // case on a sphere
|
||||||
} // loop on 2 faces
|
} // loop on 2 faces
|
||||||
|
|
||||||
// int quadFactor = (*Elems1.begin())->IsQuadratic() ? 2 : 1;
|
|
||||||
|
|
||||||
node1To2Map.clear();
|
node1To2Map.clear();
|
||||||
int res = SMESH_MeshEditor::FindMatchingNodes( Elems1, Elems2,
|
assocRes = SMESH_MeshEditor::FindMatchingNodes( Elems1, Elems2,
|
||||||
vNode1, vNode2,
|
vNode1, vNode2,
|
||||||
eNode1[0], eNode2[0],
|
eNode1[0], eNode2[0],
|
||||||
node1To2Map);
|
node1To2Map);
|
||||||
if ( res != SMESH_MeshEditor::SEW_OK )
|
if (( assocRes != SMESH_MeshEditor::SEW_OK ) &&
|
||||||
RETURN_BAD_RESULT("FindMatchingNodes() result " << res );
|
( eNode1[1] || eNode2[1] )) // there is another node to try (on a closed EDGE)
|
||||||
|
{
|
||||||
|
node1To2Map.clear();
|
||||||
|
if ( eNode1[1] ) std::swap( eNode1[0], eNode1[1] );
|
||||||
|
else std::swap( eNode2[0], eNode2[1] );
|
||||||
|
continue; // one more attempt
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ( assocRes != SMESH_MeshEditor::SEW_OK )
|
||||||
|
RETURN_BAD_RESULT("FindMatchingNodes() result " << assocRes );
|
||||||
|
|
||||||
// On a sphere, add matching nodes on the edge
|
// On a sphere, add matching nodes on the edge
|
||||||
|
|
||||||
|
@ -568,6 +568,7 @@ namespace {
|
|||||||
vector< gp_XYZ > srcPnts, tgtPnts;
|
vector< gp_XYZ > srcPnts, tgtPnts;
|
||||||
srcPnts.reserve( totNbSeg );
|
srcPnts.reserve( totNbSeg );
|
||||||
tgtPnts.reserve( totNbSeg );
|
tgtPnts.reserve( totNbSeg );
|
||||||
|
gp_XYZ srcBC( 0,0,0 ), tgtBC( 0,0,0 );
|
||||||
for ( size_t iW = 0; iW < srcWires.size(); ++iW )
|
for ( size_t iW = 0; iW < srcWires.size(); ++iW )
|
||||||
{
|
{
|
||||||
const double minSegLen = srcWires[iW]->Length() / totNbSeg;
|
const double minSegLen = srcWires[iW]->Length() / totNbSeg;
|
||||||
@ -584,6 +585,8 @@ namespace {
|
|||||||
tgtPnts.push_back( tgtWires[iW]->Value3d( tgtU ).XYZ() );
|
tgtPnts.push_back( tgtWires[iW]->Value3d( tgtU ).XYZ() );
|
||||||
srcU += srcDu;
|
srcU += srcDu;
|
||||||
tgtU += tgtDu;
|
tgtU += tgtDu;
|
||||||
|
srcBC += srcPnts.back();
|
||||||
|
tgtBC += tgtPnts.back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -596,6 +599,8 @@ namespace {
|
|||||||
const int nbTestPnt = 20;
|
const int nbTestPnt = 20;
|
||||||
const size_t iStep = Max( 1, int( srcPnts.size() / nbTestPnt ));
|
const size_t iStep = Max( 1, int( srcPnts.size() / nbTestPnt ));
|
||||||
// check boundary
|
// check boundary
|
||||||
|
gp_Pnt trsfTgt = trsf.Transform( srcBC / srcPnts.size() );
|
||||||
|
trsfIsOK = ( trsfTgt.SquareDistance( tgtBC / tgtPnts.size() ) < tol*tol );
|
||||||
for ( size_t i = 0; ( i < srcPnts.size() && trsfIsOK ); i += iStep )
|
for ( size_t i = 0; ( i < srcPnts.size() && trsfIsOK ); i += iStep )
|
||||||
{
|
{
|
||||||
gp_Pnt trsfTgt = trsf.Transform( srcPnts[i] );
|
gp_Pnt trsfTgt = trsf.Transform( srcPnts[i] );
|
||||||
@ -606,8 +611,8 @@ namespace {
|
|||||||
{
|
{
|
||||||
BRepAdaptor_Surface srcSurf( srcFace );
|
BRepAdaptor_Surface srcSurf( srcFace );
|
||||||
gp_Pnt srcP =
|
gp_Pnt srcP =
|
||||||
srcSurf.Value( 0.5 * ( srcSurf.FirstUParameter() + srcSurf.LastUParameter() ),
|
srcSurf.Value( 0.321 * ( srcSurf.FirstUParameter() + srcSurf.LastUParameter() ),
|
||||||
0.5 * ( srcSurf.FirstVParameter() + srcSurf.LastVParameter() ));
|
0.123 * ( srcSurf.FirstVParameter() + srcSurf.LastVParameter() ));
|
||||||
gp_Pnt tgtTrsfP = trsf.Transform( srcP );
|
gp_Pnt tgtTrsfP = trsf.Transform( srcP );
|
||||||
TopLoc_Location loc;
|
TopLoc_Location loc;
|
||||||
GeomAPI_ProjectPointOnSurf& proj = helper.GetProjector( tgtFace, loc, 0.1*tol );
|
GeomAPI_ProjectPointOnSurf& proj = helper.GetProjector( tgtFace, loc, 0.1*tol );
|
||||||
@ -888,10 +893,9 @@ namespace {
|
|||||||
case SMDS_TOP_EDGE: {
|
case SMDS_TOP_EDGE: {
|
||||||
TopoDS_Shape srcEdge = srcHelper.GetSubShapeByNode( srcNode, srcHelper.GetMeshDS() );
|
TopoDS_Shape srcEdge = srcHelper.GetSubShapeByNode( srcNode, srcHelper.GetMeshDS() );
|
||||||
TopoDS_Edge tgtEdge = TopoDS::Edge( shape2ShapeMap( srcEdge, /*isSrc=*/true ));
|
TopoDS_Edge tgtEdge = TopoDS::Edge( shape2ShapeMap( srcEdge, /*isSrc=*/true ));
|
||||||
tgtMeshDS->SetNodeOnEdge( n, TopoDS::Edge( tgtEdge ));
|
double U = Precision::Infinite();
|
||||||
double U = srcHelper.GetNodeU( TopoDS::Edge( srcEdge ), srcNode );
|
|
||||||
helper.CheckNodeU( tgtEdge, n, U, Precision::PConfusion());
|
helper.CheckNodeU( tgtEdge, n, U, Precision::PConfusion());
|
||||||
n->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition( U )));
|
tgtMeshDS->SetNodeOnEdge( n, TopoDS::Edge( tgtEdge ), U );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SMDS_TOP_VERTEX: {
|
case SMDS_TOP_VERTEX: {
|
||||||
@ -922,12 +926,12 @@ namespace {
|
|||||||
*/
|
*/
|
||||||
//================================================================================
|
//================================================================================
|
||||||
|
|
||||||
void fixDistortedFaces( SMESH_MesherHelper& helper,
|
bool fixDistortedFaces( SMESH_MesherHelper& helper,
|
||||||
TSideVector& tgtWires )
|
TSideVector& tgtWires )
|
||||||
{
|
{
|
||||||
SMESH_subMesh* faceSM = helper.GetMesh()->GetSubMesh( helper.GetSubShape() );
|
SMESH_subMesh* faceSM = helper.GetMesh()->GetSubMesh( helper.GetSubShape() );
|
||||||
|
|
||||||
if ( helper.IsDistorted2D( faceSM ))
|
if ( helper.IsDistorted2D( faceSM, /*checkUV=*/false ))
|
||||||
{
|
{
|
||||||
SMESH_MeshEditor editor( helper.GetMesh() );
|
SMESH_MeshEditor editor( helper.GetMesh() );
|
||||||
SMESHDS_SubMesh* smDS = faceSM->GetSubMeshDS();
|
SMESHDS_SubMesh* smDS = faceSM->GetSubMeshDS();
|
||||||
@ -965,7 +969,12 @@ namespace {
|
|||||||
set<const SMDS_MeshNode*> fixedNodes;
|
set<const SMDS_MeshNode*> fixedNodes;
|
||||||
editor.Smooth( faces, fixedNodes, algo, /*nbIterations=*/ 10,
|
editor.Smooth( faces, fixedNodes, algo, /*nbIterations=*/ 10,
|
||||||
/*theTgtAspectRatio=*/1.0, /*the2D=*/!isPlanar);
|
/*theTgtAspectRatio=*/1.0, /*the2D=*/!isPlanar);
|
||||||
|
|
||||||
|
helper.ToFixNodeParameters( true );
|
||||||
|
|
||||||
|
return !helper.IsDistorted2D( faceSM, /*checkUV=*/true );
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
@ -1048,25 +1057,28 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
|
|||||||
if ( err && !err->IsOK() )
|
if ( err && !err->IsOK() )
|
||||||
return error( err );
|
return error( err );
|
||||||
|
|
||||||
bool done = false;
|
bool projDone = false;
|
||||||
|
|
||||||
if ( !done )
|
if ( !projDone )
|
||||||
{
|
{
|
||||||
// try to project from the same face with different location
|
// try to project from the same face with different location
|
||||||
done = projectPartner( tgtFace, srcFace, tgtWires, srcWires,
|
projDone = projectPartner( tgtFace, srcFace, tgtWires, srcWires,
|
||||||
shape2ShapeMap, _src2tgtNodes, is1DComputed );
|
shape2ShapeMap, _src2tgtNodes, is1DComputed );
|
||||||
}
|
}
|
||||||
if ( !done )
|
if ( !projDone )
|
||||||
{
|
{
|
||||||
// projection in case if the faces are similar in 2D space
|
// projection in case if the faces are similar in 2D space
|
||||||
done = projectBy2DSimilarity( tgtFace, srcFace, tgtWires, srcWires,
|
projDone = projectBy2DSimilarity( tgtFace, srcFace, tgtWires, srcWires,
|
||||||
shape2ShapeMap, _src2tgtNodes, is1DComputed);
|
shape2ShapeMap, _src2tgtNodes, is1DComputed);
|
||||||
}
|
}
|
||||||
|
|
||||||
SMESH_MesherHelper helper( theMesh );
|
SMESH_MesherHelper helper( theMesh );
|
||||||
helper.SetSubShape( tgtFace );
|
helper.SetSubShape( tgtFace );
|
||||||
|
|
||||||
if ( !done )
|
// it will remove mesh built on edges and vertices in failure case
|
||||||
|
MeshCleaner cleaner( tgtSubMesh );
|
||||||
|
|
||||||
|
if ( !projDone )
|
||||||
{
|
{
|
||||||
_src2tgtNodes.clear();
|
_src2tgtNodes.clear();
|
||||||
// --------------------
|
// --------------------
|
||||||
@ -1166,10 +1178,6 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
|
|||||||
if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK )
|
if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK )
|
||||||
return error("Can't make mesh by source mesh pattern");
|
return error("Can't make mesh by source mesh pattern");
|
||||||
|
|
||||||
// it will remove mesh built by pattern mapper on edges and vertices
|
|
||||||
// in failure case
|
|
||||||
MeshCleaner cleaner( tgtSubMesh );
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// mapper doesn't take care of nodes already existing on edges and vertices,
|
// mapper doesn't take care of nodes already existing on edges and vertices,
|
||||||
// so we must merge nodes created by it with existing ones
|
// so we must merge nodes created by it with existing ones
|
||||||
@ -1329,14 +1337,6 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
|
|||||||
if ( nbFaceBeforeMerge != nbFaceAtferMerge && !helper.HasDegeneratedEdges() )
|
if ( nbFaceBeforeMerge != nbFaceAtferMerge && !helper.HasDegeneratedEdges() )
|
||||||
return error(COMPERR_BAD_INPUT_MESH, "Probably invalid node parameters on geom faces");
|
return error(COMPERR_BAD_INPUT_MESH, "Probably invalid node parameters on geom faces");
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------
|
|
||||||
// The mapper can create distorted faces by placing nodes out of the FACE
|
|
||||||
// boundary -- fix bad faces by smoothing
|
|
||||||
// ----------------------------------------------------------------
|
|
||||||
|
|
||||||
fixDistortedFaces( helper, tgtWires );
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
// The mapper can't create quadratic elements, so convert if needed
|
// The mapper can't create quadratic elements, so convert if needed
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
@ -1355,11 +1355,18 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
|
|||||||
editor.ConvertToQuadratic(/*theForce3d=*/false, tgtFaces, false);
|
editor.ConvertToQuadratic(/*theForce3d=*/false, tgtFaces, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
cleaner.Release(); // not to remove mesh
|
|
||||||
|
|
||||||
} // end of projection using Pattern mapping
|
} // end of projection using Pattern mapping
|
||||||
|
|
||||||
|
|
||||||
|
if ( !projDone || is1DComputed )
|
||||||
|
// ----------------------------------------------------------------
|
||||||
|
// The mapper can create distorted faces by placing nodes out of the FACE
|
||||||
|
// boundary, also bad face can be created if EDGEs already discretized
|
||||||
|
// --> fix bad faces by smoothing
|
||||||
|
// ----------------------------------------------------------------
|
||||||
|
if ( !fixDistortedFaces( helper, tgtWires ))
|
||||||
|
return error("Invalid mesh generated");
|
||||||
|
|
||||||
// ---------------------------
|
// ---------------------------
|
||||||
// Check elements orientation
|
// Check elements orientation
|
||||||
// ---------------------------
|
// ---------------------------
|
||||||
@ -1405,6 +1412,8 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cleaner.Release(); // not to remove mesh
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user