Salome HOME
correct the preceeding patch
[modules/smesh.git] / src / StdMeshers / StdMeshers_QuadToTriaAdaptor.cxx
index ecf386bd425f232de23b0a3f8bd5dd34baeb34dd..b0204258988607ddf899d87d8192ef7c4a90619b 100644 (file)
@@ -17,7 +17,6 @@
 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
-//  SMESH SMESH : implementaion of SMESH idl descriptions
 // File      : StdMeshers_QuadToTriaAdaptor.cxx
 // Module    : SMESH
 // Created   : Wen May 07 16:37:07 2008
@@ -47,7 +46,7 @@ using namespace std;
 enum EQuadNature { NOT_QUAD, QUAD, DEGEN_QUAD, PYRAM_APEX = 4, TRIA_APEX = 0 };
 
 // std-like iterator used to get coordinates of nodes of mesh element
-typedef SMDS_StdIterator< SMESH_MeshEditor::TNodeXYZ, SMDS_ElemIteratorPtr > TXyzIterator;
+typedef SMDS_StdIterator< SMESH_TNodeXYZ, SMDS_ElemIteratorPtr > TXyzIterator;
 
 namespace
 {
@@ -91,7 +90,7 @@ namespace
         int ind = baseNodes[0] ? 1:0;
         if ( baseNodes[ ind ])
           return false; // pyramids with a common base face
-        baseNodes   [ ind ] = PrmI->GetNode(i);
+        baseNodes    [ ind ] = PrmI->GetNode(i);
         baseNodesIndI[ ind ] = i;
         baseNodesIndJ[ ind ] = j;
       }
@@ -99,10 +98,10 @@ namespace
     if ( !baseNodes[1] ) return false; // not adjacent
 
     // Get normals of triangles sharing baseNodes
-    gp_XYZ apexI = SMESH_MeshEditor::TNodeXYZ( nApexI );
-    gp_XYZ apexJ = SMESH_MeshEditor::TNodeXYZ( nApexJ );
-    gp_XYZ base1 = SMESH_MeshEditor::TNodeXYZ( baseNodes[0]);
-    gp_XYZ base2 = SMESH_MeshEditor::TNodeXYZ( baseNodes[1]);
+    gp_XYZ apexI = SMESH_TNodeXYZ( nApexI );
+    gp_XYZ apexJ = SMESH_TNodeXYZ( nApexJ );
+    gp_XYZ base1 = SMESH_TNodeXYZ( baseNodes[0]);
+    gp_XYZ base2 = SMESH_TNodeXYZ( baseNodes[1]);
     gp_Vec baseVec( base1, base2 );
     gp_Vec baI( base1, apexI );
     gp_Vec baJ( base1, apexJ );
@@ -114,12 +113,11 @@ namespace
     bool tooClose = ( angle < 15 * PI180 );
 
     // Check if pyramids collide
-    bool isOutI, isOutJ;
     if ( !tooClose && baI * baJ > 0 )
     {
       // find out if nI points outside of PrmI or inside
       int dInd = baseNodesIndI[1] - baseNodesIndI[0];
-      isOutI = ( abs(dInd)==1 ) ? dInd < 0 : dInd > 0;
+      bool isOutI = ( abs(dInd)==1 ) ? dInd < 0 : dInd > 0;
 
       // find out sign of projection of nJ to baI
       double proj = baI * nJ;
@@ -131,11 +129,17 @@ namespace
     if ( tooClose && !hasShape )
     {
       // check order of baseNodes within pyramids, it must be opposite
-      int dInd = baseNodesIndJ[1] - baseNodesIndJ[0];
-      isOutJ = ( abs(dInd)==1 ) ? dInd < 0 : dInd > 0;
+      int dInd;
+      dInd = baseNodesIndI[1] - baseNodesIndI[0];
+      bool isOutI = ( abs(dInd)==1 ) ? dInd < 0 : dInd > 0;
+      dInd = baseNodesIndJ[1] - baseNodesIndJ[0];
+      bool isOutJ = ( abs(dInd)==1 ) ? dInd < 0 : dInd > 0;
       if ( isOutJ == isOutI )
         return false; // other domain
 
+      // direct both normals outside pyramid
+      ( isOutI ? nJ : nI ).Reverse();
+
       // check absence of a face separating domains between pyramids
       TIDSortedElemSet emptySet, avoidSet;
       int i1, i2;
@@ -150,6 +154,9 @@ namespace
         while ( otherNodeInd == i1 || otherNodeInd == i2 ) otherNodeInd++;
         const SMDS_MeshNode* otherFaceNode = f->GetNode( otherNodeInd );
 
+        if ( otherFaceNode == nApexI || otherFaceNode == nApexJ )
+          continue; // f is a temporary triangle
+
         // check if f is a base face of either of pyramids
         if ( f->NbCornerNodes() == 4 &&
              ( PrmI->GetNodeIndex( otherFaceNode ) >= 0 ||
@@ -157,8 +164,7 @@ namespace
           continue; // f is a base quadrangle
 
         // check projections of face direction (baOFN) to triange normals (nI and nJ)
-        gp_Vec baOFN( base1, SMESH_MeshEditor::TNodeXYZ( otherFaceNode ));
-        ( isOutI ? nJ : nI ).Reverse();
+        gp_Vec baOFN( base1, SMESH_TNodeXYZ( otherFaceNode ));
         if ( nI * baOFN > 0 && nJ * baOFN > 0 )
         {
           tooClose = false; // f is between pyramids
@@ -182,15 +188,15 @@ void StdMeshers_QuadToTriaAdaptor::MergePiramids( const SMDS_MeshElement*     Pr
                                                   set<const SMDS_MeshNode*> & nodesToMove)
 {
   const SMDS_MeshNode* Nrem = PrmJ->GetNode(4); // node to remove
-  int nbJ = Nrem->NbInverseElements( SMDSAbs_Volume );
-  SMESH_MeshEditor::TNodeXYZ Pj( Nrem );
+  //int nbJ = Nrem->NbInverseElements( SMDSAbs_Volume );
+  SMESH_TNodeXYZ Pj( Nrem );
 
   // an apex node to make common to all merged pyramids
   SMDS_MeshNode* CommonNode = const_cast<SMDS_MeshNode*>(PrmI->GetNode(4));
   if ( CommonNode == Nrem ) return; // already merged
-  int nbI = CommonNode->NbInverseElements( SMDSAbs_Volume );
-  SMESH_MeshEditor::TNodeXYZ Pi( CommonNode );
-  gp_XYZ Pnew = ( nbI*Pi + nbJ*Pj ) / (nbI+nbJ);
+  //int nbI = CommonNode->NbInverseElements( SMDSAbs_Volume );
+  SMESH_TNodeXYZ Pi( CommonNode );
+  gp_XYZ Pnew = /*( nbI*Pi + nbJ*Pj ) / (nbI+nbJ);*/ 0.5 * ( Pi + Pj );
   CommonNode->setXYZ( Pnew.X(), Pnew.Y(), Pnew.Z() );
 
   nodesToMove.insert( CommonNode );
@@ -201,7 +207,7 @@ void StdMeshers_QuadToTriaAdaptor::MergePiramids( const SMDS_MeshElement*     Pr
 
   // find and remove coincided faces of merged pyramids
   vector< const SMDS_MeshElement* > inverseElems
-    // copy inverse elements to avoid iteration on changing conainer 
+    // copy inverse elements to avoid iteration on changing container 
     ( TStdElemIterator( CommonNode->GetInverseElementIterator(SMDSAbs_Face)), itEnd);
   for ( unsigned i = 0; i < inverseElems.size(); ++i )
   {
@@ -468,22 +474,13 @@ bool StdMeshers_QuadToTriaAdaptor::CheckIntersection (const gp_Pnt&       P,
   vector< const SMDS_MeshElement* > suspectElems;
   searcher->GetElementsNearLine( line, SMDSAbs_Face, suspectElems);
   
-//   for (TopExp_Explorer exp(aShape,TopAbs_FACE);exp.More();exp.Next()) {
-//     const TopoDS_Shape& aShapeFace = exp.Current();
-//     if(aShapeFace==NotCheckedFace)
-//       continue;
-//     const SMESHDS_SubMesh * aSubMeshDSFace = meshDS->MeshElements(aShapeFace);
-//     if ( aSubMeshDSFace ) {
-//       SMDS_ElemIteratorPtr iteratorElem = aSubMeshDSFace->GetElements();
-//       while ( iteratorElem->more() ) { // loop on elements on a face
-//         const SMDS_MeshElement* face = iteratorElem->next();
   for ( int i = 0; i < suspectElems.size(); ++i )
   {
     const SMDS_MeshElement* face = suspectElems[i];
     if ( face == NotCheckedFace ) continue;
     Handle(TColgp_HSequenceOfPnt) aContour = new TColgp_HSequenceOfPnt;
     for ( int i = 0; i < face->NbCornerNodes(); ++i ) 
-      aContour->Append( SMESH_MeshEditor::TNodeXYZ( face->GetNode(i) ));
+      aContour->Append( SMESH_TNodeXYZ( face->GetNode(i) ));
     if( HasIntersection(P, PC, Pres, aContour) ) {
       res = true;
       double tmp = PC.Distance(Pres);
@@ -521,7 +518,6 @@ int StdMeshers_QuadToTriaAdaptor::Preparation(const SMDS_MeshElement*       face
 {
   if( face->NbCornerNodes() != 4 )
   {
-    //myNbTriangles += int( face->NbCornerNodes() == 3 );
     return NOT_QUAD;
   }
 
@@ -529,12 +525,11 @@ int StdMeshers_QuadToTriaAdaptor::Preparation(const SMDS_MeshElement*       face
   gp_XYZ xyzC(0., 0., 0.);
   for ( i = 0; i < 4; ++i )
   {
-    gp_XYZ p = SMESH_MeshEditor::TNodeXYZ( FNodes[i] = face->GetNode(i) );
+    gp_XYZ p = SMESH_TNodeXYZ( FNodes[i] = face->GetNode(i) );
     PN->SetValue( i+1, p );
     xyzC += p;
   }
   PC = xyzC/4;
-  //cout<<"  PC("<<PC.X()<<","<<PC.Y()<<","<<PC.Z()<<")"<<endl;
 
   int nbp = 4;
 
@@ -882,7 +877,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh)
         if(F==face) continue;
         Handle(TColgp_HSequenceOfPnt) aContour = new TColgp_HSequenceOfPnt;
         for ( int i = 0; i < 4; ++i )
-          aContour->Append( SMESH_MeshEditor::TNodeXYZ( F->GetNode(i) ));
+          aContour->Append( SMESH_TNodeXYZ( F->GetNode(i) ));
         gp_Pnt PPP;
         if( !volumes[0] && HasIntersection(Ptmp1, PC, PPP, aContour) ) {
           IsOK1 = true;
@@ -970,7 +965,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh)
       Handle(TColgp_HSequenceOfPnt) aContour = new TColgp_HSequenceOfPnt;
       int nbN = F->NbNodes() / ( F->IsQuadratic() ? 2 : 1 );
       for ( i = 0; i < nbN; ++i )
-        aContour->Append( SMESH_MeshEditor::TNodeXYZ( F->GetNode(i) ));
+        aContour->Append( SMESH_TNodeXYZ( F->GetNode(i) ));
       gp_Pnt intP;
       for ( int isRev = 0; isRev < 2; ++isRev )
       {
@@ -1062,18 +1057,20 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh&
     for(k=0; k<5; k++) // loop on 4 base nodes of PrmI
     {
       const SMDS_MeshNode* n = PrmI->GetNode(k);
-      PsI[k] = SMESH_MeshEditor::TNodeXYZ( n );
+      PsI[k] = SMESH_TNodeXYZ( n );
       SMDS_ElemIteratorPtr vIt = n->GetInverseElementIterator( SMDSAbs_Volume );
       while ( vIt->more() )
-        checkedPyrams.insert( vIt->next() );
+      {
+        const SMDS_MeshElement* PrmJ = vIt->next();
+        if ( SMESH_Algo::GetCommonNodes( PrmI, PrmJ ).size() > 1 )
+          checkedPyrams.insert( PrmJ );
+      }
     }
 
     // check intersection with distant pyramids
     for(k=0; k<4; k++) // loop on 4 base nodes of PrmI
     {
       gp_Vec Vtmp(PsI[k],PsI[4]);
-      gp_Pnt Pshift = PsI[k].XYZ() + Vtmp.XYZ() * 0.01; // base node moved a bit to apex
-
       gp_Ax1 line( PsI[k], Vtmp );
       vector< const SMDS_MeshElement* > suspectPyrams;
       searcher->GetElementsNearLine( line, SMDSAbs_Volume, suspectPyrams);
@@ -1094,12 +1091,16 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh&
         vector<gp_Pnt> PsJ( xyzIt, TXyzIterator() );
 
         gp_Pnt Pint;
-        bool hasInt = 
+        bool hasInt=false;
+        for(k=0; k<4 && !hasInt; k++) {
+          gp_Vec Vtmp(PsI[k],PsI[4]);
+          gp_Pnt Pshift = PsI[k].XYZ() + Vtmp.XYZ() * 0.01; // base node moved a bit to apex
+          hasInt = 
           ( HasIntersection3( Pshift, PsI[4], Pint, PsJ[0], PsJ[1], PsJ[4]) ||
             HasIntersection3( Pshift, PsI[4], Pint, PsJ[1], PsJ[2], PsJ[4]) ||
             HasIntersection3( Pshift, PsI[4], Pint, PsJ[2], PsJ[3], PsJ[4]) ||
             HasIntersection3( Pshift, PsI[4], Pint, PsJ[3], PsJ[0], PsJ[4]) );
-
+        }
         for(k=0; k<4 && !hasInt; k++) {
           gp_Vec Vtmp(PsJ[k],PsJ[4]);
           gp_Pnt Pshift = PsJ[k].XYZ() + Vtmp.XYZ() * 0.01;
@@ -1202,14 +1203,3 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh&
   return true;
 }
 
-//================================================================================
-/*!
- * \brief Return list of created triangles for given face
- */
-//================================================================================
-
-// const list<const SMDS_MeshFace* >* StdMeshers_QuadToTriaAdaptor::GetTriangles (const SMDS_MeshElement* aQuad)
-// {
-//   TQuad2Trias::iterator it = myResMap.find(aQuad);
-//   return ( it != myResMap.end() ?  & it->second : 0 );
-// }