1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_MeshEditor_i.cxx
23 // Author : Nicolas REJNERI
30 // A macro used in SMESH_TryCatch.hxx,
31 // it re-raises a CORBA SALOME exception thrown by SMESH_MeshEditor_i and caught by SMESH_CATCH
32 #define SMY_OWN_CATCH \
33 catch ( SALOME::SALOME_Exception & e ) { throw e; }
35 #include "SMESH_MeshEditor_i.hxx"
37 #include "SMDS_EdgePosition.hxx"
38 #include "SMDS_ElemIterator.hxx"
39 #include "SMDS_FacePosition.hxx"
40 #include "SMDS_IteratorOnIterators.hxx"
41 #include "SMDS_LinearEdge.hxx"
42 #include "SMDS_Mesh0DElement.hxx"
43 #include "SMDS_MeshFace.hxx"
44 #include "SMDS_MeshVolume.hxx"
45 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
46 #include "SMDS_SetIterator.hxx"
47 #include "SMDS_VolumeTool.hxx"
48 #include "SMESHDS_Group.hxx"
49 #include "SMESHDS_GroupOnGeom.hxx"
50 #include "SMESH_ControlsDef.hxx"
51 #include "SMESH_Filter_i.hxx"
52 #include "SMESH_Gen_i.hxx"
53 #include "SMESH_Group.hxx"
54 #include "SMESH_Group_i.hxx"
55 #include "SMESH_MeshAlgos.hxx"
56 #include "SMESH_MeshPartDS.hxx"
57 #include "SMESH_MesherHelper.hxx"
58 #include "SMESH_PythonDump.hxx"
59 #include "SMESH_subMeshEventListener.hxx"
60 #include "SMESH_subMesh_i.hxx"
62 #include <utilities.h>
63 #include <Utils_ExceptHandlers.hxx>
64 #include <Utils_CorbaException.hxx>
65 #include <SALOMEDS_wrap.hxx>
66 #include <SALOME_GenericObj_i.hh>
68 #include <BRepAdaptor_Surface.hxx>
69 #include <BRep_Tool.hxx>
70 #include <TopExp_Explorer.hxx>
72 #include <TopoDS_Edge.hxx>
73 #include <TopoDS_Face.hxx>
78 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
82 #include <Standard_Failure.hxx>
85 #include <Standard_ErrorHandler.hxx>
91 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
93 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
96 using SMESH::TPythonDump;
99 namespace MeshEditor_I {
101 //=============================================================================
103 * \brief Mesh to apply modifications for preview purposes
105 //=============================================================================
107 struct TPreviewMesh: public SMESH_Mesh
109 SMDSAbs_ElementType myPreviewType; // type to show
111 TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
112 _isShapeToMesh = (_id =_studyId = 0);
113 _myMeshDS = new SMESHDS_Mesh( _id, true );
114 myPreviewType = previewElements;
117 virtual ~TPreviewMesh() { delete _myMeshDS; _myMeshDS = 0; }
118 //!< Copy a set of elements
119 void Copy(const TIDSortedElemSet & theElements,
120 TIDSortedElemSet& theCopyElements,
121 SMDSAbs_ElementType theSelectType = SMDSAbs_All,
122 SMDSAbs_ElementType theAvoidType = SMDSAbs_All)
124 // loop on theIDsOfElements
125 TIDSortedElemSet::const_iterator eIt = theElements.begin();
126 for ( ; eIt != theElements.end(); ++eIt )
128 const SMDS_MeshElement* anElem = *eIt;
129 if ( !anElem ) continue;
130 SMDSAbs_ElementType type = anElem->GetType();
131 if ( type == theAvoidType ||
132 ( theSelectType != SMDSAbs_All && type != theSelectType ))
134 const SMDS_MeshElement* anElemCopy;
135 if ( type == SMDSAbs_Node)
136 anElemCopy = Copy( cast2Node(anElem) );
138 anElemCopy = Copy( anElem );
140 theCopyElements.insert( theCopyElements.end(), anElemCopy );
144 SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
146 // copy element nodes
147 int anElemNbNodes = anElem->NbNodes();
148 vector< int > anElemNodesID( anElemNbNodes ) ;
149 SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
150 for ( int i = 0; itElemNodes->more(); i++)
152 const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
154 anElemNodesID[i] = anElemNode->GetID();
157 // creates a corresponding element on copied nodes
158 SMDS_MeshElement* anElemCopy = 0;
159 if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
161 const SMDS_VtkVolume* ph =
162 dynamic_cast<const SMDS_VtkVolume*> (anElem);
164 anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
165 (anElemNodesID, ph->GetQuantities(),anElem->GetID());
168 anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
175 SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
177 return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(),
178 anElemNode->GetID());
182 GetMeshDS()->ClearMesh();
184 };// struct TPreviewMesh
186 static SMESH_NodeSearcher * theNodeSearcher = 0;
187 static SMESH_ElementSearcher * theElementSearcher = 0;
189 //=============================================================================
191 * \brief Deleter of theNodeSearcher at any compute event occured
193 //=============================================================================
195 struct TSearchersDeleter : public SMESH_subMeshEventListener
198 string myMeshPartIOR;
200 TSearchersDeleter(): SMESH_subMeshEventListener( false, // won't be deleted by submesh
201 "SMESH_MeshEditor_i::TSearchersDeleter"),
203 //!< Delete theNodeSearcher
206 if ( theNodeSearcher ) delete theNodeSearcher; theNodeSearcher = 0;
207 if ( theElementSearcher ) delete theElementSearcher; theElementSearcher = 0;
209 typedef map < int, SMESH_subMesh * > TDependsOnMap;
210 //!< The meshod called by submesh: do my main job
211 void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
212 SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
214 if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
216 Unset( sm->GetFather() );
219 //!< set self on all submeshes and delete theNodeSearcher if other mesh is set
220 void Set(SMESH_Mesh* mesh, const string& meshPartIOR = string())
222 if ( myMesh != mesh || myMeshPartIOR != meshPartIOR)
229 myMeshPartIOR = meshPartIOR;
230 SMESH_subMesh* sm = mesh->GetSubMesh( mesh->GetShapeToMesh() );
231 SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true );
232 while ( smIt->more() )
235 sm->SetEventListener( this, 0, sm );
239 //!< delete self from all submeshes
240 void Unset(SMESH_Mesh* mesh)
242 if ( SMESH_subMesh* sm = mesh->GetSubMeshContaining(1) ) {
243 SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true );
244 while ( smIt->more() )
245 smIt->next()->DeleteEventListener( this );
250 } theSearchersDeleter;
252 TCollection_AsciiString mirrorTypeName( SMESH::SMESH_MeshEditor::MirrorType theMirrorType )
254 TCollection_AsciiString typeStr;
255 switch ( theMirrorType ) {
256 case SMESH::SMESH_MeshEditor::POINT:
257 typeStr = "SMESH.SMESH_MeshEditor.POINT";
259 case SMESH::SMESH_MeshEditor::AXIS:
260 typeStr = "SMESH.SMESH_MeshEditor.AXIS";
263 typeStr = "SMESH.SMESH_MeshEditor.PLANE";
267 //================================================================================
269 * \brief function for conversion of long_array to TIDSortedElemSet
270 * \param IDs - array of IDs
271 * \param aMesh - mesh
272 * \param aMap - collection to fill
273 * \param aType - element type
275 //================================================================================
277 void arrayToSet(const SMESH::long_array & IDs,
278 const SMESHDS_Mesh* aMesh,
279 TIDSortedElemSet& aMap,
280 const SMDSAbs_ElementType aType = SMDSAbs_All,
281 SMDS_MeshElement::Filter* aFilter = NULL)
283 SMDS_MeshElement::NonNullFilter filter1;
284 SMDS_MeshElement::TypeFilter filter2( aType );
286 if ( aFilter == NULL )
287 aFilter = ( aType == SMDSAbs_All ) ? (SMDS_MeshElement::Filter*) &filter1 : (SMDS_MeshElement::Filter*) &filter2;
289 SMDS_MeshElement::Filter & filter = *aFilter;
291 if ( aType == SMDSAbs_Node )
292 for (int i=0; i<IDs.length(); i++) {
293 const SMDS_MeshElement * elem = aMesh->FindNode( IDs[i] );
295 aMap.insert( aMap.end(), elem );
298 for (int i=0; i<IDs.length(); i++) {
299 const SMDS_MeshElement * elem = aMesh->FindElement( IDs[i] );
301 aMap.insert( aMap.end(), elem );
304 //================================================================================
306 * \brief Retrieve elements of given type from SMESH_IDSource
308 //================================================================================
310 bool idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource,
311 const SMESHDS_Mesh* theMeshDS,
312 TIDSortedElemSet& theElemSet,
313 const SMDSAbs_ElementType theType,
314 const bool emptyIfIsMesh=false)
317 if ( CORBA::is_nil( theIDSource ) )
319 if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
322 SMESH::long_array_var anIDs = theIDSource->GetIDs();
323 if ( anIDs->length() == 0 )
325 SMESH::array_of_ElementType_var types = theIDSource->GetTypes();
326 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
328 if ( theType == SMDSAbs_All || theType == SMDSAbs_Node )
329 arrayToSet( anIDs, theMeshDS, theElemSet, SMDSAbs_Node );
335 arrayToSet( anIDs, theMeshDS, theElemSet, theType);
336 return bool(anIDs->length()) == bool(theElemSet.size());
340 //================================================================================
342 * \brief Retrieve nodes from SMESH_IDSource
344 //================================================================================
346 void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject,
347 const SMESHDS_Mesh* theMeshDS,
348 TIDSortedNodeSet& theNodeSet)
351 if ( CORBA::is_nil( theObject ) )
353 SMESH::array_of_ElementType_var types = theObject->GetTypes();
354 SMESH::long_array_var aElementsId = theObject->GetIDs();
355 if ( types->length() == 1 && types[0] == SMESH::NODE)
357 for(int i = 0; i < aElementsId->length(); i++)
358 if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] ))
359 theNodeSet.insert( theNodeSet.end(), n);
361 else if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
363 SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator();
364 while ( nIt->more( ))
365 if( const SMDS_MeshElement * elem = nIt->next() )
366 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
370 for(int i = 0; i < aElementsId->length(); i++)
371 if( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] ))
372 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
376 //================================================================================
378 * \brief Returns elements connected to the given elements
380 //================================================================================
382 void getElementsAround(const TIDSortedElemSet& theElements,
383 const SMESHDS_Mesh* theMeshDS,
384 TIDSortedElemSet& theElementsAround)
386 if ( theElements.empty() ) return;
388 SMDSAbs_ElementType elemType = (*theElements.begin())->GetType();
389 bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() );
391 theMeshDS->GetMeshInfo().NbElements( elemType ) == theElements.size() )
392 return; // all the elements are in theElements
395 elemType = SMDSAbs_All;
397 TIDSortedElemSet visitedNodes;
398 TIDSortedElemSet::const_iterator elemIt = theElements.begin();
399 for ( ; elemIt != theElements.end(); ++elemIt )
401 const SMDS_MeshElement* e = *elemIt;
402 int i = e->NbCornerNodes();
405 const SMDS_MeshNode* n = e->GetNode( i );
406 if ( visitedNodes.insert( n ).second )
408 SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
409 while ( invIt->more() )
411 const SMDS_MeshElement* elemAround = invIt->next();
412 if ( !theElements.count( elemAround ))
413 theElementsAround.insert( elemAround );
420 //================================================================================
422 * \brief Return a string used to detect change of mesh part on which theElementSearcher
423 * is going to be used
425 //================================================================================
427 string getPartIOR( SMESH::SMESH_IDSource_ptr theMeshPart, SMESH::ElementType type)
429 string partIOR = SMESH_Gen_i::GetORB()->object_to_string( theMeshPart );
430 if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( theMeshPart ))
431 // take into account passible group modification
432 partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() );
433 partIOR += SMESH_Comment( type );
437 } // namespace MeshEditor_I
439 using namespace MeshEditor_I;
441 //=============================================================================
445 //=============================================================================
447 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview):
449 myMesh( &theMesh->GetImpl() ),
451 myIsPreviewMode ( isPreview ),
457 //================================================================================
461 //================================================================================
463 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
465 PortableServer::POA_var poa = SMESH_Gen_i::GetPOA();
466 PortableServer::ObjectId_var anObjectId = poa->servant_to_id(this);
467 poa->deactivate_object(anObjectId.in());
469 //deleteAuxIDSources();
470 delete myPreviewMesh; myPreviewMesh = 0;
471 delete myPreviewEditor; myPreviewEditor = 0;
474 //================================================================================
476 * \brief Clear members
478 //================================================================================
480 void SMESH_MeshEditor_i::initData(bool deleteSearchers)
482 if ( myIsPreviewMode ) {
483 if ( myPreviewMesh ) myPreviewMesh->RemoveAll();
486 if ( deleteSearchers )
487 TSearchersDeleter::Delete();
489 getEditor().GetError().reset();
490 getEditor().CrearLastCreated();
493 //================================================================================
495 * \brief Increment mesh modif time and optionally record that the performed
496 * modification may influence futher mesh re-compute.
497 * \param [in] isReComputeSafe - true if the modification does not infulence
498 * futher mesh re-compute
500 //================================================================================
502 void SMESH_MeshEditor_i::declareMeshModified( bool isReComputeSafe )
504 myMesh->GetMeshDS()->Modified();
505 if ( !isReComputeSafe )
506 myMesh->SetIsModified( true );
509 //================================================================================
511 * \brief Return either myEditor or myPreviewEditor depending on myIsPreviewMode.
512 * WARNING: in preview mode call getPreviewMesh() before getEditor()!
514 //================================================================================
516 ::SMESH_MeshEditor& SMESH_MeshEditor_i::getEditor()
518 if ( myIsPreviewMode && !myPreviewEditor ) {
519 if ( !myPreviewMesh ) getPreviewMesh();
520 myPreviewEditor = new ::SMESH_MeshEditor( myPreviewMesh );
522 return myIsPreviewMode ? *myPreviewEditor : myEditor;
525 //================================================================================
527 * \brief Initialize and return myPreviewMesh
528 * \param previewElements - type of elements to show in preview
530 * WARNING: call it once par a method!
532 //================================================================================
534 TPreviewMesh * SMESH_MeshEditor_i::getPreviewMesh(SMDSAbs_ElementType previewElements)
536 if ( !myPreviewMesh || myPreviewMesh->myPreviewType != previewElements )
538 delete myPreviewEditor;
540 delete myPreviewMesh;
541 myPreviewMesh = new TPreviewMesh( previewElements );
543 myPreviewMesh->Clear();
544 return myPreviewMesh;
547 //================================================================================
549 * Return data of mesh edition preview
551 //================================================================================
553 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
554 throw (SALOME::SALOME_Exception)
557 const bool hasBadElems = ( getEditor().GetError() && getEditor().GetError()->HasBadElems() );
559 if ( myIsPreviewMode || hasBadElems ) { // --- MeshPreviewStruct filling ---
561 list<int> aNodesConnectivity;
562 typedef map<int, int> TNodesMap;
565 SMESHDS_Mesh* aMeshDS;
566 std::auto_ptr< SMESH_MeshPartDS > aMeshPartDS;
568 aMeshPartDS.reset( new SMESH_MeshPartDS( getEditor().GetError()->myBadElements ));
569 aMeshDS = aMeshPartDS.get();
572 aMeshDS = getEditor().GetMeshDS();
574 myPreviewData = new SMESH::MeshPreviewStruct();
575 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
578 SMDSAbs_ElementType previewType = SMDSAbs_All;
580 if (TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( getEditor().GetMesh() )) {
581 previewType = aPreviewMesh->myPreviewType;
582 switch ( previewType ) {
583 case SMDSAbs_Edge : break;
584 case SMDSAbs_Face : break;
585 case SMDSAbs_Volume: break;
587 if ( aMeshDS->GetMeshInfo().NbElements() == 0 ) previewType = SMDSAbs_Node;
591 myPreviewData->elementTypes.length( aMeshDS->GetMeshInfo().NbElements( previewType ));
593 SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator(previewType);
595 while ( itMeshElems->more() ) {
596 const SMDS_MeshElement* aMeshElem = itMeshElems->next();
597 SMDS_NodeIteratorPtr itElemNodes = aMeshElem->nodeIterator();
598 while ( itElemNodes->more() ) {
599 const SMDS_MeshNode* aMeshNode = itElemNodes->next();
600 int aNodeID = aMeshNode->GetID();
601 TNodesMap::iterator anIter = nodesMap.find(aNodeID);
602 if ( anIter == nodesMap.end() ) {
603 // filling the nodes coordinates
604 myPreviewData->nodesXYZ[j].x = aMeshNode->X();
605 myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
606 myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
607 anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
610 aNodesConnectivity.push_back(anIter->second);
613 // filling the elements types
614 SMDSAbs_ElementType aType = aMeshElem->GetType();
615 bool isPoly = aMeshElem->IsPoly();
616 myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
617 myPreviewData->elementTypes[i].isPoly = isPoly;
618 myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
621 myPreviewData->nodesXYZ.length( j );
623 // filling the elements connectivities
624 list<int>::iterator aConnIter = aNodesConnectivity.begin();
625 myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
626 for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
627 myPreviewData->elementConnectivities[i] = *aConnIter;
629 return myPreviewData._retn();
631 SMESH_CATCH( SMESH::throwCorbaException );
635 //================================================================================
637 * \brief Returns list of it's IDs of created nodes
638 * \retval SMESH::long_array* - list of node ID
640 //================================================================================
642 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
643 throw (SALOME::SALOME_Exception)
646 SMESH::long_array_var myLastCreatedNodes = new SMESH::long_array();
648 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedNodes();
649 myLastCreatedNodes->length( aSeq.Length() );
650 for (int i = 1; i <= aSeq.Length(); i++)
651 myLastCreatedNodes[i-1] = aSeq.Value(i)->GetID();
653 return myLastCreatedNodes._retn();
654 SMESH_CATCH( SMESH::throwCorbaException );
658 //================================================================================
660 * \brief Returns list of it's IDs of created elements
661 * \retval SMESH::long_array* - list of elements' ID
663 //================================================================================
665 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
666 throw (SALOME::SALOME_Exception)
669 SMESH::long_array_var myLastCreatedElems = new SMESH::long_array();
671 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
672 myLastCreatedElems->length( aSeq.Length() );
673 for ( int i = 1; i <= aSeq.Length(); i++ )
674 myLastCreatedElems[i-1] = aSeq.Value(i)->GetID();
676 return myLastCreatedElems._retn();
677 SMESH_CATCH( SMESH::throwCorbaException );
681 //=======================================================================
682 //function : ClearLastCreated
683 //purpose : Clears sequences of last created elements and nodes
684 //=======================================================================
686 void SMESH_MeshEditor_i::ClearLastCreated() throw (SALOME::SALOME_Exception)
689 getEditor().CrearLastCreated();
690 SMESH_CATCH( SMESH::throwCorbaException );
693 //=======================================================================
695 * Returns description of an error/warning occured during the last operation
696 * WARNING: ComputeError.code >= 100 and no corresponding enum in IDL API
698 //=======================================================================
700 SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError()
701 throw (SALOME::SALOME_Exception)
704 SMESH::ComputeError_var errOut = new SMESH::ComputeError;
705 SMESH_ComputeErrorPtr& errIn = getEditor().GetError();
706 if ( errIn && !errIn->IsOK() )
708 errOut->code = -( errIn->myName < 0 ? errIn->myName + 1: errIn->myName ); // -1 -> 0
709 errOut->comment = errIn->myComment.c_str();
710 errOut->subShapeID = -1;
711 errOut->hasBadMesh = !errIn->myBadElements.empty();
716 errOut->subShapeID = -1;
717 errOut->hasBadMesh = false;
720 return errOut._retn();
721 SMESH_CATCH( SMESH::throwCorbaException );
725 //=======================================================================
726 //function : MakeIDSource
727 //purpose : Wrap a sequence of ids in a SMESH_IDSource.
728 // Call UnRegister() as you fininsh using it!!
729 //=======================================================================
731 struct SMESH_MeshEditor_i::_IDSource : public virtual POA_SMESH::SMESH_IDSource,
732 public virtual SALOME::GenericObj_i
734 SMESH::long_array _ids;
735 SMESH::ElementType _type;
736 SMESH::SMESH_Mesh_ptr _mesh;
737 SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); }
738 SMESH::long_array* GetMeshInfo() { return 0; }
739 SMESH::long_array* GetNbElementsByType()
741 SMESH::long_array_var aRes = new SMESH::long_array();
742 aRes->length(SMESH::NB_ELEMENT_TYPES);
743 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
744 aRes[ i ] = ( i == _type ) ? _ids.length() : 0;
747 SMESH::SMESH_Mesh_ptr GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _mesh ); }
748 bool IsMeshInfoCorrect() { return true; }
749 SMESH::array_of_ElementType* GetTypes()
751 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
752 if ( _ids.length() > 0 ) {
756 return types._retn();
760 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
761 SMESH::ElementType type)
763 // if ( myAuxIDSources.size() > 10 ) {
764 // delete myAuxIDSources.front();
765 // myAuxIDSources.pop_front();
768 _IDSource* idSrc = new _IDSource;
769 idSrc->_mesh = myMesh_i->_this();
772 //myAuxIDSources.push_back( idSrc );
774 SMESH::SMESH_IDSource_var anIDSourceVar = idSrc->_this();
776 return anIDSourceVar._retn();
779 bool SMESH_MeshEditor_i::IsTemporaryIDSource( SMESH::SMESH_IDSource_ptr& idSource )
781 return SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource );
784 CORBA::Long* SMESH_MeshEditor_i::GetTemporaryIDs( SMESH::SMESH_IDSource_ptr& idSource,
787 if ( _IDSource* tmpIdSource = SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource ))
789 nbIds = (int) tmpIdSource->_ids.length();
790 return & tmpIdSource->_ids[0];
796 // void SMESH_MeshEditor_i::deleteAuxIDSources()
798 // std::list< _IDSource* >::iterator idSrcIt = myAuxIDSources.begin();
799 // for ( ; idSrcIt != myAuxIDSources.end(); ++idSrcIt )
801 // myAuxIDSources.clear();
804 //=============================================================================
808 //=============================================================================
811 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
812 throw (SALOME::SALOME_Exception)
819 for (int i = 0; i < IDsOfElements.length(); i++)
820 IdList.push_back( IDsOfElements[i] );
822 // Update Python script
823 TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
826 bool ret = getEditor().Remove( IdList, false );
828 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 ); // issue 0020693
831 SMESH_CATCH( SMESH::throwCorbaException );
835 //=============================================================================
839 //=============================================================================
841 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
842 throw (SALOME::SALOME_Exception)
848 for (int i = 0; i < IDsOfNodes.length(); i++)
849 IdList.push_back( IDsOfNodes[i] );
851 // Update Python script
852 TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
854 bool ret = getEditor().Remove( IdList, true );
856 declareMeshModified( /*isReComputeSafe=*/ !ret ); // issue 0020693
859 SMESH_CATCH( SMESH::throwCorbaException );
863 //=============================================================================
867 //=============================================================================
869 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
870 throw (SALOME::SALOME_Exception)
875 // Update Python script
876 TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
878 // Create filter to find all orphan nodes
879 SMESH::Controls::Filter::TIdSequence seq;
880 SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
881 SMESH::Controls::Filter::GetElementsId( getMeshDS(), predicate, seq );
883 // remove orphan nodes (if there are any)
885 for ( int i = 0; i < seq.size(); i++ )
886 IdList.push_back( seq[i] );
888 int nbNodesBefore = myMesh->NbNodes();
889 getEditor().Remove( IdList, true );
890 int nbNodesAfter = myMesh->NbNodes();
892 declareMeshModified( /*isReComputeSafe=*/ IdList.size() == 0 ); // issue 0020693
893 return nbNodesBefore - nbNodesAfter;
895 SMESH_CATCH( SMESH::throwCorbaException );
899 //=============================================================================
903 //=============================================================================
905 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,CORBA::Double y, CORBA::Double z)
906 throw (SALOME::SALOME_Exception)
911 const SMDS_MeshNode* N = getMeshDS()->AddNode(x, y, z);
913 // Update Python script
914 TPythonDump() << "nodeID = " << this << ".AddNode( "
915 << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )";
917 declareMeshModified( /*isReComputeSafe=*/false );
920 SMESH_CATCH( SMESH::throwCorbaException );
924 //=============================================================================
926 * Create 0D element on the given node.
928 //=============================================================================
930 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
931 throw (SALOME::SALOME_Exception)
936 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
937 SMDS_MeshElement* elem = getMeshDS()->Add0DElement(aNode);
939 // Update Python script
940 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
942 declareMeshModified( /*isReComputeSafe=*/false );
944 return elem ? elem->GetID() : 0;
946 SMESH_CATCH( SMESH::throwCorbaException );
950 //=============================================================================
952 * Create a ball element on the given node.
954 //=============================================================================
956 CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diameter)
957 throw (SALOME::SALOME_Exception)
962 if ( diameter < std::numeric_limits<double>::min() )
963 THROW_SALOME_CORBA_EXCEPTION("Invalid diameter", SALOME::BAD_PARAM);
965 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
966 SMDS_MeshElement* elem = getMeshDS()->AddBall(aNode, diameter);
968 // Update Python script
969 TPythonDump() << "ballElem = "
970 << this << ".AddBall( " << IDOfNode << ", " << diameter <<" )";
972 declareMeshModified( /*isReComputeSafe=*/false );
973 return elem ? elem->GetID() : 0;
975 SMESH_CATCH( SMESH::throwCorbaException );
979 //=============================================================================
981 * Create an edge, either linear and quadratic (this is determed
982 * by number of given nodes, two or three)
984 //=============================================================================
986 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
987 throw (SALOME::SALOME_Exception)
992 int NbNodes = IDsOfNodes.length();
993 SMDS_MeshElement* elem = 0;
996 CORBA::Long index1 = IDsOfNodes[0];
997 CORBA::Long index2 = IDsOfNodes[1];
998 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(index1),
999 getMeshDS()->FindNode(index2));
1001 // Update Python script
1002 TPythonDump() << "edge = " << this << ".AddEdge([ "
1003 << index1 << ", " << index2 <<" ])";
1006 CORBA::Long n1 = IDsOfNodes[0];
1007 CORBA::Long n2 = IDsOfNodes[1];
1008 CORBA::Long n12 = IDsOfNodes[2];
1009 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(n1),
1010 getMeshDS()->FindNode(n2),
1011 getMeshDS()->FindNode(n12));
1012 // Update Python script
1013 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
1014 <<n1<<", "<<n2<<", "<<n12<<" ])";
1017 declareMeshModified( /*isReComputeSafe=*/false );
1018 return elem ? elem->GetID() : 0;
1020 SMESH_CATCH( SMESH::throwCorbaException );
1024 //=============================================================================
1028 //=============================================================================
1030 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
1031 throw (SALOME::SALOME_Exception)
1036 int NbNodes = IDsOfNodes.length();
1042 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1043 for (int i = 0; i < NbNodes; i++)
1044 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1046 SMDS_MeshElement* elem = 0;
1048 case 3: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]); break;
1049 case 4: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]); break;
1050 case 6: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1051 nodes[4], nodes[5]); break;
1052 case 7: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1053 nodes[4], nodes[5], nodes[6]); break;
1054 case 8: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1055 nodes[4], nodes[5], nodes[6], nodes[7]); break;
1056 case 9: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1057 nodes[4], nodes[5], nodes[6], nodes[7],
1059 default: elem = getMeshDS()->AddPolygonalFace(nodes);
1062 // Update Python script
1063 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
1065 declareMeshModified( /*isReComputeSafe=*/false );
1067 return elem ? elem->GetID() : 0;
1069 SMESH_CATCH( SMESH::throwCorbaException );
1073 //=============================================================================
1077 //=============================================================================
1078 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
1079 throw (SALOME::SALOME_Exception)
1084 int NbNodes = IDsOfNodes.length();
1085 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1086 for (int i = 0; i < NbNodes; i++)
1087 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1089 const SMDS_MeshElement* elem = getMeshDS()->AddPolygonalFace(nodes);
1091 // Update Python script
1092 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
1094 declareMeshModified( /*isReComputeSafe=*/false );
1095 return elem ? elem->GetID() : 0;
1097 SMESH_CATCH( SMESH::throwCorbaException );
1101 //=============================================================================
1103 * Create volume, either linear and quadratic (this is determed
1104 * by number of given nodes)
1106 //=============================================================================
1108 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
1109 throw (SALOME::SALOME_Exception)
1114 int NbNodes = IDsOfNodes.length();
1115 vector< const SMDS_MeshNode*> n(NbNodes);
1116 for(int i=0;i<NbNodes;i++)
1117 n[i]= getMeshDS()->FindNode(IDsOfNodes[i]);
1119 SMDS_MeshElement* elem = 0;
1122 case 4 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
1123 case 5 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
1124 case 6 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
1125 case 8 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
1126 case 10:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1127 n[6],n[7],n[8],n[9]);
1129 case 12:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1130 n[6],n[7],n[8],n[9],n[10],n[11]);
1132 case 13:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
1133 n[7],n[8],n[9],n[10],n[11],n[12]);
1135 case 15:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
1136 n[9],n[10],n[11],n[12],n[13],n[14]);
1138 case 20:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1139 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1140 n[15],n[16],n[17],n[18],n[19]);
1142 case 27:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1143 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1144 n[15],n[16],n[17],n[18],n[19],
1145 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
1149 // Update Python script
1150 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
1152 declareMeshModified( /*isReComputeSafe=*/false );
1153 return elem ? elem->GetID() : 0;
1155 SMESH_CATCH( SMESH::throwCorbaException );
1159 //=============================================================================
1161 * AddPolyhedralVolume
1163 //=============================================================================
1164 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
1165 const SMESH::long_array & Quantities)
1166 throw (SALOME::SALOME_Exception)
1171 int NbNodes = IDsOfNodes.length();
1172 std::vector<const SMDS_MeshNode*> n (NbNodes);
1173 for (int i = 0; i < NbNodes; i++)
1175 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDsOfNodes[i]);
1176 if (!aNode) return 0;
1180 int NbFaces = Quantities.length();
1181 std::vector<int> q (NbFaces);
1182 for (int j = 0; j < NbFaces; j++)
1183 q[j] = Quantities[j];
1185 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(n, q);
1187 // Update Python script
1188 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
1189 << IDsOfNodes << ", " << Quantities << " )";
1191 declareMeshModified( /*isReComputeSafe=*/false );
1192 return elem ? elem->GetID() : 0;
1194 SMESH_CATCH( SMESH::throwCorbaException );
1198 //=============================================================================
1200 * AddPolyhedralVolumeByFaces
1202 //=============================================================================
1204 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
1205 throw (SALOME::SALOME_Exception)
1210 int NbFaces = IdsOfFaces.length();
1211 std::vector<const SMDS_MeshNode*> poly_nodes;
1212 std::vector<int> quantities (NbFaces);
1214 for (int i = 0; i < NbFaces; i++) {
1215 const SMDS_MeshElement* aFace = getMeshDS()->FindElement(IdsOfFaces[i]);
1216 quantities[i] = aFace->NbNodes();
1218 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
1219 while (It->more()) {
1220 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
1224 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
1226 // Update Python script
1227 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
1228 << IdsOfFaces << " )";
1230 declareMeshModified( /*isReComputeSafe=*/false );
1231 return elem ? elem->GetID() : 0;
1233 SMESH_CATCH( SMESH::throwCorbaException );
1237 //=============================================================================
1239 // \brief Create 0D elements on all nodes of the given object except those
1240 // nodes on which a 0D element already exists.
1241 // \param theObject object on whose nodes 0D elements will be created.
1242 // \param theGroupName optional name of a group to add 0D elements created
1243 // and/or found on nodes of \a theObject.
1244 // \return an object (a new group or a temporary SMESH_IDSource) holding
1245 // ids of new and/or found 0D elements.
1247 //=============================================================================
1249 SMESH::SMESH_IDSource_ptr
1250 SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObject,
1251 const char* theGroupName)
1252 throw (SALOME::SALOME_Exception)
1257 SMESH::SMESH_IDSource_var result;
1260 TIDSortedElemSet elements, elems0D;
1261 prepareIdSource( theObject );
1262 if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
1263 getEditor().Create0DElementsOnAllNodes( elements, elems0D );
1265 SMESH::long_array_var newElems = new SMESH::long_array;
1266 newElems->length( elems0D.size() );
1267 TIDSortedElemSet::iterator eIt = elems0D.begin();
1268 for ( size_t i = 0; i < elems0D.size(); ++i, ++eIt )
1269 newElems[ i ] = (*eIt)->GetID();
1271 SMESH::SMESH_GroupBase_var groupToFill;
1272 if ( theGroupName && strlen( theGroupName ))
1274 // Get existing group named theGroupName
1275 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
1276 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
1277 SMESH::SMESH_GroupBase_var group = groups[i];
1278 if ( !group->_is_nil() ) {
1279 CORBA::String_var name = group->GetName();
1280 if ( strcmp( name.in(), theGroupName ) == 0 && group->GetType() == SMESH::ELEM0D ) {
1281 groupToFill = group;
1286 if ( groupToFill->_is_nil() )
1287 groupToFill = myMesh_i->CreateGroup( SMESH::ELEM0D, theGroupName );
1288 else if ( !SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1289 groupToFill = myMesh_i->ConvertToStandalone( groupToFill );
1292 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1294 group_i->Add( newElems );
1295 result = SMESH::SMESH_IDSource::_narrow( groupToFill );
1296 pyDump << groupToFill;
1300 result = MakeIDSource( newElems, SMESH::ELEM0D );
1301 pyDump << "elem0DIDs";
1304 pyDump << " = " << this << ".Create0DElementsOnAllNodes( "
1305 << theObject << ", '" << theGroupName << "' )";
1307 return result._retn();
1309 SMESH_CATCH( SMESH::throwCorbaException );
1313 //=============================================================================
1315 * \brief Bind a node to a vertex
1316 * \param NodeID - node ID
1317 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1318 * \retval boolean - false if NodeID or VertexID is invalid
1320 //=============================================================================
1322 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
1323 throw (SALOME::SALOME_Exception)
1327 SMESHDS_Mesh * mesh = getMeshDS();
1328 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1330 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1332 if ( mesh->MaxShapeIndex() < VertexID )
1333 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1335 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
1336 if ( shape.ShapeType() != TopAbs_VERTEX )
1337 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1339 mesh->SetNodeOnVertex( node, VertexID );
1341 myMesh->SetIsModified( true );
1343 SMESH_CATCH( SMESH::throwCorbaException );
1346 //=============================================================================
1348 * \brief Store node position on an edge
1349 * \param NodeID - node ID
1350 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
1351 * \param paramOnEdge - parameter on edge where the node is located
1352 * \retval boolean - false if any parameter is invalid
1354 //=============================================================================
1356 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
1357 CORBA::Double paramOnEdge)
1358 throw (SALOME::SALOME_Exception)
1362 SMESHDS_Mesh * mesh = getMeshDS();
1363 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1365 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1367 if ( mesh->MaxShapeIndex() < EdgeID )
1368 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1370 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
1371 if ( shape.ShapeType() != TopAbs_EDGE )
1372 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1375 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
1376 if ( paramOnEdge < f || paramOnEdge > l )
1377 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
1379 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
1381 myMesh->SetIsModified( true );
1383 SMESH_CATCH( SMESH::throwCorbaException );
1386 //=============================================================================
1388 * \brief Store node position on a face
1389 * \param NodeID - node ID
1390 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
1391 * \param u - U parameter on face where the node is located
1392 * \param v - V parameter on face where the node is located
1393 * \retval boolean - false if any parameter is invalid
1395 //=============================================================================
1397 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
1398 CORBA::Double u, CORBA::Double v)
1399 throw (SALOME::SALOME_Exception)
1402 SMESHDS_Mesh * mesh = getMeshDS();
1403 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1405 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1407 if ( mesh->MaxShapeIndex() < FaceID )
1408 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1410 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
1411 if ( shape.ShapeType() != TopAbs_FACE )
1412 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1414 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
1415 bool isOut = ( u < surf.FirstUParameter() ||
1416 u > surf.LastUParameter() ||
1417 v < surf.FirstVParameter() ||
1418 v > surf.LastVParameter() );
1422 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
1423 << " u( " << surf.FirstUParameter()
1424 << "," << surf.LastUParameter()
1425 << ") v( " << surf.FirstVParameter()
1426 << "," << surf.LastVParameter() << ")" );
1428 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
1431 mesh->SetNodeOnFace( node, FaceID, u, v );
1432 myMesh->SetIsModified( true );
1434 SMESH_CATCH( SMESH::throwCorbaException );
1437 //=============================================================================
1439 * \brief Bind a node to a solid
1440 * \param NodeID - node ID
1441 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1442 * \retval boolean - false if NodeID or SolidID is invalid
1444 //=============================================================================
1446 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
1447 throw (SALOME::SALOME_Exception)
1450 SMESHDS_Mesh * mesh = getMeshDS();
1451 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1453 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1455 if ( mesh->MaxShapeIndex() < SolidID )
1456 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1458 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
1459 if ( shape.ShapeType() != TopAbs_SOLID &&
1460 shape.ShapeType() != TopAbs_SHELL)
1461 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1463 mesh->SetNodeInVolume( node, SolidID );
1465 SMESH_CATCH( SMESH::throwCorbaException );
1468 //=============================================================================
1470 * \brief Bind an element to a shape
1471 * \param ElementID - element ID
1472 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
1474 //=============================================================================
1476 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
1477 CORBA::Long ShapeID)
1478 throw (SALOME::SALOME_Exception)
1481 SMESHDS_Mesh * mesh = getMeshDS();
1482 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
1484 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
1486 if ( mesh->MaxShapeIndex() < ShapeID || ShapeID < 1 )
1487 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1489 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1490 if ( shape.ShapeType() != TopAbs_EDGE &&
1491 shape.ShapeType() != TopAbs_FACE &&
1492 shape.ShapeType() != TopAbs_SOLID &&
1493 shape.ShapeType() != TopAbs_SHELL )
1494 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1496 mesh->SetMeshElementOnShape( elem, ShapeID );
1498 myMesh->SetIsModified( true );
1500 SMESH_CATCH( SMESH::throwCorbaException );
1503 //=============================================================================
1507 //=============================================================================
1509 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1510 CORBA::Long NodeID2)
1511 throw (SALOME::SALOME_Exception)
1516 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1517 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1521 // Update Python script
1522 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1523 << NodeID1 << ", " << NodeID2 << " )";
1525 int ret = getEditor().InverseDiag ( n1, n2 );
1527 declareMeshModified( /*isReComputeSafe=*/false );
1530 SMESH_CATCH( SMESH::throwCorbaException );
1534 //=============================================================================
1538 //=============================================================================
1540 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1541 CORBA::Long NodeID2)
1542 throw (SALOME::SALOME_Exception)
1547 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1548 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1552 // Update Python script
1553 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1554 << NodeID1 << ", " << NodeID2 << " )";
1557 bool stat = getEditor().DeleteDiag ( n1, n2 );
1559 declareMeshModified( /*isReComputeSafe=*/!stat );
1563 SMESH_CATCH( SMESH::throwCorbaException );
1567 //=============================================================================
1571 //=============================================================================
1573 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1574 throw (SALOME::SALOME_Exception)
1579 for (int i = 0; i < IDsOfElements.length(); i++)
1581 CORBA::Long index = IDsOfElements[i];
1582 const SMDS_MeshElement * elem = getMeshDS()->FindElement(index);
1584 getEditor().Reorient( elem );
1586 // Update Python script
1587 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1589 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 );
1592 SMESH_CATCH( SMESH::throwCorbaException );
1596 //=============================================================================
1600 //=============================================================================
1602 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1603 throw (SALOME::SALOME_Exception)
1608 TPythonDump aTPythonDump; // suppress dump in Reorient()
1610 prepareIdSource( theObject );
1612 SMESH::long_array_var anElementsId = theObject->GetIDs();
1613 CORBA::Boolean isDone = Reorient(anElementsId);
1615 // Update Python script
1616 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1618 declareMeshModified( /*isReComputeSafe=*/ anElementsId->length() == 0 );
1621 SMESH_CATCH( SMESH::throwCorbaException );
1625 //=======================================================================
1626 //function : Reorient2D
1627 //purpose : Reorient faces contained in \a the2Dgroup.
1628 // the2Dgroup - the mesh or its part to reorient
1629 // theDirection - desired direction of normal of \a theFace
1630 // theFace - ID of face whose orientation is checked.
1631 // It can be < 1 then \a thePoint is used to find a face.
1632 // thePoint - is used to find a face if \a theFace < 1.
1633 // return number of reoriented elements.
1634 //=======================================================================
1636 CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
1637 const SMESH::DirStruct& theDirection,
1638 CORBA::Long theFace,
1639 const SMESH::PointStruct& thePoint)
1640 throw (SALOME::SALOME_Exception)
1643 initData(/*deleteSearchers=*/false);
1645 TIDSortedElemSet elements;
1646 prepareIdSource( the2Dgroup );
1647 if ( !idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1))
1648 THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
1651 const SMDS_MeshElement* face = 0;
1654 face = getMeshDS()->FindElement( theFace );
1656 THROW_SALOME_CORBA_EXCEPTION("Inexistent face given", SALOME::BAD_PARAM);
1657 if ( face->GetType() != SMDSAbs_Face )
1658 THROW_SALOME_CORBA_EXCEPTION("Wrong element type", SALOME::BAD_PARAM);
1662 // create theElementSearcher if needed
1663 theSearchersDeleter.Set( myMesh, getPartIOR( the2Dgroup, SMESH::FACE ));
1664 if ( !theElementSearcher )
1666 if ( elements.empty() ) // search in the whole mesh
1668 if ( myMesh->NbFaces() == 0 )
1669 THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM);
1671 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
1675 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
1676 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
1678 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt);
1682 gp_Pnt p( thePoint.x, thePoint.y, thePoint.z );
1683 face = theElementSearcher->FindClosestTo( p, SMDSAbs_Face );
1686 THROW_SALOME_CORBA_EXCEPTION("No face found by point", SALOME::INTERNAL_ERROR );
1687 if ( !elements.empty() && !elements.count( face ))
1688 THROW_SALOME_CORBA_EXCEPTION("Found face is not in the group", SALOME::BAD_PARAM );
1691 const SMESH::PointStruct * P = &theDirection.PS;
1692 gp_Vec dirVec( P->x, P->y, P->z );
1693 if ( dirVec.Magnitude() < std::numeric_limits< double >::min() )
1694 THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM);
1696 int nbReori = getEditor().Reorient2D( elements, dirVec, face );
1699 declareMeshModified( /*isReComputeSafe=*/false );
1701 TPythonDump() << this << ".Reorient2D( "
1702 << the2Dgroup << ", "
1703 << theDirection << ", "
1705 << thePoint << " )";
1709 SMESH_CATCH( SMESH::throwCorbaException );
1713 //=============================================================================
1715 * \brief Fuse neighbour triangles into quadrangles.
1717 //=============================================================================
1719 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1720 SMESH::NumericalFunctor_ptr Criterion,
1721 CORBA::Double MaxAngle)
1722 throw (SALOME::SALOME_Exception)
1727 SMESHDS_Mesh* aMesh = getMeshDS();
1728 TIDSortedElemSet faces,copyFaces;
1729 SMDS_MeshElement::GeomFilter triaFilter(SMDSGeom_TRIANGLE);
1730 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face, & triaFilter);
1731 TIDSortedElemSet* workElements = & faces;
1733 if ( myIsPreviewMode ) {
1734 SMDSAbs_ElementType select = SMDSAbs_Face;
1735 getPreviewMesh( SMDSAbs_Face )->Copy( faces, copyFaces, select );
1736 workElements = & copyFaces;
1739 SMESH::NumericalFunctor_i* aNumericalFunctor =
1740 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1741 SMESH::Controls::NumericalFunctorPtr aCrit;
1742 if ( !aNumericalFunctor )
1743 aCrit.reset( new SMESH::Controls::MaxElementLength2D() );
1745 aCrit = aNumericalFunctor->GetNumericalFunctor();
1747 if ( !myIsPreviewMode ) {
1748 // Update Python script
1749 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1750 << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1753 bool stat = getEditor().TriToQuad( *workElements, aCrit, MaxAngle );
1755 declareMeshModified( /*isReComputeSafe=*/!stat );
1758 SMESH_CATCH( SMESH::throwCorbaException );
1762 //=============================================================================
1764 * \brief Fuse neighbour triangles into quadrangles.
1766 //=============================================================================
1768 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1769 SMESH::NumericalFunctor_ptr Criterion,
1770 CORBA::Double MaxAngle)
1771 throw (SALOME::SALOME_Exception)
1776 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1778 prepareIdSource( theObject );
1779 SMESH::long_array_var anElementsId = theObject->GetIDs();
1780 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1782 if ( !myIsPreviewMode ) {
1783 SMESH::NumericalFunctor_i* aNumericalFunctor =
1784 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1786 // Update Python script
1787 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1788 << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1793 SMESH_CATCH( SMESH::throwCorbaException );
1797 //=============================================================================
1799 * \brief Split quadrangles into triangles.
1801 //=============================================================================
1803 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1804 SMESH::NumericalFunctor_ptr Criterion)
1805 throw (SALOME::SALOME_Exception)
1810 SMESHDS_Mesh* aMesh = getMeshDS();
1811 TIDSortedElemSet faces;
1812 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1814 SMESH::NumericalFunctor_i* aNumericalFunctor =
1815 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1816 SMESH::Controls::NumericalFunctorPtr aCrit;
1817 if ( !aNumericalFunctor )
1818 aCrit.reset( new SMESH::Controls::AspectRatio() );
1820 aCrit = aNumericalFunctor->GetNumericalFunctor();
1823 // Update Python script
1824 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1826 CORBA::Boolean stat = getEditor().QuadToTri( faces, aCrit );
1828 declareMeshModified( /*isReComputeSafe=*/false );
1831 SMESH_CATCH( SMESH::throwCorbaException );
1835 //=============================================================================
1837 * \brief Split quadrangles into triangles.
1839 //=============================================================================
1841 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1842 SMESH::NumericalFunctor_ptr Criterion)
1843 throw (SALOME::SALOME_Exception)
1848 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1850 prepareIdSource( theObject );
1851 SMESH::long_array_var anElementsId = theObject->GetIDs();
1852 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1854 SMESH::NumericalFunctor_i* aNumericalFunctor =
1855 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1857 // Update Python script
1858 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1860 declareMeshModified( /*isReComputeSafe=*/false );
1863 SMESH_CATCH( SMESH::throwCorbaException );
1867 //================================================================================
1869 * \brief Split each of quadrangles into 4 triangles.
1870 * \param [in] theObject - theQuads Container of quadrangles to split.
1872 //================================================================================
1874 void SMESH_MeshEditor_i::QuadTo4Tri (SMESH::SMESH_IDSource_ptr theObject)
1875 throw (SALOME::SALOME_Exception)
1880 TIDSortedElemSet faces;
1881 prepareIdSource( theObject );
1882 if ( !idSourceToSet( theObject, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/true ) &&
1884 THROW_SALOME_CORBA_EXCEPTION("No faces given", SALOME::BAD_PARAM);
1886 getEditor().QuadTo4Tri( faces );
1887 TPythonDump() << this << ".QuadTo4Tri( " << theObject << " )";
1889 SMESH_CATCH( SMESH::throwCorbaException );
1892 //=============================================================================
1894 * \brief Split quadrangles into triangles.
1896 //=============================================================================
1898 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1899 CORBA::Boolean Diag13)
1900 throw (SALOME::SALOME_Exception)
1905 SMESHDS_Mesh* aMesh = getMeshDS();
1906 TIDSortedElemSet faces;
1907 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1909 // Update Python script
1910 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1911 << IDsOfElements << ", " << Diag13 << " )";
1913 CORBA::Boolean stat = getEditor().QuadToTri( faces, Diag13 );
1915 declareMeshModified( /*isReComputeSafe=*/ !stat );
1918 SMESH_CATCH( SMESH::throwCorbaException );
1922 //=============================================================================
1924 * \brief Split quadrangles into triangles.
1926 //=============================================================================
1928 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1929 CORBA::Boolean Diag13)
1930 throw (SALOME::SALOME_Exception)
1935 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
1937 prepareIdSource( theObject );
1938 SMESH::long_array_var anElementsId = theObject->GetIDs();
1939 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
1941 // Update Python script
1942 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
1943 << theObject << ", " << Diag13 << " )";
1945 declareMeshModified( /*isReComputeSafe=*/!isDone );
1948 SMESH_CATCH( SMESH::throwCorbaException );
1953 //=============================================================================
1955 * Find better splitting of the given quadrangle.
1956 * \param IDOfQuad ID of the quadrangle to be splitted.
1957 * \param Criterion A criterion to choose a diagonal for splitting.
1958 * \return 1 if 1-3 diagonal is better, 2 if 2-4
1959 * diagonal is better, 0 if error occurs.
1961 //=============================================================================
1963 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
1964 SMESH::NumericalFunctor_ptr Criterion)
1965 throw (SALOME::SALOME_Exception)
1970 const SMDS_MeshElement* quad = getMeshDS()->FindElement(IDOfQuad);
1971 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
1973 SMESH::NumericalFunctor_i* aNumericalFunctor =
1974 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
1975 SMESH::Controls::NumericalFunctorPtr aCrit;
1976 if (aNumericalFunctor)
1977 aCrit = aNumericalFunctor->GetNumericalFunctor();
1979 aCrit.reset(new SMESH::Controls::AspectRatio());
1981 int id = getEditor().BestSplit(quad, aCrit);
1982 declareMeshModified( /*isReComputeSafe=*/ id < 1 );
1986 SMESH_CATCH( SMESH::throwCorbaException );
1990 //================================================================================
1992 * \brief Split volumic elements into tetrahedrons
1994 //================================================================================
1996 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
1997 CORBA::Short methodFlags)
1998 throw (SALOME::SALOME_Exception)
2002 prepareIdSource( elems );
2004 ::SMESH_MeshEditor::TFacetOfElem elemSet;
2005 const int noneFacet = -1;
2006 SMDS_ElemIteratorPtr volIt = myMesh_i->GetElements( elems, SMESH::VOLUME );
2007 while( volIt->more() )
2008 elemSet.insert( elemSet.end(), make_pair( volIt->next(), noneFacet ));
2010 getEditor().SplitVolumes( elemSet, int( methodFlags ));
2011 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2013 TPythonDump() << this << ".SplitVolumesIntoTetra( "
2014 << elems << ", " << methodFlags << " )";
2016 SMESH_CATCH( SMESH::throwCorbaException );
2019 //================================================================================
2021 * \brief Split hexahedra into triangular prisms
2022 * \param elems - elements to split
2023 * \param facetToSplitNormal - normal used to find a facet of hexahedron
2024 * to split into triangles
2025 * \param methodFlags - flags passing splitting method:
2026 * 1 - split the hexahedron into 2 prisms
2027 * 2 - split the hexahedron into 4 prisms
2029 //================================================================================
2031 void SMESH_MeshEditor_i::SplitHexahedraIntoPrisms (SMESH::SMESH_IDSource_ptr elems,
2032 const SMESH::PointStruct & startHexPoint,
2033 const SMESH::DirStruct& facetToSplitNormal,
2034 CORBA::Short methodFlags,
2035 CORBA::Boolean allDomains)
2036 throw (SALOME::SALOME_Exception)
2040 prepareIdSource( elems );
2042 gp_Ax1 facetNorm( gp_Pnt( startHexPoint.x,
2045 gp_Dir( facetToSplitNormal.PS.x,
2046 facetToSplitNormal.PS.y,
2047 facetToSplitNormal.PS.z ));
2048 TIDSortedElemSet elemSet;
2049 SMESH::long_array_var anElementsId = elems->GetIDs();
2050 SMDS_MeshElement::GeomFilter filter( SMDSGeom_HEXA );
2051 arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume, &filter );
2053 ::SMESH_MeshEditor::TFacetOfElem elemFacets;
2054 while ( !elemSet.empty() )
2056 getEditor().GetHexaFacetsToSplit( elemSet, facetNorm, elemFacets );
2060 ::SMESH_MeshEditor::TFacetOfElem::iterator ef = elemFacets.begin();
2061 for ( ; ef != elemFacets.end(); ++ef )
2062 elemSet.erase( ef->first );
2065 if ( methodFlags == 2 )
2066 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_4_PRISMS );
2068 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_2_PRISMS );
2070 getEditor().SplitVolumes( elemFacets, int( methodFlags ));
2071 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2073 TPythonDump() << this << ".SplitHexahedraIntoPrisms( "
2075 << startHexPoint << ", "
2076 << facetToSplitNormal<< ", "
2077 << methodFlags<< ", "
2078 << allDomains << " )";
2080 SMESH_CATCH( SMESH::throwCorbaException );
2083 //=======================================================================
2086 //=======================================================================
2089 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
2090 const SMESH::long_array & IDsOfFixedNodes,
2091 CORBA::Long MaxNbOfIterations,
2092 CORBA::Double MaxAspectRatio,
2093 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2094 throw (SALOME::SALOME_Exception)
2096 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2097 MaxAspectRatio, Method, false );
2101 //=======================================================================
2102 //function : SmoothParametric
2104 //=======================================================================
2107 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
2108 const SMESH::long_array & IDsOfFixedNodes,
2109 CORBA::Long MaxNbOfIterations,
2110 CORBA::Double MaxAspectRatio,
2111 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2112 throw (SALOME::SALOME_Exception)
2114 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2115 MaxAspectRatio, Method, true );
2119 //=======================================================================
2120 //function : SmoothObject
2122 //=======================================================================
2125 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
2126 const SMESH::long_array & IDsOfFixedNodes,
2127 CORBA::Long MaxNbOfIterations,
2128 CORBA::Double MaxAspectRatio,
2129 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2130 throw (SALOME::SALOME_Exception)
2132 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2133 MaxAspectRatio, Method, false);
2137 //=======================================================================
2138 //function : SmoothParametricObject
2140 //=======================================================================
2143 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
2144 const SMESH::long_array & IDsOfFixedNodes,
2145 CORBA::Long MaxNbOfIterations,
2146 CORBA::Double MaxAspectRatio,
2147 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2148 throw (SALOME::SALOME_Exception)
2150 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2151 MaxAspectRatio, Method, true);
2155 //=============================================================================
2159 //=============================================================================
2162 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
2163 const SMESH::long_array & IDsOfFixedNodes,
2164 CORBA::Long MaxNbOfIterations,
2165 CORBA::Double MaxAspectRatio,
2166 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2168 throw (SALOME::SALOME_Exception)
2173 SMESHDS_Mesh* aMesh = getMeshDS();
2175 TIDSortedElemSet elements;
2176 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
2178 set<const SMDS_MeshNode*> fixedNodes;
2179 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
2180 CORBA::Long index = IDsOfFixedNodes[i];
2181 const SMDS_MeshNode * node = aMesh->FindNode(index);
2183 fixedNodes.insert( node );
2185 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
2186 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
2187 method = ::SMESH_MeshEditor::CENTROIDAL;
2189 getEditor().Smooth(elements, fixedNodes, method,
2190 MaxNbOfIterations, MaxAspectRatio, IsParametric );
2192 declareMeshModified( /*isReComputeSafe=*/true ); // does not prevent re-compute
2194 // Update Python script
2195 TPythonDump() << "isDone = " << this << "."
2196 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
2197 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
2198 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2199 << "SMESH.SMESH_MeshEditor."
2200 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2201 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2205 SMESH_CATCH( SMESH::throwCorbaException );
2209 //=============================================================================
2213 //=============================================================================
2216 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
2217 const SMESH::long_array & IDsOfFixedNodes,
2218 CORBA::Long MaxNbOfIterations,
2219 CORBA::Double MaxAspectRatio,
2220 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2222 throw (SALOME::SALOME_Exception)
2227 TPythonDump aTPythonDump; // suppress dump in smooth()
2229 prepareIdSource( theObject );
2230 SMESH::long_array_var anElementsId = theObject->GetIDs();
2231 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
2232 MaxAspectRatio, Method, IsParametric);
2234 // Update Python script
2235 aTPythonDump << "isDone = " << this << "."
2236 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
2237 << theObject << ", " << IDsOfFixedNodes << ", "
2238 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2239 << "SMESH.SMESH_MeshEditor."
2240 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2241 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2245 SMESH_CATCH( SMESH::throwCorbaException );
2249 //=============================================================================
2253 //=============================================================================
2255 void SMESH_MeshEditor_i::RenumberNodes()
2256 throw (SALOME::SALOME_Exception)
2259 // Update Python script
2260 TPythonDump() << this << ".RenumberNodes()";
2262 getMeshDS()->Renumber( true );
2264 SMESH_CATCH( SMESH::throwCorbaException );
2267 //=============================================================================
2271 //=============================================================================
2273 void SMESH_MeshEditor_i::RenumberElements()
2274 throw (SALOME::SALOME_Exception)
2277 // Update Python script
2278 TPythonDump() << this << ".RenumberElements()";
2280 getMeshDS()->Renumber( false );
2282 SMESH_CATCH( SMESH::throwCorbaException );
2285 //=======================================================================
2287 * \brief Return groups by their IDs
2289 //=======================================================================
2291 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
2292 throw (SALOME::SALOME_Exception)
2297 myMesh_i->CreateGroupServants();
2298 return myMesh_i->GetGroups( *groupIDs );
2300 SMESH_CATCH( SMESH::throwCorbaException );
2304 //=======================================================================
2305 //function : rotationSweep
2307 //=======================================================================
2309 SMESH::ListOfGroups*
2310 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
2311 const SMESH::AxisStruct & theAxis,
2312 CORBA::Double theAngleInRadians,
2313 CORBA::Long theNbOfSteps,
2314 CORBA::Double theTolerance,
2315 const bool theMakeGroups,
2316 const SMDSAbs_ElementType theElementType)
2317 throw (SALOME::SALOME_Exception)
2322 TIDSortedElemSet inElements, copyElements;
2323 arrayToSet(theIDsOfElements, getMeshDS(), inElements, theElementType);
2325 TIDSortedElemSet* workElements = & inElements;
2326 bool makeWalls=true;
2327 if ( myIsPreviewMode )
2329 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2330 getPreviewMesh( SMDSAbs_Face )->Copy( inElements, copyElements, select, avoid );
2331 workElements = & copyElements;
2332 //makeWalls = false;
2335 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
2336 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
2338 ::SMESH_MeshEditor::PGroupIDs groupIds =
2339 getEditor().RotationSweep (*workElements, Ax1, theAngleInRadians,
2340 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
2342 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2344 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2346 SMESH_CATCH( SMESH::throwCorbaException );
2350 //=======================================================================
2351 //function : RotationSweep
2353 //=======================================================================
2355 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
2356 const SMESH::AxisStruct & theAxis,
2357 CORBA::Double theAngleInRadians,
2358 CORBA::Long theNbOfSteps,
2359 CORBA::Double theTolerance)
2360 throw (SALOME::SALOME_Exception)
2362 if ( !myIsPreviewMode ) {
2363 TPythonDump() << this << ".RotationSweep( "
2364 << theIDsOfElements << ", "
2366 << TVar( theAngleInRadians ) << ", "
2367 << TVar( theNbOfSteps ) << ", "
2368 << TVar( theTolerance ) << " )";
2370 rotationSweep(theIDsOfElements,
2378 //=======================================================================
2379 //function : RotationSweepMakeGroups
2381 //=======================================================================
2383 SMESH::ListOfGroups*
2384 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2385 const SMESH::AxisStruct& theAxis,
2386 CORBA::Double theAngleInRadians,
2387 CORBA::Long theNbOfSteps,
2388 CORBA::Double theTolerance)
2389 throw (SALOME::SALOME_Exception)
2391 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2393 SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
2399 if (!myIsPreviewMode) {
2400 dumpGroupsList(aPythonDump, aGroups);
2401 aPythonDump << this << ".RotationSweepMakeGroups( "
2402 << theIDsOfElements << ", "
2404 << TVar( theAngleInRadians ) << ", "
2405 << TVar( theNbOfSteps ) << ", "
2406 << TVar( theTolerance ) << " )";
2411 //=======================================================================
2412 //function : RotationSweepObject
2414 //=======================================================================
2416 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2417 const SMESH::AxisStruct & theAxis,
2418 CORBA::Double theAngleInRadians,
2419 CORBA::Long theNbOfSteps,
2420 CORBA::Double theTolerance)
2421 throw (SALOME::SALOME_Exception)
2423 if ( !myIsPreviewMode ) {
2424 TPythonDump() << this << ".RotationSweepObject( "
2425 << theObject << ", "
2427 << theAngleInRadians << ", "
2428 << theNbOfSteps << ", "
2429 << theTolerance << " )";
2431 prepareIdSource( theObject );
2432 SMESH::long_array_var anElementsId = theObject->GetIDs();
2433 rotationSweep(anElementsId,
2441 //=======================================================================
2442 //function : RotationSweepObject1D
2444 //=======================================================================
2446 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2447 const SMESH::AxisStruct & theAxis,
2448 CORBA::Double theAngleInRadians,
2449 CORBA::Long theNbOfSteps,
2450 CORBA::Double theTolerance)
2451 throw (SALOME::SALOME_Exception)
2453 if ( !myIsPreviewMode ) {
2454 TPythonDump() << this << ".RotationSweepObject1D( "
2455 << theObject << ", "
2457 << TVar( theAngleInRadians ) << ", "
2458 << TVar( theNbOfSteps ) << ", "
2459 << TVar( theTolerance ) << " )";
2461 prepareIdSource( theObject );
2462 SMESH::long_array_var anElementsId = theObject->GetIDs();
2463 rotationSweep(anElementsId,
2472 //=======================================================================
2473 //function : RotationSweepObject2D
2475 //=======================================================================
2477 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2478 const SMESH::AxisStruct & theAxis,
2479 CORBA::Double theAngleInRadians,
2480 CORBA::Long theNbOfSteps,
2481 CORBA::Double theTolerance)
2482 throw (SALOME::SALOME_Exception)
2484 if ( !myIsPreviewMode ) {
2485 TPythonDump() << this << ".RotationSweepObject2D( "
2486 << theObject << ", "
2488 << TVar( theAngleInRadians ) << ", "
2489 << TVar( theNbOfSteps ) << ", "
2490 << TVar( theTolerance ) << " )";
2492 prepareIdSource( theObject );
2493 SMESH::long_array_var anElementsId = theObject->GetIDs();
2494 rotationSweep(anElementsId,
2503 //=======================================================================
2504 //function : RotationSweepObjectMakeGroups
2506 //=======================================================================
2508 SMESH::ListOfGroups*
2509 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2510 const SMESH::AxisStruct& theAxis,
2511 CORBA::Double theAngleInRadians,
2512 CORBA::Long theNbOfSteps,
2513 CORBA::Double theTolerance)
2514 throw (SALOME::SALOME_Exception)
2516 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2518 prepareIdSource( theObject );
2519 SMESH::long_array_var anElementsId = theObject->GetIDs();
2520 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2526 if (!myIsPreviewMode) {
2527 dumpGroupsList(aPythonDump, aGroups);
2528 aPythonDump << this << ".RotationSweepObjectMakeGroups( "
2529 << theObject << ", "
2531 << theAngleInRadians << ", "
2532 << theNbOfSteps << ", "
2533 << theTolerance << " )";
2538 //=======================================================================
2539 //function : RotationSweepObject1DMakeGroups
2541 //=======================================================================
2543 SMESH::ListOfGroups*
2544 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2545 const SMESH::AxisStruct& theAxis,
2546 CORBA::Double theAngleInRadians,
2547 CORBA::Long theNbOfSteps,
2548 CORBA::Double theTolerance)
2549 throw (SALOME::SALOME_Exception)
2551 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2553 prepareIdSource( theObject );
2554 SMESH::long_array_var anElementsId = theObject->GetIDs();
2555 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2562 if (!myIsPreviewMode) {
2563 dumpGroupsList(aPythonDump, aGroups);
2564 aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
2565 << theObject << ", "
2567 << TVar( theAngleInRadians ) << ", "
2568 << TVar( theNbOfSteps ) << ", "
2569 << TVar( theTolerance ) << " )";
2574 //=======================================================================
2575 //function : RotationSweepObject2DMakeGroups
2577 //=======================================================================
2579 SMESH::ListOfGroups*
2580 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2581 const SMESH::AxisStruct& theAxis,
2582 CORBA::Double theAngleInRadians,
2583 CORBA::Long theNbOfSteps,
2584 CORBA::Double theTolerance)
2585 throw (SALOME::SALOME_Exception)
2587 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2589 prepareIdSource( theObject );
2590 SMESH::long_array_var anElementsId = theObject->GetIDs();
2591 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2598 if (!myIsPreviewMode) {
2599 dumpGroupsList(aPythonDump, aGroups);
2600 aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
2601 << theObject << ", "
2603 << TVar( theAngleInRadians ) << ", "
2604 << TVar( theNbOfSteps ) << ", "
2605 << TVar( theTolerance ) << " )";
2611 //=======================================================================
2612 //function : extrusionSweep
2614 //=======================================================================
2616 SMESH::ListOfGroups*
2617 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
2618 const SMESH::DirStruct & theStepVector,
2619 CORBA::Long theNbOfSteps,
2621 const SMDSAbs_ElementType theElementType)
2622 throw (SALOME::SALOME_Exception)
2627 TIDSortedElemSet elements, copyElements;
2628 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
2630 const SMESH::PointStruct * P = &theStepVector.PS;
2631 gp_Vec stepVec( P->x, P->y, P->z );
2633 TIDSortedElemSet* workElements = & elements;
2635 SMDSAbs_ElementType aType = SMDSAbs_Face;
2636 if (theElementType == SMDSAbs_Node)
2638 aType = SMDSAbs_Edge;
2640 if ( myIsPreviewMode ) {
2641 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2642 getPreviewMesh( aType )->Copy( elements, copyElements, select, avoid );
2643 workElements = & copyElements;
2644 theMakeGroups = false;
2647 ::SMESH_MeshEditor::TTElemOfElemListMap aHystory;
2648 ::SMESH_MeshEditor::PGroupIDs groupIds =
2649 getEditor().ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
2651 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2653 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2655 SMESH_CATCH( SMESH::throwCorbaException );
2659 //=======================================================================
2660 //function : ExtrusionSweep
2662 //=======================================================================
2664 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
2665 const SMESH::DirStruct & theStepVector,
2666 CORBA::Long theNbOfSteps)
2667 throw (SALOME::SALOME_Exception)
2669 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
2670 if (!myIsPreviewMode) {
2671 TPythonDump() << this << ".ExtrusionSweep( "
2672 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps) << " )";
2676 //=======================================================================
2677 //function : ExtrusionSweep0D
2679 //=======================================================================
2681 void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElements,
2682 const SMESH::DirStruct & theStepVector,
2683 CORBA::Long theNbOfSteps)
2684 throw (SALOME::SALOME_Exception)
2686 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2687 if (!myIsPreviewMode) {
2688 TPythonDump() << this << ".ExtrusionSweep0D( "
2689 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps)<< " )";
2693 //=======================================================================
2694 //function : ExtrusionSweepObject
2696 //=======================================================================
2698 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2699 const SMESH::DirStruct & theStepVector,
2700 CORBA::Long theNbOfSteps)
2701 throw (SALOME::SALOME_Exception)
2703 prepareIdSource( theObject );
2704 SMESH::long_array_var anElementsId = theObject->GetIDs();
2705 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
2706 if (!myIsPreviewMode) {
2707 TPythonDump() << this << ".ExtrusionSweepObject( "
2708 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
2712 //=======================================================================
2713 //function : ExtrusionSweepObject0D
2715 //=======================================================================
2717 void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObject,
2718 const SMESH::DirStruct & theStepVector,
2719 CORBA::Long theNbOfSteps)
2720 throw (SALOME::SALOME_Exception)
2722 prepareIdSource( theObject );
2723 SMESH::long_array_var anElementsId = theObject->GetIDs();
2724 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2725 if ( !myIsPreviewMode ) {
2726 TPythonDump() << this << ".ExtrusionSweepObject0D( "
2727 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2731 //=======================================================================
2732 //function : ExtrusionSweepObject1D
2734 //=======================================================================
2736 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2737 const SMESH::DirStruct & theStepVector,
2738 CORBA::Long theNbOfSteps)
2739 throw (SALOME::SALOME_Exception)
2741 prepareIdSource( theObject );
2742 SMESH::long_array_var anElementsId = theObject->GetIDs();
2743 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
2744 if ( !myIsPreviewMode ) {
2745 TPythonDump() << this << ".ExtrusionSweepObject1D( "
2746 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2750 //=======================================================================
2751 //function : ExtrusionSweepObject2D
2753 //=======================================================================
2755 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2756 const SMESH::DirStruct & theStepVector,
2757 CORBA::Long theNbOfSteps)
2758 throw (SALOME::SALOME_Exception)
2760 prepareIdSource( theObject );
2761 SMESH::long_array_var anElementsId = theObject->GetIDs();
2762 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
2763 if ( !myIsPreviewMode ) {
2764 TPythonDump() << this << ".ExtrusionSweepObject2D( "
2765 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2769 //=======================================================================
2770 //function : ExtrusionSweepMakeGroups
2772 //=======================================================================
2774 SMESH::ListOfGroups*
2775 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2776 const SMESH::DirStruct& theStepVector,
2777 CORBA::Long theNbOfSteps)
2778 throw (SALOME::SALOME_Exception)
2780 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2782 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
2784 if (!myIsPreviewMode) {
2785 dumpGroupsList(aPythonDump, aGroups);
2786 aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
2787 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2792 //=======================================================================
2793 //function : ExtrusionSweepMakeGroups0D
2795 //=======================================================================
2797 SMESH::ListOfGroups*
2798 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups0D(const SMESH::long_array& theIDsOfElements,
2799 const SMESH::DirStruct& theStepVector,
2800 CORBA::Long theNbOfSteps)
2801 throw (SALOME::SALOME_Exception)
2803 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2805 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true,SMDSAbs_Node);
2807 if (!myIsPreviewMode) {
2808 dumpGroupsList(aPythonDump, aGroups);
2809 aPythonDump << this << ".ExtrusionSweepMakeGroups0D( " << theIDsOfElements
2810 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2815 //=======================================================================
2816 //function : ExtrusionSweepObjectMakeGroups
2818 //=======================================================================
2820 SMESH::ListOfGroups*
2821 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2822 const SMESH::DirStruct& theStepVector,
2823 CORBA::Long theNbOfSteps)
2824 throw (SALOME::SALOME_Exception)
2826 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2828 prepareIdSource( theObject );
2829 SMESH::long_array_var anElementsId = theObject->GetIDs();
2830 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
2832 if (!myIsPreviewMode) {
2833 dumpGroupsList(aPythonDump, aGroups);
2834 aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
2835 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2840 //=======================================================================
2841 //function : ExtrusionSweepObject0DMakeGroups
2843 //=======================================================================
2845 SMESH::ListOfGroups*
2846 SMESH_MeshEditor_i::ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2847 const SMESH::DirStruct& theStepVector,
2848 CORBA::Long theNbOfSteps)
2849 throw (SALOME::SALOME_Exception)
2851 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2853 prepareIdSource( theObject );
2854 SMESH::long_array_var anElementsId = theObject->GetIDs();
2855 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2856 theNbOfSteps, true, SMDSAbs_Node);
2857 if (!myIsPreviewMode) {
2858 dumpGroupsList(aPythonDump, aGroups);
2859 aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject
2860 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2865 //=======================================================================
2866 //function : ExtrusionSweepObject1DMakeGroups
2868 //=======================================================================
2870 SMESH::ListOfGroups*
2871 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2872 const SMESH::DirStruct& theStepVector,
2873 CORBA::Long theNbOfSteps)
2874 throw (SALOME::SALOME_Exception)
2876 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2878 prepareIdSource( theObject );
2879 SMESH::long_array_var anElementsId = theObject->GetIDs();
2880 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2881 theNbOfSteps, true, SMDSAbs_Edge);
2882 if (!myIsPreviewMode) {
2883 dumpGroupsList(aPythonDump, aGroups);
2884 aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
2885 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2890 //=======================================================================
2891 //function : ExtrusionSweepObject2DMakeGroups
2893 //=======================================================================
2895 SMESH::ListOfGroups*
2896 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2897 const SMESH::DirStruct& theStepVector,
2898 CORBA::Long theNbOfSteps)
2899 throw (SALOME::SALOME_Exception)
2901 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2903 prepareIdSource( theObject );
2904 SMESH::long_array_var anElementsId = theObject->GetIDs();
2905 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2906 theNbOfSteps, true, SMDSAbs_Face);
2907 if (!myIsPreviewMode) {
2908 dumpGroupsList(aPythonDump, aGroups);
2909 aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
2910 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2916 //=======================================================================
2917 //function : advancedExtrusion
2919 //=======================================================================
2921 SMESH::ListOfGroups*
2922 SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
2923 const SMESH::DirStruct & theStepVector,
2924 CORBA::Long theNbOfSteps,
2925 CORBA::Long theExtrFlags,
2926 CORBA::Double theSewTolerance,
2927 const bool theMakeGroups)
2928 throw (SALOME::SALOME_Exception)
2933 TIDSortedElemSet elements;
2934 arrayToSet(theIDsOfElements, getMeshDS(), elements);
2936 const SMESH::PointStruct * P = &theStepVector.PS;
2937 gp_Vec stepVec( P->x, P->y, P->z );
2939 ::SMESH_MeshEditor::TTElemOfElemListMap aHystory;
2940 ::SMESH_MeshEditor::PGroupIDs groupIds =
2941 getEditor().ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
2942 theMakeGroups, theExtrFlags, theSewTolerance);
2944 declareMeshModified( /*isReComputeSafe=*/true );
2946 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2948 SMESH_CATCH( SMESH::throwCorbaException );
2952 //=======================================================================
2953 //function : AdvancedExtrusion
2955 //=======================================================================
2957 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2958 const SMESH::DirStruct & theStepVector,
2959 CORBA::Long theNbOfSteps,
2960 CORBA::Long theExtrFlags,
2961 CORBA::Double theSewTolerance)
2962 throw (SALOME::SALOME_Exception)
2964 if ( !myIsPreviewMode ) {
2965 TPythonDump() << "stepVector = " << theStepVector;
2966 TPythonDump() << this << ".AdvancedExtrusion("
2969 << theNbOfSteps << ","
2970 << theExtrFlags << ", "
2971 << theSewTolerance << " )";
2973 advancedExtrusion( theIDsOfElements,
2981 //=======================================================================
2982 //function : AdvancedExtrusionMakeGroups
2984 //=======================================================================
2985 SMESH::ListOfGroups*
2986 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
2987 const SMESH::DirStruct& theStepVector,
2988 CORBA::Long theNbOfSteps,
2989 CORBA::Long theExtrFlags,
2990 CORBA::Double theSewTolerance)
2991 throw (SALOME::SALOME_Exception)
2993 if (!myIsPreviewMode) {
2994 TPythonDump() << "stepVector = " << theStepVector;
2996 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2998 SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
3005 if (!myIsPreviewMode) {
3006 dumpGroupsList(aPythonDump, aGroups);
3007 aPythonDump << this << ".AdvancedExtrusionMakeGroups("
3010 << theNbOfSteps << ","
3011 << theExtrFlags << ", "
3012 << theSewTolerance << " )";
3018 //================================================================================
3020 * \brief Convert extrusion error to IDL enum
3022 //================================================================================
3024 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
3026 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
3030 RETCASE( EXTR_NO_ELEMENTS );
3031 RETCASE( EXTR_PATH_NOT_EDGE );
3032 RETCASE( EXTR_BAD_PATH_SHAPE );
3033 RETCASE( EXTR_BAD_STARTING_NODE );
3034 RETCASE( EXTR_BAD_ANGLES_NUMBER );
3035 RETCASE( EXTR_CANT_GET_TANGENT );
3037 return SMESH::SMESH_MeshEditor::EXTR_OK;
3041 //=======================================================================
3042 //function : extrusionAlongPath
3044 //=======================================================================
3045 SMESH::ListOfGroups*
3046 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfElements,
3047 SMESH::SMESH_Mesh_ptr thePathMesh,
3048 GEOM::GEOM_Object_ptr thePathShape,
3049 CORBA::Long theNodeStart,
3050 CORBA::Boolean theHasAngles,
3051 const SMESH::double_array & theAngles,
3052 CORBA::Boolean theHasRefPoint,
3053 const SMESH::PointStruct & theRefPoint,
3054 const bool theMakeGroups,
3055 SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
3056 const SMDSAbs_ElementType theElementType)
3057 throw (SALOME::SALOME_Exception)
3060 MESSAGE("extrusionAlongPath");
3063 if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
3064 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3067 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3069 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3070 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3072 if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
3073 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3077 SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
3079 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3083 TIDSortedElemSet elements;
3084 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
3086 list<double> angles;
3087 for (int i = 0; i < theAngles.length(); i++) {
3088 angles.push_back( theAngles[i] );
3091 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
3093 int nbOldGroups = myMesh->NbGroup();
3095 ::SMESH_MeshEditor::Extrusion_Error error =
3096 getEditor().ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
3097 theHasAngles, angles, false,
3098 theHasRefPoint, refPnt, theMakeGroups );
3100 declareMeshModified( /*isReComputeSafe=*/true );
3101 theError = convExtrError( error );
3103 if ( theMakeGroups ) {
3104 list<int> groupIDs = myMesh->GetGroupIds();
3105 list<int>::iterator newBegin = groupIDs.begin();
3106 std::advance( newBegin, nbOldGroups ); // skip old groups
3107 groupIDs.erase( groupIDs.begin(), newBegin );
3108 return getGroups( & groupIDs );
3112 SMESH_CATCH( SMESH::throwCorbaException );
3116 //=======================================================================
3117 //function : extrusionAlongPathX
3119 //=======================================================================
3121 SMESH::ListOfGroups*
3122 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements,
3123 SMESH::SMESH_IDSource_ptr Path,
3124 CORBA::Long NodeStart,
3125 CORBA::Boolean HasAngles,
3126 const SMESH::double_array& Angles,
3127 CORBA::Boolean LinearVariation,
3128 CORBA::Boolean HasRefPoint,
3129 const SMESH::PointStruct& RefPoint,
3131 const SMDSAbs_ElementType ElementType,
3132 SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
3133 throw (SALOME::SALOME_Exception)
3136 SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
3140 list<double> angles;
3141 for (int i = 0; i < Angles.length(); i++) {
3142 angles.push_back( Angles[i] );
3144 gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
3145 int nbOldGroups = myMesh->NbGroup();
3147 if ( Path->_is_nil() ) {
3148 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3152 TIDSortedElemSet elements, copyElements;
3153 arrayToSet(IDsOfElements, getMeshDS(), elements, ElementType);
3155 TIDSortedElemSet* workElements = &elements;
3157 if ( myIsPreviewMode )
3159 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
3160 getPreviewMesh( SMDSAbs_Face )->Copy( elements, copyElements, select, avoid );
3161 workElements = & copyElements;
3165 ::SMESH_MeshEditor::Extrusion_Error error;
3167 if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path ))
3170 SMDS_MeshNode* aNodeStart =
3171 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
3172 if ( !aNodeStart ) {
3173 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3176 error = getEditor().ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
3177 HasAngles, angles, LinearVariation,
3178 HasRefPoint, refPnt, MakeGroups );
3179 declareMeshModified( /*isReComputeSafe=*/true );
3181 else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
3184 SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
3185 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
3186 SMDS_MeshNode* aNodeStart =
3187 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
3188 if ( !aNodeStart ) {
3189 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3192 SMESH_subMesh* aSubMesh =
3193 aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
3194 error = getEditor().ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
3195 HasAngles, angles, LinearVariation,
3196 HasRefPoint, refPnt, MakeGroups );
3197 declareMeshModified( /*isReComputeSafe=*/true );
3199 else if ( SMESH::DownCast<SMESH_Group_i*>( Path ))
3201 // path as group of 1D elements
3207 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3211 Error = convExtrError( error );
3214 list<int> groupIDs = myMesh->GetGroupIds();
3215 list<int>::iterator newBegin = groupIDs.begin();
3216 std::advance( newBegin, nbOldGroups ); // skip old groups
3217 groupIDs.erase( groupIDs.begin(), newBegin );
3218 return getGroups( & groupIDs );
3222 SMESH_CATCH( SMESH::throwCorbaException );
3226 //=======================================================================
3227 //function : ExtrusionAlongPath
3229 //=======================================================================
3231 SMESH::SMESH_MeshEditor::Extrusion_Error
3232 SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements,
3233 SMESH::SMESH_Mesh_ptr thePathMesh,
3234 GEOM::GEOM_Object_ptr thePathShape,
3235 CORBA::Long theNodeStart,
3236 CORBA::Boolean theHasAngles,
3237 const SMESH::double_array & theAngles,
3238 CORBA::Boolean theHasRefPoint,
3239 const SMESH::PointStruct & theRefPoint)
3240 throw (SALOME::SALOME_Exception)
3242 MESSAGE("ExtrusionAlongPath");
3243 if ( !myIsPreviewMode ) {
3244 TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
3245 << theIDsOfElements << ", "
3246 << thePathMesh << ", "
3247 << thePathShape << ", "
3248 << theNodeStart << ", "
3249 << theHasAngles << ", "
3250 << theAngles << ", "
3251 << theHasRefPoint << ", "
3252 << "SMESH.PointStruct( "
3253 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3254 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3255 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3257 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3258 extrusionAlongPath( theIDsOfElements,
3271 //=======================================================================
3272 //function : ExtrusionAlongPathObject
3274 //=======================================================================
3276 SMESH::SMESH_MeshEditor::Extrusion_Error
3277 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject,
3278 SMESH::SMESH_Mesh_ptr thePathMesh,
3279 GEOM::GEOM_Object_ptr thePathShape,
3280 CORBA::Long theNodeStart,
3281 CORBA::Boolean theHasAngles,
3282 const SMESH::double_array & theAngles,
3283 CORBA::Boolean theHasRefPoint,
3284 const SMESH::PointStruct & theRefPoint)
3285 throw (SALOME::SALOME_Exception)
3287 if ( !myIsPreviewMode ) {
3288 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
3289 << theObject << ", "
3290 << thePathMesh << ", "
3291 << thePathShape << ", "
3292 << theNodeStart << ", "
3293 << theHasAngles << ", "
3294 << theAngles << ", "
3295 << theHasRefPoint << ", "
3296 << "SMESH.PointStruct( "
3297 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3298 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3299 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3301 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3302 prepareIdSource( theObject );
3303 SMESH::long_array_var anElementsId = theObject->GetIDs();
3304 extrusionAlongPath( anElementsId,
3317 //=======================================================================
3318 //function : ExtrusionAlongPathObject1D
3320 //=======================================================================
3322 SMESH::SMESH_MeshEditor::Extrusion_Error
3323 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject,
3324 SMESH::SMESH_Mesh_ptr thePathMesh,
3325 GEOM::GEOM_Object_ptr thePathShape,
3326 CORBA::Long theNodeStart,
3327 CORBA::Boolean theHasAngles,
3328 const SMESH::double_array & theAngles,
3329 CORBA::Boolean theHasRefPoint,
3330 const SMESH::PointStruct & theRefPoint)
3331 throw (SALOME::SALOME_Exception)
3333 if ( !myIsPreviewMode ) {
3334 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
3335 << theObject << ", "
3336 << thePathMesh << ", "
3337 << thePathShape << ", "
3338 << theNodeStart << ", "
3339 << theHasAngles << ", "
3340 << theAngles << ", "
3341 << theHasRefPoint << ", "
3342 << "SMESH.PointStruct( "
3343 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3344 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3345 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3347 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3348 prepareIdSource( theObject );
3349 SMESH::long_array_var anElementsId = theObject->GetIDs();
3350 extrusionAlongPath( anElementsId,
3364 //=======================================================================
3365 //function : ExtrusionAlongPathObject2D
3367 //=======================================================================
3369 SMESH::SMESH_MeshEditor::Extrusion_Error
3370 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject,
3371 SMESH::SMESH_Mesh_ptr thePathMesh,
3372 GEOM::GEOM_Object_ptr thePathShape,
3373 CORBA::Long theNodeStart,
3374 CORBA::Boolean theHasAngles,
3375 const SMESH::double_array & theAngles,
3376 CORBA::Boolean theHasRefPoint,
3377 const SMESH::PointStruct & theRefPoint)
3378 throw (SALOME::SALOME_Exception)
3380 if ( !myIsPreviewMode ) {
3381 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
3382 << theObject << ", "
3383 << thePathMesh << ", "
3384 << thePathShape << ", "
3385 << theNodeStart << ", "
3386 << theHasAngles << ", "
3387 << theAngles << ", "
3388 << theHasRefPoint << ", "
3389 << "SMESH.PointStruct( "
3390 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3391 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3392 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3394 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3395 prepareIdSource( theObject );
3396 SMESH::long_array_var anElementsId = theObject->GetIDs();
3397 extrusionAlongPath( anElementsId,
3412 //=======================================================================
3413 //function : ExtrusionAlongPathMakeGroups
3415 //=======================================================================
3417 SMESH::ListOfGroups*
3418 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theIDsOfElements,
3419 SMESH::SMESH_Mesh_ptr thePathMesh,
3420 GEOM::GEOM_Object_ptr thePathShape,
3421 CORBA::Long theNodeStart,
3422 CORBA::Boolean theHasAngles,
3423 const SMESH::double_array& theAngles,
3424 CORBA::Boolean theHasRefPoint,
3425 const SMESH::PointStruct& theRefPoint,
3426 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3427 throw (SALOME::SALOME_Exception)
3429 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3431 SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements,
3441 if (!myIsPreviewMode) {
3442 bool isDumpGroups = aGroups && aGroups->length() > 0;
3444 aPythonDump << "(" << aGroups << ", error)";
3446 aPythonDump <<"error";
3448 aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
3449 << theIDsOfElements << ", "
3450 << thePathMesh << ", "
3451 << thePathShape << ", "
3452 << theNodeStart << ", "
3453 << theHasAngles << ", "
3454 << theAngles << ", "
3455 << theHasRefPoint << ", "
3456 << "SMESH.PointStruct( "
3457 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3458 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3459 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3464 //=======================================================================
3465 //function : ExtrusionAlongPathObjectMakeGroups
3467 //=======================================================================
3469 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3470 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3471 SMESH::SMESH_Mesh_ptr thePathMesh,
3472 GEOM::GEOM_Object_ptr thePathShape,
3473 CORBA::Long theNodeStart,
3474 CORBA::Boolean theHasAngles,
3475 const SMESH::double_array& theAngles,
3476 CORBA::Boolean theHasRefPoint,
3477 const SMESH::PointStruct& theRefPoint,
3478 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3479 throw (SALOME::SALOME_Exception)
3481 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3483 prepareIdSource( theObject );
3484 SMESH::long_array_var anElementsId = theObject->GetIDs();
3485 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3496 if (!myIsPreviewMode) {
3497 bool isDumpGroups = aGroups && aGroups->length() > 0;
3499 aPythonDump << "(" << aGroups << ", error)";
3501 aPythonDump <<"error";
3503 aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
3504 << theObject << ", "
3505 << thePathMesh << ", "
3506 << thePathShape << ", "
3507 << theNodeStart << ", "
3508 << theHasAngles << ", "
3509 << theAngles << ", "
3510 << theHasRefPoint << ", "
3511 << "SMESH.PointStruct( "
3512 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3513 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3514 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3519 //=======================================================================
3520 //function : ExtrusionAlongPathObject1DMakeGroups
3522 //=======================================================================
3524 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3525 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3526 SMESH::SMESH_Mesh_ptr thePathMesh,
3527 GEOM::GEOM_Object_ptr thePathShape,
3528 CORBA::Long theNodeStart,
3529 CORBA::Boolean theHasAngles,
3530 const SMESH::double_array& theAngles,
3531 CORBA::Boolean theHasRefPoint,
3532 const SMESH::PointStruct& theRefPoint,
3533 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3534 throw (SALOME::SALOME_Exception)
3536 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3538 prepareIdSource( theObject );
3539 SMESH::long_array_var anElementsId = theObject->GetIDs();
3540 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3552 if (!myIsPreviewMode) {
3553 bool isDumpGroups = aGroups && aGroups->length() > 0;
3555 aPythonDump << "(" << aGroups << ", error)";
3557 aPythonDump << "error";
3559 aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
3560 << theObject << ", "
3561 << thePathMesh << ", "
3562 << thePathShape << ", "
3563 << theNodeStart << ", "
3564 << theHasAngles << ", "
3565 << theAngles << ", "
3566 << theHasRefPoint << ", "
3567 << "SMESH.PointStruct( "
3568 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3569 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3570 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3575 //=======================================================================
3576 //function : ExtrusionAlongPathObject2DMakeGroups
3578 //=======================================================================
3580 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3581 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3582 SMESH::SMESH_Mesh_ptr thePathMesh,
3583 GEOM::GEOM_Object_ptr thePathShape,
3584 CORBA::Long theNodeStart,
3585 CORBA::Boolean theHasAngles,
3586 const SMESH::double_array& theAngles,
3587 CORBA::Boolean theHasRefPoint,
3588 const SMESH::PointStruct& theRefPoint,
3589 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3590 throw (SALOME::SALOME_Exception)
3592 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3594 prepareIdSource( theObject );
3595 SMESH::long_array_var anElementsId = theObject->GetIDs();
3596 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3608 if (!myIsPreviewMode) {
3609 bool isDumpGroups = aGroups && aGroups->length() > 0;
3611 aPythonDump << "(" << aGroups << ", error)";
3613 aPythonDump << "error";
3615 aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
3616 << theObject << ", "
3617 << thePathMesh << ", "
3618 << thePathShape << ", "
3619 << theNodeStart << ", "
3620 << theHasAngles << ", "
3621 << theAngles << ", "
3622 << theHasRefPoint << ", "
3623 << "SMESH.PointStruct( "
3624 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3625 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3626 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3631 //=======================================================================
3632 //function : ExtrusionAlongPathObjX
3634 //=======================================================================
3636 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3637 ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr Object,
3638 SMESH::SMESH_IDSource_ptr Path,
3639 CORBA::Long NodeStart,
3640 CORBA::Boolean HasAngles,
3641 const SMESH::double_array& Angles,
3642 CORBA::Boolean LinearVariation,
3643 CORBA::Boolean HasRefPoint,
3644 const SMESH::PointStruct& RefPoint,
3645 CORBA::Boolean MakeGroups,
3646 SMESH::ElementType ElemType,
3647 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3648 throw (SALOME::SALOME_Exception)
3650 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3652 prepareIdSource( Object );
3653 SMESH::long_array_var anElementsId = Object->GetIDs();
3654 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
3663 (SMDSAbs_ElementType)ElemType,
3666 if (!myIsPreviewMode) {
3667 bool isDumpGroups = aGroups && aGroups->length() > 0;
3669 aPythonDump << "(" << *aGroups << ", error)";
3671 aPythonDump << "error";
3673 aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
3676 << NodeStart << ", "
3677 << HasAngles << ", "
3678 << TVar( Angles ) << ", "
3679 << LinearVariation << ", "
3680 << HasRefPoint << ", "
3681 << "SMESH.PointStruct( "
3682 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3683 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3684 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3685 << MakeGroups << ", "
3686 << ElemType << " )";
3691 //=======================================================================
3692 //function : ExtrusionAlongPathX
3694 //=======================================================================
3696 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3697 ExtrusionAlongPathX(const SMESH::long_array& IDsOfElements,
3698 SMESH::SMESH_IDSource_ptr Path,
3699 CORBA::Long NodeStart,
3700 CORBA::Boolean HasAngles,
3701 const SMESH::double_array& Angles,
3702 CORBA::Boolean LinearVariation,
3703 CORBA::Boolean HasRefPoint,
3704 const SMESH::PointStruct& RefPoint,
3705 CORBA::Boolean MakeGroups,
3706 SMESH::ElementType ElemType,
3707 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3708 throw (SALOME::SALOME_Exception)
3710 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3712 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
3721 (SMDSAbs_ElementType)ElemType,
3724 if (!myIsPreviewMode) {
3725 bool isDumpGroups = aGroups && aGroups->length() > 0;
3727 aPythonDump << "(" << *aGroups << ", error)";
3729 aPythonDump <<"error";
3731 aPythonDump << " = " << this << ".ExtrusionAlongPathX( "
3732 << IDsOfElements << ", "
3734 << NodeStart << ", "
3735 << HasAngles << ", "
3736 << TVar( Angles ) << ", "
3737 << LinearVariation << ", "
3738 << HasRefPoint << ", "
3739 << "SMESH.PointStruct( "
3740 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3741 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3742 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3743 << MakeGroups << ", "
3744 << ElemType << " )";
3749 //================================================================================
3751 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
3752 * of given angles along path steps
3753 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
3754 * which proceeds the extrusion
3755 * \param PathShape is shape(edge); as the mesh can be complex, the edge
3756 * is used to define the sub-mesh for the path
3758 //================================================================================
3760 SMESH::double_array*
3761 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
3762 GEOM::GEOM_Object_ptr thePathShape,
3763 const SMESH::double_array & theAngles)
3765 SMESH::double_array_var aResult = new SMESH::double_array();
3766 int nbAngles = theAngles.length();
3767 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
3769 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3770 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3771 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3772 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
3773 return aResult._retn();
3774 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
3775 if ( nbSteps == nbAngles )
3777 aResult.inout() = theAngles;
3781 aResult->length( nbSteps );
3782 double rAn2St = double( nbAngles ) / double( nbSteps );
3783 double angPrev = 0, angle;
3784 for ( int iSt = 0; iSt < nbSteps; ++iSt )
3786 double angCur = rAn2St * ( iSt+1 );
3787 double angCurFloor = floor( angCur );
3788 double angPrevFloor = floor( angPrev );
3789 if ( angPrevFloor == angCurFloor )
3790 angle = rAn2St * theAngles[ int( angCurFloor ) ];
3793 int iP = int( angPrevFloor );
3794 double angPrevCeil = ceil(angPrev);
3795 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
3797 int iC = int( angCurFloor );
3798 if ( iC < nbAngles )
3799 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
3801 iP = int( angPrevCeil );
3803 angle += theAngles[ iC ];
3805 aResult[ iSt ] = angle;
3810 // Update Python script
3811 TPythonDump() << "rotAngles = " << theAngles;
3812 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
3813 << thePathMesh << ", "
3814 << thePathShape << ", "
3817 return aResult._retn();
3820 //=======================================================================
3823 //=======================================================================
3825 SMESH::ListOfGroups*
3826 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
3827 const SMESH::AxisStruct & theAxis,
3828 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3829 CORBA::Boolean theCopy,
3831 ::SMESH_Mesh* theTargetMesh)
3832 throw (SALOME::SALOME_Exception)
3837 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3838 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3840 if ( theTargetMesh )
3844 switch ( theMirrorType ) {
3845 case SMESH::SMESH_MeshEditor::POINT:
3846 aTrsf.SetMirror( P );
3848 case SMESH::SMESH_MeshEditor::AXIS:
3849 aTrsf.SetMirror( gp_Ax1( P, V ));
3852 aTrsf.SetMirror( gp_Ax2( P, V ));
3855 TIDSortedElemSet copyElements;
3856 TIDSortedElemSet* workElements = & theElements;
3858 if ( myIsPreviewMode )
3860 TPreviewMesh * tmpMesh = getPreviewMesh();
3861 tmpMesh->Copy( theElements, copyElements);
3862 if ( !theCopy && !theTargetMesh )
3864 TIDSortedElemSet elemsAround, elemsAroundCopy;
3865 getElementsAround( theElements, getMeshDS(), elemsAround );
3866 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3868 workElements = & copyElements;
3869 theMakeGroups = false;
3872 ::SMESH_MeshEditor::PGroupIDs groupIds =
3873 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3875 if ( theCopy && !myIsPreviewMode)
3877 if ( theTargetMesh )
3879 theTargetMesh->GetMeshDS()->Modified();
3883 declareMeshModified( /*isReComputeSafe=*/false );
3886 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3888 SMESH_CATCH( SMESH::throwCorbaException );
3892 //=======================================================================
3895 //=======================================================================
3897 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3898 const SMESH::AxisStruct & theAxis,
3899 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3900 CORBA::Boolean theCopy)
3901 throw (SALOME::SALOME_Exception)
3903 if ( !myIsPreviewMode ) {
3904 TPythonDump() << this << ".Mirror( "
3905 << theIDsOfElements << ", "
3907 << mirrorTypeName(theMirrorType) << ", "
3910 if ( theIDsOfElements.length() > 0 )
3912 TIDSortedElemSet elements;
3913 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3914 mirror(elements, theAxis, theMirrorType, theCopy, false);
3919 //=======================================================================
3920 //function : MirrorObject
3922 //=======================================================================
3924 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3925 const SMESH::AxisStruct & theAxis,
3926 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3927 CORBA::Boolean theCopy)
3928 throw (SALOME::SALOME_Exception)
3930 if ( !myIsPreviewMode ) {
3931 TPythonDump() << this << ".MirrorObject( "
3932 << theObject << ", "
3934 << mirrorTypeName(theMirrorType) << ", "
3937 TIDSortedElemSet elements;
3939 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3941 prepareIdSource( theObject );
3942 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3943 mirror(elements, theAxis, theMirrorType, theCopy, false);
3946 //=======================================================================
3947 //function : MirrorMakeGroups
3949 //=======================================================================
3951 SMESH::ListOfGroups*
3952 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3953 const SMESH::AxisStruct& theMirror,
3954 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3955 throw (SALOME::SALOME_Exception)
3957 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3959 SMESH::ListOfGroups * aGroups = 0;
3960 if ( theIDsOfElements.length() > 0 )
3962 TIDSortedElemSet elements;
3963 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3964 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3966 if (!myIsPreviewMode) {
3967 dumpGroupsList(aPythonDump, aGroups);
3968 aPythonDump << this << ".MirrorMakeGroups( "
3969 << theIDsOfElements << ", "
3970 << theMirror << ", "
3971 << mirrorTypeName(theMirrorType) << " )";
3976 //=======================================================================
3977 //function : MirrorObjectMakeGroups
3979 //=======================================================================
3981 SMESH::ListOfGroups*
3982 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3983 const SMESH::AxisStruct& theMirror,
3984 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3985 throw (SALOME::SALOME_Exception)
3987 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3989 SMESH::ListOfGroups * aGroups = 0;
3990 TIDSortedElemSet elements;
3991 prepareIdSource( theObject );
3992 if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3993 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3995 if (!myIsPreviewMode)
3997 dumpGroupsList(aPythonDump,aGroups);
3998 aPythonDump << this << ".MirrorObjectMakeGroups( "
3999 << theObject << ", "
4000 << theMirror << ", "
4001 << mirrorTypeName(theMirrorType) << " )";
4006 //=======================================================================
4007 //function : MirrorMakeMesh
4009 //=======================================================================
4011 SMESH::SMESH_Mesh_ptr
4012 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
4013 const SMESH::AxisStruct& theMirror,
4014 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
4015 CORBA::Boolean theCopyGroups,
4016 const char* theMeshName)
4017 throw (SALOME::SALOME_Exception)
4019 SMESH_Mesh_i* mesh_i;
4020 SMESH::SMESH_Mesh_var mesh;
4021 { // open new scope to dump "MakeMesh" command
4022 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4024 TPythonDump pydump; // to prevent dump at mesh creation
4026 mesh = makeMesh( theMeshName );
4027 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4028 if (mesh_i && theIDsOfElements.length() > 0 )
4030 TIDSortedElemSet elements;
4031 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4032 mirror(elements, theMirror, theMirrorType,
4033 false, theCopyGroups, & mesh_i->GetImpl());
4034 mesh_i->CreateGroupServants();
4037 if (!myIsPreviewMode) {
4038 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
4039 << theIDsOfElements << ", "
4040 << theMirror << ", "
4041 << mirrorTypeName(theMirrorType) << ", "
4042 << theCopyGroups << ", '"
4043 << theMeshName << "' )";
4048 if (!myIsPreviewMode && mesh_i)
4049 mesh_i->GetGroups();
4051 return mesh._retn();
4054 //=======================================================================
4055 //function : MirrorObjectMakeMesh
4057 //=======================================================================
4059 SMESH::SMESH_Mesh_ptr
4060 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4061 const SMESH::AxisStruct& theMirror,
4062 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
4063 CORBA::Boolean theCopyGroups,
4064 const char* theMeshName)
4065 throw (SALOME::SALOME_Exception)
4067 SMESH_Mesh_i* mesh_i;
4068 SMESH::SMESH_Mesh_var mesh;
4069 { // open new scope to dump "MakeMesh" command
4070 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4072 TPythonDump pydump; // to prevent dump at mesh creation
4074 mesh = makeMesh( theMeshName );
4075 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4076 TIDSortedElemSet elements;
4077 prepareIdSource( theObject );
4079 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4081 mirror(elements, theMirror, theMirrorType,
4082 false, theCopyGroups, & mesh_i->GetImpl());
4083 mesh_i->CreateGroupServants();
4085 if (!myIsPreviewMode) {
4086 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
4087 << theObject << ", "
4088 << theMirror << ", "
4089 << mirrorTypeName(theMirrorType) << ", "
4090 << theCopyGroups << ", '"
4091 << theMeshName << "' )";
4096 if (!myIsPreviewMode && mesh_i)
4097 mesh_i->GetGroups();
4099 return mesh._retn();
4102 //=======================================================================
4103 //function : translate
4105 //=======================================================================
4107 SMESH::ListOfGroups*
4108 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
4109 const SMESH::DirStruct & theVector,
4110 CORBA::Boolean theCopy,
4112 ::SMESH_Mesh* theTargetMesh)
4113 throw (SALOME::SALOME_Exception)
4118 if ( theTargetMesh )
4122 const SMESH::PointStruct * P = &theVector.PS;
4123 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
4125 TIDSortedElemSet copyElements;
4126 TIDSortedElemSet* workElements = &theElements;
4128 if ( myIsPreviewMode )
4130 TPreviewMesh * tmpMesh = getPreviewMesh();
4131 tmpMesh->Copy( theElements, copyElements);
4132 if ( !theCopy && !theTargetMesh )
4134 TIDSortedElemSet elemsAround, elemsAroundCopy;
4135 getElementsAround( theElements, getMeshDS(), elemsAround );
4136 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4138 workElements = & copyElements;
4139 theMakeGroups = false;
4142 ::SMESH_MeshEditor::PGroupIDs groupIds =
4143 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4145 if ( theCopy && !myIsPreviewMode )
4147 if ( theTargetMesh )
4149 theTargetMesh->GetMeshDS()->Modified();
4153 declareMeshModified( /*isReComputeSafe=*/false );
4157 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4159 SMESH_CATCH( SMESH::throwCorbaException );
4163 //=======================================================================
4164 //function : Translate
4166 //=======================================================================
4168 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
4169 const SMESH::DirStruct & theVector,
4170 CORBA::Boolean theCopy)
4171 throw (SALOME::SALOME_Exception)
4173 if (!myIsPreviewMode) {
4174 TPythonDump() << this << ".Translate( "
4175 << theIDsOfElements << ", "
4176 << theVector << ", "
4179 if (theIDsOfElements.length()) {
4180 TIDSortedElemSet elements;
4181 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4182 translate(elements, theVector, theCopy, false);
4186 //=======================================================================
4187 //function : TranslateObject
4189 //=======================================================================
4191 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
4192 const SMESH::DirStruct & theVector,
4193 CORBA::Boolean theCopy)
4194 throw (SALOME::SALOME_Exception)
4196 if (!myIsPreviewMode) {
4197 TPythonDump() << this << ".TranslateObject( "
4198 << theObject << ", "
4199 << theVector << ", "
4202 TIDSortedElemSet elements;
4204 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4206 prepareIdSource( theObject );
4207 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4208 translate(elements, theVector, theCopy, false);
4211 //=======================================================================
4212 //function : TranslateMakeGroups
4214 //=======================================================================
4216 SMESH::ListOfGroups*
4217 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
4218 const SMESH::DirStruct& theVector)
4219 throw (SALOME::SALOME_Exception)
4221 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4223 SMESH::ListOfGroups * aGroups = 0;
4224 if (theIDsOfElements.length()) {
4225 TIDSortedElemSet elements;
4226 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4227 aGroups = translate(elements,theVector,true,true);
4229 if (!myIsPreviewMode) {
4230 dumpGroupsList(aPythonDump, aGroups);
4231 aPythonDump << this << ".TranslateMakeGroups( "
4232 << theIDsOfElements << ", "
4233 << theVector << " )";
4238 //=======================================================================
4239 //function : TranslateObjectMakeGroups
4241 //=======================================================================
4243 SMESH::ListOfGroups*
4244 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4245 const SMESH::DirStruct& theVector)
4246 throw (SALOME::SALOME_Exception)
4248 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4250 SMESH::ListOfGroups * aGroups = 0;
4251 TIDSortedElemSet elements;
4252 prepareIdSource( theObject );
4253 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4254 aGroups = translate(elements, theVector, true, true);
4256 if (!myIsPreviewMode) {
4257 dumpGroupsList(aPythonDump, aGroups);
4258 aPythonDump << this << ".TranslateObjectMakeGroups( "
4259 << theObject << ", "
4260 << theVector << " )";
4265 //=======================================================================
4266 //function : TranslateMakeMesh
4268 //=======================================================================
4270 SMESH::SMESH_Mesh_ptr
4271 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
4272 const SMESH::DirStruct& theVector,
4273 CORBA::Boolean theCopyGroups,
4274 const char* theMeshName)
4275 throw (SALOME::SALOME_Exception)
4277 SMESH_Mesh_i* mesh_i;
4278 SMESH::SMESH_Mesh_var mesh;
4280 { // open new scope to dump "MakeMesh" command
4281 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4283 TPythonDump pydump; // to prevent dump at mesh creation
4285 mesh = makeMesh( theMeshName );
4286 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4288 if ( mesh_i && theIDsOfElements.length() )
4290 TIDSortedElemSet elements;
4291 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4292 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
4293 mesh_i->CreateGroupServants();
4296 if ( !myIsPreviewMode ) {
4297 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
4298 << theIDsOfElements << ", "
4299 << theVector << ", "
4300 << theCopyGroups << ", '"
4301 << theMeshName << "' )";
4306 if (!myIsPreviewMode && mesh_i)
4307 mesh_i->GetGroups();
4309 return mesh._retn();
4312 //=======================================================================
4313 //function : TranslateObjectMakeMesh
4315 //=======================================================================
4317 SMESH::SMESH_Mesh_ptr
4318 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4319 const SMESH::DirStruct& theVector,
4320 CORBA::Boolean theCopyGroups,
4321 const char* theMeshName)
4322 throw (SALOME::SALOME_Exception)
4325 SMESH_Mesh_i* mesh_i;
4326 SMESH::SMESH_Mesh_var mesh;
4327 { // open new scope to dump "MakeMesh" command
4328 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4330 TPythonDump pydump; // to prevent dump at mesh creation
4331 mesh = makeMesh( theMeshName );
4332 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4334 TIDSortedElemSet elements;
4335 prepareIdSource( theObject );
4337 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4339 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
4340 mesh_i->CreateGroupServants();
4342 if ( !myIsPreviewMode ) {
4343 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
4344 << theObject << ", "
4345 << theVector << ", "
4346 << theCopyGroups << ", '"
4347 << theMeshName << "' )";
4352 if (!myIsPreviewMode && mesh_i)
4353 mesh_i->GetGroups();
4355 return mesh._retn();
4357 SMESH_CATCH( SMESH::throwCorbaException );
4361 //=======================================================================
4364 //=======================================================================
4366 SMESH::ListOfGroups*
4367 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
4368 const SMESH::AxisStruct & theAxis,
4369 CORBA::Double theAngle,
4370 CORBA::Boolean theCopy,
4372 ::SMESH_Mesh* theTargetMesh)
4373 throw (SALOME::SALOME_Exception)
4378 if ( theTargetMesh )
4381 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
4382 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
4385 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
4387 TIDSortedElemSet copyElements;
4388 TIDSortedElemSet* workElements = &theElements;
4389 if ( myIsPreviewMode ) {
4390 TPreviewMesh * tmpMesh = getPreviewMesh();
4391 tmpMesh->Copy( theElements, copyElements );
4392 if ( !theCopy && !theTargetMesh )
4394 TIDSortedElemSet elemsAround, elemsAroundCopy;
4395 getElementsAround( theElements, getMeshDS(), elemsAround );
4396 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4398 workElements = ©Elements;
4399 theMakeGroups = false;
4402 ::SMESH_MeshEditor::PGroupIDs groupIds =
4403 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4405 if ( theCopy && !myIsPreviewMode)
4407 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
4408 else declareMeshModified( /*isReComputeSafe=*/false );
4411 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4413 SMESH_CATCH( SMESH::throwCorbaException );
4417 //=======================================================================
4420 //=======================================================================
4422 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
4423 const SMESH::AxisStruct & theAxis,
4424 CORBA::Double theAngle,
4425 CORBA::Boolean theCopy)
4426 throw (SALOME::SALOME_Exception)
4428 if (!myIsPreviewMode) {
4429 TPythonDump() << this << ".Rotate( "
4430 << theIDsOfElements << ", "
4432 << TVar( theAngle ) << ", "
4435 if (theIDsOfElements.length() > 0)
4437 TIDSortedElemSet elements;
4438 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4439 rotate(elements,theAxis,theAngle,theCopy,false);
4443 //=======================================================================
4444 //function : RotateObject
4446 //=======================================================================
4448 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
4449 const SMESH::AxisStruct & theAxis,
4450 CORBA::Double theAngle,
4451 CORBA::Boolean theCopy)
4452 throw (SALOME::SALOME_Exception)
4454 if ( !myIsPreviewMode ) {
4455 TPythonDump() << this << ".RotateObject( "
4456 << theObject << ", "
4458 << TVar( theAngle ) << ", "
4461 TIDSortedElemSet elements;
4462 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4463 prepareIdSource( theObject );
4464 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4465 rotate(elements,theAxis,theAngle,theCopy,false);
4468 //=======================================================================
4469 //function : RotateMakeGroups
4471 //=======================================================================
4473 SMESH::ListOfGroups*
4474 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
4475 const SMESH::AxisStruct& theAxis,
4476 CORBA::Double theAngle)
4477 throw (SALOME::SALOME_Exception)
4479 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4481 SMESH::ListOfGroups * aGroups = 0;
4482 if (theIDsOfElements.length() > 0)
4484 TIDSortedElemSet elements;
4485 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4486 aGroups = rotate(elements,theAxis,theAngle,true,true);
4488 if (!myIsPreviewMode) {
4489 dumpGroupsList(aPythonDump, aGroups);
4490 aPythonDump << this << ".RotateMakeGroups( "
4491 << theIDsOfElements << ", "
4493 << TVar( theAngle ) << " )";
4498 //=======================================================================
4499 //function : RotateObjectMakeGroups
4501 //=======================================================================
4503 SMESH::ListOfGroups*
4504 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4505 const SMESH::AxisStruct& theAxis,
4506 CORBA::Double theAngle)
4507 throw (SALOME::SALOME_Exception)
4509 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4511 SMESH::ListOfGroups * aGroups = 0;
4512 TIDSortedElemSet elements;
4513 prepareIdSource( theObject );
4514 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4515 aGroups = rotate(elements, theAxis, theAngle, true, true);
4517 if (!myIsPreviewMode) {
4518 dumpGroupsList(aPythonDump, aGroups);
4519 aPythonDump << this << ".RotateObjectMakeGroups( "
4520 << theObject << ", "
4522 << TVar( theAngle ) << " )";
4527 //=======================================================================
4528 //function : RotateMakeMesh
4530 //=======================================================================
4532 SMESH::SMESH_Mesh_ptr
4533 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
4534 const SMESH::AxisStruct& theAxis,
4535 CORBA::Double theAngleInRadians,
4536 CORBA::Boolean theCopyGroups,
4537 const char* theMeshName)
4538 throw (SALOME::SALOME_Exception)
4541 SMESH::SMESH_Mesh_var mesh;
4542 SMESH_Mesh_i* mesh_i;
4544 { // open new scope to dump "MakeMesh" command
4545 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4547 TPythonDump pydump; // to prevent dump at mesh creation
4549 mesh = makeMesh( theMeshName );
4550 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4552 if ( mesh_i && theIDsOfElements.length() > 0 )
4554 TIDSortedElemSet elements;
4555 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4556 rotate(elements, theAxis, theAngleInRadians,
4557 false, theCopyGroups, & mesh_i->GetImpl());
4558 mesh_i->CreateGroupServants();
4560 if ( !myIsPreviewMode ) {
4561 pydump << mesh << " = " << this << ".RotateMakeMesh( "
4562 << theIDsOfElements << ", "
4564 << TVar( theAngleInRadians ) << ", "
4565 << theCopyGroups << ", '"
4566 << theMeshName << "' )";
4571 if (!myIsPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
4572 mesh_i->GetGroups();
4574 return mesh._retn();
4576 SMESH_CATCH( SMESH::throwCorbaException );
4580 //=======================================================================
4581 //function : RotateObjectMakeMesh
4583 //=======================================================================
4585 SMESH::SMESH_Mesh_ptr
4586 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4587 const SMESH::AxisStruct& theAxis,
4588 CORBA::Double theAngleInRadians,
4589 CORBA::Boolean theCopyGroups,
4590 const char* theMeshName)
4591 throw (SALOME::SALOME_Exception)
4594 SMESH::SMESH_Mesh_var mesh;
4595 SMESH_Mesh_i* mesh_i;
4597 {// open new scope to dump "MakeMesh" command
4598 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4600 TPythonDump pydump; // to prevent dump at mesh creation
4601 mesh = makeMesh( theMeshName );
4602 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4604 TIDSortedElemSet elements;
4605 prepareIdSource( theObject );
4607 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4609 rotate(elements, theAxis, theAngleInRadians,
4610 false, theCopyGroups, & mesh_i->GetImpl());
4611 mesh_i->CreateGroupServants();
4613 if ( !myIsPreviewMode ) {
4614 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
4615 << theObject << ", "
4617 << TVar( theAngleInRadians ) << ", "
4618 << theCopyGroups << ", '"
4619 << theMeshName << "' )";
4624 if (!myIsPreviewMode && mesh_i)
4625 mesh_i->GetGroups();
4627 return mesh._retn();
4629 SMESH_CATCH( SMESH::throwCorbaException );
4633 //=======================================================================
4636 //=======================================================================
4638 SMESH::ListOfGroups*
4639 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
4640 const SMESH::PointStruct& thePoint,
4641 const SMESH::double_array& theScaleFact,
4642 CORBA::Boolean theCopy,
4644 ::SMESH_Mesh* theTargetMesh)
4645 throw (SALOME::SALOME_Exception)
4649 if ( theScaleFact.length() < 1 )
4650 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
4651 if ( theScaleFact.length() == 2 )
4652 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
4654 if ( theTargetMesh )
4657 TIDSortedElemSet elements;
4658 prepareIdSource( theObject );
4659 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4660 if ( !idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4665 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
4666 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
4668 double tol = std::numeric_limits<double>::max();
4670 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
4671 0, S[1], 0, thePoint.y * (1-S[1]),
4672 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
4674 TIDSortedElemSet copyElements;
4675 TIDSortedElemSet* workElements = &elements;
4676 if ( myIsPreviewMode )
4678 TPreviewMesh * tmpMesh = getPreviewMesh();
4679 tmpMesh->Copy( elements, copyElements);
4680 if ( !theCopy && !theTargetMesh )
4682 TIDSortedElemSet elemsAround, elemsAroundCopy;
4683 getElementsAround( elements, getMeshDS(), elemsAround );
4684 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4686 workElements = & copyElements;
4687 theMakeGroups = false;
4690 ::SMESH_MeshEditor::PGroupIDs groupIds =
4691 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4693 if ( theCopy && !myIsPreviewMode )
4695 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
4696 else declareMeshModified( /*isReComputeSafe=*/false );
4698 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4700 SMESH_CATCH( SMESH::throwCorbaException );
4704 //=======================================================================
4707 //=======================================================================
4709 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
4710 const SMESH::PointStruct& thePoint,
4711 const SMESH::double_array& theScaleFact,
4712 CORBA::Boolean theCopy)
4713 throw (SALOME::SALOME_Exception)
4715 if ( !myIsPreviewMode ) {
4716 TPythonDump() << this << ".Scale( "
4717 << theObject << ", "
4719 << TVar( theScaleFact ) << ", "
4722 scale(theObject, thePoint, theScaleFact, theCopy, false);
4726 //=======================================================================
4727 //function : ScaleMakeGroups
4729 //=======================================================================
4731 SMESH::ListOfGroups*
4732 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4733 const SMESH::PointStruct& thePoint,
4734 const SMESH::double_array& theScaleFact)
4735 throw (SALOME::SALOME_Exception)
4737 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4739 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
4740 if (!myIsPreviewMode) {
4741 dumpGroupsList(aPythonDump, aGroups);
4742 aPythonDump << this << ".Scale("
4745 << TVar( theScaleFact ) << ",True,True)";
4751 //=======================================================================
4752 //function : ScaleMakeMesh
4754 //=======================================================================
4756 SMESH::SMESH_Mesh_ptr
4757 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4758 const SMESH::PointStruct& thePoint,
4759 const SMESH::double_array& theScaleFact,
4760 CORBA::Boolean theCopyGroups,
4761 const char* theMeshName)
4762 throw (SALOME::SALOME_Exception)
4764 SMESH_Mesh_i* mesh_i;
4765 SMESH::SMESH_Mesh_var mesh;
4766 { // open new scope to dump "MakeMesh" command
4767 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4769 TPythonDump pydump; // to prevent dump at mesh creation
4770 mesh = makeMesh( theMeshName );
4771 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4775 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
4776 mesh_i->CreateGroupServants();
4778 if ( !myIsPreviewMode )
4779 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
4780 << theObject << ", "
4782 << TVar( theScaleFact ) << ", "
4783 << theCopyGroups << ", '"
4784 << theMeshName << "' )";
4788 if (!myIsPreviewMode && mesh_i)
4789 mesh_i->GetGroups();
4791 return mesh._retn();
4795 //=======================================================================
4796 //function : FindCoincidentNodes
4798 //=======================================================================
4800 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance,
4801 SMESH::array_of_long_array_out GroupsOfNodes)
4802 throw (SALOME::SALOME_Exception)
4807 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4808 TIDSortedNodeSet nodes; // no input nodes
4809 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4811 GroupsOfNodes = new SMESH::array_of_long_array;
4812 GroupsOfNodes->length( aListOfListOfNodes.size() );
4813 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4814 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
4815 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4816 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4817 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4818 aGroup.length( aListOfNodes.size() );
4819 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4820 aGroup[ j ] = (*lIt)->GetID();
4822 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
4823 << Tolerance << " )";
4825 SMESH_CATCH( SMESH::throwCorbaException );
4828 //=======================================================================
4829 //function : FindCoincidentNodesOnPart
4831 //=======================================================================
4833 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
4834 CORBA::Double Tolerance,
4835 SMESH::array_of_long_array_out GroupsOfNodes)
4836 throw (SALOME::SALOME_Exception)
4841 TIDSortedNodeSet nodes;
4842 prepareIdSource( theObject );
4843 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4845 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4847 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4849 GroupsOfNodes = new SMESH::array_of_long_array;
4850 GroupsOfNodes->length( aListOfListOfNodes.size() );
4851 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4852 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4854 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4855 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4856 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4857 aGroup.length( aListOfNodes.size() );
4858 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4859 aGroup[ j ] = (*lIt)->GetID();
4861 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
4863 << Tolerance << " )";
4865 SMESH_CATCH( SMESH::throwCorbaException );
4868 //================================================================================
4870 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
4871 * ExceptSubMeshOrGroups
4873 //================================================================================
4875 void SMESH_MeshEditor_i::
4876 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
4877 CORBA::Double theTolerance,
4878 SMESH::array_of_long_array_out theGroupsOfNodes,
4879 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups)
4880 throw (SALOME::SALOME_Exception)
4885 TIDSortedNodeSet nodes;
4886 prepareIdSource( theObject );
4887 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4889 for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
4891 TIDSortedNodeSet exceptNodes;
4892 idSourceToNodeSet( theExceptSubMeshOrGroups[i], getMeshDS(), exceptNodes );
4893 TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
4894 for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
4895 nodes.erase( *avoidNode );
4897 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4899 getEditor().FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
4901 theGroupsOfNodes = new SMESH::array_of_long_array;
4902 theGroupsOfNodes->length( aListOfListOfNodes.size() );
4903 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4904 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4906 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4907 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4908 SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
4909 aGroup.length( aListOfNodes.size() );
4910 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4911 aGroup[ j ] = (*lIt)->GetID();
4913 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
4915 << theTolerance << ", "
4916 << theExceptSubMeshOrGroups << " )";
4918 SMESH_CATCH( SMESH::throwCorbaException );
4921 //=======================================================================
4922 //function : MergeNodes
4924 //=======================================================================
4926 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
4927 throw (SALOME::SALOME_Exception)
4932 SMESHDS_Mesh* aMesh = getMeshDS();
4934 TPythonDump aTPythonDump;
4935 aTPythonDump << this << ".MergeNodes([";
4936 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4937 for (int i = 0; i < GroupsOfNodes.length(); i++)
4939 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
4940 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
4941 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
4942 for ( int j = 0; j < aNodeGroup.length(); j++ )
4944 CORBA::Long index = aNodeGroup[ j ];
4945 const SMDS_MeshNode * node = aMesh->FindNode(index);
4947 aListOfNodes.push_back( node );
4949 if ( aListOfNodes.size() < 2 )
4950 aListOfListOfNodes.pop_back();
4952 if ( i > 0 ) aTPythonDump << ", ";
4953 aTPythonDump << aNodeGroup;
4955 getEditor().MergeNodes( aListOfListOfNodes );
4957 aTPythonDump << "])";
4959 declareMeshModified( /*isReComputeSafe=*/false );
4961 SMESH_CATCH( SMESH::throwCorbaException );
4964 //=======================================================================
4965 //function : FindEqualElements
4967 //=======================================================================
4969 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
4970 SMESH::array_of_long_array_out GroupsOfElementsID)
4971 throw (SALOME::SALOME_Exception)
4976 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
4977 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
4979 TIDSortedElemSet elems;
4980 prepareIdSource( theObject );
4981 idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true);
4983 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4984 getEditor().FindEqualElements( elems, aListOfListOfElementsID );
4986 GroupsOfElementsID = new SMESH::array_of_long_array;
4987 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
4989 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt =
4990 aListOfListOfElementsID.begin();
4991 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j)
4993 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
4994 list<int>& listOfIDs = *arraysIt;
4995 aGroup.length( listOfIDs.size() );
4996 list<int>::iterator idIt = listOfIDs.begin();
4997 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k )
4998 aGroup[ k ] = *idIt;
5001 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
5005 SMESH_CATCH( SMESH::throwCorbaException );
5008 //=======================================================================
5009 //function : MergeElements
5011 //=======================================================================
5013 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
5014 throw (SALOME::SALOME_Exception)
5019 TPythonDump aTPythonDump;
5020 aTPythonDump << this << ".MergeElements( [";
5022 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
5024 for (int i = 0; i < GroupsOfElementsID.length(); i++) {
5025 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
5026 aListOfListOfElementsID.push_back( list< int >() );
5027 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
5028 for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
5029 CORBA::Long id = anElemsIDGroup[ j ];
5030 aListOfElemsID.push_back( id );
5032 if ( aListOfElemsID.size() < 2 )
5033 aListOfListOfElementsID.pop_back();
5034 if ( i > 0 ) aTPythonDump << ", ";
5035 aTPythonDump << anElemsIDGroup;
5038 getEditor().MergeElements(aListOfListOfElementsID);
5040 declareMeshModified( /*isReComputeSafe=*/true );
5042 aTPythonDump << "] )";
5044 SMESH_CATCH( SMESH::throwCorbaException );
5047 //=======================================================================
5048 //function : MergeEqualElements
5050 //=======================================================================
5052 void SMESH_MeshEditor_i::MergeEqualElements()
5053 throw (SALOME::SALOME_Exception)
5058 getEditor().MergeEqualElements();
5060 declareMeshModified( /*isReComputeSafe=*/true );
5062 TPythonDump() << this << ".MergeEqualElements()";
5064 SMESH_CATCH( SMESH::throwCorbaException );
5067 //=============================================================================
5069 * Move the node to a given point
5071 //=============================================================================
5073 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
5077 throw (SALOME::SALOME_Exception)
5080 initData(/*deleteSearchers=*/false);
5082 const SMDS_MeshNode * node = getMeshDS()->FindNode( NodeID );
5086 if ( theNodeSearcher )
5087 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5089 if ( myIsPreviewMode ) // make preview data
5091 // in a preview mesh, make edges linked to a node
5092 TPreviewMesh& tmpMesh = *getPreviewMesh();
5093 TIDSortedElemSet linkedNodes;
5094 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
5095 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
5096 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
5097 for ( ; nIt != linkedNodes.end(); ++nIt )
5099 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
5100 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
5104 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
5105 // fill preview data
5107 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
5108 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
5110 getMeshDS()->MoveNode(node, x, y, z);
5112 if ( !myIsPreviewMode )
5114 // Update Python script
5115 TPythonDump() << "isDone = " << this << ".MoveNode( "
5116 << NodeID << ", " << TVar(x) << ", " << TVar(y) << ", " << TVar(z) << " )";
5117 declareMeshModified( /*isReComputeSafe=*/false );
5120 SMESH_CATCH( SMESH::throwCorbaException );
5125 //================================================================================
5127 * \brief Return ID of node closest to a given point
5129 //================================================================================
5131 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
5134 throw (SALOME::SALOME_Exception)
5137 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5139 if ( !theNodeSearcher ) {
5140 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
5143 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
5144 return node->GetID();
5146 SMESH_CATCH( SMESH::throwCorbaException );
5150 //================================================================================
5152 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
5153 * move the node closest to the point to point's location and return ID of the node
5155 //================================================================================
5157 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
5160 CORBA::Long theNodeID)
5161 throw (SALOME::SALOME_Exception)
5164 // We keep theNodeSearcher until any mesh modification:
5165 // 1) initData() deletes theNodeSearcher at any edition,
5166 // 2) TSearchersDeleter - at any mesh compute event and mesh change
5168 initData(/*deleteSearchers=*/false);
5170 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5172 int nodeID = theNodeID;
5173 const SMDS_MeshNode* node = getMeshDS()->FindNode( nodeID );
5174 if ( !node ) // preview moving node
5176 if ( !theNodeSearcher ) {
5177 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
5180 node = theNodeSearcher->FindClosestTo( p );
5183 nodeID = node->GetID();
5184 if ( myIsPreviewMode ) // make preview data
5186 // in a preview mesh, make edges linked to a node
5187 TPreviewMesh tmpMesh = *getPreviewMesh();
5188 TIDSortedElemSet linkedNodes;
5189 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
5190 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
5191 for ( ; nIt != linkedNodes.end(); ++nIt )
5193 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
5194 tmpMesh.Copy( &edge );
5197 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
5199 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
5200 // fill preview data
5202 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
5204 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
5208 getMeshDS()->MoveNode(node, x, y, z);
5212 if ( !myIsPreviewMode )
5214 TPythonDump() << "nodeID = " << this
5215 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
5216 << ", " << nodeID << " )";
5218 declareMeshModified( /*isReComputeSafe=*/false );
5223 SMESH_CATCH( SMESH::throwCorbaException );
5227 //=======================================================================
5229 * Return elements of given type where the given point is IN or ON.
5231 * 'ALL' type means elements of any type excluding nodes
5233 //=======================================================================
5235 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
5238 SMESH::ElementType type)
5239 throw (SALOME::SALOME_Exception)
5242 SMESH::long_array_var res = new SMESH::long_array;
5243 vector< const SMDS_MeshElement* > foundElems;
5245 theSearchersDeleter.Set( myMesh );
5246 if ( !theElementSearcher ) {
5247 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
5249 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
5250 SMDSAbs_ElementType( type ),
5252 res->length( foundElems.size() );
5253 for ( int i = 0; i < foundElems.size(); ++i )
5254 res[i] = foundElems[i]->GetID();
5256 if ( !myIsPreviewMode ) // call from tui
5257 TPythonDump() << "res = " << this << ".FindElementsByPoint( "
5265 SMESH_CATCH( SMESH::throwCorbaException );
5269 //=======================================================================
5270 //function : FindAmongElementsByPoint
5271 //purpose : Searching among the given elements, return elements of given type
5272 // where the given point is IN or ON.
5273 // 'ALL' type means elements of any type excluding nodes
5274 //=======================================================================
5277 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
5281 SMESH::ElementType type)
5282 throw (SALOME::SALOME_Exception)
5285 SMESH::long_array_var res = new SMESH::long_array;
5287 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
5288 if ( types->length() == 1 && // a part contains only nodes or 0D elements
5289 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) &&
5290 type != types[0] ) // but search of elements of dim > 0
5293 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
5294 return FindElementsByPoint( x,y,z, type );
5296 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
5298 theSearchersDeleter.Set( myMesh, getPartIOR( elementIDs, type ));
5299 if ( !theElementSearcher )
5301 // create a searcher from elementIDs
5302 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
5303 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
5305 if ( !idSourceToSet( elementIDs, meshDS, elements,
5306 SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
5309 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5310 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
5312 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt );
5315 vector< const SMDS_MeshElement* > foundElems;
5317 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
5318 SMDSAbs_ElementType( type ),
5320 res->length( foundElems.size() );
5321 for ( int i = 0; i < foundElems.size(); ++i )
5322 res[i] = foundElems[i]->GetID();
5324 if ( !myIsPreviewMode ) // call from tui
5325 TPythonDump() << "res = " << this << ".FindAmongElementsByPoint( "
5326 << elementIDs << ", "
5334 SMESH_CATCH( SMESH::throwCorbaException );
5338 //=======================================================================
5339 //function : GetPointState
5340 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
5341 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
5342 //=======================================================================
5344 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
5347 throw (SALOME::SALOME_Exception)
5350 theSearchersDeleter.Set( myMesh );
5351 if ( !theElementSearcher ) {
5352 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
5354 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
5356 SMESH_CATCH( SMESH::throwCorbaException );
5360 //=======================================================================
5361 //function : convError
5363 //=======================================================================
5365 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
5367 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
5371 RETCASE( SEW_BORDER1_NOT_FOUND );
5372 RETCASE( SEW_BORDER2_NOT_FOUND );
5373 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
5374 RETCASE( SEW_BAD_SIDE_NODES );
5375 RETCASE( SEW_VOLUMES_TO_SPLIT );
5376 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
5377 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
5378 RETCASE( SEW_BAD_SIDE1_NODES );
5379 RETCASE( SEW_BAD_SIDE2_NODES );
5381 return SMESH::SMESH_MeshEditor::SEW_OK;
5384 //=======================================================================
5385 //function : SewFreeBorders
5387 //=======================================================================
5389 SMESH::SMESH_MeshEditor::Sew_Error
5390 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
5391 CORBA::Long SecondNodeID1,
5392 CORBA::Long LastNodeID1,
5393 CORBA::Long FirstNodeID2,
5394 CORBA::Long SecondNodeID2,
5395 CORBA::Long LastNodeID2,
5396 CORBA::Boolean CreatePolygons,
5397 CORBA::Boolean CreatePolyedrs)
5398 throw (SALOME::SALOME_Exception)
5403 SMESHDS_Mesh* aMesh = getMeshDS();
5405 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
5406 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
5407 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
5408 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
5409 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
5410 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
5412 if (!aBorderFirstNode ||
5413 !aBorderSecondNode||
5415 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5416 if (!aSide2FirstNode ||
5417 !aSide2SecondNode ||
5419 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
5421 TPythonDump() << "error = " << this << ".SewFreeBorders( "
5422 << FirstNodeID1 << ", "
5423 << SecondNodeID1 << ", "
5424 << LastNodeID1 << ", "
5425 << FirstNodeID2 << ", "
5426 << SecondNodeID2 << ", "
5427 << LastNodeID2 << ", "
5428 << CreatePolygons<< ", "
5429 << CreatePolyedrs<< " )";
5431 SMESH::SMESH_MeshEditor::Sew_Error error =
5432 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5443 declareMeshModified( /*isReComputeSafe=*/false );
5446 SMESH_CATCH( SMESH::throwCorbaException );
5447 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5451 //=======================================================================
5452 //function : SewConformFreeBorders
5454 //=======================================================================
5456 SMESH::SMESH_MeshEditor::Sew_Error
5457 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
5458 CORBA::Long SecondNodeID1,
5459 CORBA::Long LastNodeID1,
5460 CORBA::Long FirstNodeID2,
5461 CORBA::Long SecondNodeID2)
5462 throw (SALOME::SALOME_Exception)
5467 SMESHDS_Mesh* aMesh = getMeshDS();
5469 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
5470 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
5471 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
5472 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
5473 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
5474 const SMDS_MeshNode* aSide2ThirdNode = 0;
5476 if (!aBorderFirstNode ||
5477 !aBorderSecondNode||
5479 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5480 if (!aSide2FirstNode ||
5482 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
5484 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
5485 << FirstNodeID1 << ", "
5486 << SecondNodeID1 << ", "
5487 << LastNodeID1 << ", "
5488 << FirstNodeID2 << ", "
5489 << SecondNodeID2 << " )";
5491 SMESH::SMESH_MeshEditor::Sew_Error error =
5492 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5501 declareMeshModified( /*isReComputeSafe=*/false );
5504 SMESH_CATCH( SMESH::throwCorbaException );
5505 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5509 //=======================================================================
5510 //function : SewBorderToSide
5512 //=======================================================================
5514 SMESH::SMESH_MeshEditor::Sew_Error
5515 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
5516 CORBA::Long SecondNodeIDOnFreeBorder,
5517 CORBA::Long LastNodeIDOnFreeBorder,
5518 CORBA::Long FirstNodeIDOnSide,
5519 CORBA::Long LastNodeIDOnSide,
5520 CORBA::Boolean CreatePolygons,
5521 CORBA::Boolean CreatePolyedrs)
5522 throw (SALOME::SALOME_Exception)
5527 SMESHDS_Mesh* aMesh = getMeshDS();
5529 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
5530 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
5531 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
5532 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
5533 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
5534 const SMDS_MeshNode* aSide2ThirdNode = 0;
5536 if (!aBorderFirstNode ||
5537 !aBorderSecondNode||
5539 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5540 if (!aSide2FirstNode ||
5542 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
5544 TPythonDump() << "error = " << this << ".SewBorderToSide( "
5545 << FirstNodeIDOnFreeBorder << ", "
5546 << SecondNodeIDOnFreeBorder << ", "
5547 << LastNodeIDOnFreeBorder << ", "
5548 << FirstNodeIDOnSide << ", "
5549 << LastNodeIDOnSide << ", "
5550 << CreatePolygons << ", "
5551 << CreatePolyedrs << ") ";
5553 SMESH::SMESH_MeshEditor::Sew_Error error =
5554 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5564 declareMeshModified( /*isReComputeSafe=*/false );
5567 SMESH_CATCH( SMESH::throwCorbaException );
5568 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5572 //=======================================================================
5573 //function : SewSideElements
5575 //=======================================================================
5577 SMESH::SMESH_MeshEditor::Sew_Error
5578 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
5579 const SMESH::long_array& IDsOfSide2Elements,
5580 CORBA::Long NodeID1OfSide1ToMerge,
5581 CORBA::Long NodeID1OfSide2ToMerge,
5582 CORBA::Long NodeID2OfSide1ToMerge,
5583 CORBA::Long NodeID2OfSide2ToMerge)
5584 throw (SALOME::SALOME_Exception)
5589 SMESHDS_Mesh* aMesh = getMeshDS();
5591 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
5592 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
5593 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
5594 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
5596 if (!aFirstNode1ToMerge ||
5597 !aFirstNode2ToMerge )
5598 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
5599 if (!aSecondNode1ToMerge||
5600 !aSecondNode2ToMerge)
5601 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
5603 TIDSortedElemSet aSide1Elems, aSide2Elems;
5604 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
5605 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
5607 TPythonDump() << "error = " << this << ".SewSideElements( "
5608 << IDsOfSide1Elements << ", "
5609 << IDsOfSide2Elements << ", "
5610 << NodeID1OfSide1ToMerge << ", "
5611 << NodeID1OfSide2ToMerge << ", "
5612 << NodeID2OfSide1ToMerge << ", "
5613 << NodeID2OfSide2ToMerge << ")";
5615 SMESH::SMESH_MeshEditor::Sew_Error error =
5616 convError( getEditor().SewSideElements (aSide1Elems, aSide2Elems,
5619 aSecondNode1ToMerge,
5620 aSecondNode2ToMerge));
5622 declareMeshModified( /*isReComputeSafe=*/false );
5625 SMESH_CATCH( SMESH::throwCorbaException );
5626 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5629 //================================================================================
5631 * \brief Set new nodes for given element
5632 * \param ide - element id
5633 * \param newIDs - new node ids
5634 * \retval CORBA::Boolean - true if result is OK
5636 //================================================================================
5638 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
5639 const SMESH::long_array& newIDs)
5640 throw (SALOME::SALOME_Exception)
5645 const SMDS_MeshElement* elem = getMeshDS()->FindElement(ide);
5646 if(!elem) return false;
5648 int nbn = newIDs.length();
5650 vector<const SMDS_MeshNode*> aNodes(nbn);
5653 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(newIDs[i]);
5656 aNodes[nbn1] = aNode;
5659 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
5660 << ide << ", " << newIDs << " )";
5662 MESSAGE("ChangeElementNodes");
5663 bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
5665 declareMeshModified( /*isReComputeSafe=*/ !res );
5669 SMESH_CATCH( SMESH::throwCorbaException );
5673 //=======================================================================
5675 * \brief Makes a part of the mesh quadratic or bi-quadratic
5677 //=======================================================================
5679 void SMESH_MeshEditor_i::convertToQuadratic(CORBA::Boolean theForce3d,
5680 CORBA::Boolean theToBiQuad,
5681 SMESH::SMESH_IDSource_ptr theObject)
5682 throw (SALOME::SALOME_Exception)
5685 TIDSortedElemSet elems;
5687 if ( !( elemsOK = CORBA::is_nil( theObject )))
5689 prepareIdSource( theObject );
5690 elemsOK = idSourceToSet( theObject, getMeshDS(), elems,
5691 SMDSAbs_All, /*emptyIfIsMesh=*/true );
5695 if ( !elems.empty() && (*elems.begin())->GetType() == SMDSAbs_Node )
5696 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5698 if ( elems.empty() ) getEditor().ConvertToQuadratic(theForce3d, theToBiQuad);
5699 else getEditor().ConvertToQuadratic(theForce3d, elems, theToBiQuad);
5701 declareMeshModified( /*isReComputeSafe=*/false );
5704 SMESH_CATCH( SMESH::throwCorbaException );
5707 //=======================================================================
5708 //function : ConvertFromQuadratic
5710 //=======================================================================
5712 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
5713 throw (SALOME::SALOME_Exception)
5715 CORBA::Boolean isDone = getEditor().ConvertFromQuadratic();
5716 TPythonDump() << this << ".ConvertFromQuadratic()";
5717 declareMeshModified( /*isReComputeSafe=*/!isDone );
5721 //=======================================================================
5722 //function : ConvertToQuadratic
5724 //=======================================================================
5726 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
5727 throw (SALOME::SALOME_Exception)
5729 convertToQuadratic( theForce3d, false );
5730 TPythonDump() << this << ".ConvertToQuadratic("<<theForce3d<<")";
5733 //================================================================================
5735 * \brief Makes a part of the mesh quadratic
5737 //================================================================================
5739 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
5740 SMESH::SMESH_IDSource_ptr theObject)
5741 throw (SALOME::SALOME_Exception)
5743 convertToQuadratic( theForce3d, false, theObject );
5744 TPythonDump() << this << ".ConvertToQuadraticObject("<<theForce3d<<", "<<theObject<<")";
5747 //================================================================================
5749 * \brief Makes a part of the mesh bi-quadratic
5751 //================================================================================
5753 void SMESH_MeshEditor_i::ConvertToBiQuadratic(CORBA::Boolean theForce3d,
5754 SMESH::SMESH_IDSource_ptr theObject)
5755 throw (SALOME::SALOME_Exception)
5757 convertToQuadratic( theForce3d, true, theObject );
5758 TPythonDump() << this << ".ConvertToBiQuadratic("<<theForce3d<<", "<<theObject<<")";
5761 //================================================================================
5763 * \brief Makes a part of the mesh linear
5765 //================================================================================
5767 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
5768 throw (SALOME::SALOME_Exception)
5774 TIDSortedElemSet elems;
5775 prepareIdSource( theObject );
5776 if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5778 if ( elems.empty() )
5780 ConvertFromQuadratic();
5782 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5784 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5788 getEditor().ConvertFromQuadratic(elems);
5791 declareMeshModified( /*isReComputeSafe=*/false );
5793 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
5795 SMESH_CATCH( SMESH::throwCorbaException );
5798 //=======================================================================
5799 //function : makeMesh
5800 //purpose : create a named imported mesh
5801 //=======================================================================
5803 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
5805 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
5806 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
5807 SALOMEDS::Study_var study = gen->GetCurrentStudy();
5808 SALOMEDS::SObject_wrap meshSO = gen->ObjectToSObject( study, mesh );
5809 gen->SetName( meshSO, theMeshName, "Mesh" );
5810 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
5812 return mesh._retn();
5815 //=======================================================================
5816 //function : dumpGroupsList
5818 //=======================================================================
5820 void SMESH_MeshEditor_i::dumpGroupsList(TPythonDump & theDumpPython,
5821 const SMESH::ListOfGroups * theGroupList)
5823 bool isDumpGroupList = ( theGroupList && theGroupList->length() > 0 );
5824 if ( isDumpGroupList )
5825 theDumpPython << theGroupList << " = ";
5828 //================================================================================
5830 \brief Generates the unique group name.
5831 \param thePrefix name prefix
5834 //================================================================================
5836 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
5838 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5839 set<string> groupNames;
5841 // Get existing group names
5842 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
5843 SMESH::SMESH_GroupBase_var aGroup = groups[i];
5844 if (CORBA::is_nil(aGroup))
5847 CORBA::String_var name = aGroup->GetName();
5848 groupNames.insert( name.in() );
5852 string name = thePrefix;
5855 while (!groupNames.insert(name).second)
5856 name = SMESH_Comment( thePrefix ) << "_" << index++;
5861 //================================================================================
5863 * \brief Prepare SMESH_IDSource for work
5865 //================================================================================
5867 void SMESH_MeshEditor_i::prepareIdSource(SMESH::SMESH_IDSource_ptr theObject)
5869 if ( SMESH::Filter_i* filter = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5871 SMESH::SMESH_Mesh_var mesh = myMesh_i->_this();
5872 filter->SetMesh( mesh );
5876 //================================================================================
5878 * \brief Duplicates given elements, i.e. creates new elements based on the
5879 * same nodes as the given ones.
5880 * \param theElements - container of elements to duplicate.
5881 * \param theGroupName - a name of group to contain the generated elements.
5882 * If a group with such a name already exists, the new elements
5883 * are added to the existng group, else a new group is created.
5884 * If \a theGroupName is empty, new elements are not added
5886 * \return a group where the new elements are added. NULL if theGroupName == "".
5889 //================================================================================
5891 SMESH::SMESH_Group_ptr
5892 SMESH_MeshEditor_i::DoubleElements(SMESH::SMESH_IDSource_ptr theElements,
5893 const char* theGroupName)
5894 throw (SALOME::SALOME_Exception)
5896 SMESH::SMESH_Group_var newGroup;
5903 TIDSortedElemSet elems;
5904 prepareIdSource( theElements );
5905 if ( idSourceToSet( theElements, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true))
5907 getEditor().DoubleElements( elems );
5909 if ( strlen( theGroupName ) && !getEditor().GetLastCreatedElems().IsEmpty() )
5912 SMESH::ElementType type =
5913 SMESH::ElementType( getEditor().GetLastCreatedElems().Value(1)->GetType() );
5914 // find existing group
5915 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5916 for ( size_t i = 0; i < groups->length(); ++i )
5917 if ( groups[i]->GetType() == type )
5919 CORBA::String_var name = groups[i]->GetName();
5920 if ( strcmp( name, theGroupName ) == 0 ) {
5921 newGroup = SMESH::SMESH_Group::_narrow( groups[i] );
5925 // create a new group
5926 if ( newGroup->_is_nil() )
5927 newGroup = myMesh_i->CreateGroup( type, theGroupName );
5929 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* >( newGroup ))
5931 SMESHDS_Group* groupDS = static_cast< SMESHDS_Group* >( group_i->GetGroupDS() );
5932 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
5933 for ( int i = 1; i <= aSeq.Length(); i++ )
5934 groupDS->SMDSGroup().Add( aSeq(i) );
5939 if ( !newGroup->_is_nil() )
5940 pyDump << newGroup << " = ";
5941 pyDump << this << ".DoubleElements( "
5942 << theElements << ", " << "'" << theGroupName <<"')";
5944 SMESH_CATCH( SMESH::throwCorbaException );
5946 return newGroup._retn();
5949 //================================================================================
5951 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5952 \param theNodes - identifiers of nodes to be doubled
5953 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
5954 nodes. If list of element identifiers is empty then nodes are doubled but
5955 they not assigned to elements
5956 \return TRUE if operation has been completed successfully, FALSE otherwise
5957 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
5959 //================================================================================
5961 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
5962 const SMESH::long_array& theModifiedElems )
5963 throw (SALOME::SALOME_Exception)
5968 list< int > aListOfNodes;
5970 for ( i = 0, n = theNodes.length(); i < n; i++ )
5971 aListOfNodes.push_back( theNodes[ i ] );
5973 list< int > aListOfElems;
5974 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5975 aListOfElems.push_back( theModifiedElems[ i ] );
5977 bool aResult = getEditor().DoubleNodes( aListOfNodes, aListOfElems );
5979 declareMeshModified( /*isReComputeSafe=*/ !aResult );
5981 // Update Python script
5982 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
5986 SMESH_CATCH( SMESH::throwCorbaException );
5990 //================================================================================
5992 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5993 This method provided for convenience works as DoubleNodes() described above.
5994 \param theNodeId - identifier of node to be doubled.
5995 \param theModifiedElems - identifiers of elements to be updated.
5996 \return TRUE if operation has been completed successfully, FALSE otherwise
5997 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
5999 //================================================================================
6001 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
6002 const SMESH::long_array& theModifiedElems )
6003 throw (SALOME::SALOME_Exception)
6006 SMESH::long_array_var aNodes = new SMESH::long_array;
6007 aNodes->length( 1 );
6008 aNodes[ 0 ] = theNodeId;
6010 TPythonDump pyDump; // suppress dump by the next line
6012 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
6014 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
6018 SMESH_CATCH( SMESH::throwCorbaException );
6022 //================================================================================
6024 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6025 This method provided for convenience works as DoubleNodes() described above.
6026 \param theNodes - group of nodes to be doubled.
6027 \param theModifiedElems - group of elements to be updated.
6028 \return TRUE if operation has been completed successfully, FALSE otherwise
6029 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
6031 //================================================================================
6033 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
6034 SMESH::SMESH_GroupBase_ptr theModifiedElems )
6035 throw (SALOME::SALOME_Exception)
6038 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
6041 SMESH::long_array_var aNodes = theNodes->GetListOfID();
6042 SMESH::long_array_var aModifiedElems;
6043 if ( !CORBA::is_nil( theModifiedElems ) )
6044 aModifiedElems = theModifiedElems->GetListOfID();
6047 aModifiedElems = new SMESH::long_array;
6048 aModifiedElems->length( 0 );
6051 TPythonDump pyDump; // suppress dump by the next line
6053 bool done = DoubleNodes( aNodes, aModifiedElems );
6055 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
6059 SMESH_CATCH( SMESH::throwCorbaException );
6063 //================================================================================
6065 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6066 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
6067 * \param theNodes - group of nodes to be doubled.
6068 * \param theModifiedElems - group of elements to be updated.
6069 * \return a new group with newly created nodes
6070 * \sa DoubleNodeGroup()
6072 //================================================================================
6074 SMESH::SMESH_Group_ptr
6075 SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
6076 SMESH::SMESH_GroupBase_ptr theModifiedElems )
6077 throw (SALOME::SALOME_Exception)
6080 SMESH::SMESH_Group_var aNewGroup;
6082 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
6083 return aNewGroup._retn();
6086 SMESH::long_array_var aNodes = theNodes->GetListOfID();
6087 SMESH::long_array_var aModifiedElems;
6088 if ( !CORBA::is_nil( theModifiedElems ) )
6089 aModifiedElems = theModifiedElems->GetListOfID();
6091 aModifiedElems = new SMESH::long_array;
6092 aModifiedElems->length( 0 );
6095 TPythonDump pyDump; // suppress dump by the next line
6097 bool aResult = DoubleNodes( aNodes, aModifiedElems );
6100 // Create group with newly created nodes
6101 SMESH::long_array_var anIds = GetLastCreatedNodes();
6102 if (anIds->length() > 0) {
6103 string anUnindexedName (theNodes->GetName());
6104 string aNewName = generateGroupName(anUnindexedName + "_double");
6105 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6106 aNewGroup->Add(anIds);
6107 pyDump << aNewGroup << " = ";
6111 pyDump << this << ".DoubleNodeGroupNew( " << theNodes << ", "
6112 << theModifiedElems << " )";
6114 return aNewGroup._retn();
6116 SMESH_CATCH( SMESH::throwCorbaException );
6120 //================================================================================
6122 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6123 This method provided for convenience works as DoubleNodes() described above.
6124 \param theNodes - list of groups of nodes to be doubled
6125 \param theModifiedElems - list of groups of elements to be updated.
6126 \return TRUE if operation has been completed successfully, FALSE otherwise
6127 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
6129 //================================================================================
6131 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
6132 const SMESH::ListOfGroups& theModifiedElems )
6133 throw (SALOME::SALOME_Exception)
6138 std::list< int > aNodes;
6140 for ( i = 0, n = theNodes.length(); i < n; i++ )
6142 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
6143 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
6145 SMESH::long_array_var aCurr = aGrp->GetListOfID();
6146 for ( j = 0, m = aCurr->length(); j < m; j++ )
6147 aNodes.push_back( aCurr[ j ] );
6151 std::list< int > anElems;
6152 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
6154 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
6155 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
6157 SMESH::long_array_var aCurr = aGrp->GetListOfID();
6158 for ( j = 0, m = aCurr->length(); j < m; j++ )
6159 anElems.push_back( aCurr[ j ] );
6163 bool aResult = getEditor().DoubleNodes( aNodes, anElems );
6165 declareMeshModified( /*isReComputeSafe=*/false );
6167 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
6171 SMESH_CATCH( SMESH::throwCorbaException );
6175 //================================================================================
6177 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6178 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
6179 * \param theNodes - group of nodes to be doubled.
6180 * \param theModifiedElems - group of elements to be updated.
6181 * \return a new group with newly created nodes
6182 * \sa DoubleNodeGroups()
6184 //================================================================================
6186 SMESH::SMESH_Group_ptr
6187 SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
6188 const SMESH::ListOfGroups& theModifiedElems )
6189 throw (SALOME::SALOME_Exception)
6191 SMESH::SMESH_Group_var aNewGroup;
6193 TPythonDump pyDump; // suppress dump by the next line
6195 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
6199 // Create group with newly created nodes
6200 SMESH::long_array_var anIds = GetLastCreatedNodes();
6201 if (anIds->length() > 0) {
6202 string anUnindexedName (theNodes[0]->GetName());
6203 string aNewName = generateGroupName(anUnindexedName + "_double");
6204 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6205 aNewGroup->Add(anIds);
6206 pyDump << aNewGroup << " = ";
6210 pyDump << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
6211 << theModifiedElems << " )";
6213 return aNewGroup._retn();
6217 //================================================================================
6219 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6220 \param theElems - the list of elements (edges or faces) to be replicated
6221 The nodes for duplication could be found from these elements
6222 \param theNodesNot - list of nodes to NOT replicate
6223 \param theAffectedElems - the list of elements (cells and edges) to which the
6224 replicated nodes should be associated to.
6225 \return TRUE if operation has been completed successfully, FALSE otherwise
6226 \sa DoubleNodeGroup(), DoubleNodeGroups()
6228 //================================================================================
6230 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
6231 const SMESH::long_array& theNodesNot,
6232 const SMESH::long_array& theAffectedElems )
6233 throw (SALOME::SALOME_Exception)
6238 SMESHDS_Mesh* aMeshDS = getMeshDS();
6239 TIDSortedElemSet anElems, aNodes, anAffected;
6240 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
6241 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
6242 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
6244 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6246 // Update Python script
6247 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
6248 << theNodesNot << ", " << theAffectedElems << " )";
6250 declareMeshModified( /*isReComputeSafe=*/false );
6253 SMESH_CATCH( SMESH::throwCorbaException );
6257 //================================================================================
6259 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6260 \param theElems - the list of elements (edges or faces) to be replicated
6261 The nodes for duplication could be found from these elements
6262 \param theNodesNot - list of nodes to NOT replicate
6263 \param theShape - shape to detect affected elements (element which geometric center
6264 located on or inside shape).
6265 The replicated nodes should be associated to affected elements.
6266 \return TRUE if operation has been completed successfully, FALSE otherwise
6267 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
6269 //================================================================================
6271 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
6272 const SMESH::long_array& theNodesNot,
6273 GEOM::GEOM_Object_ptr theShape )
6274 throw (SALOME::SALOME_Exception)
6280 SMESHDS_Mesh* aMeshDS = getMeshDS();
6281 TIDSortedElemSet anElems, aNodes;
6282 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
6283 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
6285 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6286 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6288 // Update Python script
6289 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
6290 << theNodesNot << ", " << theShape << " )";
6292 declareMeshModified( /*isReComputeSafe=*/false );
6295 SMESH_CATCH( SMESH::throwCorbaException );
6299 //================================================================================
6301 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6302 \param theElems - group of of elements (edges or faces) to be replicated
6303 \param theNodesNot - group of nodes not to replicated
6304 \param theAffectedElems - group of elements to which the replicated nodes
6305 should be associated to.
6306 \return TRUE if operation has been completed successfully, FALSE otherwise
6307 \sa DoubleNodes(), DoubleNodeGroups()
6309 //================================================================================
6312 SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
6313 SMESH::SMESH_GroupBase_ptr theNodesNot,
6314 SMESH::SMESH_GroupBase_ptr theAffectedElems)
6315 throw (SALOME::SALOME_Exception)
6318 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6324 SMESHDS_Mesh* aMeshDS = getMeshDS();
6325 TIDSortedElemSet anElems, aNodes, anAffected;
6326 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6327 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6328 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
6330 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6332 // Update Python script
6333 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
6334 << theNodesNot << ", " << theAffectedElems << " )";
6336 declareMeshModified( /*isReComputeSafe=*/false );
6339 SMESH_CATCH( SMESH::throwCorbaException );
6343 //================================================================================
6345 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6346 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
6347 * \param theElems - group of of elements (edges or faces) to be replicated
6348 * \param theNodesNot - group of nodes not to replicated
6349 * \param theAffectedElems - group of elements to which the replicated nodes
6350 * should be associated to.
6351 * \return a new group with newly created elements
6352 * \sa DoubleNodeElemGroup()
6354 //================================================================================
6356 SMESH::SMESH_Group_ptr
6357 SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
6358 SMESH::SMESH_GroupBase_ptr theNodesNot,
6359 SMESH::SMESH_GroupBase_ptr theAffectedElems)
6360 throw (SALOME::SALOME_Exception)
6363 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroup2New( theElems,
6367 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
6368 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
6370 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupNew( "
6372 << theNodesNot << ", "
6373 << theAffectedElems << " )";
6375 return elemGroup._retn();
6378 //================================================================================
6380 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6381 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
6382 * \param theElems - group of of elements (edges or faces) to be replicated
6383 * \param theNodesNot - group of nodes not to replicated
6384 * \param theAffectedElems - group of elements to which the replicated nodes
6385 * should be associated to.
6386 * \return a new group with newly created elements
6387 * \sa DoubleNodeElemGroup()
6389 //================================================================================
6391 SMESH::ListOfGroups*
6392 SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
6393 SMESH::SMESH_GroupBase_ptr theNodesNot,
6394 SMESH::SMESH_GroupBase_ptr theAffectedElems,
6395 CORBA::Boolean theElemGroupNeeded,
6396 CORBA::Boolean theNodeGroupNeeded)
6397 throw (SALOME::SALOME_Exception)
6400 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
6401 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
6402 aTwoGroups->length( 2 );
6404 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6405 return aTwoGroups._retn();
6410 SMESHDS_Mesh* aMeshDS = getMeshDS();
6411 TIDSortedElemSet anElems, aNodes, anAffected;
6412 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6413 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6414 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
6417 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6419 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6425 // Create group with newly created elements
6426 CORBA::String_var elemGroupName = theElems->GetName();
6427 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
6428 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
6430 SMESH::long_array_var anIds = GetLastCreatedElems();
6431 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
6432 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
6433 aNewElemGroup->Add(anIds);
6435 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
6437 SMESH::long_array_var anIds = GetLastCreatedNodes();
6438 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6439 aNewNodeGroup->Add(anIds);
6443 // Update Python script
6446 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
6447 else pyDump << aNewElemGroup << ", ";
6448 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
6449 else pyDump << aNewNodeGroup << " ] = ";
6451 pyDump << this << ".DoubleNodeElemGroup2New( " << theElems << ", "
6452 << theNodesNot << ", "
6453 << theAffectedElems << ", "
6454 << theElemGroupNeeded << ", "
6455 << theNodeGroupNeeded <<" )";
6457 aTwoGroups[0] = aNewElemGroup._retn();
6458 aTwoGroups[1] = aNewNodeGroup._retn();
6459 return aTwoGroups._retn();
6461 SMESH_CATCH( SMESH::throwCorbaException );
6465 //================================================================================
6467 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6468 \param theElems - group of of elements (edges or faces) to be replicated
6469 \param theNodesNot - group of nodes not to replicated
6470 \param theShape - shape to detect affected elements (element which geometric center
6471 located on or inside shape).
6472 The replicated nodes should be associated to affected elements.
6473 \return TRUE if operation has been completed successfully, FALSE otherwise
6474 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
6476 //================================================================================
6479 SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
6480 SMESH::SMESH_GroupBase_ptr theNodesNot,
6481 GEOM::GEOM_Object_ptr theShape )
6482 throw (SALOME::SALOME_Exception)
6485 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6491 SMESHDS_Mesh* aMeshDS = getMeshDS();
6492 TIDSortedElemSet anElems, aNodes, anAffected;
6493 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6494 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6496 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6497 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6500 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6502 // Update Python script
6503 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
6504 << theNodesNot << ", " << theShape << " )";
6507 SMESH_CATCH( SMESH::throwCorbaException );
6511 //================================================================================
6513 * \brief Re-load elements from a list of groups into a TIDSortedElemSet
6514 * \param [in] theGrpList - groups
6515 * \param [in] theMeshDS - mesh
6516 * \param [out] theElemSet - set of elements
6517 * \param [in] theIsNodeGrp - is \a theGrpList includes goups of nodes
6519 //================================================================================
6521 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
6522 SMESHDS_Mesh* theMeshDS,
6523 TIDSortedElemSet& theElemSet,
6524 const bool theIsNodeGrp)
6526 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
6528 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
6529 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
6530 : aGrp->GetType() != SMESH::NODE ) )
6532 SMESH::long_array_var anIDs = aGrp->GetIDs();
6533 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
6538 //================================================================================
6540 \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6541 This method provided for convenience works as DoubleNodes() described above.
6542 \param theElems - list of groups of elements (edges or faces) to be replicated
6543 \param theNodesNot - list of groups of nodes not to replicated
6544 \param theAffectedElems - group of elements to which the replicated nodes
6545 should be associated to.
6546 \return TRUE if operation has been completed successfully, FALSE otherwise
6547 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
6549 //================================================================================
6552 SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
6553 const SMESH::ListOfGroups& theNodesNot,
6554 const SMESH::ListOfGroups& theAffectedElems)
6555 throw (SALOME::SALOME_Exception)
6561 SMESHDS_Mesh* aMeshDS = getMeshDS();
6562 TIDSortedElemSet anElems, aNodes, anAffected;
6563 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6564 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6565 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6567 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6569 // Update Python script
6570 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
6571 << &theNodesNot << ", " << &theAffectedElems << " )";
6573 declareMeshModified( /*isReComputeSafe=*/false );
6576 SMESH_CATCH( SMESH::throwCorbaException );
6580 //================================================================================
6582 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6583 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6584 \param theElems - list of groups of elements (edges or faces) to be replicated
6585 \param theNodesNot - list of groups of nodes not to replicated
6586 \param theAffectedElems - group of elements to which the replicated nodes
6587 should be associated to.
6588 * \return a new group with newly created elements
6589 * \sa DoubleNodeElemGroups()
6591 //================================================================================
6593 SMESH::SMESH_Group_ptr
6594 SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
6595 const SMESH::ListOfGroups& theNodesNot,
6596 const SMESH::ListOfGroups& theAffectedElems)
6597 throw (SALOME::SALOME_Exception)
6600 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroups2New( theElems,
6604 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
6605 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
6607 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupsNew( "
6609 << theNodesNot << ", "
6610 << theAffectedElems << " )";
6612 return elemGroup._retn();
6615 //================================================================================
6617 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6618 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6619 \param theElems - list of groups of elements (edges or faces) to be replicated
6620 \param theNodesNot - list of groups of nodes not to replicated
6621 \param theAffectedElems - group of elements to which the replicated nodes
6622 should be associated to.
6623 * \return a new group with newly created elements
6624 * \sa DoubleNodeElemGroups()
6626 //================================================================================
6628 SMESH::ListOfGroups*
6629 SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems,
6630 const SMESH::ListOfGroups& theNodesNot,
6631 const SMESH::ListOfGroups& theAffectedElems,
6632 CORBA::Boolean theElemGroupNeeded,
6633 CORBA::Boolean theNodeGroupNeeded)
6634 throw (SALOME::SALOME_Exception)
6637 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
6638 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
6639 aTwoGroups->length( 2 );
6644 SMESHDS_Mesh* aMeshDS = getMeshDS();
6645 TIDSortedElemSet anElems, aNodes, anAffected;
6646 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6647 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6648 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6650 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6652 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6657 // Create group with newly created elements
6658 CORBA::String_var elemGroupName = theElems[0]->GetName();
6659 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
6660 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
6662 SMESH::long_array_var anIds = GetLastCreatedElems();
6663 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
6664 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
6665 aNewElemGroup->Add(anIds);
6667 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
6669 SMESH::long_array_var anIds = GetLastCreatedNodes();
6670 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6671 aNewNodeGroup->Add(anIds);
6675 // Update Python script
6678 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
6679 else pyDump << aNewElemGroup << ", ";
6680 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
6681 else pyDump << aNewNodeGroup << " ] = ";
6683 pyDump << this << ".DoubleNodeElemGroups2New( " << &theElems << ", "
6684 << &theNodesNot << ", "
6685 << &theAffectedElems << ", "
6686 << theElemGroupNeeded << ", "
6687 << theNodeGroupNeeded << " )";
6689 aTwoGroups[0] = aNewElemGroup._retn();
6690 aTwoGroups[1] = aNewNodeGroup._retn();
6691 return aTwoGroups._retn();
6693 SMESH_CATCH( SMESH::throwCorbaException );
6697 //================================================================================
6699 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6700 This method provided for convenience works as DoubleNodes() described above.
6701 \param theElems - list of groups of elements (edges or faces) to be replicated
6702 \param theNodesNot - list of groups of nodes not to replicated
6703 \param theShape - shape to detect affected elements (element which geometric center
6704 located on or inside shape).
6705 The replicated nodes should be associated to affected elements.
6706 \return TRUE if operation has been completed successfully, FALSE otherwise
6707 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
6709 //================================================================================
6712 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
6713 const SMESH::ListOfGroups& theNodesNot,
6714 GEOM::GEOM_Object_ptr theShape )
6715 throw (SALOME::SALOME_Exception)
6721 SMESHDS_Mesh* aMeshDS = getMeshDS();
6722 TIDSortedElemSet anElems, aNodes;
6723 listOfGroupToSet(theElems, aMeshDS, anElems,false );
6724 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6726 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6727 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6729 // Update Python script
6730 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
6731 << &theNodesNot << ", " << theShape << " )";
6733 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6736 SMESH_CATCH( SMESH::throwCorbaException );
6740 //================================================================================
6742 \brief Identify the elements that will be affected by node duplication (actual
6743 duplication is not performed.
6744 This method is the first step of DoubleNodeElemGroupsInRegion.
6745 \param theElems - list of groups of elements (edges or faces) to be replicated
6746 \param theNodesNot - list of groups of nodes not to replicated
6747 \param theShape - shape to detect affected elements (element which geometric center
6748 located on or inside shape).
6749 The replicated nodes should be associated to affected elements.
6750 \return groups of affected elements
6751 \sa DoubleNodeElemGroupsInRegion()
6753 //================================================================================
6754 SMESH::ListOfGroups*
6755 SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theElems,
6756 const SMESH::ListOfGroups& theNodesNot,
6757 GEOM::GEOM_Object_ptr theShape )
6758 throw (SALOME::SALOME_Exception)
6761 MESSAGE("AffectedElemGroupsInRegion");
6762 SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
6763 bool isEdgeGroup = false;
6764 bool isFaceGroup = false;
6765 bool isVolumeGroup = false;
6766 SMESH::SMESH_Group_var aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE, "affectedEdges");
6767 SMESH::SMESH_Group_var aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE, "affectedFaces");
6768 SMESH::SMESH_Group_var aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME, "affectedVolumes");
6772 ::SMESH_MeshEditor aMeshEditor(myMesh);
6774 SMESHDS_Mesh* aMeshDS = getMeshDS();
6775 TIDSortedElemSet anElems, aNodes;
6776 listOfGroupToSet(theElems, aMeshDS, anElems, false);
6777 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true);
6779 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape(theShape);
6780 TIDSortedElemSet anAffected;
6781 bool aResult = aMeshEditor.AffectedElemGroupsInRegion(anElems, aNodes, aShape, anAffected);
6784 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6789 int lg = anAffected.size();
6790 MESSAGE("lg="<< lg);
6791 SMESH::long_array_var volumeIds = new SMESH::long_array;
6792 volumeIds->length(lg);
6793 SMESH::long_array_var faceIds = new SMESH::long_array;
6794 faceIds->length(lg);
6795 SMESH::long_array_var edgeIds = new SMESH::long_array;
6796 edgeIds->length(lg);
6801 TIDSortedElemSet::const_iterator eIt = anAffected.begin();
6802 for (; eIt != anAffected.end(); ++eIt)
6804 const SMDS_MeshElement* anElem = *eIt;
6807 int elemId = anElem->GetID();
6808 if (myMesh->GetElementType(elemId, true) == SMDSAbs_Volume)
6809 volumeIds[ivol++] = elemId;
6810 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Face)
6811 faceIds[iface++] = elemId;
6812 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Edge)
6813 edgeIds[iedge++] = elemId;
6815 volumeIds->length(ivol);
6816 faceIds->length(iface);
6817 edgeIds->length(iedge);
6819 aNewVolumeGroup->Add(volumeIds);
6820 aNewFaceGroup->Add(faceIds);
6821 aNewEdgeGroup->Add(edgeIds);
6822 isVolumeGroup = (aNewVolumeGroup->Size() > 0);
6823 isFaceGroup = (aNewFaceGroup->Size() > 0);
6824 isEdgeGroup = (aNewEdgeGroup->Size() > 0);
6828 if (isEdgeGroup) nbGroups++;
6829 if (isFaceGroup) nbGroups++;
6830 if (isVolumeGroup) nbGroups++;
6831 aListOfGroups->length(nbGroups);
6834 if (isEdgeGroup) aListOfGroups[i++] = aNewEdgeGroup._retn();
6835 if (isFaceGroup) aListOfGroups[i++] = aNewFaceGroup._retn();
6836 if (isVolumeGroup) aListOfGroups[i++] = aNewVolumeGroup._retn();
6838 // Update Python script
6841 if (isEdgeGroup) pyDump << aNewEdgeGroup << ", ";
6842 if (isFaceGroup) pyDump << aNewFaceGroup << ", ";
6843 if (isVolumeGroup) pyDump << aNewVolumeGroup << ", ";
6845 pyDump << this << ".AffectedElemGroupsInRegion( "
6846 << &theElems << ", " << &theNodesNot << ", " << theShape << " )";
6848 return aListOfGroups._retn();
6850 SMESH_CATCH( SMESH::throwCorbaException );
6854 //================================================================================
6856 \brief Generated skin mesh (containing 2D cells) from 3D mesh
6857 The created 2D mesh elements based on nodes of free faces of boundary volumes
6858 \return TRUE if operation has been completed successfully, FALSE otherwise
6860 //================================================================================
6862 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
6863 throw (SALOME::SALOME_Exception)
6868 bool aResult = getEditor().Make2DMeshFrom3D();
6870 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
6872 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6875 SMESH_CATCH( SMESH::throwCorbaException );
6879 //================================================================================
6881 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
6882 * The list of groups must contain at least two groups. The groups have to be disjoint:
6883 * no common element into two different groups.
6884 * The nodes of the internal faces at the boundaries of the groups are doubled.
6885 * Optionally, the internal faces are replaced by flat elements.
6886 * Triangles are transformed into prisms, and quadrangles into hexahedrons.
6887 * The flat elements are stored in groups of volumes.
6888 * These groups are named according to the position of the group in the list:
6889 * the group j_n_p is the group of the flat elements that are built between the group #n and the group #p in the list.
6890 * If there is no shared faces between the group #n and the group #p in the list, the group j_n_p is not created.
6891 * All the flat elements are gathered into the group named "joints3D" (or "joints2D" in 2D situation).
6892 * The flat element of the multiple junctions between the simple junction are stored in a group named "jointsMultiples".
6893 * @param theDomains - list of groups of volumes
6894 * @param createJointElems - if TRUE, create the elements
6895 * @return TRUE if operation has been completed successfully, FALSE otherwise
6897 //================================================================================
6900 SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
6901 CORBA::Boolean createJointElems )
6902 throw (SALOME::SALOME_Exception)
6904 bool aResult = false;
6909 SMESHDS_Mesh* aMeshDS = getMeshDS();
6911 // MESSAGE("theDomains.length = "<<theDomains.length());
6912 if ( theDomains.length() <= 1 )
6913 THROW_SALOME_CORBA_EXCEPTION("At least 2 groups are required.", SALOME::BAD_PARAM);
6914 vector<TIDSortedElemSet> domains;
6917 for ( int i = 0, n = theDomains.length(); i < n; i++ )
6919 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
6920 if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
6922 // if ( aGrp->GetType() != SMESH::VOLUME )
6923 // THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
6924 TIDSortedElemSet domain;
6926 domains.push_back(domain);
6927 SMESH::long_array_var anIDs = aGrp->GetIDs();
6928 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
6932 aResult = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems );
6933 // TODO publish the groups of flat elements in study
6935 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6937 // Update Python script
6938 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
6939 << ", " << createJointElems << " )";
6941 SMESH_CATCH( SMESH::throwCorbaException );
6946 //================================================================================
6948 * \brief Double nodes on some external faces and create flat elements.
6949 * Flat elements are mainly used by some types of mechanic calculations.
6951 * Each group of the list must be constituted of faces.
6952 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
6953 * @param theGroupsOfFaces - list of groups of faces
6954 * @return TRUE if operation has been completed successfully, FALSE otherwise
6956 //================================================================================
6959 SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
6960 throw (SALOME::SALOME_Exception)
6965 SMESHDS_Mesh* aMeshDS = getMeshDS();
6967 vector<TIDSortedElemSet> faceGroups;
6970 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
6972 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
6973 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
6975 TIDSortedElemSet faceGroup;
6977 faceGroups.push_back(faceGroup);
6978 SMESH::long_array_var anIDs = aGrp->GetIDs();
6979 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
6983 bool aResult = getEditor().CreateFlatElementsOnFacesGroups( faceGroups );
6984 // TODO publish the groups of flat elements in study
6986 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6988 // Update Python script
6989 TPythonDump() << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
6992 SMESH_CATCH( SMESH::throwCorbaException );
6996 //================================================================================
6998 * \brief Identify all the elements around a geom shape, get the faces delimiting
7001 * Build groups of volume to remove, groups of faces to replace on the skin of the
7002 * object, groups of faces to remove inside the object, (idem edges).
7003 * Build ordered list of nodes at the border of each group of faces to replace
7004 * (to be used to build a geom subshape).
7006 //================================================================================
7008 void SMESH_MeshEditor_i::CreateHoleSkin(CORBA::Double radius,
7009 GEOM::GEOM_Object_ptr theShape,
7010 const char* groupName,
7011 const SMESH::double_array& theNodesCoords,
7012 SMESH::array_of_long_array_out GroupsOfNodes)
7013 throw (SALOME::SALOME_Exception)
7018 std::vector<std::vector<int> > aListOfListOfNodes;
7019 ::SMESH_MeshEditor aMeshEditor( myMesh );
7021 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
7022 if ( !theNodeSearcher )
7023 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
7025 vector<double> nodesCoords;
7026 for (int i = 0; i < theNodesCoords.length(); i++)
7028 nodesCoords.push_back( theNodesCoords[i] );
7031 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
7032 aMeshEditor.CreateHoleSkin(radius, aShape, theNodeSearcher, groupName,
7033 nodesCoords, aListOfListOfNodes);
7035 GroupsOfNodes = new SMESH::array_of_long_array;
7036 GroupsOfNodes->length( aListOfListOfNodes.size() );
7037 std::vector<std::vector<int> >::iterator llIt = aListOfListOfNodes.begin();
7038 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
7040 vector<int>& aListOfNodes = *llIt;
7041 vector<int>::iterator lIt = aListOfNodes.begin();;
7042 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
7043 aGroup.length( aListOfNodes.size() );
7044 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
7045 aGroup[ j ] = (*lIt);
7047 TPythonDump() << "lists_nodes = " << this << ".CreateHoleSkin( "
7050 << ", '" << groupName << "', "
7051 << theNodesCoords << " )";
7053 SMESH_CATCH( SMESH::throwCorbaException );
7056 // issue 20749 ===================================================================
7058 * \brief Creates missing boundary elements
7059 * \param elements - elements whose boundary is to be checked
7060 * \param dimension - defines type of boundary elements to create
7061 * \param groupName - a name of group to store created boundary elements in,
7062 * "" means not to create the group
7063 * \param meshName - a name of new mesh to store created boundary elements in,
7064 * "" means not to create the new mesh
7065 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
7066 * \param toCopyExistingBondary - if true, not only new but also pre-existing
7067 * boundary elements will be copied into the new mesh
7068 * \param group - returns the create group, if any
7069 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
7071 // ================================================================================
7073 SMESH::SMESH_Mesh_ptr
7074 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
7075 SMESH::Bnd_Dimension dim,
7076 const char* groupName,
7077 const char* meshName,
7078 CORBA::Boolean toCopyElements,
7079 CORBA::Boolean toCopyExistingBondary,
7080 SMESH::SMESH_Group_out group)
7081 throw (SALOME::SALOME_Exception)
7086 if ( dim > SMESH::BND_1DFROM2D )
7087 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
7089 SMESHDS_Mesh* aMeshDS = getMeshDS();
7091 SMESH::SMESH_Mesh_var mesh_var;
7092 SMESH::SMESH_Group_var group_var;
7096 TIDSortedElemSet elements;
7097 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
7098 prepareIdSource( idSource );
7099 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
7103 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
7104 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
7106 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
7108 // group of new boundary elements
7109 SMESH_Group* smesh_group = 0;
7110 if ( strlen(groupName) )
7112 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
7113 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
7114 smesh_group = group_i->GetSmeshGroup();
7118 getEditor().MakeBoundaryMesh( elements,
7119 ::SMESH_MeshEditor::Bnd_Dimension(dim),
7123 toCopyExistingBondary);
7126 smesh_mesh->GetMeshDS()->Modified();
7129 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
7131 // result of MakeBoundaryMesh() is a tuple (mesh, group)
7132 if ( mesh_var->_is_nil() )
7133 pyDump << myMesh_i->_this() << ", ";
7135 pyDump << mesh_var << ", ";
7136 if ( group_var->_is_nil() )
7137 pyDump << "_NoneGroup = "; // assignment to None is forbiden
7139 pyDump << group_var << " = ";
7140 pyDump << this << ".MakeBoundaryMesh( "
7142 << "SMESH." << dimName[int(dim)] << ", "
7143 << "'" << groupName << "', "
7144 << "'" << meshName<< "', "
7145 << toCopyElements << ", "
7146 << toCopyExistingBondary << ")";
7148 group = group_var._retn();
7149 return mesh_var._retn();
7151 SMESH_CATCH( SMESH::throwCorbaException );
7152 return SMESH::SMESH_Mesh::_nil();
7155 //================================================================================
7157 * \brief Creates missing boundary elements
7158 * \param dimension - defines type of boundary elements to create
7159 * \param groupName - a name of group to store all boundary elements in,
7160 * "" means not to create the group
7161 * \param meshName - a name of a new mesh, which is a copy of the initial
7162 * mesh + created boundary elements; "" means not to create the new mesh
7163 * \param toCopyAll - if true, the whole initial mesh will be copied into
7164 * the new mesh else only boundary elements will be copied into the new mesh
7165 * \param groups - optional groups of elements to make boundary around
7166 * \param mesh - returns the mesh where elements were added to
7167 * \param group - returns the created group, if any
7168 * \retval long - number of added boundary elements
7170 //================================================================================
7172 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
7173 const char* groupName,
7174 const char* meshName,
7175 CORBA::Boolean toCopyAll,
7176 const SMESH::ListOfIDSources& groups,
7177 SMESH::SMESH_Mesh_out mesh,
7178 SMESH::SMESH_Group_out group)
7179 throw (SALOME::SALOME_Exception)
7184 if ( dim > SMESH::BND_1DFROM2D )
7185 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
7187 // separate groups belonging to this and other mesh
7188 SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
7189 SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
7190 groupsOfThisMesh->length( groups.length() );
7191 groupsOfOtherMesh->length( groups.length() );
7192 int nbGroups = 0, nbGroupsOfOtherMesh = 0;
7193 for ( int i = 0; i < groups.length(); ++i )
7195 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
7196 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
7197 groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
7199 groupsOfThisMesh[ nbGroups++ ] = groups[i];
7200 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
7201 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
7203 groupsOfThisMesh->length( nbGroups );
7204 groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
7209 if ( nbGroupsOfOtherMesh > 0 )
7211 // process groups belonging to another mesh
7212 SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
7213 SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
7214 nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
7215 groupsOfOtherMesh, mesh, group );
7218 SMESH::SMESH_Mesh_var mesh_var;
7219 SMESH::SMESH_Group_var group_var;
7222 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
7223 const bool toCopyMesh = ( strlen( meshName ) > 0 );
7227 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
7229 /*toCopyGroups=*/false,
7230 /*toKeepIDs=*/true);
7232 mesh_var = makeMesh(meshName);
7234 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
7235 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
7238 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
7239 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
7241 // group of boundary elements
7242 SMESH_Group* smesh_group = 0;
7243 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
7244 if ( strlen(groupName) )
7246 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
7247 group_var = mesh_i->CreateGroup( groupType, groupName );
7248 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
7249 smesh_group = group_i->GetSmeshGroup();
7252 TIDSortedElemSet elements;
7254 if ( groups.length() > 0 )
7256 for ( int i = 0; i < nbGroups; ++i )
7259 if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
7261 SMESH::Bnd_Dimension bdim =
7262 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
7263 nbAdded += getEditor().MakeBoundaryMesh( elements,
7264 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
7267 /*toCopyElements=*/false,
7268 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
7269 /*toAddExistingBondary=*/true,
7270 /*aroundElements=*/true);
7276 nbAdded += getEditor().MakeBoundaryMesh( elements,
7277 ::SMESH_MeshEditor::Bnd_Dimension(dim),
7280 /*toCopyElements=*/false,
7281 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
7282 /*toAddExistingBondary=*/true);
7284 tgtMesh->GetMeshDS()->Modified();
7286 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
7288 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
7289 pyDump << "nbAdded, ";
7290 if ( mesh_var->_is_nil() )
7291 pyDump << myMesh_i->_this() << ", ";
7293 pyDump << mesh_var << ", ";
7294 if ( group_var->_is_nil() )
7295 pyDump << "_NoneGroup = "; // assignment to None is forbiden
7297 pyDump << group_var << " = ";
7298 pyDump << this << ".MakeBoundaryElements( "
7299 << "SMESH." << dimName[int(dim)] << ", "
7300 << "'" << groupName << "', "
7301 << "'" << meshName<< "', "
7302 << toCopyAll << ", "
7305 mesh = mesh_var._retn();
7306 group = group_var._retn();
7309 SMESH_CATCH( SMESH::throwCorbaException );