mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2025-01-27 00:40:32 +05:00
#17336 [CEA 17333] Mesh offset generates a segmentation violation
This commit is contained in:
parent
d7e7b8a466
commit
155c6427af
@ -48,7 +48,7 @@ namespace
|
|||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
/*!
|
/*!
|
||||||
* \brief Intersected face side storing a node created at this intersection
|
* \brief Intersected face side storing a node created at this intersection
|
||||||
* and a intersected face
|
* and an intersected face
|
||||||
*/
|
*/
|
||||||
struct CutLink
|
struct CutLink
|
||||||
{
|
{
|
||||||
@ -105,7 +105,7 @@ namespace
|
|||||||
int myIndex; // positive -> side index, negative -> State
|
int myIndex; // positive -> side index, negative -> State
|
||||||
const SMDS_MeshElement* myFace;
|
const SMDS_MeshElement* myFace;
|
||||||
|
|
||||||
enum State { _INTERNAL = -1, _COPLANAR = -2 };
|
enum State { _INTERNAL = -1, _COPLANAR = -2, _PENDING = -3 };
|
||||||
|
|
||||||
void Set( const SMDS_MeshNode* Node1,
|
void Set( const SMDS_MeshNode* Node1,
|
||||||
const SMDS_MeshNode* Node2,
|
const SMDS_MeshNode* Node2,
|
||||||
@ -1524,7 +1524,8 @@ namespace SMESH_MeshAlgos
|
|||||||
SMESH_MeshAlgos::GetBarycentricCoords( p2D( p ),
|
SMESH_MeshAlgos::GetBarycentricCoords( p2D( p ),
|
||||||
p2D( nodes[0] ), p2D( nodes[1] ), p2D( nodes[2] ),
|
p2D( nodes[0] ), p2D( nodes[1] ), p2D( nodes[2] ),
|
||||||
bc1, bc2 );
|
bc1, bc2 );
|
||||||
return ( 0. < bc1 && 0. < bc2 && bc1 + bc2 < 1. );
|
//return ( 0. < bc1 && 0. < bc2 && bc1 + bc2 < 1. );
|
||||||
|
return ( myTol < bc1 && myTol < bc2 && bc1 + bc2 + myTol < 1. );
|
||||||
}
|
}
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
@ -1676,7 +1677,11 @@ namespace SMESH_MeshAlgos
|
|||||||
|
|
||||||
size_t limit = cf.myLinks.size() * cf.myLinks.size() * 2;
|
size_t limit = cf.myLinks.size() * cf.myLinks.size() * 2;
|
||||||
|
|
||||||
for ( size_t i1 = 3; i1 < cf.myLinks.size(); ++i1 )
|
size_t i1 = 3;
|
||||||
|
while ( cf.myLinks[i1-1].IsInternal() && i1 > 0 )
|
||||||
|
--i1;
|
||||||
|
|
||||||
|
for ( ; i1 < cf.myLinks.size(); ++i1 )
|
||||||
{
|
{
|
||||||
if ( !cf.myLinks[i1].IsInternal() )
|
if ( !cf.myLinks[i1].IsInternal() )
|
||||||
continue;
|
continue;
|
||||||
@ -1998,6 +2003,28 @@ namespace SMESH_MeshAlgos
|
|||||||
myMesh->RemoveFreeElement( f );
|
myMesh->RemoveFreeElement( f );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove faces that are merged off
|
||||||
|
for ( cutFacesIt = myCutFaces.cbegin(); cutFacesIt != myCutFaces.cend(); ++cutFacesIt )
|
||||||
|
{
|
||||||
|
const CutFace& cf = *cutFacesIt;
|
||||||
|
if ( !cf.myLinks.empty() || cf.myInitFace->IsNull() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
nodes.assign( cf.myInitFace->begin_nodes(), cf.myInitFace->end_nodes() );
|
||||||
|
for ( size_t i = 0; i < nodes.size(); ++i )
|
||||||
|
{
|
||||||
|
const SMDS_MeshNode* n = nodes[ i ];
|
||||||
|
while ( myRemove2KeepNodes.IsBound( n ))
|
||||||
|
n = myRemove2KeepNodes( n );
|
||||||
|
if ( n != nodes[ i ] && cf.myInitFace->GetNodeIndex( n ) >= 0 )
|
||||||
|
{
|
||||||
|
theNew2OldFaces[ cf.myInitFace->GetID() ].first = 0;
|
||||||
|
myMesh->RemoveFreeElement( cf.myInitFace );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// remove faces connected to cut off parts of cf.myInitFace
|
// remove faces connected to cut off parts of cf.myInitFace
|
||||||
|
|
||||||
nodes.resize(2);
|
nodes.resize(2);
|
||||||
@ -2010,9 +2037,9 @@ namespace SMESH_MeshAlgos
|
|||||||
if ( nodes[0] != nodes[1] &&
|
if ( nodes[0] != nodes[1] &&
|
||||||
myMesh->GetElementsByNodes( nodes, faces ))
|
myMesh->GetElementsByNodes( nodes, faces ))
|
||||||
{
|
{
|
||||||
if ( cutOffLinks[i].myFace &&
|
if ( // cutOffLinks[i].myFace &&
|
||||||
cutOffLinks[i].myIndex != EdgePart::_COPLANAR &&
|
cutOffLinks[i].myIndex != EdgePart::_COPLANAR &&
|
||||||
faces.size() == 2 )
|
faces.size() != 1 )
|
||||||
continue;
|
continue;
|
||||||
for ( size_t iF = 0; iF < faces.size(); ++iF )
|
for ( size_t iF = 0; iF < faces.size(); ++iF )
|
||||||
{
|
{
|
||||||
@ -2045,13 +2072,22 @@ namespace SMESH_MeshAlgos
|
|||||||
for ( size_t i = 0; i < touchedFaces.size(); ++i )
|
for ( size_t i = 0; i < touchedFaces.size(); ++i )
|
||||||
{
|
{
|
||||||
const CutFace& cf = *touchedFaces[i];
|
const CutFace& cf = *touchedFaces[i];
|
||||||
|
if ( cf.myInitFace->IsNull() )
|
||||||
|
continue;
|
||||||
|
|
||||||
int index = cf.myInitFace->GetID(); // index in theNew2OldFaces
|
int index = cf.myInitFace->GetID(); // index in theNew2OldFaces
|
||||||
if ( !theNew2OldFaces[ index ].first )
|
if ( !theNew2OldFaces[ index ].first )
|
||||||
continue; // already cut off
|
continue; // already cut off
|
||||||
|
|
||||||
|
cf.InitLinks();
|
||||||
if ( !cf.ReplaceNodes( myRemove2KeepNodes ))
|
if ( !cf.ReplaceNodes( myRemove2KeepNodes ))
|
||||||
|
{
|
||||||
|
if ( cf.myLinks.size() == 3 &&
|
||||||
|
cf.myInitFace->GetNodeIndex( cf.myLinks[0].myNode1 ) >= 0 &&
|
||||||
|
cf.myInitFace->GetNodeIndex( cf.myLinks[1].myNode1 ) >= 0 &&
|
||||||
|
cf.myInitFace->GetNodeIndex( cf.myLinks[2].myNode1 ) >= 0 )
|
||||||
continue; // just keep as is
|
continue; // just keep as is
|
||||||
|
}
|
||||||
|
|
||||||
if ( cf.myLinks.size() == 3 )
|
if ( cf.myLinks.size() == 3 )
|
||||||
{
|
{
|
||||||
@ -2737,8 +2773,16 @@ namespace
|
|||||||
{
|
{
|
||||||
theLoops.AddNewLoop();
|
theLoops.AddNewLoop();
|
||||||
theLoops.AddEdge( myLinks[0] );
|
theLoops.AddEdge( myLinks[0] );
|
||||||
|
if ( myLinks[0].myNode2 == myLinks[1].myNode1 )
|
||||||
|
{
|
||||||
theLoops.AddEdge( myLinks[1] );
|
theLoops.AddEdge( myLinks[1] );
|
||||||
theLoops.AddEdge( myLinks[2] );
|
theLoops.AddEdge( myLinks[2] );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
theLoops.AddEdge( myLinks[2] );
|
||||||
|
theLoops.AddEdge( myLinks[1] );
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2828,6 +2872,8 @@ namespace
|
|||||||
TLinkMap& theCutOffCoplanarLinks) const
|
TLinkMap& theCutOffCoplanarLinks) const
|
||||||
{
|
{
|
||||||
EdgePart sideEdge;
|
EdgePart sideEdge;
|
||||||
|
boost::container::flat_set< const SMDS_MeshElement* > checkedCoplanar;
|
||||||
|
|
||||||
for ( size_t i = 0; i < myLinks.size(); ++i )
|
for ( size_t i = 0; i < myLinks.size(); ++i )
|
||||||
{
|
{
|
||||||
if ( !myLinks[i].myFace )
|
if ( !myLinks[i].myFace )
|
||||||
@ -2875,6 +2921,21 @@ namespace
|
|||||||
loop = theLoops.GetLoopOf( twin );
|
loop = theLoops.GetLoopOf( twin );
|
||||||
toErase = ( loop && !loop->myLinks.empty() );
|
toErase = ( loop && !loop->myLinks.empty() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( toErase ) // do not erase if cutFace is connected to a co-planar cutFace
|
||||||
|
{
|
||||||
|
checkedCoplanar.clear();
|
||||||
|
for ( size_t iE = 0; iE < myLinks.size() && toErase; ++iE )
|
||||||
|
{
|
||||||
|
if ( !myLinks[iE].myFace || myLinks[iE].myIndex != EdgePart::_COPLANAR )
|
||||||
|
continue;
|
||||||
|
bool isAdded = checkedCoplanar.insert( myLinks[iE].myFace ).second;
|
||||||
|
if ( !isAdded )
|
||||||
|
continue;
|
||||||
|
toErase = SMESH_MeshAlgos::GetCommonNodes( myLinks[i ].myFace,
|
||||||
|
myLinks[iE].myFace ).size() < 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( toErase )
|
if ( toErase )
|
||||||
@ -2963,7 +3024,9 @@ namespace
|
|||||||
if ( myIndex + e.myIndex == _COPLANAR + _INTERNAL )
|
if ( myIndex + e.myIndex == _COPLANAR + _INTERNAL )
|
||||||
{
|
{
|
||||||
//check if the faces are connected
|
//check if the faces are connected
|
||||||
int nbCommonNodes = SMESH_MeshAlgos::GetCommonNodes( e.myFace, myFace ).size();
|
int nbCommonNodes = 0;
|
||||||
|
if ( e.myFace && myFace )
|
||||||
|
nbCommonNodes = SMESH_MeshAlgos::GetCommonNodes( e.myFace, myFace ).size();
|
||||||
bool toReplace = (( myIndex == _INTERNAL && nbCommonNodes > 1 ) ||
|
bool toReplace = (( myIndex == _INTERNAL && nbCommonNodes > 1 ) ||
|
||||||
( myIndex == _COPLANAR && nbCommonNodes < 2 ));
|
( myIndex == _COPLANAR && nbCommonNodes < 2 ));
|
||||||
if ( toReplace )
|
if ( toReplace )
|
||||||
@ -3070,7 +3133,7 @@ SMDS_Mesh* SMESH_MeshAlgos::MakeOffset( SMDS_ElemIteratorPtr theFaceIt,
|
|||||||
{
|
{
|
||||||
p.Set( nodes[i] );
|
p.Set( nodes[i] );
|
||||||
double dist = ( pPrev - p ).SquareModulus();
|
double dist = ( pPrev - p ).SquareModulus();
|
||||||
if ( dist > std::numeric_limits<double>::min() )
|
if ( dist < minNodeDist && dist > std::numeric_limits<double>::min() )
|
||||||
minNodeDist = dist;
|
minNodeDist = dist;
|
||||||
pPrev = p;
|
pPrev = p;
|
||||||
}
|
}
|
||||||
@ -3240,7 +3303,10 @@ SMDS_Mesh* SMESH_MeshAlgos::MakeOffset( SMDS_ElemIteratorPtr theFaceIt,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
if ( !isConcaveNode2 && nbCommonNodes > 0 )
|
if ( !isConcaveNode2 && nbCommonNodes > 0 )
|
||||||
continue;
|
{
|
||||||
|
if ( normals[ newFace->GetID() ] * normals[ closeFace->GetID() ] < 1.0 )
|
||||||
|
continue; // not co-planar
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
intersector.Cut( newFace, closeFace, nbCommonNodes );
|
intersector.Cut( newFace, closeFace, nbCommonNodes );
|
||||||
|
@ -2495,7 +2495,7 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
|
|||||||
"ExtrusionByNormal", "ExtrusionSweepObject2D","ExtrusionAlongPath","ExtrusionAlongPathObject",
|
"ExtrusionByNormal", "ExtrusionSweepObject2D","ExtrusionAlongPath","ExtrusionAlongPathObject",
|
||||||
"ExtrusionAlongPathX","ExtrusionAlongPathObject1D","ExtrusionAlongPathObject2D",
|
"ExtrusionAlongPathX","ExtrusionAlongPathObject1D","ExtrusionAlongPathObject2D",
|
||||||
"ExtrusionSweepObjects","RotationSweepObjects","ExtrusionAlongPathObjects",
|
"ExtrusionSweepObjects","RotationSweepObjects","ExtrusionAlongPathObjects",
|
||||||
"Mirror","MirrorObject","Translate","TranslateObject","Rotate","RotateObject",
|
"Mirror","MirrorObject","Translate","TranslateObject","Rotate","RotateObject","Offset",
|
||||||
"FindCoincidentNodes","MergeNodes","FindEqualElements","FillHole",
|
"FindCoincidentNodes","MergeNodes","FindEqualElements","FillHole",
|
||||||
"MergeElements","MergeEqualElements","SewFreeBorders","SewConformFreeBorders",
|
"MergeElements","MergeEqualElements","SewFreeBorders","SewConformFreeBorders",
|
||||||
"FindCoincidentFreeBorders", "SewCoincidentFreeBorders",
|
"FindCoincidentFreeBorders", "SewCoincidentFreeBorders",
|
||||||
|
Loading…
Reference in New Issue
Block a user