-// Copyright (C) 2007-2019 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
_thickness = Max( _thickness, hyp->GetTotalThickness() );
_stretchFactor += hyp->GetStretchFactor();
_method = hyp->GetMethod();
+ if ( _groupName.empty() )
+ _groupName = hyp->GetGroupName();
}
}
double GetTotalThickness() const { return _thickness; /*_nbHyps ? _thickness / _nbHyps : 0;*/ }
double GetStretchFactor() const { return _nbHyps ? _stretchFactor / _nbHyps : 0; }
int GetNumberLayers() const { return _nbLayers; }
int GetMethod() const { return _method; }
+ bool ToCreateGroup() const { return !_groupName.empty(); }
+ const std::string& GetGroupName() const { return _groupName; }
bool UseSurfaceNormal() const
{ return _method == StdMeshers_ViscousLayers::SURF_OFFSET_SMOOTH; }
static bool Equals( double v1, double v2 ) { return Abs( v1 - v2 ) < 0.01 * ( v1 + v2 ); }
private:
- int _nbLayers, _nbHyps, _method;
- double _thickness, _stretchFactor;
+ int _nbLayers, _nbHyps, _method;
+ double _thickness, _stretchFactor;
+ std::string _groupName;
};
//--------------------------------------------------------------------------------
private:
- bool findSolidsWithLayers();
+ bool findSolidsWithLayers(const bool checkFaceMesh=true);
bool setBefore( _SolidData& solidBefore, _SolidData& solidAfter );
bool findFacesWithLayers(const bool onlyWith=false);
void findPeriodicFaces();
StdMeshers_ViscousLayers::StdMeshers_ViscousLayers(int hypId, SMESH_Gen* gen)
:SMESH_Hypothesis(hypId, gen),
_isToIgnoreShapes(1), _nbLayers(1), _thickness(1), _stretchFactor(1),
- _method( SURF_OFFSET_SMOOTH )
+ _method( SURF_OFFSET_SMOOTH ),
+ _groupName("")
{
_name = StdMeshers_ViscousLayers::GetHypType();
_param_algo_dim = -3; // auxiliary hyp used by 3D algos
if ( _method != method )
_method = method, NotifySubMeshesHypothesisModification();
} // --------------------------------------------------------------------------------
+void StdMeshers_ViscousLayers::SetGroupName(const std::string& name)
+{
+ if ( _groupName != name )
+ {
+ _groupName = name;
+ if ( !_groupName.empty() )
+ NotifySubMeshesHypothesisModification();
+ }
+} // --------------------------------------------------------------------------------
SMESH_ProxyMesh::Ptr
StdMeshers_ViscousLayers::Compute(SMESH_Mesh& theMesh,
const TopoDS_Shape& theShape,
save << " " << _shapeIds[i];
save << " " << !_isToIgnoreShapes; // negate to keep the behavior in old studies.
save << " " << _method;
+ save << " " << _groupName.size();
+ if ( !_groupName.empty() )
+ save << " " << _groupName;
return save;
} // --------------------------------------------------------------------------------
std::istream & StdMeshers_ViscousLayers::LoadFrom(std::istream & load)
_isToIgnoreShapes = !shapeToTreat;
if ( load >> method )
_method = (ExtrusionMethod) method;
+ int nameSize = 0;
+ if ( load >> nameSize && nameSize > 0 )
+ {
+ _groupName.resize( nameSize );
+ load.get( _groupName[0] ); // remove a white-space
+ load.getline( &_groupName[0], nameSize + 1 );
+ }
}
else {
_isToIgnoreShapes = true; // old behavior
( std::find( _shapeIds.begin(), _shapeIds.end(), shapeIndex ) != _shapeIds.end() );
return IsToIgnoreShapes() ? !isIn : isIn;
}
+
+// --------------------------------------------------------------------------------
+SMDS_MeshGroup* StdMeshers_ViscousLayers::CreateGroup( const std::string& theName,
+ SMESH_Mesh& theMesh,
+ SMDSAbs_ElementType theType)
+{
+ SMESH_Group* group = 0;
+ SMDS_MeshGroup* groupDS = 0;
+
+ if ( theName.empty() )
+ return groupDS;
+
+ if ( SMESH_Mesh::GroupIteratorPtr grIt = theMesh.GetGroups() )
+ while( grIt->more() && !group )
+ {
+ group = grIt->next();
+ if ( !group ||
+ group->GetGroupDS()->GetType() != theType ||
+ group->GetName() != theName ||
+ !dynamic_cast< SMESHDS_Group* >( group->GetGroupDS() ))
+ group = 0;
+ }
+ if ( !group )
+ group = theMesh.AddGroup( theType, theName.c_str() );
+
+ groupDS = & dynamic_cast< SMESHDS_Group* >( group->GetGroupDS() )->SMDSGroup();
+
+ return groupDS;
+}
+
// END StdMeshers_ViscousLayers hypothesis
//================================================================================
PyDump(SMESH_Mesh& m) {
int tag = 3 + m.GetId();
const char* fname = "/tmp/viscous.py";
- cout << "execfile('"<<fname<<"')"<<endl;
+ cout << "exec(open('"<<fname<<"','rb').read() )"<<endl;
py = _pyStream = new ofstream(fname);
*py << "import SMESH" << endl
<< "from salome.smesh import smeshBuilder" << endl
return SMESH_ComputeErrorPtr(); // everything already computed
- findSolidsWithLayers();
+ findSolidsWithLayers( /*checkFaceMesh=*/false );
bool ok = findFacesWithLayers( true );
// remove _MeshOfSolid's of _SolidData's
*/
//================================================================================
-bool _ViscousBuilder::findSolidsWithLayers()
+bool _ViscousBuilder::findSolidsWithLayers(const bool checkFaceMesh)
{
// get all solids
TopTools_IndexedMapOfShape allSolids;
SMESH_HypoFilter filter;
for ( int i = 1; i <= allSolids.Extent(); ++i )
{
- // find StdMeshers_ViscousLayers hyp assigned to the i-th solid
SMESH_subMesh* sm = _mesh->GetSubMesh( allSolids(i) );
if ( sm->GetSubMeshDS() && sm->GetSubMeshDS()->NbElements() > 0 )
continue; // solid is already meshed
+ // TODO: check if algo is hidden
SMESH_Algo* algo = sm->GetAlgo();
if ( !algo ) continue;
- // TODO: check if algo is hidden
+ // check if all FACEs are meshed, which can be false if Compute() a sub-shape
+ if ( checkFaceMesh )
+ {
+ bool facesMeshed = true;
+ SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(false,true);
+ while ( smIt->more() && facesMeshed )
+ {
+ SMESH_subMesh * faceSM = smIt->next();
+ if ( faceSM->GetSubShape().ShapeType() != TopAbs_FACE )
+ break;
+ facesMeshed = faceSM->IsMeshComputed();
+ }
+ if ( !facesMeshed )
+ continue;
+ }
+ // find StdMeshers_ViscousLayers hyp assigned to the i-th solid
const list <const SMESHDS_Hypothesis *> & allHyps =
algo->GetUsedHypothesis(*_mesh, allSolids(i), /*ignoreAuxiliary=*/false);
_SolidData* soData = 0;
if ( isC1 )
{
double maxEdgeLen = 3 * Min( eov._edges[0]->_maxLen, eov._hyp.GetTotalThickness() );
- double eLen1 = SMESH_Algo::EdgeLength( TopoDS::Edge( dirOfEdges[i].first->_shape ));
- double eLen2 = SMESH_Algo::EdgeLength( TopoDS::Edge( dirOfEdges[j].first->_shape ));
- if ( eLen1 < maxEdgeLen ) eov._eosC1.push_back( dirOfEdges[i].first );
- if ( eLen2 < maxEdgeLen ) eov._eosC1.push_back( dirOfEdges[j].first );
- dirOfEdges[i].first = 0;
- dirOfEdges[j].first = 0;
+ for ( int isJ = 0; isJ < 2; ++isJ ) // loop on [i,j]
+ {
+ size_t k = isJ ? j : i;
+ const TopoDS_Edge& e = TopoDS::Edge( dirOfEdges[k].first->_shape );
+ double eLen = SMESH_Algo::EdgeLength( e );
+ if ( eLen < maxEdgeLen )
+ {
+ TopoDS_Shape oppV = SMESH_MesherHelper::IthVertex( 0, e );
+ if ( oppV.IsSame( V ))
+ oppV = SMESH_MesherHelper::IthVertex( 1, e );
+ _EdgesOnShape* eovOpp = data.GetShapeEdges( oppV );
+ if ( dirOfEdges[k].second * eovOpp->_edges[0]->_normal < 0 )
+ eov._eosC1.push_back( dirOfEdges[k].first );
+ }
+ dirOfEdges[k].first = 0;
+ }
}
}
} // fill _eosC1 of VERTEXes
void _Smoother1D::offPointsToPython() const
{
const char* fname = "/tmp/offPoints.py";
- cout << "execfile('"<<fname<<"')"<<endl;
+ cout << "exec(open('"<<fname<<"','rb').read() )"<<endl;
ofstream py(fname);
py << "import SMESH" << endl
<< "from salome.smesh import smeshBuilder" << endl
const TGeomID faceID = getMeshDS()->ShapeToIndex( exp.Current() );
if ( data._ignoreFaceIds.count( faceID ))
continue;
+ _EdgesOnShape* eos = data.GetShapeEdges( faceID );
+ SMDS_MeshGroup* group = StdMeshers_ViscousLayers::CreateGroup( eos->_hyp.GetGroupName(),
+ *helper.GetMesh(),
+ SMDSAbs_Volume );
+ std::vector< const SMDS_MeshElement* > vols;
const bool isReversedFace = data._reversedFaceIds.count( faceID );
SMESHDS_SubMesh* fSubM = getMeshDS()->MeshElements( exp.Current() );
SMDS_ElemIteratorPtr fIt = fSubM->GetElements();
if ( 0 < nnSet.size() && nnSet.size() < 3 )
continue;
+ vols.clear();
+ const SMDS_MeshElement* vol;
+
switch ( nbNodes )
{
case 3: // TRIA
{
// PENTA
for ( size_t iZ = 1; iZ < minZ; ++iZ )
- helper.AddVolume( (*nnVec[0])[iZ-1], (*nnVec[1])[iZ-1], (*nnVec[2])[iZ-1],
- (*nnVec[0])[iZ], (*nnVec[1])[iZ], (*nnVec[2])[iZ]);
+ {
+ vol = helper.AddVolume( (*nnVec[0])[iZ-1], (*nnVec[1])[iZ-1], (*nnVec[2])[iZ-1],
+ (*nnVec[0])[iZ], (*nnVec[1])[iZ], (*nnVec[2])[iZ]);
+ vols.push_back( vol );
+ }
for ( size_t iZ = minZ; iZ < maxZ; ++iZ )
{
int i2 = *degenEdgeInd.begin();
int i0 = helper.WrapIndex( i2 - 1, nbNodes );
int i1 = helper.WrapIndex( i2 + 1, nbNodes );
- helper.AddVolume( (*nnVec[i0])[iZ-1], (*nnVec[i1])[iZ-1],
- (*nnVec[i1])[iZ ], (*nnVec[i0])[iZ ], (*nnVec[i2]).back());
+ vol = helper.AddVolume( (*nnVec[i0])[iZ-1], (*nnVec[i1])[iZ-1],
+ (*nnVec[i1])[iZ ], (*nnVec[i0])[iZ ], (*nnVec[i2]).back());
+ vols.push_back( vol );
}
else // TETRA
{
int i3 = !degenEdgeInd.count(0) ? 0 : !degenEdgeInd.count(1) ? 1 : 2;
- helper.AddVolume( (*nnVec[ 0 ])[ i3 == 0 ? iZ-1 : nnVec[0]->size()-1 ],
- (*nnVec[ 1 ])[ i3 == 1 ? iZ-1 : nnVec[1]->size()-1 ],
- (*nnVec[ 2 ])[ i3 == 2 ? iZ-1 : nnVec[2]->size()-1 ],
- (*nnVec[ i3 ])[ iZ ]);
+ vol = helper.AddVolume( (*nnVec[ 0 ])[ i3 == 0 ? iZ-1 : nnVec[0]->size()-1 ],
+ (*nnVec[ 1 ])[ i3 == 1 ? iZ-1 : nnVec[1]->size()-1 ],
+ (*nnVec[ 2 ])[ i3 == 2 ? iZ-1 : nnVec[2]->size()-1 ],
+ (*nnVec[ i3 ])[ iZ ]);
+ vols.push_back( vol );
}
}
break; // TRIA
{
// HEX
for ( size_t iZ = 1; iZ < minZ; ++iZ )
- helper.AddVolume( (*nnVec[0])[iZ-1], (*nnVec[1])[iZ-1],
- (*nnVec[2])[iZ-1], (*nnVec[3])[iZ-1],
- (*nnVec[0])[iZ], (*nnVec[1])[iZ],
- (*nnVec[2])[iZ], (*nnVec[3])[iZ]);
+ {
+ vol = helper.AddVolume( (*nnVec[0])[iZ-1], (*nnVec[1])[iZ-1],
+ (*nnVec[2])[iZ-1], (*nnVec[3])[iZ-1],
+ (*nnVec[0])[iZ], (*nnVec[1])[iZ],
+ (*nnVec[2])[iZ], (*nnVec[3])[iZ]);
+ vols.push_back( vol );
+ }
for ( size_t iZ = minZ; iZ < maxZ; ++iZ )
{
int i0 = helper.WrapIndex( i3 + 1, nbNodes );
int i1 = helper.WrapIndex( i0 + 1, nbNodes );
- const SMDS_MeshElement* vol =
- helper.AddVolume( nnVec[i3]->back(), (*nnVec[i0])[iZ], (*nnVec[i0])[iZ-1],
- nnVec[i2]->back(), (*nnVec[i1])[iZ], (*nnVec[i1])[iZ-1]);
+ vol = helper.AddVolume( nnVec[i3]->back(), (*nnVec[i0])[iZ], (*nnVec[i0])[iZ-1],
+ nnVec[i2]->back(), (*nnVec[i1])[iZ], (*nnVec[i1])[iZ-1]);
+ vols.push_back( vol );
if ( !ok && vol )
degenVols.push_back( vol );
}
default: // degen HEX
{
- const SMDS_MeshElement* vol =
- helper.AddVolume( nnVec[0]->size() > iZ-1 ? (*nnVec[0])[iZ-1] : nnVec[0]->back(),
- nnVec[1]->size() > iZ-1 ? (*nnVec[1])[iZ-1] : nnVec[1]->back(),
- nnVec[2]->size() > iZ-1 ? (*nnVec[2])[iZ-1] : nnVec[2]->back(),
- nnVec[3]->size() > iZ-1 ? (*nnVec[3])[iZ-1] : nnVec[3]->back(),
- nnVec[0]->size() > iZ ? (*nnVec[0])[iZ] : nnVec[0]->back(),
- nnVec[1]->size() > iZ ? (*nnVec[1])[iZ] : nnVec[1]->back(),
- nnVec[2]->size() > iZ ? (*nnVec[2])[iZ] : nnVec[2]->back(),
- nnVec[3]->size() > iZ ? (*nnVec[3])[iZ] : nnVec[3]->back());
+ vol = helper.AddVolume( nnVec[0]->size() > iZ-1 ? (*nnVec[0])[iZ-1] : nnVec[0]->back(),
+ nnVec[1]->size() > iZ-1 ? (*nnVec[1])[iZ-1] : nnVec[1]->back(),
+ nnVec[2]->size() > iZ-1 ? (*nnVec[2])[iZ-1] : nnVec[2]->back(),
+ nnVec[3]->size() > iZ-1 ? (*nnVec[3])[iZ-1] : nnVec[3]->back(),
+ nnVec[0]->size() > iZ ? (*nnVec[0])[iZ] : nnVec[0]->back(),
+ nnVec[1]->size() > iZ ? (*nnVec[1])[iZ] : nnVec[1]->back(),
+ nnVec[2]->size() > iZ ? (*nnVec[2])[iZ] : nnVec[2]->back(),
+ nnVec[3]->size() > iZ ? (*nnVec[3])[iZ] : nnVec[3]->back());
+ vols.push_back( vol );
degenVols.push_back( vol );
}
}
return error("Not supported type of element", data._index);
} // switch ( nbNodes )
+
+ if ( group )
+ for ( size_t i = 0; i < vols.size(); ++i )
+ group->Add( vols[ i ]);
+
} // while ( fIt->more() )
} // loop on FACEs
PeriodicFaces( ShrinkFace* sf1, ShrinkFace* sf2 ): _shriFace{ sf1, sf2 } {}
bool IncludeShrunk( const TopoDS_Face& face, const TopTools_MapOfShape& shrunkFaces ) const;
bool MoveNodes( const TopoDS_Face& tgtFace );
+ void Clear() { _nnMap.clear(); }
+ bool IsEmpty() const { return _nnMap.empty(); }
};
//--------------------------------------------------------------------------------
return & _periodicFaces[ i ];
return 0;
}
+ void ClearPeriodic( const TopoDS_Face& face )
+ {
+ for ( size_t i = 0; i < _periodicFaces.size(); ++i )
+ if ( _periodicFaces[ i ]._shriFace[0]->IsSame( face ) ||
+ _periodicFaces[ i ]._shriFace[1]->IsSame( face ))
+ _periodicFaces[ i ].Clear();
+ }
};
//================================================================================
bool PeriodicFaces::IncludeShrunk( const TopoDS_Face& face,
const TopTools_MapOfShape& shrunkFaces ) const
{
+ if ( IsEmpty() ) return false;
return (( _shriFace[0]->IsSame( face ) && _shriFace[1]->IsShrunk( shrunkFaces )) ||
( _shriFace[1]->IsSame( face ) && _shriFace[0]->IsShrunk( shrunkFaces )));
}
if ( iSrc != 0 )
{
trsfInverse = _trsf;
- trsfInverse.Invert();
+ if ( !trsfInverse.Invert())
+ return false;
trsf = &trsfInverse;
}
SMESHDS_Mesh* meshDS = dataSrc->GetHelper().GetMeshDS();
}
}
bool done = ( n2n == _nnMap.end() );
- // cout << "MMMMMMMOOOOOOOOOOVVVVVVVVVVVEEEEEEEE "
- // << _shriFace[iSrc]->_subMesh->GetId() << " -> "
- // << _shriFace[iTgt]->_subMesh->GetId() << " -- "
- // << ( done ? "DONE" : "FAIL") << endl;
+ debugMsg( "PeriodicFaces::MoveNodes "
+ << _shriFace[iSrc]->_subMesh->GetId() << " -> "
+ << _shriFace[iTgt]->_subMesh->GetId() << " -- "
+ << ( done ? "DONE" : "FAIL"));
return done;
}
getMeshDS()->RemoveFreeNode( n, smDS, /*fromGroups=*/false );
}
}
+ _periodicity->ClearPeriodic( F );
+
// restore position and UV of target nodes
gp_Pnt p;
for ( size_t iS = 0; iS < subEOS.size(); ++iS )
if ( !n2 )
return error(SMESH_Comment("Wrongly meshed EDGE ") << getMeshDS()->ShapeToIndex( E ));
+ if ( n2 == tgtNode ) // for 3D_mesh_GHS3D_01/B1
+ {
+ // shrunk by other SOLID
+ edge.Set( _LayerEdge::SHRUNK ); // ???
+ return true;
+ }
+
double uSrc = helper.GetNodeU( E, srcNode, n2 );
double uTgt = helper.GetNodeU( E, tgtNode, srcNode );
double u2 = helper.GetNodeU( E, n2, srcNode );