Salome HOME
PAL10467. Add "Quadrangle Preference" hypothesis for "Quadrangle(Mapping)" algo
[modules/smesh.git] / src / StdMeshers / StdMeshers_Quadrangle_2D.cxx
index da6b6a2e4ebff1db3d8a6f701705963ff33e7329..e40390c6e7596e5b8d8b383853bdb07825eb616e 100644 (file)
@@ -67,8 +67,8 @@ StdMeshers_Quadrangle_2D::StdMeshers_Quadrangle_2D (int hypId, int studyId, SMES
 {
   MESSAGE("StdMeshers_Quadrangle_2D::StdMeshers_Quadrangle_2D");
   _name = "Quadrangle_2D";
-  //  _shapeType = TopAbs_FACE;
   _shapeType = (1 << TopAbs_FACE);
+  _compatibleHypothesis.push_back("QuadranglePreference");
 }
 
 //=============================================================================
@@ -89,16 +89,16 @@ StdMeshers_Quadrangle_2D::~StdMeshers_Quadrangle_2D()
 //=============================================================================
 
 bool StdMeshers_Quadrangle_2D::CheckHypothesis
-                         (SMESH_Mesh& aMesh,
-                          const TopoDS_Shape& aShape,
+                         (SMESH_Mesh&                          aMesh,
+                          const TopoDS_Shape&                  aShape,
                           SMESH_Hypothesis::Hypothesis_Status& aStatus)
 {
-  //MESSAGE("StdMeshers_Quadrangle_2D::CheckHypothesis");
-
   bool isOk = true;
   aStatus = SMESH_Hypothesis::HYP_OK;
 
-  // nothing to check
+  // there is only one compatible Hypothesis so far
+  const list <const SMESHDS_Hypothesis * >&hyps = GetUsedHypothesis(aMesh, aShape);
+  myQuadranglePreference = hyps.size() > 0;
 
   return isOk;
 }
@@ -125,31 +125,18 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
 
   int nbdown  = quad->nbPts[0];
   int nbup    = quad->nbPts[2];
-//  bool isDownOut = (nbdown > nbup);
-//  bool isUpOut   = (nbdown < nbup);
 
   int nbright = quad->nbPts[1];
   int nbleft  = quad->nbPts[3];
-//  bool isRightOut = (nbright > nbleft);
-//  bool isLeftOut  = (nbright < nbleft);
 
   int nbhoriz  = Min(nbdown, nbup);
   int nbvertic = Min(nbright, nbleft);
 
-  int nbVertices = nbhoriz * nbvertic;
-  int nbQuad = (nbhoriz - 1) * (nbvertic - 1);
-  //SCRUTE(nbVertices);
-  //SCRUTE(nbQuad);
-
-  //   const TopoDS_Face& FF = TopoDS::Face(aShape);
-  //   bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD);
-  //   TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
   const TopoDS_Face& F = TopoDS::Face(aShape);
-  bool faceIsForward = (F.Orientation() == TopAbs_FORWARD);
   Handle(Geom_Surface) S = BRep_Tool::Surface(F);
 
   // internal mesh nodes
-  int i, j;
+  int i, j, geomFaceID = meshDS->ShapeToIndex( F );
   for (i = 1; i < nbhoriz - 1; i++) {
     for (j = 1; j < nbvertic - 1; j++) {
       int ij = j * nbhoriz + i;
@@ -157,12 +144,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
       double v = quad->uv_grid[ij].v;
       gp_Pnt P = S->Value(u, v);
       SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z());
-      meshDS->SetNodeOnFace(node, F);
+      meshDS->SetNodeOnFace(node, geomFaceID, u, v);
       quad->uv_grid[ij].node = node;
-      SMDS_FacePosition* fpos =
-        dynamic_cast<SMDS_FacePosition*>(node->GetPosition().get());
-      fpos->SetUParameter(u);
-      fpos->SetVParameter(v);
     }
   }
 
@@ -190,7 +173,6 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
   if (quad->isEdgeOut[0]) { jlow++; } else { if (quad->isEdgeOut[2]) jup--; }
 
   // regular quadrangles
-  //   bool isQuadForward = ( faceIsForward == quad->isEdgeForward[0]);
   for (i = ilow; i < iup; i++) {
     for (j = jlow; j < jup; j++) {
       const SMDS_MeshNode *a, *b, *c, *d;
@@ -198,10 +180,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
       b = quad->uv_grid[j * nbhoriz + i + 1].node;
       c = quad->uv_grid[(j + 1) * nbhoriz + i + 1].node;
       d = quad->uv_grid[(j + 1) * nbhoriz + i].node;
-      //  if (isQuadForward) faceId = meshDS->AddFace(a,b,c,d);
-      //  else faceId = meshDS->AddFace(a,d,c,b);
       SMDS_MeshFace * face = meshDS->AddFace(a, b, c, d);
-      meshDS->SetMeshElementOnShape(face, F);
+      meshDS->SetMeshElementOnShape(face, geomFaceID);
     }
   }
 
@@ -272,14 +252,14 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
 
       if (near == g) { // make triangle
         SMDS_MeshFace* face = meshDS->AddFace(a, b, c);
-        meshDS->SetMeshElementOnShape(face, F);
+        meshDS->SetMeshElementOnShape(face, geomFaceID);
       } else { // make quadrangle
         if (near - 1 < ilow)
           d = uv_e3[1].node;
         else
           d = quad->uv_grid[nbhoriz + near - 1].node;
         SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d);
-        meshDS->SetMeshElementOnShape(face, F);
+        meshDS->SetMeshElementOnShape(face, geomFaceID);
 
         // if node d is not at position g - make additional triangles
         if (near - 1 > g) {
@@ -290,7 +270,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
             else
               d = quad->uv_grid[nbhoriz + k - 1].node;
             SMDS_MeshFace* face = meshDS->AddFace(a, c, d);
-            meshDS->SetMeshElementOnShape(face, F);
+            meshDS->SetMeshElementOnShape(face, geomFaceID);
           }
         }
         g = near;
@@ -352,14 +332,14 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
 
         if (near == g) { // make triangle
           SMDS_MeshFace* face = meshDS->AddFace(a, b, c);
-          meshDS->SetMeshElementOnShape(face, F);
+          meshDS->SetMeshElementOnShape(face, geomFaceID);
         } else { // make quadrangle
           if (near + 1 > iup)
             d = uv_e1[nbright - 2].node;
           else
             d = quad->uv_grid[nbhoriz*(nbvertic - 2) + near + 1].node;
           SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d);
-          meshDS->SetMeshElementOnShape(face, F);
+          meshDS->SetMeshElementOnShape(face, geomFaceID);
 
           if (near + 1 < g) { // if d not is at g - make additional triangles
             for (int k = near + 1; k < g; k++) {
@@ -369,7 +349,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
               else
                 d = quad->uv_grid[nbhoriz*(nbvertic - 2) + k + 1].node;
               SMDS_MeshFace* face = meshDS->AddFace(a, c, d);
-              meshDS->SetMeshElementOnShape(face, F);
+              meshDS->SetMeshElementOnShape(face, geomFaceID);
             }
           }
           g = near;
@@ -417,14 +397,14 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
 
       if (near == g) { // make triangle
         SMDS_MeshFace* face = meshDS->AddFace(a, b, c);
-        meshDS->SetMeshElementOnShape(face, F);
+        meshDS->SetMeshElementOnShape(face, geomFaceID);
       } else { // make quadrangle
         if (near - 1 < jlow)
           d = uv_e0[nbdown - 2].node;
         else
           d = quad->uv_grid[nbhoriz*near - 2].node;
         SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d);
-        meshDS->SetMeshElementOnShape(face, F);
+        meshDS->SetMeshElementOnShape(face, geomFaceID);
 
         if (near - 1 > g) { // if d not is at g - make additional triangles
           for (int k = near - 1; k > g; k--) {
@@ -434,7 +414,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
             else
               d = quad->uv_grid[nbhoriz*k - 2].node;
             SMDS_MeshFace* face = meshDS->AddFace(a, c, d);
-            meshDS->SetMeshElementOnShape(face, F);
+            meshDS->SetMeshElementOnShape(face, geomFaceID);
           }
         }
         g = near;
@@ -479,14 +459,14 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
 
         if (near == g) { // make triangle
           SMDS_MeshFace* face = meshDS->AddFace(a, b, c);
-          meshDS->SetMeshElementOnShape(face, F);
+          meshDS->SetMeshElementOnShape(face, geomFaceID);
         } else { // make quadrangle
           if (near + 1 > jup)
             d = uv_e2[1].node;
           else
             d = quad->uv_grid[nbhoriz*(near + 1) + 1].node;
           SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d);
-          meshDS->SetMeshElementOnShape(face, F);
+          meshDS->SetMeshElementOnShape(face, geomFaceID);
 
           if (near + 1 < g) { // if d not is at g - make additional triangles
             for (int k = near + 1; k < g; k++) {
@@ -496,7 +476,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
               else
                 d = quad->uv_grid[nbhoriz*(k + 1) + 1].node;
               SMDS_MeshFace* face = meshDS->AddFace(a, c, d);
-              meshDS->SetMeshElementOnShape(face, F);
+              meshDS->SetMeshElementOnShape(face, geomFaceID);
             }
           }
           g = near;
@@ -520,26 +500,16 @@ FaceQuadStruct *StdMeshers_Quadrangle_2D::CheckAnd2Dcompute
   (SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
-//  MESSAGE("StdMeshers_Quadrangle_2D::CheckAnd2Dcompute");
-
-  SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape);
 
-  //   const TopoDS_Face& FF = TopoDS::Face(aShape);
-  //   bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD);
-  //   TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
   const TopoDS_Face & F = TopoDS::Face(aShape);
-  bool faceIsForward = (F.Orientation() == TopAbs_FORWARD);
 
   // verify 1 wire only, with 4 edges
 
   if (NumberOfWires(F) != 1)
   {
-    MESSAGE("only 1 wire by face (quadrangles)");
+    INFOS("only 1 wire by face (quadrangles)");
     return 0;
-    //throw SALOME_Exception(LOCALIZED("only 1 wire by face (quadrangles)"));
   }
-  //   const TopoDS_Wire WW = BRepTools::OuterWire(F);
-  //   TopoDS_Wire W = TopoDS::Wire(WW.Oriented(TopAbs_FORWARD));
   const TopoDS_Wire& W = BRepTools::OuterWire(F);
   BRepTools_WireExplorer wexp (W, F);
 
@@ -551,8 +521,6 @@ FaceQuadStruct *StdMeshers_Quadrangle_2D::CheckAnd2Dcompute
   int nbEdges = 0;
   for (wexp.Init(W, F); wexp.More(); wexp.Next())
   {
-    //       const TopoDS_Edge& EE = wexp.Current();
-    //       TopoDS_Edge E = TopoDS::Edge(EE.Oriented(TopAbs_FORWARD));
     const TopoDS_Edge& E = wexp.Current();
     int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
     if (nbEdges < 4)
@@ -565,26 +533,11 @@ FaceQuadStruct *StdMeshers_Quadrangle_2D::CheckAnd2Dcompute
 
   if (nbEdges != 4)
   {
-    MESSAGE("face must have 4 edges /quadrangles");
+    INFOS("face must have 4 edges /quadrangles");
     QuadDelete(quad);
     return 0;
-    //throw SALOME_Exception(LOCALIZED("face must have 4 edges /quadrangles"));
   }
 
-//  if (quad->nbPts[0] != quad->nbPts[2]) {
-//    MESSAGE("different point number-opposed edge");
-//    QuadDelete(quad);
-//    return 0;
-//    //throw SALOME_Exception(LOCALIZED("different point number-opposed edge"));
-//  }
-//
-//  if (quad->nbPts[1] != quad->nbPts[3]) {
-//    MESSAGE("different point number-opposed edge");
-//    QuadDelete(quad);
-//    return 0;
-//    //throw SALOME_Exception(LOCALIZED("different point number-opposed edge"));
-//  }
-
   // set normalized grid on unit square in parametric domain
 
   SetNormalizedGrid(aMesh, F, quad);
@@ -660,10 +613,11 @@ void StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh,
     quad->isEdgeForward[i] = false;
   }
 
-  double eps2d = 1.e-3; // *** utiliser plutot TopExp::CommonVertex, puis
-  // distances si piece fausse
-//  int i = 0;
-  if ((pf[1].Distance(pl[0]) < eps2d) || (pl[1].Distance(pl[0]) < eps2d))
+  double l0f1 = pl[0].SquareDistance(pf[1]);
+  double l0l1 = pl[0].SquareDistance(pl[1]);
+  double f0f1 = pf[0].SquareDistance(pf[1]);
+  double f0l1 = pf[0].SquareDistance(pl[1]);
+  if ( Min( l0f1, l0l1 ) < Min ( f0f1, f0l1 ))
   {
     quad->isEdgeForward[0] = true;
   } else {
@@ -673,10 +627,11 @@ void StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh,
     pf[0] = c2d[0]->Value(quad->first[0]);
     pl[0] = c2d[0]->Value(quad->last[0]);
   }
-
   for (int i = 1; i < 4; i++)
   {
-    quad->isEdgeForward[i] = (pf[i].Distance(pl[i - 1]) < eps2d);
+    l0l1 = pl[i - 1].SquareDistance(pl[i]);
+    l0f1 = pl[i - 1].SquareDistance(pf[i]);
+    quad->isEdgeForward[i] = ( l0f1 < l0l1 );
     if (!quad->isEdgeForward[i])
     {
       double tmp = quad->first[i];
@@ -684,19 +639,8 @@ void StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh,
       quad->last[i] = tmp;
       pf[i] = c2d[i]->Value(quad->first[i]);
       pl[i] = c2d[i]->Value(quad->last[i]);
-      //SCRUTE(pf[i].Distance(pl[i-1]));
-      ASSERT(pf[i].Distance(pl[i - 1]) < eps2d);
     }
   }
-  //SCRUTE(pf[0].Distance(pl[3]));
-  ASSERT(pf[0].Distance(pl[3]) < eps2d);
-
-//   for (int i=0; i<4; i++)
-//     {
-//       SCRUTE(quad->isEdgeForward[i]);
-//       MESSAGE(" -first "<<i<<" "<<pf[i].X()<<" "<<pf[i].Y());
-//       MESSAGE(" -last  "<<i<<" "<<pl[i].X()<<" "<<pl[i].Y());
-//     }
 
   // 2 --- load 2d edge points (u,v) with orientation and value on unit square
 
@@ -706,7 +650,6 @@ void StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh,
     quad->uv_edges[i] = LoadEdgePoints(aMesh, F, quad->edge[i],
                                        quad->first[i], quad->last[i]);
     if (!quad->uv_edges[i]) loadOk = false;
-    //    quad->isEdgeForward[i]);
   }
 
   for (int i = 2; i < 4; i++)
@@ -714,23 +657,19 @@ void StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh,
     quad->uv_edges[i] = LoadEdgePoints(aMesh, F, quad->edge[i],
                                        quad->last[i], quad->first[i]);
     if (!quad->uv_edges[i]) loadOk = false;
-    //    !quad->isEdgeForward[i]);
   }
 
   if (!loadOk)
   {
-//    MESSAGE("StdMeshers_Quadrangle_2D::SetNormalizedGrid - LoadEdgePoints failed");
+    INFOS("StdMeshers_Quadrangle_2D::SetNormalizedGrid - LoadEdgePoints failed");
     QuadDelete( quad );
     quad = 0;
     return;
   }
   // 3 --- 2D normalized values on unit square [0..1][0..1]
 
-//  int nbdown = quad->nbPts[0];
-//  int nbright = quad->nbPts[1];
   int nbhoriz  = Min(quad->nbPts[0], quad->nbPts[2]);
   int nbvertic = Min(quad->nbPts[1], quad->nbPts[3]);
-//  MESSAGE("nbhoriz, nbvertic = " << nbhoriz << nbvertic);
 
   quad->isEdgeOut[0] = (quad->nbPts[0] > quad->nbPts[2]);
   quad->isEdgeOut[1] = (quad->nbPts[1] > quad->nbPts[3]);
@@ -846,8 +785,6 @@ void StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh,
 
       uv_grid[ij].u = u;
       uv_grid[ij].v = v;
-
-      //MESSAGE("-uv- "<<i<<" "<<j<<" "<<uv_grid[ij].u<<" "<<uv_grid[ij].v);
     }
   }
 }
@@ -865,8 +802,6 @@ UVPtStruct* StdMeshers_Quadrangle_2D::LoadEdgePoints (SMESH_Mesh & aMesh,
 {
   //MESSAGE("StdMeshers_Quadrangle_2D::LoadEdgePoints");
 
-  SMDS_Mesh* meshDS = aMesh.GetMeshDS();
-
   // --- IDNodes of first and last Vertex
 
   TopoDS_Vertex VFirst, VLast;
@@ -982,7 +917,6 @@ UVPtStruct* StdMeshers_Quadrangle_2D::LoadEdgePoints (SMESH_Mesh & aMesh,
   for (int i = 0; i < nbPoints + 2; i++)
   {
     uvslf[i].normParam = (uvslf[i].param - paramin) / (paramax - paramin);
-    //SCRUTE(uvslf[i].normParam);
   }
 
   return uvslf;