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 NETGENPlugin_Mesher::Evaluate(MapShapeNbElems& aResMap) { #ifdef WNT netgen::MeshingParameters& mparams = netgen::GlobalMeshingParameters(); #else netgen::MeshingParameters& mparams = netgen::mparam; #endif // ------------------------- // Prepare OCC geometry // ------------------------- netgen::OCCGeometry occgeo; list< SMESH_subMesh* > meshedSM; PrepareOCCgeometry( occgeo, _shape, *_mesh, &meshedSM ); bool tooManyElems = false; const int hugeNb = std::numeric_limits<int>::max() / 100; // ---------------- // evaluate 1D // ---------------- // pass 1D simple parameters to NETGEN int nbs = 0; if ( _simpleHyp ) { if ( int nbSeg = _simpleHyp->GetNumberOfSegments() ) { nbs = nbSeg; // nb of segments mparams.segmentsperedge = nbSeg + 0.1; mparams.maxh = occgeo.boundingbox.Diam(); mparams.grading = 0.01; } else { // segment length mparams.segmentsperedge = 1; mparams.maxh = _simpleHyp->GetLocalLength(); } } TopTools_DataMapOfShapeInteger EdgesMap; double fullLen = 0.0; double fullNbSeg = 0; for (TopExp_Explorer exp(_shape, TopAbs_EDGE); exp.More(); exp.Next()) { TopoDS_Edge E = TopoDS::Edge( exp.Current() ); if( EdgesMap.IsBound(E) ) continue; SMESH_subMesh *sm = _mesh->GetSubMesh(E); std::vector<int> aVec(SMDSEntity_Last, 0); double aLen = SMESH_Algo::EdgeLength(E); fullLen += aLen; int nb1d = nbs; tooManyElems = ( aLen/hugeNb > mparams.maxh ); if(nb1d==0 && !tooManyElems) { nb1d = (int)( aLen/mparams.maxh + 1 ); } if ( tooManyElems ) // avoid FPE { aVec[SMDSEntity_Node] = hugeNb; aVec[ mparams.secondorder > 0 ? SMDSEntity_Quad_Edge : SMDSEntity_Edge] = hugeNb; } else { fullNbSeg += nb1d; if( mparams.secondorder > 0 ) { aVec[SMDSEntity_Node] = 2*nb1d - 1; aVec[SMDSEntity_Quad_Edge] = nb1d; } else { aVec[SMDSEntity_Node] = nb1d - 1; aVec[SMDSEntity_Edge] = nb1d; } } aResMap.insert(std::make_pair(sm,aVec)); EdgesMap.Bind(E,nb1d); } // ---------------- // evaluate 2D // ---------------- if ( _simpleHyp ) { if ( double area = _simpleHyp->GetMaxElementArea() ) { // face area mparams.maxh = sqrt(2. * area/sqrt(3.0)); mparams.grading = 0.4; // moderate size growth } else { // length from edges mparams.maxh = fullLen/fullNbSeg; mparams.grading = 0.2; // slow size growth } mparams.maxh = min( mparams.maxh, occgeo.boundingbox.Diam()/2 ); } for (TopExp_Explorer exp(_shape, TopAbs_FACE); exp.More(); exp.Next()) { TopoDS_Face F = TopoDS::Face( exp.Current() ); SMESH_subMesh *sm = _mesh->GetSubMesh(F); GProp_GProps G; BRepGProp::SurfaceProperties(F,G); double anArea = G.Mass(); tooManyElems = tooManyElems || ( anArea/hugeNb > mparams.maxh*mparams.maxh ); int nb1d = 0; if ( !tooManyElems ) for (TopExp_Explorer exp1(F,TopAbs_EDGE); exp1.More(); exp1.Next()) nb1d += EdgesMap.Find(exp1.Current()); int nbFaces = tooManyElems ? hugeNb : int( 4*anArea / mparams.maxh*mparams.maxh*sqrt(3.)); int nbNodes = tooManyElems ? hugeNb : (( nbFaces*3 - (nb1d-1)*2 ) / 6 + 1 ); std::vector<int> aVec(SMDSEntity_Last, 0); if( mparams.secondorder > 0 ) { int nb1d_in = (nbFaces*3 - nb1d) / 2; aVec[SMDSEntity_Node] = nbNodes + nb1d_in; aVec[SMDSEntity_Quad_Triangle] = nbFaces; } else { aVec[SMDSEntity_Node] = nbNodes; aVec[SMDSEntity_Triangle] = nbFaces; } aResMap.insert(std::make_pair(sm,aVec)); } // ---------------- // evaluate 3D // ---------------- if(_isVolume) { // pass 3D simple parameters to NETGEN const NETGENPlugin_SimpleHypothesis_3D* simple3d = dynamic_cast< const NETGENPlugin_SimpleHypothesis_3D* > ( _simpleHyp ); if ( simple3d ) { if ( double vol = simple3d->GetMaxElementVolume() ) { // max volume mparams.maxh = pow( 72, 1/6. ) * pow( vol, 1/3. ); mparams.maxh = min( mparams.maxh, occgeo.boundingbox.Diam()/2 ); } else { // using previous length from faces } mparams.grading = 0.4; } GProp_GProps G; BRepGProp::VolumeProperties(_shape,G); double aVolume = G.Mass(); double tetrVol = 0.1179*mparams.maxh*mparams.maxh*mparams.maxh; tooManyElems = tooManyElems || ( aVolume/hugeNb > tetrVol ); int nbVols = tooManyElems ? hugeNb : int(aVolume/tetrVol); int nb1d_in = int(( nbVols*6 - fullNbSeg ) / 6 ); std::vector<int> aVec(SMDSEntity_Last, 0 ); if ( tooManyElems ) // avoid FPE { aVec[SMDSEntity_Node] = hugeNb; aVec[ mparams.secondorder > 0 ? SMDSEntity_Quad_Tetra : SMDSEntity_Tetra] = hugeNb; } else { if( mparams.secondorder > 0 ) { aVec[SMDSEntity_Node] = nb1d_in/3 + 1 + nb1d_in; aVec[SMDSEntity_Quad_Tetra] = nbVols; } else { aVec[SMDSEntity_Node] = nb1d_in/3 + 1; aVec[SMDSEntity_Tetra] = nbVols; } } SMESH_subMesh *sm = _mesh->GetSubMesh(_shape); 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 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 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_Projection_3D::Evaluate(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, MapShapeNbElems& aResMap) { if ( !_sourceHypo ) return false; SMESH_Mesh * srcMesh = _sourceHypo->GetSourceMesh(); SMESH_Mesh * tgtMesh = & aMesh; if ( !srcMesh ) srcMesh = tgtMesh; // get shell from shape3D TopoDS_Shell srcShell, tgtShell; TopExp_Explorer exp( _sourceHypo->GetSource3DShape(), TopAbs_SHELL ); int nbShell; for ( nbShell = 0; exp.More(); exp.Next(), ++nbShell ) srcShell = TopoDS::Shell( exp.Current() ); if ( nbShell != 1 ) return error(COMPERR_BAD_SHAPE, SMESH_Comment("Source shape must have 1 shell but not ") << nbShell); exp.Init( aShape, TopAbs_SHELL ); for ( nbShell = 0; exp.More(); exp.Next(), ++nbShell ) tgtShell = TopoDS::Shell( exp.Current() ); if ( nbShell != 1 ) return error(COMPERR_BAD_SHAPE, SMESH_Comment("Target shape must have 1 shell but not ") << nbShell); // Check that shapes are blocks if ( SMESH_MesherHelper::Count( tgtShell, TopAbs_FACE , 1 ) != 6 || SMESH_MesherHelper::Count( tgtShell, TopAbs_EDGE , 1 ) != 12 || SMESH_MesherHelper::Count( tgtShell, TopAbs_WIRE , 1 ) != 6 ) return error(COMPERR_BAD_SHAPE, "Target shape is not a block"); if ( SMESH_MesherHelper::Count( srcShell, TopAbs_FACE , 1 ) != 6 || SMESH_MesherHelper::Count( srcShell, TopAbs_EDGE , 1 ) != 12 || SMESH_MesherHelper::Count( srcShell, TopAbs_WIRE , 1 ) != 6 ) return error(COMPERR_BAD_SHAPE, "Source shape is not a block"); // Assure that mesh on a source shape is computed SMESH_subMesh* srcSubMesh = srcMesh->GetSubMesh( _sourceHypo->GetSource3DShape() ); if ( !srcSubMesh->IsMeshComputed() ) return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed"); std::vector<int> aVec(SMDSEntity_Last); for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aVec[i] = 0; aVec[SMDSEntity_Node] = srcSubMesh->GetSubMeshDS()->NbNodes(); //bool quadratic = false; SMDS_ElemIteratorPtr elemIt = srcSubMesh->GetSubMeshDS()->GetElements(); while ( elemIt->more() ) { const SMDS_MeshElement* E = elemIt->next(); if( E->NbNodes()==4 ) { aVec[SMDSEntity_Tetra]++; } else if( E->NbNodes()==5 ) { aVec[SMDSEntity_Pyramid]++; } else if( E->NbNodes()==6 ) { aVec[SMDSEntity_Penta]++; } else if( E->NbNodes()==8 ) { aVec[SMDSEntity_Hexa]++; } else if( E->NbNodes()==10 && E->IsQuadratic() ) { aVec[SMDSEntity_Quad_Tetra]++; } else if( E->NbNodes()==13 && E->IsQuadratic() ) { aVec[SMDSEntity_Quad_Pyramid]++; } else if( E->NbNodes()==15 && E->IsQuadratic() ) { aVec[SMDSEntity_Quad_Penta]++; } else if( E->NbNodes()==20 && E->IsQuadratic() ) { aVec[SMDSEntity_Quad_Hexa]++; } else { aVec[SMDSEntity_Polyhedra]++; } } SMESH_subMesh * sm = aMesh.GetSubMesh(aShape); aResMap.insert(std::make_pair(sm,aVec)); return true; }
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; }