// cout << msg << " ("<< p.X() << "; " <<p.Y() << "; " <<p.Z() << ") " <<endl;\
// }
-typedef StdMeshers_ProjectionUtils TAssocTool;
-typedef SMESH_Comment TCom;
+namespace TAssocTool = StdMeshers_ProjectionUtils;
+
+typedef SMESH_Comment TCom;
enum { ID_BOT_FACE = SMESH_Block::ID_Fxy0,
ID_TOP_FACE = SMESH_Block::ID_Fxy1,
: StdMeshers_Quadrangle_2D( gen->GetANewId(), studyId, gen)
{
}
- static StdMeshers_Quadrangle_2D* instance( SMESH_Algo* fatherAlgo,
- SMESH_Mesh* mesh=0)
+ static StdMeshers_Quadrangle_2D* instance( SMESH_Algo* fatherAlgo,
+ SMESH_MesherHelper* helper=0)
{
static TQuadrangleAlgo* algo = new TQuadrangleAlgo( fatherAlgo->GetStudyId(),
fatherAlgo->GetGen() );
- if ( mesh &&
+ if ( helper &&
algo->myProxyMesh &&
- algo->myProxyMesh->GetMesh() != mesh )
- algo->myProxyMesh.reset( new SMESH_ProxyMesh( *mesh ));
+ algo->myProxyMesh->GetMesh() != helper->GetMesh() )
+ algo->myProxyMesh.reset( new SMESH_ProxyMesh( *helper->GetMesh() ));
algo->myQuadStruct.reset();
+ if ( helper )
+ algo->_quadraticMesh = helper->GetIsQuadratic();
+
return algo;
}
};
if ( nbSolids < 1 )
return true;
- Prism_3D::TPrismTopo prism;
-
- if ( nbSolids == 1 )
- {
- return ( initPrism( prism, TopExp_Explorer( theShape, TopAbs_SOLID ).Current() ) &&
- compute( prism ));
- }
-
TopTools_IndexedDataMapOfShapeListOfShape faceToSolids;
TopExp::MapShapesAndAncestors( theShape, TopAbs_FACE, TopAbs_SOLID, faceToSolids );
// look for meshed FACEs ("source" FACEs) that must be prism bottoms
- list< TopoDS_Face > meshedFaces;//, notQuadMeshedFaces, notQuadFaces;
+ list< TopoDS_Face > meshedFaces, notQuadMeshedFaces, notQuadFaces;
const bool meshHasQuads = ( theMesh.NbQuadrangles() > 0 );
for ( int iF = 1; iF < faceToSolids.Extent(); ++iF )
{
{
if ( !meshHasQuads ||
!helper.IsSameElemGeometry( faceSM->GetSubMeshDS(), SMDSGeom_QUADRANGLE ) ||
- !helper.IsStructured( faceSM ))
- // notQuadMeshedFaces are of higher priority
+ !helper.IsStructured( faceSM )
+ )
+ notQuadMeshedFaces.push_front( face );
+ else if ( myHelper->Count( face, TopAbs_EDGE, /*ignoreSame=*/false ) != 4 )
meshedFaces.push_front( face );
else
meshedFaces.push_back( face );
}
+ else if ( myHelper->Count( face, TopAbs_EDGE, /*ignoreSame=*/false ) != 4 )
+ {
+ notQuadFaces.push_back( face );
+ }
}
- //meshedFaces.splice( meshedFaces.begin(), notQuadMeshedFaces );
+ // notQuadFaces are of medium priority, put them before ordinary meshed faces
+ meshedFaces.splice( meshedFaces.begin(), notQuadFaces );
+ // notQuadMeshedFaces are of highest priority, put them before notQuadFaces
+ meshedFaces.splice( meshedFaces.begin(), notQuadMeshedFaces );
- if ( meshedFaces.empty() )
- return error( COMPERR_BAD_INPUT_MESH, "No meshed source faces found" );
+ Prism_3D::TPrismTopo prism;
+
+ if ( nbSolids == 1 )
+ {
+ if ( !meshedFaces.empty() )
+ prism.myBottom = meshedFaces.front();
+ return ( initPrism( prism, TopExp_Explorer( theShape, TopAbs_SOLID ).Current() ) &&
+ compute( prism ));
+ }
TopTools_MapOfShape meshedSolids;
list< Prism_3D::TPrismTopo > meshedPrism;
{
TopoDS_Face face = meshedFaces.front();
meshedFaces.pop_front();
- solidIt.Initialize( faceToSolids.FindFromKey( face ));
- for ( ; solidIt.More(); solidIt.Next() )
+ TopTools_ListOfShape& solidList = faceToSolids.ChangeFromKey( face );
+ while ( !solidList.IsEmpty() )
{
- const TopoDS_Shape& solid = solidIt.Value();
- if ( !meshedSolids.Add( solid ))
- continue; // already computed prism
-
- prism.Clear();
- prism.myBottom = face;
- if ( !initPrism( prism, solid ) ||
- !compute( prism ))
- return false;
+ TopoDS_Shape solid = solidList.First();
+ solidList.RemoveFirst();
+ if ( meshedSolids.Add( solid ))
+ {
+ prism.Clear();
+ prism.myBottom = face;
+ if ( !initPrism( prism, solid ) ||
+ !compute( prism ))
+ return false;
- meshedFaces.push_front( prism.myTop );
- meshedPrism.push_back( prism );
+ meshedFaces.push_front( prism.myTop );
+ meshedPrism.push_back( prism );
+ }
}
}
if ( meshedSolids.Extent() == nbSolids )
break;
+ // below in the loop we try to find source FACEs somehow
+
// project mesh from source FACEs of computed prisms to
// prisms sharing wall FACEs
list< Prism_3D::TPrismTopo >::iterator prismIt = meshedPrism.begin();
for ( ; wQuad != prismIt->myWallQuads[iW].end(); ++ wQuad )
{
const TopoDS_Face& wFace = (*wQuad)->face;
- solidIt.Initialize( faceToSolids.FindFromKey( wFace ));
- for ( ; solidIt.More(); solidIt.Next() )
+ TopTools_ListOfShape& solidList = faceToSolids.ChangeFromKey( wFace );
+ solidIt.Initialize( solidList );
+ while ( solidIt.More() )
{
const TopoDS_Shape& solid = solidIt.Value();
- if ( meshedSolids.Contains( solid ))
+ if ( meshedSolids.Contains( solid )) {
+ solidList.Remove( solidIt );
continue; // already computed prism
-
+ }
// find a source FACE of the SOLID: it's a FACE sharing a bottom EDGE with wFace
const TopoDS_Edge& wEdge = (*wQuad)->side[ QUAD_TOP_SIDE ]->Edge(0);
PShapeIteratorPtr faceIt = myHelper->GetAncestors( wEdge, *myHelper->GetMesh(),
}
mySetErrorToSM = true;
InitComputeError();
+ if ( meshedSolids.Contains( solid ))
+ solidList.Remove( solidIt );
+ else
+ solidIt.Next();
}
}
}
break; // to compute prisms with avident sources
}
+ // find FACEs with local 1D hyps, which has to be computed by now,
+ // or at least any computed FACEs
+ for ( int iF = 1; ( meshedFaces.empty() && iF < faceToSolids.Extent() ); ++iF )
+ {
+ const TopoDS_Face& face = TopoDS::Face( faceToSolids.FindKey( iF ));
+ const TopTools_ListOfShape& solidList = faceToSolids.FindFromKey( face );
+ if ( solidList.IsEmpty() ) continue;
+ SMESH_subMesh* faceSM = theMesh.GetSubMesh( face );
+ if ( !faceSM->IsEmpty() )
+ {
+ meshedFaces.push_back( face ); // lower priority
+ }
+ else
+ {
+ bool allSubMeComputed = true;
+ SMESH_subMeshIteratorPtr smIt = faceSM->getDependsOnIterator(false,true);
+ while ( smIt->more() && allSubMeComputed )
+ allSubMeComputed = smIt->next()->IsMeshComputed();
+ if ( allSubMeComputed )
+ {
+ faceSM->ComputeStateEngine( SMESH_subMesh::COMPUTE );
+ if ( !faceSM->IsEmpty() )
+ meshedFaces.push_front( face ); // higher priority
+ else
+ faceSM->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+ }
+ }
+ }
+
+
// TODO. there are other ways to find out the source FACE:
// propagation, topological similarity, ect.
+ // simply try to mesh all not meshed SOLIDs
+ if ( meshedFaces.empty() )
+ {
+ for ( TopExp_Explorer solid( theShape, TopAbs_SOLID ); solid.More(); solid.Next() )
+ {
+ mySetErrorToSM = false;
+ prism.Clear();
+ if ( !meshedSolids.Contains( solid.Current() ) &&
+ initPrism( prism, solid.Current() ))
+ {
+ mySetErrorToSM = true;
+ if ( !compute( prism ))
+ return false;
+ meshedFaces.push_front( prism.myTop );
+ meshedFaces.push_front( prism.myBottom );
+ meshedPrism.push_back( prism );
+ meshedSolids.Add( solid.Current() );
+ }
+ mySetErrorToSM = true;
+ }
+ }
if ( meshedFaces.empty() ) // set same error to 10 not-computed solids
{
SMESH_subMesh* sm = theMesh.GetSubMesh( solid.Current() );
sm->GetComputeError() = err;
}
- return false;
+ return error( err );
}
}
return true;
SMESH_Mesh* mesh = myHelper->GetMesh();
- StdMeshers_Quadrangle_2D* quadAlgo = TQuadrangleAlgo::instance( this, mesh );
+ StdMeshers_Quadrangle_2D* quadAlgo = TQuadrangleAlgo::instance( this, myHelper );
TopTools_MapOfShape faceMap;
TopTools_IndexedDataMapOfShapeListOfShape edgeToFaces;
// -------------------------
// Compose a vector of indixes of right neighbour FACE for each wall FACE
- // that is not so evident in case of several WIREs
+ // that is not so evident in case of several WIREs in the bottom FACE
thePrism.myRightQuadIndex.clear();
for ( size_t i = 0; i < thePrism.myWallQuads.size(); ++i )
thePrism.myRightQuadIndex.push_back( i+1 );
// try to use transformation (issue 0020680)
vector<gp_Trsf> trsf;
- if ( myBlock.GetLayersTransformation(trsf))
+ if ( myBlock.GetLayersTransformation( trsf, thePrism ))
{
// loop on nodes inside the bottom face
TNode2ColumnMap::iterator bot_column = myBotToColumnMap.begin();
SMESHDS_Mesh* meshDS = myHelper->GetMeshDS();
TProjction1dAlgo* projector1D = TProjction1dAlgo::instance( this );
- StdMeshers_Quadrangle_2D* quadAlgo = TQuadrangleAlgo::instance( this, mesh );
+ StdMeshers_Quadrangle_2D* quadAlgo = TQuadrangleAlgo::instance( this, myHelper );
SMESH_HypoFilter hyp1dFilter( SMESH_HypoFilter::IsAlgo(),/*not=*/true);
hyp1dFilter.And( SMESH_HypoFilter::HasDim( 1 ));
}
}
wgt2quad.insert( make_pair( wgt, iW ));
+
+ // in quadratic mesh, pass ignoreMediumNodes to quad sides
+ if ( myHelper->GetIsQuadratic() )
+ {
+ quad = thePrism.myWallQuads[iW].begin();
+ for ( ; quad != thePrism.myWallQuads[iW].end(); ++quad )
+ for ( int i = 0; i < NB_QUAD_SIDES; ++i )
+ (*quad)->side[ i ]->SetIgnoreMediumNodes( true );
+ }
}
// Project 'vertical' EDGEs, from left to right
// -------------------------------
const TopoDS_Face& face = (*quad)->face;
SMESH_subMesh* fSM = mesh->GetSubMesh( face );
- if ( fSM->IsMeshComputed() ) continue;
-
- // make all EDGES meshed
- fSM->ComputeSubMeshStateEngine( SMESH_subMesh::COMPUTE );
- if ( !fSM->SubMeshesComputed() )
- return toSM( error( COMPERR_BAD_INPUT_MESH,
- "Not all edges have valid algorithm and hypothesis"));
- // mesh the <face>
- quadAlgo->InitComputeError();
- bool ok = quadAlgo->Compute( *mesh, face );
- fSM->GetComputeError() = quadAlgo->GetComputeError();
- if ( !ok )
- return false;
- fSM->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+ if ( ! fSM->IsMeshComputed() )
+ {
+ // make all EDGES meshed
+ fSM->ComputeSubMeshStateEngine( SMESH_subMesh::COMPUTE );
+ if ( !fSM->SubMeshesComputed() )
+ return toSM( error( COMPERR_BAD_INPUT_MESH,
+ "Not all edges have valid algorithm and hypothesis"));
+ // mesh the <face>
+ quadAlgo->InitComputeError();
+ bool ok = quadAlgo->Compute( *mesh, face );
+ fSM->GetComputeError() = quadAlgo->GetComputeError();
+ if ( !ok )
+ return false;
+ fSM->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+ }
+ if ( myHelper->GetIsQuadratic() )
+ {
+ // fill myHelper with medium nodes built by quadAlgo
+ SMDS_ElemIteratorPtr fIt = fSM->GetSubMeshDS()->GetElements();
+ while ( fIt->more() )
+ myHelper->AddTLinks( dynamic_cast<const SMDS_MeshFace*>( fIt->next() ));
+ }
}
}
SMESHDS_SubMesh * topSMDS = topSM->GetSubMeshDS();
if ( !botSMDS || botSMDS->NbElements() == 0 )
- return toSM( error(TCom("No elememts on face #") << botSM->GetId() ));
+ {
+ _gen->Compute( *myHelper->GetMesh(), botSM->GetSubShape() );
+ botSMDS = botSM->GetSubMeshDS();
+ if ( !botSMDS || botSMDS->NbElements() == 0 )
+ return toSM( error(TCom("No elememts on face #") << botSM->GetId() ));
+ }
bool needProject = !topSM->IsMeshComputed();
if ( !needProject &&
// if the bottom faces is orienetd OK then top faces must be reversed
bool reverseTop = true;
if ( myHelper->NbAncestors( botFace, *myBlock.Mesh(), TopAbs_SOLID ) > 1 )
- reverseTop = ! SMESH_Algo::IsReversedSubMesh( TopoDS::Face( botFace ), meshDS );
+ reverseTop = ! myHelper->IsReversedSubMesh( TopoDS::Face( botFace ));
int iFrw, iRev, *iPtr = &( reverseTop ? iRev : iFrw );
// loop on bottom mesh faces
// Issue 0020843 - one of side FACEs is quasi-quadrilateral (not 4 EDGEs).
// Remove from notQuadGeomSubMesh faces meshed with regular grid
int nbQuasiQuads = removeQuasiQuads( notQuadGeomSubMesh, myHelper,
- TQuadrangleAlgo::instance(this,myHelper->GetMesh()) );
+ TQuadrangleAlgo::instance(this,myHelper) );
nbNotQuad -= nbQuasiQuads;
if ( nbNotQuad > 2 )
return toSM( error(COMPERR_BAD_SHAPE,
// from bottom to top.
//=======================================================================
-bool StdMeshers_PrismAsBlock::GetLayersTransformation(vector<gp_Trsf> & trsf) const
+bool StdMeshers_PrismAsBlock::GetLayersTransformation(vector<gp_Trsf> & trsf,
+ const Prism_3D::TPrismTopo& prism) const
{
const int zSize = VerticalSize();
if ( zSize < 3 ) return true;
vector< const TNodeColumn* > columns;
{
- const TopoDS_Shape& baseFace = Shape(ID_BOT_FACE);
- list< TopoDS_Edge > orderedEdges;
- list< int > nbEdgesInWires;
- GetOrderedEdges( TopoDS::Face( baseFace ), orderedEdges, nbEdgesInWires );
bool isReverse;
- list< TopoDS_Edge >::iterator edgeIt = orderedEdges.begin();
- for ( int iE = 0; iE < nbEdgesInWires.front(); ++iE, ++edgeIt )
+ list< TopoDS_Edge >::const_iterator edgeIt = prism.myBottomEdges.begin();
+ for ( int iE = 0; iE < prism.myNbEdgesInWires.front(); ++iE, ++edgeIt )
{
if ( BRep_Tool::Degenerated( *edgeIt )) continue;
const TParam2ColumnMap* u2colMap =