Salome HOME
23050: EDF 10631 SMESH: Nodes outside the plane after ConvertToQuadratic
authoreap <eap@opencascade.com>
Thu, 23 Apr 2015 14:24:53 +0000 (17:24 +0300)
committereap <eap@opencascade.com>
Thu, 23 Apr 2015 14:24:53 +0000 (17:24 +0300)
    Fix SMESH_MesherHelper::FixQuadraticElements()

Bug: SIGSEGV in Convert To Quadratic after mesh.Clear() if the previous Convert reported a warning
Bug: Group On Filter with BelongToMeshGroup is not updated if refers to a group with BelongToPlane

src/Controls/SMESH_Controls.cxx
src/SMESH/SMESH_MesherHelper.cxx
src/SMESH_I/SMESH_MeshEditor_i.cxx

index 267fc2a281706a87f8c345a78b92aadc95d81adf..714f48e97d304055a7ef490e19842c6a4b970c6d 100644 (file)
@@ -3856,6 +3856,10 @@ void BelongToMeshGroup::SetMesh( const SMDS_Mesh* theMesh )
           myGroup = *g;
     }
   }
+  if ( myGroup )
+  {
+    myGroup->IsEmpty(); // make GroupOnFilter update its predicate
+  }
 }
 
 bool BelongToMeshGroup::IsSatisfy( long theElementId )
index 99a33d678d5af07277342d897ebfe28a61cfd95a..2ba354d20866b55266980d59fa561136e96bda5b 100644 (file)
@@ -3301,12 +3301,13 @@ namespace { // Structures used by FixQuadraticElements()
     mutable vector<const QFace* > _faces;
     mutable gp_Vec                _nodeMove;
     mutable int                   _nbMoves;
+    mutable bool                  _is2dFixed; // is moved along surface or in 3D
 
     QLink(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2, const SMDS_MeshNode* nm):
       SMESH_TLink( n1,n2 ), _mediumNode(nm), _nodeMove(0,0,0), _nbMoves(0) {
       _faces.reserve(4);
-      //if ( MediumPos() != SMDS_TOP_3DSPACE )
-        _nodeMove = MediumPnt() - MiddlePnt();
+      _nodeMove = MediumPnt() - MiddlePnt();
+      _is2dFixed = ( MediumPos() != SMDS_TOP_FACE );
     }
     void SetContinuesFaces() const;
     const QFace* GetContinuesFace( const QFace* face ) const;
@@ -3321,10 +3322,11 @@ namespace { // Structures used by FixQuadraticElements()
     const SMDS_MeshNode* EndPosNode(SMDS_TypeOfPosition pos) const
     { return EndPos(0) == pos ? node1() : EndPos(1) == pos ? node2() : 0; }
 
-    void Move(const gp_Vec& move, bool sum=false) const
-    { _nodeMove += move; _nbMoves += sum ? (_nbMoves==0) : 1; }
+    void Move(const gp_Vec& move, bool sum=false, bool is2dFixed=false) const
+    { _nodeMove += move; _nbMoves += sum ? (_nbMoves==0) : 1; _is2dFixed |= is2dFixed; }
     gp_XYZ Move() const { return _nodeMove.XYZ() / _nbMoves; }
     bool IsMoved() const { return (_nbMoves > 0 /*&& !IsStraight()*/); }
+    bool IsFixedOnSurface() const { return _is2dFixed; }
     bool IsStraight() const
     { return isStraightLink( (XYZ(node1())-XYZ(node2())).SquareModulus(),
                              _nodeMove.SquareMagnitude());
@@ -3803,7 +3805,7 @@ namespace { // Structures used by FixQuadraticElements()
       double r = thePrevLen / fullLen;
 
       gp_Vec move = linkNorm * refProj * ( 1 - r );
-      theLink->Move( move, true );
+      theLink->Move( move, /*sum=*/true );
 
       MSG(string(theStep,'.')<<" Move "<< theLink->_mediumNode->GetID()<<
           " by " << refProj * ( 1 - r ) << " following " <<
@@ -4794,7 +4796,7 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError,
         }
         else if ( error == ERR_TRI ) {  // chain contains continues triangles
           TSplitTriaResult res = splitTrianglesIntoChains( rawChain, chains, pos );
-          if ( res != _OK ) { // not quadrangles split into triangles
+          if ( res != _OK ) { // not 'quadrangles split into triangles' in chain
             fixTriaNearBoundary( rawChain, *this );
             break;
           }
@@ -4921,6 +4923,7 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError,
               gp_Vec x = x01.Normalized() + x12.Normalized();
               trsf.SetTransformation( gp_Ax3( gp::Origin(), link1->Normal(), x), gp_Ax3() );
               move.Transform(trsf);
+              (*link1)->Move( move, /*sum=*/false, /*is2dFixed=*/false );
             }
             else {
               // compute 3D displacement by 2D one
@@ -4945,8 +4948,8 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError,
                      "newUV: "<<newUV.X()<<", "<<newUV.Y()<<" \t");
               }
 #endif
+              (*link1)->Move( move, /*sum=*/false, /*is2dFixed=*/true );
             }
-            (*link1)->Move( move );
             MSG( "Move " << (*link1)->_mediumNode->GetID() << " following "
                  << chain.front()->_mediumNode->GetID() <<"-"
                  << chain.back ()->_mediumNode->GetID() <<
@@ -4965,11 +4968,28 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError,
   const bool toFixCentralNodes = ( myMesh->NbBiQuadQuadrangles() +
                                    myMesh->NbBiQuadTriangles() +
                                    myMesh->NbTriQuadraticHexas() );
+  double distXYZ[4];
+  faceHlp.ToFixNodeParameters( true );
 
   for ( pLink = links.begin(); pLink != links.end(); ++pLink ) {
     if ( pLink->IsMoved() )
     {
       gp_Pnt p = pLink->MiddlePnt() + pLink->Move();
+
+      // put on surface nodes on FACE but moved in 3D (23050)
+      if ( !pLink->IsFixedOnSurface() )
+      {
+        faceHlp.SetSubShape( pLink->_mediumNode->getshapeId() );
+        if ( faceHlp.GetSubShape().ShapeType() == TopAbs_FACE )
+        {
+          const_cast<SMDS_MeshNode*>( pLink->_mediumNode )->setXYZ( p.X(), p.Y(), p.Z());
+          p.Coord( distXYZ[1], distXYZ[2], distXYZ[3] );
+          gp_XY uv( Precision::Infinite(), 0 );
+          faceHlp.CheckNodeUV( TopoDS::Face( faceHlp.GetSubShape() ), pLink->_mediumNode,
+                               uv, /*tol=*/pLink->Move().Modulus(), /*force=*/true, distXYZ );
+          p.SetCoord( distXYZ[1], distXYZ[2], distXYZ[3] );
+        }
+      }
       GetMeshDS()->MoveNode( pLink->_mediumNode, p.X(), p.Y(), p.Z());
 
       // collect bi-quadratic elements
index d01cf35f5ec872d1f41cb5beb3768c9b0f780f41..3ca7757c881cba6d6b8d3f1e1e285913b9a6e989 100644 (file)
@@ -477,7 +477,7 @@ void SMESH_MeshEditor_i::initData(bool deleteSearchers)
 /*!
  * \brief Increment mesh modif time and optionally record that the performed
  *        modification may influence futher mesh re-compute.
- *  \param [in] isReComputeSafe - true if the modification does not infulence
+ *  \param [in] isReComputeSafe - true if the modification does not influence
  *              futher mesh re-compute
  */
 //================================================================================
@@ -4797,6 +4797,8 @@ void SMESH_MeshEditor_i::convertToQuadratic(CORBA::Boolean            theForce3d
   throw (SALOME::SALOME_Exception)
 {
   SMESH_TRY;
+  initData();
+
   TIDSortedElemSet elems;
   bool elemsOK;
   if ( !( elemsOK = CORBA::is_nil( theObject )))
@@ -4826,10 +4828,16 @@ void SMESH_MeshEditor_i::convertToQuadratic(CORBA::Boolean            theForce3d
 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
   throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
+  initData();
+
   CORBA::Boolean isDone = getEditor().ConvertFromQuadratic();
   TPythonDump() << this << ".ConvertFromQuadratic()";
   declareMeshModified( /*isReComputeSafe=*/!isDone );
   return isDone;
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+  return false;
 }
 
 //=======================================================================
@@ -4882,6 +4890,7 @@ void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr th
   throw (SALOME::SALOME_Exception)
 {
   SMESH_TRY;
+  initData();
 
   TPythonDump pyDump;