+ // Add to _noShrinkShapes sub-shapes of FACE's that can't be shrinked since
+ // the algo of the SOLID sharing the FACE does not support it or for other reasons
+ set< string > notSupportAlgos; notSupportAlgos.insert( structAlgoName );
+ for ( size_t i = 0; i < _sdVec.size(); ++i )
+ {
+ map< TGeomID, TopoDS_Shape >::iterator e2f = _sdVec[i]._shrinkShape2Shape.begin();
+ for ( ; e2f != _sdVec[i]._shrinkShape2Shape.end(); ++e2f )
+ {
+ const TopoDS_Shape& fWOL = e2f->second;
+ const TGeomID edgeID = e2f->first;
+ TGeomID faceID = getMeshDS()->ShapeToIndex( fWOL );
+ TopoDS_Shape edge = getMeshDS()->IndexToShape( edgeID );
+ if ( edge.ShapeType() != TopAbs_EDGE )
+ continue; // shrink shape is VERTEX
+
+ TopoDS_Shape solid;
+ PShapeIteratorPtr soIt = helper.GetAncestors(fWOL, *_mesh, TopAbs_SOLID);
+ while ( soIt->more() && solid.IsNull() )
+ {
+ const TopoDS_Shape* so = soIt->next();
+ if ( !so->IsSame( _sdVec[i]._solid ))
+ solid = *so;
+ }
+ if ( solid.IsNull() )
+ continue;
+
+ bool noShrinkE = false;
+ SMESH_Algo* algo = _mesh->GetSubMesh( solid )->GetAlgo();
+ bool isStructured = ( algo && algo->GetName() == structAlgoName );
+ size_t iSolid = _solids.FindIndex( solid ) - 1;
+ if ( iSolid < _sdVec.size() && _sdVec[ iSolid ]._ignoreFaceIds.count( faceID ))
+ {
+ // the adjacent SOLID has NO layers on fWOL;
+ // shrink allowed if
+ // - there are layers on the EDGE in the adjacent SOLID
+ // - there are NO layers in the adjacent SOLID && algo is unstructured and computed later
+ bool hasWLAdj = (_sdVec[iSolid]._shrinkShape2Shape.count( edgeID ));
+ bool shrinkAllowed = (( hasWLAdj ) ||
+ ( !isStructured && setBefore( _sdVec[ i ], _sdVec[ iSolid ] )));
+ noShrinkE = !shrinkAllowed;
+ }
+ else if ( iSolid < _sdVec.size() )
+ {
+ // the adjacent SOLID has layers on fWOL;
+ // check if SOLID's mesh is unstructured and then try to set it
+ // to be computed after the i-th solid
+ if ( isStructured || !setBefore( _sdVec[ i ], _sdVec[ iSolid ] ))
+ noShrinkE = true; // don't shrink fWOL
+ }
+ else
+ {
+ // the adjacent SOLID has NO layers at all
+ noShrinkE = isStructured;
+ }
+
+ if ( noShrinkE )
+ {
+ _sdVec[i]._noShrinkShapes.insert( edgeID );
+
+ // check if there is a collision with to-shrink-from EDGEs in iSolid
+ // if ( iSolid < _sdVec.size() )
+ // {
+ // shapes.Clear();
+ // TopExp::MapShapes( fWOL, TopAbs_EDGE, shapes);
+ // for ( int iE = 1; iE <= shapes.Extent(); ++iE )
+ // {
+ // const TopoDS_Edge& E = TopoDS::Edge( shapes( iE ));
+ // const TGeomID eID = getMeshDS()->ShapeToIndex( E );
+ // if ( eID == edgeID ||
+ // !_sdVec[iSolid]._shrinkShape2Shape.count( eID ) ||
+ // _sdVec[i]._noShrinkShapes.count( eID ))
+ // continue;
+ // for ( int is1st = 0; is1st < 2; ++is1st )
+ // {
+ // TopoDS_Vertex V = helper.IthVertex( is1st, E );
+ // if ( _sdVec[i]._noShrinkShapes.count( getMeshDS()->ShapeToIndex( V ) ))
+ // {
+ // return error("No way to make a conformal mesh with "
+ // "the given set of faces with layers", _sdVec[i]._index);
+ // }
+ // }
+ // }
+ // }
+ }
+
+ // add VERTEXes of the edge in _noShrinkShapes, which is necessary if
+ // _shrinkShape2Shape is different in the adjacent SOLID
+ for ( TopoDS_Iterator vIt( edge ); vIt.More(); vIt.Next() )
+ {
+ TGeomID vID = getMeshDS()->ShapeToIndex( vIt.Value() );
+ bool noShrinkV = false, noShrinkIfAdjMeshed = false;
+
+ if ( iSolid < _sdVec.size() )
+ {
+ if ( _sdVec[ iSolid ]._ignoreFaceIds.count( faceID ))
+ {
+ map< TGeomID, TopoDS_Shape >::iterator i2S, i2SAdj;
+ i2S = _sdVec[i ]._shrinkShape2Shape.find( vID );
+ i2SAdj = _sdVec[iSolid]._shrinkShape2Shape.find( vID );
+ if ( i2SAdj == _sdVec[iSolid]._shrinkShape2Shape.end() )
+ noShrinkV = (( isStructured ) ||
+ ( noShrinkIfAdjMeshed = i2S->second.ShapeType() == TopAbs_EDGE ));
+ else
+ noShrinkV = ( ! i2S->second.IsSame( i2SAdj->second ));
+ }
+ else
+ {
+ noShrinkV = noShrinkE;
+ }
+ }
+ else
+ {
+ // the adjacent SOLID has NO layers at all
+ if ( isStructured )
+ {
+ noShrinkV = true;
+ }
+ else
+ {
+ noShrinkV = noShrinkIfAdjMeshed =
+ ( _sdVec[i]._shrinkShape2Shape[ vID ].ShapeType() == TopAbs_EDGE );
+ }
+ }
+
+ if ( noShrinkV && noShrinkIfAdjMeshed )
+ {
+ // noShrinkV if FACEs in the adjacent SOLID are meshed
+ PShapeIteratorPtr fIt = helper.GetAncestors( _sdVec[i]._shrinkShape2Shape[ vID ],
+ *_mesh, TopAbs_FACE, &solid );
+ while ( fIt->more() )
+ {
+ const TopoDS_Shape* f = fIt->next();
+ if ( !f->IsSame( fWOL ))
+ {
+ noShrinkV = ! _mesh->GetSubMesh( *f )->IsEmpty();
+ break;
+ }
+ }
+ }
+ if ( noShrinkV )
+ _sdVec[i]._noShrinkShapes.insert( vID );
+ }
+
+ } // loop on _sdVec[i]._shrinkShape2Shape
+ } // loop on _sdVec to fill in _SolidData::_noShrinkShapes
+
+
+ // add FACEs of other SOLIDs to _ignoreFaceIds