Salome HOME
Merge from BR_imps_2013 14/01/2014
[modules/smesh.git] / src / StdMeshers / StdMeshers_Propagation.cxx
index c6b9b015fb50193491cfb8dd7525e74b8cfe26f4..15bd1944cc121a3faad57c2caa4a587848ec2e59 100644 (file)
@@ -1,34 +1,36 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2013  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
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 //
-//  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.
+// 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.
 //
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_Propagation.cxx
 //  Module : SMESH
-
+//
 #include "StdMeshers_Propagation.hxx"
 
 #include "utilities.h"
 
 #include "SMDS_SetIterator.hxx"
 #include "SMESH_Algo.hxx"
+#include "SMESH_Gen.hxx"
 #include "SMESH_HypoFilter.hxx"
 #include "SMESH_Mesh.hxx"
 #include "SMESH_subMesh.hxx"
@@ -39,7 +41,7 @@
 #include <TopoDS.hxx>
 
 #define DBGMSG(txt) \
-//  cout << txt << endl;
+  //  cout << txt << endl;
 
 using namespace std;
 
@@ -62,7 +64,8 @@ namespace {
     /*!
      * \brief Return an edge from which hypotheses are propagated from
      */
-    static TopoDS_Edge GetSource(SMESH_subMesh * submesh);
+    static TopoDS_Edge GetSource(SMESH_subMesh * submesh,
+                                 bool&           isPropagOfDistribution);
     /*!
      * \brief Does it's main job
      */
@@ -88,23 +91,28 @@ StdMeshers_Propagation::StdMeshers_Propagation (int hypId, int studyId, SMESH_Ge
   _name = GetName();
   _param_algo_dim = -1; // 1D auxiliary
 }
+StdMeshers_PropagOfDistribution::StdMeshers_PropagOfDistribution (int hypId,
+                                                                  int studyId,
+                                                                  SMESH_Gen * gen)
+  : StdMeshers_Propagation(hypId, studyId, gen)                        { _name = GetName(); }
 StdMeshers_Propagation::~StdMeshers_Propagation()                      {}
 string StdMeshers_Propagation::GetName ()                              { return "Propagation"; }
+string StdMeshers_PropagOfDistribution::GetName ()                     { return "PropagOfDistribution"; }
 ostream & StdMeshers_Propagation::SaveTo (ostream & save)              { return save; }
 istream & StdMeshers_Propagation::LoadFrom (istream & load)            { return load; }
-ostream & operator << (ostream & save, StdMeshers_Propagation & hyp)   { return hyp.SaveTo(save); }
-istream & operator >> (istream & load, StdMeshers_Propagation & hyp)   { return hyp.LoadFrom(load); }
 bool StdMeshers_Propagation::SetParametersByMesh(const SMESH_Mesh*,
                                                  const TopoDS_Shape& ) { return false; }
 bool StdMeshers_Propagation::SetParametersByDefaults(const TDefaults&,const SMESH_Mesh*) { return false; }
 void StdMeshers_Propagation::SetPropagationMgr(SMESH_subMesh* subMesh) { PropagationMgr::Set( subMesh ); }
 /*!
- * \brief Return an edge from which hypotheses are propagated from
+ * \brief Return an edge from which hypotheses are propagated
  */
-TopoDS_Edge StdMeshers_Propagation::GetPropagationSource(SMESH_Mesh& theMesh,
-                                                         const TopoDS_Shape& theEdge)
+TopoDS_Edge StdMeshers_Propagation::GetPropagationSource(SMESH_Mesh&         theMesh,
+                                                         const TopoDS_Shape& theEdge,
+                                                         bool&               isPropagOfDistribution)
 {
-  return PropagationMgr::GetSource(theMesh.GetSubMeshContaining( theEdge ));
+  return PropagationMgr::GetSource( theMesh.GetSubMeshContaining( theEdge ),
+                                    isPropagOfDistribution);
 }
 
 //=============================================================================
@@ -124,11 +132,13 @@ namespace {
   struct PropagationMgrData : public EventListenerData
   {
     bool myForward; //!< true if a curve of edge in chain is codirected with one of source edge
+    bool myIsPropagOfDistribution; //!< type of Propagation hyp
     PropagationMgrData( SubMeshState state=WAIT_PROPAG_HYP ): EventListenerData(true) {
-      myType = state; myForward = true;
+      myType = state; myForward = true; myIsPropagOfDistribution = false;
     }
     void Init() {
       myType = WAIT_PROPAG_HYP;  mySubMeshes.clear(); myForward = true;
+      myIsPropagOfDistribution = false;
     }
     SubMeshState State() const {
       return (SubMeshState) myType;
@@ -215,8 +225,13 @@ namespace {
   const SMESH_Hypothesis* getProagationHyp (SMESH_Mesh&         theMesh,
                                             const TopoDS_Shape& theEdge)
   {
-    static SMESH_HypoFilter propagHypFilter
-      ( SMESH_HypoFilter::HasName( StdMeshers_Propagation::GetName ()));
+    static SMESH_HypoFilter propagHypFilter;
+    if ( propagHypFilter.IsEmpty() )
+    {
+      propagHypFilter.
+        Init( SMESH_HypoFilter::HasName( StdMeshers_Propagation::GetName ())).
+        Or  ( SMESH_HypoFilter::HasName( StdMeshers_PropagOfDistribution::GetName ()));
+    }
     return theMesh.GetHypothesis( theEdge, propagHypFilter, true );
   }
   //================================================================================
@@ -246,6 +261,10 @@ namespace {
     PropagationMgrData* chainData = getData( theMainSubMesh );
     chainData->SetState( HAS_PROPAG_HYP );
 
+    if ( const SMESH_Hypothesis * propagHyp = getProagationHyp( *mesh, theMainEdge ))
+      chainData->myIsPropagOfDistribution =
+        ( StdMeshers_PropagOfDistribution::GetName() == propagHyp->GetName() );
+
     // Edge submeshes, to which the 1D hypothesis will be propagated from theMainEdge
     list<SMESH_subMesh*> & chain = chainData->mySubMeshes;
     chain.clear();
@@ -266,7 +285,7 @@ namespace {
       for (; itA.More(); itA.Next())
       {
         // there are objects of different type among the ancestors of edge
-        if ( itA.Value().ShapeType() != TopAbs_WIRE || !checkedShapes.Add( itA.Value() ))
+        if ( itA.Value().ShapeType() != TopAbs_WIRE /*|| !checkedShapes.Add( itA.Value() )*/)
           continue;
 
         // Get ordered edges and find index of anE in a sequence
@@ -288,8 +307,7 @@ namespace {
           continue; // too few edges
         }
         else if ( edges.size() == 4 ) {
-          int oppIndex = edgeIndex + 2;
-          if ( oppIndex > 3 ) oppIndex -= 4;
+          int oppIndex = ( edgeIndex + 2 ) % 4;
           anOppE = edges[ oppIndex ];
         }
         else {
@@ -346,6 +364,10 @@ namespace {
             oppSM->ComputeStateEngine( SMESH_subMesh::CLEAN );
             oppData->SetState( IN_CHAIN );
             DBGMSG( "set IN_CHAIN on " << oppSM->GetId() );
+            if ( oppSM->GetAlgoState() != SMESH_subMesh::HYP_OK )
+              // make oppSM check algo state
+              if ( SMESH_Algo* algo = mesh->GetGen()->GetAlgo( *mesh, anOppE ))
+                oppSM->AlgoStateEngine(SMESH_subMesh::ADD_FATHER_ALGO,algo);
           }
           else {
             oppData->SetState( LAST_IN_CHAIN );
@@ -444,7 +466,8 @@ namespace {
   //================================================================================
 
   PropagationMgr::PropagationMgr()
-    : SMESH_subMeshEventListener( false ) // won't be deleted by submesh
+    : SMESH_subMeshEventListener( false, // won't be deleted by submesh
+                                  "StdMeshers_Propagation::PropagationMgr")
   {}
   //================================================================================
   /*!
@@ -454,18 +477,23 @@ namespace {
 
   void PropagationMgr::Set(SMESH_subMesh * submesh)
   {
+    if ( findData( submesh )) return;
     DBGMSG( "PropagationMgr::Set() on  " << submesh->GetId() );
-    EventListenerData* data = new PropagationMgrData();
+    PropagationMgrData* data = new PropagationMgrData();
     submesh->SetEventListener( getListener(), data, submesh );
 
     const SMESH_Hypothesis * propagHyp =
       getProagationHyp( *submesh->GetFather(), submesh->GetSubShape() );
     if ( propagHyp )
+    {
+      data->myIsPropagOfDistribution =
+        ( StdMeshers_PropagOfDistribution::GetName() == propagHyp->GetName() );
       getListener()->ProcessEvent( SMESH_subMesh::ADD_HYP,
                                    SMESH_subMesh::ALGO_EVENT,
                                    submesh,
                                    data,
                                    propagHyp);
+    }
   }
   //================================================================================
   /*!
@@ -473,7 +501,8 @@ namespace {
    */
   //================================================================================
 
-  TopoDS_Edge PropagationMgr::GetSource(SMESH_subMesh * submesh)
+  TopoDS_Edge PropagationMgr::GetSource(SMESH_subMesh * submesh,
+                                        bool&           isPropagOfDistribution)
   {
     if ( PropagationMgrData* data = findData( submesh )) {
       if ( data->State() == IN_CHAIN ) {
@@ -482,6 +511,9 @@ namespace {
           TopoDS_Shape edge = sm->GetSubShape();
           edge = edge.Oriented( data->myForward ? TopAbs_FORWARD : TopAbs_REVERSED );
           DBGMSG( " GetSource() = edge " << sm->GetId() << " REV = " << (!data->myForward));
+          isPropagOfDistribution = false;
+          if ( PropagationMgrData* data = findData( sm ))
+            isPropagOfDistribution = data->myIsPropagOfDistribution;
           if ( edge.ShapeType() == TopAbs_EDGE )
             return TopoDS::Edge( edge );
         }
@@ -495,9 +527,9 @@ namespace {
    */
   //================================================================================
 
-  void PropagationMgr::ProcessEvent(const int          event,
-                                    const int          eventType,
-                                    SMESH_subMesh*     subMesh,
+  void PropagationMgr::ProcessEvent(const int                       event,
+                                    const int                       eventType,
+                                    SMESH_subMesh*                  subMesh,
                                     SMESH_subMeshEventListenerData* listenerData,
                                     const SMESH_Hypothesis*         hyp)
   {
@@ -509,7 +541,8 @@ namespace {
       return;
     DBGMSG( "PropagationMgr::ProcessEvent() on  " << subMesh->GetId() );
 
-    bool isPropagHyp = ( StdMeshers_Propagation::GetName() == hyp->GetName() );
+    bool isPropagHyp = ( StdMeshers_Propagation::GetName()          == hyp->GetName() ||
+                         StdMeshers_PropagOfDistribution::GetName() == hyp->GetName() );
 
     PropagationMgrData* data = static_cast<PropagationMgrData*>( listenerData );
     switch ( data->State() ) {