Salome HOME
Merge branch 'occ/shaper2smesh'
[modules/smesh.git] / src / SMESH_I / SMESH_Gen_i_1.cxx
index af0dab97fab64a4cc027fd240a971dfe08a331d6..580663d464707729b7e045d832c8e7ee0444fd2f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2019  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
@@ -237,7 +237,8 @@ GEOM::GEOM_Object_ptr SMESH_Gen_i::ShapeToGeomObject (const TopoDS_Shape& theSha
     if ( aClient && aClient->Find( theShape, IOR ))
     {
       CORBA::Object_var obj = GetORB()->string_to_object( IOR.ToCString() );
-      aShapeObj = GEOM::GEOM_Object::_narrow ( obj );
+      if ( !obj->_non_existent() )
+        aShapeObj = GEOM::GEOM_Object::_narrow ( obj );
     }
   }
   return aShapeObj._retn();
@@ -251,9 +252,10 @@ GEOM::GEOM_Object_ptr SMESH_Gen_i::ShapeToGeomObject (const TopoDS_Shape& theSha
 TopoDS_Shape SMESH_Gen_i::GeomObjectToShape(GEOM::GEOM_Object_ptr theGeomObject)
 {
   TopoDS_Shape S;
-  if ( !theGeomObject->_is_nil() ) {
-    GEOM_Client* aClient = GetShapeReader();
-    GEOM::GEOM_Gen_ptr aGeomEngine = GetGeomEngine();
+  if ( !theGeomObject->_is_nil() && !theGeomObject->_non_existent() )
+  {
+    GEOM_Client*           aClient = GetShapeReader();
+    GEOM::GEOM_Gen_var aGeomEngine = GetGeomEngine( theGeomObject );
     if ( aClient && !aGeomEngine->_is_nil () )
       S = aClient->GetShape( aGeomEngine, theGeomObject );
   }
@@ -262,7 +264,7 @@ TopoDS_Shape SMESH_Gen_i::GeomObjectToShape(GEOM::GEOM_Object_ptr theGeomObject)
 
 //=======================================================================
 //function : publish
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 static SALOMEDS::SObject_ptr publish(CORBA::Object_ptr     theIOR,
@@ -308,10 +310,12 @@ static SALOMEDS::SObject_ptr publish(CORBA::Object_ptr     theIOR,
     if ( !sameIOR )
     {
       iorAttr->SetValue( objStr.in() );
-      // 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();
+      // UnRegister() !!! --> random problems when meshing in parallel (yacs foreach) in
+      // distributed python scripts, because simultaneously created meshes are
+      // published into the same SO; as a result the mesh published first dies
+      SALOME::GenericObj_var genObj = SALOME::GenericObj::_narrow( theIOR );
+      if ( !genObj->_is_nil() )
+        genObj->UnRegister();
     }
   }
 
@@ -450,6 +454,9 @@ static void addReference (SALOMEDS::SObject_ptr theSObject,
 
     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 = aStudy->GetUseCaseBuilder();
@@ -529,8 +536,23 @@ SALOMEDS::SComponent_ptr SMESH_Gen_i::PublishComponent()
   SALOMEDS::StudyBuilder_var    aStudyBuilder  = getStudyServant()->NewBuilder();
   SALOMEDS::UseCaseBuilder_wrap useCaseBuilder = getStudyServant()->GetUseCaseBuilder();
 
-  CORBA::String_var   compDataType = ComponentDataType();
-  SALOMEDS::SComponent_wrap father = getStudyServant()->FindComponent( compDataType.in() );
+  std::string compDataType = ComponentDataType(); // SMESH module's data type
+  std::string ior = SMESH_Gen_i::GetORB()->object_to_string( SMESH_Gen::_this() ); // IOR of this SMESH engine
+
+  // Find study component which corresponds to this SMESH engine
+
+  SALOMEDS::SComponent_wrap father;
+  SALOMEDS::SComponentIterator_wrap citer = getStudyServant()->NewComponentIterator();
+  for ( ; citer->More(); citer->Next()) {
+    SALOMEDS::SComponent_wrap f_i = citer->Value();
+    CORBA::String_var ior_i;
+    bool ok = f_i->ComponentIOR(ior_i.out());
+    if ( ok && compDataType == f_i->ComponentDataType() && ior == ior_i.in()) {
+      father = f_i;
+      break;
+    }
+  }
+  
   if ( !CORBA::is_nil( father ) ) {
     // check that the component is added to the use case browser
     if ( !useCaseBuilder->IsUseCaseNode( father ) ) {
@@ -540,19 +562,21 @@ SALOMEDS::SComponent_ptr SMESH_Gen_i::PublishComponent()
     return father._retn();
   }
 
+  // If component for this SMESH engine does not exist in the study, create it
+
   SALOME_ModuleCatalog::ModuleCatalog_var aCat =
     SALOME_ModuleCatalog::ModuleCatalog::_narrow( GetNS()->Resolve("/Kernel/ModulCatalog") );
   if ( CORBA::is_nil( aCat ) )
     return father._retn();
 
-  SALOME_ModuleCatalog::Acomponent_var aComp = aCat->GetComponent( compDataType.in() );
+  SALOME_ModuleCatalog::Acomponent_var aComp = aCat->GetComponent( compDataType.c_str() );
   if ( CORBA::is_nil( aComp ) )
     return father._retn();
 
   SALOMEDS::GenericAttribute_wrap anAttr;
   SALOMEDS::AttributePixMap_wrap  aPixmap;
 
-  father  = aStudyBuilder->NewComponent( compDataType.in() );
+  father  = aStudyBuilder->NewComponent( compDataType.c_str() );
   aStudyBuilder->DefineComponentInstance( father, SMESH_Gen::_this() );
   anAttr  = aStudyBuilder->FindOrCreateAttribute( father, "AttributePixMap" );
   aPixmap = anAttr;
@@ -598,7 +622,7 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::PublishMesh (SMESH::SMESH_Mesh_ptr theMesh,
     else
       aTag++;
 
-    aMeshSO = publish ( theMesh, father, aTag, "ICON_SMESH_TREE_MESH_WARN" );
+    aMeshSO = publish( theMesh, father, aTag, "ICON_SMESH_TREE_MESH_WARN" );
     if ( aMeshSO->_is_nil() )
       return aMeshSO._retn();
   }
@@ -670,6 +694,8 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::PublishSubMesh (SMESH::SMESH_Mesh_ptr    theM
   if ( theMesh->_is_nil() || theSubMesh->_is_nil() || theShapeObject->_is_nil() )
     return SALOMEDS::SObject::_nil();
 
+  std::string newName( theName ? theName : "" );
+
   SALOMEDS::SObject_wrap aSubMeshSO = ObjectToSObject( theSubMesh );
   if ( aSubMeshSO->_is_nil() )
   {
@@ -721,24 +747,47 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::PublishSubMesh (SMESH::SMESH_Mesh_ptr    theM
 
     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 = getStudyServant()->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 ( theSubMesh, aRootSO, 0, pm[isEmpty] );
+    aSubMeshSO = publish ( 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
 
-  addReference( aSubMeshSO, theShapeObject, 1 );
+  addReference( aSubMeshSO, theShapeObject, GetRefOnShapeTag() );
 
   // 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( aHyp );
     AddHypothesisToShape( theMesh, theShapeObject, aHyp );
@@ -791,21 +840,25 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::PublishGroup (SMESH::SMESH_Mesh_ptr  theMesh,
         SetName( aRootSO, aRootNames[aType] );
 
       // Add new group to corresponding sub-tree
-      int isEmpty = false;
+      int isEmpty = ( theMesh->NbNodes() == 0 );
       std::string pm[2] = { "ICON_SMESH_TREE_GROUP", "ICON_SMESH_TREE_MESH_WARN" };
-      if ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ))
-      {
-        pm[0] = "ICON_SMESH_TREE_GROUP_ON_FILTER";
-      }
-      else if ( SMESH::DownCast< SMESH_Group_i* > ( theGroup ))
+      if ( !isEmpty )
       {
-        if ( theGroup->GetType() == SMESH::NODE )
-          isEmpty = ( theMesh->NbNodes() == 0 );
-        else
+        if ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup )) // on filter
+        {
+          pm[0] = "ICON_SMESH_TREE_GROUP_ON_FILTER";
+
+          if ( theGroup->GetType() != SMESH::NODE )
+          {
+            isEmpty = true;
+            SMESH::array_of_ElementType_var allElemTypes = theMesh->GetTypes();
+            for ( size_t i =0; i < allElemTypes->length() && isEmpty; ++i )
+              isEmpty = ( allElemTypes[i] != theGroup->GetType() );
+          }
+        }
+        else // standalone or on geometry
         {
-          SMESH::array_of_ElementType_var allElemTypes = theMesh->GetTypes();
-          for ( size_t i =0; i < allElemTypes->length() && isEmpty; ++i )
-            isEmpty = ( allElemTypes[i] != theGroup->GetType() );
+          isEmpty = ( theGroup->Size() == 0 );
         }
       }
       aGroupSO = publish ( theGroup, aRootSO, 0, pm[isEmpty].c_str() );
@@ -818,21 +871,21 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::PublishGroup (SMESH::SMESH_Mesh_ptr  theMesh,
 
   //Add reference to geometry
   if ( !theShapeObject->_is_nil() )
-    addReference( aGroupSO, theShapeObject, 1 );
+    addReference( aGroupSO, theShapeObject, GetRefOnShapeTag() );
 
   return aGroupSO._retn();
 }
 
 //=======================================================================
 //function : PublishHypothesis
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 SALOMEDS::SObject_ptr
-  SMESH_Gen_i::PublishHypothesis (SMESH::SMESH_Hypothesis_ptr theHyp,
-                                  const char*                 theName)
+SMESH_Gen_i::PublishHypothesis (SMESH::SMESH_Hypothesis_ptr theHyp,
+                                const char*                 theName)
 {
-  if(MYDEBUG) MESSAGE("PublishHypothesis")
+  if(MYDEBUG) MESSAGE("PublishHypothesis");
   if ( !myIsEnablePublish )
     return SALOMEDS::SObject::_nil();
   if (theHyp->_is_nil())
@@ -946,6 +999,64 @@ void SMESH_Gen_i::UpdateIcons( SMESH::SMESH_Mesh_ptr theMesh )
   }
 }
 
+//=======================================================================
+//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(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 = getStudyServant()->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 : IsInvalid
+//purpose  : Check object validity == absence of AttributeTextColor=(178,34,34)
+//=======================================================================
+
+bool SMESH_Gen_i::IsInvalid( SALOMEDS::SObject_ptr theSObject )
+{
+  bool isValid = true;
+  if ( !theSObject->_is_nil() )
+  {
+    SALOMEDS::GenericAttribute_wrap attr;
+    SALOMEDS::StudyBuilder_var studyBuilder = getStudyServant()->NewBuilder();
+    if ( studyBuilder->FindAttribute( theSObject, attr.inout(), "AttributeTextColor" ))
+    {
+      SALOMEDS::AttributeTextColor_wrap colorAttr = attr;
+      SALOMEDS::Color color = colorAttr->TextColor();
+      isValid = ( color.R != 178 || color.G != 34 || color.B != 34 );
+    }
+  }
+  return isValid;
+}
+
 //=======================================================================
 //function : GetMeshOrSubmeshByShape
 //purpose  : 
@@ -1320,6 +1431,50 @@ 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( 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 = getStudyServant()->NewBuilder();
+          SALOMEDS::GenericAttribute_wrap attr =
+            studyBuilder->FindOrCreateAttribute( refSO, "AttributeDrawable" );
+          SALOMEDS::AttributeDrawable_wrap ga = attr;
+          ga->SetDrawable( false );
+        }
+      }
+    }
+  }
+  catch (...) {
+  }
+
+  return subMesh._retn();
+}
 
 
 // ==============