+ * Evaluate
+ */
+//=============================================================================
+
+bool StdMeshers_Hexa_3D::Evaluate(SMESH_Mesh & aMesh,
+ const TopoDS_Shape & aShape,
+ MapShapeNbElems& aResMap)
+{
+ vector < SMESH_subMesh * >meshFaces;
+ TopTools_SequenceOfShape aFaces;
+ for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next()) {
+ aFaces.Append(exp.Current());
+ SMESH_subMesh *aSubMesh = aMesh.GetSubMeshContaining(exp.Current());
+ ASSERT(aSubMesh);
+ meshFaces.push_back(aSubMesh);
+ }
+ if (meshFaces.size() != 6) {
+ //return error(COMPERR_BAD_SHAPE, TComm(meshFaces.size())<<" instead of 6 faces in a block");
+ static StdMeshers_CompositeHexa_3D compositeHexa(-10, 0, aMesh.GetGen());
+ return compositeHexa.Evaluate(aMesh, aShape, aResMap);
+ }
+
+ int i = 0;
+ for(; i<6; i++) {
+ //TopoDS_Shape aFace = meshFaces[i]->GetSubShape();
+ TopoDS_Shape aFace = aFaces.Value(i+1);
+ SMESH_Algo *algo = _gen->GetAlgo(aMesh, aFace);
+ if( !algo ) {
+ std::vector<int> aResVec(SMDSEntity_Last);
+ for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0;
+ SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+ aResMap.insert(std::make_pair(sm,aResVec));
+ SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
+ smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
+ return false;
+ }
+ string algoName = algo->GetName();
+ bool isAllQuad = false;
+ if (algoName == "Quadrangle_2D") {
+ MapShapeNbElemsItr anIt = aResMap.find(meshFaces[i]);
+ if( anIt == aResMap.end() ) continue;
+ std::vector<int> aVec = (*anIt).second;
+ int nbtri = Max(aVec[SMDSEntity_Triangle],aVec[SMDSEntity_Quad_Triangle]);
+ if( nbtri == 0 )
+ isAllQuad = true;
+ }
+ if ( ! isAllQuad ) {
+ return EvaluatePentahedralMesh(aMesh, aShape, aResMap);
+ }
+ }
+
+ // find number of 1d elems for 1 face
+ int nb1d = 0;
+ TopTools_MapOfShape Edges1;
+ bool IsQuadratic = false;
+ bool IsFirst = true;
+ for (TopExp_Explorer exp(aFaces.Value(1), TopAbs_EDGE); exp.More(); exp.Next()) {
+ Edges1.Add(exp.Current());
+ SMESH_subMesh *sm = aMesh.GetSubMesh(exp.Current());
+ if( sm ) {
+ MapShapeNbElemsItr anIt = aResMap.find(sm);
+ if( anIt == aResMap.end() ) continue;
+ std::vector<int> aVec = (*anIt).second;
+ nb1d += Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]);
+ if(IsFirst) {
+ IsQuadratic = (aVec[SMDSEntity_Quad_Edge] > aVec[SMDSEntity_Edge]);
+ IsFirst = false;
+ }
+ }
+ }
+ // find face opposite to 1 face
+ int OppNum = 0;
+ for(i=2; i<=6; i++) {
+ bool IsOpposite = true;
+ for(TopExp_Explorer exp(aFaces.Value(i), TopAbs_EDGE); exp.More(); exp.Next()) {
+ if( Edges1.Contains(exp.Current()) ) {
+ IsOpposite = false;
+ break;
+ }
+ }
+ if(IsOpposite) {
+ OppNum = i;
+ break;
+ }
+ }
+ // find number of 2d elems on side faces
+ int nb2d = 0;
+ for(i=2; i<=6; i++) {
+ if( i == OppNum ) continue;
+ MapShapeNbElemsItr anIt = aResMap.find( meshFaces[i-1] );
+ if( anIt == aResMap.end() ) continue;
+ std::vector<int> aVec = (*anIt).second;
+ nb2d += Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]);
+ }
+
+ MapShapeNbElemsItr anIt = aResMap.find( meshFaces[0] );
+ std::vector<int> aVec = (*anIt).second;
+ int nb2d_face0 = Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]);
+ int nb0d_face0 = aVec[SMDSEntity_Node];
+
+ std::vector<int> aResVec(SMDSEntity_Last);
+ for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0;
+ if(IsQuadratic) {
+ aResVec[SMDSEntity_Quad_Hexa] = nb2d_face0 * ( nb2d/nb1d );
+ int nb1d_face0_int = ( nb2d_face0*4 - nb1d ) / 2;
+ aResVec[SMDSEntity_Node] = nb0d_face0 * ( 2*nb2d/nb1d - 1 ) - nb1d_face0_int * nb2d/nb1d;
+ }
+ else {
+ aResVec[SMDSEntity_Node] = nb0d_face0 * ( nb2d/nb1d - 1 );
+ aResVec[SMDSEntity_Hexa] = nb2d_face0 * ( nb2d/nb1d );
+ }
+ SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+ aResMap.insert(std::make_pair(sm,aResVec));
+
+ return true;
+}
+
+//================================================================================
+/*!
+ * \brief Computes hexahedral mesh from 2D mesh of block
+ */
+//================================================================================
+
+bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, SMESH_MesherHelper* aHelper)
+{
+ static StdMeshers_HexaFromSkin_3D * algo = 0;
+ if ( !algo ) {
+ SMESH_Gen* gen = aMesh.GetGen();
+ algo = new StdMeshers_HexaFromSkin_3D( gen->GetANewId(), 0, gen );
+ }
+ algo->InitComputeError();
+ algo->Compute( aMesh, aHelper );
+ return error( algo->GetComputeError());
+}
+
+//=============================================================================
+/*!
+ *