X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESH_I%2FSMESH_MeshEditor_i.cxx;h=e87f092a24eedb24845e8929c5ed63f03f1f1def;hp=bc5073500db6148ef201df650fef4b78575afc70;hb=d9f4b53e489dd5857db264ede6acded7b076c9f1;hpb=60bb6273b99dc88e3d6f360d7ae5792a77c68d06 diff --git a/src/SMESH_I/SMESH_MeshEditor_i.cxx b/src/SMESH_I/SMESH_MeshEditor_i.cxx index bc5073500..e87f092a2 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.cxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2022 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 @@ -102,7 +102,7 @@ namespace MeshEditor_I { //!< Constructor TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) { _isShapeToMesh = (_id = 0); - _myMeshDS = new SMESHDS_Mesh( _id, true ); + _meshDS = new SMESHDS_Mesh( _id, true ); myPreviewType = previewElements; } //!< Copy a set of elements @@ -155,8 +155,8 @@ namespace MeshEditor_I { //!< Copy a node SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode ) { - return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(), - anElemNode->GetID()); + return _meshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(), + anElemNode->GetID()); } void RemoveAll() { @@ -834,7 +834,7 @@ CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::smIdType_array & IDs //============================================================================= /*! - * + * Remove orphan nodes */ //============================================================================= @@ -865,6 +865,58 @@ SMESH::smIdType SMESH_MeshEditor_i::RemoveOrphanNodes() return 0; } +//============================================================================= +/*! + * Remove a node and fill a hole appeared by changing surrounding faces + */ +//============================================================================= + +void SMESH_MeshEditor_i::RemoveNodeWithReconnection( SMESH::smIdType nodeID ) +{ + SMESH_TRY; + initData(); + + const SMDS_MeshNode * node = getMeshDS()->FindNode( nodeID ); + if ( ! node ) + THROW_SALOME_CORBA_EXCEPTION( SMESH_Comment( "Invalid node ID ") << nodeID, + SALOME::BAD_PARAM); + if ( node->NbInverseElements( SMDSAbs_Volume ) > 0 ) + THROW_SALOME_CORBA_EXCEPTION( "RemoveNodeWithReconnection() applies to 2D mesh only", + SALOME::BAD_PARAM); + + if ( myIsPreviewMode ) // make preview data + { + // in a preview mesh, make edges linked to a node + TPreviewMesh& tmpMesh = *getPreviewMesh( SMDSAbs_Edge ); + TIDSortedElemSet linkedNodes; + ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes ); + SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy( node ); + for ( const SMDS_MeshElement* n : linkedNodes ) + { + SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( n )); + tmpMesh.GetMeshDS()->AddEdge( nodeCpy1, nodeCpy2 ); + } + // copy surrounding faces + for ( SMDS_ElemIteratorPtr fIt = node->GetInverseElementIterator( SMDSAbs_Face ); fIt->more(); ) + tmpMesh.Copy ( fIt->next() ); + + // remove copied node + if ( nodeCpy1 ) + getEditor().RemoveNodeWithReconnection( nodeCpy1 ); + } + else + { + getEditor().RemoveNodeWithReconnection( node ); + + // Update Python script + TPythonDump() << this << ".RemoveNodeWithReconnection( " << nodeID << " )"; + + declareMeshModified( /*isReComputeSafe=*/ true ); + } + + SMESH_CATCH( SMESH::throwCorbaException ); +} + //============================================================================= /*! * Add a new node. @@ -1567,6 +1619,121 @@ CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(SMESH::smIdType NodeID1, return 0; } +//============================================================================= +/*! + * \brief Split a diagonal of a quadrangle formed by two adjacent triangles + * so that four new triangles appear in place of the two triangles + */ +//============================================================================= + +void SMESH_MeshEditor_i::AddNodeOnSegment(SMESH::smIdType nodeID1, + SMESH::smIdType nodeID2, + CORBA::Double position) +{ + SMESH_TRY; + initData(); + + const SMDS_MeshNode * n1 = getMeshDS()->FindNode( nodeID1 ); + const SMDS_MeshNode * n2 = getMeshDS()->FindNode( nodeID2 ); + if ( !n1 ) + THROW_SALOME_CORBA_EXCEPTION( SMESH_Comment( "Invalid node ID: ") << nodeID1, + SALOME::BAD_PARAM); + if ( !n2 ) + THROW_SALOME_CORBA_EXCEPTION( SMESH_Comment( "Invalid node ID: ") << nodeID2, + SALOME::BAD_PARAM); + + if ( myIsPreviewMode ) // make preview data + { + TPreviewMesh* tmpMesh = getPreviewMesh(); + TIDSortedElemSet elemSet, avoidSet; + TopoDS_Shape shape; + while ( const SMDS_MeshElement* face = SMESH_MeshAlgos::FindFaceInSet( n1, n2, + elemSet, avoidSet )) + { + if ( avoidSet.empty() ) + { + shape = getMeshDS()->IndexToShape( face->GetShapeID() ); + if ( !shape.IsNull() ) + { + tmpMesh->ShapeToMesh( TopoDS_Shape() ); + tmpMesh->ShapeToMesh( shape ); + } + } + SMDS_MeshElement* faceCopy = tmpMesh->Copy ( face ); + avoidSet.insert( face ); + + if ( !shape.IsNull() ) + tmpMesh->GetMeshDS()->SetMeshElementOnShape( faceCopy, shape ); + } + n1 = tmpMesh->GetMeshDS()->FindNode( nodeID1 ); + n2 = tmpMesh->GetMeshDS()->FindNode( nodeID2 ); + + if ( !shape.IsNull() ) + { + tmpMesh->GetMeshDS()->SetMeshElementOnShape( n1, shape ); + tmpMesh->GetMeshDS()->SetMeshElementOnShape( n2, shape ); + } + } + + getEditor().SplitEdge( n1, n2, position ); + + if ( !myIsPreviewMode ) + { + // Update Python script + TPythonDump() << this << ".AddNodeOnSegment( " + << nodeID1 << ", " << nodeID2 << ", " << position << " )"; + + declareMeshModified( /*isReComputeSafe=*/true ); + } + + SMESH_CATCH( SMESH::throwCorbaException ); +} + +//============================================================================= +/*! + * \brief Split a face into triangles by adding a new node onto the face + * and connecting the new node with face nodes + */ +//============================================================================= + +void SMESH_MeshEditor_i::AddNodeOnFace(SMESH::smIdType theFaceID, + CORBA::Double theX, + CORBA::Double theY, + CORBA::Double theZ) +{ + SMESH_TRY; + initData(); + + const SMDS_MeshElement * face = getMeshDS()->FindElement( theFaceID ); + if ( !face ) + THROW_SALOME_CORBA_EXCEPTION( SMESH_Comment( "Invalid face ID: ") << theFaceID, + SALOME::BAD_PARAM); + if ( face->GetType() != SMDSAbs_Face ) + THROW_SALOME_CORBA_EXCEPTION( "The element is not a face ", SALOME::BAD_PARAM ); + + if ( myIsPreviewMode ) // make preview data + { + TPreviewMesh* tmpMesh = getPreviewMesh(); + face = tmpMesh->Copy ( face ); + } + + getEditor().SplitFace( face, theX, theY, theZ ); + + if ( !myIsPreviewMode ) + { + // Update Python script + TPythonDump() << this << ".AddNodeOnFace( " + << theFaceID << ", " + << theX << ", " + << theY << ", " + << theZ << " )"; + + declareMeshModified( /*isReComputeSafe=*/true ); + } + + SMESH_CATCH( SMESH::throwCorbaException ); +} + //============================================================================= /*! * @@ -1696,7 +1863,8 @@ CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup, if ( dirVec.Magnitude() < std::numeric_limits< double >::min() ) THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM); - int nbReori = getEditor().Reorient2D( elements, dirVec, face ); + TIDSortedElemSet refFaces = { face }; + int nbReori = getEditor().Reorient2D( elements, dirVec, refFaces, /*allowNonManifold=*/true ); if ( nbReori ) { declareMeshModified( /*isReComputeSafe=*/false ); @@ -1713,6 +1881,64 @@ CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup, return 0; } +//======================================================================= +//function : Reorient2DByNeighbours +//purpose : Reorient faces contained in a list of objectFaces +// equally to faces contained in a list of referenceFaces. +//======================================================================= + +CORBA::Long +SMESH_MeshEditor_i::Reorient2DByNeighbours(const SMESH::ListOfIDSources& theObjectFaces, + const SMESH::ListOfIDSources& theReferenceFaces) +{ + SMESH_TRY; + initData(/*deleteSearchers=*/false); + + if ( theObjectFaces.length() == 0 ) + return 0; + + // get object faces + TIDSortedElemSet objFaces; + bool invalidObjFaces = false; + for ( CORBA::ULong i = 0; i < theObjectFaces.length(); ++i ) + { + IDSource_Error err; + if ( !idSourceToSet( theObjectFaces[i], getMeshDS(), objFaces, SMDSAbs_Face, + /*emptyIfIsMesh=*/1, &err ) && + err == IDSource_INVALID ) + invalidObjFaces = true; + } + if ( objFaces.empty() && invalidObjFaces ) + THROW_SALOME_CORBA_EXCEPTION("No valid faces in given groups", SALOME::BAD_PARAM); + + // get reference faces + TIDSortedElemSet refFaces; + for ( CORBA::ULong i = 0; i < theReferenceFaces.length(); ++i ) + { + idSourceToSet( theReferenceFaces[i], getMeshDS(), refFaces, SMDSAbs_Face, /*emptyIfIsMesh=*/1 ); + } + if ( refFaces.empty() && theReferenceFaces.length() > 0 ) + THROW_SALOME_CORBA_EXCEPTION("Reference faces are invalid", SALOME::BAD_PARAM); + + + gp_Vec zeroVec( 0,0,0 ); + + // reorient + int nbReori = getEditor().Reorient2D( objFaces, zeroVec, refFaces, /*allowNonManifold=*/false ); + + if ( nbReori ) + declareMeshModified( /*isReComputeSafe=*/false ); + + TPythonDump() << this << ".Reorient2DByNeighbours(" + << theObjectFaces << ", " + << theReferenceFaces << ")"; + + return nbReori; + + SMESH_CATCH( SMESH::throwCorbaException ); + return 0; +} + //======================================================================= //function : Reorient2DBy3D //purpose : Reorient faces basing on orientation of adjacent volumes. @@ -2006,8 +2232,8 @@ CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr th */ //============================================================================= -CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad, - SMESH::NumericalFunctor_ptr Criterion) +CORBA::Short SMESH_MeshEditor_i::BestSplit (SMESH::smIdType IDOfQuad, + SMESH::NumericalFunctor_ptr Criterion) { SMESH_TRY; initData(); @@ -4430,7 +4656,6 @@ CORBA::Boolean SMESH_MeshEditor_i::MoveNode(SMESH::smIdType NodeID, // move copied node if ( nodeCpy1 ) tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z); - // fill preview data } else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));