Salome HOME
correct the preceeding patch
[modules/smesh.git] / src / StdMeshers / StdMeshers_QuadToTriaAdaptor.cxx
index bd0198e0e8685b52b31fbd4706fb1119b0a39c83..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
@@ -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;
       }
@@ -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;
@@ -133,12 +131,15 @@ namespace
       // check order of baseNodes within pyramids, it must be opposite
       int dInd;
       dInd = baseNodesIndI[1] - baseNodesIndI[0];
-      isOutI = ( abs(dInd)==1 ) ? dInd < 0 : dInd > 0;
+      bool isOutI = ( abs(dInd)==1 ) ? dInd < 0 : dInd > 0;
       dInd = baseNodesIndJ[1] - baseNodesIndJ[0];
-      isOutJ = ( abs(dInd)==1 ) ? dInd < 0 : dInd > 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;
@@ -153,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 ||
@@ -161,7 +165,6 @@ namespace
 
         // check projections of face direction (baOFN) to triange normals (nI and nJ)
         gp_Vec baOFN( base1, SMESH_TNodeXYZ( otherFaceNode ));
-        ( isOutI ? nJ : nI ).Reverse();
         if ( nI * baOFN > 0 && nJ * baOFN > 0 )
         {
           tooClose = false; // f is between pyramids
@@ -185,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 );
+  //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 );
+  //int nbI = CommonNode->NbInverseElements( SMDSAbs_Volume );
   SMESH_TNodeXYZ Pi( CommonNode );
-  gp_XYZ Pnew = ( nbI*Pi + nbJ*Pj ) / (nbI+nbJ);
+  gp_XYZ Pnew = /*( nbI*Pi + nbJ*Pj ) / (nbI+nbJ);*/ 0.5 * ( Pi + Pj );
   CommonNode->setXYZ( Pnew.X(), Pnew.Y(), Pnew.Z() );
 
   nodesToMove.insert( CommonNode );
@@ -1057,15 +1060,17 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh&
       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);
@@ -1086,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;
@@ -1194,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 );
-// }