-// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2020 CEA/DEN, EDF R&D, OPEN CASCADE
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
//=======================================================================
StdMeshers_RadialQuadrangle_1D2D::StdMeshers_RadialQuadrangle_1D2D(int hypId,
- int studyId,
SMESH_Gen* gen)
- :StdMeshers_Quadrangle_2D( hypId, studyId, gen )
+ :StdMeshers_Quadrangle_2D( hypId, gen )
{
_name = "RadialQuadrangle_1D2D";
_shapeType = (1 << TopAbs_FACE); // 1 bit per shape type
static TEdgeMarker theEdgeMarker;
return &theEdgeMarker;
}
- //! Clear face sumbesh if something happens on edges
+ //! Clear edge sumbesh if something happens on face
void ProcessEvent(const int event,
const int eventType,
- SMESH_subMesh* edgeSubMesh,
- EventListenerData* data,
+ SMESH_subMesh* faceSubMesh,
+ EventListenerData* edgesHolder,
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 );
- SMESH_subMesh* faceSubMesh = data->mySubMeshes.front();
- faceSubMesh->ComputeStateEngine( SMESH_subMesh::CLEAN );
+ std::list<SMESH_subMesh*>::iterator smIt = edgesHolder->mySubMeshes.begin();
+ for ( ; smIt != edgesHolder->mySubMeshes.end(); ++smIt )
+ {
+ SMESH_subMesh* edgeSM = *smIt;
+ edgeSM->ComputeStateEngine( SMESH_subMesh::CLEAN );
+ }
}
}
- };
-
- //================================================================================
- /*!
- * \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 ))
+ //! Store edge SMESH_subMesh'es computed by the algo
+ static void markEdge( const TopoDS_Edge& edge, SMESH_subMesh* faceSM )
{
- if ( !edgeSM->GetEventListenerData( TEdgeMarker::getListener() ))
- faceSubMesh->SetEventListener( TEdgeMarker::getListener(),
- SMESH_subMeshEventListenerData::MakeData(faceSubMesh),
- edgeSM);
+ 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 );
+ }
+ }
}
- }
+ };
//================================================================================
/*!
if ( nbWire > 2 || nbEdgesInWire.front() < 1 ) return 0;
// remove degenerated EDGEs
+ TopTools_MapOfShape degenVV;
list<TopoDS_Edge>::iterator edge = edges.begin();
while ( edge != edges.end() )
if ( SMESH_Algo::isDegenerated( *edge ))
+ {
+ degenVV.Add( SMESH_MesherHelper::IthVertex( 0, *edge ));
+ degenVV.Add( SMESH_MesherHelper::IthVertex( 1, *edge ));
edge = edges.erase( edge );
+ }
else
+ {
++edge;
+ }
int nbEdges = edges.size();
// find VERTEXes between continues EDGEs
double len1 = (++l2i)->first;
double len2 = (++l2i)->first;
if ( len1 - len0 > len2 - len1 )
- deviation2sideInd.insert( make_pair( 0., len2sideInd.begin()->second ));
+ deviation2sideInd.insert( std::make_pair( 0., len2sideInd.begin()->second ));
else
- deviation2sideInd.insert( make_pair( 0., len2sideInd.rbegin()->second ));
+ deviation2sideInd.insert( std::make_pair( 0., len2sideInd.rbegin()->second ));
+ }
+
+ double minDevi = deviation2sideInd.begin()->first;
+ int iMinCurv = deviation2sideInd.begin()->second;
+ if ( sides.size() == 3 && degenVV.Size() == 1 &&
+ minDevi / sides[ iMinCurv ]->Length() > 1e-3 )
+ {
+ // a triangle with curved sides and a degenerated EDGE (IPAL54585);
+ // use a side opposite to the degenerated EDGE as an elliptic one
+ for ( size_t iS = 0; iS < sides.size(); ++iS )
+ if ( degenVV.Contains( sides[ iS ]->FirstVertex() ))
+ {
+ deviation2sideInd.clear();
+ deviation2sideInd.insert( std::make_pair( 0.,( iS + 1 ) % sides.size() ));
+ break;
+ }
}
int iCirc = deviation2sideInd.rbegin()->second;
const int myID = -1001;
TNodeDistributor* myHyp = dynamic_cast<TNodeDistributor*>( aMesh.GetHypothesis( myID ));
if ( !myHyp )
- myHyp = new TNodeDistributor( myID, 0, aMesh.GetGen() );
+ myHyp = new TNodeDistributor( myID, aMesh.GetGen() );
return myHyp;
}
// -----------------------------------------------------------------------------
}
protected:
// -----------------------------------------------------------------------------
- TNodeDistributor( int hypId, int studyId, SMESH_Gen* gen)
- : StdMeshers_Regular_1D( hypId, studyId, gen)
+ TNodeDistributor( int hypId, SMESH_Gen* gen)
+ : StdMeshers_Regular_1D( hypId, gen)
{
}
// -----------------------------------------------------------------------------
* \brief Allow algo to do something after persistent restoration
* \param subMesh - restored submesh
*
- * call markEdgeAsComputedByMe()
+ * call TEdgeMarker::markEdge()
*/
//=======================================================================
void StdMeshers_RadialQuadrangle_1D2D::SubmeshRestored(SMESH_subMesh* faceSubMesh)
{
if ( !faceSubMesh->IsEmpty() )
+ SetEventListener( faceSubMesh );
+}
+
+//=======================================================================
+/*!
+ * \brief Sets event listener to a submesh
+ * \param subMesh - submesh where algo is set
+ *
+ * This method is called when a submesh gets HYP_OK algo_state.
+ */
+//=======================================================================
+
+void StdMeshers_RadialQuadrangle_1D2D::SetEventListener(SMESH_subMesh* faceSubMesh)
+{
+ 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 );
}
}
list< TopoDS_Edge >::iterator ee = emptyEdges.begin();
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
linSide1->GetUVPtStruct();
quad->side[1] = linSide1;
quad->side[2] = StdMeshers_FaceSide::New( circSide.get(), centerNode, ¢erUV );
quad->side[3] = linSide2;
+ quad->face = F;
myQuadList.push_back( quad );
else
ok = StdMeshers_Quadrangle_2D::computeTriangles( aMesh, F, quad );
+ if ( helper.HasDegeneratedEdges() )
+ {
+ StdMeshers_Quadrangle_2D::myNeedSmooth = true;
+ StdMeshers_Quadrangle_2D::smooth( quad );
+ }
+
StdMeshers_Quadrangle_2D::myHelper = 0;
return ok;