-// Copyright (C) 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012 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
// 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_ViscousLayers.cxx
// Created : Wed Dec 1 15:15:34 2010
using namespace std;
//================================================================================
-namespace VISCOUS
+namespace VISCOUS_3D
{
typedef int TGeomID;
* \brief Listener of events of 3D sub-meshes computed with viscous layers.
* It is used to clear an inferior dim sub-meshes modified by viscous layers
*/
- class _SrinkShapeListener : SMESH_subMeshEventListener
+ class _ShrinkShapeListener : SMESH_subMeshEventListener
{
- _SrinkShapeListener(): SMESH_subMeshEventListener(/*isDeletable=*/false) {}
- static SMESH_subMeshEventListener* Get() { static _SrinkShapeListener l; return &l; }
+ _ShrinkShapeListener()
+ : SMESH_subMeshEventListener(/*isDeletable=*/false,
+ "StdMeshers_ViscousLayers::_ShrinkShapeListener") {}
public:
+ static SMESH_subMeshEventListener* Get() { static _ShrinkShapeListener l; return &l; }
virtual void ProcessEvent(const int event,
const int eventType,
SMESH_subMesh* solidSM,
SMESH_subMeshEventListener::ProcessEvent(event,eventType,solidSM,data,hyp);
}
}
- static void ToClearSubMeshWithSolid( SMESH_subMesh* sm,
- const TopoDS_Shape& solid)
- {
- SMESH_subMesh* solidSM = sm->GetFather()->GetSubMesh( solid );
- SMESH_subMeshEventListenerData* data = solidSM->GetEventListenerData( Get());
- if ( data )
- {
- if ( find( data->mySubMeshes.begin(), data->mySubMeshes.end(), sm ) ==
- data->mySubMeshes.end())
- data->mySubMeshes.push_back( sm );
- }
- else
- {
- data = SMESH_subMeshEventListenerData::MakeData( /*dependent=*/sm );
- sm->SetEventListener( Get(), data, /*whereToListenTo=*/solidSM );
- }
- }
};
//--------------------------------------------------------------------------------
/*!
*/
class _ViscousListener : SMESH_subMeshEventListener
{
- _ViscousListener(): SMESH_subMeshEventListener(/*isDeletable=*/false) {}
+ _ViscousListener():
+ SMESH_subMeshEventListener(/*isDeletable=*/false,
+ "StdMeshers_ViscousLayers::_ViscousListener") {}
static SMESH_subMeshEventListener* Get() { static _ViscousListener l; return &l; }
public:
virtual void ProcessEvent(const int event,
}
};
+ //================================================================================
+ /*!
+ * \brief sets a sub-mesh event listener to clear sub-meshes of sub-shapes of
+ * the main shape when sub-mesh of the main shape is cleared,
+ * for example to clear sub-meshes of FACEs when sub-mesh of a SOLID
+ * is cleared
+ */
+ //================================================================================
+
+ void ToClearSubWithMain( SMESH_subMesh* sub, const TopoDS_Shape& main)
+ {
+ SMESH_subMesh* mainSM = sub->GetFather()->GetSubMesh( main );
+ SMESH_subMeshEventListenerData* data =
+ mainSM->GetEventListenerData( _ShrinkShapeListener::Get());
+ if ( data )
+ {
+ if ( find( data->mySubMeshes.begin(), data->mySubMeshes.end(), sub ) ==
+ data->mySubMeshes.end())
+ data->mySubMeshes.push_back( sub );
+ }
+ else
+ {
+ data = SMESH_subMeshEventListenerData::MakeData( /*dependent=*/sub );
+ sub->SetEventListener( _ShrinkShapeListener::Get(), data, /*whereToListenTo=*/mainSM );
+ }
+ }
//--------------------------------------------------------------------------------
/*!
* \brief Simplex (triangle or tetrahedron) based on 1 (tria) or 2 (tet) nodes of
virtual SMDSAbs_ElementType GetType() const { return SMDSAbs_Face; }
virtual vtkIdType GetVtkType() const { return -1; }
virtual SMDSAbs_EntityType GetEntityType() const { return SMDSEntity_Last; }
- virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const
+ virtual SMDSAbs_GeometryType GetGeomType() const { return SMDSGeom_TRIANGLE; }
+virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const
{ return SMDS_ElemIteratorPtr( new SMDS_NodeVectorElemIterator( _nn.begin(), _nn.end()));}
};
//--------------------------------------------------------------------------------
_nn[3]=_le2->_nodes[0];
}
};
-} // namespace VISCOUS
+} // namespace VISCOUS_3D
//================================================================================
// StdMeshers_ViscousLayers hypothesis
_name = StdMeshers_ViscousLayers::GetHypType();
_param_algo_dim = -3; // auxiliary hyp used by 3D algos
} // --------------------------------------------------------------------------------
-void StdMeshers_ViscousLayers::SetIgnoreFaces(const std::vector<int>& faceIds)
+void StdMeshers_ViscousLayers::SetBndShapesToIgnore(const std::vector<int>& faceIds)
+{
+ if ( faceIds != _ignoreBndShapeIds )
+ _ignoreBndShapeIds = faceIds, NotifySubMeshesHypothesisModification();
+} // --------------------------------------------------------------------------------
+bool StdMeshers_ViscousLayers::IsIgnoredShape(const int shapeID) const
{
- if ( faceIds != _ignoreFaceIds )
- _ignoreFaceIds = faceIds, NotifySubMeshesHypothesisModification();
+ return ( find( _ignoreBndShapeIds.begin(), _ignoreBndShapeIds.end(), shapeID )
+ != _ignoreBndShapeIds.end() );
} // --------------------------------------------------------------------------------
void StdMeshers_ViscousLayers::SetTotalThickness(double thickness)
{
const TopoDS_Shape& theShape,
const bool toMakeN2NMap) const
{
- using namespace VISCOUS;
+ using namespace VISCOUS_3D;
_ViscousBuilder bulder;
SMESH_ComputeErrorPtr err = bulder.Compute( theMesh, theShape );
if ( err && !err->IsOK() )
save << " " << _nbLayers
<< " " << _thickness
<< " " << _stretchFactor
- << " " << _ignoreFaceIds.size();
- for ( unsigned i = 0; i < _ignoreFaceIds.size(); ++i )
- save << " " << _ignoreFaceIds[i];
+ << " " << _ignoreBndShapeIds.size();
+ for ( unsigned i = 0; i < _ignoreBndShapeIds.size(); ++i )
+ save << " " << _ignoreBndShapeIds[i];
return save;
} // --------------------------------------------------------------------------------
std::istream & StdMeshers_ViscousLayers::LoadFrom(std::istream & load)
{
int nbFaces, faceID;
load >> _nbLayers >> _thickness >> _stretchFactor >> nbFaces;
- while ( _ignoreFaceIds.size() < nbFaces && load >> faceID )
- _ignoreFaceIds.push_back( faceID );
+ while ( _ignoreBndShapeIds.size() < nbFaces && load >> faceID )
+ _ignoreBndShapeIds.push_back( faceID );
return load;
} // --------------------------------------------------------------------------------
bool StdMeshers_ViscousLayers::SetParametersByMesh(const SMESH_Mesh* theMesh,
#endif
}
-using namespace VISCOUS;
+using namespace VISCOUS_3D;
//================================================================================
/*!
{
if ( ! makeLayer(_sdVec[i]) )
return _error;
+
+ if ( _sdVec[i]._edges.size() == 0 )
+ continue;
if ( ! inflate(_sdVec[i]) )
return _error;
vector<TopoDS_Shape> ignoreFaces;
for ( unsigned i = 0; i < _sdVec.size(); ++i )
{
- vector<TGeomID> ids = _sdVec[i]._hyp->GetIgnoreFaces();
+ vector<TGeomID> ids = _sdVec[i]._hyp->GetBndShapesToIgnore();
for ( unsigned i = 0; i < ids.size(); ++i )
{
const TopoDS_Shape& s = getMeshDS()->IndexToShape( ids[i] );
else // 2D
{
const gp_XY center( center3D.X(), center3D.Y() );
-
+
gp_XY uv0 = helper.GetNodeUV( F, data._edges[iFrom]->_2neibors->_nodes[0]);
gp_XY uvM = helper.GetNodeUV( F, data._edges[iFrom]->_nodes.back());
gp_XY uv1 = helper.GetNodeUV( F, data._edges[iTo-1]->_2neibors->_nodes[1]);
gp_Vec2d vec0( center, uv0 );
- gp_Vec2d vecM( center, uvM);
+ gp_Vec2d vecM( center, uvM );
gp_Vec2d vec1( center, uv1 );
double uLast = vec0.Angle( vec1 ); // -PI - +PI
double uMidl = vec0.Angle( vecM );
- if ( uLast < 0 ) uLast += 2.*M_PI; // 0.0 - 2*PI
- if ( uMidl < 0 ) uMidl += 2.*M_PI;
- const bool sense = ( uMidl < uLast );
+ if ( uLast * uMidl < 0. )
+ uLast += ( uMidl > 0 ? +2. : -2. ) * M_PI;
const double radius = 0.5 * ( vec0.Magnitude() + vec1.Magnitude() );
- gp_Ax2d axis( center, vec0 );
- gp_Circ2d circ ( axis, radius, sense );
+ gp_Ax2d axis( center, vec0 );
+ gp_Circ2d circ( axis, radius );
for ( int i = iFrom; i < iTo; ++i )
{
double newU = uLast * len[i-iFrom] / len.back();
}
}
+ if ( !getMeshDS()->IsEmbeddedMode() )
+ // Log node movement
+ for ( unsigned i = 0; i < data._edges.size(); ++i )
+ {
+ _LayerEdge& edge = *data._edges[i];
+ SMESH_TNodeXYZ p ( edge._nodes.back() );
+ getMeshDS()->MoveNode( p._node, p.X(), p.Y(), p.Z() );
+ }
+
// TODO: make quadratic prisms and polyhedrons(?)
helper.SetElementsOnShape(true);
}
SMESH_MesherHelper helper( *_mesh );
+ helper.ToFixNodeParameters( true );
// EDGE's to shrink
- map< int, _Shrinker1D > e2shrMap;
+ map< TGeomID, _Shrinker1D > e2shrMap;
// loop on FACES to srink mesh on
map< TGeomID, _SolidData* >::iterator f2sd = f2sdMap.begin();
_Shrinker1D& srinker = e2shrMap[ edgeIndex ];
eShri1D.insert( & srinker );
srinker.AddEdge( edge, helper );
+ VISCOUS_3D::ToClearSubWithMain( _mesh->GetSubMesh( edge->_sWOL ), data._solid );
// restore params of nodes on EGDE if the EDGE has been already
// srinked while srinking another FACE
srinker.RestoreParams();
for ( unsigned i = 0; i < nodesToSmooth.size(); ++i )
{
moved |= nodesToSmooth[i].Smooth( badNb,surface,helper,refSign,
- /*isCentroidal=*/isConcaveFace,/*set3D=*/false );
+ /*isCentroidal=*/isConcaveFace,
+ /*set3D=*/isConcaveFace);
}
if ( badNb < oldBadNb )
nbNoImpSteps = 0;
bool highQuality;
{
const bool hasTria = _mesh->NbTriangles(), hasQuad = _mesh->NbQuadrangles();
- if ( hasTria != hasQuad )
- {
+ if ( hasTria != hasQuad ) {
highQuality = hasQuad;
}
- else
- {
+ else {
set<int> nbNodesSet;
SMDS_ElemIteratorPtr fIt = smDS->GetElements();
while ( fIt->more() && nbNodesSet.size() < 2 )
dumpFunctionEnd();
}
// Set an event listener to clear FACE sub-mesh together with SOLID sub-mesh
- _SrinkShapeListener::ToClearSubMeshWithSolid( sm, data._solid );
+ VISCOUS_3D::ToClearSubWithMain( sm, data._solid );
+
+ if ( !getMeshDS()->IsEmbeddedMode() )
+ // Log node movement
+ for ( unsigned i = 0; i < nodesToSmooth.size(); ++i )
+ {
+ SMESH_TNodeXYZ p ( nodesToSmooth[i]._node );
+ getMeshDS()->MoveNode( nodesToSmooth[i]._node, p.X(), p.Y(), p.Z() );
+ }
} // loop on FACES to srink mesh on
GeomAdaptor_Curve aCurve(C, f,l);
const double totLen = GCPnts_AbscissaPoint::Length(aCurve, f, l);
- int nbExpectNodes = eSubMesh->NbNodes() - e->_nodes.size();
+ int nbExpectNodes = eSubMesh->NbNodes();
_initU .reserve( nbExpectNodes );
_normPar.reserve( nbExpectNodes );
_nodes .reserve( nbExpectNodes );
F = e2f->second.Oriented( TopAbs_FORWARD );
reverse = ( helper.GetSubShapeOri( F, E ) == TopAbs_REVERSED );
if ( helper.GetSubShapeOri( data._solid, F ) == TopAbs_REVERSED )
+ reverse = !reverse, F.Reverse();
+ if ( SMESH_Algo::IsReversedSubMesh( TopoDS::Face(F), getMeshDS() ))
reverse = !reverse;
}
else
vector< const SMDS_MeshNode*>& nn1 = ledges[j-dj1]->_nodes;
vector< const SMDS_MeshNode*>& nn2 = ledges[j-dj2]->_nodes;
if ( isOnFace )
- for ( unsigned z = 1; z < nn1.size(); ++z )
+ for ( size_t z = 1; z < nn1.size(); ++z )
sm->AddElement( getMeshDS()->AddFace( nn1[z-1], nn2[z-1], nn2[z], nn1[z] ));
else
- for ( unsigned z = 1; z < nn1.size(); ++z )
+ for ( size_t z = 1; z < nn1.size(); ++z )
sm->AddElement( new SMDS_FaceOfNodes( nn1[z-1], nn2[z-1], nn2[z], nn1[z]));
}
+
+ // Make edges
+ for ( int isFirst = 0; isFirst < 2; ++isFirst )
+ {
+ _LayerEdge* edge = isFirst ? ledges.front() : ledges.back();
+ if ( !edge->_sWOL.IsNull() && edge->_sWOL.ShapeType() == TopAbs_EDGE )
+ {
+ vector< const SMDS_MeshNode*>& nn = edge->_nodes;
+ if ( nn[1]->GetInverseElementIterator( SMDSAbs_Edge )->more() )
+ continue;
+ helper.SetSubShape( edge->_sWOL );
+ helper.SetElementsOnShape( true );
+ for ( size_t z = 1; z < nn.size(); ++z )
+ helper.AddEdge( nn[z-1], nn[z] );
+ }
+ }
}
}