From 318d07b4db4d3ae7ad912d58c0d7fa147e118b62 Mon Sep 17 00:00:00 2001 From: eap Date: Tue, 19 May 2009 15:40:53 +0000 Subject: [PATCH] 0020279: [CEA 334] control the "random" use when using mesh algorithms 1) delete temporary faces in destructor 2) bind created pyramids to shape 3) create quadratic pyramids when necessary 4) sort faces by IDs --- .../StdMeshers_QuadToTriaAdaptor.cxx | 176 +++++++++--------- 1 file changed, 84 insertions(+), 92 deletions(-) diff --git a/src/StdMeshers/StdMeshers_QuadToTriaAdaptor.cxx b/src/StdMeshers/StdMeshers_QuadToTriaAdaptor.cxx index f40c32c02..28a4166c5 100644 --- a/src/StdMeshers/StdMeshers_QuadToTriaAdaptor.cxx +++ b/src/StdMeshers/StdMeshers_QuadToTriaAdaptor.cxx @@ -27,19 +27,18 @@ // #include "StdMeshers_QuadToTriaAdaptor.hxx" -//#include -//#include +#include +#include +#include + +#include +#include +#include +#include #include #include -#include -#include -#include -#include -#include -#include #include #include -#include #include typedef NCollection_Array1 StdMeshers_Array1OfSequenceOfInteger; @@ -62,7 +61,23 @@ StdMeshers_QuadToTriaAdaptor::StdMeshers_QuadToTriaAdaptor() //================================================================================ StdMeshers_QuadToTriaAdaptor::~StdMeshers_QuadToTriaAdaptor() -{} +{ + // delete temporary faces + map< const SMDS_MeshElement*, list >::iterator + f_f = myResMap.begin(), ffEnd = myResMap.end(); + for ( ; f_f != ffEnd; ++f_f ) + { + list& fList = f_f->second; + list::iterator f = fList.begin(), fEnd = fList.end(); + for ( ; f != fEnd; ++f ) + delete *f; + } + myResMap.clear(); + +// TF2PyramMap::iterator itp = myMapFPyram.begin(); +// for(; itp!=myMapFPyram.end(); itp++) +// cout << itp->second << endl; +} //======================================================================= @@ -285,18 +300,18 @@ static bool CompareTrias(const SMDS_MeshElement* F1,const SMDS_MeshElement* F2) //function : IsDegenarate //purpose : Auxilare for Preparation() //======================================================================= -static int IsDegenarate(const Handle(TColgp_HArray1OfPnt)& PN) -{ - int i = 1; - for(; i<4; i++) { - int j = i+1; - for(; j<=4; j++) { - if( PN->Value(i).Distance(PN->Value(j)) < 1.e-6 ) - return j; - } - } - return 0; -} +// static int IsDegenarate(const Handle(TColgp_HArray1OfPnt)& PN) +// { +// int i = 1; +// for(; i<4; i++) { +// int j = i+1; +// for(; j<=4; j++) { +// if( PN->Value(i).Distance(PN->Value(j)) < 1.e-6 ) +// return j; +// } +// } +// return 0; +// } //======================================================================= @@ -307,8 +322,8 @@ static int IsDegenarate(const Handle(TColgp_HArray1OfPnt)& PN) // 2 if given face is degenerate quad (two nodes are coincided) //======================================================================= int StdMeshers_QuadToTriaAdaptor::Preparation(const SMDS_MeshElement* face, - Handle(TColgp_HArray1OfPnt) PN, - Handle(TColgp_HArray1OfVec) VN, + Handle(TColgp_HArray1OfPnt)& PN, + Handle(TColgp_HArray1OfVec)& VN, std::vector& FNodes, gp_Pnt& PC, gp_Vec& VNorm) { @@ -427,6 +442,9 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape myMapFPyram.clear(); SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); + SMESH_MesherHelper helper(aMesh); + helper.IsQuadraticSubMesh(aShape); + helper.SetElementsOnShape( true ); for (TopExp_Explorer exp(aShape,TopAbs_FACE);exp.More();exp.Next()) { const TopoDS_Shape& aShapeFace = exp.Current(); @@ -481,9 +499,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape double height = PCbest.Distance(PC); if(height<1.e-6) { // create new PCbest using a bit shift along VNorm - PCbest = gp_Pnt( PC.X() + VNorm.X()*0.001, - PC.Y() + VNorm.Y()*0.001, - PC.Z() + VNorm.Z()*0.001); + PCbest = PC.XYZ() + VNorm.XYZ() * 0.001; } else { // check possible intersection with other faces @@ -494,27 +510,23 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape //cout<<" PCbest("<AddNode( PCbest.X(), PCbest.Y(), PCbest.Z() ); + SMDS_MeshNode* NewNode = helper.AddNode( PCbest.X(), PCbest.Y(), PCbest.Z() ); // add triangles to result map std::list aList; for(i=0; i<4; i++) { @@ -524,7 +536,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape myResMap.insert(make_pair(face,aList)); // create pyramid SMDS_MeshVolume* aPyram = - meshDS->AddVolume( FNodes[0], FNodes[1], FNodes[2], FNodes[3], NewNode ); + helper.AddVolume( FNodes[0], FNodes[1], FNodes[2], FNodes[3], NewNode ); myMapFPyram.insert(make_pair(face,aPyram)); } // end loop on elements on a face } @@ -543,13 +555,20 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh) { myResMap.clear(); myMapFPyram.clear(); + SMESH_MesherHelper helper(aMesh); + helper.IsQuadraticSubMesh(aMesh.GetShapeToMesh()); + helper.SetElementsOnShape( true ); SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); - SMDS_FaceIteratorPtr itFace = meshDS->facesIterator(); + SMDS_FaceIteratorPtr fIt = meshDS->facesIterator(); + TIDSortedElemSet sortedFaces; // 0020279: control the "random" use when using mesh algorithms + while( fIt->more()) sortedFaces.insert( fIt->next() ); - while(itFace->more()) { - const SMDS_MeshElement* face = itFace->next(); + TIDSortedElemSet::iterator itFace = sortedFaces.begin(), fEnd = sortedFaces.end(); + for ( ; itFace != fEnd; ++itFace ) + { + const SMDS_MeshElement* face = *itFace; if ( !face ) continue; //cout<GetID() = "<GetID()<Value(1).Distance(PN->Value(2)) + PN->Value(2).Distance(PN->Value(3)); - gp_Dir tmpDir(VNorm); - gp_Pnt Ptmp1( PC.X() + tmpDir.X()*tmp*1.e6, - PC.Y() + tmpDir.Y()*tmp*1.e6, - PC.Z() + tmpDir.Z()*tmp*1.e6 ); - gp_Pnt Ptmp2( PC.X() + tmpDir.Reversed().X()*tmp*1.e6, - PC.Y() + tmpDir.Reversed().Y()*tmp*1.e6, - PC.Z() + tmpDir.Reversed().Z()*tmp*1.e6 ); + gp_Pnt Ptmp1 = PC.XYZ() + VNorm.XYZ() * tmp * 1.e6; + gp_Pnt Ptmp2 = PC.XYZ() - VNorm.XYZ() * tmp * 1.e6; // check intersection for Ptmp1 and Ptmp2 bool IsRev = false; bool IsOK1 = false; @@ -586,9 +600,8 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh) double dist1 = RealLast(); double dist2 = RealLast(); gp_Pnt Pres1,Pres2; - SMDS_FaceIteratorPtr itf = meshDS->facesIterator(); - while(itf->more()) { - const SMDS_MeshElement* F = itf->next(); + for (TIDSortedElemSet::iterator itF = sortedFaces.begin(); itF != fEnd; ++itF ) { + const SMDS_MeshElement* F = *itF; if(F==face) continue; Handle(TColgp_HSequenceOfPnt) aContour = new TColgp_HSequenceOfPnt; SMDS_ElemIteratorPtr nodeIt = F->nodesIterator(); @@ -665,9 +678,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh) double height = PCbest.Distance(PC); if(height<1.e-6) { // create new PCbest using a bit shift along VNorm - PCbest = gp_Pnt( PC.X() + VNorm.X()*0.001, - PC.Y() + VNorm.Y()*0.001, - PC.Z() + VNorm.Z()*0.001); + PCbest = PC.XYZ() + VNorm.XYZ() * 0.001; height = PCbest.Distance(PC); } //cout<<" PCbest("<Value(1).Distance(PN->Value(3)) + PN->Value(2).Distance(PN->Value(4)); gp_Dir tmpDir(V1); - gp_Pnt Ptmp1( PC.X() + tmpDir.X()*tmp*1.e6, - PC.Y() + tmpDir.Y()*tmp*1.e6, - PC.Z() + tmpDir.Z()*tmp*1.e6 ); - gp_Pnt Ptmp2( PC.X() + tmpDir.Reversed().X()*tmp*1.e6, - PC.Y() + tmpDir.Reversed().Y()*tmp*1.e6, - PC.Z() + tmpDir.Reversed().Z()*tmp*1.e6 ); + gp_Pnt Ptmp1 = PC.XYZ() + tmpDir.XYZ() * tmp * 1.e6; + gp_Pnt Ptmp2 = PC.XYZ() - tmpDir.XYZ() * tmp * 1.e6; // check intersection for Ptmp1 and Ptmp2 bool IsRev = false; bool IsOK1 = false; @@ -689,9 +696,8 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh) double dist1 = RealLast(); double dist2 = RealLast(); gp_Pnt Pres1,Pres2; - SMDS_FaceIteratorPtr itf = meshDS->facesIterator(); - while(itf->more()) { - const SMDS_MeshElement* F = itf->next(); + for (TIDSortedElemSet::iterator itF = sortedFaces.begin(); itF != fEnd; ++itF ) { + const SMDS_MeshElement* F = *itF; if(F==face) continue; Handle(TColgp_HSequenceOfPnt) aContour = new TColgp_HSequenceOfPnt; SMDS_ElemIteratorPtr nodeIt = F->nodesIterator(); @@ -734,9 +740,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh) double tmp = PC.Distance(Pres1)/3.; if( height > tmp ) { height = tmp; - PCbest = gp_Pnt( PC.X() + tmpDir.X()*height, - PC.Y() + tmpDir.Y()*height, - PC.Z() + tmpDir.Z()*height ); + PCbest = PC.XYZ() + tmpDir.XYZ() * height; } } else if( !IsOK1 && IsOK2 ) { @@ -744,9 +748,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh) IsRev = true; double tmp = PC.Distance(Pres2)/3.; if( height > tmp ) height = tmp; - PCbest = gp_Pnt( PC.X() + tmpDir.Reversed().X()*height, - PC.Y() + tmpDir.Reversed().Y()*height, - PC.Z() + tmpDir.Reversed().Z()*height ); + PCbest = PC.XYZ() - tmpDir.XYZ() * height; } else { // IsOK1 && IsOK2 double tmp1 = PC.Distance(Pres1)/3.; @@ -755,23 +757,19 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh) // using existed direction if( height > tmp1 ) { height = tmp1; - PCbest = gp_Pnt( PC.X() + tmpDir.X()*height, - PC.Y() + tmpDir.Y()*height, - PC.Z() + tmpDir.Z()*height ); + PCbest = PC.XYZ() + tmpDir.XYZ() * height; } } else { // using opposite direction IsRev = true; if( height > tmp2 ) height = tmp2; - PCbest = gp_Pnt( PC.X() + tmpDir.Reversed().X()*height, - PC.Y() + tmpDir.Reversed().Y()*height, - PC.Z() + tmpDir.Reversed().Z()*height ); + PCbest = PC.XYZ() - tmpDir.XYZ() * height; } } // create node for PCbest - SMDS_MeshNode* NewNode = meshDS->AddNode( PCbest.X(), PCbest.Y(), PCbest.Z() ); + SMDS_MeshNode* NewNode = helper.AddNode( PCbest.X(), PCbest.Y(), PCbest.Z() ); // add triangles to result map std::list aList; for(i=0; i<4; i++) { @@ -786,9 +784,9 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh) // create pyramid SMDS_MeshVolume* aPyram; if(IsRev) - aPyram = meshDS->AddVolume( FNodes[0], FNodes[1], FNodes[2], FNodes[3], NewNode ); + aPyram = helper.AddVolume( FNodes[0], FNodes[1], FNodes[2], FNodes[3], NewNode ); else - aPyram = meshDS->AddVolume( FNodes[0], FNodes[3], FNodes[2], FNodes[1], NewNode ); + aPyram = helper.AddVolume( FNodes[0], FNodes[3], FNodes[2], FNodes[1], NewNode ); myMapFPyram.insert(make_pair(face,aPyram)); } // end loop on elements on a face @@ -811,10 +809,9 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh) if(NbPyram==0) return true; - std::vector< const SMDS_MeshElement* > Pyrams(NbPyram); - std::vector< const SMDS_MeshElement* > Faces(NbPyram); - std::map< const SMDS_MeshElement*, - const SMDS_MeshElement* >::iterator itp = myMapFPyram.begin(); + vector< const SMDS_MeshElement* > Pyrams(NbPyram); + vector< const SMDS_MeshElement* > Faces(NbPyram); + TF2PyramMap::iterator itp = myMapFPyram.begin(); int i = 0; for(; itp!=myMapFPyram.end(); itp++, i++) { Faces[i] = (*itp).first; @@ -845,7 +842,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh) int nbI = aMergesI.Length(); const TColStd_SequenceOfInteger& aMergesJ = MergesInfo.Value(j); int nbJ = aMergesJ.Length(); - + // check if two pyramids already merged int k = 2; bool NeedCont = false; for(; k<=nbI; k++) { @@ -854,7 +851,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh) break; } } - if(NeedCont) continue; + if(NeedCont) continue; // already merged const SMDS_MeshElement* Prm2 = Pyrams[j]; nIt = Prm2->nodesIterator(); @@ -872,9 +869,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh) gp_Pnt Pint; for(k=0; k<4; k++) { gp_Vec Vtmp(Ps1[k],Ps1[4]); - gp_Pnt Pshift( Ps1[k].X() + Vtmp.X()*0.01, - Ps1[k].Y() + Vtmp.Y()*0.01, - Ps1[k].Z() + Vtmp.Z()*0.01 ); + gp_Pnt Pshift = Ps1[k].XYZ() + Vtmp.XYZ() * 0.01; int m=0; for(; m<3; m++) { if( HasIntersection3( Pshift, Ps1[4], Pint, Ps2[m], Ps2[m+1], Ps2[4]) ) { @@ -890,9 +885,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh) if(!hasInt) { for(k=0; k<4; k++) { gp_Vec Vtmp(Ps2[k],Ps2[4]); - gp_Pnt Pshift( Ps2[k].X() + Vtmp.X()*0.01, - Ps2[k].Y() + Vtmp.Y()*0.01, - Ps2[k].Z() + Vtmp.Z()*0.01 ); + gp_Pnt Pshift = Ps2[k].XYZ() + Vtmp.XYZ() * 0.01; int m=0; for(; m<3; m++) { if( HasIntersection3( Pshift, Ps2[4], Pint, Ps1[m], Ps1[m+1], Ps1[4]) ) { @@ -1129,16 +1122,15 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh) * \brief Return list of created triangles for given face */ //================================================================================ -std::list StdMeshers_QuadToTriaAdaptor::GetTriangles +const std::list* StdMeshers_QuadToTriaAdaptor::GetTriangles (const SMDS_MeshElement* aFace) { - std::list aRes; std::map< const SMDS_MeshElement*, std::list >::iterator it = myResMap.find(aFace); if( it != myResMap.end() ) { - return it->second; + return & it->second; } - return aRes; + return 0; }