Salome HOME
0022098: EDF 2036 SMESH: Create groups from none conected parts of a mesh
[modules/smesh.git] / src / StdMeshers / StdMeshers_QuadToTriaAdaptor.cxx
index 5764cc6eac0520dda5a7f2a24ae226c59a627b0d..c69fa9e7a5bea43830f733f4a71cf4c917550b1b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 
 #include "SMDS_SetIterator.hxx"
 
+#include "SMESHDS_GroupBase.hxx"
 #include "SMESH_Algo.hxx"
+#include "SMESH_Group.hxx"
+#include "SMESH_MeshAlgos.hxx"
 #include "SMESH_MesherHelper.hxx"
 
 #include <IntAna_IntConicQuad.hxx>
@@ -38,7 +41,9 @@
 #include <TopoDS.hxx>
 #include <gp_Lin.hxx>
 #include <gp_Pln.hxx>
+#include "utilities.h"
 
+#include <string>
 #include <numeric>
 #include <limits>
 
@@ -145,8 +150,8 @@ namespace
       TIDSortedElemSet emptySet, avoidSet;
       int i1, i2;
       while ( const SMDS_MeshElement* f =
-              SMESH_MeshEditor::FindFaceInSet( baseNodes[0], baseNodes[1],
-                                               emptySet, avoidSet, &i1, &i2 ))
+              SMESH_MeshAlgos::FindFaceInSet( baseNodes[0], baseNodes[1],
+                                              emptySet, avoidSet, &i1, &i2 ))
       {
         avoidSet.insert( f );
 
@@ -224,7 +229,7 @@ namespace
           }
         }
 
-      // Within pyramids, replace nodes to remove by nodes to keep  
+      // Within pyramids, replace nodes to remove by nodes to keep
 
       for ( unsigned i = 0; i < pyrams.size(); ++i )
       {
@@ -281,7 +286,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 container 
+    // copy inverse elements to avoid iteration on changing container
     ( TStdElemIterator( CommonNode->GetInverseElementIterator(SMDSAbs_Face)), itEnd);
   for ( unsigned i = 0; i < inverseElems.size(); ++i )
   {
@@ -538,7 +543,7 @@ bool StdMeshers_QuadToTriaAdaptor::CheckIntersection (const gp_Pnt&       P,
                                                       const SMDS_MeshElement* NotCheckedFace)
 {
   if ( !myElemSearcher )
-    myElemSearcher = SMESH_MeshEditor(&aMesh).GetElementSearcher();
+    myElemSearcher = SMESH_MeshAlgos::GetElementSearcher( *aMesh.GetMeshDS() );
   SMESH_ElementSearcher* searcher = const_cast<SMESH_ElementSearcher*>(myElemSearcher);
 
   //SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
@@ -550,13 +555,13 @@ bool StdMeshers_QuadToTriaAdaptor::CheckIntersection (const gp_Pnt&       P,
   gp_Ax1 line( P, gp_Vec(P,PC));
   vector< const SMDS_MeshElement* > suspectElems;
   searcher->GetElementsNearLine( line, SMDSAbs_Face, suspectElems);
-  
+
   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 ) 
+    for ( int i = 0; i < face->NbCornerNodes(); ++i )
       aContour->Append( SMESH_TNodeXYZ( face->GetNode(i) ));
     if( HasIntersection(P, PC, Pres, aContour) ) {
       res = true;
@@ -702,7 +707,7 @@ int StdMeshers_QuadToTriaAdaptor::Preparation(const SMDS_MeshElement*       face
 
 //=======================================================================
 //function : Compute
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh&         aMesh,
@@ -726,9 +731,9 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh&         aMesh,
 
   if ( myElemSearcher ) delete myElemSearcher;
   if ( aProxyMesh )
-    myElemSearcher = SMESH_MeshEditor(&aMesh).GetElementSearcher( aProxyMesh->GetFaces(aShape));
+    myElemSearcher = SMESH_MeshAlgos::GetElementSearcher( *meshDS, aProxyMesh->GetFaces(aShape));
   else
-    myElemSearcher = SMESH_MeshEditor(&aMesh).GetElementSearcher();
+    myElemSearcher = SMESH_MeshAlgos::GetElementSearcher( *meshDS );
 
   const SMESHDS_SubMesh * aSubMeshDSFace;
   Handle(TColgp_HArray1OfPnt) PN = new TColgp_HArray1OfPnt(1,5);
@@ -752,7 +757,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh&         aMesh,
     {
       bool isRev = false;
       if ( helper.NbAncestors( aShapeFace, aMesh, aShape.ShapeType() ) > 1 )
-        isRev = SMESH_Algo::IsReversedSubMesh( TopoDS::Face(aShapeFace), meshDS );
+        isRev = helper.IsReversedSubMesh( TopoDS::Face(aShapeFace) );
 
       SMDS_ElemIteratorPtr iteratorElem = aSubMeshDSFace->GetElements();
       while ( iteratorElem->more() ) // loop on elements on a geometrical face
@@ -875,7 +880,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh&         aMesh,
 
           delete myElemSearcher;
           myElemSearcher =
-            SMESH_MeshEditor(&aMesh).GetElementSearcher( aProxyMesh->GetFaces(aShape));
+            SMESH_MeshAlgos::GetElementSearcher( *meshDS, aProxyMesh->GetFaces(aShape));
         }
       }
     }
@@ -898,20 +903,50 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh)
   if ( aMesh.NbQuadrangles() < 1 )
     return false;
 
+  // find if there is a group of faces identified as skin faces, with normal going outside the volume
+  std::string groupName = "skinFaces";
+  SMESHDS_GroupBase* groupDS = 0;
+  SMESH_Mesh::GroupIteratorPtr groupIt = aMesh.GetGroups();
+  while ( groupIt->more() )
+    {
+      groupDS = 0;
+      SMESH_Group * group = groupIt->next();
+      if ( !group ) continue;
+      groupDS = group->GetGroupDS();
+      if ( !groupDS || groupDS->IsEmpty() )
+      {
+        groupDS = 0;
+        continue;
+      }
+      if (groupDS->GetType() != SMDSAbs_Face)
+      {
+        groupDS = 0;
+        continue;
+      }
+      std::string grpName = group->GetName();
+      if (grpName == groupName)
+      {
+        MESSAGE("group skinFaces provided");
+        break;
+      }
+      else
+        groupDS = 0;
+    }
+
   vector<const SMDS_MeshElement*> myPyramids;
   SMESH_MesherHelper helper(aMesh);
   helper.IsQuadraticSubMesh(aMesh.GetShapeToMesh());
   helper.SetElementsOnShape( true );
 
-  if ( !myElemSearcher )
-    myElemSearcher = SMESH_MeshEditor(&aMesh).GetElementSearcher();
-  SMESH_ElementSearcher* searcher = const_cast<SMESH_ElementSearcher*>(myElemSearcher);
-
   SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
   SMESH_ProxyMesh::SubMesh* prxSubMesh = getProxySubMesh();
 
+  if ( !myElemSearcher )
+    myElemSearcher = SMESH_MeshAlgos::GetElementSearcher( *meshDS );
+  SMESH_ElementSearcher* searcher = const_cast<SMESH_ElementSearcher*>(myElemSearcher);
+
   SMDS_FaceIteratorPtr fIt = meshDS->facesIterator(/*idInceasingOrder=*/true);
-  while( fIt->more()) 
+  while( fIt->more())
   {
     const SMDS_MeshElement* face = fIt->next();
     if ( !face ) continue;
@@ -1003,7 +1038,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh)
       continue;
     }
 
-    // Case of non-degenerated quadrangle 
+    // Case of non-degenerated quadrangle
 
     // Find pyramid peak
 
@@ -1062,6 +1097,24 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh)
       }
     }
 
+    // if the face belong to the group of skinFaces, do not build a pyramid outside
+    if (groupDS && groupDS->Contains(face))
+    {
+      intersected[0] = false;
+    }
+    else if ( intersected[0] && intersected[1] ) // check if one of pyramids is in a hole
+    {
+      gp_Pnt P ( PC.XYZ() + tmpDir.XYZ() * 0.5 * PC.Distance( intPnt[0] ));
+      if ( searcher->GetPointState( P ) == TopAbs_OUT )
+        intersected[0] = false;
+      else
+      {
+        P = ( PC.XYZ() - tmpDir.XYZ() * 0.5 * PC.Distance( intPnt[1] ));
+        if ( searcher->GetPointState( P ) == TopAbs_OUT )
+          intersected[1] = false;
+      }
+    }
+
     // Create one or two pyramids
 
     for ( int isRev = 0; isRev < 2; ++isRev )
@@ -1112,7 +1165,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh&
   int i, j, k, myShapeID = myPyramids[0]->GetNode(4)->getshapeId();
 
   if ( myElemSearcher ) delete myElemSearcher;
-  myElemSearcher = SMESH_MeshEditor(&aMesh).GetElementSearcher();
+  myElemSearcher = SMESH_MeshAlgos::GetElementSearcher( *meshDS );
   SMESH_ElementSearcher* searcher = const_cast<SMESH_ElementSearcher*>(myElemSearcher);
 
   set<const SMDS_MeshNode*> nodesToMove;
@@ -1143,7 +1196,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh&
       while ( vIt->more() )
       {
         const SMDS_MeshElement* PrmJ = vIt->next();
-        if ( SMESH_Algo::GetCommonNodes( PrmI, PrmJ ).size() > 1 )
+        if ( SMESH_MeshAlgos::GetCommonNodes( PrmI, PrmJ ).size() > 1 )
           checkedPyrams.insert( PrmJ );
       }
     }
@@ -1176,7 +1229,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh&
         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 = 
+          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]) ||
@@ -1185,7 +1238,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh&
         for(k=0; k<4 && !hasInt; k++) {
           gp_Vec Vtmp(PsJ[k],PsJ[4]);
           gp_Pnt Pshift = PsJ[k].XYZ() + Vtmp.XYZ() * 0.01;
-          hasInt = 
+          hasInt =
             ( HasIntersection3( Pshift, PsJ[4], Pint, PsI[0], PsI[1], PsI[4]) ||
               HasIntersection3( Pshift, PsJ[4], Pint, PsI[1], PsI[2], PsI[4]) ||
               HasIntersection3( Pshift, PsJ[4], Pint, PsI[2], PsI[3], PsI[4]) ||
@@ -1215,7 +1268,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh&
               PCi += PsI[k].XYZ();
               PCj += PsJ[k].XYZ();
             }
-            PCi /= 4; PCj /= 4; 
+            PCi /= 4; PCj /= 4;
             gp_Vec VN1(PCi,PsI[4]);
             gp_Vec VN2(PCj,PsJ[4]);
             gp_Vec VI1(PCi,Pint);