Salome HOME
23586: [EDF] HYDRO: Copy mesh to new geometry
[modules/smesh.git] / src / SMESH_I / SMESH_Gen_i_1.cxx
index 346150a0bdf20fa0763b5e2e88dfdda5b756d733..dacbf60909053c6a9505fe96e349cffdd1c523d4 100644 (file)
@@ -265,8 +265,7 @@ static SALOMEDS::SObject_ptr publish(SALOMEDS::Study_ptr   theStudy,
   SALOMEDS::SObject_wrap SO = SMESH_Gen_i::ObjectToSObject( theStudy, theIOR );
   SALOMEDS::StudyBuilder_var     aStudyBuilder = theStudy->NewBuilder();
   SALOMEDS::UseCaseBuilder_wrap useCaseBuilder = theStudy->GetUseCaseBuilder();
-  SALOMEDS::SObject_wrap objAfter;
-  bool isNewSO = false;
+  bool isNewSO = false, isInUseCaseTree = false;
   if ( SO->_is_nil() )
   {
     if ( theTag == 0 ) {
@@ -277,22 +276,15 @@ static SALOMEDS::SObject_ptr publish(SALOMEDS::Study_ptr   theStudy,
     {
       SO = aStudyBuilder->NewObjectToTag( theFatherObject, theTag );
       isNewSO = true;
-
-      // define the next tag after given one in the data tree to insert SObject
-      SALOMEDS::SObject_wrap curObj;
-      if ( theFatherObject->GetLastChildTag() > theTag )
-      {
-        SALOMEDS::UseCaseIterator_wrap
-          anUseCaseIter = useCaseBuilder->GetUseCaseIterator(theFatherObject);
-        for ( ; anUseCaseIter->More(); anUseCaseIter->Next() ) {
-          curObj = anUseCaseIter->Value();
-          if ( curObj->Tag() > theTag  ) {
-            objAfter = curObj;
-            break;
-          }
-        }
-      }
     }
+    else
+    {
+      isInUseCaseTree = useCaseBuilder->IsUseCaseNode( SO );
+    }
+  }
+  else
+  {
+    isInUseCaseTree = useCaseBuilder->IsUseCaseNode( SO );
   }
 
   SALOMEDS::GenericAttribute_wrap anAttr;
@@ -306,10 +298,10 @@ static SALOMEDS::SObject_ptr publish(SALOMEDS::Study_ptr   theStudy,
     if ( !sameIOR )
     {
       iorAttr->SetValue( objStr.in() );
-      // UnRegister() !!!
-      SALOME::GenericObj_var genObj = SALOME::GenericObj::_narrow( theIOR );
-      if ( !genObj->_is_nil() )
-        genObj->UnRegister();
+      // UnRegister() !!! --> No: random problems when meshing in parallel (yacs foreach) in distributed python scripts
+//      SALOME::GenericObj_var genObj = SALOME::GenericObj::_narrow( theIOR );
+//      if ( !genObj->_is_nil() )
+//        genObj->UnRegister();
     }
   }
 
@@ -325,13 +317,30 @@ static SALOMEDS::SObject_ptr publish(SALOMEDS::Study_ptr   theStudy,
     selAttr->SetSelectable( false );
   }
 
+  if ( !isNewSO )
+    aStudyBuilder->RemoveReference( SO );// remove garbage reference (23336)
+
   // add object to the use case tree
   // (to support tree representation customization and drag-n-drop)
-  if ( isNewSO )
+  if ( isNewSO || !isInUseCaseTree )
   {
-    if ( !CORBA::is_nil( objAfter ) )
+    // define the next tag after given one in the data tree to insert SObject
+    SALOMEDS::SObject_wrap curObj, objAfter;
+    if ( theFatherObject->GetLastChildTag() > theTag && theTag > 0 )
+    {
+      SALOMEDS::UseCaseIterator_wrap
+        anUseCaseIter = useCaseBuilder->GetUseCaseIterator(theFatherObject);
+      for ( ; anUseCaseIter->More(); anUseCaseIter->Next() ) {
+        curObj = anUseCaseIter->Value();
+        if ( curObj->Tag() > theTag  ) {
+          objAfter = curObj;
+          break;
+        }
+      }
+    }
+    if ( !CORBA::is_nil( objAfter ))
       useCaseBuilder->InsertBefore( SO, objAfter );    // insert at given tag
-    else if ( !useCaseBuilder->IsUseCaseNode( SO ) )
+    else if ( !isInUseCaseTree )
       useCaseBuilder->AppendTo( theFatherObject, SO ); // append to the end of list
   }
   return SO._retn();
@@ -433,6 +442,9 @@ static void addReference (SALOMEDS::Study_ptr   theStudy,
 
     aStudyBuilder->Addreference( aReferenceSO, aToObjSO );
 
+    // make the reference visible (invisible ref is created by createInvalidSubMesh())
+    aStudyBuilder->RemoveAttribute( aReferenceSO, "AttributeDrawable" );
+
     // add reference to the use case tree
     // (to support tree representation customization and drag-n-drop)
     SALOMEDS::UseCaseBuilder_wrap  useCaseBuilder = theStudy->GetUseCaseBuilder();
@@ -639,7 +651,7 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::PublishMesh (SALOMEDS::Study_ptr   theStudy,
 
 //=======================================================================
 //function : PublishSubMesh
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 SALOMEDS::SObject_ptr SMESH_Gen_i::PublishSubMesh (SALOMEDS::Study_ptr      theStudy,
@@ -652,6 +664,8 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::PublishSubMesh (SALOMEDS::Study_ptr      theS
       theSubMesh->_is_nil() || theShapeObject->_is_nil() )
     return SALOMEDS::SObject::_nil();
 
+  std::string newName( theName ? theName : "" );
+
   SALOMEDS::SObject_wrap aSubMeshSO = ObjectToSObject( theStudy, theSubMesh );
   if ( aSubMeshSO->_is_nil() )
   {
@@ -703,15 +717,37 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::PublishSubMesh (SALOMEDS::Study_ptr      theS
 
     SetName( aRootSO, aRootName );
 
-    // Add new submesh to corresponding sub-tree
+    // Add new sub-mesh to corresponding sub-tree
+    int tag = 0; // to use a new SObject
+    if ( theName && theName[0] == '0' )
+    {
+      // theName can be an entry of an invalid sub-mesh which theSubMesh should replace
+      SALOMEDS::SObject_wrap aSObj = theStudy->FindObjectID( theName );
+      if ( aSObj )
+      {
+        CORBA::String_var oldName = aSObj->GetName();
+        newName = oldName.in();
+        SALOMEDS::SObject_wrap aRootSO2 = aSObj->GetFather();
+        if ( aRootSO->Tag() == aRootSO2->Tag() ) // same parent
+          tag = aSObj->Tag(); // to use the same SObject
+        else
+        {
+          CORBA::Object_var anObj = SObjectToObject( aSObj );
+          SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( anObj );
+          theMesh->RemoveSubMesh( sm );
+        }
+      }
+    }
     SMESH::array_of_ElementType_var elemTypes = theSubMesh->GetTypes();
     const int isEmpty = ( elemTypes->length() == 0 );
     const char* pm[2] = { "ICON_SMESH_TREE_MESH", "ICON_SMESH_TREE_MESH_WARN" };
-    aSubMeshSO = publish (theStudy, theSubMesh, aRootSO, 0, pm[isEmpty] );
+    aSubMeshSO = publish (theStudy, theSubMesh, aRootSO, tag, pm[isEmpty] );
     if ( aSubMeshSO->_is_nil() )
       return aSubMeshSO._retn();
+
+    highLightInvalid( aSubMeshSO, false ); // now it is valid
   }
-  SetName( aSubMeshSO, theName, "SubMesh" );
+  SetName( aSubMeshSO, newName.c_str(), "SubMesh" );
 
   // Add reference to theShapeObject
 
@@ -720,7 +756,8 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::PublishSubMesh (SALOMEDS::Study_ptr      theS
   // Publish hypothesis
 
   SMESH::ListOfHypothesis_var hypList = theMesh->GetHypothesisList( theShapeObject );
-  for ( CORBA::ULong i = 0; i < hypList->length(); i++ ) {
+  for ( CORBA::ULong i = 0; i < hypList->length(); i++ )
+  {
     SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( hypList[ i ]);
     SALOMEDS::SObject_wrap so = PublishHypothesis( theStudy, aHyp );
     AddHypothesisToShape( theStudy, theMesh, theShapeObject, aHyp );
@@ -758,7 +795,7 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::PublishGroup (SALOMEDS::Study_ptr    theStudy
       "Groups of Faces", "Groups of Volumes", "Groups of 0D Elements",
       "Groups of Balls" };
 
-    // Currently, groups with heterogenous content are not supported
+    // Currently, groups with heterogeneous content are not supported
     if ( aType != SMESH::ALL )
     {
       long aRootTag = GetNodeGroupsTag() + aType - 1;
@@ -851,6 +888,42 @@ SALOMEDS::SObject_ptr
   return aHypSO._retn();
 }
 
+//=======================================================================
+//function : HighLightInvalid
+//purpose  : change font color of a object in the Object Browser
+//=======================================================================
+
+void SMESH_Gen_i::HighLightInvalid( CORBA::Object_ptr theObject, bool isInvalid )
+{
+  SALOMEDS::SObject_wrap so = ObjectToSObject( myCurrentStudy, theObject );
+  highLightInvalid( so.in(), isInvalid );
+}
+
+//=======================================================================
+//function : highLightInvalid
+//purpose  : change font color of a object in the Object Browser
+//=======================================================================
+
+void SMESH_Gen_i::highLightInvalid( SALOMEDS::SObject_ptr theSObject, bool isInvalid )
+{
+  if ( !theSObject->_is_nil() )
+  {
+    SALOMEDS::StudyBuilder_var studyBuilder = myCurrentStudy->NewBuilder();
+    if ( isInvalid )
+    {
+      SALOMEDS::Color red = { 178,34,34 }; // to differ from reference color
+      SALOMEDS::GenericAttribute_wrap attr =
+        studyBuilder->FindOrCreateAttribute( theSObject, "AttributeTextColor" );
+      SALOMEDS::AttributeTextColor_wrap colorAttr = attr;
+      colorAttr->SetTextColor( red );
+    }
+    else
+    {
+      studyBuilder->RemoveAttribute( theSObject, "AttributeTextColor" );
+    }
+  }
+}
+
 //=======================================================================
 //function : GetMeshOrSubmeshByShape
 //purpose  : 
@@ -912,7 +985,7 @@ bool SMESH_Gen_i::AddHypothesisToShape(SALOMEDS::Study_ptr         theStudy,
   if ( aMeshSO->_is_nil() || aHypSO->_is_nil())
     return false;
 
-  // Find a mesh or submesh refering to theShape
+  // Find a mesh or submesh referring to theShape
   SALOMEDS::SObject_wrap aMeshOrSubMesh =
     GetMeshOrSubmeshByShape( theStudy, theMesh, theShape );
   if ( aMeshOrSubMesh->_is_nil() )
@@ -997,7 +1070,7 @@ bool SMESH_Gen_i::RemoveHypothesisFromShape(SALOMEDS::Study_ptr         theStudy
  * \brief Stores names of variables that WILL be passes as parameters when calling
  *        some method of a given object.
  *  \param [in] theObject - the object whose a method WILL be called with \a theParameters.
- *  \param [in] theParameters - a string contating parameters separated by ':'.
+ *  \param [in] theParameters - a string containing parameters separated by ':'.
  */
 //================================================================================
 
@@ -1012,7 +1085,7 @@ void SMESH_Gen_i::UpdateParameters(CORBA::Object_ptr theObject, const char* theP
   myLastObj.clear();
   myLastParameters.clear();
   myLastParamIndex.clear(); /* vector holding indices of virables within the string
-                               of all varibles used for theObject */ 
+                               of all variables used for theObject */ 
   int nbVars = 0;
   int pos = 0, prevPos = 0, len = strlen( theParameters );
   if ( len == 0 ) return;
@@ -1041,7 +1114,7 @@ void SMESH_Gen_i::UpdateParameters(CORBA::Object_ptr theObject, const char* theP
     return;
 
   // store
-  // (1) variable names in the string of all varibles used for theObject and
+  // (1) variable names in the string of all variables used for theObject and
   // (2) indices of found variables in myLastParamIndex.
 
   // remember theObject
@@ -1088,7 +1161,7 @@ void SMESH_Gen_i::UpdateParameters(CORBA::Object_ptr theObject, const char* theP
         if ( pos < varStr.size() )
         {
           varFound = ( varStr.compare( pos, myLastParameters[i].size(), myLastParameters[i] ) == 0 &&
-                       // same string begining but is length same?
+                       // same string beginning but is length same?
                        ( pos + myLastParameters[i].size() >= varStr.size() ||
                          separators.find( varStr[ pos+1 ]) != std::string::npos ));
           if ( varFound )
@@ -1235,3 +1308,48 @@ char* SMESH_Gen_i::GetParameters(CORBA::Object_ptr theObject)
   }
   return aResult._retn();
 }
+
+//================================================================================
+/*!
+ * \brief Create a sub-mesh on a geometry that is not a sub-shape of the main shape
+ * for the case where a valid sub-shape not found by CopyMeshWithGeom().
+ * The invalid sub-mesh has GetId() < 0.
+ */
+//================================================================================
+
+SMESH::SMESH_subMesh_ptr
+SMESH_Gen_i::createInvalidSubMesh(SMESH::SMESH_Mesh_ptr theMesh,
+                                  GEOM::GEOM_Object_ptr theStrangerGeom,
+                                  const char*           theName)
+{
+  SMESH::SMESH_subMesh_var subMesh;
+
+  try
+  {
+    SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( theMesh );
+    subMesh = mesh_i->createSubMesh( theStrangerGeom );
+
+    if ( !subMesh->_is_nil() && CanPublishInStudy( subMesh ))
+    {
+      SALOMEDS::SObject_wrap so = PublishSubMesh( myCurrentStudy, theMesh, subMesh, theStrangerGeom, theName );
+
+      // hide a reference to geometry
+      if ( !so->_is_nil() )
+      {
+        SALOMEDS::SObject_wrap refSO;
+        if ( so->FindSubObject( GetRefOnShapeTag(), refSO.inout() ))
+        {
+          SALOMEDS::StudyBuilder_var studyBuilder = myCurrentStudy->NewBuilder();
+          SALOMEDS::GenericAttribute_wrap attr =
+            studyBuilder->FindOrCreateAttribute( refSO, "AttributeDrawable" );
+          SALOMEDS::AttributeDrawable_wrap ga = attr;
+          ga->SetDrawable( false );
+        }
+      }
+    }
+  }
+  catch (...) {
+  }
+
+  return subMesh._retn();
+}