Salome HOME
23036: [CEA 1459] Regression projection 1D2D
authoreap <eap@opencascade.com>
Tue, 7 Apr 2015 17:39:18 +0000 (20:39 +0300)
committereap <eap@opencascade.com>
Tue, 7 Apr 2015 17:39:18 +0000 (20:39 +0300)
+ Fix Pb: SIGSEGV in StdMeshers_Prism_3D::IsApplicable() on the shape of 23036
+ Fix Pb: "Projection 3D" algo is available in Create mesh dlg on the shape of 23036
+ Add debug trace in case of exceptions in IsApplicable()
+ Fix 52667: SIGSEGV at attempt to create mesh without Geometry when setting hypothesis

src/SMESH_I/SMESH_Gen_i.cxx
src/StdMeshers/StdMeshers_Hexa_3D.hxx
src/StdMeshers/StdMeshers_Prism_3D.cxx
src/StdMeshers/StdMeshers_ProjectionUtils.cxx
src/StdMeshers/StdMeshers_Projection_2D.cxx
src/StdMeshers/StdMeshers_Projection_3D.cxx
src/StdMeshers/StdMeshers_Projection_3D.hxx
src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.cxx
src/StdMeshers_I/StdMeshers_Projection_1D_2D_3D_i.cxx
src/StdMeshers_I/StdMeshers_Projection_1D_2D_3D_i.hxx
src/StdMeshers_I/StdMeshers_i.cxx

index 4683529..58bbe32 100644 (file)
@@ -5140,8 +5140,7 @@ CORBA::Boolean SMESH_Gen_i::IsApplicable ( const char*           theAlgoType,
   if (aCreator)
   {
     TopoDS_Shape shape = GeomObjectToShape( theGeomObject );
-    if ( !shape.IsNull() )
-      return aCreator->IsApplicable( shape, toCheckAll );
+    return shape.IsNull() || aCreator->IsApplicable( shape, toCheckAll );
   }
   else
   {
@@ -5149,6 +5148,10 @@ CORBA::Boolean SMESH_Gen_i::IsApplicable ( const char*           theAlgoType,
   }
 
   SMESH_CATCH( SMESH::doNothing );
+
+#ifdef _DEBUG_
+  cout << "SMESH_Gen_i::IsApplicable(): exception in " << ( theAlgoType ? theAlgoType : "") << endl;
+#endif
   return true;
 }
 
index 415db0d..e186863 100644 (file)
@@ -55,7 +55,8 @@ public:
                         MapShapeNbElems& aResMap);
 
   static bool IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll);
-protected:
+
+ protected:
 
   const StdMeshers_ViscousLayers* _viscousLayersHyp;
 };
index 343a347..0bd7070 100644 (file)
@@ -2549,7 +2549,7 @@ namespace // utils used by StdMeshers_Prism_3D::IsApplicable()
       for ( iE = 0; iE < *nbE; ++e, ++iE )
         if ( SMESH_Algo::isDegenerated( *e ))
         {
-          ee.erase( e );
+          e = --ee.erase( e );
           --(*nbE);
           --iE;
         }
index a21f5d7..85ecfac 100644 (file)
@@ -756,6 +756,10 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
           TopoDS_Face nextFace1 = GetNextFace( edgeToFace1, *eIt1, face1 );
           TopoDS_Face nextFace2 = GetNextFace( edgeToFace2, *eIt2, face2 );
           if ( !nextFace1.IsNull() && !nextFace2.IsNull() ) {
+            if ( SMESH_MesherHelper::GetSubShapeOri( nextFace1, *eIt1 ) == eIt1->Orientation() )
+              nextFace1.Reverse();
+            if ( SMESH_MesherHelper::GetSubShapeOri( nextFace2, *eIt2 ) == eIt2->Orientation() )
+              nextFace2.Reverse();
             FE1.push_back( make_pair( nextFace1, *eIt1 ));
             FE2.push_back( make_pair( nextFace2, *eIt2 ));
           }
@@ -1170,11 +1174,11 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
       if ( !VV1[1].IsNull() ) {
         InsertAssociation( VV1[0], VV2[0], theMap );
         InsertAssociation( VV1[1], VV2[1], theMap );
+        TShapeShapeMap::EAssocType asType = theMap._assocType;
+        theMap.SetAssocType( TShapeShapeMap::PROPAGATION );
         if ( FindSubShapeAssociation( theShape1, theMesh1, theShape2, theMesh2, theMap ))
-        {
-          theMap.SetAssocType( TShapeShapeMap::PROPAGATION );
           return true;
-        }
+        theMap._assocType = asType;
       }
     }
     break; // try by vertex closeness
@@ -1230,11 +1234,11 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
       {
         InsertAssociation( VV1[0], VV1[0], theMap );
         InsertAssociation( VV1[1], VV1[1], theMap );
-        if (FindSubShapeAssociation( theShape1, theMesh1, theShape2, theMesh2, theMap ))
-        {
-          theMap.SetAssocType( TShapeShapeMap::COMMON_VERTEX );
+        TShapeShapeMap::EAssocType asType = theMap._assocType;
+        theMap.SetAssocType( TShapeShapeMap::COMMON_VERTEX );
+        if ( FindSubShapeAssociation( theShape1, theMesh1, theShape2, theMesh2, theMap ))
           return true;
-        }
+        theMap._assocType = asType;
       }
     }
   }
@@ -1593,20 +1597,21 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face&    face1,
               // reverse edges2 if needed
               if ( SMESH_MesherHelper::IsClosedEdge( *edge1Beg ))
               {
-                double f,l;
-                Handle(Geom2d_Curve) c1 = BRep_Tool::CurveOnSurface( *edge1Beg, face1,f,l );
-                if (  edge1Beg->Orientation() == TopAbs_REVERSED )
-                  std::swap( f,l );
-                gp_Pnt2d uv1 = dUV + c1->Value( f * 0.8 + l * 0.2 ).XY();
-
-                Handle(Geom2d_Curve) c2 = BRep_Tool::CurveOnSurface( *edge2Beg, face2,f,l );
-                if (  edge2Beg->Orientation() == TopAbs_REVERSED )
-                  std::swap( f,l );
-                gp_Pnt2d uv2 = c2->Value( f * 0.8 + l * 0.2 );
-                gp_Pnt2d uv3 = c2->Value( l * 0.8 + f * 0.2 );
-
-                if ( uv1.SquareDistance( uv2 ) > uv1.SquareDistance( uv3 ))
-                  edge2Beg->Reverse();
+                // Commented (so far?) as it's not checked if orientation must be same or reversed
+                // double f,l;
+                // Handle(Geom2d_Curve) c1 = BRep_Tool::CurveOnSurface( *edge1Beg, face1,f,l );
+                // if (  edge1Beg->Orientation() == TopAbs_REVERSED )
+                //   std::swap( f,l );
+                // gp_Pnt2d uv1 = dUV + c1->Value( f * 0.8 + l * 0.2 ).XY();
+
+                // Handle(Geom2d_Curve) c2 = BRep_Tool::CurveOnSurface( *edge2Beg, face2,f,l );
+                // if (  edge2Beg->Orientation() == TopAbs_REVERSED )
+                //   std::swap( f,l );
+                // gp_Pnt2d uv2 = c2->Value( f * 0.8 + l * 0.2 );
+                // gp_Pnt2d uv3 = c2->Value( l * 0.8 + f * 0.2 );
+
+                // if ( uv1.SquareDistance( uv2 ) > uv1.SquareDistance( uv3 ))
+                //   edge2Beg->Reverse();
               }
               else
               {
index bde99cd..2db02b2 100644 (file)
@@ -427,15 +427,44 @@ namespace {
     // get ordered src EDGEs
     TError err;
     srcWires = StdMeshers_FaceSide::GetFaceWires( srcFace, *srcMesh,/*skipMediumNodes=*/0, err);
-    if ( err && !err->IsOK() )
+    if ( err && !err->IsOK() || srcWires.empty() )
       return err;
 
+    SMESH_MesherHelper srcHelper( *srcMesh );
+    srcHelper.SetSubShape( srcFace );
+
     // make corresponding sequence of tgt EDGEs
     tgtWires.resize( srcWires.size() );
     for ( size_t iW = 0; iW < srcWires.size(); ++iW )
     {
-      list< TopoDS_Edge > tgtEdges;
+      // check ori
+      bool reverse = false;
       StdMeshers_FaceSidePtr srcWire = srcWires[iW];
+      // for ( int iE = 0; iE < srcWire->NbEdges(); ++iE )
+      // {
+      //   if ( srcHelper.IsRealSeam( srcWire->EdgeID( iE )))
+      //     continue;
+      //   TopoDS_Shape srcE = srcWire->Edge( iE );
+      //   TopoDS_Shape tgtE = shape2ShapeMap( srcE, /*isSrc=*/true);
+      //   if ( shape2ShapeMap._assocType == TShapeShapeMap::PROPAGATION ||
+      //        shape2ShapeMap._assocType == TShapeShapeMap::PROPAGATION)
+      //   {
+      //     reverse = false;
+      //   }
+      //   else if ( tgtMesh == srcMesh )
+      //   {
+      //     reverse = (( srcE.Orientation() == srcHelper.GetSubShapeOri( srcFace, srcE )) !=
+      //                ( tgtE.Orientation() == srcHelper.GetSubShapeOri( tgtFace, tgtE )));
+      //   }
+      //   else
+      //   {
+      //     TopoDS_Shape srcEbis = shape2ShapeMap( tgtE, /*isSrc=*/false );
+      //     reverse = ( srcE.Orientation() != srcEbis.Orientation() );
+      //   }
+      //   break;
+      // }
+
+      list< TopoDS_Edge > tgtEdges;
       TopTools_IndexedMapOfShape edgeMap; // to detect seam edges
       for ( int iE = 0; iE < srcWire->NbEdges(); ++iE )
       {
@@ -443,6 +472,7 @@ namespace {
         TopoDS_Edge     tgtE = TopoDS::Edge( shape2ShapeMap( srcE, /*isSrc=*/true));
         TopoDS_Shape srcEbis = shape2ShapeMap( tgtE, /*isSrc=*/false );
         if ( srcE.Orientation() != srcEbis.Orientation() )
+          //if ( reverse )
           tgtE.Reverse();
         // reverse a seam edge encountered for the second time
         const int index = edgeMap.Add( tgtE );
@@ -999,6 +1029,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
     srcMesh = tgtMesh;
 
   SMESHDS_Mesh * meshDS = theMesh.GetMeshDS();
+  SMESH_MesherHelper helper( theMesh );
 
   // ---------------------------
   // Make sub-shapes association
@@ -1015,8 +1046,8 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   {
     if ( srcShape.ShapeType() == TopAbs_FACE )
     {
-      int nbE1 = SMESH_MesherHelper::Count( tgtFace, TopAbs_EDGE, /*ignoreSame=*/true );
-      int nbE2 = SMESH_MesherHelper::Count( srcShape, TopAbs_EDGE, /*ignoreSame=*/true );
+      int nbE1 = helper.Count( tgtFace, TopAbs_EDGE, /*ignoreSame=*/true );
+      int nbE2 = helper.Count( srcShape, TopAbs_EDGE, /*ignoreSame=*/true );
       if ( nbE1 != nbE2 )
         return error(COMPERR_BAD_SHAPE,
                      SMESH_Comment("Different number of edges in source and target faces: ")
@@ -1026,6 +1057,23 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   }
   TopoDS_Face srcFace = TopoDS::Face( shape2ShapeMap( tgtFace ).Oriented(TopAbs_FORWARD));
 
+  // orient faces
+  // if ( srcMesh == tgtMesh )
+  // {
+  //   TopoDS_Shape solid =
+  //     helper.GetCommonAncestor( srcFace, tgtFace, *tgtMesh, TopAbs_SOLID );
+  //   if ( !solid.IsNull() )
+  //   {
+  //     srcFace.Orientation( helper.GetSubShapeOri( solid, srcFace ));
+  //     tgtFace.Orientation( helper.GetSubShapeOri( solid, tgtFace ));
+  //   }
+  //   else if ( helper.NbAncestors( srcFace, *tgtMesh, TopAbs_SOLID ) == 1 &&
+  //             helper.NbAncestors( tgtFace, *tgtMesh, TopAbs_SOLID ) == 1 )
+  //   {
+  //     srcFace.Orientation( helper.GetSubShapeOri( tgtMesh->GetShapeToMesh(), srcFace ));
+  //     tgtFace.Orientation( helper.GetSubShapeOri( tgtMesh->GetShapeToMesh(), tgtFace ));
+  //   }
+  // }
   // ----------------------------------------------
   // Assure that mesh on a source Face is computed
   // ----------------------------------------------
@@ -1072,7 +1120,6 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
                                       shape2ShapeMap, _src2tgtNodes, is1DComputed);
   }
 
-  SMESH_MesherHelper helper( theMesh );
   helper.SetSubShape( tgtFace );
 
   // it will remove mesh built on edges and vertices in failure case
@@ -1308,8 +1355,8 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
              u2nodesOnSeam.size()            > 0 &&
              seam.ShapeType() == TopAbs_EDGE )
         {
-          int nbE1 = SMESH_MesherHelper::Count( tgtFace, TopAbs_EDGE, /*ignoreSame=*/true );
-          int nbE2 = SMESH_MesherHelper::Count( srcFace, TopAbs_EDGE, /*ignoreSame=*/true );
+          int nbE1 = helper.Count( tgtFace, TopAbs_EDGE, /*ignoreSame=*/true );
+          int nbE2 = helper.Count( srcFace, TopAbs_EDGE, /*ignoreSame=*/true );
           if ( nbE1 != nbE2 ) // 2 EDGEs are mapped to a seam EDGE
           {
             // find the 2 EDGEs of srcFace
index e6a76ed..1dc3ace 100644 (file)
@@ -541,3 +541,39 @@ void StdMeshers_Projection_3D::SetEventListener(SMESH_subMesh* subMesh)
                                 _sourceHypo->GetSourceMesh() );
 }
   
+//================================================================================
+/*!
+ * \brief Return true if the algorithm can mesh this shape
+ *  \param [in] aShape - shape to check
+ *  \param [in] toCheckAll - if true, this check returns OK if all shapes are OK,
+ *              else, returns OK if at least one shape is OK
+ */
+//================================================================================
+
+bool StdMeshers_Projection_3D::IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll)
+{
+  TopExp_Explorer exp0( aShape, TopAbs_SOLID );
+  if ( !exp0.More() ) return false;
+
+  TopTools_IndexedMapOfOrientedShape blockShapes;
+  TopoDS_Vertex v;
+  TopoDS_Shell shell;
+  for ( ; exp0.More(); exp0.Next() )
+  {
+    int nbFoundShells = 0;
+    TopExp_Explorer exp1( exp0.Current(), TopAbs_SHELL );
+    for ( ; exp1.More(); exp1.Next(), ++nbFoundShells )
+    {
+      shell = TopoDS::Shell( exp1.Current() );
+      if ( nbFoundShells == 2 ) break;
+    }
+    if ( nbFoundShells != 1 ) {
+      if ( toCheckAll ) return false;
+      continue;
+    }   
+    bool isBlock = SMESH_Block::FindBlockShapes( shell, v, v, blockShapes );
+    if ( toCheckAll && !isBlock ) return false;
+    if ( !toCheckAll && isBlock ) return true;
+  }
+  return toCheckAll;
+}
index e0895ba..27e1773 100644 (file)
@@ -57,7 +57,9 @@ public:
    */
   virtual void SetEventListener(SMESH_subMesh* whenSetToSubMesh);
   
-protected:
+  static bool IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll);
+
+ protected:
 
   const StdMeshers_ProjectionSource3D* _sourceHypo;
 
index cfb8016..0d86a14 100644 (file)
@@ -223,6 +223,7 @@ QFrame* StdMeshersGUI_NbSegmentsCreator::buildFrame()
   lay->setStretchFactor( GroupC1, 1);
   lay->setStretchFactor( myReversedEdgesBox, 1);
 
+  myReversedEdgesHelper = 0;
   if ( !aGeomEntry.isEmpty() || !aMainEntry.isEmpty() )
   {
     myReversedEdgesHelper = new StdMeshersGUI_PropagationHelperWdg( myDirectionWidget, fr, false );
index 4f7a924..dfe12ad 100644 (file)
@@ -66,6 +66,17 @@ StdMeshers_Projection_3D_i::~StdMeshers_Projection_3D_i()
   return ( ::StdMeshers_Projection_3D* )myBaseImpl;
 }
 
+//================================================================================
+/*!
+ * \brief Return true if the algorithm is applicable to a shape
+ */
+//================================================================================
+
+CORBA::Boolean StdMeshers_Projection_3D_i::IsApplicable(const TopoDS_Shape &S,
+                                                        CORBA::Boolean toCheckAll)
+{
+  return ::StdMeshers_Projection_3D::IsApplicable( S, toCheckAll );
+}
 
 //=============================================================================
 /*!
index 58413c1..f2b65aa 100644 (file)
@@ -37,6 +37,7 @@
 #include "StdMeshers_Projection_3D.hxx"
 
 class SMESH_Gen;
+class TopoDS_Shape;
 
 // ======================================================
 // Projection 3D algorithm
@@ -57,6 +58,9 @@ public:
 
   // Get implementation
   ::StdMeshers_Projection_3D* GetImpl();
+
+  // Return true if the algorithm is applicable to a shape
+  static CORBA::Boolean IsApplicable(const TopoDS_Shape &S, CORBA::Boolean toCheckAll);
 };
 
 // ======================================================
index f794db2..c7ae1a7 100644 (file)
@@ -225,7 +225,7 @@ STDMESHERS_I_EXPORT
     else if (strcmp(aHypName, "Projection_2D") == 0)
       aCreator = new StdHypothesisCreator_i<StdMeshers_Projection_2D_i>;
     else if (strcmp(aHypName, "Projection_3D") == 0)
-      aCreator = new StdHypothesisCreator_i<StdMeshers_Projection_3D_i, StdMeshers_Hexa_3D_i>;
+      aCreator = new StdHypothesisCreator_i<StdMeshers_Projection_3D_i, StdMeshers_Projection_3D_i>;
     else if (strcmp(aHypName, "Prism_3D") == 0)
       aCreator = new StdHypothesisCreator_i<StdMeshers_Prism_3D_i, StdMeshers_Prism_3D_i>;
     else if (strcmp(aHypName, "RadialPrism_3D") == 0)