mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2025-01-13 02:00:34 +05:00
#16648 [CEA] RadialQuadrangle algorithm hypothesis change requires a Clear Mesh Data beforehand
+ 1) Optimize FreeEdges::IsFreeEdge() 2) Fix SMESH_MeshEditor::FindFreeBorder() for the case of multi-continuation 3) Improve Mesh.GetLength() to accept groups and list of IDs
This commit is contained in:
parent
385d4cede5
commit
d2248790d7
@ -2565,18 +2565,14 @@ void FreeEdges::SetMesh( const SMDS_Mesh* theMesh )
|
|||||||
|
|
||||||
bool FreeEdges::IsFreeEdge( const SMDS_MeshNode** theNodes, const int theFaceId )
|
bool FreeEdges::IsFreeEdge( const SMDS_MeshNode** theNodes, const int theFaceId )
|
||||||
{
|
{
|
||||||
TColStd_MapOfInteger aMap;
|
SMDS_ElemIteratorPtr anElemIter = theNodes[ 0 ]->GetInverseElementIterator(SMDSAbs_Face);
|
||||||
for ( int i = 0; i < 2; i++ )
|
while( anElemIter->more() )
|
||||||
{
|
{
|
||||||
SMDS_ElemIteratorPtr anElemIter = theNodes[ i ]->GetInverseElementIterator(SMDSAbs_Face);
|
if ( const SMDS_MeshElement* anElem = anElemIter->next())
|
||||||
while( anElemIter->more() )
|
|
||||||
{
|
{
|
||||||
if ( const SMDS_MeshElement* anElem = anElemIter->next())
|
const int anId = anElem->GetID();
|
||||||
{
|
if ( anId != theFaceId && anElem->GetNodeIndex( theNodes[1] ) >= 0 )
|
||||||
const int anId = anElem->GetID();
|
return false;
|
||||||
if ( anId != theFaceId && !aMap.Add( anId ))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -7681,9 +7681,9 @@ bool SMESH_MeshEditor::FindFreeBorder (const SMDS_MeshNode* theFirst
|
|||||||
// push_back the best free border
|
// push_back the best free border
|
||||||
cNL = & contNodes[ contNodes[0].empty() ? 1 : 0 ];
|
cNL = & contNodes[ contNodes[0].empty() ? 1 : 0 ];
|
||||||
cFL = & contFaces[ contFaces[0].empty() ? 1 : 0 ];
|
cFL = & contFaces[ contFaces[0].empty() ? 1 : 0 ];
|
||||||
theNodes.pop_back(); // remove nIgnore
|
//theNodes.pop_back(); // remove nIgnore
|
||||||
theNodes.pop_back(); // remove nStart
|
theNodes.pop_back(); // remove nStart
|
||||||
theFaces.pop_back(); // remove curElem
|
//theFaces.pop_back(); // remove curElem
|
||||||
theNodes.splice( theNodes.end(), *cNL );
|
theNodes.splice( theNodes.end(), *cNL );
|
||||||
theFaces.splice( theFaces.end(), *cFL );
|
theFaces.splice( theFaces.end(), *cFL );
|
||||||
return true;
|
return true;
|
||||||
|
@ -494,28 +494,37 @@ namespace
|
|||||||
<< " in a PolySegment " << iSeg );
|
<< " in a PolySegment " << iSeg );
|
||||||
|
|
||||||
if ( path.myDot1 == 0. &&
|
if ( path.myDot1 == 0. &&
|
||||||
path.myDot2 == 0. &&
|
path.myDot2 == 0. )
|
||||||
paths.size() - nbPaths >= 2 ) // use a face non-parallel to the plane
|
|
||||||
{
|
{
|
||||||
const SMDS_MeshElement* goodFace = 0;
|
if ( paths.size() - nbPaths >= 2 ) // use a face non-parallel to the plane
|
||||||
for ( size_t j = nbPaths; j < paths.size(); ++j )
|
|
||||||
{
|
{
|
||||||
path = paths[j];
|
const SMDS_MeshElement* goodFace = 0;
|
||||||
if ( path.Extend( plnNorm, plnOrig ))
|
for ( size_t j = nbPaths; j < paths.size(); ++j )
|
||||||
goodFace = paths[j].myFace;
|
|
||||||
else
|
|
||||||
paths[j].myFace = 0;
|
|
||||||
}
|
|
||||||
if ( !goodFace )
|
|
||||||
throw SALOME_Exception ( SMESH_Comment("Cant move from point ") << iP+1
|
|
||||||
<< " of a PolySegment " << iSeg );
|
|
||||||
for ( size_t j = nbPaths; j < paths.size(); ++j )
|
|
||||||
if ( !paths[j].myFace )
|
|
||||||
{
|
{
|
||||||
paths[j].myFace = goodFace;
|
path = paths[j];
|
||||||
paths[j].myNodeInd1 = goodFace->GetNodeIndex( paths[j].myNode1.Node() );
|
if ( path.Extend( plnNorm, plnOrig ))
|
||||||
paths[j].myNodeInd2 = goodFace->GetNodeIndex( paths[j].myNode2.Node() );
|
goodFace = paths[j].myFace;
|
||||||
|
else
|
||||||
|
paths[j].myFace = 0;
|
||||||
}
|
}
|
||||||
|
if ( !goodFace )
|
||||||
|
throw SALOME_Exception ( SMESH_Comment("Cant move from point ") << iP+1
|
||||||
|
<< " of a PolySegment " << iSeg );
|
||||||
|
for ( size_t j = nbPaths; j < paths.size(); ++j )
|
||||||
|
if ( !paths[j].myFace )
|
||||||
|
{
|
||||||
|
paths[j].myFace = goodFace;
|
||||||
|
paths[j].myNodeInd1 = goodFace->GetNodeIndex( paths[j].myNode1.Node() );
|
||||||
|
paths[j].myNodeInd2 = goodFace->GetNodeIndex( paths[j].myNode2.Node() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // use the sole found face
|
||||||
|
{
|
||||||
|
path = paths.back();
|
||||||
|
std::swap( path.myNode1, path.myNode2 );
|
||||||
|
std::swap( path.myNodeInd1, path.myNodeInd2 );
|
||||||
|
paths.push_back( path );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -456,7 +456,7 @@ bool SMESH_PreMeshInfo::readPreInfoFromHDF()
|
|||||||
mapOfNames );
|
mapOfNames );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
infoHdfGroup->CloseOnDisk();
|
infoHdfGroup->CloseOnDisk();
|
||||||
}
|
}
|
||||||
|
|
||||||
aFile->CloseOnDisk();
|
aFile->CloseOnDisk();
|
||||||
@ -841,8 +841,9 @@ void SMESH_PreMeshInfo::FullLoadFromFile() const
|
|||||||
meshDS->Modified();
|
meshDS->Modified();
|
||||||
|
|
||||||
// load dependent meshes referring/referred via hypotheses
|
// load dependent meshes referring/referred via hypotheses
|
||||||
mesh.GetSubMesh( mesh.GetShapeToMesh() )->
|
SMESH_subMesh* mainSub = mesh.GetSubMesh( mesh.GetShapeToMesh() );
|
||||||
ComputeStateEngine (SMESH_subMesh::SUBMESH_LOADED);
|
mainSub->ComputeStateEngine (SMESH_subMesh::SUBMESH_RESTORED); // #16648
|
||||||
|
mainSub->ComputeStateEngine (SMESH_subMesh::SUBMESH_LOADED);
|
||||||
|
|
||||||
MYDEBUGOUT( "END FullLoadFromFile()" );
|
MYDEBUGOUT( "END FullLoadFromFile()" );
|
||||||
}
|
}
|
||||||
|
@ -1235,8 +1235,6 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
|
|||||||
def GetMeshInfo(self, obj):
|
def GetMeshInfo(self, obj):
|
||||||
"""
|
"""
|
||||||
Get the mesh statistic.
|
Get the mesh statistic.
|
||||||
Use :meth:`smeshBuilder.EnumToLong` to get an integer from
|
|
||||||
an item of :class:`SMESH.EntityType`.
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
dictionary { :class:`SMESH.EntityType` - "count of elements" }
|
dictionary { :class:`SMESH.EntityType` - "count of elements" }
|
||||||
@ -3091,8 +3089,6 @@ class Mesh(metaclass = MeshMeta):
|
|||||||
def GetMeshInfo(self, obj = None):
|
def GetMeshInfo(self, obj = None):
|
||||||
"""
|
"""
|
||||||
Get the mesh statistic.
|
Get the mesh statistic.
|
||||||
Use :meth:`smeshBuilder.EnumToLong` to get an integer from
|
|
||||||
an item of :class:`SMESH.EntityType`.
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
dictionary { :class:`SMESH.EntityType` - "count of elements" }
|
dictionary { :class:`SMESH.EntityType` - "count of elements" }
|
||||||
@ -6951,52 +6947,90 @@ class Mesh(metaclass = MeshMeta):
|
|||||||
|
|
||||||
def GetLength(self, elemId=None):
|
def GetLength(self, elemId=None):
|
||||||
"""
|
"""
|
||||||
Get length of 1D element or sum of lengths of all 1D mesh elements
|
Get length of all given 1D elements or sum length of all 1D mesh elements
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
elemId: mesh element ID (if not defined - sum of length of all 1D elements will be calculated)
|
elemId: either a mesh element ID or a list of IDs or :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`. By default sum length of all 1D elements will be calculated.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
element's length value if *elemId* is specified or sum of all 1D mesh elements' lengths otherwise
|
Sum of lengths of given elements
|
||||||
"""
|
"""
|
||||||
|
|
||||||
length = 0
|
length = 0
|
||||||
if elemId == None:
|
if elemId == None:
|
||||||
length = self.smeshpyD.GetLength(self)
|
length = self.smeshpyD.GetLength(self)
|
||||||
|
elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
|
||||||
|
length = self.smeshpyD.GetLength(elemId)
|
||||||
|
elif elemId == []:
|
||||||
|
length = 0
|
||||||
|
elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
|
||||||
|
for obj in elemId:
|
||||||
|
length += self.smeshpyD.GetLength(obj)
|
||||||
|
elif isinstance(elemId, list) and isinstance(elemId[0], int):
|
||||||
|
unRegister = genObjUnRegister()
|
||||||
|
obj = self.GetIDSource( elemId )
|
||||||
|
unRegister.set( obj )
|
||||||
|
length = self.smeshpyD.GetLength( obj )
|
||||||
else:
|
else:
|
||||||
length = self.FunctorValue(SMESH.FT_Length, elemId)
|
length = self.FunctorValue(SMESH.FT_Length, elemId)
|
||||||
return length
|
return length
|
||||||
|
|
||||||
def GetArea(self, elemId=None):
|
def GetArea(self, elemId=None):
|
||||||
"""
|
"""
|
||||||
Get area of 2D element or sum of areas of all 2D mesh elements
|
Get area of given 2D elements or sum area of all 2D mesh elements
|
||||||
elemId mesh element ID (if not defined - sum of areas of all 2D elements will be calculated)
|
|
||||||
|
Parameters:
|
||||||
|
elemId: either a mesh element ID or a list of IDs or :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`. By default sum area of all 2D elements will be calculated.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
element's area value if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
|
Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
|
||||||
"""
|
"""
|
||||||
|
|
||||||
area = 0
|
area = 0
|
||||||
if elemId == None:
|
if elemId == None:
|
||||||
area = self.smeshpyD.GetArea(self)
|
area = self.smeshpyD.GetArea(self)
|
||||||
|
elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
|
||||||
|
area = self.smeshpyD.GetArea(elemId)
|
||||||
|
elif elemId == []:
|
||||||
|
area = 0
|
||||||
|
elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
|
||||||
|
for obj in elemId:
|
||||||
|
area += self.smeshpyD.GetArea(obj)
|
||||||
|
elif isinstance(elemId, list) and isinstance(elemId[0], int):
|
||||||
|
unRegister = genObjUnRegister()
|
||||||
|
obj = self.GetIDSource( elemId )
|
||||||
|
unRegister.set( obj )
|
||||||
|
area = self.smeshpyD.GetArea( obj )
|
||||||
else:
|
else:
|
||||||
area = self.FunctorValue(SMESH.FT_Area, elemId)
|
area = self.FunctorValue(SMESH.FT_Area, elemId)
|
||||||
return area
|
return area
|
||||||
|
|
||||||
def GetVolume(self, elemId=None):
|
def GetVolume(self, elemId=None):
|
||||||
"""
|
"""
|
||||||
Get volume of 3D element or sum of volumes of all 3D mesh elements
|
Get volume of a 3D element or sum of volumes of all 3D mesh elements
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
elemId: mesh element ID (if not defined - sum of volumes of all 3D elements will be calculated)
|
elemId: either a mesh element ID or a list of IDs or :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`. By default sum volume of all 3D elements will be calculated.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
|
Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
|
||||||
"""
|
"""
|
||||||
|
|
||||||
volume = 0
|
volume = 0
|
||||||
if elemId == None:
|
if elemId == None:
|
||||||
volume = self.smeshpyD.GetVolume(self)
|
volume= self.smeshpyD.GetVolume(self)
|
||||||
|
elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
|
||||||
|
volume= self.smeshpyD.GetVolume(elemId)
|
||||||
|
elif elemId == []:
|
||||||
|
volume = 0
|
||||||
|
elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
|
||||||
|
for obj in elemId:
|
||||||
|
volume+= self.smeshpyD.GetVolume(obj)
|
||||||
|
elif isinstance(elemId, list) and isinstance(elemId[0], int):
|
||||||
|
unRegister = genObjUnRegister()
|
||||||
|
obj = self.GetIDSource( elemId )
|
||||||
|
unRegister.set( obj )
|
||||||
|
volume= self.smeshpyD.GetVolume( obj )
|
||||||
else:
|
else:
|
||||||
volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
|
volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
|
||||||
return volume
|
return volume
|
||||||
|
@ -163,39 +163,46 @@ namespace
|
|||||||
static TEdgeMarker theEdgeMarker;
|
static TEdgeMarker theEdgeMarker;
|
||||||
return &theEdgeMarker;
|
return &theEdgeMarker;
|
||||||
}
|
}
|
||||||
//! Clear face sumbesh if something happens on edges
|
//! Clear edge sumbesh if something happens on face
|
||||||
void ProcessEvent(const int event,
|
void ProcessEvent(const int event,
|
||||||
const int eventType,
|
const int eventType,
|
||||||
SMESH_subMesh* edgeSubMesh,
|
SMESH_subMesh* faceSubMesh,
|
||||||
EventListenerData* data,
|
EventListenerData* edgesHolder,
|
||||||
const SMESH_Hypothesis* /*hyp*/)
|
const SMESH_Hypothesis* /*hyp*/)
|
||||||
{
|
{
|
||||||
if ( data && !data->mySubMeshes.empty() && eventType == SMESH_subMesh::ALGO_EVENT)
|
if ( edgesHolder && eventType == SMESH_subMesh::ALGO_EVENT)
|
||||||
{
|
{
|
||||||
ASSERT( data->mySubMeshes.front() != edgeSubMesh );
|
std::list<SMESH_subMesh*>::iterator smIt = edgesHolder->mySubMeshes.begin();
|
||||||
SMESH_subMesh* faceSubMesh = data->mySubMeshes.front();
|
for ( ; smIt != edgesHolder->mySubMeshes.end(); ++smIt )
|
||||||
faceSubMesh->ComputeStateEngine( SMESH_subMesh::CLEAN );
|
{
|
||||||
|
SMESH_subMesh* edgeSM = *smIt;
|
||||||
|
edgeSM->ComputeStateEngine( SMESH_subMesh::CLEAN );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//! Store edge SMESH_subMesh'es computed by the algo
|
||||||
|
static void markEdge( const TopoDS_Edge& edge, SMESH_subMesh* faceSM )
|
||||||
|
{
|
||||||
|
if ( SMESH_subMesh* edgeSM = faceSM->GetFather()->GetSubMeshContaining( edge ))
|
||||||
|
{
|
||||||
|
EventListenerData* edgesHolder = faceSM->GetEventListenerData( getListener() );
|
||||||
|
if ( edgesHolder )
|
||||||
|
{
|
||||||
|
std::list<SMESH_subMesh*>::iterator smIt = std::find( edgesHolder->mySubMeshes.begin(),
|
||||||
|
edgesHolder->mySubMeshes.end(),
|
||||||
|
edgeSM );
|
||||||
|
if ( smIt == edgesHolder->mySubMeshes.end() )
|
||||||
|
edgesHolder->mySubMeshes.push_back( edgeSM );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
edgesHolder = SMESH_subMeshEventListenerData::MakeData( edgeSM );
|
||||||
|
faceSM->SetEventListener( TEdgeMarker::getListener(), edgesHolder, faceSM );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//================================================================================
|
|
||||||
/*!
|
|
||||||
* \brief Mark an edge as computed by StdMeshers_RadialQuadrangle_1D2D
|
|
||||||
*/
|
|
||||||
//================================================================================
|
|
||||||
|
|
||||||
void markEdgeAsComputedByMe(const TopoDS_Edge& edge, SMESH_subMesh* faceSubMesh)
|
|
||||||
{
|
|
||||||
if ( SMESH_subMesh* edgeSM = faceSubMesh->GetFather()->GetSubMeshContaining( edge ))
|
|
||||||
{
|
|
||||||
if ( !edgeSM->GetEventListenerData( TEdgeMarker::getListener() ))
|
|
||||||
faceSubMesh->SetEventListener( TEdgeMarker::getListener(),
|
|
||||||
SMESH_subMeshEventListenerData::MakeData(faceSubMesh),
|
|
||||||
edgeSM);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
/*!
|
/*!
|
||||||
* \brief Return sides of the face connected in the order: aCircEdge, aLinEdge1, aLinEdge2
|
* \brief Return sides of the face connected in the order: aCircEdge, aLinEdge1, aLinEdge2
|
||||||
@ -744,7 +751,7 @@ protected:
|
|||||||
* \brief Allow algo to do something after persistent restoration
|
* \brief Allow algo to do something after persistent restoration
|
||||||
* \param subMesh - restored submesh
|
* \param subMesh - restored submesh
|
||||||
*
|
*
|
||||||
* call markEdgeAsComputedByMe()
|
* call TEdgeMarker::markEdge()
|
||||||
*/
|
*/
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
|
||||||
@ -754,7 +761,7 @@ void StdMeshers_RadialQuadrangle_1D2D::SubmeshRestored(SMESH_subMesh* faceSubMes
|
|||||||
{
|
{
|
||||||
for ( TopExp_Explorer e( faceSubMesh->GetSubShape(), TopAbs_EDGE ); e.More(); e.Next() )
|
for ( TopExp_Explorer e( faceSubMesh->GetSubShape(), TopAbs_EDGE ); e.More(); e.Next() )
|
||||||
{
|
{
|
||||||
markEdgeAsComputedByMe( TopoDS::Edge( e.Current() ), faceSubMesh );
|
TEdgeMarker::markEdge( TopoDS::Edge( e.Current() ), faceSubMesh );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -963,7 +970,7 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh& aMesh,
|
|||||||
|
|
||||||
list< TopoDS_Edge >::iterator ee = emptyEdges.begin();
|
list< TopoDS_Edge >::iterator ee = emptyEdges.begin();
|
||||||
for ( ; ee != emptyEdges.end(); ++ee )
|
for ( ; ee != emptyEdges.end(); ++ee )
|
||||||
markEdgeAsComputedByMe( *ee, aMesh.GetSubMesh( F ));
|
TEdgeMarker::markEdge( *ee, aMesh.GetSubMesh( F ));
|
||||||
|
|
||||||
circSide->GetUVPtStruct(); // let sides take into account just computed nodes
|
circSide->GetUVPtStruct(); // let sides take into account just computed nodes
|
||||||
linSide1->GetUVPtStruct();
|
linSide1->GetUVPtStruct();
|
||||||
|
Loading…
Reference in New Issue
Block a user