Salome HOME
Fix regressions
[modules/smesh.git] / src / SMESH_I / SMESH_MeshEditor_i.cxx
index d01b62999c9e0e16968fe9d794472efac5cc658c..c54b068cfec6e98d108d6b8001e9c8e626a4c0d3 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -6,7 +6,7 @@
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -307,33 +307,56 @@ namespace MeshEditor_I {
    */
   //================================================================================
 
+  enum IDSource_Error { IDSource_OK, IDSource_INVALID, IDSource_EMPTY };
+
   bool idSourceToSet(SMESH::SMESH_IDSource_ptr  theIDSource,
                      const SMESHDS_Mesh*        theMeshDS,
                      TIDSortedElemSet&          theElemSet,
                      const SMDSAbs_ElementType  theType,
-                     const bool                 emptyIfIsMesh=false)
+                     const bool                 emptyIfIsMesh = false,
+                     IDSource_Error*            error = 0)
 
   {
+    if ( error ) *error = IDSource_OK;
+
     if ( CORBA::is_nil( theIDSource ) )
+    {
+      if ( error ) *error = IDSource_INVALID;
       return false;
+    }
     if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
+    {
+      if ( error && theMeshDS->GetMeshInfo().NbElements( theType ) == 0 )
+        *error = IDSource_EMPTY;
       return true;
-
+    }
     SMESH::long_array_var anIDs = theIDSource->GetIDs();
     if ( anIDs->length() == 0 )
+    {
+      if ( error ) *error = IDSource_EMPTY;
       return false;
+    }
     SMESH::array_of_ElementType_var types = theIDSource->GetTypes();
     if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
     {
       if ( theType == SMDSAbs_All || theType == SMDSAbs_Node )
+      {
         arrayToSet( anIDs, theMeshDS, theElemSet, SMDSAbs_Node );
+      }
       else
+      {
+        if ( error ) *error = IDSource_INVALID;
         return false;
+      }
     }
     else
     {
       arrayToSet( anIDs, theMeshDS, theElemSet, theType);
-      return bool(anIDs->length()) == bool(theElemSet.size());
+      if ( bool(anIDs->length()) != bool(theElemSet.size()))
+      {
+        if ( error ) *error = IDSource_INVALID;
+        return false;
+      }
     }
     return true;
   }
@@ -1644,7 +1667,11 @@ CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
 
   TIDSortedElemSet elements;
   prepareIdSource( the2Dgroup );
-  if ( !idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1))
+  IDSource_Error error;
+  idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error );
+  if ( error == IDSource_EMPTY )
+    return 0;
+  if ( error == IDSource_INVALID )
     THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
 
 
@@ -1710,6 +1737,58 @@ CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
   return 0;
 }
 
+//=======================================================================
+//function : Reorient2DBy3D
+//purpose  : Reorient faces basing on orientation of adjacent volumes.
+//=======================================================================
+
+CORBA::Long SMESH_MeshEditor_i::Reorient2DBy3D(const SMESH::ListOfIDSources& faceGroups,
+                                               SMESH::SMESH_IDSource_ptr     volumeGroup,
+                                               CORBA::Boolean                outsideNormal)
+  throw (SALOME::SALOME_Exception)
+{
+  SMESH_TRY;
+  initData();
+
+  TIDSortedElemSet volumes;
+  prepareIdSource( volumeGroup );
+  IDSource_Error volsError;
+  idSourceToSet( volumeGroup, getMeshDS(), volumes, SMDSAbs_Volume, /*emptyIfMesh=*/1, &volsError);
+
+  int nbReori = 0;
+  for ( size_t i = 0; i < faceGroups.length(); ++i )
+  {
+    SMESH::SMESH_IDSource_ptr faceGrp = faceGroups[i].in();
+    prepareIdSource( faceGrp );
+
+    TIDSortedElemSet faces;
+    IDSource_Error error;
+    idSourceToSet( faceGrp, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error );
+    if ( error == IDSource_INVALID && faceGroups.length() == 1 )
+      THROW_SALOME_CORBA_EXCEPTION("No faces in a given object", SALOME::BAD_PARAM);
+    if ( error == IDSource_OK && volsError != IDSource_OK )
+      THROW_SALOME_CORBA_EXCEPTION("No volumes in a given object", SALOME::BAD_PARAM);
+
+    nbReori += getEditor().Reorient2DBy3D( faces, volumes, outsideNormal );
+
+    if ( error != IDSource_EMPTY && faces.empty() ) // all faces in the mesh treated
+      break;
+  }
+
+  if ( nbReori ) {
+    declareMeshModified( /*isReComputeSafe=*/false );
+  }
+  TPythonDump() << this << ".Reorient2DBy3D( "
+                << faceGroups << ", "
+                << volumeGroup << ", "
+                << outsideNormal << " )";
+
+  return nbReori;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return 0;
+}
+
 //=============================================================================
 /*!
  * \brief Fuse neighbour triangles into quadrangles.
@@ -6875,18 +6954,21 @@ CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
  * If there is no shared faces between the group #n and the group #p in the list, the group j_n_p is not created.
  * All the flat elements are gathered into the group named "joints3D" (or "joints2D" in 2D situation).
  * The flat element of the multiple junctions between the simple junction are stored in a group named "jointsMultiples".
- * @param theDomains - list of groups of volumes
- * @param createJointElems - if TRUE, create the elements
- * @return TRUE if operation has been completed successfully, FALSE otherwise
+ * \param theDomains - list of groups of volumes
+ * \param createJointElems - if TRUE, create the elements
+ * \param onAllBoundaries - if TRUE, the nodes and elements are also created on
+ *        the boundary between \a theDomains and the rest mesh
+ * \return TRUE if operation has been completed successfully, FALSE otherwise
  */
 //================================================================================
 
 CORBA::Boolean
 SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
-                                                  CORBA::Boolean             createJointElems )
+                                                  CORBA::Boolean             createJointElems,
+                                                  CORBA::Boolean             onAllBoundaries )
   throw (SALOME::SALOME_Exception)
 {
-  bool aResult = false;
+  bool isOK = false;
 
   SMESH_TRY;
   initData();
@@ -6894,10 +6976,11 @@ SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& the
   SMESHDS_Mesh* aMeshDS = getMeshDS();
 
   // MESSAGE("theDomains.length = "<<theDomains.length());
-  if ( theDomains.length() <= 1 )
+  if ( theDomains.length() <= 1 && !onAllBoundaries )
     THROW_SALOME_CORBA_EXCEPTION("At least 2 groups are required.", SALOME::BAD_PARAM);
+
   vector<TIDSortedElemSet> domains;
-  domains.clear();
+  domains.resize( theDomains.length() );
 
   for ( int i = 0, n = theDomains.length(); i < n; i++ )
   {
@@ -6906,26 +6989,25 @@ SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& the
     {
 //      if ( aGrp->GetType() != SMESH::VOLUME )
 //        THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
-      TIDSortedElemSet domain;
-      domain.clear();
-      domains.push_back(domain);
       SMESH::long_array_var anIDs = aGrp->GetIDs();
       arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
     }
   }
 
-  aResult = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems );
+  isOK = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems, onAllBoundaries );
   // TODO publish the groups of flat elements in study
 
-  declareMeshModified( /*isReComputeSafe=*/ !aResult );
+  declareMeshModified( /*isReComputeSafe=*/ !isOK );
 
   // Update Python script
   TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
-      << ", " << createJointElems << " )";
+                << ", " << createJointElems << ", " << onAllBoundaries << " )";
 
   SMESH_CATCH( SMESH::throwCorbaException );
 
-  return aResult;
+  myMesh_i->CreateGroupServants(); // publish created groups if any
+
+  return isOK;
 }
 
 //================================================================================