bool NETGENPlugin_NETGEN_3D::Evaluate(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, MapShapeNbElems& aResMap) { int nbtri = 0, nbqua = 0; double fullArea = 0.0; for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next()) { TopoDS_Face F = TopoDS::Face( exp.Current() ); SMESH_subMesh *sm = aMesh.GetSubMesh(F); MapShapeNbElemsItr anIt = aResMap.find(sm); if( anIt==aResMap.end() ) { SMESH_ComputeErrorPtr& smError = sm->GetComputeError(); smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this)); return false; } std::vector<int> aVec = (*anIt).second; nbtri += Max(aVec[SMDSEntity_Triangle],aVec[SMDSEntity_Quad_Triangle]); nbqua += Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]); GProp_GProps G; BRepGProp::SurfaceProperties(F,G); double anArea = G.Mass(); fullArea += anArea; } // collect info from edges int nb0d_e = 0, nb1d_e = 0; bool IsQuadratic = false; bool IsFirst = true; TopTools_MapOfShape tmpMap; for (TopExp_Explorer exp(aShape, TopAbs_EDGE); exp.More(); exp.Next()) { TopoDS_Edge E = TopoDS::Edge(exp.Current()); if( tmpMap.Contains(E) ) continue; tmpMap.Add(E); SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current()); MapShapeNbElemsItr anIt = aResMap.find(aSubMesh); if( anIt==aResMap.end() ) { SMESH_ComputeErrorPtr& smError = aSubMesh->GetComputeError(); smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED, "Submesh can not be evaluated",this)); return false; } std::vector<int> aVec = (*anIt).second; nb0d_e += aVec[SMDSEntity_Node]; nb1d_e += Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]); if(IsFirst) { IsQuadratic = (aVec[SMDSEntity_Quad_Edge] > aVec[SMDSEntity_Edge]); IsFirst = false; } } tmpMap.Clear(); double ELen_face = sqrt(2.* ( fullArea/(nbtri+nbqua*2) ) / sqrt(3.0) ); double ELen_vol = pow( 72, 1/6. ) * pow( _maxElementVolume, 1/3. ); double ELen = Min(ELen_vol,ELen_face*2); GProp_GProps G; BRepGProp::VolumeProperties(aShape,G); double aVolume = G.Mass(); double tetrVol = 0.1179*ELen*ELen*ELen; double CoeffQuality = 0.9; int nbVols = (int)aVolume/tetrVol/CoeffQuality; int nb1d_f = (nbtri*3 + nbqua*4 - nb1d_e) / 2; int nb1d_in = (int) ( nbVols*6 - nb1d_e - nb1d_f ) / 5; std::vector<int> aVec(SMDSEntity_Last); for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aVec[i]=0; if( IsQuadratic ) { aVec[SMDSEntity_Node] = nb1d_in/6 + 1 + nb1d_in; aVec[SMDSEntity_Quad_Tetra] = nbVols - nbqua*2; aVec[SMDSEntity_Quad_Pyramid] = nbqua; } else { aVec[SMDSEntity_Node] = nb1d_in/6 + 1; aVec[SMDSEntity_Tetra] = nbVols - nbqua*2; aVec[SMDSEntity_Pyramid] = nbqua; } SMESH_subMesh *sm = aMesh.GetSubMesh(aShape); aResMap.insert(std::make_pair(sm,aVec)); return true; }
bool StdMeshers_RadialPrism_3D::Evaluate(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, MapShapeNbElems& aResMap) { // get 2 shells TopoDS_Solid solid = TopoDS::Solid( aShape ); TopoDS_Shell outerShell = BRepClass3d::OuterShell( solid ); TopoDS_Shape innerShell; int nbShells = 0; for ( TopoDS_Iterator It (solid); It.More(); It.Next(), ++nbShells ) if ( !outerShell.IsSame( It.Value() )) innerShell = It.Value(); if ( nbShells != 2 ) { 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; } // Associate sub-shapes of the shells ProjectionUtils::TShapeShapeMap shape2ShapeMap; if ( !ProjectionUtils::FindSubShapeAssociation( outerShell, &aMesh, innerShell, &aMesh, shape2ShapeMap) ) { 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; } // get info for outer shell int nb0d_Out=0, nb2d_3_Out=0, nb2d_4_Out=0; //TopTools_SequenceOfShape FacesOut; for (TopExp_Explorer exp(outerShell, TopAbs_FACE); exp.More(); exp.Next()) { //FacesOut.Append(exp.Current()); SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current()); MapShapeNbElemsItr anIt = aResMap.find(aSubMesh); std::vector<int> aVec = (*anIt).second; nb0d_Out += aVec[SMDSEntity_Node]; nb2d_3_Out += Max(aVec[SMDSEntity_Triangle],aVec[SMDSEntity_Quad_Triangle]); nb2d_4_Out += Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]); } int nb1d_Out = 0; TopTools_MapOfShape tmpMap; for (TopExp_Explorer exp(outerShell, TopAbs_EDGE); exp.More(); exp.Next()) { if( tmpMap.Contains( exp.Current() ) ) continue; tmpMap.Add( exp.Current() ); SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current()); MapShapeNbElemsItr anIt = aResMap.find(aSubMesh); std::vector<int> aVec = (*anIt).second; nb0d_Out += aVec[SMDSEntity_Node]; nb1d_Out += Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]); } tmpMap.Clear(); for (TopExp_Explorer exp(outerShell, TopAbs_VERTEX); exp.More(); exp.Next()) { if( tmpMap.Contains( exp.Current() ) ) continue; tmpMap.Add( exp.Current() ); nb0d_Out++; } // get info for inner shell int nb0d_In=0, nb2d_3_In=0, nb2d_4_In=0; //TopTools_SequenceOfShape FacesIn; for (TopExp_Explorer exp(innerShell, TopAbs_FACE); exp.More(); exp.Next()) { //FacesIn.Append(exp.Current()); SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current()); MapShapeNbElemsItr anIt = aResMap.find(aSubMesh); std::vector<int> aVec = (*anIt).second; nb0d_In += aVec[SMDSEntity_Node]; nb2d_3_In += Max(aVec[SMDSEntity_Triangle],aVec[SMDSEntity_Quad_Triangle]); nb2d_4_In += Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]); } int nb1d_In = 0; tmpMap.Clear(); bool IsQuadratic = false; bool IsFirst = true; for (TopExp_Explorer exp(innerShell, TopAbs_EDGE); exp.More(); exp.Next()) { if( tmpMap.Contains( exp.Current() ) ) continue; tmpMap.Add( exp.Current() ); SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current()); MapShapeNbElemsItr anIt = aResMap.find(aSubMesh); std::vector<int> aVec = (*anIt).second; nb0d_In += aVec[SMDSEntity_Node]; nb1d_In += Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]); if(IsFirst) { IsQuadratic = (aVec[SMDSEntity_Quad_Edge] > aVec[SMDSEntity_Edge]); IsFirst = false; } } tmpMap.Clear(); for (TopExp_Explorer exp(innerShell, TopAbs_VERTEX); exp.More(); exp.Next()) { if( tmpMap.Contains( exp.Current() ) ) continue; tmpMap.Add( exp.Current() ); nb0d_In++; } bool IsOK = (nb0d_Out==nb0d_In) && (nb1d_Out==nb1d_In) && (nb2d_3_Out==nb2d_3_In) && (nb2d_4_Out==nb2d_4_In); if(!IsOK) { 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; } int nbLayers = 0; if( myNbLayerHypo ) { nbLayers = myNbLayerHypo->GetNumberOfLayers(); } if ( myDistributionHypo ) { if ( !myDistributionHypo->GetLayerDistribution() ) { 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; } TopExp_Explorer exp(outerShell, TopAbs_VERTEX); TopoDS_Vertex Vout = TopoDS::Vertex(exp.Current()); TopoDS_Vertex Vin = TopoDS::Vertex( shape2ShapeMap(Vout) ); if ( myLayerPositions.empty() ) { gp_Pnt pIn = BRep_Tool::Pnt(Vin); gp_Pnt pOut = BRep_Tool::Pnt(Vout); computeLayerPositions( pIn, pOut ); } nbLayers = myLayerPositions.size() + 1; } std::vector<int> aResVec(SMDSEntity_Last); for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0; if(IsQuadratic) { aResVec[SMDSEntity_Quad_Penta] = nb2d_3_Out * nbLayers; aResVec[SMDSEntity_Quad_Hexa] = nb2d_4_Out * nbLayers; int nb1d = ( nb2d_3_Out*3 + nb2d_4_Out*4 ) / 2; aResVec[SMDSEntity_Node] = nb0d_Out * ( 2*nbLayers - 1 ) - nb1d * nbLayers; } else { aResVec[SMDSEntity_Node] = nb0d_Out * ( nbLayers - 1 ); aResVec[SMDSEntity_Penta] = nb2d_3_Out * nbLayers; aResVec[SMDSEntity_Hexa] = nb2d_4_Out * nbLayers; } SMESH_subMesh * sm = aMesh.GetSubMesh(aShape); aResMap.insert(std::make_pair(sm,aResVec)); return true; }
bool NETGENPlugin_NETGEN_2D_ONLY::Evaluate(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, MapShapeNbElems& aResMap) { TopoDS_Face F = TopoDS::Face(aShape); if(F.IsNull()) return false; // collect info from edges int nb0d = 0, nb1d = 0; bool IsQuadratic = false; bool IsFirst = true; double fullLen = 0.0; TopTools_MapOfShape tmpMap; for (TopExp_Explorer exp(F, TopAbs_EDGE); exp.More(); exp.Next()) { TopoDS_Edge E = TopoDS::Edge(exp.Current()); if( tmpMap.Contains(E) ) continue; tmpMap.Add(E); SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current()); MapShapeNbElemsItr anIt = aResMap.find(aSubMesh); if( anIt==aResMap.end() ) { SMESH_subMesh *sm = aMesh.GetSubMesh(F); SMESH_ComputeErrorPtr& smError = sm->GetComputeError(); smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this)); return false; } std::vector<int> aVec = (*anIt).second; nb0d += aVec[SMDSEntity_Node]; nb1d += Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]); double aLen = SMESH_Algo::EdgeLength(E); fullLen += aLen; if(IsFirst) { IsQuadratic = (aVec[SMDSEntity_Quad_Edge] > aVec[SMDSEntity_Edge]); IsFirst = false; } } tmpMap.Clear(); // compute edge length double ELen = 0; if (_hypLengthFromEdges || (!_hypLengthFromEdges && !_hypMaxElementArea)) { if ( nb1d > 0 ) ELen = fullLen / nb1d; } if ( _hypMaxElementArea ) { double maxArea = _hypMaxElementArea->GetMaxArea(); ELen = sqrt(2. * maxArea/sqrt(3.0)); } GProp_GProps G; BRepGProp::SurfaceProperties(F,G); double anArea = G.Mass(); const int hugeNb = numeric_limits<int>::max()/10; if ( anArea / hugeNb > ELen*ELen ) { SMESH_subMesh *sm = aMesh.GetSubMesh(F); SMESH_ComputeErrorPtr& smError = sm->GetComputeError(); smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated.\nToo small element length",this)); return false; } int nbFaces = (int) ( anArea / ( ELen*ELen*sqrt(3.) / 4 ) ); int nbNodes = (int) ( ( nbFaces*3 - (nb1d-1)*2 ) / 6 + 1 ); std::vector<int> aVec(SMDSEntity_Last); for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aVec[i]=0; if( IsQuadratic ) { aVec[SMDSEntity_Node] = nbNodes; aVec[SMDSEntity_Quad_Triangle] = nbFaces; } else { aVec[SMDSEntity_Node] = nbNodes; aVec[SMDSEntity_Triangle] = nbFaces; } SMESH_subMesh *sm = aMesh.GetSubMesh(F); aResMap.insert(std::make_pair(sm,aVec)); return true; }
bool StdMeshers_RadialQuadrangle_1D2D::Evaluate(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, MapShapeNbElems& aResMap) { if( aShape.ShapeType() != TopAbs_FACE ) { return false; } SMESH_subMesh * smf = aMesh.GetSubMesh(aShape); MapShapeNbElemsItr anIt = aResMap.find(smf); if( anIt != aResMap.end() ) { return false; } myLayerPositions.clear(); gp_Pnt P0(0,0,0); gp_Pnt P1(100,0,0); computeLayerPositions(P0,P1); TopoDS_Edge E1,E2,E3; Handle(Geom_Curve) C1,C2,C3; double f1,l1,f2,l2,f3,l3; int nbe = 0; TopExp_Explorer exp; for ( exp.Init( aShape, TopAbs_EDGE ); exp.More(); exp.Next() ) { nbe++; TopoDS_Edge E = TopoDS::Edge( exp.Current() ); if(nbe==1) { E1 = E; C1 = BRep_Tool::Curve(E,f1,l1); } else if(nbe==2) { E2 = E; C2 = BRep_Tool::Curve(E,f2,l2); } else if(nbe==3) { E3 = E; C3 = BRep_Tool::Curve(E,f3,l3); } } TopoDS_Edge CircEdge, LinEdge1, LinEdge2; int nb0d=0, nb2d_tria=0, nb2d_quad=0; bool isQuadratic = false; if(nbe==1) { // C1 must be a circle Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast(C1); if( !aCirc.IsNull() ) { bool ok = _gen->Evaluate( aMesh, CircEdge, aResMap ); if(ok) { SMESH_subMesh * sm = aMesh.GetSubMesh(CircEdge); MapShapeNbElemsItr anIt = aResMap.find(sm); vector<int> aVec = (*anIt).second; isQuadratic = aVec[SMDSEntity_Quad_Edge]>aVec[SMDSEntity_Edge]; if(isQuadratic) { // main nodes nb0d = (aVec[SMDSEntity_Node]+1) * myLayerPositions.size(); // radial medium nodes nb0d += (aVec[SMDSEntity_Node]+1) * (myLayerPositions.size()+1); // other medium nodes nb0d += (aVec[SMDSEntity_Node]+1) * myLayerPositions.size(); } else { nb0d = (aVec[SMDSEntity_Node]+1) * myLayerPositions.size(); } nb2d_tria = aVec[SMDSEntity_Node] + 1; nb2d_quad = nb0d; } } } else if(nbe==2) { // one curve must be a half of circle and other curve must be // a segment of line Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(C1); while( !tc.IsNull() ) { C1 = tc->BasisCurve(); tc = Handle(Geom_TrimmedCurve)::DownCast(C1); } tc = Handle(Geom_TrimmedCurve)::DownCast(C2); while( !tc.IsNull() ) { C2 = tc->BasisCurve(); tc = Handle(Geom_TrimmedCurve)::DownCast(C2); } Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast(C1); Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast(C2); CircEdge = E1; LinEdge1 = E2; double fp = f1; double lp = l1; if( aCirc.IsNull() ) { aCirc = Handle(Geom_Circle)::DownCast(C2); CircEdge = E2; LinEdge1 = E1; fp = f2; lp = l2; aLine = Handle(Geom_Line)::DownCast(C3); } bool ok = !aCirc.IsNull() && !aLine.IsNull(); if( fabs(fabs(lp-fp)-M_PI) > Precision::Confusion() ) { // not half of circle ok = false; } SMESH_subMesh* sm1 = aMesh.GetSubMesh(LinEdge1); MapShapeNbElemsItr anIt = aResMap.find(sm1); if( anIt!=aResMap.end() ) { ok = false; } if(ok) { ok = _gen->Evaluate( aMesh, CircEdge, aResMap ); } if(ok) { SMESH_subMesh * sm = aMesh.GetSubMesh(CircEdge); MapShapeNbElemsItr anIt = aResMap.find(sm); vector<int> aVec = (*anIt).second; isQuadratic = aVec[SMDSEntity_Quad_Edge]>aVec[SMDSEntity_Edge]; if(isQuadratic) { // main nodes nb0d = aVec[SMDSEntity_Node] * myLayerPositions.size(); // radial medium nodes nb0d += aVec[SMDSEntity_Node] * (myLayerPositions.size()+1); // other medium nodes nb0d += (aVec[SMDSEntity_Node]+1) * myLayerPositions.size(); } else { nb0d = aVec[SMDSEntity_Node] * myLayerPositions.size(); } nb2d_tria = aVec[SMDSEntity_Node] + 1; nb2d_quad = nb2d_tria * myLayerPositions.size(); // add evaluation for edges vector<int> aResVec(SMDSEntity_Last); for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0; if(isQuadratic) { aResVec[SMDSEntity_Node] = 4*myLayerPositions.size() + 3; aResVec[SMDSEntity_Quad_Edge] = 2*myLayerPositions.size() + 2; } else { aResVec[SMDSEntity_Node] = 2*myLayerPositions.size() + 1; aResVec[SMDSEntity_Edge] = 2*myLayerPositions.size() + 2; } sm = aMesh.GetSubMesh(LinEdge1); aResMap.insert(make_pair(sm,aResVec)); } } else { // nbe==3 // one curve must be a part of circle and other curves must be // segments of line Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(C1); while( !tc.IsNull() ) { C1 = tc->BasisCurve(); tc = Handle(Geom_TrimmedCurve)::DownCast(C1); } tc = Handle(Geom_TrimmedCurve)::DownCast(C2); while( !tc.IsNull() ) { C2 = tc->BasisCurve(); tc = Handle(Geom_TrimmedCurve)::DownCast(C2); } tc = Handle(Geom_TrimmedCurve)::DownCast(C3); while( !tc.IsNull() ) { C3 = tc->BasisCurve(); tc = Handle(Geom_TrimmedCurve)::DownCast(C3); } Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast(C1); Handle(Geom_Line) aLine1 = Handle(Geom_Line)::DownCast(C2); Handle(Geom_Line) aLine2 = Handle(Geom_Line)::DownCast(C3); CircEdge = E1; LinEdge1 = E2; LinEdge2 = E3; double fp = f1; double lp = l1; if( aCirc.IsNull() ) { aCirc = Handle(Geom_Circle)::DownCast(C2); CircEdge = E2; LinEdge1 = E3; LinEdge2 = E1; fp = f2; lp = l2; aLine1 = Handle(Geom_Line)::DownCast(C3); aLine2 = Handle(Geom_Line)::DownCast(C1); if( aCirc.IsNull() ) { aCirc = Handle(Geom_Circle)::DownCast(C3); CircEdge = E3; LinEdge1 = E1; LinEdge2 = E2; fp = f3; lp = l3; aLine1 = Handle(Geom_Line)::DownCast(C1); aLine2 = Handle(Geom_Line)::DownCast(C2); } } bool ok = !aCirc.IsNull() && !aLine1.IsNull() && !aLine1.IsNull(); SMESH_subMesh* sm = aMesh.GetSubMesh(LinEdge1); MapShapeNbElemsItr anIt = aResMap.find(sm); if( anIt!=aResMap.end() ) { ok = false; } sm = aMesh.GetSubMesh(LinEdge2); anIt = aResMap.find(sm); if( anIt!=aResMap.end() ) { ok = false; } if(ok) { ok = _gen->Evaluate( aMesh, CircEdge, aResMap ); } if(ok) { SMESH_subMesh * sm = aMesh.GetSubMesh(CircEdge); MapShapeNbElemsItr anIt = aResMap.find(sm); vector<int> aVec = (*anIt).second; isQuadratic = aVec[SMDSEntity_Quad_Edge]>aVec[SMDSEntity_Edge]; if(isQuadratic) { // main nodes nb0d = aVec[SMDSEntity_Node] * myLayerPositions.size(); // radial medium nodes nb0d += aVec[SMDSEntity_Node] * (myLayerPositions.size()+1); // other medium nodes nb0d += (aVec[SMDSEntity_Node]+1) * myLayerPositions.size(); } else { nb0d = aVec[SMDSEntity_Node] * myLayerPositions.size(); } nb2d_tria = aVec[SMDSEntity_Node] + 1; nb2d_quad = nb2d_tria * myLayerPositions.size(); // add evaluation for edges vector<int> aResVec(SMDSEntity_Last); for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0; if(isQuadratic) { aResVec[SMDSEntity_Node] = 2*myLayerPositions.size() + 1; aResVec[SMDSEntity_Quad_Edge] = myLayerPositions.size() + 1; } else { aResVec[SMDSEntity_Node] = myLayerPositions.size(); aResVec[SMDSEntity_Edge] = myLayerPositions.size() + 1; } sm = aMesh.GetSubMesh(LinEdge1); aResMap.insert(make_pair(sm,aResVec)); sm = aMesh.GetSubMesh(LinEdge2); aResMap.insert(make_pair(sm,aResVec)); } } vector<int> aResVec(SMDSEntity_Last); for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0; SMESH_subMesh * sm = aMesh.GetSubMesh(aShape); //cout<<"nb0d = "<<nb0d<<" nb2d_tria = "<<nb2d_tria<<" nb2d_quad = "<<nb2d_quad<<endl; if(nb0d>0) { aResVec[0] = nb0d; if(isQuadratic) { aResVec[SMDSEntity_Quad_Triangle] = nb2d_tria; aResVec[SMDSEntity_Quad_Quadrangle] = nb2d_quad; } else { aResVec[SMDSEntity_Triangle] = nb2d_tria; aResVec[SMDSEntity_Quadrangle] = nb2d_quad; } aResMap.insert(make_pair(sm,aResVec)); return true; } // invalid case aResMap.insert(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; }
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; }