1 // Copyright (C) 2007-2014 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, or (at your option) any later version.
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>
67 #include <Basics_OCCTVersion.hxx>
69 #include <BRepAdaptor_Surface.hxx>
70 #include <BRep_Tool.hxx>
71 #include <TopExp_Explorer.hxx>
73 #include <TopoDS_Edge.hxx>
74 #include <TopoDS_Face.hxx>
79 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
83 #include <Standard_Failure.hxx>
86 #include <Standard_ErrorHandler.hxx>
92 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
94 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
97 using SMESH::TPythonDump;
100 namespace MeshEditor_I {
102 //=============================================================================
104 * \brief Mesh to apply modifications for preview purposes
106 //=============================================================================
108 struct TPreviewMesh: public SMESH_Mesh
110 SMDSAbs_ElementType myPreviewType; // type to show
112 TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
113 _isShapeToMesh = (_id =_studyId = 0);
114 _myMeshDS = new SMESHDS_Mesh( _id, true );
115 myPreviewType = previewElements;
118 virtual ~TPreviewMesh() { delete _myMeshDS; _myMeshDS = 0; }
119 //!< Copy a set of elements
120 void Copy(const TIDSortedElemSet & theElements,
121 TIDSortedElemSet& theCopyElements,
122 SMDSAbs_ElementType theSelectType = SMDSAbs_All,
123 SMDSAbs_ElementType theAvoidType = SMDSAbs_All)
125 // loop on theIDsOfElements
126 TIDSortedElemSet::const_iterator eIt = theElements.begin();
127 for ( ; eIt != theElements.end(); ++eIt )
129 const SMDS_MeshElement* anElem = *eIt;
130 if ( !anElem ) continue;
131 SMDSAbs_ElementType type = anElem->GetType();
132 if ( type == theAvoidType ||
133 ( theSelectType != SMDSAbs_All && type != theSelectType ))
135 const SMDS_MeshElement* anElemCopy;
136 if ( type == SMDSAbs_Node)
137 anElemCopy = Copy( cast2Node(anElem) );
139 anElemCopy = Copy( anElem );
141 theCopyElements.insert( theCopyElements.end(), anElemCopy );
145 SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
147 // copy element nodes
148 int anElemNbNodes = anElem->NbNodes();
149 vector< int > anElemNodesID( anElemNbNodes ) ;
150 SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
151 for ( int i = 0; itElemNodes->more(); i++)
153 const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
155 anElemNodesID[i] = anElemNode->GetID();
158 // creates a corresponding element on copied nodes
159 SMDS_MeshElement* anElemCopy = 0;
160 if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
162 const SMDS_VtkVolume* ph =
163 dynamic_cast<const SMDS_VtkVolume*> (anElem);
165 anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
166 (anElemNodesID, ph->GetQuantities(),anElem->GetID());
169 anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
176 SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
178 return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(),
179 anElemNode->GetID());
183 GetMeshDS()->ClearMesh();
185 };// struct TPreviewMesh
187 static SMESH_NodeSearcher * theNodeSearcher = 0;
188 static SMESH_ElementSearcher * theElementSearcher = 0;
190 //=============================================================================
192 * \brief Deleter of theNodeSearcher at any compute event occured
194 //=============================================================================
196 struct TSearchersDeleter : public SMESH_subMeshEventListener
199 string myMeshPartIOR;
201 TSearchersDeleter(): SMESH_subMeshEventListener( false, // won't be deleted by submesh
202 "SMESH_MeshEditor_i::TSearchersDeleter"),
204 //!< Delete theNodeSearcher
207 if ( theNodeSearcher ) delete theNodeSearcher; theNodeSearcher = 0;
208 if ( theElementSearcher ) delete theElementSearcher; theElementSearcher = 0;
210 typedef map < int, SMESH_subMesh * > TDependsOnMap;
211 //!< The meshod called by submesh: do my main job
212 void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
213 SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
215 if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
217 Unset( sm->GetFather() );
220 //!< set self on all submeshes and delete theNodeSearcher if other mesh is set
221 void Set(SMESH_Mesh* mesh, const string& meshPartIOR = string())
223 if ( myMesh != mesh || myMeshPartIOR != meshPartIOR)
230 myMeshPartIOR = meshPartIOR;
231 SMESH_subMesh* sm = mesh->GetSubMesh( mesh->GetShapeToMesh() );
232 SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true );
233 while ( smIt->more() )
236 sm->SetEventListener( this, 0, sm );
240 //!< delete self from all submeshes
241 void Unset(SMESH_Mesh* mesh)
243 if ( SMESH_subMesh* sm = mesh->GetSubMeshContaining(1) ) {
244 SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true );
245 while ( smIt->more() )
246 smIt->next()->DeleteEventListener( this );
251 } theSearchersDeleter;
253 TCollection_AsciiString mirrorTypeName( SMESH::SMESH_MeshEditor::MirrorType theMirrorType )
255 TCollection_AsciiString typeStr;
256 switch ( theMirrorType ) {
257 case SMESH::SMESH_MeshEditor::POINT:
258 typeStr = "SMESH.SMESH_MeshEditor.POINT";
260 case SMESH::SMESH_MeshEditor::AXIS:
261 typeStr = "SMESH.SMESH_MeshEditor.AXIS";
264 typeStr = "SMESH.SMESH_MeshEditor.PLANE";
268 //================================================================================
270 * \brief function for conversion of long_array to TIDSortedElemSet
271 * \param IDs - array of IDs
272 * \param aMesh - mesh
273 * \param aMap - collection to fill
274 * \param aType - element type
276 //================================================================================
278 void arrayToSet(const SMESH::long_array & IDs,
279 const SMESHDS_Mesh* aMesh,
280 TIDSortedElemSet& aMap,
281 const SMDSAbs_ElementType aType = SMDSAbs_All,
282 SMDS_MeshElement::Filter* aFilter = NULL)
284 SMDS_MeshElement::NonNullFilter filter1;
285 SMDS_MeshElement::TypeFilter filter2( aType );
287 if ( aFilter == NULL )
288 aFilter = ( aType == SMDSAbs_All ) ? (SMDS_MeshElement::Filter*) &filter1 : (SMDS_MeshElement::Filter*) &filter2;
290 SMDS_MeshElement::Filter & filter = *aFilter;
292 if ( aType == SMDSAbs_Node )
293 for (int i=0; i<IDs.length(); i++) {
294 const SMDS_MeshElement * elem = aMesh->FindNode( IDs[i] );
296 aMap.insert( aMap.end(), elem );
299 for (int i=0; i<IDs.length(); i++) {
300 const SMDS_MeshElement * elem = aMesh->FindElement( IDs[i] );
302 aMap.insert( aMap.end(), elem );
305 //================================================================================
307 * \brief Retrieve elements of given type from SMESH_IDSource
309 //================================================================================
311 enum IDSource_Error { IDSource_OK, IDSource_INVALID, IDSource_EMPTY };
313 bool idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource,
314 const SMESHDS_Mesh* theMeshDS,
315 TIDSortedElemSet& theElemSet,
316 const SMDSAbs_ElementType theType,
317 const bool emptyIfIsMesh = false,
318 IDSource_Error* error = 0)
321 if ( error ) *error = IDSource_OK;
323 if ( CORBA::is_nil( theIDSource ) )
325 if ( error ) *error = IDSource_INVALID;
328 if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
330 if ( error && theMeshDS->GetMeshInfo().NbElements( theType ) == 0 )
331 *error = IDSource_EMPTY;
334 SMESH::long_array_var anIDs = theIDSource->GetIDs();
335 if ( anIDs->length() == 0 )
337 if ( error ) *error = IDSource_EMPTY;
340 SMESH::array_of_ElementType_var types = theIDSource->GetTypes();
341 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
343 if ( theType == SMDSAbs_All || theType == SMDSAbs_Node )
345 arrayToSet( anIDs, theMeshDS, theElemSet, SMDSAbs_Node );
349 if ( error ) *error = IDSource_INVALID;
355 arrayToSet( anIDs, theMeshDS, theElemSet, theType);
356 if ( bool(anIDs->length()) != bool(theElemSet.size()))
358 if ( error ) *error = IDSource_INVALID;
364 //================================================================================
366 * \brief Retrieve nodes from SMESH_IDSource
368 //================================================================================
370 void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject,
371 const SMESHDS_Mesh* theMeshDS,
372 TIDSortedNodeSet& theNodeSet)
375 if ( CORBA::is_nil( theObject ) )
377 SMESH::array_of_ElementType_var types = theObject->GetTypes();
378 SMESH::long_array_var aElementsId = theObject->GetIDs();
379 if ( types->length() == 1 && types[0] == SMESH::NODE)
381 for(int i = 0; i < aElementsId->length(); i++)
382 if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] ))
383 theNodeSet.insert( theNodeSet.end(), n);
385 else if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
387 SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator();
388 while ( nIt->more( ))
389 if( const SMDS_MeshElement * elem = nIt->next() )
390 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
394 for(int i = 0; i < aElementsId->length(); i++)
395 if( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] ))
396 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
400 //================================================================================
402 * \brief Returns elements connected to the given elements
404 //================================================================================
406 void getElementsAround(const TIDSortedElemSet& theElements,
407 const SMESHDS_Mesh* theMeshDS,
408 TIDSortedElemSet& theElementsAround)
410 if ( theElements.empty() ) return;
412 SMDSAbs_ElementType elemType = (*theElements.begin())->GetType();
413 bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() );
415 theMeshDS->GetMeshInfo().NbElements( elemType ) == theElements.size() )
416 return; // all the elements are in theElements
419 elemType = SMDSAbs_All;
421 TIDSortedElemSet visitedNodes;
422 TIDSortedElemSet::const_iterator elemIt = theElements.begin();
423 for ( ; elemIt != theElements.end(); ++elemIt )
425 const SMDS_MeshElement* e = *elemIt;
426 int i = e->NbCornerNodes();
429 const SMDS_MeshNode* n = e->GetNode( i );
430 if ( visitedNodes.insert( n ).second )
432 SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
433 while ( invIt->more() )
435 const SMDS_MeshElement* elemAround = invIt->next();
436 if ( !theElements.count( elemAround ))
437 theElementsAround.insert( elemAround );
444 //================================================================================
446 * \brief Return a string used to detect change of mesh part on which theElementSearcher
447 * is going to be used
449 //================================================================================
451 string getPartIOR( SMESH::SMESH_IDSource_ptr theMeshPart, SMESH::ElementType type)
453 string partIOR = SMESH_Gen_i::GetORB()->object_to_string( theMeshPart );
454 if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( theMeshPart ))
455 // take into account passible group modification
456 partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() );
457 partIOR += SMESH_Comment( type );
461 } // namespace MeshEditor_I
463 using namespace MeshEditor_I;
465 //=============================================================================
469 //=============================================================================
471 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview):
473 myMesh( &theMesh->GetImpl() ),
475 myIsPreviewMode ( isPreview ),
481 //================================================================================
485 //================================================================================
487 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
489 PortableServer::POA_var poa = SMESH_Gen_i::GetPOA();
490 PortableServer::ObjectId_var anObjectId = poa->servant_to_id(this);
491 poa->deactivate_object(anObjectId.in());
493 //deleteAuxIDSources();
494 delete myPreviewMesh; myPreviewMesh = 0;
495 delete myPreviewEditor; myPreviewEditor = 0;
498 //================================================================================
500 * \brief Clear members
502 //================================================================================
504 void SMESH_MeshEditor_i::initData(bool deleteSearchers)
506 if ( myIsPreviewMode ) {
507 if ( myPreviewMesh ) myPreviewMesh->RemoveAll();
510 if ( deleteSearchers )
511 TSearchersDeleter::Delete();
513 getEditor().GetError().reset();
514 getEditor().CrearLastCreated();
517 //================================================================================
519 * \brief Increment mesh modif time and optionally record that the performed
520 * modification may influence futher mesh re-compute.
521 * \param [in] isReComputeSafe - true if the modification does not infulence
522 * futher mesh re-compute
524 //================================================================================
526 void SMESH_MeshEditor_i::declareMeshModified( bool isReComputeSafe )
528 myMesh->GetMeshDS()->Modified();
529 if ( !isReComputeSafe )
530 myMesh->SetIsModified( true );
533 //================================================================================
535 * \brief Return either myEditor or myPreviewEditor depending on myIsPreviewMode.
536 * WARNING: in preview mode call getPreviewMesh() before getEditor()!
538 //================================================================================
540 ::SMESH_MeshEditor& SMESH_MeshEditor_i::getEditor()
542 if ( myIsPreviewMode && !myPreviewEditor ) {
543 if ( !myPreviewMesh ) getPreviewMesh();
544 myPreviewEditor = new ::SMESH_MeshEditor( myPreviewMesh );
546 return myIsPreviewMode ? *myPreviewEditor : myEditor;
549 //================================================================================
551 * \brief Initialize and return myPreviewMesh
552 * \param previewElements - type of elements to show in preview
554 * WARNING: call it once par a method!
556 //================================================================================
558 TPreviewMesh * SMESH_MeshEditor_i::getPreviewMesh(SMDSAbs_ElementType previewElements)
560 if ( !myPreviewMesh || myPreviewMesh->myPreviewType != previewElements )
562 delete myPreviewEditor;
564 delete myPreviewMesh;
565 myPreviewMesh = new TPreviewMesh( previewElements );
567 myPreviewMesh->Clear();
568 return myPreviewMesh;
571 //================================================================================
573 * Return data of mesh edition preview
575 //================================================================================
577 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
578 throw (SALOME::SALOME_Exception)
581 const bool hasBadElems = ( getEditor().GetError() && getEditor().GetError()->HasBadElems() );
583 if ( myIsPreviewMode || hasBadElems ) { // --- MeshPreviewStruct filling ---
585 list<int> aNodesConnectivity;
586 typedef map<int, int> TNodesMap;
589 SMESHDS_Mesh* aMeshDS;
590 std::auto_ptr< SMESH_MeshPartDS > aMeshPartDS;
592 aMeshPartDS.reset( new SMESH_MeshPartDS( getEditor().GetError()->myBadElements ));
593 aMeshDS = aMeshPartDS.get();
596 aMeshDS = getEditor().GetMeshDS();
598 myPreviewData = new SMESH::MeshPreviewStruct();
599 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
602 SMDSAbs_ElementType previewType = SMDSAbs_All;
604 if (TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( getEditor().GetMesh() )) {
605 previewType = aPreviewMesh->myPreviewType;
606 switch ( previewType ) {
607 case SMDSAbs_Edge : break;
608 case SMDSAbs_Face : break;
609 case SMDSAbs_Volume: break;
611 if ( aMeshDS->GetMeshInfo().NbElements() == 0 ) previewType = SMDSAbs_Node;
615 myPreviewData->elementTypes.length( aMeshDS->GetMeshInfo().NbElements( previewType ));
617 SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator(previewType);
619 while ( itMeshElems->more() ) {
620 const SMDS_MeshElement* aMeshElem = itMeshElems->next();
621 SMDS_NodeIteratorPtr itElemNodes = aMeshElem->nodeIterator();
622 while ( itElemNodes->more() ) {
623 const SMDS_MeshNode* aMeshNode = itElemNodes->next();
624 int aNodeID = aMeshNode->GetID();
625 TNodesMap::iterator anIter = nodesMap.find(aNodeID);
626 if ( anIter == nodesMap.end() ) {
627 // filling the nodes coordinates
628 myPreviewData->nodesXYZ[j].x = aMeshNode->X();
629 myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
630 myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
631 anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
634 aNodesConnectivity.push_back(anIter->second);
637 // filling the elements types
638 SMDSAbs_ElementType aType = aMeshElem->GetType();
639 bool isPoly = aMeshElem->IsPoly();
640 myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
641 myPreviewData->elementTypes[i].isPoly = isPoly;
642 myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
645 myPreviewData->nodesXYZ.length( j );
647 // filling the elements connectivities
648 list<int>::iterator aConnIter = aNodesConnectivity.begin();
649 myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
650 for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
651 myPreviewData->elementConnectivities[i] = *aConnIter;
653 return myPreviewData._retn();
655 SMESH_CATCH( SMESH::throwCorbaException );
659 //================================================================================
661 * \brief Returns list of it's IDs of created nodes
662 * \retval SMESH::long_array* - list of node ID
664 //================================================================================
666 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
667 throw (SALOME::SALOME_Exception)
670 SMESH::long_array_var myLastCreatedNodes = new SMESH::long_array();
672 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedNodes();
673 myLastCreatedNodes->length( aSeq.Length() );
674 for (int i = 1; i <= aSeq.Length(); i++)
675 myLastCreatedNodes[i-1] = aSeq.Value(i)->GetID();
677 return myLastCreatedNodes._retn();
678 SMESH_CATCH( SMESH::throwCorbaException );
682 //================================================================================
684 * \brief Returns list of it's IDs of created elements
685 * \retval SMESH::long_array* - list of elements' ID
687 //================================================================================
689 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
690 throw (SALOME::SALOME_Exception)
693 SMESH::long_array_var myLastCreatedElems = new SMESH::long_array();
695 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
696 myLastCreatedElems->length( aSeq.Length() );
697 for ( int i = 1; i <= aSeq.Length(); i++ )
698 myLastCreatedElems[i-1] = aSeq.Value(i)->GetID();
700 return myLastCreatedElems._retn();
701 SMESH_CATCH( SMESH::throwCorbaException );
705 //=======================================================================
706 //function : ClearLastCreated
707 //purpose : Clears sequences of last created elements and nodes
708 //=======================================================================
710 void SMESH_MeshEditor_i::ClearLastCreated() throw (SALOME::SALOME_Exception)
713 getEditor().CrearLastCreated();
714 SMESH_CATCH( SMESH::throwCorbaException );
717 //=======================================================================
719 * Returns description of an error/warning occured during the last operation
720 * WARNING: ComputeError.code >= 100 and no corresponding enum in IDL API
722 //=======================================================================
724 SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError()
725 throw (SALOME::SALOME_Exception)
728 SMESH::ComputeError_var errOut = new SMESH::ComputeError;
729 SMESH_ComputeErrorPtr& errIn = getEditor().GetError();
730 if ( errIn && !errIn->IsOK() )
732 errOut->code = -( errIn->myName < 0 ? errIn->myName + 1: errIn->myName ); // -1 -> 0
733 errOut->comment = errIn->myComment.c_str();
734 errOut->subShapeID = -1;
735 errOut->hasBadMesh = !errIn->myBadElements.empty();
740 errOut->subShapeID = -1;
741 errOut->hasBadMesh = false;
744 return errOut._retn();
745 SMESH_CATCH( SMESH::throwCorbaException );
749 //=======================================================================
750 //function : MakeIDSource
751 //purpose : Wrap a sequence of ids in a SMESH_IDSource.
752 // Call UnRegister() as you fininsh using it!!
753 //=======================================================================
755 struct SMESH_MeshEditor_i::_IDSource : public virtual POA_SMESH::SMESH_IDSource,
756 public virtual SALOME::GenericObj_i
758 SMESH::long_array _ids;
759 SMESH::ElementType _type;
760 SMESH::SMESH_Mesh_ptr _mesh;
761 SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); }
762 SMESH::long_array* GetMeshInfo() { return 0; }
763 SMESH::long_array* GetNbElementsByType()
765 SMESH::long_array_var aRes = new SMESH::long_array();
766 aRes->length(SMESH::NB_ELEMENT_TYPES);
767 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
768 aRes[ i ] = ( i == _type ) ? _ids.length() : 0;
771 SMESH::SMESH_Mesh_ptr GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _mesh ); }
772 bool IsMeshInfoCorrect() { return true; }
773 SMESH::array_of_ElementType* GetTypes()
775 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
776 if ( _ids.length() > 0 ) {
780 return types._retn();
784 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
785 SMESH::ElementType type)
787 // if ( myAuxIDSources.size() > 10 ) {
788 // delete myAuxIDSources.front();
789 // myAuxIDSources.pop_front();
792 _IDSource* idSrc = new _IDSource;
793 idSrc->_mesh = myMesh_i->_this();
796 //myAuxIDSources.push_back( idSrc );
798 SMESH::SMESH_IDSource_var anIDSourceVar = idSrc->_this();
800 return anIDSourceVar._retn();
803 bool SMESH_MeshEditor_i::IsTemporaryIDSource( SMESH::SMESH_IDSource_ptr& idSource )
805 return SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource );
808 CORBA::Long* SMESH_MeshEditor_i::GetTemporaryIDs( SMESH::SMESH_IDSource_ptr& idSource,
811 if ( _IDSource* tmpIdSource = SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource ))
813 nbIds = (int) tmpIdSource->_ids.length();
814 return & tmpIdSource->_ids[0];
820 // void SMESH_MeshEditor_i::deleteAuxIDSources()
822 // std::list< _IDSource* >::iterator idSrcIt = myAuxIDSources.begin();
823 // for ( ; idSrcIt != myAuxIDSources.end(); ++idSrcIt )
825 // myAuxIDSources.clear();
828 //=============================================================================
832 //=============================================================================
835 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
836 throw (SALOME::SALOME_Exception)
843 for (int i = 0; i < IDsOfElements.length(); i++)
844 IdList.push_back( IDsOfElements[i] );
846 // Update Python script
847 TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
850 bool ret = getEditor().Remove( IdList, false );
852 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 ); // issue 0020693
855 SMESH_CATCH( SMESH::throwCorbaException );
859 //=============================================================================
863 //=============================================================================
865 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
866 throw (SALOME::SALOME_Exception)
872 for (int i = 0; i < IDsOfNodes.length(); i++)
873 IdList.push_back( IDsOfNodes[i] );
875 // Update Python script
876 TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
878 bool ret = getEditor().Remove( IdList, true );
880 declareMeshModified( /*isReComputeSafe=*/ !ret ); // issue 0020693
883 SMESH_CATCH( SMESH::throwCorbaException );
887 //=============================================================================
891 //=============================================================================
893 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
894 throw (SALOME::SALOME_Exception)
899 // Update Python script
900 TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
902 // Create filter to find all orphan nodes
903 SMESH::Controls::Filter::TIdSequence seq;
904 SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
905 SMESH::Controls::Filter::GetElementsId( getMeshDS(), predicate, seq );
907 // remove orphan nodes (if there are any)
909 for ( int i = 0; i < seq.size(); i++ )
910 IdList.push_back( seq[i] );
912 int nbNodesBefore = myMesh->NbNodes();
913 getEditor().Remove( IdList, true );
914 int nbNodesAfter = myMesh->NbNodes();
916 declareMeshModified( /*isReComputeSafe=*/ IdList.size() == 0 ); // issue 0020693
917 return nbNodesBefore - nbNodesAfter;
919 SMESH_CATCH( SMESH::throwCorbaException );
923 //=============================================================================
927 //=============================================================================
929 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,CORBA::Double y, CORBA::Double z)
930 throw (SALOME::SALOME_Exception)
935 const SMDS_MeshNode* N = getMeshDS()->AddNode(x, y, z);
937 // Update Python script
938 TPythonDump() << "nodeID = " << this << ".AddNode( "
939 << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )";
941 declareMeshModified( /*isReComputeSafe=*/false );
944 SMESH_CATCH( SMESH::throwCorbaException );
948 //=============================================================================
950 * Create 0D element on the given node.
952 //=============================================================================
954 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
955 throw (SALOME::SALOME_Exception)
960 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
961 SMDS_MeshElement* elem = getMeshDS()->Add0DElement(aNode);
963 // Update Python script
964 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
966 declareMeshModified( /*isReComputeSafe=*/false );
968 return elem ? elem->GetID() : 0;
970 SMESH_CATCH( SMESH::throwCorbaException );
974 //=============================================================================
976 * Create a ball element on the given node.
978 //=============================================================================
980 CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diameter)
981 throw (SALOME::SALOME_Exception)
986 if ( diameter < std::numeric_limits<double>::min() )
987 THROW_SALOME_CORBA_EXCEPTION("Invalid diameter", SALOME::BAD_PARAM);
989 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
990 SMDS_MeshElement* elem = getMeshDS()->AddBall(aNode, diameter);
992 // Update Python script
993 TPythonDump() << "ballElem = "
994 << this << ".AddBall( " << IDOfNode << ", " << diameter <<" )";
996 declareMeshModified( /*isReComputeSafe=*/false );
997 return elem ? elem->GetID() : 0;
999 SMESH_CATCH( SMESH::throwCorbaException );
1003 //=============================================================================
1005 * Create an edge, either linear and quadratic (this is determed
1006 * by number of given nodes, two or three)
1008 //=============================================================================
1010 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
1011 throw (SALOME::SALOME_Exception)
1016 int NbNodes = IDsOfNodes.length();
1017 SMDS_MeshElement* elem = 0;
1020 CORBA::Long index1 = IDsOfNodes[0];
1021 CORBA::Long index2 = IDsOfNodes[1];
1022 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(index1),
1023 getMeshDS()->FindNode(index2));
1025 // Update Python script
1026 TPythonDump() << "edge = " << this << ".AddEdge([ "
1027 << index1 << ", " << index2 <<" ])";
1030 CORBA::Long n1 = IDsOfNodes[0];
1031 CORBA::Long n2 = IDsOfNodes[1];
1032 CORBA::Long n12 = IDsOfNodes[2];
1033 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(n1),
1034 getMeshDS()->FindNode(n2),
1035 getMeshDS()->FindNode(n12));
1036 // Update Python script
1037 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
1038 <<n1<<", "<<n2<<", "<<n12<<" ])";
1041 declareMeshModified( /*isReComputeSafe=*/false );
1042 return elem ? elem->GetID() : 0;
1044 SMESH_CATCH( SMESH::throwCorbaException );
1048 //=============================================================================
1052 //=============================================================================
1054 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
1055 throw (SALOME::SALOME_Exception)
1060 int NbNodes = IDsOfNodes.length();
1066 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1067 for (int i = 0; i < NbNodes; i++)
1068 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1070 SMDS_MeshElement* elem = 0;
1072 case 3: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]); break;
1073 case 4: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]); break;
1074 case 6: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1075 nodes[4], nodes[5]); break;
1076 case 7: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1077 nodes[4], nodes[5], nodes[6]); break;
1078 case 8: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1079 nodes[4], nodes[5], nodes[6], nodes[7]); break;
1080 case 9: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1081 nodes[4], nodes[5], nodes[6], nodes[7],
1083 default: elem = getMeshDS()->AddPolygonalFace(nodes);
1086 // Update Python script
1087 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
1089 declareMeshModified( /*isReComputeSafe=*/false );
1091 return elem ? elem->GetID() : 0;
1093 SMESH_CATCH( SMESH::throwCorbaException );
1097 //=============================================================================
1101 //=============================================================================
1102 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
1103 throw (SALOME::SALOME_Exception)
1108 int NbNodes = IDsOfNodes.length();
1109 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1110 for (int i = 0; i < NbNodes; i++)
1111 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1113 const SMDS_MeshElement* elem = getMeshDS()->AddPolygonalFace(nodes);
1115 // Update Python script
1116 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
1118 declareMeshModified( /*isReComputeSafe=*/false );
1119 return elem ? elem->GetID() : 0;
1121 SMESH_CATCH( SMESH::throwCorbaException );
1125 //=============================================================================
1127 * Create volume, either linear and quadratic (this is determed
1128 * by number of given nodes)
1130 //=============================================================================
1132 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
1133 throw (SALOME::SALOME_Exception)
1138 int NbNodes = IDsOfNodes.length();
1139 vector< const SMDS_MeshNode*> n(NbNodes);
1140 for(int i=0;i<NbNodes;i++)
1141 n[i]= getMeshDS()->FindNode(IDsOfNodes[i]);
1143 SMDS_MeshElement* elem = 0;
1146 case 4 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
1147 case 5 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
1148 case 6 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
1149 case 8 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
1150 case 10:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1151 n[6],n[7],n[8],n[9]);
1153 case 12:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1154 n[6],n[7],n[8],n[9],n[10],n[11]);
1156 case 13:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
1157 n[7],n[8],n[9],n[10],n[11],n[12]);
1159 case 15:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
1160 n[9],n[10],n[11],n[12],n[13],n[14]);
1162 case 20:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1163 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1164 n[15],n[16],n[17],n[18],n[19]);
1166 case 27:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1167 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1168 n[15],n[16],n[17],n[18],n[19],
1169 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
1173 // Update Python script
1174 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
1176 declareMeshModified( /*isReComputeSafe=*/false );
1177 return elem ? elem->GetID() : 0;
1179 SMESH_CATCH( SMESH::throwCorbaException );
1183 //=============================================================================
1185 * AddPolyhedralVolume
1187 //=============================================================================
1188 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
1189 const SMESH::long_array & Quantities)
1190 throw (SALOME::SALOME_Exception)
1195 int NbNodes = IDsOfNodes.length();
1196 std::vector<const SMDS_MeshNode*> n (NbNodes);
1197 for (int i = 0; i < NbNodes; i++)
1199 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDsOfNodes[i]);
1200 if (!aNode) return 0;
1204 int NbFaces = Quantities.length();
1205 std::vector<int> q (NbFaces);
1206 for (int j = 0; j < NbFaces; j++)
1207 q[j] = Quantities[j];
1209 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(n, q);
1211 // Update Python script
1212 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
1213 << IDsOfNodes << ", " << Quantities << " )";
1215 declareMeshModified( /*isReComputeSafe=*/false );
1216 return elem ? elem->GetID() : 0;
1218 SMESH_CATCH( SMESH::throwCorbaException );
1222 //=============================================================================
1224 * AddPolyhedralVolumeByFaces
1226 //=============================================================================
1228 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
1229 throw (SALOME::SALOME_Exception)
1234 int NbFaces = IdsOfFaces.length();
1235 std::vector<const SMDS_MeshNode*> poly_nodes;
1236 std::vector<int> quantities (NbFaces);
1238 for (int i = 0; i < NbFaces; i++) {
1239 const SMDS_MeshElement* aFace = getMeshDS()->FindElement(IdsOfFaces[i]);
1240 quantities[i] = aFace->NbNodes();
1242 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
1243 while (It->more()) {
1244 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
1248 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
1250 // Update Python script
1251 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
1252 << IdsOfFaces << " )";
1254 declareMeshModified( /*isReComputeSafe=*/false );
1255 return elem ? elem->GetID() : 0;
1257 SMESH_CATCH( SMESH::throwCorbaException );
1261 //=============================================================================
1263 // \brief Create 0D elements on all nodes of the given object except those
1264 // nodes on which a 0D element already exists.
1265 // \param theObject object on whose nodes 0D elements will be created.
1266 // \param theGroupName optional name of a group to add 0D elements created
1267 // and/or found on nodes of \a theObject.
1268 // \return an object (a new group or a temporary SMESH_IDSource) holding
1269 // ids of new and/or found 0D elements.
1271 //=============================================================================
1273 SMESH::SMESH_IDSource_ptr
1274 SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObject,
1275 const char* theGroupName)
1276 throw (SALOME::SALOME_Exception)
1281 SMESH::SMESH_IDSource_var result;
1284 TIDSortedElemSet elements, elems0D;
1285 prepareIdSource( theObject );
1286 if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
1287 getEditor().Create0DElementsOnAllNodes( elements, elems0D );
1289 SMESH::long_array_var newElems = new SMESH::long_array;
1290 newElems->length( elems0D.size() );
1291 TIDSortedElemSet::iterator eIt = elems0D.begin();
1292 for ( size_t i = 0; i < elems0D.size(); ++i, ++eIt )
1293 newElems[ i ] = (*eIt)->GetID();
1295 SMESH::SMESH_GroupBase_var groupToFill;
1296 if ( theGroupName && strlen( theGroupName ))
1298 // Get existing group named theGroupName
1299 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
1300 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
1301 SMESH::SMESH_GroupBase_var group = groups[i];
1302 if ( !group->_is_nil() ) {
1303 CORBA::String_var name = group->GetName();
1304 if ( strcmp( name.in(), theGroupName ) == 0 && group->GetType() == SMESH::ELEM0D ) {
1305 groupToFill = group;
1310 if ( groupToFill->_is_nil() )
1311 groupToFill = myMesh_i->CreateGroup( SMESH::ELEM0D, theGroupName );
1312 else if ( !SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1313 groupToFill = myMesh_i->ConvertToStandalone( groupToFill );
1316 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1318 group_i->Add( newElems );
1319 result = SMESH::SMESH_IDSource::_narrow( groupToFill );
1320 pyDump << groupToFill;
1324 result = MakeIDSource( newElems, SMESH::ELEM0D );
1325 pyDump << "elem0DIDs";
1328 pyDump << " = " << this << ".Create0DElementsOnAllNodes( "
1329 << theObject << ", '" << theGroupName << "' )";
1331 return result._retn();
1333 SMESH_CATCH( SMESH::throwCorbaException );
1337 //=============================================================================
1339 * \brief Bind a node to a vertex
1340 * \param NodeID - node ID
1341 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1342 * \retval boolean - false if NodeID or VertexID is invalid
1344 //=============================================================================
1346 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
1347 throw (SALOME::SALOME_Exception)
1351 SMESHDS_Mesh * mesh = getMeshDS();
1352 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1354 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1356 if ( mesh->MaxShapeIndex() < VertexID )
1357 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1359 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
1360 if ( shape.ShapeType() != TopAbs_VERTEX )
1361 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1363 mesh->SetNodeOnVertex( node, VertexID );
1365 myMesh->SetIsModified( true );
1367 SMESH_CATCH( SMESH::throwCorbaException );
1370 //=============================================================================
1372 * \brief Store node position on an edge
1373 * \param NodeID - node ID
1374 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
1375 * \param paramOnEdge - parameter on edge where the node is located
1376 * \retval boolean - false if any parameter is invalid
1378 //=============================================================================
1380 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
1381 CORBA::Double paramOnEdge)
1382 throw (SALOME::SALOME_Exception)
1386 SMESHDS_Mesh * mesh = getMeshDS();
1387 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1389 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1391 if ( mesh->MaxShapeIndex() < EdgeID )
1392 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1394 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
1395 if ( shape.ShapeType() != TopAbs_EDGE )
1396 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1399 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
1400 if ( paramOnEdge < f || paramOnEdge > l )
1401 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
1403 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
1405 myMesh->SetIsModified( true );
1407 SMESH_CATCH( SMESH::throwCorbaException );
1410 //=============================================================================
1412 * \brief Store node position on a face
1413 * \param NodeID - node ID
1414 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
1415 * \param u - U parameter on face where the node is located
1416 * \param v - V parameter on face where the node is located
1417 * \retval boolean - false if any parameter is invalid
1419 //=============================================================================
1421 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
1422 CORBA::Double u, CORBA::Double v)
1423 throw (SALOME::SALOME_Exception)
1426 SMESHDS_Mesh * mesh = getMeshDS();
1427 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1429 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1431 if ( mesh->MaxShapeIndex() < FaceID )
1432 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1434 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
1435 if ( shape.ShapeType() != TopAbs_FACE )
1436 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1438 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
1439 bool isOut = ( u < surf.FirstUParameter() ||
1440 u > surf.LastUParameter() ||
1441 v < surf.FirstVParameter() ||
1442 v > surf.LastVParameter() );
1446 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
1447 << " u( " << surf.FirstUParameter()
1448 << "," << surf.LastUParameter()
1449 << ") v( " << surf.FirstVParameter()
1450 << "," << surf.LastVParameter() << ")" );
1452 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
1455 mesh->SetNodeOnFace( node, FaceID, u, v );
1456 myMesh->SetIsModified( true );
1458 SMESH_CATCH( SMESH::throwCorbaException );
1461 //=============================================================================
1463 * \brief Bind a node to a solid
1464 * \param NodeID - node ID
1465 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1466 * \retval boolean - false if NodeID or SolidID is invalid
1468 //=============================================================================
1470 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
1471 throw (SALOME::SALOME_Exception)
1474 SMESHDS_Mesh * mesh = getMeshDS();
1475 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1477 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1479 if ( mesh->MaxShapeIndex() < SolidID )
1480 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1482 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
1483 if ( shape.ShapeType() != TopAbs_SOLID &&
1484 shape.ShapeType() != TopAbs_SHELL)
1485 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1487 mesh->SetNodeInVolume( node, SolidID );
1489 SMESH_CATCH( SMESH::throwCorbaException );
1492 //=============================================================================
1494 * \brief Bind an element to a shape
1495 * \param ElementID - element ID
1496 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
1498 //=============================================================================
1500 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
1501 CORBA::Long ShapeID)
1502 throw (SALOME::SALOME_Exception)
1505 SMESHDS_Mesh * mesh = getMeshDS();
1506 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
1508 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
1510 if ( mesh->MaxShapeIndex() < ShapeID || ShapeID < 1 )
1511 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1513 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1514 if ( shape.ShapeType() != TopAbs_EDGE &&
1515 shape.ShapeType() != TopAbs_FACE &&
1516 shape.ShapeType() != TopAbs_SOLID &&
1517 shape.ShapeType() != TopAbs_SHELL )
1518 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1520 mesh->SetMeshElementOnShape( elem, ShapeID );
1522 myMesh->SetIsModified( true );
1524 SMESH_CATCH( SMESH::throwCorbaException );
1527 //=============================================================================
1531 //=============================================================================
1533 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1534 CORBA::Long NodeID2)
1535 throw (SALOME::SALOME_Exception)
1540 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1541 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1545 // Update Python script
1546 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1547 << NodeID1 << ", " << NodeID2 << " )";
1549 int ret = getEditor().InverseDiag ( n1, n2 );
1551 declareMeshModified( /*isReComputeSafe=*/false );
1554 SMESH_CATCH( SMESH::throwCorbaException );
1558 //=============================================================================
1562 //=============================================================================
1564 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1565 CORBA::Long NodeID2)
1566 throw (SALOME::SALOME_Exception)
1571 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1572 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1576 // Update Python script
1577 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1578 << NodeID1 << ", " << NodeID2 << " )";
1581 bool stat = getEditor().DeleteDiag ( n1, n2 );
1583 declareMeshModified( /*isReComputeSafe=*/!stat );
1587 SMESH_CATCH( SMESH::throwCorbaException );
1591 //=============================================================================
1595 //=============================================================================
1597 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1598 throw (SALOME::SALOME_Exception)
1603 for (int i = 0; i < IDsOfElements.length(); i++)
1605 CORBA::Long index = IDsOfElements[i];
1606 const SMDS_MeshElement * elem = getMeshDS()->FindElement(index);
1608 getEditor().Reorient( elem );
1610 // Update Python script
1611 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1613 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 );
1616 SMESH_CATCH( SMESH::throwCorbaException );
1620 //=============================================================================
1624 //=============================================================================
1626 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1627 throw (SALOME::SALOME_Exception)
1632 TPythonDump aTPythonDump; // suppress dump in Reorient()
1634 prepareIdSource( theObject );
1636 SMESH::long_array_var anElementsId = theObject->GetIDs();
1637 CORBA::Boolean isDone = Reorient(anElementsId);
1639 // Update Python script
1640 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1642 declareMeshModified( /*isReComputeSafe=*/ anElementsId->length() == 0 );
1645 SMESH_CATCH( SMESH::throwCorbaException );
1649 //=======================================================================
1650 //function : Reorient2D
1651 //purpose : Reorient faces contained in \a the2Dgroup.
1652 // the2Dgroup - the mesh or its part to reorient
1653 // theDirection - desired direction of normal of \a theFace
1654 // theFace - ID of face whose orientation is checked.
1655 // It can be < 1 then \a thePoint is used to find a face.
1656 // thePoint - is used to find a face if \a theFace < 1.
1657 // return number of reoriented elements.
1658 //=======================================================================
1660 CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
1661 const SMESH::DirStruct& theDirection,
1662 CORBA::Long theFace,
1663 const SMESH::PointStruct& thePoint)
1664 throw (SALOME::SALOME_Exception)
1667 initData(/*deleteSearchers=*/false);
1669 TIDSortedElemSet elements;
1670 prepareIdSource( the2Dgroup );
1671 IDSource_Error error;
1672 idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error );
1673 if ( error == IDSource_EMPTY )
1675 if ( error == IDSource_INVALID )
1676 THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
1679 const SMDS_MeshElement* face = 0;
1682 face = getMeshDS()->FindElement( theFace );
1684 THROW_SALOME_CORBA_EXCEPTION("Inexistent face given", SALOME::BAD_PARAM);
1685 if ( face->GetType() != SMDSAbs_Face )
1686 THROW_SALOME_CORBA_EXCEPTION("Wrong element type", SALOME::BAD_PARAM);
1690 // create theElementSearcher if needed
1691 theSearchersDeleter.Set( myMesh, getPartIOR( the2Dgroup, SMESH::FACE ));
1692 if ( !theElementSearcher )
1694 if ( elements.empty() ) // search in the whole mesh
1696 if ( myMesh->NbFaces() == 0 )
1697 THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM);
1699 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
1703 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
1704 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
1706 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt);
1710 gp_Pnt p( thePoint.x, thePoint.y, thePoint.z );
1711 face = theElementSearcher->FindClosestTo( p, SMDSAbs_Face );
1714 THROW_SALOME_CORBA_EXCEPTION("No face found by point", SALOME::INTERNAL_ERROR );
1715 if ( !elements.empty() && !elements.count( face ))
1716 THROW_SALOME_CORBA_EXCEPTION("Found face is not in the group", SALOME::BAD_PARAM );
1719 const SMESH::PointStruct * P = &theDirection.PS;
1720 gp_Vec dirVec( P->x, P->y, P->z );
1721 if ( dirVec.Magnitude() < std::numeric_limits< double >::min() )
1722 THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM);
1724 int nbReori = getEditor().Reorient2D( elements, dirVec, face );
1727 declareMeshModified( /*isReComputeSafe=*/false );
1729 TPythonDump() << this << ".Reorient2D( "
1730 << the2Dgroup << ", "
1731 << theDirection << ", "
1733 << thePoint << " )";
1737 SMESH_CATCH( SMESH::throwCorbaException );
1741 //=======================================================================
1742 //function : Reorient2DBy3D
1743 //purpose : Reorient faces basing on orientation of adjacent volumes.
1744 //=======================================================================
1746 CORBA::Long SMESH_MeshEditor_i::Reorient2DBy3D(const SMESH::ListOfIDSources& faceGroups,
1747 SMESH::SMESH_IDSource_ptr volumeGroup,
1748 CORBA::Boolean outsideNormal)
1749 throw (SALOME::SALOME_Exception)
1754 TIDSortedElemSet volumes;
1755 prepareIdSource( volumeGroup );
1756 IDSource_Error volsError;
1757 idSourceToSet( volumeGroup, getMeshDS(), volumes, SMDSAbs_Volume, /*emptyIfMesh=*/1, &volsError);
1760 for ( size_t i = 0; i < faceGroups.length(); ++i )
1762 SMESH::SMESH_IDSource_ptr faceGrp = faceGroups[i].in();
1763 prepareIdSource( faceGrp );
1765 TIDSortedElemSet faces;
1766 IDSource_Error error;
1767 idSourceToSet( faceGrp, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error );
1768 if ( error == IDSource_INVALID && faceGroups.length() == 1 )
1769 THROW_SALOME_CORBA_EXCEPTION("No faces in a given object", SALOME::BAD_PARAM);
1770 if ( error == IDSource_OK && volsError != IDSource_OK )
1771 THROW_SALOME_CORBA_EXCEPTION("No volumes in a given object", SALOME::BAD_PARAM);
1773 nbReori += getEditor().Reorient2DBy3D( faces, volumes, outsideNormal );
1775 if ( error != IDSource_EMPTY && faces.empty() ) // all faces in the mesh treated
1780 declareMeshModified( /*isReComputeSafe=*/false );
1782 TPythonDump() << this << ".Reorient2DBy3D( "
1783 << faceGroups << ", "
1784 << volumeGroup << ", "
1785 << outsideNormal << " )";
1789 SMESH_CATCH( SMESH::throwCorbaException );
1793 //=============================================================================
1795 * \brief Fuse neighbour triangles into quadrangles.
1797 //=============================================================================
1799 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1800 SMESH::NumericalFunctor_ptr Criterion,
1801 CORBA::Double MaxAngle)
1802 throw (SALOME::SALOME_Exception)
1807 SMESHDS_Mesh* aMesh = getMeshDS();
1808 TIDSortedElemSet faces,copyFaces;
1809 SMDS_MeshElement::GeomFilter triaFilter(SMDSGeom_TRIANGLE);
1810 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face, & triaFilter);
1811 TIDSortedElemSet* workElements = & faces;
1813 if ( myIsPreviewMode ) {
1814 SMDSAbs_ElementType select = SMDSAbs_Face;
1815 getPreviewMesh( SMDSAbs_Face )->Copy( faces, copyFaces, select );
1816 workElements = & copyFaces;
1819 SMESH::NumericalFunctor_i* aNumericalFunctor =
1820 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1821 SMESH::Controls::NumericalFunctorPtr aCrit;
1822 if ( !aNumericalFunctor )
1823 aCrit.reset( new SMESH::Controls::MaxElementLength2D() );
1825 aCrit = aNumericalFunctor->GetNumericalFunctor();
1827 if ( !myIsPreviewMode ) {
1828 // Update Python script
1829 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1830 << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1833 bool stat = getEditor().TriToQuad( *workElements, aCrit, MaxAngle );
1835 declareMeshModified( /*isReComputeSafe=*/!stat );
1838 SMESH_CATCH( SMESH::throwCorbaException );
1842 //=============================================================================
1844 * \brief Fuse neighbour triangles into quadrangles.
1846 //=============================================================================
1848 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1849 SMESH::NumericalFunctor_ptr Criterion,
1850 CORBA::Double MaxAngle)
1851 throw (SALOME::SALOME_Exception)
1856 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1858 prepareIdSource( theObject );
1859 SMESH::long_array_var anElementsId = theObject->GetIDs();
1860 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1862 if ( !myIsPreviewMode ) {
1863 SMESH::NumericalFunctor_i* aNumericalFunctor =
1864 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1866 // Update Python script
1867 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1868 << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1873 SMESH_CATCH( SMESH::throwCorbaException );
1877 //=============================================================================
1879 * \brief Split quadrangles into triangles.
1881 //=============================================================================
1883 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1884 SMESH::NumericalFunctor_ptr Criterion)
1885 throw (SALOME::SALOME_Exception)
1890 SMESHDS_Mesh* aMesh = getMeshDS();
1891 TIDSortedElemSet faces;
1892 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1894 SMESH::NumericalFunctor_i* aNumericalFunctor =
1895 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1896 SMESH::Controls::NumericalFunctorPtr aCrit;
1897 if ( !aNumericalFunctor )
1898 aCrit.reset( new SMESH::Controls::AspectRatio() );
1900 aCrit = aNumericalFunctor->GetNumericalFunctor();
1903 // Update Python script
1904 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1906 CORBA::Boolean stat = getEditor().QuadToTri( faces, aCrit );
1908 declareMeshModified( /*isReComputeSafe=*/false );
1911 SMESH_CATCH( SMESH::throwCorbaException );
1915 //=============================================================================
1917 * \brief Split quadrangles into triangles.
1919 //=============================================================================
1921 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1922 SMESH::NumericalFunctor_ptr Criterion)
1923 throw (SALOME::SALOME_Exception)
1928 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1930 prepareIdSource( theObject );
1931 SMESH::long_array_var anElementsId = theObject->GetIDs();
1932 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1934 SMESH::NumericalFunctor_i* aNumericalFunctor =
1935 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1937 // Update Python script
1938 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1940 declareMeshModified( /*isReComputeSafe=*/false );
1943 SMESH_CATCH( SMESH::throwCorbaException );
1947 //================================================================================
1949 * \brief Split each of quadrangles into 4 triangles.
1950 * \param [in] theObject - theQuads Container of quadrangles to split.
1952 //================================================================================
1954 void SMESH_MeshEditor_i::QuadTo4Tri (SMESH::SMESH_IDSource_ptr theObject)
1955 throw (SALOME::SALOME_Exception)
1960 TIDSortedElemSet faces;
1961 prepareIdSource( theObject );
1962 if ( !idSourceToSet( theObject, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/true ) &&
1964 THROW_SALOME_CORBA_EXCEPTION("No faces given", SALOME::BAD_PARAM);
1966 getEditor().QuadTo4Tri( faces );
1967 TPythonDump() << this << ".QuadTo4Tri( " << theObject << " )";
1969 SMESH_CATCH( SMESH::throwCorbaException );
1972 //=============================================================================
1974 * \brief Split quadrangles into triangles.
1976 //=============================================================================
1978 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1979 CORBA::Boolean Diag13)
1980 throw (SALOME::SALOME_Exception)
1985 SMESHDS_Mesh* aMesh = getMeshDS();
1986 TIDSortedElemSet faces;
1987 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1989 // Update Python script
1990 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1991 << IDsOfElements << ", " << Diag13 << " )";
1993 CORBA::Boolean stat = getEditor().QuadToTri( faces, Diag13 );
1995 declareMeshModified( /*isReComputeSafe=*/ !stat );
1998 SMESH_CATCH( SMESH::throwCorbaException );
2002 //=============================================================================
2004 * \brief Split quadrangles into triangles.
2006 //=============================================================================
2008 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
2009 CORBA::Boolean Diag13)
2010 throw (SALOME::SALOME_Exception)
2015 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
2017 prepareIdSource( theObject );
2018 SMESH::long_array_var anElementsId = theObject->GetIDs();
2019 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
2021 // Update Python script
2022 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
2023 << theObject << ", " << Diag13 << " )";
2025 declareMeshModified( /*isReComputeSafe=*/!isDone );
2028 SMESH_CATCH( SMESH::throwCorbaException );
2033 //=============================================================================
2035 * Find better splitting of the given quadrangle.
2036 * \param IDOfQuad ID of the quadrangle to be splitted.
2037 * \param Criterion A criterion to choose a diagonal for splitting.
2038 * \return 1 if 1-3 diagonal is better, 2 if 2-4
2039 * diagonal is better, 0 if error occurs.
2041 //=============================================================================
2043 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
2044 SMESH::NumericalFunctor_ptr Criterion)
2045 throw (SALOME::SALOME_Exception)
2050 const SMDS_MeshElement* quad = getMeshDS()->FindElement(IDOfQuad);
2051 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
2053 SMESH::NumericalFunctor_i* aNumericalFunctor =
2054 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
2055 SMESH::Controls::NumericalFunctorPtr aCrit;
2056 if (aNumericalFunctor)
2057 aCrit = aNumericalFunctor->GetNumericalFunctor();
2059 aCrit.reset(new SMESH::Controls::AspectRatio());
2061 int id = getEditor().BestSplit(quad, aCrit);
2062 declareMeshModified( /*isReComputeSafe=*/ id < 1 );
2066 SMESH_CATCH( SMESH::throwCorbaException );
2070 //================================================================================
2072 * \brief Split volumic elements into tetrahedrons
2074 //================================================================================
2076 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
2077 CORBA::Short methodFlags)
2078 throw (SALOME::SALOME_Exception)
2082 prepareIdSource( elems );
2084 ::SMESH_MeshEditor::TFacetOfElem elemSet;
2085 const int noneFacet = -1;
2086 SMDS_ElemIteratorPtr volIt = myMesh_i->GetElements( elems, SMESH::VOLUME );
2087 while( volIt->more() )
2088 elemSet.insert( elemSet.end(), make_pair( volIt->next(), noneFacet ));
2090 getEditor().SplitVolumes( elemSet, int( methodFlags ));
2091 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2093 TPythonDump() << this << ".SplitVolumesIntoTetra( "
2094 << elems << ", " << methodFlags << " )";
2096 SMESH_CATCH( SMESH::throwCorbaException );
2099 //================================================================================
2101 * \brief Split hexahedra into triangular prisms
2102 * \param elems - elements to split
2103 * \param facetToSplitNormal - normal used to find a facet of hexahedron
2104 * to split into triangles
2105 * \param methodFlags - flags passing splitting method:
2106 * 1 - split the hexahedron into 2 prisms
2107 * 2 - split the hexahedron into 4 prisms
2109 //================================================================================
2111 void SMESH_MeshEditor_i::SplitHexahedraIntoPrisms (SMESH::SMESH_IDSource_ptr elems,
2112 const SMESH::PointStruct & startHexPoint,
2113 const SMESH::DirStruct& facetToSplitNormal,
2114 CORBA::Short methodFlags,
2115 CORBA::Boolean allDomains)
2116 throw (SALOME::SALOME_Exception)
2120 prepareIdSource( elems );
2122 gp_Ax1 facetNorm( gp_Pnt( startHexPoint.x,
2125 gp_Dir( facetToSplitNormal.PS.x,
2126 facetToSplitNormal.PS.y,
2127 facetToSplitNormal.PS.z ));
2128 TIDSortedElemSet elemSet;
2129 SMESH::long_array_var anElementsId = elems->GetIDs();
2130 SMDS_MeshElement::GeomFilter filter( SMDSGeom_HEXA );
2131 arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume, &filter );
2133 ::SMESH_MeshEditor::TFacetOfElem elemFacets;
2134 while ( !elemSet.empty() )
2136 getEditor().GetHexaFacetsToSplit( elemSet, facetNorm, elemFacets );
2140 ::SMESH_MeshEditor::TFacetOfElem::iterator ef = elemFacets.begin();
2141 for ( ; ef != elemFacets.end(); ++ef )
2142 elemSet.erase( ef->first );
2145 if ( methodFlags == 2 )
2146 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_4_PRISMS );
2148 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_2_PRISMS );
2150 getEditor().SplitVolumes( elemFacets, int( methodFlags ));
2151 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2153 TPythonDump() << this << ".SplitHexahedraIntoPrisms( "
2155 << startHexPoint << ", "
2156 << facetToSplitNormal<< ", "
2157 << methodFlags<< ", "
2158 << allDomains << " )";
2160 SMESH_CATCH( SMESH::throwCorbaException );
2163 //=======================================================================
2166 //=======================================================================
2169 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
2170 const SMESH::long_array & IDsOfFixedNodes,
2171 CORBA::Long MaxNbOfIterations,
2172 CORBA::Double MaxAspectRatio,
2173 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2174 throw (SALOME::SALOME_Exception)
2176 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2177 MaxAspectRatio, Method, false );
2181 //=======================================================================
2182 //function : SmoothParametric
2184 //=======================================================================
2187 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
2188 const SMESH::long_array & IDsOfFixedNodes,
2189 CORBA::Long MaxNbOfIterations,
2190 CORBA::Double MaxAspectRatio,
2191 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2192 throw (SALOME::SALOME_Exception)
2194 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2195 MaxAspectRatio, Method, true );
2199 //=======================================================================
2200 //function : SmoothObject
2202 //=======================================================================
2205 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
2206 const SMESH::long_array & IDsOfFixedNodes,
2207 CORBA::Long MaxNbOfIterations,
2208 CORBA::Double MaxAspectRatio,
2209 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2210 throw (SALOME::SALOME_Exception)
2212 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2213 MaxAspectRatio, Method, false);
2217 //=======================================================================
2218 //function : SmoothParametricObject
2220 //=======================================================================
2223 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
2224 const SMESH::long_array & IDsOfFixedNodes,
2225 CORBA::Long MaxNbOfIterations,
2226 CORBA::Double MaxAspectRatio,
2227 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2228 throw (SALOME::SALOME_Exception)
2230 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2231 MaxAspectRatio, Method, true);
2235 //=============================================================================
2239 //=============================================================================
2242 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
2243 const SMESH::long_array & IDsOfFixedNodes,
2244 CORBA::Long MaxNbOfIterations,
2245 CORBA::Double MaxAspectRatio,
2246 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2248 throw (SALOME::SALOME_Exception)
2253 SMESHDS_Mesh* aMesh = getMeshDS();
2255 TIDSortedElemSet elements;
2256 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
2258 set<const SMDS_MeshNode*> fixedNodes;
2259 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
2260 CORBA::Long index = IDsOfFixedNodes[i];
2261 const SMDS_MeshNode * node = aMesh->FindNode(index);
2263 fixedNodes.insert( node );
2265 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
2266 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
2267 method = ::SMESH_MeshEditor::CENTROIDAL;
2269 getEditor().Smooth(elements, fixedNodes, method,
2270 MaxNbOfIterations, MaxAspectRatio, IsParametric );
2272 declareMeshModified( /*isReComputeSafe=*/true ); // does not prevent re-compute
2274 // Update Python script
2275 TPythonDump() << "isDone = " << this << "."
2276 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
2277 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
2278 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2279 << "SMESH.SMESH_MeshEditor."
2280 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2281 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2285 SMESH_CATCH( SMESH::throwCorbaException );
2289 //=============================================================================
2293 //=============================================================================
2296 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
2297 const SMESH::long_array & IDsOfFixedNodes,
2298 CORBA::Long MaxNbOfIterations,
2299 CORBA::Double MaxAspectRatio,
2300 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2302 throw (SALOME::SALOME_Exception)
2307 TPythonDump aTPythonDump; // suppress dump in smooth()
2309 prepareIdSource( theObject );
2310 SMESH::long_array_var anElementsId = theObject->GetIDs();
2311 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
2312 MaxAspectRatio, Method, IsParametric);
2314 // Update Python script
2315 aTPythonDump << "isDone = " << this << "."
2316 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
2317 << theObject << ", " << IDsOfFixedNodes << ", "
2318 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2319 << "SMESH.SMESH_MeshEditor."
2320 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2321 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2325 SMESH_CATCH( SMESH::throwCorbaException );
2329 //=============================================================================
2333 //=============================================================================
2335 void SMESH_MeshEditor_i::RenumberNodes()
2336 throw (SALOME::SALOME_Exception)
2339 // Update Python script
2340 TPythonDump() << this << ".RenumberNodes()";
2342 getMeshDS()->Renumber( true );
2344 SMESH_CATCH( SMESH::throwCorbaException );
2347 //=============================================================================
2351 //=============================================================================
2353 void SMESH_MeshEditor_i::RenumberElements()
2354 throw (SALOME::SALOME_Exception)
2357 // Update Python script
2358 TPythonDump() << this << ".RenumberElements()";
2360 getMeshDS()->Renumber( false );
2362 SMESH_CATCH( SMESH::throwCorbaException );
2365 //=======================================================================
2367 * \brief Return groups by their IDs
2369 //=======================================================================
2371 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
2372 throw (SALOME::SALOME_Exception)
2377 myMesh_i->CreateGroupServants();
2378 return myMesh_i->GetGroups( *groupIDs );
2380 SMESH_CATCH( SMESH::throwCorbaException );
2384 //=======================================================================
2385 //function : rotationSweep
2387 //=======================================================================
2389 SMESH::ListOfGroups*
2390 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
2391 const SMESH::AxisStruct & theAxis,
2392 CORBA::Double theAngleInRadians,
2393 CORBA::Long theNbOfSteps,
2394 CORBA::Double theTolerance,
2395 const bool theMakeGroups,
2396 const SMDSAbs_ElementType theElementType)
2397 throw (SALOME::SALOME_Exception)
2402 TIDSortedElemSet inElements, copyElements;
2403 arrayToSet(theIDsOfElements, getMeshDS(), inElements, theElementType);
2405 TIDSortedElemSet* workElements = & inElements;
2406 bool makeWalls=true;
2407 if ( myIsPreviewMode )
2409 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2410 getPreviewMesh( SMDSAbs_Face )->Copy( inElements, copyElements, select, avoid );
2411 workElements = & copyElements;
2412 //makeWalls = false;
2415 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
2416 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
2418 ::SMESH_MeshEditor::PGroupIDs groupIds =
2419 getEditor().RotationSweep (*workElements, Ax1, theAngleInRadians,
2420 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
2422 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2424 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2426 SMESH_CATCH( SMESH::throwCorbaException );
2430 //=======================================================================
2431 //function : RotationSweep
2433 //=======================================================================
2435 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
2436 const SMESH::AxisStruct & theAxis,
2437 CORBA::Double theAngleInRadians,
2438 CORBA::Long theNbOfSteps,
2439 CORBA::Double theTolerance)
2440 throw (SALOME::SALOME_Exception)
2442 if ( !myIsPreviewMode ) {
2443 TPythonDump() << this << ".RotationSweep( "
2444 << theIDsOfElements << ", "
2446 << TVar( theAngleInRadians ) << ", "
2447 << TVar( theNbOfSteps ) << ", "
2448 << TVar( theTolerance ) << " )";
2450 rotationSweep(theIDsOfElements,
2458 //=======================================================================
2459 //function : RotationSweepMakeGroups
2461 //=======================================================================
2463 SMESH::ListOfGroups*
2464 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2465 const SMESH::AxisStruct& theAxis,
2466 CORBA::Double theAngleInRadians,
2467 CORBA::Long theNbOfSteps,
2468 CORBA::Double theTolerance)
2469 throw (SALOME::SALOME_Exception)
2471 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2473 SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
2479 if (!myIsPreviewMode) {
2480 dumpGroupsList(aPythonDump, aGroups);
2481 aPythonDump << this << ".RotationSweepMakeGroups( "
2482 << theIDsOfElements << ", "
2484 << TVar( theAngleInRadians ) << ", "
2485 << TVar( theNbOfSteps ) << ", "
2486 << TVar( theTolerance ) << " )";
2491 //=======================================================================
2492 //function : RotationSweepObject
2494 //=======================================================================
2496 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2497 const SMESH::AxisStruct & theAxis,
2498 CORBA::Double theAngleInRadians,
2499 CORBA::Long theNbOfSteps,
2500 CORBA::Double theTolerance)
2501 throw (SALOME::SALOME_Exception)
2503 if ( !myIsPreviewMode ) {
2504 TPythonDump() << this << ".RotationSweepObject( "
2505 << theObject << ", "
2507 << theAngleInRadians << ", "
2508 << theNbOfSteps << ", "
2509 << theTolerance << " )";
2511 prepareIdSource( theObject );
2512 SMESH::long_array_var anElementsId = theObject->GetIDs();
2513 rotationSweep(anElementsId,
2521 //=======================================================================
2522 //function : RotationSweepObject1D
2524 //=======================================================================
2526 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2527 const SMESH::AxisStruct & theAxis,
2528 CORBA::Double theAngleInRadians,
2529 CORBA::Long theNbOfSteps,
2530 CORBA::Double theTolerance)
2531 throw (SALOME::SALOME_Exception)
2533 if ( !myIsPreviewMode ) {
2534 TPythonDump() << this << ".RotationSweepObject1D( "
2535 << theObject << ", "
2537 << TVar( theAngleInRadians ) << ", "
2538 << TVar( theNbOfSteps ) << ", "
2539 << TVar( theTolerance ) << " )";
2541 prepareIdSource( theObject );
2542 SMESH::long_array_var anElementsId = theObject->GetIDs();
2543 rotationSweep(anElementsId,
2552 //=======================================================================
2553 //function : RotationSweepObject2D
2555 //=======================================================================
2557 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2558 const SMESH::AxisStruct & theAxis,
2559 CORBA::Double theAngleInRadians,
2560 CORBA::Long theNbOfSteps,
2561 CORBA::Double theTolerance)
2562 throw (SALOME::SALOME_Exception)
2564 if ( !myIsPreviewMode ) {
2565 TPythonDump() << this << ".RotationSweepObject2D( "
2566 << theObject << ", "
2568 << TVar( theAngleInRadians ) << ", "
2569 << TVar( theNbOfSteps ) << ", "
2570 << TVar( theTolerance ) << " )";
2572 prepareIdSource( theObject );
2573 SMESH::long_array_var anElementsId = theObject->GetIDs();
2574 rotationSweep(anElementsId,
2583 //=======================================================================
2584 //function : RotationSweepObjectMakeGroups
2586 //=======================================================================
2588 SMESH::ListOfGroups*
2589 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2590 const SMESH::AxisStruct& theAxis,
2591 CORBA::Double theAngleInRadians,
2592 CORBA::Long theNbOfSteps,
2593 CORBA::Double theTolerance)
2594 throw (SALOME::SALOME_Exception)
2596 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2598 prepareIdSource( theObject );
2599 SMESH::long_array_var anElementsId = theObject->GetIDs();
2600 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2606 if (!myIsPreviewMode) {
2607 dumpGroupsList(aPythonDump, aGroups);
2608 aPythonDump << this << ".RotationSweepObjectMakeGroups( "
2609 << theObject << ", "
2611 << theAngleInRadians << ", "
2612 << theNbOfSteps << ", "
2613 << theTolerance << " )";
2618 //=======================================================================
2619 //function : RotationSweepObject1DMakeGroups
2621 //=======================================================================
2623 SMESH::ListOfGroups*
2624 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2625 const SMESH::AxisStruct& theAxis,
2626 CORBA::Double theAngleInRadians,
2627 CORBA::Long theNbOfSteps,
2628 CORBA::Double theTolerance)
2629 throw (SALOME::SALOME_Exception)
2631 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2633 prepareIdSource( theObject );
2634 SMESH::long_array_var anElementsId = theObject->GetIDs();
2635 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2642 if (!myIsPreviewMode) {
2643 dumpGroupsList(aPythonDump, aGroups);
2644 aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
2645 << theObject << ", "
2647 << TVar( theAngleInRadians ) << ", "
2648 << TVar( theNbOfSteps ) << ", "
2649 << TVar( theTolerance ) << " )";
2654 //=======================================================================
2655 //function : RotationSweepObject2DMakeGroups
2657 //=======================================================================
2659 SMESH::ListOfGroups*
2660 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2661 const SMESH::AxisStruct& theAxis,
2662 CORBA::Double theAngleInRadians,
2663 CORBA::Long theNbOfSteps,
2664 CORBA::Double theTolerance)
2665 throw (SALOME::SALOME_Exception)
2667 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2669 prepareIdSource( theObject );
2670 SMESH::long_array_var anElementsId = theObject->GetIDs();
2671 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2678 if (!myIsPreviewMode) {
2679 dumpGroupsList(aPythonDump, aGroups);
2680 aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
2681 << theObject << ", "
2683 << TVar( theAngleInRadians ) << ", "
2684 << TVar( theNbOfSteps ) << ", "
2685 << TVar( theTolerance ) << " )";
2691 //=======================================================================
2692 //function : extrusionSweep
2694 //=======================================================================
2696 SMESH::ListOfGroups*
2697 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
2698 const SMESH::DirStruct & theStepVector,
2699 CORBA::Long theNbOfSteps,
2701 const SMDSAbs_ElementType theElementType)
2702 throw (SALOME::SALOME_Exception)
2707 TIDSortedElemSet elements, copyElements;
2708 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
2710 const SMESH::PointStruct * P = &theStepVector.PS;
2711 gp_Vec stepVec( P->x, P->y, P->z );
2713 TIDSortedElemSet* workElements = & elements;
2715 SMDSAbs_ElementType aType = SMDSAbs_Face;
2716 if (theElementType == SMDSAbs_Node)
2718 aType = SMDSAbs_Edge;
2720 if ( myIsPreviewMode ) {
2721 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2722 getPreviewMesh( aType )->Copy( elements, copyElements, select, avoid );
2723 workElements = & copyElements;
2724 theMakeGroups = false;
2727 ::SMESH_MeshEditor::TTElemOfElemListMap aHystory;
2728 ::SMESH_MeshEditor::PGroupIDs groupIds =
2729 getEditor().ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
2731 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2733 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2735 SMESH_CATCH( SMESH::throwCorbaException );
2739 //=======================================================================
2740 //function : ExtrusionSweep
2742 //=======================================================================
2744 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
2745 const SMESH::DirStruct & theStepVector,
2746 CORBA::Long theNbOfSteps)
2747 throw (SALOME::SALOME_Exception)
2749 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
2750 if (!myIsPreviewMode) {
2751 TPythonDump() << this << ".ExtrusionSweep( "
2752 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps) << " )";
2756 //=======================================================================
2757 //function : ExtrusionSweep0D
2759 //=======================================================================
2761 void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElements,
2762 const SMESH::DirStruct & theStepVector,
2763 CORBA::Long theNbOfSteps)
2764 throw (SALOME::SALOME_Exception)
2766 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2767 if (!myIsPreviewMode) {
2768 TPythonDump() << this << ".ExtrusionSweep0D( "
2769 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps)<< " )";
2773 //=======================================================================
2774 //function : ExtrusionSweepObject
2776 //=======================================================================
2778 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2779 const SMESH::DirStruct & theStepVector,
2780 CORBA::Long theNbOfSteps)
2781 throw (SALOME::SALOME_Exception)
2783 prepareIdSource( theObject );
2784 SMESH::long_array_var anElementsId = theObject->GetIDs();
2785 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
2786 if (!myIsPreviewMode) {
2787 TPythonDump() << this << ".ExtrusionSweepObject( "
2788 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
2792 //=======================================================================
2793 //function : ExtrusionSweepObject0D
2795 //=======================================================================
2797 void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObject,
2798 const SMESH::DirStruct & theStepVector,
2799 CORBA::Long theNbOfSteps)
2800 throw (SALOME::SALOME_Exception)
2802 prepareIdSource( theObject );
2803 SMESH::long_array_var anElementsId = theObject->GetIDs();
2804 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2805 if ( !myIsPreviewMode ) {
2806 TPythonDump() << this << ".ExtrusionSweepObject0D( "
2807 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2811 //=======================================================================
2812 //function : ExtrusionSweepObject1D
2814 //=======================================================================
2816 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2817 const SMESH::DirStruct & theStepVector,
2818 CORBA::Long theNbOfSteps)
2819 throw (SALOME::SALOME_Exception)
2821 prepareIdSource( theObject );
2822 SMESH::long_array_var anElementsId = theObject->GetIDs();
2823 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
2824 if ( !myIsPreviewMode ) {
2825 TPythonDump() << this << ".ExtrusionSweepObject1D( "
2826 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2830 //=======================================================================
2831 //function : ExtrusionSweepObject2D
2833 //=======================================================================
2835 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2836 const SMESH::DirStruct & theStepVector,
2837 CORBA::Long theNbOfSteps)
2838 throw (SALOME::SALOME_Exception)
2840 prepareIdSource( theObject );
2841 SMESH::long_array_var anElementsId = theObject->GetIDs();
2842 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
2843 if ( !myIsPreviewMode ) {
2844 TPythonDump() << this << ".ExtrusionSweepObject2D( "
2845 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2849 //=======================================================================
2850 //function : ExtrusionSweepMakeGroups
2852 //=======================================================================
2854 SMESH::ListOfGroups*
2855 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2856 const SMESH::DirStruct& theStepVector,
2857 CORBA::Long theNbOfSteps)
2858 throw (SALOME::SALOME_Exception)
2860 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2862 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
2864 if (!myIsPreviewMode) {
2865 dumpGroupsList(aPythonDump, aGroups);
2866 aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
2867 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2872 //=======================================================================
2873 //function : ExtrusionSweepMakeGroups0D
2875 //=======================================================================
2877 SMESH::ListOfGroups*
2878 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups0D(const SMESH::long_array& theIDsOfElements,
2879 const SMESH::DirStruct& theStepVector,
2880 CORBA::Long theNbOfSteps)
2881 throw (SALOME::SALOME_Exception)
2883 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2885 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true,SMDSAbs_Node);
2887 if (!myIsPreviewMode) {
2888 dumpGroupsList(aPythonDump, aGroups);
2889 aPythonDump << this << ".ExtrusionSweepMakeGroups0D( " << theIDsOfElements
2890 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2895 //=======================================================================
2896 //function : ExtrusionSweepObjectMakeGroups
2898 //=======================================================================
2900 SMESH::ListOfGroups*
2901 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2902 const SMESH::DirStruct& theStepVector,
2903 CORBA::Long theNbOfSteps)
2904 throw (SALOME::SALOME_Exception)
2906 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2908 prepareIdSource( theObject );
2909 SMESH::long_array_var anElementsId = theObject->GetIDs();
2910 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
2912 if (!myIsPreviewMode) {
2913 dumpGroupsList(aPythonDump, aGroups);
2914 aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
2915 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2920 //=======================================================================
2921 //function : ExtrusionSweepObject0DMakeGroups
2923 //=======================================================================
2925 SMESH::ListOfGroups*
2926 SMESH_MeshEditor_i::ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2927 const SMESH::DirStruct& theStepVector,
2928 CORBA::Long theNbOfSteps)
2929 throw (SALOME::SALOME_Exception)
2931 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2933 prepareIdSource( theObject );
2934 SMESH::long_array_var anElementsId = theObject->GetIDs();
2935 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2936 theNbOfSteps, true, SMDSAbs_Node);
2937 if (!myIsPreviewMode) {
2938 dumpGroupsList(aPythonDump, aGroups);
2939 aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject
2940 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2945 //=======================================================================
2946 //function : ExtrusionSweepObject1DMakeGroups
2948 //=======================================================================
2950 SMESH::ListOfGroups*
2951 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2952 const SMESH::DirStruct& theStepVector,
2953 CORBA::Long theNbOfSteps)
2954 throw (SALOME::SALOME_Exception)
2956 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2958 prepareIdSource( theObject );
2959 SMESH::long_array_var anElementsId = theObject->GetIDs();
2960 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2961 theNbOfSteps, true, SMDSAbs_Edge);
2962 if (!myIsPreviewMode) {
2963 dumpGroupsList(aPythonDump, aGroups);
2964 aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
2965 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2970 //=======================================================================
2971 //function : ExtrusionSweepObject2DMakeGroups
2973 //=======================================================================
2975 SMESH::ListOfGroups*
2976 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2977 const SMESH::DirStruct& theStepVector,
2978 CORBA::Long theNbOfSteps)
2979 throw (SALOME::SALOME_Exception)
2981 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2983 prepareIdSource( theObject );
2984 SMESH::long_array_var anElementsId = theObject->GetIDs();
2985 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2986 theNbOfSteps, true, SMDSAbs_Face);
2987 if (!myIsPreviewMode) {
2988 dumpGroupsList(aPythonDump, aGroups);
2989 aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
2990 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2996 //=======================================================================
2997 //function : advancedExtrusion
2999 //=======================================================================
3001 SMESH::ListOfGroups*
3002 SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
3003 const SMESH::DirStruct & theStepVector,
3004 CORBA::Long theNbOfSteps,
3005 CORBA::Long theExtrFlags,
3006 CORBA::Double theSewTolerance,
3007 const bool theMakeGroups)
3008 throw (SALOME::SALOME_Exception)
3013 TIDSortedElemSet elements;
3014 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3016 const SMESH::PointStruct * P = &theStepVector.PS;
3017 gp_Vec stepVec( P->x, P->y, P->z );
3019 ::SMESH_MeshEditor::TTElemOfElemListMap aHystory;
3020 ::SMESH_MeshEditor::PGroupIDs groupIds =
3021 getEditor().ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
3022 theMakeGroups, theExtrFlags, theSewTolerance);
3024 declareMeshModified( /*isReComputeSafe=*/true );
3026 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3028 SMESH_CATCH( SMESH::throwCorbaException );
3032 //=======================================================================
3033 //function : AdvancedExtrusion
3035 //=======================================================================
3037 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
3038 const SMESH::DirStruct & theStepVector,
3039 CORBA::Long theNbOfSteps,
3040 CORBA::Long theExtrFlags,
3041 CORBA::Double theSewTolerance)
3042 throw (SALOME::SALOME_Exception)
3044 if ( !myIsPreviewMode ) {
3045 TPythonDump() << "stepVector = " << theStepVector;
3046 TPythonDump() << this << ".AdvancedExtrusion("
3049 << theNbOfSteps << ","
3050 << theExtrFlags << ", "
3051 << theSewTolerance << " )";
3053 advancedExtrusion( theIDsOfElements,
3061 //=======================================================================
3062 //function : AdvancedExtrusionMakeGroups
3064 //=======================================================================
3065 SMESH::ListOfGroups*
3066 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
3067 const SMESH::DirStruct& theStepVector,
3068 CORBA::Long theNbOfSteps,
3069 CORBA::Long theExtrFlags,
3070 CORBA::Double theSewTolerance)
3071 throw (SALOME::SALOME_Exception)
3073 if (!myIsPreviewMode) {
3074 TPythonDump() << "stepVector = " << theStepVector;
3076 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3078 SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
3085 if (!myIsPreviewMode) {
3086 dumpGroupsList(aPythonDump, aGroups);
3087 aPythonDump << this << ".AdvancedExtrusionMakeGroups("
3090 << theNbOfSteps << ","
3091 << theExtrFlags << ", "
3092 << theSewTolerance << " )";
3098 //================================================================================
3100 * \brief Convert extrusion error to IDL enum
3102 //================================================================================
3104 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
3106 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
3110 RETCASE( EXTR_NO_ELEMENTS );
3111 RETCASE( EXTR_PATH_NOT_EDGE );
3112 RETCASE( EXTR_BAD_PATH_SHAPE );
3113 RETCASE( EXTR_BAD_STARTING_NODE );
3114 RETCASE( EXTR_BAD_ANGLES_NUMBER );
3115 RETCASE( EXTR_CANT_GET_TANGENT );
3117 return SMESH::SMESH_MeshEditor::EXTR_OK;
3121 //=======================================================================
3122 //function : extrusionAlongPath
3124 //=======================================================================
3125 SMESH::ListOfGroups*
3126 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfElements,
3127 SMESH::SMESH_Mesh_ptr thePathMesh,
3128 GEOM::GEOM_Object_ptr thePathShape,
3129 CORBA::Long theNodeStart,
3130 CORBA::Boolean theHasAngles,
3131 const SMESH::double_array & theAngles,
3132 CORBA::Boolean theHasRefPoint,
3133 const SMESH::PointStruct & theRefPoint,
3134 const bool theMakeGroups,
3135 SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
3136 const SMDSAbs_ElementType theElementType)
3137 throw (SALOME::SALOME_Exception)
3140 MESSAGE("extrusionAlongPath");
3143 if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
3144 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3147 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3149 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3150 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3152 if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
3153 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3157 SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
3159 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3163 TIDSortedElemSet elements;
3164 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
3166 list<double> angles;
3167 for (int i = 0; i < theAngles.length(); i++) {
3168 angles.push_back( theAngles[i] );
3171 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
3173 int nbOldGroups = myMesh->NbGroup();
3175 ::SMESH_MeshEditor::Extrusion_Error error =
3176 getEditor().ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
3177 theHasAngles, angles, false,
3178 theHasRefPoint, refPnt, theMakeGroups );
3180 declareMeshModified( /*isReComputeSafe=*/true );
3181 theError = convExtrError( error );
3183 if ( theMakeGroups ) {
3184 list<int> groupIDs = myMesh->GetGroupIds();
3185 list<int>::iterator newBegin = groupIDs.begin();
3186 std::advance( newBegin, nbOldGroups ); // skip old groups
3187 groupIDs.erase( groupIDs.begin(), newBegin );
3188 return getGroups( & groupIDs );
3192 SMESH_CATCH( SMESH::throwCorbaException );
3196 //=======================================================================
3197 //function : extrusionAlongPathX
3199 //=======================================================================
3201 SMESH::ListOfGroups*
3202 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements,
3203 SMESH::SMESH_IDSource_ptr Path,
3204 CORBA::Long NodeStart,
3205 CORBA::Boolean HasAngles,
3206 const SMESH::double_array& Angles,
3207 CORBA::Boolean LinearVariation,
3208 CORBA::Boolean HasRefPoint,
3209 const SMESH::PointStruct& RefPoint,
3211 const SMDSAbs_ElementType ElementType,
3212 SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
3213 throw (SALOME::SALOME_Exception)
3216 SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
3220 list<double> angles;
3221 for (int i = 0; i < Angles.length(); i++) {
3222 angles.push_back( Angles[i] );
3224 gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
3225 int nbOldGroups = myMesh->NbGroup();
3227 if ( Path->_is_nil() ) {
3228 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3232 TIDSortedElemSet elements, copyElements;
3233 arrayToSet(IDsOfElements, getMeshDS(), elements, ElementType);
3235 TIDSortedElemSet* workElements = &elements;
3237 if ( myIsPreviewMode )
3239 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
3240 getPreviewMesh( SMDSAbs_Face )->Copy( elements, copyElements, select, avoid );
3241 workElements = & copyElements;
3245 ::SMESH_MeshEditor::Extrusion_Error error;
3247 if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path ))
3250 SMDS_MeshNode* aNodeStart =
3251 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
3252 if ( !aNodeStart ) {
3253 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3256 error = getEditor().ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
3257 HasAngles, angles, LinearVariation,
3258 HasRefPoint, refPnt, MakeGroups );
3259 declareMeshModified( /*isReComputeSafe=*/true );
3261 else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
3264 SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
3265 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
3266 SMDS_MeshNode* aNodeStart =
3267 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
3268 if ( !aNodeStart ) {
3269 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3272 SMESH_subMesh* aSubMesh =
3273 aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
3274 error = getEditor().ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
3275 HasAngles, angles, LinearVariation,
3276 HasRefPoint, refPnt, MakeGroups );
3277 declareMeshModified( /*isReComputeSafe=*/true );
3279 else if ( SMESH::DownCast<SMESH_Group_i*>( Path ))
3281 // path as group of 1D elements
3287 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3291 Error = convExtrError( error );
3294 list<int> groupIDs = myMesh->GetGroupIds();
3295 list<int>::iterator newBegin = groupIDs.begin();
3296 std::advance( newBegin, nbOldGroups ); // skip old groups
3297 groupIDs.erase( groupIDs.begin(), newBegin );
3298 return getGroups( & groupIDs );
3302 SMESH_CATCH( SMESH::throwCorbaException );
3306 //=======================================================================
3307 //function : ExtrusionAlongPath
3309 //=======================================================================
3311 SMESH::SMESH_MeshEditor::Extrusion_Error
3312 SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements,
3313 SMESH::SMESH_Mesh_ptr thePathMesh,
3314 GEOM::GEOM_Object_ptr thePathShape,
3315 CORBA::Long theNodeStart,
3316 CORBA::Boolean theHasAngles,
3317 const SMESH::double_array & theAngles,
3318 CORBA::Boolean theHasRefPoint,
3319 const SMESH::PointStruct & theRefPoint)
3320 throw (SALOME::SALOME_Exception)
3322 MESSAGE("ExtrusionAlongPath");
3323 if ( !myIsPreviewMode ) {
3324 TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
3325 << theIDsOfElements << ", "
3326 << thePathMesh << ", "
3327 << thePathShape << ", "
3328 << theNodeStart << ", "
3329 << theHasAngles << ", "
3330 << theAngles << ", "
3331 << theHasRefPoint << ", "
3332 << "SMESH.PointStruct( "
3333 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3334 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3335 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3337 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3338 extrusionAlongPath( theIDsOfElements,
3351 //=======================================================================
3352 //function : ExtrusionAlongPathObject
3354 //=======================================================================
3356 SMESH::SMESH_MeshEditor::Extrusion_Error
3357 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject,
3358 SMESH::SMESH_Mesh_ptr thePathMesh,
3359 GEOM::GEOM_Object_ptr thePathShape,
3360 CORBA::Long theNodeStart,
3361 CORBA::Boolean theHasAngles,
3362 const SMESH::double_array & theAngles,
3363 CORBA::Boolean theHasRefPoint,
3364 const SMESH::PointStruct & theRefPoint)
3365 throw (SALOME::SALOME_Exception)
3367 if ( !myIsPreviewMode ) {
3368 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
3369 << theObject << ", "
3370 << thePathMesh << ", "
3371 << thePathShape << ", "
3372 << theNodeStart << ", "
3373 << theHasAngles << ", "
3374 << theAngles << ", "
3375 << theHasRefPoint << ", "
3376 << "SMESH.PointStruct( "
3377 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3378 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3379 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3381 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3382 prepareIdSource( theObject );
3383 SMESH::long_array_var anElementsId = theObject->GetIDs();
3384 extrusionAlongPath( anElementsId,
3397 //=======================================================================
3398 //function : ExtrusionAlongPathObject1D
3400 //=======================================================================
3402 SMESH::SMESH_MeshEditor::Extrusion_Error
3403 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject,
3404 SMESH::SMESH_Mesh_ptr thePathMesh,
3405 GEOM::GEOM_Object_ptr thePathShape,
3406 CORBA::Long theNodeStart,
3407 CORBA::Boolean theHasAngles,
3408 const SMESH::double_array & theAngles,
3409 CORBA::Boolean theHasRefPoint,
3410 const SMESH::PointStruct & theRefPoint)
3411 throw (SALOME::SALOME_Exception)
3413 if ( !myIsPreviewMode ) {
3414 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
3415 << theObject << ", "
3416 << thePathMesh << ", "
3417 << thePathShape << ", "
3418 << theNodeStart << ", "
3419 << theHasAngles << ", "
3420 << theAngles << ", "
3421 << theHasRefPoint << ", "
3422 << "SMESH.PointStruct( "
3423 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3424 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3425 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3427 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3428 prepareIdSource( theObject );
3429 SMESH::long_array_var anElementsId = theObject->GetIDs();
3430 extrusionAlongPath( anElementsId,
3444 //=======================================================================
3445 //function : ExtrusionAlongPathObject2D
3447 //=======================================================================
3449 SMESH::SMESH_MeshEditor::Extrusion_Error
3450 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject,
3451 SMESH::SMESH_Mesh_ptr thePathMesh,
3452 GEOM::GEOM_Object_ptr thePathShape,
3453 CORBA::Long theNodeStart,
3454 CORBA::Boolean theHasAngles,
3455 const SMESH::double_array & theAngles,
3456 CORBA::Boolean theHasRefPoint,
3457 const SMESH::PointStruct & theRefPoint)
3458 throw (SALOME::SALOME_Exception)
3460 if ( !myIsPreviewMode ) {
3461 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
3462 << theObject << ", "
3463 << thePathMesh << ", "
3464 << thePathShape << ", "
3465 << theNodeStart << ", "
3466 << theHasAngles << ", "
3467 << theAngles << ", "
3468 << theHasRefPoint << ", "
3469 << "SMESH.PointStruct( "
3470 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3471 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3472 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3474 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3475 prepareIdSource( theObject );
3476 SMESH::long_array_var anElementsId = theObject->GetIDs();
3477 extrusionAlongPath( anElementsId,
3492 //=======================================================================
3493 //function : ExtrusionAlongPathMakeGroups
3495 //=======================================================================
3497 SMESH::ListOfGroups*
3498 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theIDsOfElements,
3499 SMESH::SMESH_Mesh_ptr thePathMesh,
3500 GEOM::GEOM_Object_ptr thePathShape,
3501 CORBA::Long theNodeStart,
3502 CORBA::Boolean theHasAngles,
3503 const SMESH::double_array& theAngles,
3504 CORBA::Boolean theHasRefPoint,
3505 const SMESH::PointStruct& theRefPoint,
3506 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3507 throw (SALOME::SALOME_Exception)
3509 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3511 SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements,
3521 if (!myIsPreviewMode) {
3522 bool isDumpGroups = aGroups && aGroups->length() > 0;
3524 aPythonDump << "(" << aGroups << ", error)";
3526 aPythonDump <<"error";
3528 aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
3529 << theIDsOfElements << ", "
3530 << thePathMesh << ", "
3531 << thePathShape << ", "
3532 << theNodeStart << ", "
3533 << theHasAngles << ", "
3534 << theAngles << ", "
3535 << theHasRefPoint << ", "
3536 << "SMESH.PointStruct( "
3537 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3538 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3539 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3544 //=======================================================================
3545 //function : ExtrusionAlongPathObjectMakeGroups
3547 //=======================================================================
3549 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3550 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3551 SMESH::SMESH_Mesh_ptr thePathMesh,
3552 GEOM::GEOM_Object_ptr thePathShape,
3553 CORBA::Long theNodeStart,
3554 CORBA::Boolean theHasAngles,
3555 const SMESH::double_array& theAngles,
3556 CORBA::Boolean theHasRefPoint,
3557 const SMESH::PointStruct& theRefPoint,
3558 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3559 throw (SALOME::SALOME_Exception)
3561 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3563 prepareIdSource( theObject );
3564 SMESH::long_array_var anElementsId = theObject->GetIDs();
3565 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3576 if (!myIsPreviewMode) {
3577 bool isDumpGroups = aGroups && aGroups->length() > 0;
3579 aPythonDump << "(" << aGroups << ", error)";
3581 aPythonDump <<"error";
3583 aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
3584 << theObject << ", "
3585 << thePathMesh << ", "
3586 << thePathShape << ", "
3587 << theNodeStart << ", "
3588 << theHasAngles << ", "
3589 << theAngles << ", "
3590 << theHasRefPoint << ", "
3591 << "SMESH.PointStruct( "
3592 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3593 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3594 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3599 //=======================================================================
3600 //function : ExtrusionAlongPathObject1DMakeGroups
3602 //=======================================================================
3604 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3605 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3606 SMESH::SMESH_Mesh_ptr thePathMesh,
3607 GEOM::GEOM_Object_ptr thePathShape,
3608 CORBA::Long theNodeStart,
3609 CORBA::Boolean theHasAngles,
3610 const SMESH::double_array& theAngles,
3611 CORBA::Boolean theHasRefPoint,
3612 const SMESH::PointStruct& theRefPoint,
3613 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3614 throw (SALOME::SALOME_Exception)
3616 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3618 prepareIdSource( theObject );
3619 SMESH::long_array_var anElementsId = theObject->GetIDs();
3620 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3632 if (!myIsPreviewMode) {
3633 bool isDumpGroups = aGroups && aGroups->length() > 0;
3635 aPythonDump << "(" << aGroups << ", error)";
3637 aPythonDump << "error";
3639 aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
3640 << theObject << ", "
3641 << thePathMesh << ", "
3642 << thePathShape << ", "
3643 << theNodeStart << ", "
3644 << theHasAngles << ", "
3645 << theAngles << ", "
3646 << theHasRefPoint << ", "
3647 << "SMESH.PointStruct( "
3648 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3649 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3650 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3655 //=======================================================================
3656 //function : ExtrusionAlongPathObject2DMakeGroups
3658 //=======================================================================
3660 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3661 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3662 SMESH::SMESH_Mesh_ptr thePathMesh,
3663 GEOM::GEOM_Object_ptr thePathShape,
3664 CORBA::Long theNodeStart,
3665 CORBA::Boolean theHasAngles,
3666 const SMESH::double_array& theAngles,
3667 CORBA::Boolean theHasRefPoint,
3668 const SMESH::PointStruct& theRefPoint,
3669 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3670 throw (SALOME::SALOME_Exception)
3672 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3674 prepareIdSource( theObject );
3675 SMESH::long_array_var anElementsId = theObject->GetIDs();
3676 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3688 if (!myIsPreviewMode) {
3689 bool isDumpGroups = aGroups && aGroups->length() > 0;
3691 aPythonDump << "(" << aGroups << ", error)";
3693 aPythonDump << "error";
3695 aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
3696 << theObject << ", "
3697 << thePathMesh << ", "
3698 << thePathShape << ", "
3699 << theNodeStart << ", "
3700 << theHasAngles << ", "
3701 << theAngles << ", "
3702 << theHasRefPoint << ", "
3703 << "SMESH.PointStruct( "
3704 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3705 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3706 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3711 //=======================================================================
3712 //function : ExtrusionAlongPathObjX
3714 //=======================================================================
3716 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3717 ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr Object,
3718 SMESH::SMESH_IDSource_ptr Path,
3719 CORBA::Long NodeStart,
3720 CORBA::Boolean HasAngles,
3721 const SMESH::double_array& Angles,
3722 CORBA::Boolean LinearVariation,
3723 CORBA::Boolean HasRefPoint,
3724 const SMESH::PointStruct& RefPoint,
3725 CORBA::Boolean MakeGroups,
3726 SMESH::ElementType ElemType,
3727 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3728 throw (SALOME::SALOME_Exception)
3730 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3732 prepareIdSource( Object );
3733 SMESH::long_array_var anElementsId = Object->GetIDs();
3734 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
3743 (SMDSAbs_ElementType)ElemType,
3746 if (!myIsPreviewMode) {
3747 bool isDumpGroups = aGroups && aGroups->length() > 0;
3749 aPythonDump << "(" << *aGroups << ", error)";
3751 aPythonDump << "error";
3753 aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
3756 << NodeStart << ", "
3757 << HasAngles << ", "
3758 << TVar( Angles ) << ", "
3759 << LinearVariation << ", "
3760 << HasRefPoint << ", "
3761 << "SMESH.PointStruct( "
3762 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3763 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3764 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3765 << MakeGroups << ", "
3766 << ElemType << " )";
3771 //=======================================================================
3772 //function : ExtrusionAlongPathX
3774 //=======================================================================
3776 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3777 ExtrusionAlongPathX(const SMESH::long_array& IDsOfElements,
3778 SMESH::SMESH_IDSource_ptr Path,
3779 CORBA::Long NodeStart,
3780 CORBA::Boolean HasAngles,
3781 const SMESH::double_array& Angles,
3782 CORBA::Boolean LinearVariation,
3783 CORBA::Boolean HasRefPoint,
3784 const SMESH::PointStruct& RefPoint,
3785 CORBA::Boolean MakeGroups,
3786 SMESH::ElementType ElemType,
3787 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3788 throw (SALOME::SALOME_Exception)
3790 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3792 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
3801 (SMDSAbs_ElementType)ElemType,
3804 if (!myIsPreviewMode) {
3805 bool isDumpGroups = aGroups && aGroups->length() > 0;
3807 aPythonDump << "(" << *aGroups << ", error)";
3809 aPythonDump <<"error";
3811 aPythonDump << " = " << this << ".ExtrusionAlongPathX( "
3812 << IDsOfElements << ", "
3814 << NodeStart << ", "
3815 << HasAngles << ", "
3816 << TVar( Angles ) << ", "
3817 << LinearVariation << ", "
3818 << HasRefPoint << ", "
3819 << "SMESH.PointStruct( "
3820 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3821 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3822 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3823 << MakeGroups << ", "
3824 << ElemType << " )";
3829 //================================================================================
3831 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
3832 * of given angles along path steps
3833 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
3834 * which proceeds the extrusion
3835 * \param PathShape is shape(edge); as the mesh can be complex, the edge
3836 * is used to define the sub-mesh for the path
3838 //================================================================================
3840 SMESH::double_array*
3841 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
3842 GEOM::GEOM_Object_ptr thePathShape,
3843 const SMESH::double_array & theAngles)
3845 SMESH::double_array_var aResult = new SMESH::double_array();
3846 int nbAngles = theAngles.length();
3847 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
3849 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3850 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3851 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3852 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
3853 return aResult._retn();
3854 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
3855 if ( nbSteps == nbAngles )
3857 aResult.inout() = theAngles;
3861 aResult->length( nbSteps );
3862 double rAn2St = double( nbAngles ) / double( nbSteps );
3863 double angPrev = 0, angle;
3864 for ( int iSt = 0; iSt < nbSteps; ++iSt )
3866 double angCur = rAn2St * ( iSt+1 );
3867 double angCurFloor = floor( angCur );
3868 double angPrevFloor = floor( angPrev );
3869 if ( angPrevFloor == angCurFloor )
3870 angle = rAn2St * theAngles[ int( angCurFloor ) ];
3873 int iP = int( angPrevFloor );
3874 double angPrevCeil = ceil(angPrev);
3875 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
3877 int iC = int( angCurFloor );
3878 if ( iC < nbAngles )
3879 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
3881 iP = int( angPrevCeil );
3883 angle += theAngles[ iC ];
3885 aResult[ iSt ] = angle;
3890 // Update Python script
3891 TPythonDump() << "rotAngles = " << theAngles;
3892 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
3893 << thePathMesh << ", "
3894 << thePathShape << ", "
3897 return aResult._retn();
3900 //=======================================================================
3903 //=======================================================================
3905 SMESH::ListOfGroups*
3906 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
3907 const SMESH::AxisStruct & theAxis,
3908 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3909 CORBA::Boolean theCopy,
3911 ::SMESH_Mesh* theTargetMesh)
3912 throw (SALOME::SALOME_Exception)
3917 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3918 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3920 if ( theTargetMesh )
3924 switch ( theMirrorType ) {
3925 case SMESH::SMESH_MeshEditor::POINT:
3926 aTrsf.SetMirror( P );
3928 case SMESH::SMESH_MeshEditor::AXIS:
3929 aTrsf.SetMirror( gp_Ax1( P, V ));
3932 aTrsf.SetMirror( gp_Ax2( P, V ));
3935 TIDSortedElemSet copyElements;
3936 TIDSortedElemSet* workElements = & theElements;
3938 if ( myIsPreviewMode )
3940 TPreviewMesh * tmpMesh = getPreviewMesh();
3941 tmpMesh->Copy( theElements, copyElements);
3942 if ( !theCopy && !theTargetMesh )
3944 TIDSortedElemSet elemsAround, elemsAroundCopy;
3945 getElementsAround( theElements, getMeshDS(), elemsAround );
3946 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3948 workElements = & copyElements;
3949 theMakeGroups = false;
3952 ::SMESH_MeshEditor::PGroupIDs groupIds =
3953 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3955 if ( theCopy && !myIsPreviewMode)
3957 if ( theTargetMesh )
3959 theTargetMesh->GetMeshDS()->Modified();
3963 declareMeshModified( /*isReComputeSafe=*/false );
3966 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3968 SMESH_CATCH( SMESH::throwCorbaException );
3972 //=======================================================================
3975 //=======================================================================
3977 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3978 const SMESH::AxisStruct & theAxis,
3979 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3980 CORBA::Boolean theCopy)
3981 throw (SALOME::SALOME_Exception)
3983 if ( !myIsPreviewMode ) {
3984 TPythonDump() << this << ".Mirror( "
3985 << theIDsOfElements << ", "
3987 << mirrorTypeName(theMirrorType) << ", "
3990 if ( theIDsOfElements.length() > 0 )
3992 TIDSortedElemSet elements;
3993 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3994 mirror(elements, theAxis, theMirrorType, theCopy, false);
3999 //=======================================================================
4000 //function : MirrorObject
4002 //=======================================================================
4004 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
4005 const SMESH::AxisStruct & theAxis,
4006 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
4007 CORBA::Boolean theCopy)
4008 throw (SALOME::SALOME_Exception)
4010 if ( !myIsPreviewMode ) {
4011 TPythonDump() << this << ".MirrorObject( "
4012 << theObject << ", "
4014 << mirrorTypeName(theMirrorType) << ", "
4017 TIDSortedElemSet elements;
4019 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4021 prepareIdSource( theObject );
4022 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4023 mirror(elements, theAxis, theMirrorType, theCopy, false);
4026 //=======================================================================
4027 //function : MirrorMakeGroups
4029 //=======================================================================
4031 SMESH::ListOfGroups*
4032 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
4033 const SMESH::AxisStruct& theMirror,
4034 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
4035 throw (SALOME::SALOME_Exception)
4037 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4039 SMESH::ListOfGroups * aGroups = 0;
4040 if ( theIDsOfElements.length() > 0 )
4042 TIDSortedElemSet elements;
4043 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4044 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
4046 if (!myIsPreviewMode) {
4047 dumpGroupsList(aPythonDump, aGroups);
4048 aPythonDump << this << ".MirrorMakeGroups( "
4049 << theIDsOfElements << ", "
4050 << theMirror << ", "
4051 << mirrorTypeName(theMirrorType) << " )";
4056 //=======================================================================
4057 //function : MirrorObjectMakeGroups
4059 //=======================================================================
4061 SMESH::ListOfGroups*
4062 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4063 const SMESH::AxisStruct& theMirror,
4064 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
4065 throw (SALOME::SALOME_Exception)
4067 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4069 SMESH::ListOfGroups * aGroups = 0;
4070 TIDSortedElemSet elements;
4071 prepareIdSource( theObject );
4072 if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4073 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
4075 if (!myIsPreviewMode)
4077 dumpGroupsList(aPythonDump,aGroups);
4078 aPythonDump << this << ".MirrorObjectMakeGroups( "
4079 << theObject << ", "
4080 << theMirror << ", "
4081 << mirrorTypeName(theMirrorType) << " )";
4086 //=======================================================================
4087 //function : MirrorMakeMesh
4089 //=======================================================================
4091 SMESH::SMESH_Mesh_ptr
4092 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
4093 const SMESH::AxisStruct& theMirror,
4094 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
4095 CORBA::Boolean theCopyGroups,
4096 const char* theMeshName)
4097 throw (SALOME::SALOME_Exception)
4099 SMESH_Mesh_i* mesh_i;
4100 SMESH::SMESH_Mesh_var mesh;
4101 { // open new scope to dump "MakeMesh" command
4102 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4104 TPythonDump pydump; // to prevent dump at mesh creation
4106 mesh = makeMesh( theMeshName );
4107 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4108 if (mesh_i && theIDsOfElements.length() > 0 )
4110 TIDSortedElemSet elements;
4111 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4112 mirror(elements, theMirror, theMirrorType,
4113 false, theCopyGroups, & mesh_i->GetImpl());
4114 mesh_i->CreateGroupServants();
4117 if (!myIsPreviewMode) {
4118 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
4119 << theIDsOfElements << ", "
4120 << theMirror << ", "
4121 << mirrorTypeName(theMirrorType) << ", "
4122 << theCopyGroups << ", '"
4123 << theMeshName << "' )";
4128 if (!myIsPreviewMode && mesh_i)
4129 mesh_i->GetGroups();
4131 return mesh._retn();
4134 //=======================================================================
4135 //function : MirrorObjectMakeMesh
4137 //=======================================================================
4139 SMESH::SMESH_Mesh_ptr
4140 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4141 const SMESH::AxisStruct& theMirror,
4142 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
4143 CORBA::Boolean theCopyGroups,
4144 const char* theMeshName)
4145 throw (SALOME::SALOME_Exception)
4147 SMESH_Mesh_i* mesh_i;
4148 SMESH::SMESH_Mesh_var mesh;
4149 { // open new scope to dump "MakeMesh" command
4150 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4152 TPythonDump pydump; // to prevent dump at mesh creation
4154 mesh = makeMesh( theMeshName );
4155 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4156 TIDSortedElemSet elements;
4157 prepareIdSource( theObject );
4159 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4161 mirror(elements, theMirror, theMirrorType,
4162 false, theCopyGroups, & mesh_i->GetImpl());
4163 mesh_i->CreateGroupServants();
4165 if (!myIsPreviewMode) {
4166 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
4167 << theObject << ", "
4168 << theMirror << ", "
4169 << mirrorTypeName(theMirrorType) << ", "
4170 << theCopyGroups << ", '"
4171 << theMeshName << "' )";
4176 if (!myIsPreviewMode && mesh_i)
4177 mesh_i->GetGroups();
4179 return mesh._retn();
4182 //=======================================================================
4183 //function : translate
4185 //=======================================================================
4187 SMESH::ListOfGroups*
4188 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
4189 const SMESH::DirStruct & theVector,
4190 CORBA::Boolean theCopy,
4192 ::SMESH_Mesh* theTargetMesh)
4193 throw (SALOME::SALOME_Exception)
4198 if ( theTargetMesh )
4202 const SMESH::PointStruct * P = &theVector.PS;
4203 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
4205 TIDSortedElemSet copyElements;
4206 TIDSortedElemSet* workElements = &theElements;
4208 if ( myIsPreviewMode )
4210 TPreviewMesh * tmpMesh = getPreviewMesh();
4211 tmpMesh->Copy( theElements, copyElements);
4212 if ( !theCopy && !theTargetMesh )
4214 TIDSortedElemSet elemsAround, elemsAroundCopy;
4215 getElementsAround( theElements, getMeshDS(), elemsAround );
4216 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4218 workElements = & copyElements;
4219 theMakeGroups = false;
4222 ::SMESH_MeshEditor::PGroupIDs groupIds =
4223 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4225 if ( theCopy && !myIsPreviewMode )
4227 if ( theTargetMesh )
4229 theTargetMesh->GetMeshDS()->Modified();
4233 declareMeshModified( /*isReComputeSafe=*/false );
4237 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4239 SMESH_CATCH( SMESH::throwCorbaException );
4243 //=======================================================================
4244 //function : Translate
4246 //=======================================================================
4248 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
4249 const SMESH::DirStruct & theVector,
4250 CORBA::Boolean theCopy)
4251 throw (SALOME::SALOME_Exception)
4253 if (!myIsPreviewMode) {
4254 TPythonDump() << this << ".Translate( "
4255 << theIDsOfElements << ", "
4256 << theVector << ", "
4259 if (theIDsOfElements.length()) {
4260 TIDSortedElemSet elements;
4261 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4262 translate(elements, theVector, theCopy, false);
4266 //=======================================================================
4267 //function : TranslateObject
4269 //=======================================================================
4271 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
4272 const SMESH::DirStruct & theVector,
4273 CORBA::Boolean theCopy)
4274 throw (SALOME::SALOME_Exception)
4276 if (!myIsPreviewMode) {
4277 TPythonDump() << this << ".TranslateObject( "
4278 << theObject << ", "
4279 << theVector << ", "
4282 TIDSortedElemSet elements;
4284 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4286 prepareIdSource( theObject );
4287 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4288 translate(elements, theVector, theCopy, false);
4291 //=======================================================================
4292 //function : TranslateMakeGroups
4294 //=======================================================================
4296 SMESH::ListOfGroups*
4297 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
4298 const SMESH::DirStruct& theVector)
4299 throw (SALOME::SALOME_Exception)
4301 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4303 SMESH::ListOfGroups * aGroups = 0;
4304 if (theIDsOfElements.length()) {
4305 TIDSortedElemSet elements;
4306 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4307 aGroups = translate(elements,theVector,true,true);
4309 if (!myIsPreviewMode) {
4310 dumpGroupsList(aPythonDump, aGroups);
4311 aPythonDump << this << ".TranslateMakeGroups( "
4312 << theIDsOfElements << ", "
4313 << theVector << " )";
4318 //=======================================================================
4319 //function : TranslateObjectMakeGroups
4321 //=======================================================================
4323 SMESH::ListOfGroups*
4324 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4325 const SMESH::DirStruct& theVector)
4326 throw (SALOME::SALOME_Exception)
4328 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4330 SMESH::ListOfGroups * aGroups = 0;
4331 TIDSortedElemSet elements;
4332 prepareIdSource( theObject );
4333 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4334 aGroups = translate(elements, theVector, true, true);
4336 if (!myIsPreviewMode) {
4337 dumpGroupsList(aPythonDump, aGroups);
4338 aPythonDump << this << ".TranslateObjectMakeGroups( "
4339 << theObject << ", "
4340 << theVector << " )";
4345 //=======================================================================
4346 //function : TranslateMakeMesh
4348 //=======================================================================
4350 SMESH::SMESH_Mesh_ptr
4351 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
4352 const SMESH::DirStruct& theVector,
4353 CORBA::Boolean theCopyGroups,
4354 const char* theMeshName)
4355 throw (SALOME::SALOME_Exception)
4357 SMESH_Mesh_i* mesh_i;
4358 SMESH::SMESH_Mesh_var mesh;
4360 { // open new scope to dump "MakeMesh" command
4361 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4363 TPythonDump pydump; // to prevent dump at mesh creation
4365 mesh = makeMesh( theMeshName );
4366 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4368 if ( mesh_i && theIDsOfElements.length() )
4370 TIDSortedElemSet elements;
4371 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4372 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
4373 mesh_i->CreateGroupServants();
4376 if ( !myIsPreviewMode ) {
4377 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
4378 << theIDsOfElements << ", "
4379 << theVector << ", "
4380 << theCopyGroups << ", '"
4381 << theMeshName << "' )";
4386 if (!myIsPreviewMode && mesh_i)
4387 mesh_i->GetGroups();
4389 return mesh._retn();
4392 //=======================================================================
4393 //function : TranslateObjectMakeMesh
4395 //=======================================================================
4397 SMESH::SMESH_Mesh_ptr
4398 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4399 const SMESH::DirStruct& theVector,
4400 CORBA::Boolean theCopyGroups,
4401 const char* theMeshName)
4402 throw (SALOME::SALOME_Exception)
4405 SMESH_Mesh_i* mesh_i;
4406 SMESH::SMESH_Mesh_var mesh;
4407 { // open new scope to dump "MakeMesh" command
4408 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4410 TPythonDump pydump; // to prevent dump at mesh creation
4411 mesh = makeMesh( theMeshName );
4412 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4414 TIDSortedElemSet elements;
4415 prepareIdSource( theObject );
4417 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4419 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
4420 mesh_i->CreateGroupServants();
4422 if ( !myIsPreviewMode ) {
4423 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
4424 << theObject << ", "
4425 << theVector << ", "
4426 << theCopyGroups << ", '"
4427 << theMeshName << "' )";
4432 if (!myIsPreviewMode && mesh_i)
4433 mesh_i->GetGroups();
4435 return mesh._retn();
4437 SMESH_CATCH( SMESH::throwCorbaException );
4441 //=======================================================================
4444 //=======================================================================
4446 SMESH::ListOfGroups*
4447 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
4448 const SMESH::AxisStruct & theAxis,
4449 CORBA::Double theAngle,
4450 CORBA::Boolean theCopy,
4452 ::SMESH_Mesh* theTargetMesh)
4453 throw (SALOME::SALOME_Exception)
4458 if ( theTargetMesh )
4461 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
4462 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
4465 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
4467 TIDSortedElemSet copyElements;
4468 TIDSortedElemSet* workElements = &theElements;
4469 if ( myIsPreviewMode ) {
4470 TPreviewMesh * tmpMesh = getPreviewMesh();
4471 tmpMesh->Copy( theElements, copyElements );
4472 if ( !theCopy && !theTargetMesh )
4474 TIDSortedElemSet elemsAround, elemsAroundCopy;
4475 getElementsAround( theElements, getMeshDS(), elemsAround );
4476 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4478 workElements = ©Elements;
4479 theMakeGroups = false;
4482 ::SMESH_MeshEditor::PGroupIDs groupIds =
4483 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4485 if ( theCopy && !myIsPreviewMode)
4487 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
4488 else declareMeshModified( /*isReComputeSafe=*/false );
4491 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4493 SMESH_CATCH( SMESH::throwCorbaException );
4497 //=======================================================================
4500 //=======================================================================
4502 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
4503 const SMESH::AxisStruct & theAxis,
4504 CORBA::Double theAngle,
4505 CORBA::Boolean theCopy)
4506 throw (SALOME::SALOME_Exception)
4508 if (!myIsPreviewMode) {
4509 TPythonDump() << this << ".Rotate( "
4510 << theIDsOfElements << ", "
4512 << TVar( theAngle ) << ", "
4515 if (theIDsOfElements.length() > 0)
4517 TIDSortedElemSet elements;
4518 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4519 rotate(elements,theAxis,theAngle,theCopy,false);
4523 //=======================================================================
4524 //function : RotateObject
4526 //=======================================================================
4528 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
4529 const SMESH::AxisStruct & theAxis,
4530 CORBA::Double theAngle,
4531 CORBA::Boolean theCopy)
4532 throw (SALOME::SALOME_Exception)
4534 if ( !myIsPreviewMode ) {
4535 TPythonDump() << this << ".RotateObject( "
4536 << theObject << ", "
4538 << TVar( theAngle ) << ", "
4541 TIDSortedElemSet elements;
4542 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4543 prepareIdSource( theObject );
4544 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4545 rotate(elements,theAxis,theAngle,theCopy,false);
4548 //=======================================================================
4549 //function : RotateMakeGroups
4551 //=======================================================================
4553 SMESH::ListOfGroups*
4554 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
4555 const SMESH::AxisStruct& theAxis,
4556 CORBA::Double theAngle)
4557 throw (SALOME::SALOME_Exception)
4559 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4561 SMESH::ListOfGroups * aGroups = 0;
4562 if (theIDsOfElements.length() > 0)
4564 TIDSortedElemSet elements;
4565 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4566 aGroups = rotate(elements,theAxis,theAngle,true,true);
4568 if (!myIsPreviewMode) {
4569 dumpGroupsList(aPythonDump, aGroups);
4570 aPythonDump << this << ".RotateMakeGroups( "
4571 << theIDsOfElements << ", "
4573 << TVar( theAngle ) << " )";
4578 //=======================================================================
4579 //function : RotateObjectMakeGroups
4581 //=======================================================================
4583 SMESH::ListOfGroups*
4584 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4585 const SMESH::AxisStruct& theAxis,
4586 CORBA::Double theAngle)
4587 throw (SALOME::SALOME_Exception)
4589 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4591 SMESH::ListOfGroups * aGroups = 0;
4592 TIDSortedElemSet elements;
4593 prepareIdSource( theObject );
4594 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4595 aGroups = rotate(elements, theAxis, theAngle, true, true);
4597 if (!myIsPreviewMode) {
4598 dumpGroupsList(aPythonDump, aGroups);
4599 aPythonDump << this << ".RotateObjectMakeGroups( "
4600 << theObject << ", "
4602 << TVar( theAngle ) << " )";
4607 //=======================================================================
4608 //function : RotateMakeMesh
4610 //=======================================================================
4612 SMESH::SMESH_Mesh_ptr
4613 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
4614 const SMESH::AxisStruct& theAxis,
4615 CORBA::Double theAngleInRadians,
4616 CORBA::Boolean theCopyGroups,
4617 const char* theMeshName)
4618 throw (SALOME::SALOME_Exception)
4621 SMESH::SMESH_Mesh_var mesh;
4622 SMESH_Mesh_i* mesh_i;
4624 { // open new scope to dump "MakeMesh" command
4625 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4627 TPythonDump pydump; // to prevent dump at mesh creation
4629 mesh = makeMesh( theMeshName );
4630 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4632 if ( mesh_i && theIDsOfElements.length() > 0 )
4634 TIDSortedElemSet elements;
4635 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4636 rotate(elements, theAxis, theAngleInRadians,
4637 false, theCopyGroups, & mesh_i->GetImpl());
4638 mesh_i->CreateGroupServants();
4640 if ( !myIsPreviewMode ) {
4641 pydump << mesh << " = " << this << ".RotateMakeMesh( "
4642 << theIDsOfElements << ", "
4644 << TVar( theAngleInRadians ) << ", "
4645 << theCopyGroups << ", '"
4646 << theMeshName << "' )";
4651 if (!myIsPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
4652 mesh_i->GetGroups();
4654 return mesh._retn();
4656 SMESH_CATCH( SMESH::throwCorbaException );
4660 //=======================================================================
4661 //function : RotateObjectMakeMesh
4663 //=======================================================================
4665 SMESH::SMESH_Mesh_ptr
4666 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4667 const SMESH::AxisStruct& theAxis,
4668 CORBA::Double theAngleInRadians,
4669 CORBA::Boolean theCopyGroups,
4670 const char* theMeshName)
4671 throw (SALOME::SALOME_Exception)
4674 SMESH::SMESH_Mesh_var mesh;
4675 SMESH_Mesh_i* mesh_i;
4677 {// open new scope to dump "MakeMesh" command
4678 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4680 TPythonDump pydump; // to prevent dump at mesh creation
4681 mesh = makeMesh( theMeshName );
4682 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4684 TIDSortedElemSet elements;
4685 prepareIdSource( theObject );
4687 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4689 rotate(elements, theAxis, theAngleInRadians,
4690 false, theCopyGroups, & mesh_i->GetImpl());
4691 mesh_i->CreateGroupServants();
4693 if ( !myIsPreviewMode ) {
4694 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
4695 << theObject << ", "
4697 << TVar( theAngleInRadians ) << ", "
4698 << theCopyGroups << ", '"
4699 << theMeshName << "' )";
4704 if (!myIsPreviewMode && mesh_i)
4705 mesh_i->GetGroups();
4707 return mesh._retn();
4709 SMESH_CATCH( SMESH::throwCorbaException );
4713 //=======================================================================
4716 //=======================================================================
4718 SMESH::ListOfGroups*
4719 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
4720 const SMESH::PointStruct& thePoint,
4721 const SMESH::double_array& theScaleFact,
4722 CORBA::Boolean theCopy,
4724 ::SMESH_Mesh* theTargetMesh)
4725 throw (SALOME::SALOME_Exception)
4729 if ( theScaleFact.length() < 1 )
4730 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
4731 if ( theScaleFact.length() == 2 )
4732 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
4734 if ( theTargetMesh )
4737 TIDSortedElemSet elements;
4738 prepareIdSource( theObject );
4739 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4740 if ( !idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4745 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
4746 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
4748 double tol = std::numeric_limits<double>::max();
4751 #if OCC_VERSION_LARGE > 0x06070100
4752 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
4753 0, S[1], 0, thePoint.y * (1-S[1]),
4754 0, 0, S[2], thePoint.z * (1-S[2]) );
4756 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
4757 0, S[1], 0, thePoint.y * (1-S[1]),
4758 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
4761 TIDSortedElemSet copyElements;
4762 TIDSortedElemSet* workElements = &elements;
4763 if ( myIsPreviewMode )
4765 TPreviewMesh * tmpMesh = getPreviewMesh();
4766 tmpMesh->Copy( elements, copyElements);
4767 if ( !theCopy && !theTargetMesh )
4769 TIDSortedElemSet elemsAround, elemsAroundCopy;
4770 getElementsAround( elements, getMeshDS(), elemsAround );
4771 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4773 workElements = & copyElements;
4774 theMakeGroups = false;
4777 ::SMESH_MeshEditor::PGroupIDs groupIds =
4778 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4780 if ( theCopy && !myIsPreviewMode )
4782 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
4783 else declareMeshModified( /*isReComputeSafe=*/false );
4785 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4787 SMESH_CATCH( SMESH::throwCorbaException );
4791 //=======================================================================
4794 //=======================================================================
4796 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
4797 const SMESH::PointStruct& thePoint,
4798 const SMESH::double_array& theScaleFact,
4799 CORBA::Boolean theCopy)
4800 throw (SALOME::SALOME_Exception)
4802 if ( !myIsPreviewMode ) {
4803 TPythonDump() << this << ".Scale( "
4804 << theObject << ", "
4806 << TVar( theScaleFact ) << ", "
4809 scale(theObject, thePoint, theScaleFact, theCopy, false);
4813 //=======================================================================
4814 //function : ScaleMakeGroups
4816 //=======================================================================
4818 SMESH::ListOfGroups*
4819 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4820 const SMESH::PointStruct& thePoint,
4821 const SMESH::double_array& theScaleFact)
4822 throw (SALOME::SALOME_Exception)
4824 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4826 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
4827 if (!myIsPreviewMode) {
4828 dumpGroupsList(aPythonDump, aGroups);
4829 aPythonDump << this << ".Scale("
4832 << TVar( theScaleFact ) << ",True,True)";
4838 //=======================================================================
4839 //function : ScaleMakeMesh
4841 //=======================================================================
4843 SMESH::SMESH_Mesh_ptr
4844 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4845 const SMESH::PointStruct& thePoint,
4846 const SMESH::double_array& theScaleFact,
4847 CORBA::Boolean theCopyGroups,
4848 const char* theMeshName)
4849 throw (SALOME::SALOME_Exception)
4851 SMESH_Mesh_i* mesh_i;
4852 SMESH::SMESH_Mesh_var mesh;
4853 { // open new scope to dump "MakeMesh" command
4854 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4856 TPythonDump pydump; // to prevent dump at mesh creation
4857 mesh = makeMesh( theMeshName );
4858 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4862 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
4863 mesh_i->CreateGroupServants();
4865 if ( !myIsPreviewMode )
4866 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
4867 << theObject << ", "
4869 << TVar( theScaleFact ) << ", "
4870 << theCopyGroups << ", '"
4871 << theMeshName << "' )";
4875 if (!myIsPreviewMode && mesh_i)
4876 mesh_i->GetGroups();
4878 return mesh._retn();
4882 //=======================================================================
4883 //function : FindCoincidentNodes
4885 //=======================================================================
4887 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance,
4888 SMESH::array_of_long_array_out GroupsOfNodes)
4889 throw (SALOME::SALOME_Exception)
4894 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4895 TIDSortedNodeSet nodes; // no input nodes
4896 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4898 GroupsOfNodes = new SMESH::array_of_long_array;
4899 GroupsOfNodes->length( aListOfListOfNodes.size() );
4900 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4901 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
4902 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4903 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4904 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4905 aGroup.length( aListOfNodes.size() );
4906 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4907 aGroup[ j ] = (*lIt)->GetID();
4909 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
4910 << Tolerance << " )";
4912 SMESH_CATCH( SMESH::throwCorbaException );
4915 //=======================================================================
4916 //function : FindCoincidentNodesOnPart
4918 //=======================================================================
4920 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
4921 CORBA::Double Tolerance,
4922 SMESH::array_of_long_array_out GroupsOfNodes)
4923 throw (SALOME::SALOME_Exception)
4928 TIDSortedNodeSet nodes;
4929 prepareIdSource( theObject );
4930 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4932 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4934 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4936 GroupsOfNodes = new SMESH::array_of_long_array;
4937 GroupsOfNodes->length( aListOfListOfNodes.size() );
4938 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4939 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4941 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4942 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4943 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4944 aGroup.length( aListOfNodes.size() );
4945 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4946 aGroup[ j ] = (*lIt)->GetID();
4948 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
4950 << Tolerance << " )";
4952 SMESH_CATCH( SMESH::throwCorbaException );
4955 //================================================================================
4957 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
4958 * ExceptSubMeshOrGroups
4960 //================================================================================
4962 void SMESH_MeshEditor_i::
4963 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
4964 CORBA::Double theTolerance,
4965 SMESH::array_of_long_array_out theGroupsOfNodes,
4966 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups)
4967 throw (SALOME::SALOME_Exception)
4972 TIDSortedNodeSet nodes;
4973 prepareIdSource( theObject );
4974 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4976 for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
4978 TIDSortedNodeSet exceptNodes;
4979 idSourceToNodeSet( theExceptSubMeshOrGroups[i], getMeshDS(), exceptNodes );
4980 TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
4981 for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
4982 nodes.erase( *avoidNode );
4984 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4986 getEditor().FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
4988 theGroupsOfNodes = new SMESH::array_of_long_array;
4989 theGroupsOfNodes->length( aListOfListOfNodes.size() );
4990 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4991 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4993 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4994 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4995 SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
4996 aGroup.length( aListOfNodes.size() );
4997 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4998 aGroup[ j ] = (*lIt)->GetID();
5000 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
5002 << theTolerance << ", "
5003 << theExceptSubMeshOrGroups << " )";
5005 SMESH_CATCH( SMESH::throwCorbaException );
5008 //=======================================================================
5009 //function : MergeNodes
5011 //=======================================================================
5013 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
5014 throw (SALOME::SALOME_Exception)
5019 SMESHDS_Mesh* aMesh = getMeshDS();
5021 TPythonDump aTPythonDump;
5022 aTPythonDump << this << ".MergeNodes([";
5023 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
5024 for (int i = 0; i < GroupsOfNodes.length(); i++)
5026 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
5027 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
5028 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
5029 for ( int j = 0; j < aNodeGroup.length(); j++ )
5031 CORBA::Long index = aNodeGroup[ j ];
5032 const SMDS_MeshNode * node = aMesh->FindNode(index);
5034 aListOfNodes.push_back( node );
5036 if ( aListOfNodes.size() < 2 )
5037 aListOfListOfNodes.pop_back();
5039 if ( i > 0 ) aTPythonDump << ", ";
5040 aTPythonDump << aNodeGroup;
5042 getEditor().MergeNodes( aListOfListOfNodes );
5044 aTPythonDump << "])";
5046 declareMeshModified( /*isReComputeSafe=*/false );
5048 SMESH_CATCH( SMESH::throwCorbaException );
5051 //=======================================================================
5052 //function : FindEqualElements
5054 //=======================================================================
5056 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
5057 SMESH::array_of_long_array_out GroupsOfElementsID)
5058 throw (SALOME::SALOME_Exception)
5063 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
5064 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
5066 TIDSortedElemSet elems;
5067 prepareIdSource( theObject );
5068 idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true);
5070 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
5071 getEditor().FindEqualElements( elems, aListOfListOfElementsID );
5073 GroupsOfElementsID = new SMESH::array_of_long_array;
5074 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
5076 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt =
5077 aListOfListOfElementsID.begin();
5078 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j)
5080 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
5081 list<int>& listOfIDs = *arraysIt;
5082 aGroup.length( listOfIDs.size() );
5083 list<int>::iterator idIt = listOfIDs.begin();
5084 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k )
5085 aGroup[ k ] = *idIt;
5088 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
5092 SMESH_CATCH( SMESH::throwCorbaException );
5095 //=======================================================================
5096 //function : MergeElements
5098 //=======================================================================
5100 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
5101 throw (SALOME::SALOME_Exception)
5106 TPythonDump aTPythonDump;
5107 aTPythonDump << this << ".MergeElements( [";
5109 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
5111 for (int i = 0; i < GroupsOfElementsID.length(); i++) {
5112 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
5113 aListOfListOfElementsID.push_back( list< int >() );
5114 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
5115 for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
5116 CORBA::Long id = anElemsIDGroup[ j ];
5117 aListOfElemsID.push_back( id );
5119 if ( aListOfElemsID.size() < 2 )
5120 aListOfListOfElementsID.pop_back();
5121 if ( i > 0 ) aTPythonDump << ", ";
5122 aTPythonDump << anElemsIDGroup;
5125 getEditor().MergeElements(aListOfListOfElementsID);
5127 declareMeshModified( /*isReComputeSafe=*/true );
5129 aTPythonDump << "] )";
5131 SMESH_CATCH( SMESH::throwCorbaException );
5134 //=======================================================================
5135 //function : MergeEqualElements
5137 //=======================================================================
5139 void SMESH_MeshEditor_i::MergeEqualElements()
5140 throw (SALOME::SALOME_Exception)
5145 getEditor().MergeEqualElements();
5147 declareMeshModified( /*isReComputeSafe=*/true );
5149 TPythonDump() << this << ".MergeEqualElements()";
5151 SMESH_CATCH( SMESH::throwCorbaException );
5154 //=============================================================================
5156 * Move the node to a given point
5158 //=============================================================================
5160 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
5164 throw (SALOME::SALOME_Exception)
5167 initData(/*deleteSearchers=*/false);
5169 const SMDS_MeshNode * node = getMeshDS()->FindNode( NodeID );
5173 if ( theNodeSearcher )
5174 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5176 if ( myIsPreviewMode ) // make preview data
5178 // in a preview mesh, make edges linked to a node
5179 TPreviewMesh& tmpMesh = *getPreviewMesh();
5180 TIDSortedElemSet linkedNodes;
5181 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
5182 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
5183 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
5184 for ( ; nIt != linkedNodes.end(); ++nIt )
5186 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
5187 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
5191 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
5192 // fill preview data
5194 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
5195 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
5197 getMeshDS()->MoveNode(node, x, y, z);
5199 if ( !myIsPreviewMode )
5201 // Update Python script
5202 TPythonDump() << "isDone = " << this << ".MoveNode( "
5203 << NodeID << ", " << TVar(x) << ", " << TVar(y) << ", " << TVar(z) << " )";
5204 declareMeshModified( /*isReComputeSafe=*/false );
5207 SMESH_CATCH( SMESH::throwCorbaException );
5212 //================================================================================
5214 * \brief Return ID of node closest to a given point
5216 //================================================================================
5218 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
5221 throw (SALOME::SALOME_Exception)
5224 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5226 if ( !theNodeSearcher ) {
5227 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
5230 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
5231 return node->GetID();
5233 SMESH_CATCH( SMESH::throwCorbaException );
5237 //================================================================================
5239 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
5240 * move the node closest to the point to point's location and return ID of the node
5242 //================================================================================
5244 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
5247 CORBA::Long theNodeID)
5248 throw (SALOME::SALOME_Exception)
5251 // We keep theNodeSearcher until any mesh modification:
5252 // 1) initData() deletes theNodeSearcher at any edition,
5253 // 2) TSearchersDeleter - at any mesh compute event and mesh change
5255 initData(/*deleteSearchers=*/false);
5257 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5259 int nodeID = theNodeID;
5260 const SMDS_MeshNode* node = getMeshDS()->FindNode( nodeID );
5261 if ( !node ) // preview moving node
5263 if ( !theNodeSearcher ) {
5264 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
5267 node = theNodeSearcher->FindClosestTo( p );
5270 nodeID = node->GetID();
5271 if ( myIsPreviewMode ) // make preview data
5273 // in a preview mesh, make edges linked to a node
5274 TPreviewMesh tmpMesh = *getPreviewMesh();
5275 TIDSortedElemSet linkedNodes;
5276 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
5277 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
5278 for ( ; nIt != linkedNodes.end(); ++nIt )
5280 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
5281 tmpMesh.Copy( &edge );
5284 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
5286 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
5287 // fill preview data
5289 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
5291 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
5295 getMeshDS()->MoveNode(node, x, y, z);
5299 if ( !myIsPreviewMode )
5301 TPythonDump() << "nodeID = " << this
5302 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
5303 << ", " << nodeID << " )";
5305 declareMeshModified( /*isReComputeSafe=*/false );
5310 SMESH_CATCH( SMESH::throwCorbaException );
5314 //=======================================================================
5316 * Return elements of given type where the given point is IN or ON.
5318 * 'ALL' type means elements of any type excluding nodes
5320 //=======================================================================
5322 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
5325 SMESH::ElementType type)
5326 throw (SALOME::SALOME_Exception)
5329 SMESH::long_array_var res = new SMESH::long_array;
5330 vector< const SMDS_MeshElement* > foundElems;
5332 theSearchersDeleter.Set( myMesh );
5333 if ( !theElementSearcher ) {
5334 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
5336 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
5337 SMDSAbs_ElementType( type ),
5339 res->length( foundElems.size() );
5340 for ( int i = 0; i < foundElems.size(); ++i )
5341 res[i] = foundElems[i]->GetID();
5345 SMESH_CATCH( SMESH::throwCorbaException );
5349 //=======================================================================
5350 //function : FindAmongElementsByPoint
5351 //purpose : Searching among the given elements, return elements of given type
5352 // where the given point is IN or ON.
5353 // 'ALL' type means elements of any type excluding nodes
5354 //=======================================================================
5357 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
5361 SMESH::ElementType type)
5362 throw (SALOME::SALOME_Exception)
5365 SMESH::long_array_var res = new SMESH::long_array;
5367 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
5368 if ( types->length() == 1 && // a part contains only nodes or 0D elements
5369 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) &&
5370 type != types[0] ) // but search of elements of dim > 0
5373 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
5374 return FindElementsByPoint( x,y,z, type );
5376 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
5378 theSearchersDeleter.Set( myMesh, getPartIOR( elementIDs, type ));
5379 if ( !theElementSearcher )
5381 // create a searcher from elementIDs
5382 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
5383 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
5385 if ( !idSourceToSet( elementIDs, meshDS, elements,
5386 SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
5389 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5390 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
5392 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt );
5395 vector< const SMDS_MeshElement* > foundElems;
5397 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
5398 SMDSAbs_ElementType( type ),
5400 res->length( foundElems.size() );
5401 for ( int i = 0; i < foundElems.size(); ++i )
5402 res[i] = foundElems[i]->GetID();
5406 SMESH_CATCH( SMESH::throwCorbaException );
5410 //=======================================================================
5411 //function : GetPointState
5412 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
5413 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
5414 //=======================================================================
5416 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
5419 throw (SALOME::SALOME_Exception)
5422 theSearchersDeleter.Set( myMesh );
5423 if ( !theElementSearcher ) {
5424 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
5426 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
5428 SMESH_CATCH( SMESH::throwCorbaException );
5432 //=======================================================================
5433 //function : convError
5435 //=======================================================================
5437 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
5439 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
5443 RETCASE( SEW_BORDER1_NOT_FOUND );
5444 RETCASE( SEW_BORDER2_NOT_FOUND );
5445 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
5446 RETCASE( SEW_BAD_SIDE_NODES );
5447 RETCASE( SEW_VOLUMES_TO_SPLIT );
5448 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
5449 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
5450 RETCASE( SEW_BAD_SIDE1_NODES );
5451 RETCASE( SEW_BAD_SIDE2_NODES );
5453 return SMESH::SMESH_MeshEditor::SEW_OK;
5456 //=======================================================================
5457 //function : SewFreeBorders
5459 //=======================================================================
5461 SMESH::SMESH_MeshEditor::Sew_Error
5462 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
5463 CORBA::Long SecondNodeID1,
5464 CORBA::Long LastNodeID1,
5465 CORBA::Long FirstNodeID2,
5466 CORBA::Long SecondNodeID2,
5467 CORBA::Long LastNodeID2,
5468 CORBA::Boolean CreatePolygons,
5469 CORBA::Boolean CreatePolyedrs)
5470 throw (SALOME::SALOME_Exception)
5475 SMESHDS_Mesh* aMesh = getMeshDS();
5477 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
5478 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
5479 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
5480 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
5481 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
5482 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
5484 if (!aBorderFirstNode ||
5485 !aBorderSecondNode||
5487 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5488 if (!aSide2FirstNode ||
5489 !aSide2SecondNode ||
5491 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
5493 TPythonDump() << "error = " << this << ".SewFreeBorders( "
5494 << FirstNodeID1 << ", "
5495 << SecondNodeID1 << ", "
5496 << LastNodeID1 << ", "
5497 << FirstNodeID2 << ", "
5498 << SecondNodeID2 << ", "
5499 << LastNodeID2 << ", "
5500 << CreatePolygons<< ", "
5501 << CreatePolyedrs<< " )";
5503 SMESH::SMESH_MeshEditor::Sew_Error error =
5504 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5515 declareMeshModified( /*isReComputeSafe=*/false );
5518 SMESH_CATCH( SMESH::throwCorbaException );
5519 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5523 //=======================================================================
5524 //function : SewConformFreeBorders
5526 //=======================================================================
5528 SMESH::SMESH_MeshEditor::Sew_Error
5529 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
5530 CORBA::Long SecondNodeID1,
5531 CORBA::Long LastNodeID1,
5532 CORBA::Long FirstNodeID2,
5533 CORBA::Long SecondNodeID2)
5534 throw (SALOME::SALOME_Exception)
5539 SMESHDS_Mesh* aMesh = getMeshDS();
5541 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
5542 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
5543 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
5544 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
5545 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
5546 const SMDS_MeshNode* aSide2ThirdNode = 0;
5548 if (!aBorderFirstNode ||
5549 !aBorderSecondNode||
5551 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5552 if (!aSide2FirstNode ||
5554 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
5556 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
5557 << FirstNodeID1 << ", "
5558 << SecondNodeID1 << ", "
5559 << LastNodeID1 << ", "
5560 << FirstNodeID2 << ", "
5561 << SecondNodeID2 << " )";
5563 SMESH::SMESH_MeshEditor::Sew_Error error =
5564 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5573 declareMeshModified( /*isReComputeSafe=*/false );
5576 SMESH_CATCH( SMESH::throwCorbaException );
5577 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5581 //=======================================================================
5582 //function : SewBorderToSide
5584 //=======================================================================
5586 SMESH::SMESH_MeshEditor::Sew_Error
5587 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
5588 CORBA::Long SecondNodeIDOnFreeBorder,
5589 CORBA::Long LastNodeIDOnFreeBorder,
5590 CORBA::Long FirstNodeIDOnSide,
5591 CORBA::Long LastNodeIDOnSide,
5592 CORBA::Boolean CreatePolygons,
5593 CORBA::Boolean CreatePolyedrs)
5594 throw (SALOME::SALOME_Exception)
5599 SMESHDS_Mesh* aMesh = getMeshDS();
5601 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
5602 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
5603 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
5604 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
5605 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
5606 const SMDS_MeshNode* aSide2ThirdNode = 0;
5608 if (!aBorderFirstNode ||
5609 !aBorderSecondNode||
5611 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5612 if (!aSide2FirstNode ||
5614 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
5616 TPythonDump() << "error = " << this << ".SewBorderToSide( "
5617 << FirstNodeIDOnFreeBorder << ", "
5618 << SecondNodeIDOnFreeBorder << ", "
5619 << LastNodeIDOnFreeBorder << ", "
5620 << FirstNodeIDOnSide << ", "
5621 << LastNodeIDOnSide << ", "
5622 << CreatePolygons << ", "
5623 << CreatePolyedrs << ") ";
5625 SMESH::SMESH_MeshEditor::Sew_Error error =
5626 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5636 declareMeshModified( /*isReComputeSafe=*/false );
5639 SMESH_CATCH( SMESH::throwCorbaException );
5640 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5644 //=======================================================================
5645 //function : SewSideElements
5647 //=======================================================================
5649 SMESH::SMESH_MeshEditor::Sew_Error
5650 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
5651 const SMESH::long_array& IDsOfSide2Elements,
5652 CORBA::Long NodeID1OfSide1ToMerge,
5653 CORBA::Long NodeID1OfSide2ToMerge,
5654 CORBA::Long NodeID2OfSide1ToMerge,
5655 CORBA::Long NodeID2OfSide2ToMerge)
5656 throw (SALOME::SALOME_Exception)
5661 SMESHDS_Mesh* aMesh = getMeshDS();
5663 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
5664 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
5665 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
5666 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
5668 if (!aFirstNode1ToMerge ||
5669 !aFirstNode2ToMerge )
5670 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
5671 if (!aSecondNode1ToMerge||
5672 !aSecondNode2ToMerge)
5673 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
5675 TIDSortedElemSet aSide1Elems, aSide2Elems;
5676 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
5677 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
5679 TPythonDump() << "error = " << this << ".SewSideElements( "
5680 << IDsOfSide1Elements << ", "
5681 << IDsOfSide2Elements << ", "
5682 << NodeID1OfSide1ToMerge << ", "
5683 << NodeID1OfSide2ToMerge << ", "
5684 << NodeID2OfSide1ToMerge << ", "
5685 << NodeID2OfSide2ToMerge << ")";
5687 SMESH::SMESH_MeshEditor::Sew_Error error =
5688 convError( getEditor().SewSideElements (aSide1Elems, aSide2Elems,
5691 aSecondNode1ToMerge,
5692 aSecondNode2ToMerge));
5694 declareMeshModified( /*isReComputeSafe=*/false );
5697 SMESH_CATCH( SMESH::throwCorbaException );
5698 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5701 //================================================================================
5703 * \brief Set new nodes for given element
5704 * \param ide - element id
5705 * \param newIDs - new node ids
5706 * \retval CORBA::Boolean - true if result is OK
5708 //================================================================================
5710 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
5711 const SMESH::long_array& newIDs)
5712 throw (SALOME::SALOME_Exception)
5717 const SMDS_MeshElement* elem = getMeshDS()->FindElement(ide);
5718 if(!elem) return false;
5720 int nbn = newIDs.length();
5722 vector<const SMDS_MeshNode*> aNodes(nbn);
5725 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(newIDs[i]);
5728 aNodes[nbn1] = aNode;
5731 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
5732 << ide << ", " << newIDs << " )";
5734 MESSAGE("ChangeElementNodes");
5735 bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
5737 declareMeshModified( /*isReComputeSafe=*/ !res );
5741 SMESH_CATCH( SMESH::throwCorbaException );
5745 //=======================================================================
5747 * \brief Makes a part of the mesh quadratic or bi-quadratic
5749 //=======================================================================
5751 void SMESH_MeshEditor_i::convertToQuadratic(CORBA::Boolean theForce3d,
5752 CORBA::Boolean theToBiQuad,
5753 SMESH::SMESH_IDSource_ptr theObject)
5754 throw (SALOME::SALOME_Exception)
5757 TIDSortedElemSet elems;
5759 if ( !( elemsOK = CORBA::is_nil( theObject )))
5761 prepareIdSource( theObject );
5762 elemsOK = idSourceToSet( theObject, getMeshDS(), elems,
5763 SMDSAbs_All, /*emptyIfIsMesh=*/true );
5767 if ( !elems.empty() && (*elems.begin())->GetType() == SMDSAbs_Node )
5768 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5770 if ( elems.empty() ) getEditor().ConvertToQuadratic(theForce3d, theToBiQuad);
5771 else getEditor().ConvertToQuadratic(theForce3d, elems, theToBiQuad);
5773 declareMeshModified( /*isReComputeSafe=*/false );
5776 SMESH_CATCH( SMESH::throwCorbaException );
5779 //=======================================================================
5780 //function : ConvertFromQuadratic
5782 //=======================================================================
5784 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
5785 throw (SALOME::SALOME_Exception)
5787 CORBA::Boolean isDone = getEditor().ConvertFromQuadratic();
5788 TPythonDump() << this << ".ConvertFromQuadratic()";
5789 declareMeshModified( /*isReComputeSafe=*/!isDone );
5793 //=======================================================================
5794 //function : ConvertToQuadratic
5796 //=======================================================================
5798 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
5799 throw (SALOME::SALOME_Exception)
5801 convertToQuadratic( theForce3d, false );
5802 TPythonDump() << this << ".ConvertToQuadratic("<<theForce3d<<")";
5805 //================================================================================
5807 * \brief Makes a part of the mesh quadratic
5809 //================================================================================
5811 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
5812 SMESH::SMESH_IDSource_ptr theObject)
5813 throw (SALOME::SALOME_Exception)
5815 convertToQuadratic( theForce3d, false, theObject );
5816 TPythonDump() << this << ".ConvertToQuadraticObject("<<theForce3d<<", "<<theObject<<")";
5819 //================================================================================
5821 * \brief Makes a part of the mesh bi-quadratic
5823 //================================================================================
5825 void SMESH_MeshEditor_i::ConvertToBiQuadratic(CORBA::Boolean theForce3d,
5826 SMESH::SMESH_IDSource_ptr theObject)
5827 throw (SALOME::SALOME_Exception)
5829 convertToQuadratic( theForce3d, true, theObject );
5830 TPythonDump() << this << ".ConvertToBiQuadratic("<<theForce3d<<", "<<theObject<<")";
5833 //================================================================================
5835 * \brief Makes a part of the mesh linear
5837 //================================================================================
5839 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
5840 throw (SALOME::SALOME_Exception)
5846 TIDSortedElemSet elems;
5847 prepareIdSource( theObject );
5848 if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5850 if ( elems.empty() )
5852 ConvertFromQuadratic();
5854 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5856 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5860 getEditor().ConvertFromQuadratic(elems);
5863 declareMeshModified( /*isReComputeSafe=*/false );
5865 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
5867 SMESH_CATCH( SMESH::throwCorbaException );
5870 //=======================================================================
5871 //function : makeMesh
5872 //purpose : create a named imported mesh
5873 //=======================================================================
5875 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
5877 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
5878 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
5879 SALOMEDS::Study_var study = gen->GetCurrentStudy();
5880 SALOMEDS::SObject_wrap meshSO = gen->ObjectToSObject( study, mesh );
5881 gen->SetName( meshSO, theMeshName, "Mesh" );
5882 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
5884 return mesh._retn();
5887 //=======================================================================
5888 //function : dumpGroupsList
5890 //=======================================================================
5892 void SMESH_MeshEditor_i::dumpGroupsList(TPythonDump & theDumpPython,
5893 const SMESH::ListOfGroups * theGroupList)
5895 bool isDumpGroupList = ( theGroupList && theGroupList->length() > 0 );
5896 if ( isDumpGroupList )
5897 theDumpPython << theGroupList << " = ";
5900 //================================================================================
5902 \brief Generates the unique group name.
5903 \param thePrefix name prefix
5906 //================================================================================
5908 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
5910 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5911 set<string> groupNames;
5913 // Get existing group names
5914 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
5915 SMESH::SMESH_GroupBase_var aGroup = groups[i];
5916 if (CORBA::is_nil(aGroup))
5919 CORBA::String_var name = aGroup->GetName();
5920 groupNames.insert( name.in() );
5924 string name = thePrefix;
5927 while (!groupNames.insert(name).second)
5928 name = SMESH_Comment( thePrefix ) << "_" << index++;
5933 //================================================================================
5935 * \brief Prepare SMESH_IDSource for work
5937 //================================================================================
5939 void SMESH_MeshEditor_i::prepareIdSource(SMESH::SMESH_IDSource_ptr theObject)
5941 if ( SMESH::Filter_i* filter = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5943 SMESH::SMESH_Mesh_var mesh = myMesh_i->_this();
5944 filter->SetMesh( mesh );
5948 //================================================================================
5950 * \brief Duplicates given elements, i.e. creates new elements based on the
5951 * same nodes as the given ones.
5952 * \param theElements - container of elements to duplicate.
5953 * \param theGroupName - a name of group to contain the generated elements.
5954 * If a group with such a name already exists, the new elements
5955 * are added to the existng group, else a new group is created.
5956 * If \a theGroupName is empty, new elements are not added
5958 * \return a group where the new elements are added. NULL if theGroupName == "".
5961 //================================================================================
5963 SMESH::SMESH_Group_ptr
5964 SMESH_MeshEditor_i::DoubleElements(SMESH::SMESH_IDSource_ptr theElements,
5965 const char* theGroupName)
5966 throw (SALOME::SALOME_Exception)
5968 SMESH::SMESH_Group_var newGroup;
5975 TIDSortedElemSet elems;
5976 prepareIdSource( theElements );
5977 if ( idSourceToSet( theElements, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true))
5979 getEditor().DoubleElements( elems );
5981 if ( strlen( theGroupName ) && !getEditor().GetLastCreatedElems().IsEmpty() )
5984 SMESH::ElementType type =
5985 SMESH::ElementType( getEditor().GetLastCreatedElems().Value(1)->GetType() );
5986 // find existing group
5987 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5988 for ( size_t i = 0; i < groups->length(); ++i )
5989 if ( groups[i]->GetType() == type )
5991 CORBA::String_var name = groups[i]->GetName();
5992 if ( strcmp( name, theGroupName ) == 0 ) {
5993 newGroup = SMESH::SMESH_Group::_narrow( groups[i] );
5997 // create a new group
5998 if ( newGroup->_is_nil() )
5999 newGroup = myMesh_i->CreateGroup( type, theGroupName );
6001 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* >( newGroup ))
6003 SMESHDS_Group* groupDS = static_cast< SMESHDS_Group* >( group_i->GetGroupDS() );
6004 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
6005 for ( int i = 1; i <= aSeq.Length(); i++ )
6006 groupDS->SMDSGroup().Add( aSeq(i) );
6011 if ( !newGroup->_is_nil() )
6012 pyDump << newGroup << " = ";
6013 pyDump << this << ".DoubleElements( "
6014 << theElements << ", " << "'" << theGroupName <<"')";
6016 SMESH_CATCH( SMESH::throwCorbaException );
6018 return newGroup._retn();
6021 //================================================================================
6023 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6024 \param theNodes - identifiers of nodes to be doubled
6025 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
6026 nodes. If list of element identifiers is empty then nodes are doubled but
6027 they not assigned to elements
6028 \return TRUE if operation has been completed successfully, FALSE otherwise
6029 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
6031 //================================================================================
6033 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
6034 const SMESH::long_array& theModifiedElems )
6035 throw (SALOME::SALOME_Exception)
6040 list< int > aListOfNodes;
6042 for ( i = 0, n = theNodes.length(); i < n; i++ )
6043 aListOfNodes.push_back( theNodes[ i ] );
6045 list< int > aListOfElems;
6046 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
6047 aListOfElems.push_back( theModifiedElems[ i ] );
6049 bool aResult = getEditor().DoubleNodes( aListOfNodes, aListOfElems );
6051 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6053 // Update Python script
6054 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
6058 SMESH_CATCH( SMESH::throwCorbaException );
6062 //================================================================================
6064 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6065 This method provided for convenience works as DoubleNodes() described above.
6066 \param theNodeId - identifier of node to be doubled.
6067 \param theModifiedElems - identifiers of elements to be updated.
6068 \return TRUE if operation has been completed successfully, FALSE otherwise
6069 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
6071 //================================================================================
6073 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
6074 const SMESH::long_array& theModifiedElems )
6075 throw (SALOME::SALOME_Exception)
6078 SMESH::long_array_var aNodes = new SMESH::long_array;
6079 aNodes->length( 1 );
6080 aNodes[ 0 ] = theNodeId;
6082 TPythonDump pyDump; // suppress dump by the next line
6084 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
6086 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
6090 SMESH_CATCH( SMESH::throwCorbaException );
6094 //================================================================================
6096 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6097 This method provided for convenience works as DoubleNodes() described above.
6098 \param theNodes - group of nodes to be doubled.
6099 \param theModifiedElems - group of elements to be updated.
6100 \return TRUE if operation has been completed successfully, FALSE otherwise
6101 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
6103 //================================================================================
6105 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
6106 SMESH::SMESH_GroupBase_ptr theModifiedElems )
6107 throw (SALOME::SALOME_Exception)
6110 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
6113 SMESH::long_array_var aNodes = theNodes->GetListOfID();
6114 SMESH::long_array_var aModifiedElems;
6115 if ( !CORBA::is_nil( theModifiedElems ) )
6116 aModifiedElems = theModifiedElems->GetListOfID();
6119 aModifiedElems = new SMESH::long_array;
6120 aModifiedElems->length( 0 );
6123 TPythonDump pyDump; // suppress dump by the next line
6125 bool done = DoubleNodes( aNodes, aModifiedElems );
6127 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
6131 SMESH_CATCH( SMESH::throwCorbaException );
6135 //================================================================================
6137 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6138 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
6139 * \param theNodes - group of nodes to be doubled.
6140 * \param theModifiedElems - group of elements to be updated.
6141 * \return a new group with newly created nodes
6142 * \sa DoubleNodeGroup()
6144 //================================================================================
6146 SMESH::SMESH_Group_ptr
6147 SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
6148 SMESH::SMESH_GroupBase_ptr theModifiedElems )
6149 throw (SALOME::SALOME_Exception)
6152 SMESH::SMESH_Group_var aNewGroup;
6154 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
6155 return aNewGroup._retn();
6158 SMESH::long_array_var aNodes = theNodes->GetListOfID();
6159 SMESH::long_array_var aModifiedElems;
6160 if ( !CORBA::is_nil( theModifiedElems ) )
6161 aModifiedElems = theModifiedElems->GetListOfID();
6163 aModifiedElems = new SMESH::long_array;
6164 aModifiedElems->length( 0 );
6167 TPythonDump pyDump; // suppress dump by the next line
6169 bool aResult = DoubleNodes( aNodes, aModifiedElems );
6172 // Create group with newly created nodes
6173 SMESH::long_array_var anIds = GetLastCreatedNodes();
6174 if (anIds->length() > 0) {
6175 string anUnindexedName (theNodes->GetName());
6176 string aNewName = generateGroupName(anUnindexedName + "_double");
6177 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6178 aNewGroup->Add(anIds);
6179 pyDump << aNewGroup << " = ";
6183 pyDump << this << ".DoubleNodeGroupNew( " << theNodes << ", "
6184 << theModifiedElems << " )";
6186 return aNewGroup._retn();
6188 SMESH_CATCH( SMESH::throwCorbaException );
6192 //================================================================================
6194 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6195 This method provided for convenience works as DoubleNodes() described above.
6196 \param theNodes - list of groups of nodes to be doubled
6197 \param theModifiedElems - list of groups of elements to be updated.
6198 \return TRUE if operation has been completed successfully, FALSE otherwise
6199 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
6201 //================================================================================
6203 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
6204 const SMESH::ListOfGroups& theModifiedElems )
6205 throw (SALOME::SALOME_Exception)
6210 std::list< int > aNodes;
6212 for ( i = 0, n = theNodes.length(); i < n; i++ )
6214 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
6215 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
6217 SMESH::long_array_var aCurr = aGrp->GetListOfID();
6218 for ( j = 0, m = aCurr->length(); j < m; j++ )
6219 aNodes.push_back( aCurr[ j ] );
6223 std::list< int > anElems;
6224 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
6226 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
6227 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
6229 SMESH::long_array_var aCurr = aGrp->GetListOfID();
6230 for ( j = 0, m = aCurr->length(); j < m; j++ )
6231 anElems.push_back( aCurr[ j ] );
6235 bool aResult = getEditor().DoubleNodes( aNodes, anElems );
6237 declareMeshModified( /*isReComputeSafe=*/false );
6239 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
6243 SMESH_CATCH( SMESH::throwCorbaException );
6247 //================================================================================
6249 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6250 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
6251 * \param theNodes - group of nodes to be doubled.
6252 * \param theModifiedElems - group of elements to be updated.
6253 * \return a new group with newly created nodes
6254 * \sa DoubleNodeGroups()
6256 //================================================================================
6258 SMESH::SMESH_Group_ptr
6259 SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
6260 const SMESH::ListOfGroups& theModifiedElems )
6261 throw (SALOME::SALOME_Exception)
6263 SMESH::SMESH_Group_var aNewGroup;
6265 TPythonDump pyDump; // suppress dump by the next line
6267 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
6271 // Create group with newly created nodes
6272 SMESH::long_array_var anIds = GetLastCreatedNodes();
6273 if (anIds->length() > 0) {
6274 string anUnindexedName (theNodes[0]->GetName());
6275 string aNewName = generateGroupName(anUnindexedName + "_double");
6276 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6277 aNewGroup->Add(anIds);
6278 pyDump << aNewGroup << " = ";
6282 pyDump << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
6283 << theModifiedElems << " )";
6285 return aNewGroup._retn();
6289 //================================================================================
6291 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6292 \param theElems - the list of elements (edges or faces) to be replicated
6293 The nodes for duplication could be found from these elements
6294 \param theNodesNot - list of nodes to NOT replicate
6295 \param theAffectedElems - the list of elements (cells and edges) to which the
6296 replicated nodes should be associated to.
6297 \return TRUE if operation has been completed successfully, FALSE otherwise
6298 \sa DoubleNodeGroup(), DoubleNodeGroups()
6300 //================================================================================
6302 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
6303 const SMESH::long_array& theNodesNot,
6304 const SMESH::long_array& theAffectedElems )
6305 throw (SALOME::SALOME_Exception)
6310 SMESHDS_Mesh* aMeshDS = getMeshDS();
6311 TIDSortedElemSet anElems, aNodes, anAffected;
6312 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
6313 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
6314 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
6316 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6318 // Update Python script
6319 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
6320 << theNodesNot << ", " << theAffectedElems << " )";
6322 declareMeshModified( /*isReComputeSafe=*/false );
6325 SMESH_CATCH( SMESH::throwCorbaException );
6329 //================================================================================
6331 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6332 \param theElems - the list of elements (edges or faces) to be replicated
6333 The nodes for duplication could be found from these elements
6334 \param theNodesNot - list of nodes to NOT replicate
6335 \param theShape - shape to detect affected elements (element which geometric center
6336 located on or inside shape).
6337 The replicated nodes should be associated to affected elements.
6338 \return TRUE if operation has been completed successfully, FALSE otherwise
6339 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
6341 //================================================================================
6343 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
6344 const SMESH::long_array& theNodesNot,
6345 GEOM::GEOM_Object_ptr theShape )
6346 throw (SALOME::SALOME_Exception)
6352 SMESHDS_Mesh* aMeshDS = getMeshDS();
6353 TIDSortedElemSet anElems, aNodes;
6354 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
6355 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
6357 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6358 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6360 // Update Python script
6361 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
6362 << theNodesNot << ", " << theShape << " )";
6364 declareMeshModified( /*isReComputeSafe=*/false );
6367 SMESH_CATCH( SMESH::throwCorbaException );
6371 //================================================================================
6373 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6374 \param theElems - group of of elements (edges or faces) to be replicated
6375 \param theNodesNot - group of nodes not to replicated
6376 \param theAffectedElems - group of elements to which the replicated nodes
6377 should be associated to.
6378 \return TRUE if operation has been completed successfully, FALSE otherwise
6379 \sa DoubleNodes(), DoubleNodeGroups()
6381 //================================================================================
6384 SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
6385 SMESH::SMESH_GroupBase_ptr theNodesNot,
6386 SMESH::SMESH_GroupBase_ptr theAffectedElems)
6387 throw (SALOME::SALOME_Exception)
6390 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6396 SMESHDS_Mesh* aMeshDS = getMeshDS();
6397 TIDSortedElemSet anElems, aNodes, anAffected;
6398 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6399 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6400 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
6402 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6404 // Update Python script
6405 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
6406 << theNodesNot << ", " << theAffectedElems << " )";
6408 declareMeshModified( /*isReComputeSafe=*/false );
6411 SMESH_CATCH( SMESH::throwCorbaException );
6415 //================================================================================
6417 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6418 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
6419 * \param theElems - group of of elements (edges or faces) to be replicated
6420 * \param theNodesNot - group of nodes not to replicated
6421 * \param theAffectedElems - group of elements to which the replicated nodes
6422 * should be associated to.
6423 * \return a new group with newly created elements
6424 * \sa DoubleNodeElemGroup()
6426 //================================================================================
6428 SMESH::SMESH_Group_ptr
6429 SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
6430 SMESH::SMESH_GroupBase_ptr theNodesNot,
6431 SMESH::SMESH_GroupBase_ptr theAffectedElems)
6432 throw (SALOME::SALOME_Exception)
6435 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroup2New( theElems,
6439 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
6440 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
6442 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupNew( "
6444 << theNodesNot << ", "
6445 << theAffectedElems << " )";
6447 return elemGroup._retn();
6450 //================================================================================
6452 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6453 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
6454 * \param theElems - group of of elements (edges or faces) to be replicated
6455 * \param theNodesNot - group of nodes not to replicated
6456 * \param theAffectedElems - group of elements to which the replicated nodes
6457 * should be associated to.
6458 * \return a new group with newly created elements
6459 * \sa DoubleNodeElemGroup()
6461 //================================================================================
6463 SMESH::ListOfGroups*
6464 SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
6465 SMESH::SMESH_GroupBase_ptr theNodesNot,
6466 SMESH::SMESH_GroupBase_ptr theAffectedElems,
6467 CORBA::Boolean theElemGroupNeeded,
6468 CORBA::Boolean theNodeGroupNeeded)
6469 throw (SALOME::SALOME_Exception)
6472 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
6473 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
6474 aTwoGroups->length( 2 );
6476 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6477 return aTwoGroups._retn();
6482 SMESHDS_Mesh* aMeshDS = getMeshDS();
6483 TIDSortedElemSet anElems, aNodes, anAffected;
6484 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6485 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6486 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
6489 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6491 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6497 // Create group with newly created elements
6498 CORBA::String_var elemGroupName = theElems->GetName();
6499 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
6500 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
6502 SMESH::long_array_var anIds = GetLastCreatedElems();
6503 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
6504 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
6505 aNewElemGroup->Add(anIds);
6507 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
6509 SMESH::long_array_var anIds = GetLastCreatedNodes();
6510 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6511 aNewNodeGroup->Add(anIds);
6515 // Update Python script
6518 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
6519 else pyDump << aNewElemGroup << ", ";
6520 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
6521 else pyDump << aNewNodeGroup << " ] = ";
6523 pyDump << this << ".DoubleNodeElemGroup2New( " << theElems << ", "
6524 << theNodesNot << ", "
6525 << theAffectedElems << ", "
6526 << theElemGroupNeeded << ", "
6527 << theNodeGroupNeeded <<" )";
6529 aTwoGroups[0] = aNewElemGroup._retn();
6530 aTwoGroups[1] = aNewNodeGroup._retn();
6531 return aTwoGroups._retn();
6533 SMESH_CATCH( SMESH::throwCorbaException );
6537 //================================================================================
6539 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6540 \param theElems - group of of elements (edges or faces) to be replicated
6541 \param theNodesNot - group of nodes not to replicated
6542 \param theShape - shape to detect affected elements (element which geometric center
6543 located on or inside shape).
6544 The replicated nodes should be associated to affected elements.
6545 \return TRUE if operation has been completed successfully, FALSE otherwise
6546 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
6548 //================================================================================
6551 SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
6552 SMESH::SMESH_GroupBase_ptr theNodesNot,
6553 GEOM::GEOM_Object_ptr theShape )
6554 throw (SALOME::SALOME_Exception)
6557 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6563 SMESHDS_Mesh* aMeshDS = getMeshDS();
6564 TIDSortedElemSet anElems, aNodes, anAffected;
6565 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6566 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6568 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6569 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6572 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6574 // Update Python script
6575 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
6576 << theNodesNot << ", " << theShape << " )";
6579 SMESH_CATCH( SMESH::throwCorbaException );
6583 //================================================================================
6585 * \brief Re-load elements from a list of groups into a TIDSortedElemSet
6586 * \param [in] theGrpList - groups
6587 * \param [in] theMeshDS - mesh
6588 * \param [out] theElemSet - set of elements
6589 * \param [in] theIsNodeGrp - is \a theGrpList includes goups of nodes
6591 //================================================================================
6593 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
6594 SMESHDS_Mesh* theMeshDS,
6595 TIDSortedElemSet& theElemSet,
6596 const bool theIsNodeGrp)
6598 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
6600 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
6601 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
6602 : aGrp->GetType() != SMESH::NODE ) )
6604 SMESH::long_array_var anIDs = aGrp->GetIDs();
6605 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
6610 //================================================================================
6612 \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6613 This method provided for convenience works as DoubleNodes() described above.
6614 \param theElems - list of groups of elements (edges or faces) to be replicated
6615 \param theNodesNot - list of groups of nodes not to replicated
6616 \param theAffectedElems - group of elements to which the replicated nodes
6617 should be associated to.
6618 \return TRUE if operation has been completed successfully, FALSE otherwise
6619 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
6621 //================================================================================
6624 SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
6625 const SMESH::ListOfGroups& theNodesNot,
6626 const SMESH::ListOfGroups& theAffectedElems)
6627 throw (SALOME::SALOME_Exception)
6633 SMESHDS_Mesh* aMeshDS = getMeshDS();
6634 TIDSortedElemSet anElems, aNodes, anAffected;
6635 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6636 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6637 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6639 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6641 // Update Python script
6642 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
6643 << &theNodesNot << ", " << &theAffectedElems << " )";
6645 declareMeshModified( /*isReComputeSafe=*/false );
6648 SMESH_CATCH( SMESH::throwCorbaException );
6652 //================================================================================
6654 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6655 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6656 \param theElems - list of groups of elements (edges or faces) to be replicated
6657 \param theNodesNot - list of groups of nodes not to replicated
6658 \param theAffectedElems - group of elements to which the replicated nodes
6659 should be associated to.
6660 * \return a new group with newly created elements
6661 * \sa DoubleNodeElemGroups()
6663 //================================================================================
6665 SMESH::SMESH_Group_ptr
6666 SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
6667 const SMESH::ListOfGroups& theNodesNot,
6668 const SMESH::ListOfGroups& theAffectedElems)
6669 throw (SALOME::SALOME_Exception)
6672 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroups2New( theElems,
6676 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
6677 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
6679 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupsNew( "
6681 << theNodesNot << ", "
6682 << theAffectedElems << " )";
6684 return elemGroup._retn();
6687 //================================================================================
6689 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6690 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6691 \param theElems - list of groups of elements (edges or faces) to be replicated
6692 \param theNodesNot - list of groups of nodes not to replicated
6693 \param theAffectedElems - group of elements to which the replicated nodes
6694 should be associated to.
6695 * \return a new group with newly created elements
6696 * \sa DoubleNodeElemGroups()
6698 //================================================================================
6700 SMESH::ListOfGroups*
6701 SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems,
6702 const SMESH::ListOfGroups& theNodesNot,
6703 const SMESH::ListOfGroups& theAffectedElems,
6704 CORBA::Boolean theElemGroupNeeded,
6705 CORBA::Boolean theNodeGroupNeeded)
6706 throw (SALOME::SALOME_Exception)
6709 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
6710 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
6711 aTwoGroups->length( 2 );
6716 SMESHDS_Mesh* aMeshDS = getMeshDS();
6717 TIDSortedElemSet anElems, aNodes, anAffected;
6718 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6719 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6720 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6722 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6724 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6729 // Create group with newly created elements
6730 CORBA::String_var elemGroupName = theElems[0]->GetName();
6731 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
6732 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
6734 SMESH::long_array_var anIds = GetLastCreatedElems();
6735 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
6736 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
6737 aNewElemGroup->Add(anIds);
6739 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
6741 SMESH::long_array_var anIds = GetLastCreatedNodes();
6742 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6743 aNewNodeGroup->Add(anIds);
6747 // Update Python script
6750 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
6751 else pyDump << aNewElemGroup << ", ";
6752 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
6753 else pyDump << aNewNodeGroup << " ] = ";
6755 pyDump << this << ".DoubleNodeElemGroups2New( " << &theElems << ", "
6756 << &theNodesNot << ", "
6757 << &theAffectedElems << ", "
6758 << theElemGroupNeeded << ", "
6759 << theNodeGroupNeeded << " )";
6761 aTwoGroups[0] = aNewElemGroup._retn();
6762 aTwoGroups[1] = aNewNodeGroup._retn();
6763 return aTwoGroups._retn();
6765 SMESH_CATCH( SMESH::throwCorbaException );
6769 //================================================================================
6771 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6772 This method provided for convenience works as DoubleNodes() described above.
6773 \param theElems - list of groups of elements (edges or faces) to be replicated
6774 \param theNodesNot - list of groups of nodes not to replicated
6775 \param theShape - shape to detect affected elements (element which geometric center
6776 located on or inside shape).
6777 The replicated nodes should be associated to affected elements.
6778 \return TRUE if operation has been completed successfully, FALSE otherwise
6779 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
6781 //================================================================================
6784 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
6785 const SMESH::ListOfGroups& theNodesNot,
6786 GEOM::GEOM_Object_ptr theShape )
6787 throw (SALOME::SALOME_Exception)
6793 SMESHDS_Mesh* aMeshDS = getMeshDS();
6794 TIDSortedElemSet anElems, aNodes;
6795 listOfGroupToSet(theElems, aMeshDS, anElems,false );
6796 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6798 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6799 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6801 // Update Python script
6802 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
6803 << &theNodesNot << ", " << theShape << " )";
6805 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6808 SMESH_CATCH( SMESH::throwCorbaException );
6812 //================================================================================
6814 \brief Identify the elements that will be affected by node duplication (actual
6815 duplication is not performed.
6816 This method is the first step of DoubleNodeElemGroupsInRegion.
6817 \param theElems - list of groups of elements (edges or faces) to be replicated
6818 \param theNodesNot - list of groups of nodes not to replicated
6819 \param theShape - shape to detect affected elements (element which geometric center
6820 located on or inside shape).
6821 The replicated nodes should be associated to affected elements.
6822 \return groups of affected elements
6823 \sa DoubleNodeElemGroupsInRegion()
6825 //================================================================================
6826 SMESH::ListOfGroups*
6827 SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theElems,
6828 const SMESH::ListOfGroups& theNodesNot,
6829 GEOM::GEOM_Object_ptr theShape )
6830 throw (SALOME::SALOME_Exception)
6833 MESSAGE("AffectedElemGroupsInRegion");
6834 SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
6835 bool isEdgeGroup = false;
6836 bool isFaceGroup = false;
6837 bool isVolumeGroup = false;
6838 SMESH::SMESH_Group_var aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE, "affectedEdges");
6839 SMESH::SMESH_Group_var aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE, "affectedFaces");
6840 SMESH::SMESH_Group_var aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME, "affectedVolumes");
6844 ::SMESH_MeshEditor aMeshEditor(myMesh);
6846 SMESHDS_Mesh* aMeshDS = getMeshDS();
6847 TIDSortedElemSet anElems, aNodes;
6848 listOfGroupToSet(theElems, aMeshDS, anElems, false);
6849 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true);
6851 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape(theShape);
6852 TIDSortedElemSet anAffected;
6853 bool aResult = aMeshEditor.AffectedElemGroupsInRegion(anElems, aNodes, aShape, anAffected);
6856 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6861 int lg = anAffected.size();
6862 MESSAGE("lg="<< lg);
6863 SMESH::long_array_var volumeIds = new SMESH::long_array;
6864 volumeIds->length(lg);
6865 SMESH::long_array_var faceIds = new SMESH::long_array;
6866 faceIds->length(lg);
6867 SMESH::long_array_var edgeIds = new SMESH::long_array;
6868 edgeIds->length(lg);
6873 TIDSortedElemSet::const_iterator eIt = anAffected.begin();
6874 for (; eIt != anAffected.end(); ++eIt)
6876 const SMDS_MeshElement* anElem = *eIt;
6879 int elemId = anElem->GetID();
6880 if (myMesh->GetElementType(elemId, true) == SMDSAbs_Volume)
6881 volumeIds[ivol++] = elemId;
6882 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Face)
6883 faceIds[iface++] = elemId;
6884 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Edge)
6885 edgeIds[iedge++] = elemId;
6887 volumeIds->length(ivol);
6888 faceIds->length(iface);
6889 edgeIds->length(iedge);
6891 aNewVolumeGroup->Add(volumeIds);
6892 aNewFaceGroup->Add(faceIds);
6893 aNewEdgeGroup->Add(edgeIds);
6894 isVolumeGroup = (aNewVolumeGroup->Size() > 0);
6895 isFaceGroup = (aNewFaceGroup->Size() > 0);
6896 isEdgeGroup = (aNewEdgeGroup->Size() > 0);
6900 if (isEdgeGroup) nbGroups++;
6901 if (isFaceGroup) nbGroups++;
6902 if (isVolumeGroup) nbGroups++;
6903 aListOfGroups->length(nbGroups);
6906 if (isEdgeGroup) aListOfGroups[i++] = aNewEdgeGroup._retn();
6907 if (isFaceGroup) aListOfGroups[i++] = aNewFaceGroup._retn();
6908 if (isVolumeGroup) aListOfGroups[i++] = aNewVolumeGroup._retn();
6910 // Update Python script
6913 if (isEdgeGroup) pyDump << aNewEdgeGroup << ", ";
6914 if (isFaceGroup) pyDump << aNewFaceGroup << ", ";
6915 if (isVolumeGroup) pyDump << aNewVolumeGroup << ", ";
6917 pyDump << this << ".AffectedElemGroupsInRegion( "
6918 << &theElems << ", " << &theNodesNot << ", " << theShape << " )";
6920 return aListOfGroups._retn();
6922 SMESH_CATCH( SMESH::throwCorbaException );
6926 //================================================================================
6928 \brief Generated skin mesh (containing 2D cells) from 3D mesh
6929 The created 2D mesh elements based on nodes of free faces of boundary volumes
6930 \return TRUE if operation has been completed successfully, FALSE otherwise
6932 //================================================================================
6934 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
6935 throw (SALOME::SALOME_Exception)
6940 bool aResult = getEditor().Make2DMeshFrom3D();
6942 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
6944 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6947 SMESH_CATCH( SMESH::throwCorbaException );
6951 //================================================================================
6953 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
6954 * The list of groups must contain at least two groups. The groups have to be disjoint:
6955 * no common element into two different groups.
6956 * The nodes of the internal faces at the boundaries of the groups are doubled.
6957 * Optionally, the internal faces are replaced by flat elements.
6958 * Triangles are transformed into prisms, and quadrangles into hexahedrons.
6959 * The flat elements are stored in groups of volumes.
6960 * These groups are named according to the position of the group in the list:
6961 * 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.
6962 * 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.
6963 * All the flat elements are gathered into the group named "joints3D" (or "joints2D" in 2D situation).
6964 * The flat element of the multiple junctions between the simple junction are stored in a group named "jointsMultiples".
6965 * \param theDomains - list of groups of volumes
6966 * \param createJointElems - if TRUE, create the elements
6967 * \param onAllBoundaries - if TRUE, the nodes and elements are also created on
6968 * the boundary between \a theDomains and the rest mesh
6969 * \return TRUE if operation has been completed successfully, FALSE otherwise
6971 //================================================================================
6974 SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
6975 CORBA::Boolean createJointElems,
6976 CORBA::Boolean onAllBoundaries )
6977 throw (SALOME::SALOME_Exception)
6984 SMESHDS_Mesh* aMeshDS = getMeshDS();
6986 // MESSAGE("theDomains.length = "<<theDomains.length());
6987 if ( theDomains.length() <= 1 && !onAllBoundaries )
6988 THROW_SALOME_CORBA_EXCEPTION("At least 2 groups are required.", SALOME::BAD_PARAM);
6990 vector<TIDSortedElemSet> domains;
6991 domains.resize( theDomains.length() );
6993 for ( int i = 0, n = theDomains.length(); i < n; i++ )
6995 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
6996 if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
6998 // if ( aGrp->GetType() != SMESH::VOLUME )
6999 // THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
7000 SMESH::long_array_var anIDs = aGrp->GetIDs();
7001 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
7005 isOK = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems, onAllBoundaries );
7006 // TODO publish the groups of flat elements in study
7008 declareMeshModified( /*isReComputeSafe=*/ !isOK );
7010 // Update Python script
7011 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
7012 << ", " << createJointElems << ", " << onAllBoundaries << " )";
7014 SMESH_CATCH( SMESH::throwCorbaException );
7016 myMesh_i->CreateGroupServants(); // publish created groups if any
7021 //================================================================================
7023 * \brief Double nodes on some external faces and create flat elements.
7024 * Flat elements are mainly used by some types of mechanic calculations.
7026 * Each group of the list must be constituted of faces.
7027 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
7028 * @param theGroupsOfFaces - list of groups of faces
7029 * @return TRUE if operation has been completed successfully, FALSE otherwise
7031 //================================================================================
7034 SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
7035 throw (SALOME::SALOME_Exception)
7040 SMESHDS_Mesh* aMeshDS = getMeshDS();
7042 vector<TIDSortedElemSet> faceGroups;
7045 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
7047 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
7048 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
7050 TIDSortedElemSet faceGroup;
7052 faceGroups.push_back(faceGroup);
7053 SMESH::long_array_var anIDs = aGrp->GetIDs();
7054 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
7058 bool aResult = getEditor().CreateFlatElementsOnFacesGroups( faceGroups );
7059 // TODO publish the groups of flat elements in study
7061 declareMeshModified( /*isReComputeSafe=*/ !aResult );
7063 // Update Python script
7064 TPythonDump() << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
7067 SMESH_CATCH( SMESH::throwCorbaException );
7071 //================================================================================
7073 * \brief Identify all the elements around a geom shape, get the faces delimiting
7076 * Build groups of volume to remove, groups of faces to replace on the skin of the
7077 * object, groups of faces to remove inside the object, (idem edges).
7078 * Build ordered list of nodes at the border of each group of faces to replace
7079 * (to be used to build a geom subshape).
7081 //================================================================================
7083 void SMESH_MeshEditor_i::CreateHoleSkin(CORBA::Double radius,
7084 GEOM::GEOM_Object_ptr theShape,
7085 const char* groupName,
7086 const SMESH::double_array& theNodesCoords,
7087 SMESH::array_of_long_array_out GroupsOfNodes)
7088 throw (SALOME::SALOME_Exception)
7093 std::vector<std::vector<int> > aListOfListOfNodes;
7094 ::SMESH_MeshEditor aMeshEditor( myMesh );
7096 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
7097 if ( !theNodeSearcher )
7098 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
7100 vector<double> nodesCoords;
7101 for (int i = 0; i < theNodesCoords.length(); i++)
7103 nodesCoords.push_back( theNodesCoords[i] );
7106 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
7107 aMeshEditor.CreateHoleSkin(radius, aShape, theNodeSearcher, groupName,
7108 nodesCoords, aListOfListOfNodes);
7110 GroupsOfNodes = new SMESH::array_of_long_array;
7111 GroupsOfNodes->length( aListOfListOfNodes.size() );
7112 std::vector<std::vector<int> >::iterator llIt = aListOfListOfNodes.begin();
7113 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
7115 vector<int>& aListOfNodes = *llIt;
7116 vector<int>::iterator lIt = aListOfNodes.begin();;
7117 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
7118 aGroup.length( aListOfNodes.size() );
7119 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
7120 aGroup[ j ] = (*lIt);
7122 TPythonDump() << "lists_nodes = " << this << ".CreateHoleSkin( "
7125 << ", '" << groupName << "', "
7126 << theNodesCoords << " )";
7128 SMESH_CATCH( SMESH::throwCorbaException );
7131 // issue 20749 ===================================================================
7133 * \brief Creates missing boundary elements
7134 * \param elements - elements whose boundary is to be checked
7135 * \param dimension - defines type of boundary elements to create
7136 * \param groupName - a name of group to store created boundary elements in,
7137 * "" means not to create the group
7138 * \param meshName - a name of new mesh to store created boundary elements in,
7139 * "" means not to create the new mesh
7140 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
7141 * \param toCopyExistingBondary - if true, not only new but also pre-existing
7142 * boundary elements will be copied into the new mesh
7143 * \param group - returns the create group, if any
7144 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
7146 // ================================================================================
7148 SMESH::SMESH_Mesh_ptr
7149 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
7150 SMESH::Bnd_Dimension dim,
7151 const char* groupName,
7152 const char* meshName,
7153 CORBA::Boolean toCopyElements,
7154 CORBA::Boolean toCopyExistingBondary,
7155 SMESH::SMESH_Group_out group)
7156 throw (SALOME::SALOME_Exception)
7161 if ( dim > SMESH::BND_1DFROM2D )
7162 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
7164 SMESHDS_Mesh* aMeshDS = getMeshDS();
7166 SMESH::SMESH_Mesh_var mesh_var;
7167 SMESH::SMESH_Group_var group_var;
7171 TIDSortedElemSet elements;
7172 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
7173 prepareIdSource( idSource );
7174 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
7178 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
7179 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
7181 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
7183 // group of new boundary elements
7184 SMESH_Group* smesh_group = 0;
7185 if ( strlen(groupName) )
7187 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
7188 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
7189 smesh_group = group_i->GetSmeshGroup();
7193 getEditor().MakeBoundaryMesh( elements,
7194 ::SMESH_MeshEditor::Bnd_Dimension(dim),
7198 toCopyExistingBondary);
7201 smesh_mesh->GetMeshDS()->Modified();
7204 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
7206 // result of MakeBoundaryMesh() is a tuple (mesh, group)
7207 if ( mesh_var->_is_nil() )
7208 pyDump << myMesh_i->_this() << ", ";
7210 pyDump << mesh_var << ", ";
7211 if ( group_var->_is_nil() )
7212 pyDump << "_NoneGroup = "; // assignment to None is forbiden
7214 pyDump << group_var << " = ";
7215 pyDump << this << ".MakeBoundaryMesh( "
7217 << "SMESH." << dimName[int(dim)] << ", "
7218 << "'" << groupName << "', "
7219 << "'" << meshName<< "', "
7220 << toCopyElements << ", "
7221 << toCopyExistingBondary << ")";
7223 group = group_var._retn();
7224 return mesh_var._retn();
7226 SMESH_CATCH( SMESH::throwCorbaException );
7227 return SMESH::SMESH_Mesh::_nil();
7230 //================================================================================
7232 * \brief Creates missing boundary elements
7233 * \param dimension - defines type of boundary elements to create
7234 * \param groupName - a name of group to store all boundary elements in,
7235 * "" means not to create the group
7236 * \param meshName - a name of a new mesh, which is a copy of the initial
7237 * mesh + created boundary elements; "" means not to create the new mesh
7238 * \param toCopyAll - if true, the whole initial mesh will be copied into
7239 * the new mesh else only boundary elements will be copied into the new mesh
7240 * \param groups - optional groups of elements to make boundary around
7241 * \param mesh - returns the mesh where elements were added to
7242 * \param group - returns the created group, if any
7243 * \retval long - number of added boundary elements
7245 //================================================================================
7247 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
7248 const char* groupName,
7249 const char* meshName,
7250 CORBA::Boolean toCopyAll,
7251 const SMESH::ListOfIDSources& groups,
7252 SMESH::SMESH_Mesh_out mesh,
7253 SMESH::SMESH_Group_out group)
7254 throw (SALOME::SALOME_Exception)
7259 if ( dim > SMESH::BND_1DFROM2D )
7260 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
7262 // separate groups belonging to this and other mesh
7263 SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
7264 SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
7265 groupsOfThisMesh->length( groups.length() );
7266 groupsOfOtherMesh->length( groups.length() );
7267 int nbGroups = 0, nbGroupsOfOtherMesh = 0;
7268 for ( int i = 0; i < groups.length(); ++i )
7270 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
7271 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
7272 groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
7274 groupsOfThisMesh[ nbGroups++ ] = groups[i];
7275 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
7276 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
7278 groupsOfThisMesh->length( nbGroups );
7279 groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
7284 if ( nbGroupsOfOtherMesh > 0 )
7286 // process groups belonging to another mesh
7287 SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
7288 SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
7289 nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
7290 groupsOfOtherMesh, mesh, group );
7293 SMESH::SMESH_Mesh_var mesh_var;
7294 SMESH::SMESH_Group_var group_var;
7297 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
7298 const bool toCopyMesh = ( strlen( meshName ) > 0 );
7302 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
7304 /*toCopyGroups=*/false,
7305 /*toKeepIDs=*/true);
7307 mesh_var = makeMesh(meshName);
7309 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
7310 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
7313 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
7314 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
7316 // group of boundary elements
7317 SMESH_Group* smesh_group = 0;
7318 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
7319 if ( strlen(groupName) )
7321 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
7322 group_var = mesh_i->CreateGroup( groupType, groupName );
7323 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
7324 smesh_group = group_i->GetSmeshGroup();
7327 TIDSortedElemSet elements;
7329 if ( groups.length() > 0 )
7331 for ( int i = 0; i < nbGroups; ++i )
7334 if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
7336 SMESH::Bnd_Dimension bdim =
7337 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
7338 nbAdded += getEditor().MakeBoundaryMesh( elements,
7339 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
7342 /*toCopyElements=*/false,
7343 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
7344 /*toAddExistingBondary=*/true,
7345 /*aroundElements=*/true);
7351 nbAdded += getEditor().MakeBoundaryMesh( elements,
7352 ::SMESH_MeshEditor::Bnd_Dimension(dim),
7355 /*toCopyElements=*/false,
7356 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
7357 /*toAddExistingBondary=*/true);
7359 tgtMesh->GetMeshDS()->Modified();
7361 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
7363 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
7364 pyDump << "nbAdded, ";
7365 if ( mesh_var->_is_nil() )
7366 pyDump << myMesh_i->_this() << ", ";
7368 pyDump << mesh_var << ", ";
7369 if ( group_var->_is_nil() )
7370 pyDump << "_NoneGroup = "; // assignment to None is forbiden
7372 pyDump << group_var << " = ";
7373 pyDump << this << ".MakeBoundaryElements( "
7374 << "SMESH." << dimName[int(dim)] << ", "
7375 << "'" << groupName << "', "
7376 << "'" << meshName<< "', "
7377 << toCopyAll << ", "
7380 mesh = mesh_var._retn();
7381 group = group_var._retn();
7384 SMESH_CATCH( SMESH::throwCorbaException );