Salome HOME
Update copyright info (2010->2011)
[plugins/blsurfplugin.git] / src / BLSURFPlugin / BLSURFPlugin_BLSURF.cxx
index 736ba52d598b6ed6246f9687b0d93d03fc196f65..4efd4f8bd0a1d1a9b64d08fbd510b7369585c9cc 100644 (file)
@@ -1,4 +1,4 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D
+//  Copyright (C) 2007-2011  CEA/DEN, EDF R&D
 //
 //  This library is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU Lesser General Public
@@ -16,6 +16,7 @@
 //
 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // ---
 // File    : BLSURFPlugin_BLSURF.cxx
 // Authors : Francis KLOSS (OCC) & Patrick LAUG (INRIA) & Lioka RAZAFINDRAZAKA (CEA)
@@ -39,6 +40,9 @@ extern "C"{
 #include <SMESH_Gen.hxx>
 #include <SMESH_Mesh.hxx>
 #include <SMESH_ControlsDef.hxx>
+#include <SMDSAbs_ElementType.hxx>
+#include "SMESHDS_Group.hxx"
+#include "SMESH_Group.hxx"
 
 #include <utilities.h>
 
@@ -210,6 +214,7 @@ std::map<int,std::vector<double> > FaceId2AttractorCoords;
 
 TopTools_IndexedMapOfShape FacesWithEnforcedVertices;
 std::map< int, std::set< std::vector<double> > > FaceId2EnforcedVertexCoords;
+std::map< std::vector<double>, std::vector<double> > EnfVertex2ProjVertex;
 
 bool HasSizeMapOnFace=false;
 bool HasSizeMapOnEdge=false;
@@ -242,7 +247,8 @@ BLSURFPlugin_BLSURF::BLSURFPlugin_BLSURF(int hypId, int studyId,
 
   myStudy = NULL;
   myStudy = aStudyMgr->GetStudyByID(_studyId);
-  MESSAGE("myStudy->StudyId() = " << myStudy->StudyId());
+  if (myStudy)
+    MESSAGE("myStudy->StudyId() = " << myStudy->StudyId());
 
   /* Initialize the Python interpreter */
   assert(Py_IsInitialized());
@@ -270,7 +276,7 @@ BLSURFPlugin_BLSURF::BLSURFPlugin_BLSURF(int hypId, int studyId,
   FaceId2AttractorCoords.clear();
   FacesWithEnforcedVertices.Clear();
   FaceId2EnforcedVertexCoords.clear();
-
+  EnfVertex2ProjVertex.clear();
 }
 
 //=============================================================================
@@ -413,19 +419,22 @@ TopoDS_Shape BLSURFPlugin_BLSURF::entryToShape(std::string entry)
 }
 
 /////////////////////////////////////////////////////////
-void createEnforcedVertexOnFace(TopoDS_Shape GeomShape, BLSURFPlugin_Hypothesis::TEnforcedVertexList enforcedVertexList)
+void createEnforcedVertexOnFace(TopoDS_Shape GeomShape, BLSURFPlugin_Hypothesis::TEnfVertexList enfVertexList)
 {
   double xe, ye, ze;
   std::vector<double> coords;
-  BLSURFPlugin_Hypothesis::TEnforcedVertex enforcedVertex;
-  BLSURFPlugin_Hypothesis::TEnforcedVertexList::const_iterator evlIt = enforcedVertexList.begin();
+  std::vector<double> s_coords;
+  std::vector<double> enfVertex;
+//   BLSURFPlugin_Hypothesis::TEnfVertex enfVertex;
+  BLSURFPlugin_Hypothesis::TEnfVertexList::const_iterator evlIt = enfVertexList.begin();
 
-  for( ; evlIt != enforcedVertexList.end() ; ++evlIt ) {
+  for( ; evlIt != enfVertexList.end() ; ++evlIt ) {
     coords.clear();
-    enforcedVertex = *evlIt;
-    xe = enforcedVertex[0];
-    ye = enforcedVertex[1];
-    ze = enforcedVertex[2];
+    s_coords.clear();
+    enfVertex = *evlIt;
+    xe = enfVertex[0];
+    ye = enfVertex[1];
+    ze = enfVertex[2];
     MESSAGE("Enforced Vertex: " << xe << ", " << ye << ", " << ze);
     // Get the (u,v) values of the enforced vertex on the face
     projectionPoint myPoint = getProjectionPoint(TopoDS::Face(GeomShape),gp_XYZ(xe,ye,ze));
@@ -437,12 +446,22 @@ void createEnforcedVertexOnFace(TopoDS_Shape GeomShape, BLSURFPlugin_Hypothesis:
     Standard_Real y0 = xyzPoint.Y();
     Standard_Real z0 = xyzPoint.Z();
     MESSAGE("Projected Vertex: " << x0 << ", " << y0 << ", " << z0);
+    MESSAGE("Parametric coordinates: " << u0 << ", " << v0 );
     coords.push_back(u0);
     coords.push_back(v0);
     coords.push_back(x0);
     coords.push_back(y0);
     coords.push_back(z0);
-  
+    
+    s_coords.push_back(x0);
+    s_coords.push_back(y0);
+    s_coords.push_back(z0);
+
+    // Save pair projected vertex / enf vertex
+    MESSAGE("Storing pair projected vertex / enf vertex:");
+    MESSAGE("("<< x0 << ", " << y0 << ", " << z0 <<") / (" << xe << ", " << ye << ", " << ze<<")");
+    EnfVertex2ProjVertex[s_coords] = enfVertex;
+    
     int key = 0;
     if (! FacesWithEnforcedVertices.Contains(TopoDS::Face(GeomShape))) {
       key = FacesWithEnforcedVertices.Add(TopoDS::Face(GeomShape));
@@ -573,7 +592,9 @@ void createAttractorOnFace(TopoDS_Shape GeomShape, std::string AttractorFunction
 
 /////////////////////////////////////////////////////////
 
-void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, blsurf_session_t *bls)
+void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp,
+                                        blsurf_session_t *             bls,
+                                        SMESH_Mesh&                   mesh)
 {
   int    _topology      = BLSURFPlugin_Hypothesis::GetDefaultTopology();
   int    _physicalMesh  = BLSURFPlugin_Hypothesis::GetDefaultPhysicalMesh();
@@ -617,6 +638,9 @@ void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, blsu
       }
 
   } else {
+    //0020968: EDF1545 SMESH: Problem in the creation of a mesh group on geometry
+    // GetDefaultPhySize() sometimes leads to computation failure
+    _phySize = mesh.GetShapeDiagonalSize() / _gen->GetBoundaryBoxSegmentation();
     MESSAGE("BLSURFPlugin_BLSURF::SetParameters using defaults");
   }
   _smp_phy_size = _phySize;
@@ -777,9 +801,9 @@ void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, blsu
     // Enforced Vertices
     //
     MESSAGE("Setting Enforced Vertices");
-    const BLSURFPlugin_Hypothesis::TEnforcedVertexMap enforcedVertexMap = BLSURFPlugin_Hypothesis::GetAllEnforcedVertices(hyp);
-    BLSURFPlugin_Hypothesis::TEnforcedVertexMap::const_iterator enfIt = enforcedVertexMap.begin();
-    for ( ; enfIt != enforcedVertexMap.end(); ++enfIt ) {
+    const BLSURFPlugin_Hypothesis::TEntryEnfVertexListMap entryEnfVertexListMap = BLSURFPlugin_Hypothesis::GetAllEnforcedVertices(hyp);
+    BLSURFPlugin_Hypothesis::TEntryEnfVertexListMap::const_iterator enfIt = entryEnfVertexListMap.begin();
+    for ( ; enfIt != entryEnfVertexListMap.end(); ++enfIt ) {
       if ( !enfIt->second.empty() ) {
         GeomShape = entryToShape(enfIt->first);
         GeomType  = GeomShape.ShapeType();
@@ -874,7 +898,7 @@ bool BLSURFPlugin_BLSURF::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape)
   VertexId2SizeMap.clear();
 
   MESSAGE("BEGIN SetParameters");
-  SetParameters(_hypothesis, bls);
+  SetParameters(_hypothesis, bls, aMesh);
   MESSAGE("END SetParameters");
 
   /* Now fill the CAD object with data from your CAD
@@ -912,8 +936,13 @@ bool BLSURFPlugin_BLSURF::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape)
   int iface = 0;
   string bad_end = "return";
   int faceKey = -1;
+  int ienf = 0;
   for (TopExp_Explorer face_iter(aShape,TopAbs_FACE);face_iter.More();face_iter.Next()) {
     TopoDS_Face f=TopoDS::Face(face_iter.Current());
+
+    // make INTERNAL face oriented FORWARD (issue 0020993)
+    if (f.Orientation() != TopAbs_FORWARD && f.Orientation() != TopAbs_REVERSED )
+      f.Orientation(TopAbs_FORWARD);
     
     if (fmap.FindIndex(f) > 0)
       continue;
@@ -941,7 +970,7 @@ bool BLSURFPlugin_BLSURF::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape)
     }
     
     if (HasSizeMapOnFace){
-      std::cout << "A size map is defined on a face" << std::endl;
+//       std::cout << "A size map is defined on a face" << std::endl;
       // Classic size map
       faceKey = FacesWithSizeMap.FindIndex(f);
       
@@ -1004,22 +1033,21 @@ bool BLSURFPlugin_BLSURF::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape)
       faceKey = FacesWithEnforcedVertices.FindIndex(f);
       std::map<int,std::set<std::vector<double> > >::const_iterator evmIt = FaceId2EnforcedVertexCoords.find(faceKey);
       if (evmIt != FaceId2EnforcedVertexCoords.end()) {
-        std::cout << "Some enforced vertices are defined" << std::endl;
-        int ienf = 0;
+        MESSAGE("Some enforced vertices are defined");
+//         int ienf = 0;
         std::set<std::vector<double> > evl;
 //         std::vector<double> ev;
         MESSAGE("Face indice: " << iface);
         MESSAGE("Adding enforced vertices");
         evl = evmIt->second;
-        MESSAGE("Number of vertices to add: "<< evl.size())
+        MESSAGE("Number of vertices to add: "<< evl.size());
         std::set< std::vector<double> >::const_iterator evlIt = evl.begin();
         for (; evlIt != evl.end(); ++evlIt) {
-//           ev = *evlIt;
-//         for (int i=0; i<evl.size() ; i++) {
-//           ev = evl[i];
-          
-//           double xyzCoords[3]  = {ev[2], ev[3], ev[4]};
-          double xyzCoords[3]  = {evlIt->at(0), evlIt->at(3), evlIt->at(4)};
+          std::vector<double> xyzCoords;
+          xyzCoords.push_back(evlIt->at(2));
+          xyzCoords.push_back(evlIt->at(3));
+          xyzCoords.push_back(evlIt->at(4));
+//           double xyzCoords[3]  = {evlIt->at(2), evlIt->at(3), evlIt->at(4)};
           MESSAGE("Check position of vertex =(" << xyzCoords[0] << "," << xyzCoords[1] << "," << xyzCoords[2] << ")");
           gp_Pnt P(xyzCoords[0],xyzCoords[1],xyzCoords[2]);
           BRepClass_FaceClassifier scl(f,P,1e-7);
@@ -1028,12 +1056,21 @@ bool BLSURFPlugin_BLSURF::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape)
           BRepClass_FaceClassifierPerform(&scl,f,P,1e-7);
           TopAbs_State result = scl.State();
           MESSAGE("Position of point on face: "<<result);
-          if ( result == TopAbs_OUT )
+          if ( result == TopAbs_OUT ) {
               MESSAGE("Point is out of face: node is not created");
-          if ( result == TopAbs_UNKNOWN )
-              MESSAGE("Point position on face is unknown: node is not created");
-          if ( result == TopAbs_ON )
-              MESSAGE("Point is on border of face: node is not created");
+              if (EnfVertex2ProjVertex.find(xyzCoords) != EnfVertex2ProjVertex.end())
+                EnfVertex2ProjVertex.erase(xyzCoords);
+          }
+          if ( result == TopAbs_UNKNOWN ) {
+            MESSAGE("Point position on face is unknown: node is not created");
+            if (EnfVertex2ProjVertex.find(xyzCoords) != EnfVertex2ProjVertex.end())
+              EnfVertex2ProjVertex.erase(xyzCoords);
+          }
+          if ( result == TopAbs_ON ) {
+            MESSAGE("Point is on border of face: node is not created");
+            if (EnfVertex2ProjVertex.find(xyzCoords) != EnfVertex2ProjVertex.end())
+              EnfVertex2ProjVertex.erase(xyzCoords);
+          }
           if ( result == TopAbs_IN )
           {
             // Point is inside face and not on border
@@ -1048,8 +1085,8 @@ bool BLSURFPlugin_BLSURF::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape)
         }
         FaceId2EnforcedVertexCoords.erase(faceKey);
       }
-      else
-        std::cout << "No enforced vertex defined" << std::endl;
+//       else
+//         std::cout << "No enforced vertex defined" << std::endl;
     }
     
     
@@ -1070,7 +1107,7 @@ bool BLSURFPlugin_BLSURF::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape)
       if (HasSizeMapOnEdge){
         edgeKey = EdgesWithSizeMap.FindIndex(e);
         if (EdgeId2SizeMap.find(edgeKey)!=EdgeId2SizeMap.end()) {
-         MESSAGE("Sizemap defined on edge with index " << edgeKey);
+          MESSAGE("Sizemap defined on edge with index " << edgeKey);
           theSizeMapStr = EdgeId2SizeMap[edgeKey];
           if (theSizeMapStr.find(bad_end) == (theSizeMapStr.size()-bad_end.size()-1))
             continue;
@@ -1240,13 +1277,87 @@ bool BLSURFPlugin_BLSURF::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape)
     mesh_get_vertex_coordinates(msh, iv, xyz);
     mesh_get_vertex_tag(msh, iv, &tag);
     // Issue 0020656. Use vertex coordinates
-    if ( tag ) {
-      gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex(pmap(tag)));
-      xyz[0] = p.X(); xyz[1] = p.Y(); xyz[2] = p.Z();
+    if ( tag > 0 && tag <= pmap.Extent() ) {
+      TopoDS_Vertex v = TopoDS::Vertex(pmap(tag));
+      double tol = BRep_Tool::Tolerance( v );
+      gp_Pnt p = BRep_Tool::Pnt( v );
+      if ( p.IsEqual( gp_Pnt( xyz[0], xyz[1], xyz[2]), 2*tol))
+        xyz[0] = p.X(), xyz[1] = p.Y(), xyz[2] = p.Z();
+      else
+        tag = 0; // enforced or attracted vertex
     }
     nodes[iv] = meshDS->AddNode(xyz[0], xyz[1], xyz[2]);
+
+    /* TODO GROUPS
+    // Create group of enforced vertices if requested
+    if(_hypothesis) {
+      std::vector<double> projVertex;
+      projVertex.push_back((double)xyz[0]);
+      projVertex.push_back((double)xyz[1]);
+      projVertex.push_back((double)xyz[2]);
+      std::map< std::vector<double>, std::vector<double> >::const_iterator projIt = EnfVertex2ProjVertex.find(projVertex);
+      if (projIt != EnfVertex2ProjVertex.end()) {
+        double x = (projIt->second)[0];
+        double y = (projIt->second)[1];
+        double z = (projIt->second)[2];
+        BLSURFPlugin_Hypothesis::TEnfVertex enfVertex;
+        enfVertex.push_back(x);
+        enfVertex.push_back(y);
+        enfVertex.push_back(z);
+          
+        BLSURFPlugin_Hypothesis::TEnfVertexGroupNameMap groupNameMap =  _hypothesis->_GetEnforcedVertexGroupNameMap();
+        BLSURFPlugin_Hypothesis::TEnfVertexGroupNameMap::const_iterator groupNameMapIt = groupNameMap.find(enfVertex);
+        if (groupNameMapIt != groupNameMap.end()) {
+          MESSAGE("Found enforced vertex @ " << xyz[0] << ", " << xyz[1] << ", " << xyz[2])
+          BLSURFPlugin_Hypothesis::TEnfGroupName groupName = groupNameMapIt->second;
+          if (groupName != "") {
+            bool groupDone = false;
+            const set<SMESHDS_GroupBase*>& allGroups = meshDS->GetGroups();
+            set<SMESHDS_GroupBase*>::const_iterator grIt;
+            MESSAGE("Parsing the groups of the mesh");
+            for ( grIt = allGroups.begin(); grIt != allGroups.end(); ++grIt ) {
+              SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>( *grIt );
+              MESSAGE("Group: " << group->GetStoreName());
+              if ( group && group->SMDSGroup().GetType()==SMDSAbs_Node
+                          && groupName.compare(group->GetStoreName())==0) {
+                group->SMDSGroup().Add(nodes[iv]);
+//                 int id = // recuperer l'id SMESH du noeud
+//                 _hypothesis->AddEnfVertexIDs(groupName,id)
+                groupDone = true;
+                MESSAGE("Successfully added enforced vertex to existing group " << groupName);
+                break;
+              }
+            }
+            if (!groupDone)
+            {
+              int groupId;
+              SMESH_Group* aGroup = aMesh.AddGroup(SMDSAbs_Node, groupName.c_str(), groupId);
+              if ( aGroup ) {
+                SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( aGroup->GetGroupDS() );
+                if ( aGroupDS ) {
+                  aGroupDS->SetStoreName( groupName.c_str() );
+                  aGroupDS->SMDSGroup().Add(nodes[iv]);
+                  MESSAGE("Successfully created enforced vertex group " << groupName);
+                  groupDone = true;
+                }
+              }
+            }
+            if (!groupDone)
+              throw SALOME_Exception(LOCALIZED("A enforced vertex node was not added to a group"));
+          }
+          else
+            MESSAGE("Group name is empty: '"<<groupName<<"' => group is not created");
+        }
+        else
+          MESSAGE("No group name for projected vertex ("<<x<<","<<y<<","<<z<<")")
+      }
+//       else
+//         MESSAGE("No group name for vertex ("<<xyz[0]<<","<<xyz[1]<<","<<xyz[2]<<")")
+    }
+    */
+
     // internal point are tagged to zero
-    if(tag){
+    if(tag > 0 && tag <= pmap.Extent() ){
       meshDS->SetNodeOnVertex(nodes[iv], TopoDS::Vertex(pmap(tag)));
       tags[iv] = false;
     } else {
@@ -1685,21 +1796,23 @@ status_t interrupt_cb(integer *interrupt_status, void *user_data)
  *  
  */
 //=============================================================================
-bool BLSURFPlugin_BLSURF::Evaluate(SMESH_Mesh& aMesh,
+bool BLSURFPlugin_BLSURF::Evaluate(SMESH_Mesh&         aMesh,
                                    const TopoDS_Shape& aShape,
-                                   MapShapeNbElems& aResMap)
+                                   MapShapeNbElems&    aResMap)
 {
   int    _physicalMesh  = BLSURFPlugin_Hypothesis::GetDefaultPhysicalMesh();
   double _phySize       = BLSURFPlugin_Hypothesis::GetDefaultPhySize();
   //int    _geometricMesh = BLSURFPlugin_Hypothesis::GetDefaultGeometricMesh();
   //double _angleMeshS    = BLSURFPlugin_Hypothesis::GetDefaultAngleMeshS();
   double _angleMeshC    = BLSURFPlugin_Hypothesis::GetDefaultAngleMeshC();
+  bool   _quadAllowed   = BLSURFPlugin_Hypothesis::GetDefaultQuadAllowed();
   if(_hypothesis) {
     _physicalMesh  = (int) _hypothesis->GetPhysicalMesh();
     _phySize       = _hypothesis->GetPhySize();
     //_geometricMesh = (int) hyp->GetGeometricMesh();
     //_angleMeshS    = hyp->GetAngleMeshS();
     _angleMeshC    = _hypothesis->GetAngleMeshC();
+    _quadAllowed   = _hypothesis->GetQuadAllowed();
   }
 
   bool IsQuadratic = false;
@@ -1766,21 +1879,40 @@ bool BLSURFPlugin_BLSURF::Evaluate(SMESH_Mesh& aMesh,
     BRepGProp::SurfaceProperties(F,G);
     double anArea = G.Mass();
     int nb1d = 0;
+    std::vector<int> nb1dVec;
     for (TopExp_Explorer exp1(F,TopAbs_EDGE); exp1.More(); exp1.Next()) {
-      nb1d += EdgesMap.Find(exp1.Current());
+      int nbSeg = EdgesMap.Find(exp1.Current());
+      nb1d += nbSeg;
+      nb1dVec.push_back( nbSeg );
     }
-    int nbFaces = (int) ( anArea/( ELen*ELen*sqrt(3.) / 4 ) );
-    int nbNodes = (int) ( ( nbFaces*3 - (nb1d-1)*2 ) / 6 + 1 );
-    std::vector<int> aVec(SMDSEntity_Last);
-    for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aVec[i]=0;
+    int nbQuad = 0;
+    int nbTria = (int) ( anArea/( ELen*ELen*sqrt(3.) / 4 ) );
+    int nbNodes = (int) ( ( nbTria*3 - (nb1d-1)*2 ) / 6 + 1 );
+    if ( _quadAllowed )
+    {
+      if ( nb1dVec.size() == 4 ) // quadrangle geom face
+      {
+        int n1 = nb1dVec[0], n2 = nb1dVec[ nb1dVec[1] == nb1dVec[0] ? 2 : 1 ];
+        nbQuad = n1 * n2;
+        nbNodes = (n1 + 1) * (n2 + 1);
+        nbTria = 0;
+      }
+      else
+      {
+        nbTria = nbQuad = nbTria / 3 + 1;
+      }
+    }
+    std::vector<int> aVec(SMDSEntity_Last,0);
     if( IsQuadratic ) {
-      int nb1d_in = (nbFaces*3 - nb1d) / 2;
+      int nb1d_in = (nbTria*3 - nb1d) / 2;
       aVec[SMDSEntity_Node] = nbNodes + nb1d_in;
-      aVec[SMDSEntity_Quad_Triangle] = nbFaces;
+      aVec[SMDSEntity_Quad_Triangle] = nbTria;
+      aVec[SMDSEntity_Quad_Quadrangle] = nbQuad;
     }
     else {
       aVec[SMDSEntity_Node] = nbNodes;
-      aVec[SMDSEntity_Triangle] = nbFaces;
+      aVec[SMDSEntity_Triangle] = nbTria;
+      aVec[SMDSEntity_Quadrangle] = nbQuad;
     }
     aResMap.insert(std::make_pair(sm,aVec));
   }