Salome HOME
Merge 'master' branch into 'V9_dev' branch.
[modules/smesh.git] / src / SMESH_I / SMESH_MeshEditor_i.cxx
index bca571b9a851136b44f9dc2d7c43d4b38e8e7f4d..4f8809f99951434c43091235847d92b1b40eabe4 100644 (file)
@@ -64,7 +64,6 @@
 #include <Utils_CorbaException.hxx>
 #include <SALOMEDS_wrap.hxx>
 #include <SALOME_GenericObj_i.hh>
-#include <Basics_OCCTVersion.hxx>
 
 #include <BRepAdaptor_Surface.hxx>
 #include <BRep_Tool.hxx>
 #include <gp_Ax2.hxx>
 #include <gp_Vec.hxx>
 
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
-#define NO_CAS_CATCH
-#endif
-
 #include <Standard_Failure.hxx>
-
-#ifdef NO_CAS_CATCH
 #include <Standard_ErrorHandler.hxx>
-#endif
 
 #include <sstream>
 #include <limits>
@@ -110,7 +102,7 @@ namespace MeshEditor_I {
     SMDSAbs_ElementType myPreviewType; // type to show
     //!< Constructor
     TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
-      _isShapeToMesh = (_id =_studyId = 0);
+      _isShapeToMesh = (_id = 0);
       _myMeshDS  = new SMESHDS_Mesh( _id, true );
       myPreviewType = previewElements;
     }
@@ -2021,7 +2013,7 @@ CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr th
 //=============================================================================
 /*!
  * Find better splitting of the given quadrangle.
- *  \param IDOfQuad  ID of the quadrangle to be splitted.
+ *  \param IDOfQuad  ID of the quadrangle to be split.
  *  \param Criterion A criterion to choose a diagonal for splitting.
  *  \return 1 if 1-3 diagonal is better, 2 if 2-4
  *          diagonal is better, 0 if error occurs.
@@ -3890,7 +3882,6 @@ SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr  theObject,
   };
   gp_Trsf aTrsf;
 
-#if OCC_VERSION_LARGE > 0x06070100
   // fight against orthogonalization
   // aTrsf.SetValues( S[0], 0,    0,    thePoint.x * (1-S[0]),
   //                  0,    S[1], 0,    thePoint.y * (1-S[1]),
@@ -3903,13 +3894,6 @@ SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr  theObject,
                 thePoint.z * (1-S[2]));
   M.SetDiagonal( S[0], S[1], S[2] );
 
-#else
-  double tol = std::numeric_limits<double>::max();
-  aTrsf.SetValues( S[0], 0,    0,    thePoint.x * (1-S[0]),
-                   0,    S[1], 0,    thePoint.y * (1-S[1]),
-                   0,    0,    S[2], thePoint.z * (1-S[2]),   tol, tol);
-#endif
-
   TIDSortedElemSet  copyElements;
   TIDSortedElemSet* workElements = &elements;
   if ( myIsPreviewMode )
@@ -5411,8 +5395,7 @@ SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
 {
   SMESH_Gen_i*              gen = SMESH_Gen_i::GetSMESHGen();
   SMESH::SMESH_Mesh_var    mesh = gen->CreateEmptyMesh();
-  SALOMEDS::Study_var     study = gen->GetCurrentStudy();
-  SALOMEDS::SObject_wrap meshSO = gen->ObjectToSObject( study, mesh );
+  SALOMEDS::SObject_wrap meshSO = gen->ObjectToSObject( mesh );
   gen->SetName( meshSO, theMeshName, "Mesh" );
   gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
 
@@ -5707,10 +5690,7 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr th
   if ( !CORBA::is_nil( theModifiedElems ) )
     aModifiedElems = theModifiedElems->GetListOfID();
   else
-  {
     aModifiedElems = new SMESH::long_array;
-    aModifiedElems->length( 0 );
-  }
 
   TPythonDump pyDump; // suppress dump by the next line
 
@@ -6423,12 +6403,9 @@ SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theEl
 {
   SMESH_TRY;
   SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
-  bool isEdgeGroup = false;
-  bool isFaceGroup = false;
-  bool isVolumeGroup = false;
-  SMESH::SMESH_Group_var aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE, "affectedEdges");
-  SMESH::SMESH_Group_var aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE, "affectedFaces");
-  SMESH::SMESH_Group_var aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME, "affectedVolumes");
+  SMESH::SMESH_Group_var aNewEdgeGroup   = SMESH::SMESH_Group::_nil();
+  SMESH::SMESH_Group_var aNewFaceGroup   = SMESH::SMESH_Group::_nil();
+  SMESH::SMESH_Group_var aNewVolumeGroup = SMESH::SMESH_Group::_nil();
 
   initData();
 
@@ -6436,75 +6413,75 @@ SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theEl
 
   SMESHDS_Mesh* aMeshDS = getMeshDS();
   TIDSortedElemSet anElems, aNodes;
-  listOfGroupToSet(theElems, aMeshDS, anElems, false);
+  bool isNodeGrp = theElems.length() ? theElems[0]->GetType() == SMESH::NODE : false;
+  listOfGroupToSet(theElems, aMeshDS, anElems, isNodeGrp);
   listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true);
 
   TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape(theShape);
   TIDSortedElemSet anAffected;
   bool aResult = aMeshEditor.AffectedElemGroupsInRegion(anElems, aNodes, aShape, anAffected);
 
-
   declareMeshModified( /*isReComputeSafe=*/ !aResult );
 
   TPythonDump pyDump;
-  if (aResult)
+  if ( aResult && anAffected.size() > 0 )
   {
-    int lg = anAffected.size();
     SMESH::long_array_var volumeIds = new SMESH::long_array;
-    volumeIds->length(lg);
-    SMESH::long_array_var faceIds = new SMESH::long_array;
-    faceIds->length(lg);
-    SMESH::long_array_var edgeIds = new SMESH::long_array;
-    edgeIds->length(lg);
+    SMESH::long_array_var   faceIds = new SMESH::long_array;
+    SMESH::long_array_var   edgeIds = new SMESH::long_array;
+    volumeIds->length( anAffected.size() );
+    faceIds  ->length( anAffected.size() );
+    edgeIds  ->length( anAffected.size() );
+
     int ivol = 0;
     int iface = 0;
     int iedge = 0;
-
     TIDSortedElemSet::const_iterator eIt = anAffected.begin();
     for (; eIt != anAffected.end(); ++eIt)
     {
       const SMDS_MeshElement* anElem = *eIt;
-      if (!anElem)
-        continue;
       int elemId = anElem->GetID();
-      if (myMesh->GetElementType(elemId, true) == SMDSAbs_Volume)
-        volumeIds[ivol++] = elemId;
-      else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Face)
-        faceIds[iface++] = elemId;
-      else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Edge)
-        edgeIds[iedge++] = elemId;
+      switch ( anElem->GetType() ) {
+      case SMDSAbs_Volume: volumeIds[ivol++] = elemId; break;
+      case SMDSAbs_Face:    faceIds[iface++] = elemId; break;
+      case SMDSAbs_Edge:    edgeIds[iedge++] = elemId; break;
+      default:;
+      }
     }
     volumeIds->length(ivol);
     faceIds->length(iface);
     edgeIds->length(iedge);
 
-    aNewVolumeGroup->Add(volumeIds);
-    aNewFaceGroup->Add(faceIds);
-    aNewEdgeGroup->Add(edgeIds);
-    isVolumeGroup = (aNewVolumeGroup->Size() > 0);
-    isFaceGroup = (aNewFaceGroup->Size() > 0);
-    isEdgeGroup = (aNewEdgeGroup->Size() > 0);
+    int nbGroups = 0;
+    if ( ivol > 0 )
+    {
+      aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME,
+                                              generateGroupName("affectedVolumes").c_str());
+      aNewVolumeGroup->Add(volumeIds);
+      aListOfGroups->length( nbGroups+1 );
+      aListOfGroups[ nbGroups++ ] = aNewVolumeGroup._retn();
+    }
+    if ( iface > 0 )
+    {
+      aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE,
+                                            generateGroupName("affectedFaces").c_str());
+      aNewFaceGroup->Add(faceIds);
+      aListOfGroups->length( nbGroups+1 );
+      aListOfGroups[ nbGroups++ ] = aNewFaceGroup._retn();
+    }
+    if ( iedge > 0 )
+    {
+      aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE,
+                                            generateGroupName("affectedEdges").c_str());
+      aNewEdgeGroup->Add(edgeIds);
+      aListOfGroups->length( nbGroups+1 );
+      aListOfGroups[ nbGroups++ ] = aNewEdgeGroup._retn();
+    }
   }
 
-  int nbGroups = 0;
-  if (isEdgeGroup)   nbGroups++;
-  if (isFaceGroup)   nbGroups++;
-  if (isVolumeGroup) nbGroups++;
-  aListOfGroups->length(nbGroups);
-
-  int i = 0;
-  if (isEdgeGroup)   aListOfGroups[i++] = aNewEdgeGroup._retn();
-  if (isFaceGroup)   aListOfGroups[i++] = aNewFaceGroup._retn();
-  if (isVolumeGroup) aListOfGroups[i++] = aNewVolumeGroup._retn();
-
   // Update Python script
 
-  pyDump << "[ ";
-  if (isEdgeGroup)   pyDump << aNewEdgeGroup << ", ";
-  if (isFaceGroup)   pyDump << aNewFaceGroup << ", ";
-  if (isVolumeGroup) pyDump << aNewVolumeGroup << ", ";
-  pyDump << "] = ";
-  pyDump << this << ".AffectedElemGroupsInRegion( "
+  pyDump << aListOfGroups << " = " << this << ".AffectedElemGroupsInRegion( "
          << &theElems << ", " << &theNodesNot << ", " << theShape << " )";
 
   return aListOfGroups._retn();
@@ -6516,7 +6493,7 @@ SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theEl
 //================================================================================
 /*!
   \brief Generated skin mesh (containing 2D cells) from 3D mesh
-   The created 2D mesh elements based on nodes of free faces of boundary volumes
+  The created 2D mesh elements based on nodes of free faces of boundary volumes
   \return TRUE if operation has been completed successfully, FALSE otherwise
 */
 //================================================================================
@@ -6973,3 +6950,130 @@ CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
   SMESH_CATCH( SMESH::throwCorbaException );
   return 0;
 }
+
+//================================================================================
+/*!
+ * \brief Create a polyline consisting of 1D mesh elements each lying on a 2D element of
+ *        the initial mesh. Positions of new nodes are found by cutting the mesh by the
+ *        plane passing through pairs of points specified by each PolySegment structure.
+ *        If there are several paths connecting a pair of points, the shortest path is
+ *        selected by the module. Position of the cutting plane is defined by the two
+ *        points and an optional vector lying on the plane specified by a PolySegment.
+ *        By default the vector is defined by Mesh module as following. A middle point
+ *        of the two given points is computed. The middle point is projected to the mesh.
+ *        The vector goes from the middle point to the projection point. In case of planar
+ *        mesh, the vector is normal to the mesh.
+ *  \param [inout] segments - PolySegment's defining positions of cutting planes.
+ *        Return the used vector and position of the middle point.
+ *  \param [in] groupName - optional name of a group where created mesh segments will
+ *        be added.
+ */
+//================================================================================
+
+void SMESH_MeshEditor_i::MakePolyLine(SMESH::ListOfPolySegments& theSegments,
+                                      const char*                theGroupName)
+  throw (SALOME::SALOME_Exception)
+{
+  if ( theSegments.length() == 0 )
+    THROW_SALOME_CORBA_EXCEPTION("No segments given", SALOME::BAD_PARAM );
+  if ( myMesh->NbFaces() == 0 )
+    THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM );
+
+  SMESH_TRY;
+  initData(/*deleteSearchers=*/false);
+
+  SMESHDS_Group* groupDS = 0;
+  SMESHDS_Mesh*   meshDS = getMeshDS();
+  if ( myIsPreviewMode ) // copy faces to the tmp mesh
+  {
+    TPreviewMesh * tmpMesh = getPreviewMesh( SMDSAbs_Edge );
+    SMDS_ElemIteratorPtr faceIt = getMeshDS()->elementsIterator( SMDSAbs_Face );
+    while ( faceIt->more() )
+      tmpMesh->Copy( faceIt->next() );
+    meshDS = tmpMesh->GetMeshDS();
+  }
+  else if ( theGroupName[0] ) // find/create a group of segments
+  {
+    SMESH_Mesh::GroupIteratorPtr grpIt = myMesh->GetGroups();
+    while ( !groupDS && grpIt->more() )
+    {
+      SMESH_Group* group = grpIt->next();
+      if ( group->GetGroupDS()->GetType() == SMDSAbs_Edge &&
+           strcmp( group->GetName(), theGroupName ) == 0 )
+      {
+        groupDS = dynamic_cast< SMESHDS_Group* >( group->GetGroupDS() );
+      }
+    }
+    if ( !groupDS )
+    {
+      SMESH::SMESH_Group_var groupVar = myMesh_i->CreateGroup( SMESH::EDGE, theGroupName );
+
+      if ( SMESH_Group_i* groupImpl = SMESH::DownCast<SMESH_Group_i*>( groupVar ))
+        groupDS = dynamic_cast< SMESHDS_Group* >( groupImpl->GetGroupDS() );
+    }
+  }
+
+  // convert input polySegments
+  ::SMESH_MeshEditor::TListOfPolySegments segments( theSegments.length() );
+  for ( CORBA::ULong i = 0; i < theSegments.length(); ++i )
+  {
+    SMESH::PolySegment&               segIn = theSegments[ i ];
+    ::SMESH_MeshEditor::PolySegment& segOut = segments[ i ];
+    segOut.myNode1[0] = meshDS->FindNode( segIn.node1ID1 );
+    segOut.myNode2[0] = meshDS->FindNode( segIn.node1ID2 );
+    segOut.myNode1[1] = meshDS->FindNode( segIn.node2ID1 );
+    segOut.myNode2[1] = meshDS->FindNode( segIn.node2ID2 );
+    segOut.myVector.SetCoord( segIn.vector.PS.x,
+                              segIn.vector.PS.y,
+                              segIn.vector.PS.z );
+    if ( !segOut.myNode1[0] )
+      THROW_SALOME_CORBA_EXCEPTION( SMESH_Comment( "Invalid node ID: ") << segIn.node1ID1,
+                                    SALOME::BAD_PARAM );
+    if ( !segOut.myNode1[1] )
+      THROW_SALOME_CORBA_EXCEPTION( SMESH_Comment( "Invalid node ID: ") << segIn.node2ID1,
+                                    SALOME::BAD_PARAM );
+  }
+
+  // get a static ElementSearcher
+  SMESH::SMESH_IDSource_var idSource = SMESH::SMESH_IDSource::_narrow( myMesh_i->_this() );
+  theSearchersDeleter.Set( myMesh, getPartIOR( idSource, SMESH::FACE ));
+  if ( !theElementSearcher )
+    theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
+
+  // compute
+  getEditor().MakePolyLine( segments, groupDS, theElementSearcher );
+
+  // return vectors
+  if ( myIsPreviewMode )
+  {
+    for ( CORBA::ULong i = 0; i < theSegments.length(); ++i )
+    {
+      SMESH::PolySegment&             segOut = theSegments[ i ];
+      ::SMESH_MeshEditor::PolySegment& segIn = segments[ i ];
+      segOut.vector.PS.x = segIn.myVector.X();
+      segOut.vector.PS.y = segIn.myVector.Y();
+      segOut.vector.PS.z = segIn.myVector.Z();
+    }
+  }
+  else
+  {
+    TPythonDump() << "_segments = []";
+    for ( CORBA::ULong i = 0; i < theSegments.length(); ++i )
+    {
+      SMESH::PolySegment& segIn = theSegments[ i ];
+      TPythonDump() << "_segments.append( SMESH.PolySegment( "
+                    << segIn.node1ID1 << ", "
+                    << segIn.node1ID2 << ", "
+                    << segIn.node2ID1 << ", "
+                    << segIn.node2ID2 << ", "
+                    << "smeshBuilder.MakeDirStruct( "
+                    << segIn.vector.PS.x << ", "
+                    << segIn.vector.PS.y << ", "
+                    << segIn.vector.PS.z << ")))";
+    }
+    TPythonDump() << this << ".MakePolyLine( _segments, '" << theGroupName << "')";
+  }
+  meshDS->Modified();
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return;
+}