Salome HOME
PAL16202,16203 (Propagation 1D on edges group)
[modules/smesh.git] / src / StdMeshers / StdMeshers_Projection_1D.cxx
index acf89664b1a2b2bcc3a3d913c48cfa0291385d32..cfae225f3ef5c2eddf418edefc5433a3e6878e69 100644 (file)
 #include "SMESH_subMesh.hxx"
 #include "SMESH_subMeshEventListener.hxx"
 #include "SMESH_Gen.hxx"
+#include "SMESH_Comment.hxx"
 
 #include <BRepAdaptor_Curve.hxx>
 #include <BRep_Tool.hxx>
 #include <GCPnts_AbscissaPoint.hxx>
+#include <TopExp.hxx>
 #include <TopoDS.hxx>
 #include <gp_Pnt.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
 
 #include "utilities.h"
 
 
 using namespace std;
 
-#define RETURN_BAD_RESULT(msg) { MESSAGE(msg); return false; }
+#define RETURN_BAD_RESULT(msg) { MESSAGE(")-: Error: " << msg); return false; }
 
 typedef StdMeshers_ProjectionUtils TAssocTool;
 
@@ -96,13 +99,13 @@ bool StdMeshers_Projection_1D::CheckHypothesis(SMESH_Mesh&
   const list <const SMESHDS_Hypothesis * >&hyps = GetUsedHypothesis(aMesh, aShape);
   if ( hyps.size() == 0 )
   {
-    aStatus = SMESH_Hypothesis::HYP_MISSING;
+    aStatus = HYP_MISSING;
     return false;  // can't work with no hypothesis
   }
 
   if ( hyps.size() > 1 )
   {
-    aStatus = SMESH_Hypothesis::HYP_ALREADY_EXIST;
+    aStatus = HYP_ALREADY_EXIST;
     return false;
   }
 
@@ -110,7 +113,7 @@ bool StdMeshers_Projection_1D::CheckHypothesis(SMESH_Mesh&
 
   string hypName = theHyp->GetName();
 
-  aStatus = SMESH_Hypothesis::HYP_OK;
+  aStatus = HYP_OK;
 
   if (hypName == "ProjectionSource1D")
   {
@@ -129,18 +132,63 @@ bool StdMeshers_Projection_1D::CheckHypothesis(SMESH_Mesh&
       // source and target vertices
       if ( !TAssocTool::IsSubShape( _sourceHypo->GetSourceVertex(), srcMesh ) ||
            !TAssocTool::IsSubShape( _sourceHypo->GetTargetVertex(), tgtMesh ) ||
-           !TAssocTool::IsSubShape( _sourceHypo->GetTargetVertex(), aShape )  ||
            !TAssocTool::IsSubShape( _sourceHypo->GetSourceVertex(),
                                     _sourceHypo->GetSourceEdge() ))
-        aStatus = SMESH_Hypothesis::HYP_BAD_PARAMETER;
+      {
+        aStatus = HYP_BAD_PARAMETER;
+        SCRUTE((TAssocTool::IsSubShape( _sourceHypo->GetSourceVertex(), srcMesh )));
+        SCRUTE((TAssocTool::IsSubShape( _sourceHypo->GetTargetVertex(), tgtMesh )));
+        SCRUTE((TAssocTool::IsSubShape( _sourceHypo->GetSourceVertex(),
+                                        _sourceHypo->GetSourceEdge() )));
+      }
+      // PAL16202
+      else 
+      {
+        bool isSub = TAssocTool::IsSubShape( _sourceHypo->GetTargetVertex(), aShape );
+        if ( !_sourceHypo->IsCompoundSource() ) {
+          if ( !isSub ) {
+            aStatus = HYP_BAD_PARAMETER;
+            SCRUTE((TAssocTool::IsSubShape( _sourceHypo->GetTargetVertex(), aShape)));
+          }
+        }
+        else if ( isSub ) {
+          // is Ok provided that source vertex is shared only by one edge
+          // of the source group
+          TopoDS_Shape sharingEdge;
+          TopTools_ListIteratorOfListOfShape ancestIt
+            ( aMesh.GetAncestors( _sourceHypo->GetSourceVertex() ));
+          for ( ; ancestIt.More(); ancestIt.Next() )
+          {
+            const TopoDS_Shape& ancestor = ancestIt.Value();
+            if ( ancestor.ShapeType() == TopAbs_EDGE &&
+                 TAssocTool::IsSubShape( ancestor, _sourceHypo->GetSourceEdge() ))
+            {
+              if ( sharingEdge.IsNull() || ancestor.IsSame( sharingEdge ))
+                sharingEdge = ancestor;
+              else {
+                // the second encountered
+                aStatus = HYP_BAD_PARAMETER;
+                MESSAGE("Source vertex is shared by several edges of a group");
+                break;
+              }
+            }
+          }
+        }
+      }
     }
     // check source edge
-    if ( !TAssocTool::IsSubShape( _sourceHypo->GetSourceEdge(), srcMesh ))
-      aStatus = SMESH_Hypothesis::HYP_BAD_PARAMETER;
+    if ( !TAssocTool::IsSubShape( _sourceHypo->GetSourceEdge(), srcMesh ) ||
+         ( srcMesh == tgtMesh && aShape == _sourceHypo->GetSourceEdge() ))
+    {
+      aStatus = HYP_BAD_PARAMETER;
+      SCRUTE((TAssocTool::IsSubShape( _sourceHypo->GetSourceEdge(), srcMesh )));
+      SCRUTE((srcMesh == tgtMesh));
+      SCRUTE(( aShape == _sourceHypo->GetSourceEdge() ));
+    }
   }
   else
   {
-    aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
+    aStatus = HYP_INCOMPATIBLE;
   }
   return ( aStatus == HYP_OK );
 }
@@ -155,13 +203,6 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   if ( !_sourceHypo )
     return false;
 
-  TopoDS_Edge tgtEdge = TopoDS::Edge( theShape.Oriented(TopAbs_FORWARD));
-  TopoDS_Edge srcEdge = TopoDS::Edge( _sourceHypo->GetSourceEdge().Oriented(TopAbs_FORWARD));
-
-  TopoDS_Vertex tgtV[2], srcV[2];
-  TopExp::Vertices( tgtEdge, tgtV[0], tgtV[1] );
-  TopExp::Vertices( srcEdge, srcV[0], srcV[1] );
-
   SMESH_Mesh * srcMesh = _sourceHypo->GetSourceMesh(); 
   SMESH_Mesh * tgtMesh = & theMesh;
   if ( !srcMesh )
@@ -173,11 +214,23 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   // Make subshapes association
   // ---------------------------
 
+  TopoDS_Edge srcEdge, tgtEdge = TopoDS::Edge( theShape.Oriented(TopAbs_FORWARD));
+  TopoDS_Shape srcShape = _sourceHypo->GetSourceEdge().Oriented(TopAbs_FORWARD);
+
   TAssocTool::TShapeShapeMap shape2ShapeMap;
-  TAssocTool::InitVertexAssociation( _sourceHypo, shape2ShapeMap );
-  if ( !TAssocTool::FindSubShapeAssociation( tgtEdge, tgtMesh, srcEdge, srcMesh,
-                                             shape2ShapeMap) )
-    RETURN_BAD_RESULT("FindSubShapeAssociation failed");
+  TAssocTool::InitVertexAssociation( _sourceHypo, shape2ShapeMap, tgtEdge );
+  if ( !TAssocTool::FindSubShapeAssociation( tgtEdge, tgtMesh, srcShape, srcMesh,
+                                             shape2ShapeMap) ||
+       !shape2ShapeMap.IsBound( tgtEdge ))
+    return error("Vertices association failed" );
+
+  srcEdge = TopoDS::Edge( shape2ShapeMap( tgtEdge ).Oriented(TopAbs_FORWARD));
+//   cout << " srcEdge #" << srcMesh->GetMeshDS()->ShapeToIndex( srcEdge )
+//        << " tgtEdge #" << tgtMesh->GetMeshDS()->ShapeToIndex( tgtEdge ) << endl;
+
+  TopoDS_Vertex tgtV[2], srcV[2];
+  TopExp::Vertices( tgtEdge, tgtV[0], tgtV[1] );
+  TopExp::Vertices( srcEdge, srcV[0], srcV[1] );
 
   // ----------------------------------------------
   // Assure that mesh on a source edge is computed
@@ -188,11 +241,11 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
 
   if ( tgtMesh == srcMesh ) {
     if ( !TAssocTool::MakeComputed( srcSubMesh ))
-      RETURN_BAD_RESULT("Impossible to compute the source mesh");
+      return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
   }
   else {
     if ( !srcSubMesh->IsMeshComputed() )
-      RETURN_BAD_RESULT("Source mesh is not computed");
+      return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
   }
   // -----------------------------------------------
   // Find out nodes distribution on the source edge
@@ -203,7 +256,7 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   
   vector< double > params; // sorted parameters of nodes on the source edge
   if ( !SMESH_Algo::GetNodeParamOnEdge( srcMesh->GetMeshDS(), srcEdge, params ))
-    RETURN_BAD_RESULT("Bad node params on the source edge");
+    return error(COMPERR_BAD_INPUT_MESH,"Bad node parameters on the source edge");
 
   int i, nbNodes = params.size();
 
@@ -222,7 +275,7 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   }
 
   bool reverse = ( srcV[0].IsSame( shape2ShapeMap( tgtV[1] )));
-  if ( shape2ShapeMap.IsBound( tgtEdge )) // case of closed edge
+  if ( tgtV[0].IsSame( tgtV[1] )) // case of closed edge
     reverse = ( shape2ShapeMap( tgtEdge ).Orientation() == TopAbs_REVERSED );
   if ( reverse ) // reverse lengths of segments
     std::reverse( lengths.begin(), lengths.end() );
@@ -235,20 +288,10 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   vector< const SMDS_MeshNode* > nodes ( nbNodes );
 
   // Get the first and last nodes
-  // -----------------------------
-
-  SMESHDS_SubMesh* smV0 = meshDS->MeshElements( tgtV[0] );
-  SMESHDS_SubMesh* smV1 = meshDS->MeshElements( tgtV[1] );
-  if ( !smV0 || !smV1 )
-    RETURN_BAD_RESULT("No submeshes on vertices");
-
-  SMDS_NodeIteratorPtr nItV0 = smV0->GetNodes();
-  SMDS_NodeIteratorPtr nItV1 = smV1->GetNodes();
-  if ( !nItV0->more() || !nItV1->more() )
-    RETURN_BAD_RESULT("No nodes on vertices");
-
-  nodes.front() = nItV0->next();
-  nodes.back()  = nItV1->next();
+  nodes.front() = VertexNode( tgtV[0], meshDS );
+  nodes.back()  = VertexNode( tgtV[1], meshDS );
+  if ( !nodes.front() || !nodes.back() )
+    return error(COMPERR_BAD_INPUT_MESH,"No node on vertex");
 
   // Compute parameters on the target edge and make internal nodes
   // --------------------------------------------------------------
@@ -271,7 +314,7 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
       // from the point at given parameter.
       GCPnts_AbscissaPoint Discret( curveAdaptor, dl * lengths[ i-1 ], tgtParams[ i-1 ] );
       if ( !Discret.IsDone() )
-        RETURN_BAD_RESULT(" GCPnts_AbscissaPoint failed");
+        return error("GCPnts_AbscissaPoint failed");
       tgtParams[ i ] = Discret.Parameter();
     }
     // make internal nodes 
@@ -311,7 +354,8 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   }
   // enough nodes to make all edges quadratic?
   if ( quadratic && ( nbNodes < 3 || ( nbNodes % 2 != 1 )))
-    RETURN_BAD_RESULT("Wrong nb nodes to make quadratic mesh");
+    return error(COMPERR_BAD_INPUT_MESH,
+                 SMESH_Comment("Wrong number of nodes to make quadratic mesh: ")<<nbNodes);
 
   // Create edges
   // -------------
@@ -344,19 +388,7 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
 
 void StdMeshers_Projection_1D::SetEventListener(SMESH_subMesh* subMesh)
 {
-  if ( _sourceHypo && ! _sourceHypo->GetSourceEdge().IsNull() )
-  {
-    SMESH_Mesh* srcMesh = _sourceHypo->GetSourceMesh();
-    if ( !srcMesh )
-      srcMesh = subMesh->GetFather();
-
-    SMESH_subMesh* srcEdgeSM =
-      srcMesh->GetSubMesh( _sourceHypo->GetSourceEdge() );
-
-    if ( srcEdgeSM != subMesh )
-      subMesh->SetEventListener( new SMESH_subMeshEventListener(),
-                                 SMESH_subMeshEventListenerData::MakeData( subMesh ),
-                                 srcEdgeSM );
-  }
+  TAssocTool::SetEventListener( subMesh,
+                                _sourceHypo->GetSourceEdge(),
+                                _sourceHypo->GetSourceMesh() );
 }
-