X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSMESH_I%2FSMESH_MeshEditor_i.cxx;h=c46ae7d0c66223bb715cd1ace6b370dad1802a71;hb=10191484fe88a27e962b8e4b57e09d390d8705c7;hp=b55f78631369b244e2b84ff91e05185cc585a7ca;hpb=41b3e4433388f439856c3b0bb3725e9c81179c24;p=modules%2Fsmesh.git diff --git a/src/SMESH_I/SMESH_MeshEditor_i.cxx b/src/SMESH_I/SMESH_MeshEditor_i.cxx index b55f78631..c46ae7d0c 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.cxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.cxx @@ -64,7 +64,6 @@ #include #include #include -#include #include #include @@ -76,15 +75,8 @@ #include #include -#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 -#define NO_CAS_CATCH -#endif - #include - -#ifdef NO_CAS_CATCH #include -#endif #include #include @@ -110,7 +102,7 @@ namespace MeshEditor_I { SMDSAbs_ElementType myPreviewType; // type to show //!< Constructor TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) { - _isShapeToMesh = (_id =_studyId = 0); + _isShapeToMesh = (_id = 0); _myMeshDS = new SMESHDS_Mesh( _id, true ); myPreviewType = previewElements; } @@ -184,7 +176,7 @@ namespace MeshEditor_I { //============================================================================= /*! - * \brief Deleter of theNodeSearcher at any compute event occured + * \brief Deleter of theNodeSearcher at any compute event occurred */ //============================================================================= @@ -467,9 +459,9 @@ 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. + * modification may influence further mesh re-compute. * \param [in] isReComputeSafe - true if the modification does not influence - * futher mesh re-compute + * further mesh re-compute */ //================================================================================ @@ -501,7 +493,7 @@ void SMESH_MeshEditor_i::declareMeshModified( bool isReComputeSafe ) * \brief Initialize and return myPreviewMesh * \param previewElements - type of elements to show in preview * - * WARNING: call it once par a method! + * WARNING: call it once per method! */ //================================================================================ @@ -669,7 +661,7 @@ void SMESH_MeshEditor_i::ClearLastCreated() throw (SALOME::SALOME_Exception) //======================================================================= /* - * Returns description of an error/warning occured during the last operation + * Returns description of an error/warning occurred during the last operation * WARNING: ComputeError.code >= 100 and no corresponding enum in IDL API */ //======================================================================= @@ -1151,6 +1143,10 @@ CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes) n[8],n[9],n[10],n[11],n[12],n[13],n[14], n[15],n[16],n[17],n[18],n[19]); break; + case 18:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7], + n[8],n[9],n[10],n[11],n[12],n[13],n[14], + n[15],n[16],n[17]); + break; case 27:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7], n[8],n[9],n[10],n[11],n[12],n[13],n[14], n[15],n[16],n[17],n[18],n[19], @@ -3108,17 +3104,14 @@ SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements, ::SMESH_MeshEditor::PGroupIDs groupIds = getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh); - if ( theCopy && !myIsPreviewMode) + if ( !myIsPreviewMode ) { if ( theTargetMesh ) - { theTargetMesh->GetMeshDS()->Modified(); - } else - { declareMeshModified( /*isReComputeSafe=*/false ); - } } + return theMakeGroups ? getGroups(groupIds.get()) : 0; SMESH_CATCH( SMESH::throwCorbaException ); @@ -3375,16 +3368,12 @@ SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements, ::SMESH_MeshEditor::PGroupIDs groupIds = getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh); - if ( theCopy && !myIsPreviewMode ) + if ( !myIsPreviewMode ) { if ( theTargetMesh ) - { theTargetMesh->GetMeshDS()->Modified(); - } else - { declareMeshModified( /*isReComputeSafe=*/false ); - } } return theMakeGroups ? getGroups(groupIds.get()) : 0; @@ -3632,7 +3621,7 @@ SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements, ::SMESH_MeshEditor::PGroupIDs groupIds = getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh); - if ( theCopy && !myIsPreviewMode) + if ( !myIsPreviewMode) { if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified(); else declareMeshModified( /*isReComputeSafe=*/false ); @@ -3893,7 +3882,6 @@ SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject, }; gp_Trsf aTrsf; -#if OCC_VERSION_LARGE > 0x06070100 // fight against orthogonalization // aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]), // 0, S[1], 0, thePoint.y * (1-S[1]), @@ -3906,13 +3894,6 @@ SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject, thePoint.z * (1-S[2])); M.SetDiagonal( S[0], S[1], S[2] ); -#else - double tol = std::numeric_limits::max(); - aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]), - 0, S[1], 0, thePoint.y * (1-S[1]), - 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol); -#endif - TIDSortedElemSet copyElements; TIDSortedElemSet* workElements = &elements; if ( myIsPreviewMode ) @@ -3932,7 +3913,7 @@ SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject, ::SMESH_MeshEditor::PGroupIDs groupIds = getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh); - if ( theCopy && !myIsPreviewMode ) + if ( !myIsPreviewMode ) { if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified(); else declareMeshModified( /*isReComputeSafe=*/false ); @@ -4009,7 +3990,7 @@ SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject, // and then "GetGroups" using SMESH_Mesh::GetGroups() TPythonDump pydump; // to prevent dump at mesh creation - mesh = makeMesh( theMeshName ); + mesh = makeMesh( theMeshName ); mesh_i = SMESH::DownCast( mesh ); if ( mesh_i ) @@ -4159,7 +4140,8 @@ FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject, //======================================================================= void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes, - const SMESH::ListOfIDSources& NodesToKeep) + const SMESH::ListOfIDSources& NodesToKeep, + CORBA::Boolean AvoidMakingHoles) throw (SALOME::SALOME_Exception) { SMESH_TRY; @@ -4203,9 +4185,9 @@ void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfN aTPythonDump << aNodeGroup; } - getEditor().MergeNodes( aListOfListOfNodes ); + getEditor().MergeNodes( aListOfListOfNodes, AvoidMakingHoles ); - aTPythonDump << "], " << NodesToKeep << ")"; + aTPythonDump << "], " << NodesToKeep << ", " << AvoidMakingHoles << ")"; declareMeshModified( /*isReComputeSafe=*/false ); @@ -4595,6 +4577,151 @@ CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x, return 0; } +//======================================================================= +//function : IsManifold +//purpose : Check if a 2D mesh is manifold +//======================================================================= + +CORBA::Boolean SMESH_MeshEditor_i::IsManifold() + throw (SALOME::SALOME_Exception) +{ + bool isManifold = true; + + SMESH_TRY; + SMESH_MeshAlgos::TFreeBorderVec foundFreeBordes; + SMESH_MeshAlgos::FindFreeBorders( *getMeshDS(), + foundFreeBordes, + /*closedOnly=*/true, + &isManifold ); + SMESH_CATCH( SMESH::throwCorbaException ); + + return isManifold; +} + +//======================================================================= +//function : IsCoherentOrientation2D +//purpose : Check if orientation of 2D elements is coherent +//======================================================================= + +CORBA::Boolean SMESH_MeshEditor_i::IsCoherentOrientation2D() + throw (SALOME::SALOME_Exception) +{ + bool isGoodOri = true; + + SMESH_TRY; + SMESH_MeshAlgos::TFreeBorderVec foundFreeBordes; + SMESH_MeshAlgos::FindFreeBorders( *getMeshDS(), + foundFreeBordes, + /*closedOnly=*/true, + /*isManifold=*/0, + &isGoodOri); + SMESH_CATCH( SMESH::throwCorbaException ); + + return isGoodOri; +} + +//======================================================================= +//function : FindFreeBorders +//purpose : Returns all or only closed FreeBorder's. +//======================================================================= + +SMESH::ListOfFreeBorders* SMESH_MeshEditor_i::FindFreeBorders(CORBA::Boolean closedOnly) + throw (SALOME::SALOME_Exception) +{ + SMESH::ListOfFreeBorders_var resBorders = new SMESH::ListOfFreeBorders; + SMESH_TRY; + + SMESH_MeshAlgos::TFreeBorderVec foundFreeBordes; + SMESH_MeshAlgos::FindFreeBorders( *getMeshDS(), foundFreeBordes, closedOnly ); + + resBorders->length( foundFreeBordes.size() ); + for ( size_t i = 0; i < foundFreeBordes.size(); ++i ) + { + const SMESH_MeshAlgos::TFreeBorder& bordNodes = foundFreeBordes[i]; + SMESH::FreeBorder& bordOut = resBorders[i]; + bordOut.nodeIDs.length( bordNodes.size() ); + for ( size_t iN = 0; iN < bordNodes.size(); ++iN ) + bordOut.nodeIDs[ iN ] = bordNodes[ iN ]->GetID(); + } + + SMESH_CATCH( SMESH::throwCorbaException ); + + return resBorders._retn(); +} + +//======================================================================= +//function : FillHole +//purpose : Fill with 2D elements a hole defined by a FreeBorder. +//======================================================================= + +void SMESH_MeshEditor_i::FillHole(const SMESH::FreeBorder& theHole) + throw (SALOME::SALOME_Exception) +{ + initData(); + + if ( theHole.nodeIDs.length() < 4 ) + THROW_SALOME_CORBA_EXCEPTION("A hole should be bound by at least 3 nodes", SALOME::BAD_PARAM); + if ( theHole.nodeIDs[0] != theHole.nodeIDs[ theHole.nodeIDs.length()-1 ] ) + THROW_SALOME_CORBA_EXCEPTION("Not closed hole boundary. " + "First and last nodes must be same", SALOME::BAD_PARAM); + + SMESH_MeshAlgos::TFreeBorder bordNodes; + bordNodes.resize( theHole.nodeIDs.length() ); + for ( size_t iN = 0; iN < theHole.nodeIDs.length(); ++iN ) + { + bordNodes[ iN ] = getMeshDS()->FindNode( theHole.nodeIDs[ iN ]); + if ( !bordNodes[ iN ] ) + THROW_SALOME_CORBA_EXCEPTION(SMESH_Comment("Node #") << theHole.nodeIDs[ iN ] + << " does not exist", SALOME::BAD_PARAM); + } + + SMESH_TRY; + + MeshEditor_I::TPreviewMesh* previewMesh = 0; + SMDS_Mesh* meshDS = getMeshDS(); + if ( myIsPreviewMode ) + { + // copy faces sharing nodes of theHole + TIDSortedElemSet holeFaces; + previewMesh = getPreviewMesh( SMDSAbs_Face ); + for ( size_t i = 0; i < bordNodes.size(); ++i ) + { + SMDS_ElemIteratorPtr fIt = bordNodes[i]->GetInverseElementIterator( SMDSAbs_Face ); + while ( fIt->more() ) + { + const SMDS_MeshElement* face = fIt->next(); + if ( holeFaces.insert( face ).second ) + previewMesh->Copy( face ); + } + bordNodes[i] = previewMesh->GetMeshDS()->FindNode( bordNodes[i]->GetID() ); + ASSERT( bordNodes[i] ); + } + meshDS = previewMesh->GetMeshDS(); + } + + std::vector newFaces; + SMESH_MeshAlgos::FillHole( bordNodes, *meshDS, newFaces ); + + if ( myIsPreviewMode ) + { + previewMesh->Clear(); + for ( size_t i = 0; i < newFaces.size(); ++i ) + previewMesh->Copy( newFaces[i] ); + } + else + { + getEditor().ClearLastCreated(); + SMESH_SequenceOfElemPtr& aSeq = + const_cast( getEditor().GetLastCreatedElems() ); + for ( size_t i = 0; i < newFaces.size(); ++i ) + aSeq.Append( newFaces[i] ); + + TPythonDump() << this << ".FillHole( SMESH.FreeBorder(" << theHole.nodeIDs << " ))"; + } + + SMESH_CATCH( SMESH::throwCorbaException ); +} + //======================================================================= //function : convError //purpose : @@ -5268,8 +5395,7 @@ SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName) { SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen(); SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh(); - SALOMEDS::Study_var study = gen->GetCurrentStudy(); - SALOMEDS::SObject_wrap meshSO = gen->ObjectToSObject( study, mesh ); + SALOMEDS::SObject_wrap meshSO = gen->ObjectToSObject( mesh ); gen->SetName( meshSO, theMeshName, "Mesh" ); gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED"); @@ -6655,7 +6781,7 @@ SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource, else pyDump << mesh_var << ", "; if ( group_var->_is_nil() ) - pyDump << "_NoneGroup = "; // assignment to None is forbiden + pyDump << "_NoneGroup = "; // assignment to None is forbidden else pyDump << group_var << " = "; pyDump << this << ".MakeBoundaryMesh( " @@ -6719,7 +6845,7 @@ CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim, else groupsOfThisMesh[ nbGroups++ ] = groups[i]; if ( SMESH::DownCast( groups[i] )) - THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM); + THROW_SALOME_CORBA_EXCEPTION("expected a group but received a mesh", SALOME::BAD_PARAM); } groupsOfThisMesh->length( nbGroups ); groupsOfOtherMesh->length( nbGroupsOfOtherMesh ); @@ -6813,7 +6939,7 @@ CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim, else pyDump << mesh_var << ", "; if ( group_var->_is_nil() ) - pyDump << "_NoneGroup = "; // assignment to None is forbiden + pyDump << "_NoneGroup = "; // assignment to None is forbidden else pyDump << group_var << " = "; pyDump << this << ".MakeBoundaryElements( " @@ -6830,3 +6956,130 @@ CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim, SMESH_CATCH( SMESH::throwCorbaException ); return 0; } + +//================================================================================ +/*! + * \brief Create a polyline consisting of 1D mesh elements each lying on a 2D element of + * the initial mesh. Positions of new nodes are found by cutting the mesh by the + * plane passing through pairs of points specified by each PolySegment structure. + * If there are several paths connecting a pair of points, the shortest path is + * selected by the module. Position of the cutting plane is defined by the two + * points and an optional vector lying on the plane specified by a PolySegment. + * By default the vector is defined by Mesh module as following. A middle point + * of the two given points is computed. The middle point is projected to the mesh. + * The vector goes from the middle point to the projection point. In case of planar + * mesh, the vector is normal to the mesh. + * \param [inout] segments - PolySegment's defining positions of cutting planes. + * Return the used vector and position of the middle point. + * \param [in] groupName - optional name of a group where created mesh segments will + * be added. + */ +//================================================================================ + +void SMESH_MeshEditor_i::MakePolyLine(SMESH::ListOfPolySegments& theSegments, + const char* theGroupName) + throw (SALOME::SALOME_Exception) +{ + if ( theSegments.length() == 0 ) + THROW_SALOME_CORBA_EXCEPTION("No segments given", SALOME::BAD_PARAM ); + if ( myMesh->NbFaces() == 0 ) + THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM ); + + SMESH_TRY; + initData(/*deleteSearchers=*/false); + + SMESHDS_Group* groupDS = 0; + SMESHDS_Mesh* meshDS = getMeshDS(); + if ( myIsPreviewMode ) // copy faces to the tmp mesh + { + TPreviewMesh * tmpMesh = getPreviewMesh( SMDSAbs_Edge ); + SMDS_ElemIteratorPtr faceIt = getMeshDS()->elementsIterator( SMDSAbs_Face ); + while ( faceIt->more() ) + tmpMesh->Copy( faceIt->next() ); + meshDS = tmpMesh->GetMeshDS(); + } + else if ( theGroupName[0] ) // find/create a group of segments + { + SMESH_Mesh::GroupIteratorPtr grpIt = myMesh->GetGroups(); + while ( !groupDS && grpIt->more() ) + { + SMESH_Group* group = grpIt->next(); + if ( group->GetGroupDS()->GetType() == SMDSAbs_Edge && + strcmp( group->GetName(), theGroupName ) == 0 ) + { + groupDS = dynamic_cast< SMESHDS_Group* >( group->GetGroupDS() ); + } + } + if ( !groupDS ) + { + SMESH::SMESH_Group_var groupVar = myMesh_i->CreateGroup( SMESH::EDGE, theGroupName ); + + if ( SMESH_Group_i* groupImpl = SMESH::DownCast( groupVar )) + groupDS = dynamic_cast< SMESHDS_Group* >( groupImpl->GetGroupDS() ); + } + } + + // convert input polySegments + ::SMESH_MeshEditor::TListOfPolySegments segments( theSegments.length() ); + for ( CORBA::ULong i = 0; i < theSegments.length(); ++i ) + { + SMESH::PolySegment& segIn = theSegments[ i ]; + ::SMESH_MeshEditor::PolySegment& segOut = segments[ i ]; + segOut.myNode1[0] = meshDS->FindNode( segIn.node1ID1 ); + segOut.myNode2[0] = meshDS->FindNode( segIn.node1ID2 ); + segOut.myNode1[1] = meshDS->FindNode( segIn.node2ID1 ); + segOut.myNode2[1] = meshDS->FindNode( segIn.node2ID2 ); + segOut.myVector.SetCoord( segIn.vector.PS.x, + segIn.vector.PS.y, + segIn.vector.PS.z ); + if ( !segOut.myNode1[0] ) + THROW_SALOME_CORBA_EXCEPTION( SMESH_Comment( "Invalid node ID: ") << segIn.node1ID1, + SALOME::BAD_PARAM ); + if ( !segOut.myNode1[1] ) + THROW_SALOME_CORBA_EXCEPTION( SMESH_Comment( "Invalid node ID: ") << segIn.node2ID1, + SALOME::BAD_PARAM ); + } + + // get a static ElementSearcher + SMESH::SMESH_IDSource_var idSource = SMESH::SMESH_IDSource::_narrow( myMesh_i->_this() ); + theSearchersDeleter.Set( myMesh, getPartIOR( idSource, SMESH::FACE )); + if ( !theElementSearcher ) + theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() ); + + // compute + getEditor().MakePolyLine( segments, groupDS, theElementSearcher ); + + // return vectors + if ( myIsPreviewMode ) + { + for ( CORBA::ULong i = 0; i < theSegments.length(); ++i ) + { + SMESH::PolySegment& segOut = theSegments[ i ]; + ::SMESH_MeshEditor::PolySegment& segIn = segments[ i ]; + segOut.vector.PS.x = segIn.myVector.X(); + segOut.vector.PS.y = segIn.myVector.Y(); + segOut.vector.PS.z = segIn.myVector.Z(); + } + } + else + { + TPythonDump() << "_segments = []"; + for ( CORBA::ULong i = 0; i < theSegments.length(); ++i ) + { + SMESH::PolySegment& segIn = theSegments[ i ]; + TPythonDump() << "_segments.append( SMESH.PolySegment( " + << segIn.node1ID1 << ", " + << segIn.node1ID2 << ", " + << segIn.node2ID1 << ", " + << segIn.node2ID2 << ", " + << "smeshBuilder.MakeDirStruct( " + << segIn.vector.PS.x << ", " + << segIn.vector.PS.y << ", " + << segIn.vector.PS.z << ")))"; + } + TPythonDump() << this << ".MakePolyLine( _segments, '" << theGroupName << "')"; + } + meshDS->Modified(); + SMESH_CATCH( SMESH::throwCorbaException ); + return; +}