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=9b79bead18dd32ccbf89e18eeda5d5c957cea472;hp=a753f0b59b70cf5b6e1613c7d8caae6d40272426;hb=30ce546b0c5099ad1112929e2db94810e683e54b;hpb=53393c4445ab377057fdbccc4d08d5369908bdf0 diff --git a/src/SMESH_I/SMESH_MeshEditor_i.cxx b/src/SMESH_I/SMESH_MeshEditor_i.cxx index a753f0b59..9b79bead1 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.cxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2016 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 @@ -114,8 +114,6 @@ namespace MeshEditor_I { _myMeshDS = new SMESHDS_Mesh( _id, true ); myPreviewType = previewElements; } - //!< Destructor - virtual ~TPreviewMesh() { delete _myMeshDS; _myMeshDS = 0; } //!< Copy a set of elements void Copy(const TIDSortedElemSet & theElements, TIDSortedElemSet& theCopyElements, @@ -156,20 +154,11 @@ namespace MeshEditor_I { } // creates a corresponding element on copied nodes - SMDS_MeshElement* anElemCopy = 0; - if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume ) - { - const SMDS_VtkVolume* ph = - dynamic_cast (anElem); - if ( ph ) - anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID - (anElemNodesID, ph->GetQuantities(),anElem->GetID()); - } - else { - anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID, - anElem->GetType(), - anElem->IsPoly() ); - } + ::SMESH_MeshEditor::ElemFeatures elemType; + elemType.Init( anElem, /*basicOnly=*/false ); + elemType.SetID( anElem->GetID() ); + SMDS_MeshElement* anElemCopy = + ::SMESH_MeshEditor(this).AddElement( anElemNodesID, elemType ); return anElemCopy; } //!< Copy a node @@ -182,6 +171,12 @@ namespace MeshEditor_I { { GetMeshDS()->ClearMesh(); } + void Remove( SMDSAbs_ElementType type ) + { + SMDS_ElemIteratorPtr eIt = GetMeshDS()->elementsIterator( type ); + while ( eIt->more() ) + GetMeshDS()->RemoveFreeElement( eIt->next(), /*sm=*/0, /*fromGroups=*/false ); + } };// struct TPreviewMesh static SMESH_NodeSearcher * theNodeSearcher = 0; @@ -189,7 +184,7 @@ namespace MeshEditor_I { //============================================================================= /*! - * \brief Deleter of theNodeSearcher at any compute event occured + * \brief Deleter of theNodeSearcher at any compute event occurred */ //============================================================================= @@ -290,77 +285,19 @@ namespace MeshEditor_I { SMDS_MeshElement::Filter & filter = *aFilter; if ( aType == SMDSAbs_Node ) - for (int i=0; iFindNode( IDs[i] ); if ( filter( elem )) aMap.insert( aMap.end(), elem ); } else - for (int i=0; iFindElement( IDs[i] ); if ( filter( elem )) aMap.insert( aMap.end(), elem ); } } - //================================================================================ - /*! - * \brief Retrieve elements of given type from SMESH_IDSource - */ - //================================================================================ - - enum IDSource_Error { IDSource_OK, IDSource_INVALID, IDSource_EMPTY }; - - bool idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource, - const SMESHDS_Mesh* theMeshDS, - TIDSortedElemSet& theElemSet, - const SMDSAbs_ElementType theType, - const bool emptyIfIsMesh = false, - IDSource_Error* error = 0) - - { - if ( error ) *error = IDSource_OK; - if ( CORBA::is_nil( theIDSource ) ) - { - if ( error ) *error = IDSource_INVALID; - return false; - } - if ( emptyIfIsMesh && SMESH::DownCast( theIDSource )) - { - if ( error && theMeshDS->GetMeshInfo().NbElements( theType ) == 0 ) - *error = IDSource_EMPTY; - return true; - } - SMESH::long_array_var anIDs = theIDSource->GetIDs(); - if ( anIDs->length() == 0 ) - { - if ( error ) *error = IDSource_EMPTY; - return false; - } - SMESH::array_of_ElementType_var types = theIDSource->GetTypes(); - if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes - { - if ( theType == SMDSAbs_All || theType == SMDSAbs_Node ) - { - arrayToSet( anIDs, theMeshDS, theElemSet, SMDSAbs_Node ); - } - else - { - if ( error ) *error = IDSource_INVALID; - return false; - } - } - else - { - arrayToSet( anIDs, theMeshDS, theElemSet, theType); - if ( bool(anIDs->length()) != bool(theElemSet.size())) - { - if ( error ) *error = IDSource_INVALID; - return false; - } - } - return true; - } //================================================================================ /*! * \brief Retrieve nodes from SMESH_IDSource @@ -378,7 +315,7 @@ namespace MeshEditor_I { SMESH::long_array_var aElementsId = theObject->GetIDs(); if ( types->length() == 1 && types[0] == SMESH::NODE) { - for(int i = 0; i < aElementsId->length(); i++) + for ( CORBA::ULong i = 0; i < aElementsId->length(); i++ ) if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] )) theNodeSet.insert( theNodeSet.end(), n); } @@ -386,13 +323,13 @@ namespace MeshEditor_I { { SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator(); while ( nIt->more( )) - if( const SMDS_MeshElement * elem = nIt->next() ) + if ( const SMDS_MeshElement * elem = nIt->next() ) theNodeSet.insert( elem->begin_nodes(), elem->end_nodes()); } else { - for(int i = 0; i < aElementsId->length(); i++) - if( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] )) + for ( CORBA::ULong i = 0; i < aElementsId->length(); i++ ) + if ( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] )) theNodeSet.insert( elem->begin_nodes(), elem->end_nodes()); } } @@ -412,7 +349,7 @@ namespace MeshEditor_I { SMDSAbs_ElementType elemType = (*theElements.begin())->GetType(); bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() ); if ( sameElemType && - theMeshDS->GetMeshInfo().NbElements( elemType ) == theElements.size() ) + theMeshDS->GetMeshInfo().NbElements( elemType ) == (int) theElements.size() ) return; // all the elements are in theElements if ( !sameElemType ) @@ -497,6 +434,17 @@ SMESH_MeshEditor_i::~SMESH_MeshEditor_i() delete myPreviewEditor; myPreviewEditor = 0; } +//================================================================================ +/*! + * \brief Returns the mesh + */ +//================================================================================ + +SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::GetMesh() +{ + return myMesh_i->_this(); +} + //================================================================================ /*! * \brief Clear members @@ -513,15 +461,15 @@ void SMESH_MeshEditor_i::initData(bool deleteSearchers) TSearchersDeleter::Delete(); } getEditor().GetError().reset(); - getEditor().CrearLastCreated(); + getEditor().ClearLastCreated(); } //================================================================================ /*! * \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 - * futher mesh re-compute + * modification may influence further mesh re-compute. + * \param [in] isReComputeSafe - true if the modification does not influence + * further mesh re-compute */ //================================================================================ @@ -553,7 +501,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! */ //================================================================================ @@ -578,7 +526,7 @@ TPreviewMesh * SMESH_MeshEditor_i::getPreviewMesh(SMDSAbs_ElementType previewEle SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData() throw (SALOME::SALOME_Exception) -{ +{ SMESH_TRY; const bool hasBadElems = ( getEditor().GetError() && getEditor().GetError()->HasBadElems() ); @@ -600,7 +548,7 @@ SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData() myPreviewData = new SMESH::MeshPreviewStruct(); myPreviewData->nodesXYZ.length(aMeshDS->NbNodes()); - + SMDSAbs_ElementType previewType = SMDSAbs_All; if ( !hasBadElems ) if (TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( getEditor().GetMesh() )) { @@ -620,7 +568,10 @@ SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData() while ( itMeshElems->more() ) { const SMDS_MeshElement* aMeshElem = itMeshElems->next(); - SMDS_NodeIteratorPtr itElemNodes = aMeshElem->nodeIterator(); + SMDS_NodeIteratorPtr itElemNodes = + (( aMeshElem->GetEntityType() == SMDSEntity_Quad_Polygon ) ? + aMeshElem->interlacedNodesIterator() : + aMeshElem->nodeIterator() ); while ( itElemNodes->more() ) { const SMDS_MeshNode* aMeshNode = itElemNodes->next(); int aNodeID = aMeshNode->GetID(); @@ -712,13 +663,13 @@ SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems() void SMESH_MeshEditor_i::ClearLastCreated() throw (SALOME::SALOME_Exception) { SMESH_TRY; - getEditor().CrearLastCreated(); + getEditor().ClearLastCreated(); SMESH_CATCH( SMESH::throwCorbaException ); } //======================================================================= /* - * 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 */ //======================================================================= @@ -843,7 +794,7 @@ SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements) list< int > IdList; - for (int i = 0; i < IDsOfElements.length(); i++) + for ( CORBA::ULong i = 0; i < IDsOfElements.length(); i++ ) IdList.push_back( IDsOfElements[i] ); // Update Python script @@ -872,7 +823,7 @@ CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNo initData(); list< int > IdList; - for (int i = 0; i < IDsOfNodes.length(); i++) + for ( CORBA::ULong i = 0; i < IDsOfNodes.length(); i++) IdList.push_back( IDsOfNodes[i] ); // Update Python script @@ -908,9 +859,7 @@ CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes() SMESH::Controls::Filter::GetElementsId( getMeshDS(), predicate, seq ); // remove orphan nodes (if there are any) - list< int > IdList; - for ( int i = 0; i < seq.size(); i++ ) - IdList.push_back( seq[i] ); + list< int > IdList( seq.begin(), seq.end() ); int nbNodesBefore = myMesh->NbNodes(); getEditor().Remove( IdList, true ); @@ -954,14 +903,19 @@ CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,CORBA::Double y, CORBA:: */ //============================================================================= -CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode) +CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode, + CORBA::Boolean DuplicateElements) throw (SALOME::SALOME_Exception) { SMESH_TRY; initData(); const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode); - SMDS_MeshElement* elem = getMeshDS()->Add0DElement(aNode); + SMDS_ElemIteratorPtr it0D = aNode->GetInverseElementIterator( SMDSAbs_0DElement ); + + SMDS_MeshElement* elem = 0; + if ( DuplicateElements || !it0D->more() ) + elem = getMeshDS()->Add0DElement(aNode); // Update Python script TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )"; @@ -1102,6 +1056,7 @@ CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes) * AddPolygonalFace */ //============================================================================= + CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes) throw (SALOME::SALOME_Exception) { @@ -1111,7 +1066,8 @@ CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsO int NbNodes = IDsOfNodes.length(); std::vector nodes (NbNodes); for (int i = 0; i < NbNodes; i++) - nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]); + if ( ! ( nodes[i] = getMeshDS()->FindNode( IDsOfNodes[i] ))) + return 0; const SMDS_MeshElement* elem = getMeshDS()->AddPolygonalFace(nodes); @@ -1125,6 +1081,35 @@ CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsO return 0; } +//============================================================================= +/*! + * AddQuadPolygonalFace + */ +//============================================================================= + +CORBA::Long SMESH_MeshEditor_i::AddQuadPolygonalFace (const SMESH::long_array & IDsOfNodes) + throw (SALOME::SALOME_Exception) +{ + SMESH_TRY; + initData(); + + int NbNodes = IDsOfNodes.length(); + std::vector nodes (NbNodes); + for (int i = 0; i < NbNodes; i++) + nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]); + + const SMDS_MeshElement* elem = getMeshDS()->AddQuadPolygonalFace(nodes); + + // Update Python script + TPythonDump() <<"faceID = "<GetID() : 0; + + SMESH_CATCH( SMESH::throwCorbaException ); + return 0; +} + //============================================================================= /*! * Create volume, either linear and quadratic (this is determed @@ -1263,11 +1248,11 @@ CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_ar //============================================================================= // -// \brief Create 0D elements on all nodes of the given object except those -// nodes on which a 0D element already exists. +// \brief Create 0D elements on all nodes of the given object. // \param theObject object on whose nodes 0D elements will be created. // \param theGroupName optional name of a group to add 0D elements created // and/or found on nodes of \a theObject. +// \param DuplicateElements to add one more 0D element to a node or not. // \return an object (a new group or a temporary SMESH_IDSource) holding // ids of new and/or found 0D elements. // @@ -1275,7 +1260,8 @@ CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_ar SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObject, - const char* theGroupName) + const char* theGroupName, + CORBA::Boolean theDuplicateElements) throw (SALOME::SALOME_Exception) { SMESH_TRY; @@ -1285,9 +1271,8 @@ SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObje TPythonDump pyDump; TIDSortedElemSet elements, elems0D; - prepareIdSource( theObject ); if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) - getEditor().Create0DElementsOnAllNodes( elements, elems0D ); + getEditor().Create0DElementsOnAllNodes( elements, elems0D, theDuplicateElements ); SMESH::long_array_var newElems = new SMESH::long_array; newElems->length( elems0D.size() ); @@ -1603,7 +1588,7 @@ CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfEleme SMESH_TRY; initData(); - for (int i = 0; i < IDsOfElements.length(); i++) + for ( CORBA::ULong i = 0; i < IDsOfElements.length(); i++ ) { CORBA::Long index = IDsOfElements[i]; const SMDS_MeshElement * elem = getMeshDS()->FindElement(index); @@ -1670,7 +1655,6 @@ CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup, initData(/*deleteSearchers=*/false); TIDSortedElemSet elements; - prepareIdSource( the2Dgroup ); IDSource_Error error; idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error ); if ( error == IDSource_EMPTY ) @@ -1755,7 +1739,6 @@ CORBA::Long SMESH_MeshEditor_i::Reorient2DBy3D(const SMESH::ListOfIDSources& fac initData(); TIDSortedElemSet volumes; - prepareIdSource( volumeGroup ); IDSource_Error volsError; idSourceToSet( volumeGroup, getMeshDS(), volumes, SMDSAbs_Volume, /*emptyIfMesh=*/1, &volsError); @@ -1763,7 +1746,6 @@ CORBA::Long SMESH_MeshEditor_i::Reorient2DBy3D(const SMESH::ListOfIDSources& fac for ( size_t i = 0; i < faceGroups.length(); ++i ) { SMESH::SMESH_IDSource_ptr faceGrp = faceGroups[i].in(); - prepareIdSource( faceGrp ); TIDSortedElemSet faces; IDSource_Error error; @@ -1961,7 +1943,6 @@ void SMESH_MeshEditor_i::QuadTo4Tri (SMESH::SMESH_IDSource_ptr theObject) initData(); TIDSortedElemSet faces; - prepareIdSource( theObject ); if ( !idSourceToSet( theObject, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/true ) && faces.empty() ) THROW_SALOME_CORBA_EXCEPTION("No faces given", SALOME::BAD_PARAM); @@ -2082,7 +2063,6 @@ void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems, { SMESH_TRY; initData(); - prepareIdSource( elems ); ::SMESH_MeshEditor::TFacetOfElem elemSet; const int noneFacet = -1; @@ -2111,7 +2091,7 @@ void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems, */ //================================================================================ -void SMESH_MeshEditor_i::SplitHexahedraIntoPrisms (SMESH::SMESH_IDSource_ptr elems, +void SMESH_MeshEditor_i::SplitHexahedraIntoPrisms( SMESH::SMESH_IDSource_ptr elems, const SMESH::PointStruct & startHexPoint, const SMESH::DirStruct& facetToSplitNormal, CORBA::Short methodFlags, @@ -2163,6 +2143,44 @@ void SMESH_MeshEditor_i::SplitHexahedraIntoPrisms (SMESH::SMESH_IDSource_ptr el SMESH_CATCH( SMESH::throwCorbaException ); } +//================================================================================ +/*! + * \brief Split bi-quadratic elements into linear ones without creation of additional nodes: + * - bi-quadratic triangle will be split into 3 linear quadrangles; + * - bi-quadratic quadrangle will be split into 4 linear quadrangles; + * - tri-quadratic hexahedron will be split into 8 linear hexahedra. + * Quadratic elements of lower dimension adjacent to the split bi-quadratic element + * will be split in order to keep the mesh conformal. + * \param elems - elements to split + */ +//================================================================================ + +void SMESH_MeshEditor_i::SplitBiQuadraticIntoLinear(const SMESH::ListOfIDSources& theElems) + throw (SALOME::SALOME_Exception) +{ + SMESH_TRY; + initData(); + + TIDSortedElemSet elemSet; + for ( size_t i = 0; i < theElems.length(); ++i ) + { + SMESH::SMESH_IDSource_ptr elems = theElems[i].in(); + SMESH::SMESH_Mesh_var mesh = elems->GetMesh(); + if ( mesh->GetId() != myMesh_i->GetId() ) + THROW_SALOME_CORBA_EXCEPTION("Wrong mesh of IDSource", SALOME::BAD_PARAM); + + idSourceToSet( elems, getMeshDS(), elemSet, SMDSAbs_All ); + } + getEditor().SplitBiQuadraticIntoLinear( elemSet ); + + declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute() + + TPythonDump() << this << ".SplitBiQuadraticIntoLinear( " + << theElems << " )"; + + SMESH_CATCH( SMESH::throwCorbaException ); +} + //======================================================================= //function : Smooth //purpose : @@ -2259,7 +2277,7 @@ SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements, arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face); set fixedNodes; - for (int i = 0; i < IDsOfFixedNodes.length(); i++) { + for ( CORBA::ULong i = 0; i < IDsOfFixedNodes.length(); i++) { CORBA::Long index = IDsOfFixedNodes[i]; const SMDS_MeshNode * node = aMesh->FindNode(index); if ( node ) @@ -2385,309 +2403,81 @@ SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list* groupID } //======================================================================= -//function : rotationSweep +//function : RotationSweepObjects //purpose : //======================================================================= SMESH::ListOfGroups* -SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements, - const SMESH::AxisStruct & theAxis, - CORBA::Double theAngleInRadians, - CORBA::Long theNbOfSteps, - CORBA::Double theTolerance, - const bool theMakeGroups, - const SMDSAbs_ElementType theElementType) +SMESH_MeshEditor_i::RotationSweepObjects(const SMESH::ListOfIDSources & theNodes, + const SMESH::ListOfIDSources & theEdges, + const SMESH::ListOfIDSources & theFaces, + const SMESH::AxisStruct & theAxis, + CORBA::Double theAngleInRadians, + CORBA::Long theNbOfSteps, + CORBA::Double theTolerance, + const bool theMakeGroups) throw (SALOME::SALOME_Exception) { SMESH_TRY; initData(); - TIDSortedElemSet inElements, copyElements; - arrayToSet(theIDsOfElements, getMeshDS(), inElements, theElementType); + TIDSortedElemSet elemsNodes[2]; + for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) { + SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE ); + while ( nIt->more() ) elemsNodes[1].insert( nIt->next() ); + } + for ( int i = 0, nb = theEdges.length(); i < nb; ++i ) + idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge ); + for ( int i = 0, nb = theFaces.length(); i < nb; ++i ) + idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face ); - TIDSortedElemSet* workElements = & inElements; + TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2]; bool makeWalls=true; if ( myIsPreviewMode ) { SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume; - getPreviewMesh( SMDSAbs_Face )->Copy( inElements, copyElements, select, avoid ); - workElements = & copyElements; - //makeWalls = false; + TPreviewMesh * tmpMesh = getPreviewMesh(); + tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid ); + tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid ); + workElements = & copyElements[0]; + //makeWalls = false; -- faces are needed for preview } + TPythonDump aPythonDump; // it is here to prevent dump of getGroups() + gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ), gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz )); ::SMESH_MeshEditor::PGroupIDs groupIds = - getEditor().RotationSweep (*workElements, Ax1, theAngleInRadians, + getEditor().RotationSweep (workElements, Ax1, theAngleInRadians, theNbOfSteps, theTolerance, theMakeGroups, makeWalls); - declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute() - - return theMakeGroups ? getGroups(groupIds.get()) : 0; - - SMESH_CATCH( SMESH::throwCorbaException ); - return 0; -} - -//======================================================================= -//function : RotationSweep -//purpose : -//======================================================================= - -void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements, - const SMESH::AxisStruct & theAxis, - CORBA::Double theAngleInRadians, - CORBA::Long theNbOfSteps, - CORBA::Double theTolerance) - throw (SALOME::SALOME_Exception) -{ - if ( !myIsPreviewMode ) { - TPythonDump() << this << ".RotationSweep( " - << theIDsOfElements << ", " - << theAxis << ", " - << TVar( theAngleInRadians ) << ", " - << TVar( theNbOfSteps ) << ", " - << TVar( theTolerance ) << " )"; - } - rotationSweep(theIDsOfElements, - theAxis, - theAngleInRadians, - theNbOfSteps, - theTolerance, - false); -} - -//======================================================================= -//function : RotationSweepMakeGroups -//purpose : -//======================================================================= + SMESH::ListOfGroups * aGroups = theMakeGroups ? getGroups( groupIds.get()) : 0; -SMESH::ListOfGroups* -SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements, - const SMESH::AxisStruct& theAxis, - CORBA::Double theAngleInRadians, - CORBA::Long theNbOfSteps, - CORBA::Double theTolerance) - throw (SALOME::SALOME_Exception) -{ - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute() - SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements, - theAxis, - theAngleInRadians, - theNbOfSteps, - theTolerance, - true); - if (!myIsPreviewMode) { - dumpGroupsList(aPythonDump, aGroups); - aPythonDump << this << ".RotationSweepMakeGroups( " - << theIDsOfElements << ", " + if ( !myIsPreviewMode ) + { + dumpGroupsList( aPythonDump, aGroups ); + aPythonDump << this<< ".RotationSweepObjects( " + << theNodes << ", " + << theEdges << ", " + << theFaces << ", " << theAxis << ", " << TVar( theAngleInRadians ) << ", " << TVar( theNbOfSteps ) << ", " - << TVar( theTolerance ) << " )"; - } - return aGroups; -} - -//======================================================================= -//function : RotationSweepObject -//purpose : -//======================================================================= - -void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::AxisStruct & theAxis, - CORBA::Double theAngleInRadians, - CORBA::Long theNbOfSteps, - CORBA::Double theTolerance) - throw (SALOME::SALOME_Exception) -{ - if ( !myIsPreviewMode ) { - TPythonDump() << this << ".RotationSweepObject( " - << theObject << ", " - << theAxis << ", " - << theAngleInRadians << ", " - << theNbOfSteps << ", " - << theTolerance << " )"; - } - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - rotationSweep(anElementsId, - theAxis, - theAngleInRadians, - theNbOfSteps, - theTolerance, - false); -} - -//======================================================================= -//function : RotationSweepObject1D -//purpose : -//======================================================================= - -void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::AxisStruct & theAxis, - CORBA::Double theAngleInRadians, - CORBA::Long theNbOfSteps, - CORBA::Double theTolerance) - throw (SALOME::SALOME_Exception) -{ - if ( !myIsPreviewMode ) { - TPythonDump() << this << ".RotationSweepObject1D( " - << theObject << ", " - << theAxis << ", " - << TVar( theAngleInRadians ) << ", " - << TVar( theNbOfSteps ) << ", " - << TVar( theTolerance ) << " )"; - } - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - rotationSweep(anElementsId, - theAxis, - theAngleInRadians, - theNbOfSteps, - theTolerance, - false, - SMDSAbs_Edge); -} - -//======================================================================= -//function : RotationSweepObject2D -//purpose : -//======================================================================= - -void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::AxisStruct & theAxis, - CORBA::Double theAngleInRadians, - CORBA::Long theNbOfSteps, - CORBA::Double theTolerance) - throw (SALOME::SALOME_Exception) -{ - if ( !myIsPreviewMode ) { - TPythonDump() << this << ".RotationSweepObject2D( " - << theObject << ", " - << theAxis << ", " - << TVar( theAngleInRadians ) << ", " - << TVar( theNbOfSteps ) << ", " - << TVar( theTolerance ) << " )"; - } - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - rotationSweep(anElementsId, - theAxis, - theAngleInRadians, - theNbOfSteps, - theTolerance, - false, - SMDSAbs_Face); -} - -//======================================================================= -//function : RotationSweepObjectMakeGroups -//purpose : -//======================================================================= - -SMESH::ListOfGroups* -SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::AxisStruct& theAxis, - CORBA::Double theAngleInRadians, - CORBA::Long theNbOfSteps, - CORBA::Double theTolerance) - throw (SALOME::SALOME_Exception) -{ - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() - - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId, - theAxis, - theAngleInRadians, - theNbOfSteps, - theTolerance, - true); - if (!myIsPreviewMode) { - dumpGroupsList(aPythonDump, aGroups); - aPythonDump << this << ".RotationSweepObjectMakeGroups( " - << theObject << ", " - << theAxis << ", " - << theAngleInRadians << ", " - << theNbOfSteps << ", " - << theTolerance << " )"; + << TVar( theTolerance ) << ", " + << theMakeGroups << " )"; } - return aGroups; -} - -//======================================================================= -//function : RotationSweepObject1DMakeGroups -//purpose : -//======================================================================= - -SMESH::ListOfGroups* -SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::AxisStruct& theAxis, - CORBA::Double theAngleInRadians, - CORBA::Long theNbOfSteps, - CORBA::Double theTolerance) - throw (SALOME::SALOME_Exception) -{ - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() - - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId, - theAxis, - theAngleInRadians, - theNbOfSteps, - theTolerance, - true, - SMDSAbs_Edge); - if (!myIsPreviewMode) { - dumpGroupsList(aPythonDump, aGroups); - aPythonDump << this << ".RotationSweepObject1DMakeGroups( " - << theObject << ", " - << theAxis << ", " - << TVar( theAngleInRadians ) << ", " - << TVar( theNbOfSteps ) << ", " - << TVar( theTolerance ) << " )"; + else + { + getPreviewMesh()->Remove( SMDSAbs_Volume ); } - return aGroups; -} - -//======================================================================= -//function : RotationSweepObject2DMakeGroups -//purpose : -//======================================================================= -SMESH::ListOfGroups* -SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::AxisStruct& theAxis, - CORBA::Double theAngleInRadians, - CORBA::Long theNbOfSteps, - CORBA::Double theTolerance) - throw (SALOME::SALOME_Exception) -{ - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + return aGroups ? aGroups : new SMESH::ListOfGroups; - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId, - theAxis, - theAngleInRadians, - theNbOfSteps, - theTolerance, - true, - SMDSAbs_Face); - if (!myIsPreviewMode) { - dumpGroupsList(aPythonDump, aGroups); - aPythonDump << this << ".RotationSweepObject2DMakeGroups( " - << theObject << ", " - << theAxis << ", " - << TVar( theAngleInRadians ) << ", " - << TVar( theNbOfSteps ) << ", " - << TVar( theTolerance ) << " )"; - } - return aGroups; + SMESH_CATCH( SMESH::throwCorbaException ); + return 0; } namespace MeshEditor_I @@ -2700,6 +2490,7 @@ namespace MeshEditor_I bool myIsExtrusionByNormal; static int makeFlags( CORBA::Boolean MakeGroups, + CORBA::Boolean LinearVariation = false, CORBA::Boolean ByAverageNormal = false, CORBA::Boolean UseInputElemsOnly = false, CORBA::Long Flags = 0, @@ -2708,18 +2499,24 @@ namespace MeshEditor_I if ( MakeGroups ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS; if ( ByAverageNormal ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BY_AVG_NORMAL; if ( UseInputElemsOnly) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY; + if ( LinearVariation ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_SCALE_LINEAR_VARIATION; if ( MakeBoundary ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BOUNDARY; return Flags; } // standard params - ExtrusionParams(const SMESH::DirStruct & theDir, - CORBA::Long theNbOfSteps, - CORBA::Boolean theMakeGroups): + ExtrusionParams(const SMESH::DirStruct & theDir, + CORBA::Long theNbOfSteps, + const SMESH::double_array & theScaleFactors, + CORBA::Boolean theLinearVariation, + const SMESH::double_array & theBasePoint, + CORBA::Boolean theMakeGroups): ::SMESH_MeshEditor::ExtrusParam ( gp_Vec( theDir.PS.x, theDir.PS.y, theDir.PS.z ), theNbOfSteps, - makeFlags( theMakeGroups )), + toList( theScaleFactors ), + TBasePoint( theBasePoint ), + makeFlags( theMakeGroups, theLinearVariation )), myIsExtrusionByNormal( false ) { } @@ -2733,7 +2530,9 @@ namespace MeshEditor_I theDir.PS.y, theDir.PS.z ), theNbOfSteps, - makeFlags( theMakeGroups, false, false, + std::list(), + 0, + makeFlags( theMakeGroups, false, false, false, theExtrFlags, false ), theSewTolerance ), myIsExtrusionByNormal( false ) @@ -2743,12 +2542,12 @@ namespace MeshEditor_I ExtrusionParams(CORBA::Double theStepSize, CORBA::Long theNbOfSteps, CORBA::Short theDim, - CORBA::Boolean theUseInputElemsOnly, CORBA::Boolean theByAverageNormal, + CORBA::Boolean theUseInputElemsOnly, CORBA::Boolean theMakeGroups ): ::SMESH_MeshEditor::ExtrusParam ( theStepSize, theNbOfSteps, - makeFlags( theMakeGroups, + makeFlags( theMakeGroups, false, theByAverageNormal, theUseInputElemsOnly ), theDim), myIsExtrusionByNormal( true ) @@ -2759,329 +2558,122 @@ namespace MeshEditor_I { Flags() &= ~(::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS); } + + private: + + static std::list toList( const SMESH::double_array & theScaleFactors ) + { + std::list scales; + for ( CORBA::ULong i = 0; i < theScaleFactors.length(); ++i ) + scales.push_back( theScaleFactors[i] ); + return scales; + } + + // structure used to convert SMESH::double_array to gp_XYZ* + struct TBasePoint + { + gp_XYZ *pp, p; + TBasePoint( const SMESH::double_array & theBasePoint ) + { + pp = 0; + if ( theBasePoint.length() == 3 ) + { + p.SetCoord( theBasePoint[0], theBasePoint[1], theBasePoint[2] ); + pp = &p; + } + } + operator const gp_XYZ*() const { return pp; } + }; }; } //======================================================================= -//function : extrusionSweep -//purpose : +/*! + * \brief Generate dim+1 elements by extrusion of elements along vector + * \param [in] edges - edges to extrude: a list including groups, sub-meshes or a mesh + * \param [in] faces - faces to extrude: a list including groups, sub-meshes or a mesh + * \param [in] nodes - nodes to extrude: a list including groups, sub-meshes or a mesh + * \param [in] stepVector - vector giving direction and distance of an extrusion step + * \param [in] nbOfSteps - number of elements to generate from one element + * \param [in] toMakeGroups - if true, new elements will be included into new groups + * corresponding to groups the input elements included in. + * \return ListOfGroups - new groups craeted if \a toMakeGroups is true + */ //======================================================================= SMESH::ListOfGroups* -SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements, - MeshEditor_I::ExtrusionParams& theParams, - const SMDSAbs_ElementType theElementType) +SMESH_MeshEditor_i::ExtrusionSweepObjects(const SMESH::ListOfIDSources & theNodes, + const SMESH::ListOfIDSources & theEdges, + const SMESH::ListOfIDSources & theFaces, + const SMESH::DirStruct & theStepVector, + CORBA::Long theNbOfSteps, + const SMESH::double_array & theScaleFactors, + CORBA::Boolean theLinearVariation, + const SMESH::double_array & theBasePoint, + CORBA::Boolean theToMakeGroups) throw (SALOME::SALOME_Exception) { SMESH_TRY; initData(); - TIDSortedElemSet elements, copyElements; - arrayToSet( theIDsOfElements, getMeshDS(), elements, theElementType ); + ExtrusionParams params( theStepVector, theNbOfSteps, theScaleFactors, + theLinearVariation, theBasePoint, theToMakeGroups ); - TIDSortedElemSet* workElements = & elements; + TIDSortedElemSet elemsNodes[2]; + for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) { + SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE ); + while ( nIt->more() ) elemsNodes[1].insert( nIt->next() ); + } + for ( int i = 0, nb = theEdges.length(); i < nb; ++i ) + idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge ); + for ( int i = 0, nb = theFaces.length(); i < nb; ++i ) + idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face ); + TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2]; + SMDSAbs_ElementType previewType = SMDSAbs_All; //SMDSAbs_Face; if ( myIsPreviewMode ) { - SMDSAbs_ElementType previewType = SMDSAbs_Face; - if (theElementType == SMDSAbs_Node) - previewType = SMDSAbs_Edge; + // if ( (*elemsNodes.begin())->GetType() == SMDSAbs_Node ) + // previewType = SMDSAbs_Edge; SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume; - getPreviewMesh( previewType )->Copy( elements, copyElements, select, avoid ); - workElements = & copyElements; - theParams.SetNoGroups(); + TPreviewMesh * tmpMesh = getPreviewMesh( previewType ); + tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid ); + tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid ); + workElements = & copyElements[0]; - if ( theParams.myIsExtrusionByNormal && !theParams.ToUseInpElemsOnly() ) - { - TIDSortedElemSet elemsAround, elemsAroundCopy; - getElementsAround( elements, getMeshDS(), elemsAround ); - getPreviewMesh( previewType )->Copy( elemsAround, elemsAroundCopy, select, avoid ); - } + params.SetNoGroups(); } + TPythonDump aPythonDump; // it is here to prevent dump of getGroups() - ::SMESH_MeshEditor::TTElemOfElemListMap aHystory; + ::SMESH_MeshEditor::TTElemOfElemListMap aHistory; ::SMESH_MeshEditor::PGroupIDs groupIds = - getEditor().ExtrusionSweep (*workElements, theParams, aHystory ); - - declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute() - - return theParams.ToMakeGroups() ? getGroups(groupIds.get()) : 0; - - SMESH_CATCH( SMESH::throwCorbaException ); - return 0; -} - -//======================================================================= -//function : ExtrusionSweep -//purpose : -//======================================================================= - -void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements, - const SMESH::DirStruct & theStepVector, - CORBA::Long theNbOfSteps) - throw (SALOME::SALOME_Exception) -{ - ExtrusionParams params( theStepVector, theNbOfSteps, false ); - extrusionSweep( theIDsOfElements, params ); - if (!myIsPreviewMode) { - TPythonDump() << this << ".ExtrusionSweep( " - << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps) << " )"; - } -} - -//======================================================================= -//function : ExtrusionSweep0D -//purpose : -//======================================================================= - -void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElements, - const SMESH::DirStruct & theStepVector, - CORBA::Long theNbOfSteps) - throw (SALOME::SALOME_Exception) -{ - ExtrusionParams params( theStepVector, theNbOfSteps, false ); - extrusionSweep( theIDsOfElements, params, SMDSAbs_Node ); - if (!myIsPreviewMode) { - TPythonDump() << this << ".ExtrusionSweep0D( " - << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps)<< " )"; - } -} - -//======================================================================= -//function : ExtrusionSweepObject -//purpose : -//======================================================================= - -void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::DirStruct & theStepVector, - CORBA::Long theNbOfSteps) - throw (SALOME::SALOME_Exception) -{ - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - ExtrusionParams params( theStepVector, theNbOfSteps, false ); - extrusionSweep( anElementsId, params ); - if (!myIsPreviewMode) { - TPythonDump() << this << ".ExtrusionSweepObject( " - << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )"; - } -} - -//======================================================================= -//function : ExtrusionSweepObject0D -//purpose : -//======================================================================= - -void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::DirStruct & theStepVector, - CORBA::Long theNbOfSteps) - throw (SALOME::SALOME_Exception) -{ - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - if ( anElementsId->length() == 0 ) - if ( SMESH_Mesh_i* mesh = SMESH::DownCast( theObject )) - anElementsId = mesh->GetNodesId(); + getEditor().ExtrusionSweep( workElements, params, aHistory ); - ExtrusionParams params( theStepVector, theNbOfSteps, false ); - extrusionSweep( anElementsId, params, SMDSAbs_Node ); - if ( !myIsPreviewMode ) { - TPythonDump() << this << ".ExtrusionSweepObject0D( " - << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )"; - } -} + SMESH::ListOfGroups * aGroups = theToMakeGroups ? getGroups( groupIds.get()) : 0; -//======================================================================= -//function : ExtrusionSweepObject1D -//purpose : -//======================================================================= - -void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::DirStruct & theStepVector, - CORBA::Long theNbOfSteps) - throw (SALOME::SALOME_Exception) -{ - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - ExtrusionParams params( theStepVector, theNbOfSteps, false ); - extrusionSweep( anElementsId, params, SMDSAbs_Edge ); - if ( !myIsPreviewMode ) { - TPythonDump() << this << ".ExtrusionSweepObject1D( " - << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )"; - } -} - -//======================================================================= -//function : ExtrusionSweepObject2D -//purpose : -//======================================================================= - -void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::DirStruct & theStepVector, - CORBA::Long theNbOfSteps) - throw (SALOME::SALOME_Exception) -{ - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - ExtrusionParams params( theStepVector, theNbOfSteps, false ); - extrusionSweep( anElementsId, params, SMDSAbs_Face ); - if ( !myIsPreviewMode ) { - TPythonDump() << this << ".ExtrusionSweepObject2D( " - << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )"; - } -} - -//======================================================================= -//function : ExtrusionSweepMakeGroups -//purpose : -//======================================================================= - -SMESH::ListOfGroups* -SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements, - const SMESH::DirStruct& theStepVector, - CORBA::Long theNbOfSteps) - throw (SALOME::SALOME_Exception) -{ - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() - - ExtrusionParams params( theStepVector, theNbOfSteps, true ); - SMESH::ListOfGroups* aGroups = extrusionSweep( theIDsOfElements, params ); - - if (!myIsPreviewMode) { - dumpGroupsList(aPythonDump, aGroups); - aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements - << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )"; - } - return aGroups; -} - -//======================================================================= -//function : ExtrusionSweepMakeGroups0D -//purpose : -//======================================================================= - -SMESH::ListOfGroups* -SMESH_MeshEditor_i::ExtrusionSweepMakeGroups0D(const SMESH::long_array& theIDsOfElements, - const SMESH::DirStruct& theStepVector, - CORBA::Long theNbOfSteps) - throw (SALOME::SALOME_Exception) -{ - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() - - ExtrusionParams params( theStepVector, theNbOfSteps, true ); - SMESH::ListOfGroups* aGroups = extrusionSweep( theIDsOfElements, params, SMDSAbs_Node ); - - if (!myIsPreviewMode) { - dumpGroupsList(aPythonDump, aGroups); - aPythonDump << this << ".ExtrusionSweepMakeGroups0D( " << theIDsOfElements - << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )"; - } - return aGroups; -} - -//======================================================================= -//function : ExtrusionSweepObjectMakeGroups -//purpose : -//======================================================================= - -SMESH::ListOfGroups* -SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::DirStruct& theStepVector, - CORBA::Long theNbOfSteps) - throw (SALOME::SALOME_Exception) -{ - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() - - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - ExtrusionParams params( theStepVector, theNbOfSteps, true ); - SMESH::ListOfGroups* aGroups = extrusionSweep( anElementsId, params ); - - if (!myIsPreviewMode) { - dumpGroupsList(aPythonDump, aGroups); - aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject - << ", " << theStepVector << ", " << theNbOfSteps << " )"; - } - return aGroups; -} - -//======================================================================= -//function : ExtrusionSweepObject0DMakeGroups -//purpose : -//======================================================================= - -SMESH::ListOfGroups* -SMESH_MeshEditor_i::ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::DirStruct& theStepVector, - CORBA::Long theNbOfSteps) - throw (SALOME::SALOME_Exception) -{ - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() - - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - ExtrusionParams params( theStepVector, theNbOfSteps, true ); - SMESH::ListOfGroups* aGroups = extrusionSweep( anElementsId, params, SMDSAbs_Node ); + declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute() - if (!myIsPreviewMode) { - dumpGroupsList(aPythonDump, aGroups); - aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject - << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )"; + if ( !myIsPreviewMode ) + { + dumpGroupsList( aPythonDump, aGroups ); + aPythonDump << this<< ".ExtrusionSweepObjects( " + << theNodes << ", " + << theEdges << ", " + << theFaces << ", " + << theStepVector << ", " + << TVar( theNbOfSteps ) << ", " + << theToMakeGroups << " )"; } - return aGroups; -} - -//======================================================================= -//function : ExtrusionSweepObject1DMakeGroups -//purpose : -//======================================================================= - -SMESH::ListOfGroups* -SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::DirStruct& theStepVector, - CORBA::Long theNbOfSteps) - throw (SALOME::SALOME_Exception) -{ - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() - - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - ExtrusionParams params( theStepVector, theNbOfSteps, true ); - SMESH::ListOfGroups* aGroups = extrusionSweep( anElementsId, params, SMDSAbs_Edge ); - - if (!myIsPreviewMode) { - dumpGroupsList(aPythonDump, aGroups); - aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject - << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )"; + else + { + getPreviewMesh( previewType )->Remove( SMDSAbs_Volume ); } - return aGroups; -} - -//======================================================================= -//function : ExtrusionSweepObject2DMakeGroups -//purpose : -//======================================================================= - -SMESH::ListOfGroups* -SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject, - const SMESH::DirStruct& theStepVector, - CORBA::Long theNbOfSteps) - throw (SALOME::SALOME_Exception) -{ - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - ExtrusionParams params( theStepVector, theNbOfSteps, true ); - SMESH::ListOfGroups* aGroups = extrusionSweep( anElementsId, params, SMDSAbs_Face ); + return aGroups ? aGroups : new SMESH::ListOfGroups; - if (!myIsPreviewMode) { - dumpGroupsList(aPythonDump, aGroups); - aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject - << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )"; - } - return aGroups; + SMESH_CATCH( SMESH::throwCorbaException ); + return 0; } //======================================================================= @@ -3090,833 +2682,304 @@ SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr t //======================================================================= SMESH::ListOfGroups* -SMESH_MeshEditor_i::ExtrusionByNormal(SMESH::SMESH_IDSource_ptr object, - CORBA::Double stepSize, - CORBA::Long nbOfSteps, - CORBA::Boolean byAverageNormal, - CORBA::Boolean useInputElemsOnly, - CORBA::Boolean makeGroups, - CORBA::Short dim) +SMESH_MeshEditor_i::ExtrusionByNormal(const SMESH::ListOfIDSources& objects, + CORBA::Double stepSize, + CORBA::Long nbOfSteps, + CORBA::Boolean byAverageNormal, + CORBA::Boolean useInputElemsOnly, + CORBA::Boolean makeGroups, + CORBA::Short dim) throw (SALOME::SALOME_Exception) { + SMESH_TRY; + initData(); + TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() ExtrusionParams params( stepSize, nbOfSteps, dim, byAverageNormal, useInputElemsOnly, makeGroups ); SMDSAbs_ElementType elemType = ( dim == 1 ? SMDSAbs_Edge : SMDSAbs_Face ); - if ( !SMESH::DownCast( object )) + if ( objects.length() > 0 && !SMESH::DownCast( objects[0] )) { - SMESH::array_of_ElementType_var elemTypes = object->GetTypes(); + SMESH::array_of_ElementType_var elemTypes = objects[0]->GetTypes(); if (( elemTypes->length() == 1 ) && ( elemTypes[0] == SMESH::EDGE || elemTypes[0] == SMESH::FACE )) elemType = ( SMDSAbs_ElementType ) elemTypes[0]; } - prepareIdSource( object ); - SMESH::long_array_var anElementsId = object->GetIDs(); - SMESH::ListOfGroups* aGroups = extrusionSweep( anElementsId, params, elemType ); - if (!myIsPreviewMode) { - dumpGroupsList(aPythonDump, aGroups); - aPythonDump << this << ".ExtrusionByNormal( " << object - << ", " << TVar( stepSize ) - << ", " << TVar( nbOfSteps ) - << ", " << byAverageNormal - << ", " << makeGroups - << ", " << dim - << " )"; - } - return aGroups ? aGroups : new SMESH::ListOfGroups; -} - -//======================================================================= -//function : AdvancedExtrusion -//purpose : -//======================================================================= + TIDSortedElemSet elemsNodes[2]; + for ( int i = 0, nb = objects.length(); i < nb; ++i ) + idSourceToSet( objects[i], getMeshDS(), elemsNodes[0], elemType ); -void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements, - const SMESH::DirStruct & theStepVector, - CORBA::Long theNbOfSteps, - CORBA::Long theExtrFlags, - CORBA::Double theSewTolerance) - throw (SALOME::SALOME_Exception) -{ - ExtrusionParams params( theStepVector, theNbOfSteps, false, theExtrFlags, theSewTolerance); - extrusionSweep( theIDsOfElements, params ); + TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2]; + SMDSAbs_ElementType previewType = SMDSAbs_Face; + if ( myIsPreviewMode ) + { + SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume; + TPreviewMesh * tmpMesh = getPreviewMesh( previewType ); + tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid ); + workElements = & copyElements[0]; - if ( !myIsPreviewMode ) { - TPythonDump() << "stepVector = " << theStepVector; - TPythonDump() << this << ".AdvancedExtrusion(" - << theIDsOfElements - << ", stepVector, " - << theNbOfSteps << "," - << theExtrFlags << ", " - << theSewTolerance << " )"; + params.SetNoGroups(); } -} -//======================================================================= -//function : AdvancedExtrusionMakeGroups -//purpose : -//======================================================================= -SMESH::ListOfGroups* -SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements, - const SMESH::DirStruct& theStepVector, - CORBA::Long theNbOfSteps, - CORBA::Long theExtrFlags, - CORBA::Double theSewTolerance) - throw (SALOME::SALOME_Exception) -{ - if (!myIsPreviewMode) { - TPythonDump() << "stepVector = " << theStepVector; - } - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + ::SMESH_MeshEditor::TTElemOfElemListMap aHistory; + ::SMESH_MeshEditor::PGroupIDs groupIds = + getEditor().ExtrusionSweep( workElements, params, aHistory ); - ExtrusionParams params( theStepVector, theNbOfSteps, true, theExtrFlags, theSewTolerance); - SMESH::ListOfGroups * aGroups = extrusionSweep( theIDsOfElements, params ); + SMESH::ListOfGroups * aGroups = makeGroups ? getGroups( groupIds.get()) : 0; if (!myIsPreviewMode) { dumpGroupsList(aPythonDump, aGroups); - aPythonDump << this << ".AdvancedExtrusionMakeGroups(" - << theIDsOfElements - << ", stepVector, " - << theNbOfSteps << "," - << theExtrFlags << ", " - << theSewTolerance << " )"; - } - return aGroups; -} - - -//================================================================================ -/*! - * \brief Convert extrusion error to IDL enum - */ -//================================================================================ - -#define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm; - -static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e ) -{ - switch ( e ) { - RETCASE( EXTR_OK ); - RETCASE( EXTR_NO_ELEMENTS ); - RETCASE( EXTR_PATH_NOT_EDGE ); - RETCASE( EXTR_BAD_PATH_SHAPE ); - RETCASE( EXTR_BAD_STARTING_NODE ); - RETCASE( EXTR_BAD_ANGLES_NUMBER ); - RETCASE( EXTR_CANT_GET_TANGENT ); - } - return SMESH::SMESH_MeshEditor::EXTR_OK; -} - - -//======================================================================= -//function : extrusionAlongPath -//purpose : -//======================================================================= -SMESH::ListOfGroups* -SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfElements, - SMESH::SMESH_Mesh_ptr thePathMesh, - GEOM::GEOM_Object_ptr thePathShape, - CORBA::Long theNodeStart, - CORBA::Boolean theHasAngles, - const SMESH::double_array & theAngles, - CORBA::Boolean theHasRefPoint, - const SMESH::PointStruct & theRefPoint, - const bool theMakeGroups, - SMESH::SMESH_MeshEditor::Extrusion_Error & theError, - const SMDSAbs_ElementType theElementType) - throw (SALOME::SALOME_Exception) -{ - SMESH_TRY; - MESSAGE("extrusionAlongPath"); - initData(); - - if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) { - theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE; - return 0; - } - SMESH_Mesh_i* aMeshImp = SMESH::DownCast( thePathMesh ); - - TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape ); - SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape ); - - if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) { - theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE; - return 0; - } - - SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart); - if ( !nodeStart ) { - theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE; - return 0; + aPythonDump << this << ".ExtrusionByNormal( " << objects + << ", " << TVar( stepSize ) + << ", " << TVar( nbOfSteps ) + << ", " << byAverageNormal + << ", " << useInputElemsOnly + << ", " << makeGroups + << ", " << dim + << " )"; } - - TIDSortedElemSet elements; - arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType); - - list angles; - for (int i = 0; i < theAngles.length(); i++) { - angles.push_back( theAngles[i] ); + else + { + getPreviewMesh( previewType )->Remove( SMDSAbs_Volume ); } - gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z ); - - int nbOldGroups = myMesh->NbGroup(); - - ::SMESH_MeshEditor::Extrusion_Error error = - getEditor().ExtrusionAlongTrack( elements, aSubMesh, nodeStart, - theHasAngles, angles, false, - theHasRefPoint, refPnt, theMakeGroups ); - - declareMeshModified( /*isReComputeSafe=*/true ); - theError = convExtrError( error ); + declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute() - if ( theMakeGroups ) { - list groupIDs = myMesh->GetGroupIds(); - list::iterator newBegin = groupIDs.begin(); - std::advance( newBegin, nbOldGroups ); // skip old groups - groupIDs.erase( groupIDs.begin(), newBegin ); - return getGroups( & groupIDs ); - } - return 0; + return aGroups ? aGroups : new SMESH::ListOfGroups; SMESH_CATCH( SMESH::throwCorbaException ); return 0; } //======================================================================= -//function : extrusionAlongPathX +//function : AdvancedExtrusion //purpose : //======================================================================= SMESH::ListOfGroups* -SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements, - SMESH::SMESH_IDSource_ptr Path, - CORBA::Long NodeStart, - CORBA::Boolean HasAngles, - const SMESH::double_array& Angles, - CORBA::Boolean LinearVariation, - CORBA::Boolean HasRefPoint, - const SMESH::PointStruct& RefPoint, - bool MakeGroups, - const SMDSAbs_ElementType ElementType, - SMESH::SMESH_MeshEditor::Extrusion_Error & Error) +SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements, + const SMESH::DirStruct & theStepVector, + CORBA::Long theNbOfSteps, + CORBA::Long theExtrFlags, + CORBA::Double theSewTolerance, + CORBA::Boolean theMakeGroups) throw (SALOME::SALOME_Exception) { SMESH_TRY; - SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups; - initData(); - list angles; - for (int i = 0; i < Angles.length(); i++) { - angles.push_back( Angles[i] ); - } - gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z ); - int nbOldGroups = myMesh->NbGroup(); + TPythonDump aPythonDump; // it is here to prevent dump of getGroups() - if ( Path->_is_nil() ) { - Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE; - return EmptyGr; - } + ExtrusionParams params( theStepVector, theNbOfSteps, theMakeGroups, + theExtrFlags, theSewTolerance ); - TIDSortedElemSet elements, copyElements; - arrayToSet(IDsOfElements, getMeshDS(), elements, ElementType); + TIDSortedElemSet elemsNodes[2]; + arrayToSet( theIDsOfElements, getMeshDS(), elemsNodes[0] ); - TIDSortedElemSet* workElements = &elements; + ::SMESH_MeshEditor::TTElemOfElemListMap aHistory; + ::SMESH_MeshEditor::PGroupIDs groupIds = + getEditor().ExtrusionSweep( elemsNodes, params, aHistory ); - if ( myIsPreviewMode ) - { - SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume; - getPreviewMesh( SMDSAbs_Face )->Copy( elements, copyElements, select, avoid ); - workElements = & copyElements; - MakeGroups = false; - } + SMESH::ListOfGroups * aGroups = theMakeGroups ? getGroups( groupIds.get()) : 0; - ::SMESH_MeshEditor::Extrusion_Error error; + declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute() - if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast( Path )) - { - // path as mesh - SMDS_MeshNode* aNodeStart = - (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart); - if ( !aNodeStart ) { - Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE; - return EmptyGr; - } - error = getEditor().ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart, - HasAngles, angles, LinearVariation, - HasRefPoint, refPnt, MakeGroups ); - declareMeshModified( /*isReComputeSafe=*/true ); - } - else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast( Path )) - { - // path as submesh - SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather(); - aMeshImp = SMESH::DownCast( aPathMesh ); - SMDS_MeshNode* aNodeStart = - (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart); - if ( !aNodeStart ) { - Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE; - return EmptyGr; - } - SMESH_subMesh* aSubMesh = - aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId()); - error = getEditor().ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart, - HasAngles, angles, LinearVariation, - HasRefPoint, refPnt, MakeGroups ); - declareMeshModified( /*isReComputeSafe=*/true ); - } - else if ( SMESH::DownCast( Path )) - { - // path as group of 1D elements - // ???????? + if ( !myIsPreviewMode ) { + dumpGroupsList(aPythonDump, aGroups); + aPythonDump << this << ".AdvancedExtrusion( " + << theIDsOfElements << ", " + << theStepVector << ", " + << theNbOfSteps << ", " + << theExtrFlags << ", " + << theSewTolerance << ", " + << theMakeGroups << " )"; } else { - // invalid path - Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE; - return EmptyGr; + getPreviewMesh()->Remove( SMDSAbs_Volume ); } - Error = convExtrError( error ); - - if ( MakeGroups ) { - list groupIDs = myMesh->GetGroupIds(); - list::iterator newBegin = groupIDs.begin(); - std::advance( newBegin, nbOldGroups ); // skip old groups - groupIDs.erase( groupIDs.begin(), newBegin ); - return getGroups( & groupIDs ); - } - return EmptyGr; + return aGroups ? aGroups : new SMESH::ListOfGroups; SMESH_CATCH( SMESH::throwCorbaException ); return 0; } -//======================================================================= -//function : ExtrusionAlongPath -//purpose : -//======================================================================= - -SMESH::SMESH_MeshEditor::Extrusion_Error -SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements, - SMESH::SMESH_Mesh_ptr thePathMesh, - GEOM::GEOM_Object_ptr thePathShape, - CORBA::Long theNodeStart, - CORBA::Boolean theHasAngles, - const SMESH::double_array & theAngles, - CORBA::Boolean theHasRefPoint, - const SMESH::PointStruct & theRefPoint) - throw (SALOME::SALOME_Exception) -{ - MESSAGE("ExtrusionAlongPath"); - if ( !myIsPreviewMode ) { - TPythonDump() << "error = " << this << ".ExtrusionAlongPath( " - << theIDsOfElements << ", " - << thePathMesh << ", " - << thePathShape << ", " - << theNodeStart << ", " - << theHasAngles << ", " - << theAngles << ", " - << theHasRefPoint << ", " - << "SMESH.PointStruct( " - << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )"; - } - SMESH::SMESH_MeshEditor::Extrusion_Error anError; - extrusionAlongPath( theIDsOfElements, - thePathMesh, - thePathShape, - theNodeStart, - theHasAngles, - theAngles, - theHasRefPoint, - theRefPoint, - false, - anError); - return anError; -} - -//======================================================================= -//function : ExtrusionAlongPathObject -//purpose : -//======================================================================= - -SMESH::SMESH_MeshEditor::Extrusion_Error -SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject, - SMESH::SMESH_Mesh_ptr thePathMesh, - GEOM::GEOM_Object_ptr thePathShape, - CORBA::Long theNodeStart, - CORBA::Boolean theHasAngles, - const SMESH::double_array & theAngles, - CORBA::Boolean theHasRefPoint, - const SMESH::PointStruct & theRefPoint) - throw (SALOME::SALOME_Exception) -{ - if ( !myIsPreviewMode ) { - TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( " - << theObject << ", " - << thePathMesh << ", " - << thePathShape << ", " - << theNodeStart << ", " - << theHasAngles << ", " - << theAngles << ", " - << theHasRefPoint << ", " - << "SMESH.PointStruct( " - << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )"; - } - SMESH::SMESH_MeshEditor::Extrusion_Error anError; - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - extrusionAlongPath( anElementsId, - thePathMesh, - thePathShape, - theNodeStart, - theHasAngles, - theAngles, - theHasRefPoint, - theRefPoint, - false, - anError); - return anError; -} - -//======================================================================= -//function : ExtrusionAlongPathObject1D -//purpose : -//======================================================================= - -SMESH::SMESH_MeshEditor::Extrusion_Error -SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject, - SMESH::SMESH_Mesh_ptr thePathMesh, - GEOM::GEOM_Object_ptr thePathShape, - CORBA::Long theNodeStart, - CORBA::Boolean theHasAngles, - const SMESH::double_array & theAngles, - CORBA::Boolean theHasRefPoint, - const SMESH::PointStruct & theRefPoint) - throw (SALOME::SALOME_Exception) -{ - if ( !myIsPreviewMode ) { - TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( " - << theObject << ", " - << thePathMesh << ", " - << thePathShape << ", " - << theNodeStart << ", " - << theHasAngles << ", " - << theAngles << ", " - << theHasRefPoint << ", " - << "SMESH.PointStruct( " - << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )"; - } - SMESH::SMESH_MeshEditor::Extrusion_Error anError; - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - extrusionAlongPath( anElementsId, - thePathMesh, - thePathShape, - theNodeStart, - theHasAngles, - theAngles, - theHasRefPoint, - theRefPoint, - false, - anError, - SMDSAbs_Edge); - return anError; -} - -//======================================================================= -//function : ExtrusionAlongPathObject2D -//purpose : -//======================================================================= - -SMESH::SMESH_MeshEditor::Extrusion_Error -SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject, - SMESH::SMESH_Mesh_ptr thePathMesh, - GEOM::GEOM_Object_ptr thePathShape, - CORBA::Long theNodeStart, - CORBA::Boolean theHasAngles, - const SMESH::double_array & theAngles, - CORBA::Boolean theHasRefPoint, - const SMESH::PointStruct & theRefPoint) - throw (SALOME::SALOME_Exception) -{ - if ( !myIsPreviewMode ) { - TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( " - << theObject << ", " - << thePathMesh << ", " - << thePathShape << ", " - << theNodeStart << ", " - << theHasAngles << ", " - << theAngles << ", " - << theHasRefPoint << ", " - << "SMESH.PointStruct( " - << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )"; - } - SMESH::SMESH_MeshEditor::Extrusion_Error anError; - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - extrusionAlongPath( anElementsId, - thePathMesh, - thePathShape, - theNodeStart, - theHasAngles, - theAngles, - theHasRefPoint, - theRefPoint, - false, - anError, - SMDSAbs_Face); - return anError; -} - - -//======================================================================= -//function : ExtrusionAlongPathMakeGroups -//purpose : -//======================================================================= +//================================================================================ +/*! + * \brief Convert extrusion error to IDL enum + */ +//================================================================================ -SMESH::ListOfGroups* -SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theIDsOfElements, - SMESH::SMESH_Mesh_ptr thePathMesh, - GEOM::GEOM_Object_ptr thePathShape, - CORBA::Long theNodeStart, - CORBA::Boolean theHasAngles, - const SMESH::double_array& theAngles, - CORBA::Boolean theHasRefPoint, - const SMESH::PointStruct& theRefPoint, - SMESH::SMESH_MeshEditor::Extrusion_Error& Error) - throw (SALOME::SALOME_Exception) +namespace { - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() +#define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm; - SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements, - thePathMesh, - thePathShape, - theNodeStart, - theHasAngles, - theAngles, - theHasRefPoint, - theRefPoint, - true, - Error); - if (!myIsPreviewMode) { - bool isDumpGroups = aGroups && aGroups->length() > 0; - if (isDumpGroups) - aPythonDump << "(" << aGroups << ", error)"; - else - aPythonDump <<"error"; - - aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( " - << theIDsOfElements << ", " - << thePathMesh << ", " - << thePathShape << ", " - << theNodeStart << ", " - << theHasAngles << ", " - << theAngles << ", " - << theHasRefPoint << ", " - << "SMESH.PointStruct( " - << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )"; + SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( ::SMESH_MeshEditor::Extrusion_Error e ) + { + switch ( e ) { + RETCASE( EXTR_OK ); + RETCASE( EXTR_NO_ELEMENTS ); + RETCASE( EXTR_PATH_NOT_EDGE ); + RETCASE( EXTR_BAD_PATH_SHAPE ); + RETCASE( EXTR_BAD_STARTING_NODE ); + RETCASE( EXTR_BAD_ANGLES_NUMBER ); + RETCASE( EXTR_CANT_GET_TANGENT ); + } + return SMESH::SMESH_MeshEditor::EXTR_OK; } - return aGroups; } //======================================================================= -//function : ExtrusionAlongPathObjectMakeGroups +//function : extrusionAlongPath //purpose : //======================================================================= - -SMESH::ListOfGroups* SMESH_MeshEditor_i:: -ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject, - SMESH::SMESH_Mesh_ptr thePathMesh, - GEOM::GEOM_Object_ptr thePathShape, - CORBA::Long theNodeStart, - CORBA::Boolean theHasAngles, - const SMESH::double_array& theAngles, - CORBA::Boolean theHasRefPoint, - const SMESH::PointStruct& theRefPoint, - SMESH::SMESH_MeshEditor::Extrusion_Error& Error) +SMESH::ListOfGroups* +SMESH_MeshEditor_i::ExtrusionAlongPathObjects(const SMESH::ListOfIDSources & theNodes, + const SMESH::ListOfIDSources & theEdges, + const SMESH::ListOfIDSources & theFaces, + SMESH::SMESH_IDSource_ptr thePathMesh, + GEOM::GEOM_Object_ptr thePathShape, + CORBA::Long theNodeStart, + CORBA::Boolean theHasAngles, + const SMESH::double_array & theAngles, + CORBA::Boolean theLinearVariation, + CORBA::Boolean theHasRefPoint, + const SMESH::PointStruct & theRefPoint, + bool theMakeGroups, + SMESH::SMESH_MeshEditor::Extrusion_Error& theError) throw (SALOME::SALOME_Exception) { - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + SMESH_TRY; + initData(); - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId, - thePathMesh, - thePathShape, - theNodeStart, - theHasAngles, - theAngles, - theHasRefPoint, - theRefPoint, - true, - Error); + SMESH::ListOfGroups_var aGroups = new SMESH::ListOfGroups; - if (!myIsPreviewMode) { - bool isDumpGroups = aGroups && aGroups->length() > 0; - if (isDumpGroups) - aPythonDump << "(" << aGroups << ", error)"; - else - aPythonDump <<"error"; + theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE; + if ( thePathMesh->_is_nil() ) + return aGroups._retn(); - aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( " - << theObject << ", " - << thePathMesh << ", " - << thePathShape << ", " - << theNodeStart << ", " - << theHasAngles << ", " - << theAngles << ", " - << theHasRefPoint << ", " - << "SMESH.PointStruct( " - << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )"; + // get a sub-mesh + SMESH_subMesh* aSubMesh = 0; + SMESH_Mesh_i* aMeshImp = SMESH::DownCast( thePathMesh ); + if ( thePathShape->_is_nil() ) + { + // thePathMesh should be either a sub-mesh or a mesh with 1D elements only + if ( SMESH_subMesh_i* sm = SMESH::DownCast( thePathMesh )) + { + SMESH::SMESH_Mesh_var mesh = thePathMesh->GetMesh(); + aMeshImp = SMESH::DownCast( mesh ); + if ( !aMeshImp ) return aGroups._retn(); + aSubMesh = aMeshImp->GetImpl().GetSubMeshContaining( sm->GetId() ); + if ( !aSubMesh ) return aGroups._retn(); + } + else if ( !aMeshImp || + aMeshImp->NbEdges() != aMeshImp->NbElements() ) + { + return aGroups._retn(); + } } - return aGroups; -} - -//======================================================================= -//function : ExtrusionAlongPathObject1DMakeGroups -//purpose : -//======================================================================= - -SMESH::ListOfGroups* SMESH_MeshEditor_i:: -ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject, - SMESH::SMESH_Mesh_ptr thePathMesh, - GEOM::GEOM_Object_ptr thePathShape, - CORBA::Long theNodeStart, - CORBA::Boolean theHasAngles, - const SMESH::double_array& theAngles, - CORBA::Boolean theHasRefPoint, - const SMESH::PointStruct& theRefPoint, - SMESH::SMESH_MeshEditor::Extrusion_Error& Error) - throw (SALOME::SALOME_Exception) -{ - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() - - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId, - thePathMesh, - thePathShape, - theNodeStart, - theHasAngles, - theAngles, - theHasRefPoint, - theRefPoint, - true, - Error, - SMDSAbs_Edge); - - if (!myIsPreviewMode) { - bool isDumpGroups = aGroups && aGroups->length() > 0; - if (isDumpGroups) - aPythonDump << "(" << aGroups << ", error)"; - else - aPythonDump << "error"; - - aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( " - << theObject << ", " - << thePathMesh << ", " - << thePathShape << ", " - << theNodeStart << ", " - << theHasAngles << ", " - << theAngles << ", " - << theHasRefPoint << ", " - << "SMESH.PointStruct( " - << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )"; + else + { + if ( !aMeshImp ) return aGroups._retn(); + TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape ); + aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape ); + if ( !aSubMesh /*|| !aSubMesh->GetSubMeshDS()*/ ) + return aGroups._retn(); } - return aGroups; -} -//======================================================================= -//function : ExtrusionAlongPathObject2DMakeGroups -//purpose : -//======================================================================= - -SMESH::ListOfGroups* SMESH_MeshEditor_i:: -ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject, - SMESH::SMESH_Mesh_ptr thePathMesh, - GEOM::GEOM_Object_ptr thePathShape, - CORBA::Long theNodeStart, - CORBA::Boolean theHasAngles, - const SMESH::double_array& theAngles, - CORBA::Boolean theHasRefPoint, - const SMESH::PointStruct& theRefPoint, - SMESH::SMESH_MeshEditor::Extrusion_Error& Error) - throw (SALOME::SALOME_Exception) -{ - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() - - prepareIdSource( theObject ); - SMESH::long_array_var anElementsId = theObject->GetIDs(); - SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId, - thePathMesh, - thePathShape, - theNodeStart, - theHasAngles, - theAngles, - theHasRefPoint, - theRefPoint, - true, - Error, - SMDSAbs_Face); - - if (!myIsPreviewMode) { - bool isDumpGroups = aGroups && aGroups->length() > 0; - if (isDumpGroups) - aPythonDump << "(" << aGroups << ", error)"; - else - aPythonDump << "error"; + SMDS_MeshNode* nodeStart = + (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart); + if ( !nodeStart ) { + theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE; + return aGroups._retn(); + } - aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( " - << theObject << ", " - << thePathMesh << ", " - << thePathShape << ", " - << theNodeStart << ", " - << theHasAngles << ", " - << theAngles << ", " - << theHasRefPoint << ", " - << "SMESH.PointStruct( " - << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", " - << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )"; + TIDSortedElemSet elemsNodes[2]; + for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) { + SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE ); + while ( nIt->more() ) elemsNodes[1].insert( nIt->next() ); } - return aGroups; -} + for ( int i = 0, nb = theEdges.length(); i < nb; ++i ) + idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge ); + for ( int i = 0, nb = theFaces.length(); i < nb; ++i ) + idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face ); -//======================================================================= -//function : ExtrusionAlongPathObjX -//purpose : -//======================================================================= + list angles; + for ( CORBA::ULong i = 0; i < theAngles.length(); i++ ) { + angles.push_back( theAngles[i] ); + } -SMESH::ListOfGroups* SMESH_MeshEditor_i:: -ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr Object, - SMESH::SMESH_IDSource_ptr Path, - CORBA::Long NodeStart, - CORBA::Boolean HasAngles, - const SMESH::double_array& Angles, - CORBA::Boolean LinearVariation, - CORBA::Boolean HasRefPoint, - const SMESH::PointStruct& RefPoint, - CORBA::Boolean MakeGroups, - SMESH::ElementType ElemType, - SMESH::SMESH_MeshEditor::Extrusion_Error& Error) - throw (SALOME::SALOME_Exception) -{ - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z ); - prepareIdSource( Object ); - SMESH::long_array_var anElementsId = Object->GetIDs(); - SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId, - Path, - NodeStart, - HasAngles, - Angles, - LinearVariation, - HasRefPoint, - RefPoint, - MakeGroups, - (SMDSAbs_ElementType)ElemType, - Error); + int nbOldGroups = myMesh->NbGroup(); - if (!myIsPreviewMode) { - bool isDumpGroups = aGroups && aGroups->length() > 0; - if (isDumpGroups) - aPythonDump << "(" << *aGroups << ", error)"; - else - aPythonDump << "error"; - - aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( " - << Object << ", " - << Path << ", " - << NodeStart << ", " - << HasAngles << ", " - << TVar( Angles ) << ", " - << LinearVariation << ", " - << HasRefPoint << ", " - << "SMESH.PointStruct( " - << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", " - << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", " - << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), " - << MakeGroups << ", " - << ElemType << " )"; + TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2]; + if ( myIsPreviewMode ) + { + SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume; + TPreviewMesh * tmpMesh = getPreviewMesh(); + tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid ); + tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid ); + workElements = & copyElements[0]; + theMakeGroups = false; } - return aGroups; -} -//======================================================================= -//function : ExtrusionAlongPathX -//purpose : -//======================================================================= + ::SMESH_MeshEditor::Extrusion_Error error; + if ( !aSubMesh ) + error = getEditor().ExtrusionAlongTrack( workElements, &(aMeshImp->GetImpl()), nodeStart, + theHasAngles, angles, theLinearVariation, + theHasRefPoint, refPnt, theMakeGroups ); + else + error = getEditor().ExtrusionAlongTrack( workElements, aSubMesh, nodeStart, + theHasAngles, angles, theLinearVariation, + theHasRefPoint, refPnt, theMakeGroups ); -SMESH::ListOfGroups* SMESH_MeshEditor_i:: -ExtrusionAlongPathX(const SMESH::long_array& IDsOfElements, - SMESH::SMESH_IDSource_ptr Path, - CORBA::Long NodeStart, - CORBA::Boolean HasAngles, - const SMESH::double_array& Angles, - CORBA::Boolean LinearVariation, - CORBA::Boolean HasRefPoint, - const SMESH::PointStruct& RefPoint, - CORBA::Boolean MakeGroups, - SMESH::ElementType ElemType, - SMESH::SMESH_MeshEditor::Extrusion_Error& Error) - throw (SALOME::SALOME_Exception) -{ - TPythonDump aPythonDump; // it is here to prevent dump of GetGroups() + declareMeshModified( /*isReComputeSafe=*/true ); + theError = convExtrError( error ); - SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements, - Path, - NodeStart, - HasAngles, - Angles, - LinearVariation, - HasRefPoint, - RefPoint, - MakeGroups, - (SMDSAbs_ElementType)ElemType, - Error); + TPythonDump aPythonDump; // it is here to prevent dump of getGroups() + if ( theMakeGroups ) { + list groupIDs = myMesh->GetGroupIds(); + list::iterator newBegin = groupIDs.begin(); + std::advance( newBegin, nbOldGroups ); // skip old groups + groupIDs.erase( groupIDs.begin(), newBegin ); + aGroups = getGroups( & groupIDs ); + if ( ! &aGroups.in() ) aGroups = new SMESH::ListOfGroups; + } - if (!myIsPreviewMode) { - bool isDumpGroups = aGroups && aGroups->length() > 0; - if (isDumpGroups) - aPythonDump << "(" << *aGroups << ", error)"; - else - aPythonDump <<"error"; - - aPythonDump << " = " << this << ".ExtrusionAlongPathX( " - << IDsOfElements << ", " - << Path << ", " - << NodeStart << ", " - << HasAngles << ", " - << TVar( Angles ) << ", " - << LinearVariation << ", " - << HasRefPoint << ", " + if ( !myIsPreviewMode ) { + if ( aGroups->length() > 0 ) aPythonDump << "(" << aGroups << ", error) = "; + else aPythonDump << "(_noGroups, error) = "; + aPythonDump << this << ".ExtrusionAlongPathObjects( " + << theNodes << ", " + << theEdges << ", " + << theFaces << ", " + << thePathMesh << ", " + << thePathShape << ", " + << theNodeStart << ", " + << theHasAngles << ", " + << TVar( theAngles ) << ", " + << theLinearVariation << ", " + << theHasRefPoint << ", " << "SMESH.PointStruct( " - << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", " - << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", " - << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), " - << MakeGroups << ", " - << ElemType << " )"; + << TVar( theHasRefPoint ? theRefPoint.x : 0 ) << ", " + << TVar( theHasRefPoint ? theRefPoint.y : 0 ) << ", " + << TVar( theHasRefPoint ? theRefPoint.z : 0 ) << " ), " + << theMakeGroups << " )"; } - return aGroups; + else + { + getPreviewMesh()->Remove( SMDSAbs_Volume ); + } + + return aGroups._retn(); + + SMESH_CATCH( SMESH::throwCorbaException ); + return 0; } //================================================================================ @@ -4045,17 +3108,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 ); @@ -4111,7 +3171,6 @@ void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObj bool emptyIfIsMesh = myIsPreviewMode ? false : true; - prepareIdSource( theObject ); if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh)) mirror(elements, theAxis, theMirrorType, theCopy, false); } @@ -4161,7 +3220,6 @@ SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr t SMESH::ListOfGroups * aGroups = 0; TIDSortedElemSet elements; - prepareIdSource( theObject ); if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) aGroups = mirror(elements, theMirror, theMirrorType, true, true); @@ -4247,7 +3305,6 @@ SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr the mesh = makeMesh( theMeshName ); mesh_i = SMESH::DownCast( mesh ); TIDSortedElemSet elements; - prepareIdSource( theObject ); if ( mesh_i && idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) { @@ -4315,16 +3372,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; @@ -4375,8 +3428,7 @@ void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject, TIDSortedElemSet elements; bool emptyIfIsMesh = myIsPreviewMode ? false : true; - - prepareIdSource( theObject ); + if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh)) translate(elements, theVector, theCopy, false); } @@ -4422,7 +3474,6 @@ SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObjec SMESH::ListOfGroups * aGroups = 0; TIDSortedElemSet elements; - prepareIdSource( theObject ); if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) aGroups = translate(elements, theVector, true, true); @@ -4505,9 +3556,8 @@ SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject, mesh_i = SMESH::DownCast( mesh ); TIDSortedElemSet elements; - prepareIdSource( theObject ); if ( mesh_i && - idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) + idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) { translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl()); mesh_i->CreateGroupServants(); @@ -4575,7 +3625,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 ); @@ -4633,7 +3683,6 @@ void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject, } TIDSortedElemSet elements; bool emptyIfIsMesh = myIsPreviewMode ? false : true; - prepareIdSource( theObject ); if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh)) rotate(elements,theAxis,theAngle,theCopy,false); } @@ -4683,7 +3732,6 @@ SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject, SMESH::ListOfGroups * aGroups = 0; TIDSortedElemSet elements; - prepareIdSource( theObject ); if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) aGroups = rotate(elements, theAxis, theAngle, true, true); @@ -4775,7 +3823,6 @@ SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject, mesh_i = SMESH::DownCast( mesh ); TIDSortedElemSet elements; - prepareIdSource( theObject ); if (mesh_i && idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) { @@ -4828,7 +3875,6 @@ SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject, theCopy = false; TIDSortedElemSet elements; - prepareIdSource( theObject ); bool emptyIfIsMesh = myIsPreviewMode ? false : true; if ( !idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh)) return 0; @@ -4838,14 +3884,23 @@ SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject, (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1], (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2], }; - double tol = std::numeric_limits::max(); gp_Trsf aTrsf; #if OCC_VERSION_LARGE > 0x06070100 - 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]) ); + // fight against orthogonalization + // 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]) ); + aTrsf.SetScale( gp::Origin(), 1.0 ); // set form which is used to make group names + gp_XYZ & loc = ( gp_XYZ& ) aTrsf.TranslationPart(); + gp_Mat & M = ( gp_Mat& ) aTrsf.HVectorialPart(); + loc.SetCoord( thePoint.x * (1-S[0]), + thePoint.y * (1-S[1]), + 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); @@ -4870,7 +3925,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 ); @@ -4973,25 +4028,24 @@ SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject, //======================================================================= -//function : FindCoincidentNodes +//function : findCoincidentNodes //purpose : //======================================================================= -void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance, - SMESH::array_of_long_array_out GroupsOfNodes) - throw (SALOME::SALOME_Exception) +void SMESH_MeshEditor_i:: +findCoincidentNodes (TIDSortedNodeSet & Nodes, + CORBA::Double Tolerance, + SMESH::array_of_long_array_out GroupsOfNodes, + CORBA::Boolean SeparateCornersAndMedium) { - SMESH_TRY; - initData(); - ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes; - TIDSortedNodeSet nodes; // no input nodes - getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes ); + getEditor().FindCoincidentNodes( Nodes, Tolerance, aListOfListOfNodes, SeparateCornersAndMedium ); GroupsOfNodes = new SMESH::array_of_long_array; GroupsOfNodes->length( aListOfListOfNodes.size() ); ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin(); - for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) { + for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) + { list< const SMDS_MeshNode* >& aListOfNodes = *llIt; list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();; SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ]; @@ -4999,8 +4053,28 @@ void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tol for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ ) aGroup[ j ] = (*lIt)->GetID(); } +} + +//======================================================================= +//function : FindCoincidentNodes +//purpose : +//======================================================================= + +void SMESH_MeshEditor_i:: +FindCoincidentNodes (CORBA::Double Tolerance, + SMESH::array_of_long_array_out GroupsOfNodes, + CORBA::Boolean SeparateCornersAndMedium) + throw (SALOME::SALOME_Exception) +{ + SMESH_TRY; + initData(); + + TIDSortedNodeSet nodes; // no input nodes + findCoincidentNodes( nodes, Tolerance, GroupsOfNodes, SeparateCornersAndMedium ); + TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( " - << Tolerance << " )"; + << Tolerance << ", " + << SeparateCornersAndMedium << " )"; SMESH_CATCH( SMESH::throwCorbaException ); } @@ -5010,37 +4084,25 @@ void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tol //purpose : //======================================================================= -void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject, - CORBA::Double Tolerance, - SMESH::array_of_long_array_out GroupsOfNodes) +void SMESH_MeshEditor_i:: +FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject, + CORBA::Double Tolerance, + SMESH::array_of_long_array_out GroupsOfNodes, + CORBA::Boolean SeparateCornersAndMedium) throw (SALOME::SALOME_Exception) { SMESH_TRY; initData(); TIDSortedNodeSet nodes; - prepareIdSource( theObject ); idSourceToNodeSet( theObject, getMeshDS(), nodes ); - ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes; - if(!nodes.empty()) - getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes ); + findCoincidentNodes( nodes, Tolerance, GroupsOfNodes, SeparateCornersAndMedium ); - GroupsOfNodes = new SMESH::array_of_long_array; - GroupsOfNodes->length( aListOfListOfNodes.size() ); - ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin(); - for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) - { - list< const SMDS_MeshNode* >& aListOfNodes = *llIt; - list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();; - SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ]; - aGroup.length( aListOfNodes.size() ); - for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ ) - aGroup[ j ] = (*lIt)->GetID(); - } TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( " - <GetElements( theExceptSubMeshOrGroups[i], + SMESH::NODE ); + while ( nodeIt->more() ) + nodes.erase( cast2Node( nodeIt->next() )); } - ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes; - if(!nodes.empty()) - getEditor().FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes ); + findCoincidentNodes( nodes, theTolerance, theGroupsOfNodes, theSeparateCornersAndMedium ); - theGroupsOfNodes = new SMESH::array_of_long_array; - theGroupsOfNodes->length( aListOfListOfNodes.size() ); - ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin(); - for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) - { - list< const SMDS_MeshNode* >& aListOfNodes = *llIt; - list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();; - SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ]; - aGroup.length( aListOfNodes.size() ); - for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ ) - aGroup[ j ] = (*lIt)->GetID(); - } TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( " << theObject<<", " << theTolerance << ", " - << theExceptSubMeshOrGroups << " )"; + << theExceptSubMeshOrGroups << ", " + << theSeparateCornersAndMedium << " )"; SMESH_CATCH( SMESH::throwCorbaException ); } @@ -5103,7 +4151,9 @@ FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject, //purpose : //======================================================================= -void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes) +void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes, + const SMESH::ListOfIDSources& NodesToKeep, + CORBA::Boolean AvoidMakingHoles) throw (SALOME::SALOME_Exception) { SMESH_TRY; @@ -5113,18 +4163,32 @@ void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfN TPythonDump aTPythonDump; aTPythonDump << this << ".MergeNodes(["; + + TIDSortedNodeSet setOfNodesToKeep; + for ( CORBA::ULong i = 0; i < NodesToKeep.length(); ++i ) + { + prepareIdSource( NodesToKeep[i] ); + SMDS_ElemIteratorPtr nodeIt = myMesh_i->GetElements( NodesToKeep[i], SMESH::NODE ); + while ( nodeIt->more() ) + setOfNodesToKeep.insert( setOfNodesToKeep.end(), cast2Node( nodeIt->next() )); + } + ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes; - for (int i = 0; i < GroupsOfNodes.length(); i++) + for ( CORBA::ULong i = 0; i < GroupsOfNodes.length(); i++ ) { const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ]; aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() ); list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back(); - for ( int j = 0; j < aNodeGroup.length(); j++ ) + for ( CORBA::ULong j = 0; j < aNodeGroup.length(); j++ ) { CORBA::Long index = aNodeGroup[ j ]; - const SMDS_MeshNode * node = aMesh->FindNode(index); - if ( node ) - aListOfNodes.push_back( node ); + if ( const SMDS_MeshNode * node = aMesh->FindNode( index )) + { + if ( setOfNodesToKeep.count( node )) + aListOfNodes.push_front( node ); + else + aListOfNodes.push_back( node ); + } } if ( aListOfNodes.size() < 2 ) aListOfListOfNodes.pop_back(); @@ -5132,9 +4196,10 @@ void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfN if ( i > 0 ) aTPythonDump << ", "; aTPythonDump << aNodeGroup; } - getEditor().MergeNodes( aListOfListOfNodes ); - aTPythonDump << "])"; + getEditor().MergeNodes( aListOfListOfNodes, AvoidMakingHoles ); + + aTPythonDump << "], " << NodesToKeep << ", " << AvoidMakingHoles << ")"; declareMeshModified( /*isReComputeSafe=*/false ); @@ -5157,7 +4222,6 @@ void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObj if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) ) { TIDSortedElemSet elems; - prepareIdSource( theObject ); idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true); ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID; @@ -5201,11 +4265,11 @@ void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsO ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID; - for (int i = 0; i < GroupsOfElementsID.length(); i++) { + for ( CORBA::ULong i = 0; i < GroupsOfElementsID.length(); i++ ) { const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ]; aListOfListOfElementsID.push_back( list< int >() ); list< int >& aListOfElemsID = aListOfListOfElementsID.back(); - for ( int j = 0; j < anElemsIDGroup.length(); j++ ) { + for ( CORBA::ULong j = 0; j < anElemsIDGroup.length(); j++ ) { CORBA::Long id = anElemsIDGroup[ j ]; aListOfElemsID.push_back( id ); } @@ -5430,7 +4494,7 @@ SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x, SMDSAbs_ElementType( type ), foundElems); res->length( foundElems.size() ); - for ( int i = 0; i < foundElems.size(); ++i ) + for ( size_t i = 0; i < foundElems.size(); ++i ) res[i] = foundElems[i]->GetID(); return res._retn(); @@ -5456,13 +4520,15 @@ SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementID { SMESH_TRY; SMESH::long_array_var res = new SMESH::long_array; - - SMESH::array_of_ElementType_var types = elementIDs->GetTypes(); - if ( types->length() == 1 && // a part contains only nodes or 0D elements - ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) && - type != types[0] ) // but search of elements of dim > 0 - return res._retn(); + if ( type != SMESH::NODE ) + { + SMESH::array_of_ElementType_var types = elementIDs->GetTypes(); + if ( types->length() == 1 && // a part contains only nodes or 0D elements + ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) && + type != types[0] ) // but search of elements of dim > 0 + return res._retn(); + } if ( SMESH::DownCast( elementIDs )) // elementIDs is the whole mesh return FindElementsByPoint( x,y,z, type ); @@ -5476,7 +4542,8 @@ SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementID SMESHDS_Mesh* meshDS = SMESH::DownCast( mesh )->GetImpl().GetMeshDS(); if ( !idSourceToSet( elementIDs, meshDS, elements, - SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true)) + ( type == SMESH::NODE ? SMDSAbs_All : (SMDSAbs_ElementType) type ), + /*emptyIfIsMesh=*/true)) return res._retn(); typedef SMDS_SetIterator TIter; @@ -5491,7 +4558,7 @@ SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementID SMDSAbs_ElementType( type ), foundElems); res->length( foundElems.size() ); - for ( int i = 0; i < foundElems.size(); ++i ) + for ( size_t i = 0; i < foundElems.size(); ++i ) res[i] = foundElems[i]->GetID(); return res._retn(); @@ -5542,10 +4609,230 @@ static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Se RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS ); RETCASE( SEW_BAD_SIDE1_NODES ); RETCASE( SEW_BAD_SIDE2_NODES ); + RETCASE( SEW_INTERNAL_ERROR ); } return SMESH::SMESH_MeshEditor::SEW_OK; } +//======================================================================= +/*! + * Returns groups of FreeBorder's coincident within the given tolerance. + * If the tolerance <= 0.0 then one tenth of an average size of elements adjacent + * to free borders being compared is used. + */ +//======================================================================= + +SMESH::CoincidentFreeBorders* +SMESH_MeshEditor_i::FindCoincidentFreeBorders(CORBA::Double tolerance) +{ + SMESH::CoincidentFreeBorders_var aCFB = new SMESH::CoincidentFreeBorders; + + SMESH_TRY; + + SMESH_MeshAlgos::CoincidentFreeBorders cfb; + SMESH_MeshAlgos::FindCoincidentFreeBorders( *getMeshDS(), tolerance, cfb ); + + // copy free borders + aCFB->borders.length( cfb._borders.size() ); + for ( size_t i = 0; i < cfb._borders.size(); ++i ) + { + SMESH_MeshAlgos::TFreeBorder& nodes = cfb._borders[i]; + SMESH::FreeBorder& aBRD = aCFB->borders[i]; + aBRD.nodeIDs.length( nodes.size() ); + for ( size_t iN = 0; iN < nodes.size(); ++iN ) + aBRD.nodeIDs[ iN ] = nodes[ iN ]->GetID(); + } + + // copy coincident parts + aCFB->coincidentGroups.length( cfb._coincidentGroups.size() ); + for ( size_t i = 0; i < cfb._coincidentGroups.size(); ++i ) + { + SMESH_MeshAlgos::TCoincidentGroup& grp = cfb._coincidentGroups[i]; + SMESH::FreeBordersGroup& aGRP = aCFB->coincidentGroups[i]; + aGRP.length( grp.size() ); + for ( size_t iP = 0; iP < grp.size(); ++iP ) + { + SMESH_MeshAlgos::TFreeBorderPart& part = grp[ iP ]; + SMESH::FreeBorderPart& aPART = aGRP[ iP ]; + aPART.border = part._border; + aPART.node1 = part._node1; + aPART.node2 = part._node2; + aPART.nodeLast = part._nodeLast; + } + } + SMESH_CATCH( SMESH::doNothing ); + + TPythonDump() << "CoincidentFreeBorders = " + << this << ".FindCoincidentFreeBorders( " << tolerance << " )"; + + return aCFB._retn(); +} + +//======================================================================= +/*! + * Sew FreeBorder's of each group + */ +//======================================================================= + +CORBA::Short SMESH_MeshEditor_i:: +SewCoincidentFreeBorders(const SMESH::CoincidentFreeBorders& freeBorders, + CORBA::Boolean createPolygons, + CORBA::Boolean createPolyhedra) + throw (SALOME::SALOME_Exception) +{ + CORBA::Short nbSewed = 0; + + SMESH_MeshAlgos::TFreeBorderVec groups; + SMESH_MeshAlgos::TFreeBorder borderNodes; // triples of nodes for every FreeBorderPart + + // check the input and collect nodes + for ( CORBA::ULong i = 0; i < freeBorders.coincidentGroups.length(); ++i ) + { + borderNodes.clear(); + const SMESH::FreeBordersGroup& aGRP = freeBorders.coincidentGroups[ i ]; + for ( CORBA::ULong iP = 0; iP < aGRP.length(); ++iP ) + { + const SMESH::FreeBorderPart& aPART = aGRP[ iP ]; + if ( aPART.border < 0 || aPART.border >= (int) freeBorders.borders.length() ) + THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::border index", SALOME::BAD_PARAM); + + const SMESH::FreeBorder& aBRD = freeBorders.borders[ aPART.border ]; + + if ( aPART.node1 < 0 || aPART.node1 > (int) aBRD.nodeIDs.length() ) + THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::node1", SALOME::BAD_PARAM); + if ( aPART.node2 < 0 || aPART.node2 > (int) aBRD.nodeIDs.length() ) + THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::node2", SALOME::BAD_PARAM); + if ( aPART.nodeLast < 0 || aPART.nodeLast > (int) aBRD.nodeIDs.length() ) + THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::nodeLast", SALOME::BAD_PARAM); + + // do not keep these nodes for further sewing as nodes can be removed by the sewing + const SMDS_MeshNode* n1 = getMeshDS()->FindNode( aBRD.nodeIDs[ aPART.node1 ]); + const SMDS_MeshNode* n2 = getMeshDS()->FindNode( aBRD.nodeIDs[ aPART.node2 ]); + const SMDS_MeshNode* n3 = getMeshDS()->FindNode( aBRD.nodeIDs[ aPART.nodeLast ]); + if ( !n1) + THROW_SALOME_CORBA_EXCEPTION("Nonexistent FreeBorderPart::node1", SALOME::BAD_PARAM); + if ( !n2 ) + THROW_SALOME_CORBA_EXCEPTION("Nonexistent FreeBorderPart::node2", SALOME::BAD_PARAM); + if ( !n3 ) + THROW_SALOME_CORBA_EXCEPTION("Nonexistent FreeBorderPart::nodeLast", SALOME::BAD_PARAM); + + borderNodes.push_back( n1 ); + borderNodes.push_back( n2 ); + borderNodes.push_back( n3 ); + } + groups.push_back( borderNodes ); + } + + // SewFreeBorder() can merge nodes, thus nodes stored in 'groups' can become dead; + // to get nodes that replace other nodes during merge we create 0D elements + // on each node and MergeNodes() will replace underlying nodes of 0D elements by + // new ones. + + vector< const SMDS_MeshElement* > tmp0Delems; + for ( size_t i = 0; i < groups.size(); ++i ) + { + SMESH_MeshAlgos::TFreeBorder& nodes = groups[i]; + for ( size_t iN = 0; iN < nodes.size(); ++iN ) + { + SMDS_ElemIteratorPtr it0D = nodes[iN]->GetInverseElementIterator(SMDSAbs_0DElement); + if ( it0D->more() ) + tmp0Delems.push_back( it0D->next() ); + else + tmp0Delems.push_back( getMeshDS()->Add0DElement( nodes[iN] )); + } + } + + // cout << endl << "INIT" << endl; + // for ( size_t i = 0; i < tmp0Delems.size(); ++i ) + // { + // cout << i << " "; + // if ( i % 3 == 0 ) cout << "^ "; + // tmp0Delems[i]->GetNode(0)->Print( cout ); + // } + + SMESH_TRY; + + ::SMESH_MeshEditor::Sew_Error res, ok = ::SMESH_MeshEditor::SEW_OK; + int i0D = 0; + for ( size_t i = 0; i < groups.size(); ++i ) + { + bool isBordToBord = true; + bool groupSewed = false; + SMESH_MeshAlgos::TFreeBorder& nodes = groups[i]; + for ( size_t iN = 3; iN+2 < nodes.size(); iN += 3 ) + { + const SMDS_MeshNode* n0 = tmp0Delems[ i0D + 0 ]->GetNode( 0 ); + const SMDS_MeshNode* n1 = tmp0Delems[ i0D + 1 ]->GetNode( 0 ); + const SMDS_MeshNode* n2 = tmp0Delems[ i0D + 2 ]->GetNode( 0 ); + + const SMDS_MeshNode* n3 = tmp0Delems[ i0D + 0 + iN ]->GetNode( 0 ); + const SMDS_MeshNode* n4 = tmp0Delems[ i0D + 1 + iN ]->GetNode( 0 ); + const SMDS_MeshNode* n5 = tmp0Delems[ i0D + 2 + iN ]->GetNode( 0 ); + + if ( !n0 || !n1 || !n2 || !n3 || !n4 || !n5 ) + continue; + + // TIDSortedElemSet emptySet, avoidSet; + // if ( !SMESH_MeshAlgos::FindFaceInSet( n0, n1, emptySet, avoidSet)) + // { + // cout << "WRONG 2nd 1" << endl; + // n0->Print( cout ); + // n1->Print( cout ); + // } + // if ( !SMESH_MeshAlgos::FindFaceInSet( n3, n4, emptySet, avoidSet)) + // { + // cout << "WRONG 2nd 2" << endl; + // n3->Print( cout ); + // n4->Print( cout ); + // } + + if ( !isBordToBord ) + { + n1 = n2; // at border-to-side sewing only last side node (n1) is needed + n2 = 0; // and n2 is not used + } + // 1st border moves to 2nd + res = getEditor().SewFreeBorder( n3, n4, n5 ,// 1st + n0 ,n1 ,n2 ,// 2nd + /*2ndIsFreeBorder=*/ isBordToBord, + createPolygons, createPolyhedra); + groupSewed = ( res == ok ); + + isBordToBord = false; + // cout << endl << "SEWED GROUP " << i << " PART " << iN / 3 << endl; + // for ( size_t t = 0; t < tmp0Delems.size(); ++t ) + // { + // cout << t << " "; + // if ( t % 3 == 0 ) cout << "^ "; + // tmp0Delems[t]->GetNode(0)->Print( cout ); + // } + } + i0D += nodes.size(); + nbSewed += groupSewed; + } + + TPythonDump() << "nbSewed = " << this << ".SewCoincidentFreeBorders( " + << freeBorders << ", " + << createPolygons << ", " + << createPolyhedra << " )"; + + SMESH_CATCH( SMESH::doNothing ); + + declareMeshModified( /*isReComputeSafe=*/false ); + + // remove tmp 0D elements + SMESH_TRY; + set< const SMDS_MeshElement* > removed0D; + for ( size_t i = 0; i < tmp0Delems.size(); ++i ) + { + if ( removed0D.insert( tmp0Delems[i] ).second ) + getMeshDS()->RemoveFreeElement( tmp0Delems[i], /*sm=*/0, /*fromGroups=*/false ); + } + SMESH_CATCH( SMESH::throwCorbaException ); + + return nbSewed; +} + //======================================================================= //function : SewFreeBorders //purpose : @@ -5595,14 +4882,14 @@ SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1, SMESH::SMESH_MeshEditor::Sew_Error error = convError( getEditor().SewFreeBorder (aBorderFirstNode, - aBorderSecondNode, - aBorderLastNode, - aSide2FirstNode, - aSide2SecondNode, - aSide2ThirdNode, - true, - CreatePolygons, - CreatePolyedrs) ); + aBorderSecondNode, + aBorderLastNode, + aSide2FirstNode, + aSide2SecondNode, + aSide2ThirdNode, + true, + CreatePolygons, + CreatePolyedrs) ); declareMeshModified( /*isReComputeSafe=*/false ); @@ -5655,13 +4942,13 @@ SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1, SMESH::SMESH_MeshEditor::Sew_Error error = convError( getEditor().SewFreeBorder (aBorderFirstNode, - aBorderSecondNode, - aBorderLastNode, - aSide2FirstNode, - aSide2SecondNode, - aSide2ThirdNode, - true, - false, false) ); + aBorderSecondNode, + aBorderLastNode, + aSide2FirstNode, + aSide2SecondNode, + aSide2ThirdNode, + true, + false, false) ); declareMeshModified( /*isReComputeSafe=*/false ); return error; @@ -5717,14 +5004,14 @@ SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder, SMESH::SMESH_MeshEditor::Sew_Error error = convError( getEditor().SewFreeBorder (aBorderFirstNode, - aBorderSecondNode, - aBorderLastNode, - aSide2FirstNode, - aSide2SecondNode, - aSide2ThirdNode, - false, - CreatePolygons, - CreatePolyedrs) ); + aBorderSecondNode, + aBorderLastNode, + aSide2FirstNode, + aSide2SecondNode, + aSide2ThirdNode, + false, + CreatePolygons, + CreatePolyedrs) ); declareMeshModified( /*isReComputeSafe=*/false ); return error; @@ -5824,7 +5111,6 @@ CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide, TPythonDump() << "isDone = " << this << ".ChangeElemNodes( " << ide << ", " << newIDs << " )"; - MESSAGE("ChangeElementNodes"); bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 ); declareMeshModified( /*isReComputeSafe=*/ !res ); @@ -5847,11 +5133,12 @@ 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 ))) { - prepareIdSource( theObject ); elemsOK = idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ); } @@ -5877,10 +5164,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; } //======================================================================= @@ -5933,11 +5226,11 @@ void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr th throw (SALOME::SALOME_Exception) { SMESH_TRY; + initData(); TPythonDump pyDump; TIDSortedElemSet elems; - prepareIdSource( theObject ); if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true )) { if ( elems.empty() ) @@ -5998,10 +5291,10 @@ void SMESH_MeshEditor_i::dumpGroupsList(TPythonDump & theDumpPytho */ //================================================================================ -string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix) +std::string SMESH_MeshEditor_i::generateGroupName(const std::string& thePrefix) { SMESH::ListOfGroups_var groups = myMesh_i->GetGroups(); - set groupNames; + set groupNames; // Get existing group names for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) { @@ -6014,7 +5307,7 @@ string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix) } // Find new name - string name = thePrefix; + std::string name = thePrefix; int index = 0; while (!groupNames.insert(name).second) @@ -6037,10 +5330,68 @@ void SMESH_MeshEditor_i::prepareIdSource(SMESH::SMESH_IDSource_ptr theObject) filter->SetMesh( mesh ); } } +//================================================================================ +/*! + * \brief Retrieve elements of given type from SMESH_IDSource + */ +//================================================================================ + +bool SMESH_MeshEditor_i::idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource, + const SMESHDS_Mesh* theMeshDS, + TIDSortedElemSet& theElemSet, + const SMDSAbs_ElementType theType, + const bool emptyIfIsMesh, + IDSource_Error* error) + +{ + if ( error ) *error = IDSource_OK; + + if ( CORBA::is_nil( theIDSource )) + { + if ( error ) *error = IDSource_INVALID; + return false; + } + if ( emptyIfIsMesh && SMESH::DownCast( theIDSource )) + { + if ( error && getMeshDS()->GetMeshInfo().NbElements( theType ) == 0 ) + *error = IDSource_EMPTY; + return true; + } + prepareIdSource( theIDSource ); + SMESH::long_array_var anIDs = theIDSource->GetIDs(); + if ( anIDs->length() == 0 ) + { + if ( error ) *error = IDSource_EMPTY; + return false; + } + SMESH::array_of_ElementType_var types = theIDSource->GetTypes(); + if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes + { + if ( theType == SMDSAbs_All || theType == SMDSAbs_Node ) + { + arrayToSet( anIDs, getMeshDS(), theElemSet, SMDSAbs_Node ); + } + else + { + if ( error ) *error = IDSource_INVALID; + return false; + } + } + else + { + arrayToSet( anIDs, getMeshDS(), theElemSet, theType); + if ( bool(anIDs->length()) != bool(theElemSet.size())) + { + if ( error ) *error = IDSource_INVALID; + return false; + } + } + return true; +} //================================================================================ /*! - * \brief Duplicates given elements, i.e. creates new elements based on the + * \brief Duplicates given elements, i.e. creates new elements based on the * same nodes as the given ones. * \param theElements - container of elements to duplicate. * \param theGroupName - a name of group to contain the generated elements. @@ -6066,7 +5417,6 @@ SMESH_MeshEditor_i::DoubleElements(SMESH::SMESH_IDSource_ptr theElements, TPythonDump pyDump; TIDSortedElemSet elems; - prepareIdSource( theElements ); if ( idSourceToSet( theElements, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true)) { getEditor().DoubleElements( elems ); @@ -6265,8 +5615,8 @@ SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes, // Create group with newly created nodes SMESH::long_array_var anIds = GetLastCreatedNodes(); if (anIds->length() > 0) { - string anUnindexedName (theNodes->GetName()); - string aNewName = generateGroupName(anUnindexedName + "_double"); + std::string anUnindexedName (theNodes->GetName()); + std::string aNewName = generateGroupName(anUnindexedName + "_double"); aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str()); aNewGroup->Add(anIds); pyDump << aNewGroup << " = "; @@ -6364,8 +5714,8 @@ SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes, // Create group with newly created nodes SMESH::long_array_var anIds = GetLastCreatedNodes(); if (anIds->length() > 0) { - string anUnindexedName (theNodes[0]->GetName()); - string aNewName = generateGroupName(anUnindexedName + "_double"); + std::string anUnindexedName (theNodes[0]->GetName()); + std::string aNewName = generateGroupName(anUnindexedName + "_double"); aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str()); aNewGroup->Add(anIds); pyDump << aNewGroup << " = "; @@ -6589,7 +5939,7 @@ SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems, { // Create group with newly created elements CORBA::String_var elemGroupName = theElems->GetName(); - string aNewName = generateGroupName( string(elemGroupName.in()) + "_double"); + std::string aNewName = generateGroupName( std::string(elemGroupName.in()) + "_double"); if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded ) { SMESH::long_array_var anIds = GetLastCreatedElems(); @@ -6821,7 +6171,7 @@ SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems { // Create group with newly created elements CORBA::String_var elemGroupName = theElems[0]->GetName(); - string aNewName = generateGroupName( string(elemGroupName.in()) + "_double"); + std::string aNewName = generateGroupName( std::string(elemGroupName.in()) + "_double"); if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded ) { SMESH::long_array_var anIds = GetLastCreatedElems(); @@ -6923,7 +6273,6 @@ SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theEl throw (SALOME::SALOME_Exception) { SMESH_TRY; - MESSAGE("AffectedElemGroupsInRegion"); SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups(); bool isEdgeGroup = false; bool isFaceGroup = false; @@ -6952,7 +6301,6 @@ SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theEl if (aResult) { int lg = anAffected.size(); - MESSAGE("lg="<< lg); SMESH::long_array_var volumeIds = new SMESH::long_array; volumeIds->length(lg); SMESH::long_array_var faceIds = new SMESH::long_array; @@ -7191,7 +6539,7 @@ void SMESH_MeshEditor_i::CreateHoleSkin(CORBA::Double radius, theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() ); vector nodesCoords; - for (int i = 0; i < theNodesCoords.length(); i++) + for ( CORBA::ULong i = 0; i < theNodesCoords.length(); i++) { nodesCoords.push_back( theNodesCoords[i] ); } @@ -7263,7 +6611,6 @@ SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource, TIDSortedElemSet elements; SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume; - prepareIdSource( idSource ); if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true )) { // mesh to fill in @@ -7302,7 +6649,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( " @@ -7353,12 +6700,12 @@ CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim, THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM); // separate groups belonging to this and other mesh - SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources; + SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources; SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources; - groupsOfThisMesh->length( groups.length() ); + groupsOfThisMesh ->length( groups.length() ); groupsOfOtherMesh->length( groups.length() ); int nbGroups = 0, nbGroupsOfOtherMesh = 0; - for ( int i = 0; i < groups.length(); ++i ) + for ( CORBA::ULong i = 0; i < groups.length(); ++i ) { SMESH::SMESH_Mesh_var m = groups[i]->GetMesh(); if ( myMesh_i != SMESH::DownCast( m )) @@ -7366,7 +6713,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 ); @@ -7460,7 +6807,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( "