1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_MeshEditor_i.cxx
23 // Author : Nicolas REJNERI
30 // A macro used in SMESH_TryCatch.hxx,
31 // it re-raises a CORBA SALOME exception thrown by SMESH_MeshEditor_i and caught by SMESH_CATCH
32 #define SMY_OWN_CATCH \
33 catch ( SALOME::SALOME_Exception & e ) { throw e; }
35 #include "SMESH_MeshEditor_i.hxx"
37 #include "SMDS_EdgePosition.hxx"
38 #include "SMDS_ElemIterator.hxx"
39 #include "SMDS_FacePosition.hxx"
40 #include "SMDS_IteratorOnIterators.hxx"
41 #include "SMDS_LinearEdge.hxx"
42 #include "SMDS_Mesh0DElement.hxx"
43 #include "SMDS_MeshFace.hxx"
44 #include "SMDS_MeshVolume.hxx"
45 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
46 #include "SMDS_SetIterator.hxx"
47 #include "SMDS_VolumeTool.hxx"
48 #include "SMESHDS_Group.hxx"
49 #include "SMESHDS_GroupOnGeom.hxx"
50 #include "SMESH_ControlsDef.hxx"
51 #include "SMESH_Filter_i.hxx"
52 #include "SMESH_Gen_i.hxx"
53 #include "SMESH_Group.hxx"
54 #include "SMESH_Group_i.hxx"
55 #include "SMESH_MeshAlgos.hxx"
56 #include "SMESH_MeshPartDS.hxx"
57 #include "SMESH_MesherHelper.hxx"
58 #include "SMESH_PythonDump.hxx"
59 #include "SMESH_subMeshEventListener.hxx"
60 #include "SMESH_subMesh_i.hxx"
62 #include <utilities.h>
63 #include <Utils_ExceptHandlers.hxx>
64 #include <Utils_CorbaException.hxx>
65 #include <SALOMEDS_wrap.hxx>
67 #include <BRepAdaptor_Surface.hxx>
68 #include <BRep_Tool.hxx>
69 #include <TopExp_Explorer.hxx>
71 #include <TopoDS_Edge.hxx>
72 #include <TopoDS_Face.hxx>
77 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
81 #include <Standard_Failure.hxx>
84 #include <Standard_ErrorHandler.hxx>
90 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
92 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
95 using SMESH::TPythonDump;
98 namespace MeshEditor_I {
100 //=============================================================================
102 * \brief Mesh to apply modifications for preview purposes
104 //=============================================================================
106 struct TPreviewMesh: public SMESH_Mesh
108 SMDSAbs_ElementType myPreviewType; // type to show
110 TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
111 _isShapeToMesh = (_id =_studyId = 0);
112 _myMeshDS = new SMESHDS_Mesh( _id, true );
113 myPreviewType = previewElements;
116 virtual ~TPreviewMesh() { delete _myMeshDS; _myMeshDS = 0; }
117 //!< Copy a set of elements
118 void Copy(const TIDSortedElemSet & theElements,
119 TIDSortedElemSet& theCopyElements,
120 SMDSAbs_ElementType theSelectType = SMDSAbs_All,
121 SMDSAbs_ElementType theAvoidType = SMDSAbs_All)
123 // loop on theIDsOfElements
124 TIDSortedElemSet::const_iterator eIt = theElements.begin();
125 for ( ; eIt != theElements.end(); ++eIt )
127 const SMDS_MeshElement* anElem = *eIt;
128 if ( !anElem ) continue;
129 SMDSAbs_ElementType type = anElem->GetType();
130 if ( type == theAvoidType ||
131 ( theSelectType != SMDSAbs_All && type != theSelectType ))
133 const SMDS_MeshElement* anElemCopy;
134 if ( type == SMDSAbs_Node)
135 anElemCopy = Copy( cast2Node(anElem) );
137 anElemCopy = Copy( anElem );
139 theCopyElements.insert( theCopyElements.end(), anElemCopy );
143 SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
145 // copy element nodes
146 int anElemNbNodes = anElem->NbNodes();
147 vector< int > anElemNodesID( anElemNbNodes ) ;
148 SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
149 for ( int i = 0; itElemNodes->more(); i++)
151 const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
153 anElemNodesID[i] = anElemNode->GetID();
156 // creates a corresponding element on copied nodes
157 SMDS_MeshElement* anElemCopy = 0;
158 if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
160 const SMDS_VtkVolume* ph =
161 dynamic_cast<const SMDS_VtkVolume*> (anElem);
163 anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
164 (anElemNodesID, ph->GetQuantities(),anElem->GetID());
167 anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
174 SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
176 return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(),
177 anElemNode->GetID());
179 };// struct TPreviewMesh
181 static SMESH_NodeSearcher * theNodeSearcher = 0;
182 static SMESH_ElementSearcher * theElementSearcher = 0;
184 //=============================================================================
186 * \brief Deleter of theNodeSearcher at any compute event occured
188 //=============================================================================
190 struct TSearchersDeleter : public SMESH_subMeshEventListener
193 string myMeshPartIOR;
195 TSearchersDeleter(): SMESH_subMeshEventListener( false, // won't be deleted by submesh
196 "SMESH_MeshEditor_i::TSearchersDeleter"),
198 //!< Delete theNodeSearcher
201 if ( theNodeSearcher ) delete theNodeSearcher; theNodeSearcher = 0;
202 if ( theElementSearcher ) delete theElementSearcher; theElementSearcher = 0;
204 typedef map < int, SMESH_subMesh * > TDependsOnMap;
205 //!< The meshod called by submesh: do my main job
206 void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
207 SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
209 if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
211 Unset( sm->GetFather() );
214 //!< set self on all submeshes and delete theNodeSearcher if other mesh is set
215 void Set(SMESH_Mesh* mesh, const string& meshPartIOR = string())
217 if ( myMesh != mesh || myMeshPartIOR != meshPartIOR)
224 myMeshPartIOR = meshPartIOR;
225 if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
226 const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
227 TDependsOnMap::const_iterator sm;
228 for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
229 sm->second->SetEventListener( this, 0, sm->second );
233 //!< delete self from all submeshes
234 void Unset(SMESH_Mesh* mesh)
236 if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
237 const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
238 TDependsOnMap::const_iterator sm;
239 for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
240 sm->second->DeleteEventListener( this );
245 } theSearchersDeleter;
247 TCollection_AsciiString mirrorTypeName( SMESH::SMESH_MeshEditor::MirrorType theMirrorType )
249 TCollection_AsciiString typeStr;
250 switch ( theMirrorType ) {
251 case SMESH::SMESH_MeshEditor::POINT:
252 typeStr = "SMESH.SMESH_MeshEditor.POINT";
254 case SMESH::SMESH_MeshEditor::AXIS:
255 typeStr = "SMESH.SMESH_MeshEditor.AXIS";
258 typeStr = "SMESH.SMESH_MeshEditor.PLANE";
262 //================================================================================
264 * \brief function for conversion of long_array to TIDSortedElemSet
265 * \param IDs - array of IDs
266 * \param aMesh - mesh
267 * \param aMap - collection to fill
268 * \param aType - element type
270 //================================================================================
272 void arrayToSet(const SMESH::long_array & IDs,
273 const SMESHDS_Mesh* aMesh,
274 TIDSortedElemSet& aMap,
275 const SMDSAbs_ElementType aType = SMDSAbs_All )
277 SMDS_MeshElement::NonNullFilter filter1;
278 SMDS_MeshElement::TypeFilter filter2( aType );
279 SMDS_MeshElement::Filter & filter =
280 ( aType == SMDSAbs_All ) ? (SMDS_MeshElement::Filter&) filter1 : filter2;
282 if ( aType == SMDSAbs_Node )
283 for (int i=0; i<IDs.length(); i++) {
284 const SMDS_MeshElement * elem = aMesh->FindNode( IDs[i] );
286 aMap.insert( aMap.end(), elem );
289 for (int i=0; i<IDs.length(); i++) {
290 const SMDS_MeshElement * elem = aMesh->FindElement( IDs[i] );
292 aMap.insert( aMap.end(), elem );
295 //================================================================================
297 * \brief Retrieve elements of given type from SMESH_IDSource
299 //================================================================================
301 bool idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource,
302 const SMESHDS_Mesh* theMeshDS,
303 TIDSortedElemSet& theElemSet,
304 const SMDSAbs_ElementType theType,
305 const bool emptyIfIsMesh=false)
308 if ( CORBA::is_nil( theIDSource ) )
310 if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
313 SMESH::long_array_var anIDs = theIDSource->GetIDs();
314 if ( anIDs->length() == 0 )
316 SMESH::array_of_ElementType_var types = theIDSource->GetTypes();
317 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
319 if ( theType == SMDSAbs_All || theType == SMDSAbs_Node )
320 arrayToSet( anIDs, theMeshDS, theElemSet, SMDSAbs_Node );
326 arrayToSet( anIDs, theMeshDS, theElemSet, theType);
327 return bool(anIDs->length()) == bool(theElemSet.size());
331 //================================================================================
333 * \brief Retrieve nodes from SMESH_IDSource
335 //================================================================================
337 void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject,
338 const SMESHDS_Mesh* theMeshDS,
339 TIDSortedNodeSet& theNodeSet)
342 if ( CORBA::is_nil( theObject ) )
344 SMESH::array_of_ElementType_var types = theObject->GetTypes();
345 SMESH::long_array_var aElementsId = theObject->GetIDs();
346 if ( types->length() == 1 && types[0] == SMESH::NODE)
348 for(int i = 0; i < aElementsId->length(); i++)
349 if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] ))
350 theNodeSet.insert( theNodeSet.end(), n);
352 else if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
354 SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator();
355 while ( nIt->more( ))
356 if( const SMDS_MeshElement * elem = nIt->next() )
357 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
361 for(int i = 0; i < aElementsId->length(); i++)
362 if( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] ))
363 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
367 //================================================================================
369 * \brief Returns elements connected to the given elements
371 //================================================================================
373 void getElementsAround(const TIDSortedElemSet& theElements,
374 const SMESHDS_Mesh* theMeshDS,
375 TIDSortedElemSet& theElementsAround)
377 if ( theElements.empty() ) return;
379 SMDSAbs_ElementType elemType = (*theElements.begin())->GetType();
380 bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() );
382 theMeshDS->GetMeshInfo().NbElements( elemType ) == theElements.size() )
383 return; // all the elements are in theElements
386 elemType = SMDSAbs_All;
388 TIDSortedElemSet visitedNodes;
389 TIDSortedElemSet::const_iterator elemIt = theElements.begin();
390 for ( ; elemIt != theElements.end(); ++elemIt )
392 const SMDS_MeshElement* e = *elemIt;
393 int i = e->NbCornerNodes();
396 const SMDS_MeshNode* n = e->GetNode( i );
397 if ( visitedNodes.insert( n ).second )
399 SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
400 while ( invIt->more() )
402 const SMDS_MeshElement* elemAround = invIt->next();
403 if ( !theElements.count( elemAround ))
404 theElementsAround.insert( elemAround );
411 //================================================================================
413 * \brief Return a string used to detect change of mesh part on which theElementSearcher
414 * is going to be used
416 //================================================================================
418 string getPartIOR( SMESH::SMESH_IDSource_ptr theMeshPart, SMESH::ElementType type)
420 string partIOR = SMESH_Gen_i::GetORB()->object_to_string( theMeshPart );
421 if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( theMeshPart ))
422 // take into account passible group modification
423 partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() );
424 partIOR += SMESH_Comment( type );
428 } // namespace MeshEditor_I
430 using namespace MeshEditor_I;
432 //=============================================================================
436 //=============================================================================
438 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview):
440 myMesh( &theMesh->GetImpl() ),
442 myIsPreviewMode ( isPreview ),
448 //================================================================================
452 //================================================================================
454 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
456 deleteAuxIDSources();
457 delete myPreviewMesh; myPreviewMesh = 0;
458 delete myPreviewEditor; myPreviewEditor = 0;
461 //================================================================================
463 * \brief Clear members
465 //================================================================================
467 void SMESH_MeshEditor_i::initData(bool deleteSearchers)
469 if ( myIsPreviewMode ) {
470 if ( myPreviewMesh ) myPreviewMesh->Clear();
473 if ( deleteSearchers )
474 TSearchersDeleter::Delete();
476 getEditor().GetError().reset();
477 getEditor().CrearLastCreated();
480 //================================================================================
482 * \brief Increment mesh modif time and optionally record that the performed
483 * modification may influence futher mesh re-compute.
484 * \param [in] isReComputeSafe - true if the modification does not infulence
485 * futher mesh re-compute
487 //================================================================================
489 void SMESH_MeshEditor_i::declareMeshModified( bool isReComputeSafe )
491 myMesh->GetMeshDS()->Modified();
492 if ( !isReComputeSafe )
493 myMesh->SetIsModified( true );
496 //================================================================================
498 * \brief Return either myEditor or myPreviewEditor depending on myIsPreviewMode.
499 * WARNING: in preview mode call getPreviewMesh() before getEditor()!
501 //================================================================================
503 ::SMESH_MeshEditor& SMESH_MeshEditor_i::getEditor()
505 if ( myIsPreviewMode && !myPreviewEditor ) {
506 if ( !myPreviewMesh ) getPreviewMesh();
507 myPreviewEditor = new ::SMESH_MeshEditor( myPreviewMesh );
509 return myIsPreviewMode ? *myPreviewEditor : myEditor;
512 //================================================================================
514 * \brief Initialize and return myPreviewMesh
515 * \param previewElements - type of elements to show in preview
517 * WARNING: call it once par a method!
519 //================================================================================
521 TPreviewMesh * SMESH_MeshEditor_i::getPreviewMesh(SMDSAbs_ElementType previewElements)
523 if ( !myPreviewMesh || myPreviewMesh->myPreviewType != previewElements )
525 delete myPreviewEditor;
527 delete myPreviewMesh;
528 myPreviewMesh = new TPreviewMesh( previewElements );
530 myPreviewMesh->Clear();
531 return myPreviewMesh;
534 //================================================================================
536 * Return data of mesh edition preview
538 //================================================================================
540 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
541 throw (SALOME::SALOME_Exception)
544 const bool hasBadElems = ( getEditor().GetError() && getEditor().GetError()->HasBadElems() );
546 if ( myIsPreviewMode || hasBadElems ) { // --- MeshPreviewStruct filling ---
548 list<int> aNodesConnectivity;
549 typedef map<int, int> TNodesMap;
552 SMESHDS_Mesh* aMeshDS;
553 std::auto_ptr< SMESH_MeshPartDS > aMeshPartDS;
555 aMeshPartDS.reset( new SMESH_MeshPartDS( getEditor().GetError()->myBadElements ));
556 aMeshDS = aMeshPartDS.get();
559 aMeshDS = getEditor().GetMeshDS();
561 myPreviewData = new SMESH::MeshPreviewStruct();
562 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
565 SMDSAbs_ElementType previewType = SMDSAbs_All;
567 if (TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( getEditor().GetMesh() )) {
568 previewType = aPreviewMesh->myPreviewType;
569 switch ( previewType ) {
570 case SMDSAbs_Edge : break;
571 case SMDSAbs_Face : break;
572 case SMDSAbs_Volume: break;
574 if ( aMeshDS->GetMeshInfo().NbElements() == 0 ) previewType = SMDSAbs_Node;
578 myPreviewData->elementTypes.length( aMeshDS->GetMeshInfo().NbElements( previewType ));
580 SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator(previewType);
582 while ( itMeshElems->more() ) {
583 const SMDS_MeshElement* aMeshElem = itMeshElems->next();
584 SMDS_NodeIteratorPtr itElemNodes = aMeshElem->nodeIterator();
585 while ( itElemNodes->more() ) {
586 const SMDS_MeshNode* aMeshNode = itElemNodes->next();
587 int aNodeID = aMeshNode->GetID();
588 TNodesMap::iterator anIter = nodesMap.find(aNodeID);
589 if ( anIter == nodesMap.end() ) {
590 // filling the nodes coordinates
591 myPreviewData->nodesXYZ[j].x = aMeshNode->X();
592 myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
593 myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
594 anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
597 aNodesConnectivity.push_back(anIter->second);
600 // filling the elements types
601 SMDSAbs_ElementType aType = aMeshElem->GetType();
602 bool isPoly = aMeshElem->IsPoly();
603 myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
604 myPreviewData->elementTypes[i].isPoly = isPoly;
605 myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
608 myPreviewData->nodesXYZ.length( j );
610 // filling the elements connectivities
611 list<int>::iterator aConnIter = aNodesConnectivity.begin();
612 myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
613 for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
614 myPreviewData->elementConnectivities[i] = *aConnIter;
616 return myPreviewData._retn();
618 SMESH_CATCH( SMESH::throwCorbaException );
622 //================================================================================
624 * \brief Returns list of it's IDs of created nodes
625 * \retval SMESH::long_array* - list of node ID
627 //================================================================================
629 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
630 throw (SALOME::SALOME_Exception)
633 SMESH::long_array_var myLastCreatedNodes = new SMESH::long_array();
635 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedNodes();
636 myLastCreatedNodes->length( aSeq.Length() );
637 for (int i = 1; i <= aSeq.Length(); i++)
638 myLastCreatedNodes[i-1] = aSeq.Value(i)->GetID();
640 return myLastCreatedNodes._retn();
641 SMESH_CATCH( SMESH::throwCorbaException );
645 //================================================================================
647 * \brief Returns list of it's IDs of created elements
648 * \retval SMESH::long_array* - list of elements' ID
650 //================================================================================
652 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
653 throw (SALOME::SALOME_Exception)
656 SMESH::long_array_var myLastCreatedElems = new SMESH::long_array();
658 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
659 myLastCreatedElems->length( aSeq.Length() );
660 for ( int i = 1; i <= aSeq.Length(); i++ )
661 myLastCreatedElems[i-1] = aSeq.Value(i)->GetID();
663 return myLastCreatedElems._retn();
664 SMESH_CATCH( SMESH::throwCorbaException );
668 //=======================================================================
669 //function : ClearLastCreated
670 //purpose : Clears sequences of last created elements and nodes
671 //=======================================================================
673 void SMESH_MeshEditor_i::ClearLastCreated() throw (SALOME::SALOME_Exception)
676 getEditor().CrearLastCreated();
677 SMESH_CATCH( SMESH::throwCorbaException );
680 //=======================================================================
682 * Returns description of an error/warning occured during the last operation
683 * WARNING: ComputeError.code >= 100 and no corresponding enum in IDL API
685 //=======================================================================
687 SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError()
688 throw (SALOME::SALOME_Exception)
691 SMESH::ComputeError_var errOut = new SMESH::ComputeError;
692 SMESH_ComputeErrorPtr& errIn = getEditor().GetError();
693 if ( errIn && !errIn->IsOK() )
695 errOut->code = -( errIn->myName < 0 ? errIn->myName + 1: errIn->myName ); // -1 -> 0
696 errOut->comment = errIn->myComment.c_str();
697 errOut->subShapeID = -1;
698 errOut->hasBadMesh = !errIn->myBadElements.empty();
703 errOut->subShapeID = -1;
704 errOut->hasBadMesh = false;
707 return errOut._retn();
708 SMESH_CATCH( SMESH::throwCorbaException );
712 //=======================================================================
713 //function : MakeIDSource
714 //purpose : Wrap a sequence of ids in a SMESH_IDSource
715 //=======================================================================
717 struct SMESH_MeshEditor_i::_IDSource : public POA_SMESH::SMESH_IDSource
719 SMESH::long_array _ids;
720 SMESH::ElementType _type;
721 SMESH::SMESH_Mesh_ptr _mesh;
722 SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); }
723 SMESH::long_array* GetMeshInfo() { return 0; }
724 SMESH::long_array* GetNbElementsByType()
726 SMESH::long_array_var aRes = new SMESH::long_array();
727 aRes->length(SMESH::NB_ELEMENT_TYPES);
728 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
729 aRes[ i ] = ( i == _type ) ? _ids.length() : 0;
732 SMESH::SMESH_Mesh_ptr GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _mesh ); }
733 bool IsMeshInfoCorrect() { return true; }
734 SMESH::array_of_ElementType* GetTypes()
736 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
737 if ( _ids.length() > 0 ) {
741 return types._retn();
745 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
746 SMESH::ElementType type)
748 if ( myAuxIDSources.size() > 10 ) {
749 delete myAuxIDSources.front();
750 myAuxIDSources.pop_front();
753 _IDSource* idSrc = new _IDSource;
754 idSrc->_mesh = myMesh_i->_this();
757 myAuxIDSources.push_back( idSrc );
759 SMESH::SMESH_IDSource_var anIDSourceVar = idSrc->_this();
761 return anIDSourceVar._retn();
764 bool SMESH_MeshEditor_i::IsTemporaryIDSource( SMESH::SMESH_IDSource_ptr& idSource )
766 return SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource );
769 CORBA::Long* SMESH_MeshEditor_i::GetTemporaryIDs( SMESH::SMESH_IDSource_ptr& idSource,
772 if ( _IDSource* tmpIdSource = SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource ))
774 nbIds = (int) tmpIdSource->_ids.length();
775 return & tmpIdSource->_ids[0];
781 void SMESH_MeshEditor_i::deleteAuxIDSources()
783 std::list< _IDSource* >::iterator idSrcIt = myAuxIDSources.begin();
784 for ( ; idSrcIt != myAuxIDSources.end(); ++idSrcIt )
786 myAuxIDSources.clear();
789 //=============================================================================
793 //=============================================================================
796 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
797 throw (SALOME::SALOME_Exception)
804 for (int i = 0; i < IDsOfElements.length(); i++)
805 IdList.push_back( IDsOfElements[i] );
807 // Update Python script
808 TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
811 bool ret = getEditor().Remove( IdList, false );
813 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 ); // issue 0020693
816 SMESH_CATCH( SMESH::throwCorbaException );
820 //=============================================================================
824 //=============================================================================
826 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
827 throw (SALOME::SALOME_Exception)
833 for (int i = 0; i < IDsOfNodes.length(); i++)
834 IdList.push_back( IDsOfNodes[i] );
836 // Update Python script
837 TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
839 bool ret = getEditor().Remove( IdList, true );
841 declareMeshModified( /*isReComputeSafe=*/ !ret ); // issue 0020693
844 SMESH_CATCH( SMESH::throwCorbaException );
848 //=============================================================================
852 //=============================================================================
854 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
855 throw (SALOME::SALOME_Exception)
860 // Update Python script
861 TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
863 // Create filter to find all orphan nodes
864 SMESH::Controls::Filter::TIdSequence seq;
865 SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
866 SMESH::Controls::Filter::GetElementsId( getMeshDS(), predicate, seq );
868 // remove orphan nodes (if there are any)
870 for ( int i = 0; i < seq.size(); i++ )
871 IdList.push_back( seq[i] );
873 int nbNodesBefore = myMesh->NbNodes();
874 getEditor().Remove( IdList, true );
875 int nbNodesAfter = myMesh->NbNodes();
877 declareMeshModified( /*isReComputeSafe=*/ IdList.size() == 0 ); // issue 0020693
878 return nbNodesBefore - nbNodesAfter;
880 SMESH_CATCH( SMESH::throwCorbaException );
884 //=============================================================================
888 //=============================================================================
890 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,CORBA::Double y, CORBA::Double z)
891 throw (SALOME::SALOME_Exception)
896 const SMDS_MeshNode* N = getMeshDS()->AddNode(x, y, z);
898 // Update Python script
899 TPythonDump() << "nodeID = " << this << ".AddNode( "
900 << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )";
902 declareMeshModified( /*isReComputeSafe=*/false );
905 SMESH_CATCH( SMESH::throwCorbaException );
909 //=============================================================================
911 * Create 0D element on the given node.
913 //=============================================================================
915 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
916 throw (SALOME::SALOME_Exception)
921 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
922 SMDS_MeshElement* elem = getMeshDS()->Add0DElement(aNode);
924 // Update Python script
925 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
927 declareMeshModified( /*isReComputeSafe=*/false );
929 return elem ? elem->GetID() : 0;
931 SMESH_CATCH( SMESH::throwCorbaException );
935 //=============================================================================
937 * Create a ball element on the given node.
939 //=============================================================================
941 CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diameter)
942 throw (SALOME::SALOME_Exception)
947 if ( diameter < std::numeric_limits<double>::min() )
948 THROW_SALOME_CORBA_EXCEPTION("Invalid diameter", SALOME::BAD_PARAM);
950 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
951 SMDS_MeshElement* elem = getMeshDS()->AddBall(aNode, diameter);
953 // Update Python script
954 TPythonDump() << "ballElem = "
955 << this << ".AddBall( " << IDOfNode << ", " << diameter <<" )";
957 declareMeshModified( /*isReComputeSafe=*/false );
958 return elem ? elem->GetID() : 0;
960 SMESH_CATCH( SMESH::throwCorbaException );
964 //=============================================================================
966 * Create an edge, either linear and quadratic (this is determed
967 * by number of given nodes, two or three)
969 //=============================================================================
971 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
972 throw (SALOME::SALOME_Exception)
977 int NbNodes = IDsOfNodes.length();
978 SMDS_MeshElement* elem = 0;
981 CORBA::Long index1 = IDsOfNodes[0];
982 CORBA::Long index2 = IDsOfNodes[1];
983 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(index1),
984 getMeshDS()->FindNode(index2));
986 // Update Python script
987 TPythonDump() << "edge = " << this << ".AddEdge([ "
988 << index1 << ", " << index2 <<" ])";
991 CORBA::Long n1 = IDsOfNodes[0];
992 CORBA::Long n2 = IDsOfNodes[1];
993 CORBA::Long n12 = IDsOfNodes[2];
994 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(n1),
995 getMeshDS()->FindNode(n2),
996 getMeshDS()->FindNode(n12));
997 // Update Python script
998 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
999 <<n1<<", "<<n2<<", "<<n12<<" ])";
1002 declareMeshModified( /*isReComputeSafe=*/false );
1003 return elem ? elem->GetID() : 0;
1005 SMESH_CATCH( SMESH::throwCorbaException );
1009 //=============================================================================
1013 //=============================================================================
1015 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
1016 throw (SALOME::SALOME_Exception)
1021 int NbNodes = IDsOfNodes.length();
1027 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1028 for (int i = 0; i < NbNodes; i++)
1029 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1031 SMDS_MeshElement* elem = 0;
1033 case 3: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]); break;
1034 case 4: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]); break;
1035 case 6: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1036 nodes[4], nodes[5]); break;
1037 case 7: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1038 nodes[4], nodes[5], nodes[6]); break;
1039 case 8: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1040 nodes[4], nodes[5], nodes[6], nodes[7]); break;
1041 case 9: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1042 nodes[4], nodes[5], nodes[6], nodes[7],
1044 default: elem = getMeshDS()->AddPolygonalFace(nodes);
1047 // Update Python script
1048 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
1050 declareMeshModified( /*isReComputeSafe=*/false );
1052 return elem ? elem->GetID() : 0;
1054 SMESH_CATCH( SMESH::throwCorbaException );
1058 //=============================================================================
1062 //=============================================================================
1063 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
1064 throw (SALOME::SALOME_Exception)
1069 int NbNodes = IDsOfNodes.length();
1070 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1071 for (int i = 0; i < NbNodes; i++)
1072 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1074 const SMDS_MeshElement* elem = getMeshDS()->AddPolygonalFace(nodes);
1076 // Update Python script
1077 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
1079 declareMeshModified( /*isReComputeSafe=*/false );
1080 return elem ? elem->GetID() : 0;
1082 SMESH_CATCH( SMESH::throwCorbaException );
1086 //=============================================================================
1088 * Create volume, either linear and quadratic (this is determed
1089 * by number of given nodes)
1091 //=============================================================================
1093 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
1094 throw (SALOME::SALOME_Exception)
1099 int NbNodes = IDsOfNodes.length();
1100 vector< const SMDS_MeshNode*> n(NbNodes);
1101 for(int i=0;i<NbNodes;i++)
1102 n[i]= getMeshDS()->FindNode(IDsOfNodes[i]);
1104 SMDS_MeshElement* elem = 0;
1107 case 4 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
1108 case 5 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
1109 case 6 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
1110 case 8 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
1111 case 10:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1112 n[6],n[7],n[8],n[9]);
1114 case 12:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1115 n[6],n[7],n[8],n[9],n[10],n[11]);
1117 case 13:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
1118 n[7],n[8],n[9],n[10],n[11],n[12]);
1120 case 15:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
1121 n[9],n[10],n[11],n[12],n[13],n[14]);
1123 case 20:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1124 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1125 n[15],n[16],n[17],n[18],n[19]);
1127 case 27:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1128 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1129 n[15],n[16],n[17],n[18],n[19],
1130 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
1134 // Update Python script
1135 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
1137 declareMeshModified( /*isReComputeSafe=*/false );
1138 return elem ? elem->GetID() : 0;
1140 SMESH_CATCH( SMESH::throwCorbaException );
1144 //=============================================================================
1146 * AddPolyhedralVolume
1148 //=============================================================================
1149 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
1150 const SMESH::long_array & Quantities)
1151 throw (SALOME::SALOME_Exception)
1156 int NbNodes = IDsOfNodes.length();
1157 std::vector<const SMDS_MeshNode*> n (NbNodes);
1158 for (int i = 0; i < NbNodes; i++)
1160 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDsOfNodes[i]);
1161 if (!aNode) return 0;
1165 int NbFaces = Quantities.length();
1166 std::vector<int> q (NbFaces);
1167 for (int j = 0; j < NbFaces; j++)
1168 q[j] = Quantities[j];
1170 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(n, q);
1172 // Update Python script
1173 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
1174 << IDsOfNodes << ", " << Quantities << " )";
1176 declareMeshModified( /*isReComputeSafe=*/false );
1177 return elem ? elem->GetID() : 0;
1179 SMESH_CATCH( SMESH::throwCorbaException );
1183 //=============================================================================
1185 * AddPolyhedralVolumeByFaces
1187 //=============================================================================
1189 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
1190 throw (SALOME::SALOME_Exception)
1195 int NbFaces = IdsOfFaces.length();
1196 std::vector<const SMDS_MeshNode*> poly_nodes;
1197 std::vector<int> quantities (NbFaces);
1199 for (int i = 0; i < NbFaces; i++) {
1200 const SMDS_MeshElement* aFace = getMeshDS()->FindElement(IdsOfFaces[i]);
1201 quantities[i] = aFace->NbNodes();
1203 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
1204 while (It->more()) {
1205 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
1209 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
1211 // Update Python script
1212 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
1213 << IdsOfFaces << " )";
1215 declareMeshModified( /*isReComputeSafe=*/false );
1216 return elem ? elem->GetID() : 0;
1218 SMESH_CATCH( SMESH::throwCorbaException );
1222 //=============================================================================
1224 // \brief Create 0D elements on all nodes of the given object except those
1225 // nodes on which a 0D element already exists.
1226 // \param theObject object on whose nodes 0D elements will be created.
1227 // \param theGroupName optional name of a group to add 0D elements created
1228 // and/or found on nodes of \a theObject.
1229 // \return an object (a new group or a temporary SMESH_IDSource) holding
1230 // ids of new and/or found 0D elements.
1232 //=============================================================================
1234 SMESH::SMESH_IDSource_ptr
1235 SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObject,
1236 const char* theGroupName)
1237 throw (SALOME::SALOME_Exception)
1242 SMESH::SMESH_IDSource_var result;
1245 TIDSortedElemSet elements, elems0D;
1246 prepareIdSource( theObject );
1247 if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
1248 getEditor().Create0DElementsOnAllNodes( elements, elems0D );
1250 SMESH::long_array_var newElems = new SMESH::long_array;
1251 newElems->length( elems0D.size() );
1252 TIDSortedElemSet::iterator eIt = elems0D.begin();
1253 for ( size_t i = 0; i < elems0D.size(); ++i, ++eIt )
1254 newElems[ i ] = (*eIt)->GetID();
1256 SMESH::SMESH_GroupBase_var groupToFill;
1257 if ( theGroupName && strlen( theGroupName ))
1259 // Get existing group named theGroupName
1260 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
1261 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
1262 SMESH::SMESH_GroupBase_var group = groups[i];
1263 if ( !group->_is_nil() ) {
1264 CORBA::String_var name = group->GetName();
1265 if ( strcmp( name.in(), theGroupName ) == 0 && group->GetType() == SMESH::ELEM0D ) {
1266 groupToFill = group;
1271 if ( groupToFill->_is_nil() )
1272 groupToFill = myMesh_i->CreateGroup( SMESH::ELEM0D, theGroupName );
1273 else if ( !SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1274 groupToFill = myMesh_i->ConvertToStandalone( groupToFill );
1277 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1279 group_i->Add( newElems );
1280 result = SMESH::SMESH_IDSource::_narrow( groupToFill );
1281 pyDump << groupToFill;
1285 result = MakeIDSource( newElems, SMESH::ELEM0D );
1286 pyDump << "elem0DIDs";
1289 pyDump << " = " << this << ".Create0DElementsOnAllNodes( "
1290 << theObject << ", '" << theGroupName << "' )";
1292 return result._retn();
1294 SMESH_CATCH( SMESH::throwCorbaException );
1298 //=============================================================================
1300 * \brief Bind a node to a vertex
1301 * \param NodeID - node ID
1302 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1303 * \retval boolean - false if NodeID or VertexID is invalid
1305 //=============================================================================
1307 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
1308 throw (SALOME::SALOME_Exception)
1312 SMESHDS_Mesh * mesh = getMeshDS();
1313 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1315 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1317 if ( mesh->MaxShapeIndex() < VertexID )
1318 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1320 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
1321 if ( shape.ShapeType() != TopAbs_VERTEX )
1322 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1324 mesh->SetNodeOnVertex( node, VertexID );
1326 myMesh->SetIsModified( true );
1328 SMESH_CATCH( SMESH::throwCorbaException );
1331 //=============================================================================
1333 * \brief Store node position on an edge
1334 * \param NodeID - node ID
1335 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
1336 * \param paramOnEdge - parameter on edge where the node is located
1337 * \retval boolean - false if any parameter is invalid
1339 //=============================================================================
1341 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
1342 CORBA::Double paramOnEdge)
1343 throw (SALOME::SALOME_Exception)
1347 SMESHDS_Mesh * mesh = getMeshDS();
1348 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1350 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1352 if ( mesh->MaxShapeIndex() < EdgeID )
1353 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1355 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
1356 if ( shape.ShapeType() != TopAbs_EDGE )
1357 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1360 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
1361 if ( paramOnEdge < f || paramOnEdge > l )
1362 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
1364 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
1366 myMesh->SetIsModified( true );
1368 SMESH_CATCH( SMESH::throwCorbaException );
1371 //=============================================================================
1373 * \brief Store node position on a face
1374 * \param NodeID - node ID
1375 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
1376 * \param u - U parameter on face where the node is located
1377 * \param v - V parameter on face where the node is located
1378 * \retval boolean - false if any parameter is invalid
1380 //=============================================================================
1382 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
1383 CORBA::Double u, CORBA::Double v)
1384 throw (SALOME::SALOME_Exception)
1387 SMESHDS_Mesh * mesh = getMeshDS();
1388 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1390 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1392 if ( mesh->MaxShapeIndex() < FaceID )
1393 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1395 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
1396 if ( shape.ShapeType() != TopAbs_FACE )
1397 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1399 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
1400 bool isOut = ( u < surf.FirstUParameter() ||
1401 u > surf.LastUParameter() ||
1402 v < surf.FirstVParameter() ||
1403 v > surf.LastVParameter() );
1407 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
1408 << " u( " << surf.FirstUParameter()
1409 << "," << surf.LastUParameter()
1410 << ") v( " << surf.FirstVParameter()
1411 << "," << surf.LastVParameter() << ")" );
1413 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
1416 mesh->SetNodeOnFace( node, FaceID, u, v );
1417 myMesh->SetIsModified( true );
1419 SMESH_CATCH( SMESH::throwCorbaException );
1422 //=============================================================================
1424 * \brief Bind a node to a solid
1425 * \param NodeID - node ID
1426 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1427 * \retval boolean - false if NodeID or SolidID is invalid
1429 //=============================================================================
1431 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
1432 throw (SALOME::SALOME_Exception)
1435 SMESHDS_Mesh * mesh = getMeshDS();
1436 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1438 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1440 if ( mesh->MaxShapeIndex() < SolidID )
1441 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1443 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
1444 if ( shape.ShapeType() != TopAbs_SOLID &&
1445 shape.ShapeType() != TopAbs_SHELL)
1446 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1448 mesh->SetNodeInVolume( node, SolidID );
1450 SMESH_CATCH( SMESH::throwCorbaException );
1453 //=============================================================================
1455 * \brief Bind an element to a shape
1456 * \param ElementID - element ID
1457 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
1459 //=============================================================================
1461 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
1462 CORBA::Long ShapeID)
1463 throw (SALOME::SALOME_Exception)
1466 SMESHDS_Mesh * mesh = getMeshDS();
1467 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
1469 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
1471 if ( mesh->MaxShapeIndex() < ShapeID || ShapeID < 1 )
1472 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1474 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1475 if ( shape.ShapeType() != TopAbs_EDGE &&
1476 shape.ShapeType() != TopAbs_FACE &&
1477 shape.ShapeType() != TopAbs_SOLID &&
1478 shape.ShapeType() != TopAbs_SHELL )
1479 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1481 mesh->SetMeshElementOnShape( elem, ShapeID );
1483 myMesh->SetIsModified( true );
1485 SMESH_CATCH( SMESH::throwCorbaException );
1488 //=============================================================================
1492 //=============================================================================
1494 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1495 CORBA::Long NodeID2)
1496 throw (SALOME::SALOME_Exception)
1501 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1502 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1506 // Update Python script
1507 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1508 << NodeID1 << ", " << NodeID2 << " )";
1510 int ret = getEditor().InverseDiag ( n1, n2 );
1512 declareMeshModified( /*isReComputeSafe=*/false );
1515 SMESH_CATCH( SMESH::throwCorbaException );
1519 //=============================================================================
1523 //=============================================================================
1525 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1526 CORBA::Long NodeID2)
1527 throw (SALOME::SALOME_Exception)
1532 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1533 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1537 // Update Python script
1538 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1539 << NodeID1 << ", " << NodeID2 << " )";
1542 bool stat = getEditor().DeleteDiag ( n1, n2 );
1544 declareMeshModified( /*isReComputeSafe=*/!stat );
1548 SMESH_CATCH( SMESH::throwCorbaException );
1552 //=============================================================================
1556 //=============================================================================
1558 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1559 throw (SALOME::SALOME_Exception)
1564 for (int i = 0; i < IDsOfElements.length(); i++)
1566 CORBA::Long index = IDsOfElements[i];
1567 const SMDS_MeshElement * elem = getMeshDS()->FindElement(index);
1569 getEditor().Reorient( elem );
1571 // Update Python script
1572 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1574 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 );
1577 SMESH_CATCH( SMESH::throwCorbaException );
1581 //=============================================================================
1585 //=============================================================================
1587 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1588 throw (SALOME::SALOME_Exception)
1593 TPythonDump aTPythonDump; // suppress dump in Reorient()
1595 prepareIdSource( theObject );
1597 SMESH::long_array_var anElementsId = theObject->GetIDs();
1598 CORBA::Boolean isDone = Reorient(anElementsId);
1600 // Update Python script
1601 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1603 declareMeshModified( /*isReComputeSafe=*/ anElementsId->length() == 0 );
1606 SMESH_CATCH( SMESH::throwCorbaException );
1610 //=======================================================================
1611 //function : Reorient2D
1612 //purpose : Reorient faces contained in \a the2Dgroup.
1613 // the2Dgroup - the mesh or its part to reorient
1614 // theDirection - desired direction of normal of \a theFace
1615 // theFace - ID of face whose orientation is checked.
1616 // It can be < 1 then \a thePoint is used to find a face.
1617 // thePoint - is used to find a face if \a theFace < 1.
1618 // return number of reoriented elements.
1619 //=======================================================================
1621 CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
1622 const SMESH::DirStruct& theDirection,
1623 CORBA::Long theFace,
1624 const SMESH::PointStruct& thePoint)
1625 throw (SALOME::SALOME_Exception)
1628 initData(/*deleteSearchers=*/false);
1630 TIDSortedElemSet elements;
1631 prepareIdSource( the2Dgroup );
1632 if ( !idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1))
1633 THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
1636 const SMDS_MeshElement* face = 0;
1639 face = getMeshDS()->FindElement( theFace );
1641 THROW_SALOME_CORBA_EXCEPTION("Inexistent face given", SALOME::BAD_PARAM);
1642 if ( face->GetType() != SMDSAbs_Face )
1643 THROW_SALOME_CORBA_EXCEPTION("Wrong element type", SALOME::BAD_PARAM);
1647 // create theElementSearcher if needed
1648 theSearchersDeleter.Set( myMesh, getPartIOR( the2Dgroup, SMESH::FACE ));
1649 if ( !theElementSearcher )
1651 if ( elements.empty() ) // search in the whole mesh
1653 if ( myMesh->NbFaces() == 0 )
1654 THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM);
1656 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
1660 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
1661 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
1663 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt);
1667 gp_Pnt p( thePoint.x, thePoint.y, thePoint.z );
1668 face = theElementSearcher->FindClosestTo( p, SMDSAbs_Face );
1671 THROW_SALOME_CORBA_EXCEPTION("No face found by point", SALOME::INTERNAL_ERROR );
1672 if ( !elements.empty() && !elements.count( face ))
1673 THROW_SALOME_CORBA_EXCEPTION("Found face is not in the group", SALOME::BAD_PARAM );
1676 const SMESH::PointStruct * P = &theDirection.PS;
1677 gp_Vec dirVec( P->x, P->y, P->z );
1678 if ( dirVec.Magnitude() < std::numeric_limits< double >::min() )
1679 THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM);
1681 int nbReori = getEditor().Reorient2D( elements, dirVec, face );
1684 declareMeshModified( /*isReComputeSafe=*/false );
1686 TPythonDump() << this << ".Reorient2D( "
1687 << the2Dgroup << ", "
1688 << theDirection << ", "
1690 << thePoint << " )";
1694 SMESH_CATCH( SMESH::throwCorbaException );
1698 //=============================================================================
1700 * \brief Fuse neighbour triangles into quadrangles.
1702 //=============================================================================
1704 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1705 SMESH::NumericalFunctor_ptr Criterion,
1706 CORBA::Double MaxAngle)
1707 throw (SALOME::SALOME_Exception)
1712 SMESHDS_Mesh* aMesh = getMeshDS();
1713 TIDSortedElemSet faces;
1714 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1716 SMESH::NumericalFunctor_i* aNumericalFunctor =
1717 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1718 SMESH::Controls::NumericalFunctorPtr aCrit;
1719 if ( !aNumericalFunctor )
1720 aCrit.reset( new SMESH::Controls::MaxElementLength2D() );
1722 aCrit = aNumericalFunctor->GetNumericalFunctor();
1724 // Update Python script
1725 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1726 << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1729 bool stat = getEditor().TriToQuad( faces, aCrit, MaxAngle );
1731 declareMeshModified( /*isReComputeSafe=*/!stat );
1734 SMESH_CATCH( SMESH::throwCorbaException );
1738 //=============================================================================
1740 * \brief Fuse neighbour triangles into quadrangles.
1742 //=============================================================================
1744 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1745 SMESH::NumericalFunctor_ptr Criterion,
1746 CORBA::Double MaxAngle)
1747 throw (SALOME::SALOME_Exception)
1752 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1754 prepareIdSource( theObject );
1755 SMESH::long_array_var anElementsId = theObject->GetIDs();
1756 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1758 SMESH::NumericalFunctor_i* aNumericalFunctor =
1759 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1761 // Update Python script
1762 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1763 << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1767 SMESH_CATCH( SMESH::throwCorbaException );
1771 //=============================================================================
1773 * \brief Split quadrangles into triangles.
1775 //=============================================================================
1777 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1778 SMESH::NumericalFunctor_ptr Criterion)
1779 throw (SALOME::SALOME_Exception)
1784 SMESHDS_Mesh* aMesh = getMeshDS();
1785 TIDSortedElemSet faces;
1786 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1788 SMESH::NumericalFunctor_i* aNumericalFunctor =
1789 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1790 SMESH::Controls::NumericalFunctorPtr aCrit;
1791 if ( !aNumericalFunctor )
1792 aCrit.reset( new SMESH::Controls::AspectRatio() );
1794 aCrit = aNumericalFunctor->GetNumericalFunctor();
1797 // Update Python script
1798 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1800 CORBA::Boolean stat = getEditor().QuadToTri( faces, aCrit );
1802 declareMeshModified( /*isReComputeSafe=*/false );
1805 SMESH_CATCH( SMESH::throwCorbaException );
1809 //=============================================================================
1811 * \brief Split quadrangles into triangles.
1813 //=============================================================================
1815 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1816 SMESH::NumericalFunctor_ptr Criterion)
1817 throw (SALOME::SALOME_Exception)
1822 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1824 prepareIdSource( theObject );
1825 SMESH::long_array_var anElementsId = theObject->GetIDs();
1826 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1828 SMESH::NumericalFunctor_i* aNumericalFunctor =
1829 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1831 // Update Python script
1832 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1834 declareMeshModified( /*isReComputeSafe=*/false );
1837 SMESH_CATCH( SMESH::throwCorbaException );
1841 //================================================================================
1843 * \brief Split each of quadrangles into 4 triangles.
1844 * \param [in] theObject - theQuads Container of quadrangles to split.
1846 //================================================================================
1848 void SMESH_MeshEditor_i::QuadTo4Tri (SMESH::SMESH_IDSource_ptr theObject)
1849 throw (SALOME::SALOME_Exception)
1854 TIDSortedElemSet faces;
1855 prepareIdSource( theObject );
1856 if ( !idSourceToSet( theObject, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/true ) &&
1858 THROW_SALOME_CORBA_EXCEPTION("No faces given", SALOME::BAD_PARAM);
1860 getEditor().QuadTo4Tri( faces );
1861 TPythonDump() << this << ".QuadTo4Tri( " << theObject << " )";
1863 SMESH_CATCH( SMESH::throwCorbaException );
1866 //=============================================================================
1868 * \brief Split quadrangles into triangles.
1870 //=============================================================================
1872 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1873 CORBA::Boolean Diag13)
1874 throw (SALOME::SALOME_Exception)
1879 SMESHDS_Mesh* aMesh = getMeshDS();
1880 TIDSortedElemSet faces;
1881 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1883 // Update Python script
1884 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1885 << IDsOfElements << ", " << Diag13 << " )";
1887 CORBA::Boolean stat = getEditor().QuadToTri( faces, Diag13 );
1889 declareMeshModified( /*isReComputeSafe=*/ !stat );
1892 SMESH_CATCH( SMESH::throwCorbaException );
1896 //=============================================================================
1898 * \brief Split quadrangles into triangles.
1900 //=============================================================================
1902 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1903 CORBA::Boolean Diag13)
1904 throw (SALOME::SALOME_Exception)
1909 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
1911 prepareIdSource( theObject );
1912 SMESH::long_array_var anElementsId = theObject->GetIDs();
1913 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
1915 // Update Python script
1916 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
1917 << theObject << ", " << Diag13 << " )";
1919 declareMeshModified( /*isReComputeSafe=*/!isDone );
1922 SMESH_CATCH( SMESH::throwCorbaException );
1927 //=============================================================================
1929 * Find better splitting of the given quadrangle.
1930 * \param IDOfQuad ID of the quadrangle to be splitted.
1931 * \param Criterion A criterion to choose a diagonal for splitting.
1932 * \return 1 if 1-3 diagonal is better, 2 if 2-4
1933 * diagonal is better, 0 if error occurs.
1935 //=============================================================================
1937 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
1938 SMESH::NumericalFunctor_ptr Criterion)
1939 throw (SALOME::SALOME_Exception)
1944 const SMDS_MeshElement* quad = getMeshDS()->FindElement(IDOfQuad);
1945 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
1947 SMESH::NumericalFunctor_i* aNumericalFunctor =
1948 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
1949 SMESH::Controls::NumericalFunctorPtr aCrit;
1950 if (aNumericalFunctor)
1951 aCrit = aNumericalFunctor->GetNumericalFunctor();
1953 aCrit.reset(new SMESH::Controls::AspectRatio());
1955 int id = getEditor().BestSplit(quad, aCrit);
1956 declareMeshModified( /*isReComputeSafe=*/ id < 1 );
1959 SMESH_CATCH( SMESH::throwCorbaException );
1963 //================================================================================
1965 * \brief Split volumic elements into tetrahedrons
1967 //================================================================================
1969 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
1970 CORBA::Short methodFlags)
1971 throw (SALOME::SALOME_Exception)
1976 prepareIdSource( elems );
1977 SMESH::long_array_var anElementsId = elems->GetIDs();
1978 TIDSortedElemSet elemSet;
1979 arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume );
1981 getEditor().SplitVolumesIntoTetra( elemSet, int( methodFlags ));
1982 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
1984 TPythonDump() << this << ".SplitVolumesIntoTetra( "
1985 << elems << ", " << methodFlags << " )";
1987 SMESH_CATCH( SMESH::throwCorbaException );
1990 //=======================================================================
1993 //=======================================================================
1996 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
1997 const SMESH::long_array & IDsOfFixedNodes,
1998 CORBA::Long MaxNbOfIterations,
1999 CORBA::Double MaxAspectRatio,
2000 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2001 throw (SALOME::SALOME_Exception)
2003 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2004 MaxAspectRatio, Method, false );
2008 //=======================================================================
2009 //function : SmoothParametric
2011 //=======================================================================
2014 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
2015 const SMESH::long_array & IDsOfFixedNodes,
2016 CORBA::Long MaxNbOfIterations,
2017 CORBA::Double MaxAspectRatio,
2018 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2019 throw (SALOME::SALOME_Exception)
2021 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2022 MaxAspectRatio, Method, true );
2026 //=======================================================================
2027 //function : SmoothObject
2029 //=======================================================================
2032 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
2033 const SMESH::long_array & IDsOfFixedNodes,
2034 CORBA::Long MaxNbOfIterations,
2035 CORBA::Double MaxAspectRatio,
2036 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2037 throw (SALOME::SALOME_Exception)
2039 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2040 MaxAspectRatio, Method, false);
2044 //=======================================================================
2045 //function : SmoothParametricObject
2047 //=======================================================================
2050 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
2051 const SMESH::long_array & IDsOfFixedNodes,
2052 CORBA::Long MaxNbOfIterations,
2053 CORBA::Double MaxAspectRatio,
2054 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2055 throw (SALOME::SALOME_Exception)
2057 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2058 MaxAspectRatio, Method, true);
2062 //=============================================================================
2066 //=============================================================================
2069 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
2070 const SMESH::long_array & IDsOfFixedNodes,
2071 CORBA::Long MaxNbOfIterations,
2072 CORBA::Double MaxAspectRatio,
2073 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2075 throw (SALOME::SALOME_Exception)
2080 SMESHDS_Mesh* aMesh = getMeshDS();
2082 TIDSortedElemSet elements;
2083 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
2085 set<const SMDS_MeshNode*> fixedNodes;
2086 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
2087 CORBA::Long index = IDsOfFixedNodes[i];
2088 const SMDS_MeshNode * node = aMesh->FindNode(index);
2090 fixedNodes.insert( node );
2092 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
2093 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
2094 method = ::SMESH_MeshEditor::CENTROIDAL;
2096 getEditor().Smooth(elements, fixedNodes, method,
2097 MaxNbOfIterations, MaxAspectRatio, IsParametric );
2099 declareMeshModified( /*isReComputeSafe=*/true ); // does not prevent re-compute
2101 // Update Python script
2102 TPythonDump() << "isDone = " << this << "."
2103 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
2104 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
2105 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2106 << "SMESH.SMESH_MeshEditor."
2107 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2108 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2112 SMESH_CATCH( SMESH::throwCorbaException );
2116 //=============================================================================
2120 //=============================================================================
2123 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
2124 const SMESH::long_array & IDsOfFixedNodes,
2125 CORBA::Long MaxNbOfIterations,
2126 CORBA::Double MaxAspectRatio,
2127 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2129 throw (SALOME::SALOME_Exception)
2134 TPythonDump aTPythonDump; // suppress dump in smooth()
2136 prepareIdSource( theObject );
2137 SMESH::long_array_var anElementsId = theObject->GetIDs();
2138 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
2139 MaxAspectRatio, Method, IsParametric);
2141 // Update Python script
2142 aTPythonDump << "isDone = " << this << "."
2143 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
2144 << theObject << ", " << IDsOfFixedNodes << ", "
2145 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2146 << "SMESH.SMESH_MeshEditor."
2147 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2148 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2152 SMESH_CATCH( SMESH::throwCorbaException );
2156 //=============================================================================
2160 //=============================================================================
2162 void SMESH_MeshEditor_i::RenumberNodes()
2163 throw (SALOME::SALOME_Exception)
2166 // Update Python script
2167 TPythonDump() << this << ".RenumberNodes()";
2169 getMeshDS()->Renumber( true );
2171 SMESH_CATCH( SMESH::throwCorbaException );
2174 //=============================================================================
2178 //=============================================================================
2180 void SMESH_MeshEditor_i::RenumberElements()
2181 throw (SALOME::SALOME_Exception)
2184 // Update Python script
2185 TPythonDump() << this << ".RenumberElements()";
2187 getMeshDS()->Renumber( false );
2189 SMESH_CATCH( SMESH::throwCorbaException );
2192 //=======================================================================
2194 * \brief Return groups by their IDs
2196 //=======================================================================
2198 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
2199 throw (SALOME::SALOME_Exception)
2204 myMesh_i->CreateGroupServants();
2205 return myMesh_i->GetGroups( *groupIDs );
2207 SMESH_CATCH( SMESH::throwCorbaException );
2211 //=======================================================================
2212 //function : rotationSweep
2214 //=======================================================================
2216 SMESH::ListOfGroups*
2217 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
2218 const SMESH::AxisStruct & theAxis,
2219 CORBA::Double theAngleInRadians,
2220 CORBA::Long theNbOfSteps,
2221 CORBA::Double theTolerance,
2222 const bool theMakeGroups,
2223 const SMDSAbs_ElementType theElementType)
2224 throw (SALOME::SALOME_Exception)
2229 TIDSortedElemSet inElements, copyElements;
2230 arrayToSet(theIDsOfElements, getMeshDS(), inElements, theElementType);
2232 TIDSortedElemSet* workElements = & inElements;
2233 bool makeWalls=true;
2234 if ( myIsPreviewMode )
2236 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2237 getPreviewMesh( SMDSAbs_Face )->Copy( inElements, copyElements, select, avoid );
2238 workElements = & copyElements;
2239 //makeWalls = false;
2242 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
2243 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
2245 ::SMESH_MeshEditor::PGroupIDs groupIds =
2246 getEditor().RotationSweep (*workElements, Ax1, theAngleInRadians,
2247 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
2249 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2251 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2253 SMESH_CATCH( SMESH::throwCorbaException );
2257 //=======================================================================
2258 //function : RotationSweep
2260 //=======================================================================
2262 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
2263 const SMESH::AxisStruct & theAxis,
2264 CORBA::Double theAngleInRadians,
2265 CORBA::Long theNbOfSteps,
2266 CORBA::Double theTolerance)
2267 throw (SALOME::SALOME_Exception)
2269 if ( !myIsPreviewMode ) {
2270 TPythonDump() << this << ".RotationSweep( "
2271 << theIDsOfElements << ", "
2273 << TVar( theAngleInRadians ) << ", "
2274 << TVar( theNbOfSteps ) << ", "
2275 << TVar( theTolerance ) << " )";
2277 rotationSweep(theIDsOfElements,
2285 //=======================================================================
2286 //function : RotationSweepMakeGroups
2288 //=======================================================================
2290 SMESH::ListOfGroups*
2291 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2292 const SMESH::AxisStruct& theAxis,
2293 CORBA::Double theAngleInRadians,
2294 CORBA::Long theNbOfSteps,
2295 CORBA::Double theTolerance)
2296 throw (SALOME::SALOME_Exception)
2298 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2300 SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
2306 if (!myIsPreviewMode) {
2307 dumpGroupsList(aPythonDump, aGroups);
2308 aPythonDump << this << ".RotationSweepMakeGroups( "
2309 << theIDsOfElements << ", "
2311 << TVar( theAngleInRadians ) << ", "
2312 << TVar( theNbOfSteps ) << ", "
2313 << TVar( theTolerance ) << " )";
2318 //=======================================================================
2319 //function : RotationSweepObject
2321 //=======================================================================
2323 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2324 const SMESH::AxisStruct & theAxis,
2325 CORBA::Double theAngleInRadians,
2326 CORBA::Long theNbOfSteps,
2327 CORBA::Double theTolerance)
2328 throw (SALOME::SALOME_Exception)
2330 if ( !myIsPreviewMode ) {
2331 TPythonDump() << this << ".RotationSweepObject( "
2332 << theObject << ", "
2334 << theAngleInRadians << ", "
2335 << theNbOfSteps << ", "
2336 << theTolerance << " )";
2338 prepareIdSource( theObject );
2339 SMESH::long_array_var anElementsId = theObject->GetIDs();
2340 rotationSweep(anElementsId,
2348 //=======================================================================
2349 //function : RotationSweepObject1D
2351 //=======================================================================
2353 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2354 const SMESH::AxisStruct & theAxis,
2355 CORBA::Double theAngleInRadians,
2356 CORBA::Long theNbOfSteps,
2357 CORBA::Double theTolerance)
2358 throw (SALOME::SALOME_Exception)
2360 if ( !myIsPreviewMode ) {
2361 TPythonDump() << this << ".RotationSweepObject1D( "
2362 << theObject << ", "
2364 << TVar( theAngleInRadians ) << ", "
2365 << TVar( theNbOfSteps ) << ", "
2366 << TVar( theTolerance ) << " )";
2368 prepareIdSource( theObject );
2369 SMESH::long_array_var anElementsId = theObject->GetIDs();
2370 rotationSweep(anElementsId,
2379 //=======================================================================
2380 //function : RotationSweepObject2D
2382 //=======================================================================
2384 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2385 const SMESH::AxisStruct & theAxis,
2386 CORBA::Double theAngleInRadians,
2387 CORBA::Long theNbOfSteps,
2388 CORBA::Double theTolerance)
2389 throw (SALOME::SALOME_Exception)
2391 if ( !myIsPreviewMode ) {
2392 TPythonDump() << this << ".RotationSweepObject2D( "
2393 << theObject << ", "
2395 << TVar( theAngleInRadians ) << ", "
2396 << TVar( theNbOfSteps ) << ", "
2397 << TVar( theTolerance ) << " )";
2399 prepareIdSource( theObject );
2400 SMESH::long_array_var anElementsId = theObject->GetIDs();
2401 rotationSweep(anElementsId,
2410 //=======================================================================
2411 //function : RotationSweepObjectMakeGroups
2413 //=======================================================================
2415 SMESH::ListOfGroups*
2416 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2417 const SMESH::AxisStruct& theAxis,
2418 CORBA::Double theAngleInRadians,
2419 CORBA::Long theNbOfSteps,
2420 CORBA::Double theTolerance)
2421 throw (SALOME::SALOME_Exception)
2423 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2425 prepareIdSource( theObject );
2426 SMESH::long_array_var anElementsId = theObject->GetIDs();
2427 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2433 if (!myIsPreviewMode) {
2434 dumpGroupsList(aPythonDump, aGroups);
2435 aPythonDump << this << ".RotationSweepObjectMakeGroups( "
2436 << theObject << ", "
2438 << theAngleInRadians << ", "
2439 << theNbOfSteps << ", "
2440 << theTolerance << " )";
2445 //=======================================================================
2446 //function : RotationSweepObject1DMakeGroups
2448 //=======================================================================
2450 SMESH::ListOfGroups*
2451 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2452 const SMESH::AxisStruct& theAxis,
2453 CORBA::Double theAngleInRadians,
2454 CORBA::Long theNbOfSteps,
2455 CORBA::Double theTolerance)
2456 throw (SALOME::SALOME_Exception)
2458 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2460 prepareIdSource( theObject );
2461 SMESH::long_array_var anElementsId = theObject->GetIDs();
2462 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2469 if (!myIsPreviewMode) {
2470 dumpGroupsList(aPythonDump, aGroups);
2471 aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
2472 << theObject << ", "
2474 << TVar( theAngleInRadians ) << ", "
2475 << TVar( theNbOfSteps ) << ", "
2476 << TVar( theTolerance ) << " )";
2481 //=======================================================================
2482 //function : RotationSweepObject2DMakeGroups
2484 //=======================================================================
2486 SMESH::ListOfGroups*
2487 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2488 const SMESH::AxisStruct& theAxis,
2489 CORBA::Double theAngleInRadians,
2490 CORBA::Long theNbOfSteps,
2491 CORBA::Double theTolerance)
2492 throw (SALOME::SALOME_Exception)
2494 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2496 prepareIdSource( theObject );
2497 SMESH::long_array_var anElementsId = theObject->GetIDs();
2498 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2505 if (!myIsPreviewMode) {
2506 dumpGroupsList(aPythonDump, aGroups);
2507 aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
2508 << theObject << ", "
2510 << TVar( theAngleInRadians ) << ", "
2511 << TVar( theNbOfSteps ) << ", "
2512 << TVar( theTolerance ) << " )";
2518 //=======================================================================
2519 //function : extrusionSweep
2521 //=======================================================================
2523 SMESH::ListOfGroups*
2524 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
2525 const SMESH::DirStruct & theStepVector,
2526 CORBA::Long theNbOfSteps,
2528 const SMDSAbs_ElementType theElementType)
2529 throw (SALOME::SALOME_Exception)
2534 TIDSortedElemSet elements, copyElements;
2535 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
2537 const SMESH::PointStruct * P = &theStepVector.PS;
2538 gp_Vec stepVec( P->x, P->y, P->z );
2540 TIDSortedElemSet* workElements = & elements;
2542 SMDSAbs_ElementType aType = SMDSAbs_Face;
2543 if (theElementType == SMDSAbs_Node)
2545 aType = SMDSAbs_Edge;
2547 if ( myIsPreviewMode ) {
2548 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2549 getPreviewMesh( aType )->Copy( elements, copyElements, select, avoid );
2550 workElements = & copyElements;
2551 theMakeGroups = false;
2554 TElemOfElemListMap aHystory;
2555 ::SMESH_MeshEditor::PGroupIDs groupIds =
2556 getEditor().ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
2558 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2560 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2562 SMESH_CATCH( SMESH::throwCorbaException );
2566 //=======================================================================
2567 //function : ExtrusionSweep
2569 //=======================================================================
2571 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
2572 const SMESH::DirStruct & theStepVector,
2573 CORBA::Long theNbOfSteps)
2574 throw (SALOME::SALOME_Exception)
2576 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
2577 if (!myIsPreviewMode) {
2578 TPythonDump() << this << ".ExtrusionSweep( "
2579 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps) << " )";
2583 //=======================================================================
2584 //function : ExtrusionSweep0D
2586 //=======================================================================
2588 void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElements,
2589 const SMESH::DirStruct & theStepVector,
2590 CORBA::Long theNbOfSteps)
2591 throw (SALOME::SALOME_Exception)
2593 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2594 if (!myIsPreviewMode) {
2595 TPythonDump() << this << ".ExtrusionSweep0D( "
2596 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps)<< " )";
2600 //=======================================================================
2601 //function : ExtrusionSweepObject
2603 //=======================================================================
2605 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2606 const SMESH::DirStruct & theStepVector,
2607 CORBA::Long theNbOfSteps)
2608 throw (SALOME::SALOME_Exception)
2610 prepareIdSource( theObject );
2611 SMESH::long_array_var anElementsId = theObject->GetIDs();
2612 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
2613 if (!myIsPreviewMode) {
2614 TPythonDump() << this << ".ExtrusionSweepObject( "
2615 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
2619 //=======================================================================
2620 //function : ExtrusionSweepObject0D
2622 //=======================================================================
2624 void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObject,
2625 const SMESH::DirStruct & theStepVector,
2626 CORBA::Long theNbOfSteps)
2627 throw (SALOME::SALOME_Exception)
2629 prepareIdSource( theObject );
2630 SMESH::long_array_var anElementsId = theObject->GetIDs();
2631 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2632 if ( !myIsPreviewMode ) {
2633 TPythonDump() << this << ".ExtrusionSweepObject0D( "
2634 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2638 //=======================================================================
2639 //function : ExtrusionSweepObject1D
2641 //=======================================================================
2643 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2644 const SMESH::DirStruct & theStepVector,
2645 CORBA::Long theNbOfSteps)
2646 throw (SALOME::SALOME_Exception)
2648 prepareIdSource( theObject );
2649 SMESH::long_array_var anElementsId = theObject->GetIDs();
2650 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
2651 if ( !myIsPreviewMode ) {
2652 TPythonDump() << this << ".ExtrusionSweepObject1D( "
2653 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2657 //=======================================================================
2658 //function : ExtrusionSweepObject2D
2660 //=======================================================================
2662 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2663 const SMESH::DirStruct & theStepVector,
2664 CORBA::Long theNbOfSteps)
2665 throw (SALOME::SALOME_Exception)
2667 prepareIdSource( theObject );
2668 SMESH::long_array_var anElementsId = theObject->GetIDs();
2669 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
2670 if ( !myIsPreviewMode ) {
2671 TPythonDump() << this << ".ExtrusionSweepObject2D( "
2672 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2676 //=======================================================================
2677 //function : ExtrusionSweepMakeGroups
2679 //=======================================================================
2681 SMESH::ListOfGroups*
2682 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2683 const SMESH::DirStruct& theStepVector,
2684 CORBA::Long theNbOfSteps)
2685 throw (SALOME::SALOME_Exception)
2687 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2689 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
2691 if (!myIsPreviewMode) {
2692 dumpGroupsList(aPythonDump, aGroups);
2693 aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
2694 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2699 //=======================================================================
2700 //function : ExtrusionSweepMakeGroups0D
2702 //=======================================================================
2704 SMESH::ListOfGroups*
2705 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups0D(const SMESH::long_array& theIDsOfElements,
2706 const SMESH::DirStruct& theStepVector,
2707 CORBA::Long theNbOfSteps)
2708 throw (SALOME::SALOME_Exception)
2710 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2712 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true,SMDSAbs_Node);
2714 if (!myIsPreviewMode) {
2715 dumpGroupsList(aPythonDump, aGroups);
2716 aPythonDump << this << ".ExtrusionSweepMakeGroups0D( " << theIDsOfElements
2717 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2722 //=======================================================================
2723 //function : ExtrusionSweepObjectMakeGroups
2725 //=======================================================================
2727 SMESH::ListOfGroups*
2728 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2729 const SMESH::DirStruct& theStepVector,
2730 CORBA::Long theNbOfSteps)
2731 throw (SALOME::SALOME_Exception)
2733 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2735 prepareIdSource( theObject );
2736 SMESH::long_array_var anElementsId = theObject->GetIDs();
2737 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
2739 if (!myIsPreviewMode) {
2740 dumpGroupsList(aPythonDump, aGroups);
2741 aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
2742 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2747 //=======================================================================
2748 //function : ExtrusionSweepObject0DMakeGroups
2750 //=======================================================================
2752 SMESH::ListOfGroups*
2753 SMESH_MeshEditor_i::ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2754 const SMESH::DirStruct& theStepVector,
2755 CORBA::Long theNbOfSteps)
2756 throw (SALOME::SALOME_Exception)
2758 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2760 prepareIdSource( theObject );
2761 SMESH::long_array_var anElementsId = theObject->GetIDs();
2762 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2763 theNbOfSteps, true, SMDSAbs_Node);
2764 if (!myIsPreviewMode) {
2765 dumpGroupsList(aPythonDump, aGroups);
2766 aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject
2767 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2772 //=======================================================================
2773 //function : ExtrusionSweepObject1DMakeGroups
2775 //=======================================================================
2777 SMESH::ListOfGroups*
2778 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2779 const SMESH::DirStruct& theStepVector,
2780 CORBA::Long theNbOfSteps)
2781 throw (SALOME::SALOME_Exception)
2783 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2785 prepareIdSource( theObject );
2786 SMESH::long_array_var anElementsId = theObject->GetIDs();
2787 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2788 theNbOfSteps, true, SMDSAbs_Edge);
2789 if (!myIsPreviewMode) {
2790 dumpGroupsList(aPythonDump, aGroups);
2791 aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
2792 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2797 //=======================================================================
2798 //function : ExtrusionSweepObject2DMakeGroups
2800 //=======================================================================
2802 SMESH::ListOfGroups*
2803 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2804 const SMESH::DirStruct& theStepVector,
2805 CORBA::Long theNbOfSteps)
2806 throw (SALOME::SALOME_Exception)
2808 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2810 prepareIdSource( theObject );
2811 SMESH::long_array_var anElementsId = theObject->GetIDs();
2812 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2813 theNbOfSteps, true, SMDSAbs_Face);
2814 if (!myIsPreviewMode) {
2815 dumpGroupsList(aPythonDump, aGroups);
2816 aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
2817 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2823 //=======================================================================
2824 //function : advancedExtrusion
2826 //=======================================================================
2828 SMESH::ListOfGroups*
2829 SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
2830 const SMESH::DirStruct & theStepVector,
2831 CORBA::Long theNbOfSteps,
2832 CORBA::Long theExtrFlags,
2833 CORBA::Double theSewTolerance,
2834 const bool theMakeGroups)
2835 throw (SALOME::SALOME_Exception)
2840 TIDSortedElemSet elements;
2841 arrayToSet(theIDsOfElements, getMeshDS(), elements);
2843 const SMESH::PointStruct * P = &theStepVector.PS;
2844 gp_Vec stepVec( P->x, P->y, P->z );
2846 TElemOfElemListMap aHystory;
2847 ::SMESH_MeshEditor::PGroupIDs groupIds =
2848 getEditor().ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
2849 theMakeGroups, theExtrFlags, theSewTolerance);
2851 declareMeshModified( /*isReComputeSafe=*/true );
2853 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2855 SMESH_CATCH( SMESH::throwCorbaException );
2859 //=======================================================================
2860 //function : AdvancedExtrusion
2862 //=======================================================================
2864 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2865 const SMESH::DirStruct & theStepVector,
2866 CORBA::Long theNbOfSteps,
2867 CORBA::Long theExtrFlags,
2868 CORBA::Double theSewTolerance)
2869 throw (SALOME::SALOME_Exception)
2871 if ( !myIsPreviewMode ) {
2872 TPythonDump() << "stepVector = " << theStepVector;
2873 TPythonDump() << this << ".AdvancedExtrusion("
2876 << theNbOfSteps << ","
2877 << theExtrFlags << ", "
2878 << theSewTolerance << " )";
2880 advancedExtrusion( theIDsOfElements,
2888 //=======================================================================
2889 //function : AdvancedExtrusionMakeGroups
2891 //=======================================================================
2892 SMESH::ListOfGroups*
2893 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
2894 const SMESH::DirStruct& theStepVector,
2895 CORBA::Long theNbOfSteps,
2896 CORBA::Long theExtrFlags,
2897 CORBA::Double theSewTolerance)
2898 throw (SALOME::SALOME_Exception)
2900 if (!myIsPreviewMode) {
2901 TPythonDump() << "stepVector = " << theStepVector;
2903 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2905 SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
2912 if (!myIsPreviewMode) {
2913 dumpGroupsList(aPythonDump, aGroups);
2914 aPythonDump << this << ".AdvancedExtrusionMakeGroups("
2917 << theNbOfSteps << ","
2918 << theExtrFlags << ", "
2919 << theSewTolerance << " )";
2925 //================================================================================
2927 * \brief Convert extrusion error to IDL enum
2929 //================================================================================
2931 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
2933 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
2937 RETCASE( EXTR_NO_ELEMENTS );
2938 RETCASE( EXTR_PATH_NOT_EDGE );
2939 RETCASE( EXTR_BAD_PATH_SHAPE );
2940 RETCASE( EXTR_BAD_STARTING_NODE );
2941 RETCASE( EXTR_BAD_ANGLES_NUMBER );
2942 RETCASE( EXTR_CANT_GET_TANGENT );
2944 return SMESH::SMESH_MeshEditor::EXTR_OK;
2948 //=======================================================================
2949 //function : extrusionAlongPath
2951 //=======================================================================
2952 SMESH::ListOfGroups*
2953 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2954 SMESH::SMESH_Mesh_ptr thePathMesh,
2955 GEOM::GEOM_Object_ptr thePathShape,
2956 CORBA::Long theNodeStart,
2957 CORBA::Boolean theHasAngles,
2958 const SMESH::double_array & theAngles,
2959 CORBA::Boolean theHasRefPoint,
2960 const SMESH::PointStruct & theRefPoint,
2961 const bool theMakeGroups,
2962 SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
2963 const SMDSAbs_ElementType theElementType)
2964 throw (SALOME::SALOME_Exception)
2967 MESSAGE("extrusionAlongPath");
2970 if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
2971 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2974 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2976 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2977 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2979 if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
2980 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2984 SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
2986 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2990 TIDSortedElemSet elements;
2991 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
2993 list<double> angles;
2994 for (int i = 0; i < theAngles.length(); i++) {
2995 angles.push_back( theAngles[i] );
2998 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
3000 int nbOldGroups = myMesh->NbGroup();
3002 ::SMESH_MeshEditor::Extrusion_Error error =
3003 getEditor().ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
3004 theHasAngles, angles, false,
3005 theHasRefPoint, refPnt, theMakeGroups );
3007 declareMeshModified( /*isReComputeSafe=*/true );
3008 theError = convExtrError( error );
3010 if ( theMakeGroups ) {
3011 list<int> groupIDs = myMesh->GetGroupIds();
3012 list<int>::iterator newBegin = groupIDs.begin();
3013 std::advance( newBegin, nbOldGroups ); // skip old groups
3014 groupIDs.erase( groupIDs.begin(), newBegin );
3015 return getGroups( & groupIDs );
3019 SMESH_CATCH( SMESH::throwCorbaException );
3023 //=======================================================================
3024 //function : extrusionAlongPathX
3026 //=======================================================================
3028 SMESH::ListOfGroups*
3029 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements,
3030 SMESH::SMESH_IDSource_ptr Path,
3031 CORBA::Long NodeStart,
3032 CORBA::Boolean HasAngles,
3033 const SMESH::double_array& Angles,
3034 CORBA::Boolean LinearVariation,
3035 CORBA::Boolean HasRefPoint,
3036 const SMESH::PointStruct& RefPoint,
3038 const SMDSAbs_ElementType ElementType,
3039 SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
3040 throw (SALOME::SALOME_Exception)
3043 SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
3047 list<double> angles;
3048 for (int i = 0; i < Angles.length(); i++) {
3049 angles.push_back( Angles[i] );
3051 gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
3052 int nbOldGroups = myMesh->NbGroup();
3054 if ( Path->_is_nil() ) {
3055 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3059 TIDSortedElemSet elements, copyElements;
3060 arrayToSet(IDsOfElements, getMeshDS(), elements, ElementType);
3062 TIDSortedElemSet* workElements = &elements;
3064 if ( myIsPreviewMode )
3066 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
3067 getPreviewMesh( SMDSAbs_Face )->Copy( elements, copyElements, select, avoid );
3068 workElements = & copyElements;
3072 ::SMESH_MeshEditor::Extrusion_Error error;
3074 if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path ))
3077 SMDS_MeshNode* aNodeStart =
3078 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
3079 if ( !aNodeStart ) {
3080 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3083 error = getEditor().ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
3084 HasAngles, angles, LinearVariation,
3085 HasRefPoint, refPnt, MakeGroups );
3086 declareMeshModified( /*isReComputeSafe=*/true );
3088 else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
3091 SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
3092 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
3093 SMDS_MeshNode* aNodeStart =
3094 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
3095 if ( !aNodeStart ) {
3096 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3099 SMESH_subMesh* aSubMesh =
3100 aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
3101 error = getEditor().ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
3102 HasAngles, angles, LinearVariation,
3103 HasRefPoint, refPnt, MakeGroups );
3104 declareMeshModified( /*isReComputeSafe=*/true );
3106 else if ( SMESH::DownCast<SMESH_Group_i*>( Path ))
3108 // path as group of 1D elements
3114 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3118 Error = convExtrError( error );
3121 list<int> groupIDs = myMesh->GetGroupIds();
3122 list<int>::iterator newBegin = groupIDs.begin();
3123 std::advance( newBegin, nbOldGroups ); // skip old groups
3124 groupIDs.erase( groupIDs.begin(), newBegin );
3125 return getGroups( & groupIDs );
3129 SMESH_CATCH( SMESH::throwCorbaException );
3133 //=======================================================================
3134 //function : ExtrusionAlongPath
3136 //=======================================================================
3138 SMESH::SMESH_MeshEditor::Extrusion_Error
3139 SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements,
3140 SMESH::SMESH_Mesh_ptr thePathMesh,
3141 GEOM::GEOM_Object_ptr thePathShape,
3142 CORBA::Long theNodeStart,
3143 CORBA::Boolean theHasAngles,
3144 const SMESH::double_array & theAngles,
3145 CORBA::Boolean theHasRefPoint,
3146 const SMESH::PointStruct & theRefPoint)
3147 throw (SALOME::SALOME_Exception)
3149 MESSAGE("ExtrusionAlongPath");
3150 if ( !myIsPreviewMode ) {
3151 TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
3152 << theIDsOfElements << ", "
3153 << thePathMesh << ", "
3154 << thePathShape << ", "
3155 << theNodeStart << ", "
3156 << theHasAngles << ", "
3157 << theAngles << ", "
3158 << theHasRefPoint << ", "
3159 << "SMESH.PointStruct( "
3160 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3161 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3162 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3164 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3165 extrusionAlongPath( theIDsOfElements,
3178 //=======================================================================
3179 //function : ExtrusionAlongPathObject
3181 //=======================================================================
3183 SMESH::SMESH_MeshEditor::Extrusion_Error
3184 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject,
3185 SMESH::SMESH_Mesh_ptr thePathMesh,
3186 GEOM::GEOM_Object_ptr thePathShape,
3187 CORBA::Long theNodeStart,
3188 CORBA::Boolean theHasAngles,
3189 const SMESH::double_array & theAngles,
3190 CORBA::Boolean theHasRefPoint,
3191 const SMESH::PointStruct & theRefPoint)
3192 throw (SALOME::SALOME_Exception)
3194 if ( !myIsPreviewMode ) {
3195 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
3196 << theObject << ", "
3197 << thePathMesh << ", "
3198 << thePathShape << ", "
3199 << theNodeStart << ", "
3200 << theHasAngles << ", "
3201 << theAngles << ", "
3202 << theHasRefPoint << ", "
3203 << "SMESH.PointStruct( "
3204 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3205 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3206 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3208 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3209 prepareIdSource( theObject );
3210 SMESH::long_array_var anElementsId = theObject->GetIDs();
3211 extrusionAlongPath( anElementsId,
3224 //=======================================================================
3225 //function : ExtrusionAlongPathObject1D
3227 //=======================================================================
3229 SMESH::SMESH_MeshEditor::Extrusion_Error
3230 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject,
3231 SMESH::SMESH_Mesh_ptr thePathMesh,
3232 GEOM::GEOM_Object_ptr thePathShape,
3233 CORBA::Long theNodeStart,
3234 CORBA::Boolean theHasAngles,
3235 const SMESH::double_array & theAngles,
3236 CORBA::Boolean theHasRefPoint,
3237 const SMESH::PointStruct & theRefPoint)
3238 throw (SALOME::SALOME_Exception)
3240 if ( !myIsPreviewMode ) {
3241 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
3242 << theObject << ", "
3243 << thePathMesh << ", "
3244 << thePathShape << ", "
3245 << theNodeStart << ", "
3246 << theHasAngles << ", "
3247 << theAngles << ", "
3248 << theHasRefPoint << ", "
3249 << "SMESH.PointStruct( "
3250 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3251 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3252 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3254 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3255 prepareIdSource( theObject );
3256 SMESH::long_array_var anElementsId = theObject->GetIDs();
3257 extrusionAlongPath( anElementsId,
3271 //=======================================================================
3272 //function : ExtrusionAlongPathObject2D
3274 //=======================================================================
3276 SMESH::SMESH_MeshEditor::Extrusion_Error
3277 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject,
3278 SMESH::SMESH_Mesh_ptr thePathMesh,
3279 GEOM::GEOM_Object_ptr thePathShape,
3280 CORBA::Long theNodeStart,
3281 CORBA::Boolean theHasAngles,
3282 const SMESH::double_array & theAngles,
3283 CORBA::Boolean theHasRefPoint,
3284 const SMESH::PointStruct & theRefPoint)
3285 throw (SALOME::SALOME_Exception)
3287 if ( !myIsPreviewMode ) {
3288 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
3289 << theObject << ", "
3290 << thePathMesh << ", "
3291 << thePathShape << ", "
3292 << theNodeStart << ", "
3293 << theHasAngles << ", "
3294 << theAngles << ", "
3295 << theHasRefPoint << ", "
3296 << "SMESH.PointStruct( "
3297 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3298 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3299 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3301 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3302 prepareIdSource( theObject );
3303 SMESH::long_array_var anElementsId = theObject->GetIDs();
3304 extrusionAlongPath( anElementsId,
3319 //=======================================================================
3320 //function : ExtrusionAlongPathMakeGroups
3322 //=======================================================================
3324 SMESH::ListOfGroups*
3325 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theIDsOfElements,
3326 SMESH::SMESH_Mesh_ptr thePathMesh,
3327 GEOM::GEOM_Object_ptr thePathShape,
3328 CORBA::Long theNodeStart,
3329 CORBA::Boolean theHasAngles,
3330 const SMESH::double_array& theAngles,
3331 CORBA::Boolean theHasRefPoint,
3332 const SMESH::PointStruct& theRefPoint,
3333 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3334 throw (SALOME::SALOME_Exception)
3336 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3338 SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements,
3348 if (!myIsPreviewMode) {
3349 bool isDumpGroups = aGroups && aGroups->length() > 0;
3351 aPythonDump << "(" << aGroups << ", error)";
3353 aPythonDump <<"error";
3355 aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
3356 << theIDsOfElements << ", "
3357 << thePathMesh << ", "
3358 << thePathShape << ", "
3359 << theNodeStart << ", "
3360 << theHasAngles << ", "
3361 << theAngles << ", "
3362 << theHasRefPoint << ", "
3363 << "SMESH.PointStruct( "
3364 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3365 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3366 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3371 //=======================================================================
3372 //function : ExtrusionAlongPathObjectMakeGroups
3374 //=======================================================================
3376 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3377 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3378 SMESH::SMESH_Mesh_ptr thePathMesh,
3379 GEOM::GEOM_Object_ptr thePathShape,
3380 CORBA::Long theNodeStart,
3381 CORBA::Boolean theHasAngles,
3382 const SMESH::double_array& theAngles,
3383 CORBA::Boolean theHasRefPoint,
3384 const SMESH::PointStruct& theRefPoint,
3385 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3386 throw (SALOME::SALOME_Exception)
3388 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3390 prepareIdSource( theObject );
3391 SMESH::long_array_var anElementsId = theObject->GetIDs();
3392 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3403 if (!myIsPreviewMode) {
3404 bool isDumpGroups = aGroups && aGroups->length() > 0;
3406 aPythonDump << "(" << aGroups << ", error)";
3408 aPythonDump <<"error";
3410 aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
3411 << theObject << ", "
3412 << thePathMesh << ", "
3413 << thePathShape << ", "
3414 << theNodeStart << ", "
3415 << theHasAngles << ", "
3416 << theAngles << ", "
3417 << theHasRefPoint << ", "
3418 << "SMESH.PointStruct( "
3419 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3420 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3421 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3426 //=======================================================================
3427 //function : ExtrusionAlongPathObject1DMakeGroups
3429 //=======================================================================
3431 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3432 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3433 SMESH::SMESH_Mesh_ptr thePathMesh,
3434 GEOM::GEOM_Object_ptr thePathShape,
3435 CORBA::Long theNodeStart,
3436 CORBA::Boolean theHasAngles,
3437 const SMESH::double_array& theAngles,
3438 CORBA::Boolean theHasRefPoint,
3439 const SMESH::PointStruct& theRefPoint,
3440 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3441 throw (SALOME::SALOME_Exception)
3443 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3445 prepareIdSource( theObject );
3446 SMESH::long_array_var anElementsId = theObject->GetIDs();
3447 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3459 if (!myIsPreviewMode) {
3460 bool isDumpGroups = aGroups && aGroups->length() > 0;
3462 aPythonDump << "(" << aGroups << ", error)";
3464 aPythonDump << "error";
3466 aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
3467 << theObject << ", "
3468 << thePathMesh << ", "
3469 << thePathShape << ", "
3470 << theNodeStart << ", "
3471 << theHasAngles << ", "
3472 << theAngles << ", "
3473 << theHasRefPoint << ", "
3474 << "SMESH.PointStruct( "
3475 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3476 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3477 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3482 //=======================================================================
3483 //function : ExtrusionAlongPathObject2DMakeGroups
3485 //=======================================================================
3487 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3488 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3489 SMESH::SMESH_Mesh_ptr thePathMesh,
3490 GEOM::GEOM_Object_ptr thePathShape,
3491 CORBA::Long theNodeStart,
3492 CORBA::Boolean theHasAngles,
3493 const SMESH::double_array& theAngles,
3494 CORBA::Boolean theHasRefPoint,
3495 const SMESH::PointStruct& theRefPoint,
3496 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3497 throw (SALOME::SALOME_Exception)
3499 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3501 prepareIdSource( theObject );
3502 SMESH::long_array_var anElementsId = theObject->GetIDs();
3503 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3515 if (!myIsPreviewMode) {
3516 bool isDumpGroups = aGroups && aGroups->length() > 0;
3518 aPythonDump << "(" << aGroups << ", error)";
3520 aPythonDump << "error";
3522 aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
3523 << theObject << ", "
3524 << thePathMesh << ", "
3525 << thePathShape << ", "
3526 << theNodeStart << ", "
3527 << theHasAngles << ", "
3528 << theAngles << ", "
3529 << theHasRefPoint << ", "
3530 << "SMESH.PointStruct( "
3531 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3532 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3533 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3538 //=======================================================================
3539 //function : ExtrusionAlongPathObjX
3541 //=======================================================================
3543 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3544 ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr Object,
3545 SMESH::SMESH_IDSource_ptr Path,
3546 CORBA::Long NodeStart,
3547 CORBA::Boolean HasAngles,
3548 const SMESH::double_array& Angles,
3549 CORBA::Boolean LinearVariation,
3550 CORBA::Boolean HasRefPoint,
3551 const SMESH::PointStruct& RefPoint,
3552 CORBA::Boolean MakeGroups,
3553 SMESH::ElementType ElemType,
3554 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3555 throw (SALOME::SALOME_Exception)
3557 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3559 prepareIdSource( Object );
3560 SMESH::long_array_var anElementsId = Object->GetIDs();
3561 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
3570 (SMDSAbs_ElementType)ElemType,
3573 if (!myIsPreviewMode) {
3574 bool isDumpGroups = aGroups && aGroups->length() > 0;
3576 aPythonDump << "(" << *aGroups << ", error)";
3578 aPythonDump << "error";
3580 aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
3583 << NodeStart << ", "
3584 << HasAngles << ", "
3585 << TVar( Angles ) << ", "
3586 << LinearVariation << ", "
3587 << HasRefPoint << ", "
3588 << "SMESH.PointStruct( "
3589 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3590 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3591 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3592 << MakeGroups << ", "
3593 << ElemType << " )";
3598 //=======================================================================
3599 //function : ExtrusionAlongPathX
3601 //=======================================================================
3603 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3604 ExtrusionAlongPathX(const SMESH::long_array& IDsOfElements,
3605 SMESH::SMESH_IDSource_ptr Path,
3606 CORBA::Long NodeStart,
3607 CORBA::Boolean HasAngles,
3608 const SMESH::double_array& Angles,
3609 CORBA::Boolean LinearVariation,
3610 CORBA::Boolean HasRefPoint,
3611 const SMESH::PointStruct& RefPoint,
3612 CORBA::Boolean MakeGroups,
3613 SMESH::ElementType ElemType,
3614 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3615 throw (SALOME::SALOME_Exception)
3617 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3619 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
3628 (SMDSAbs_ElementType)ElemType,
3631 if (!myIsPreviewMode) {
3632 bool isDumpGroups = aGroups && aGroups->length() > 0;
3634 aPythonDump << "(" << *aGroups << ", error)";
3636 aPythonDump <<"error";
3638 aPythonDump << " = " << this << ".ExtrusionAlongPathX( "
3639 << IDsOfElements << ", "
3641 << NodeStart << ", "
3642 << HasAngles << ", "
3643 << TVar( Angles ) << ", "
3644 << LinearVariation << ", "
3645 << HasRefPoint << ", "
3646 << "SMESH.PointStruct( "
3647 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3648 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3649 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3650 << MakeGroups << ", "
3651 << ElemType << " )";
3656 //================================================================================
3658 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
3659 * of given angles along path steps
3660 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
3661 * which proceeds the extrusion
3662 * \param PathShape is shape(edge); as the mesh can be complex, the edge
3663 * is used to define the sub-mesh for the path
3665 //================================================================================
3667 SMESH::double_array*
3668 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
3669 GEOM::GEOM_Object_ptr thePathShape,
3670 const SMESH::double_array & theAngles)
3672 SMESH::double_array_var aResult = new SMESH::double_array();
3673 int nbAngles = theAngles.length();
3674 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
3676 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3677 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3678 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3679 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
3680 return aResult._retn();
3681 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
3682 if ( nbSteps == nbAngles )
3684 aResult.inout() = theAngles;
3688 aResult->length( nbSteps );
3689 double rAn2St = double( nbAngles ) / double( nbSteps );
3690 double angPrev = 0, angle;
3691 for ( int iSt = 0; iSt < nbSteps; ++iSt )
3693 double angCur = rAn2St * ( iSt+1 );
3694 double angCurFloor = floor( angCur );
3695 double angPrevFloor = floor( angPrev );
3696 if ( angPrevFloor == angCurFloor )
3697 angle = rAn2St * theAngles[ int( angCurFloor ) ];
3700 int iP = int( angPrevFloor );
3701 double angPrevCeil = ceil(angPrev);
3702 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
3704 int iC = int( angCurFloor );
3705 if ( iC < nbAngles )
3706 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
3708 iP = int( angPrevCeil );
3710 angle += theAngles[ iC ];
3712 aResult[ iSt ] = angle;
3717 // Update Python script
3718 TPythonDump() << "rotAngles = " << theAngles;
3719 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
3720 << thePathMesh << ", "
3721 << thePathShape << ", "
3724 return aResult._retn();
3727 //=======================================================================
3730 //=======================================================================
3732 SMESH::ListOfGroups*
3733 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
3734 const SMESH::AxisStruct & theAxis,
3735 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3736 CORBA::Boolean theCopy,
3738 ::SMESH_Mesh* theTargetMesh)
3739 throw (SALOME::SALOME_Exception)
3744 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3745 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3747 if ( theTargetMesh )
3751 switch ( theMirrorType ) {
3752 case SMESH::SMESH_MeshEditor::POINT:
3753 aTrsf.SetMirror( P );
3755 case SMESH::SMESH_MeshEditor::AXIS:
3756 aTrsf.SetMirror( gp_Ax1( P, V ));
3759 aTrsf.SetMirror( gp_Ax2( P, V ));
3762 TIDSortedElemSet copyElements;
3763 TIDSortedElemSet* workElements = & theElements;
3765 if ( myIsPreviewMode )
3767 TPreviewMesh * tmpMesh = getPreviewMesh();
3768 tmpMesh->Copy( theElements, copyElements);
3769 if ( !theCopy && !theTargetMesh )
3771 TIDSortedElemSet elemsAround, elemsAroundCopy;
3772 getElementsAround( theElements, getMeshDS(), elemsAround );
3773 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3775 workElements = & copyElements;
3776 theMakeGroups = false;
3779 ::SMESH_MeshEditor::PGroupIDs groupIds =
3780 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3782 if ( theCopy && !myIsPreviewMode)
3784 if ( theTargetMesh )
3786 theTargetMesh->GetMeshDS()->Modified();
3790 declareMeshModified( /*isReComputeSafe=*/false );
3793 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3795 SMESH_CATCH( SMESH::throwCorbaException );
3799 //=======================================================================
3802 //=======================================================================
3804 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3805 const SMESH::AxisStruct & theAxis,
3806 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3807 CORBA::Boolean theCopy)
3808 throw (SALOME::SALOME_Exception)
3810 if ( !myIsPreviewMode ) {
3811 TPythonDump() << this << ".Mirror( "
3812 << theIDsOfElements << ", "
3814 << mirrorTypeName(theMirrorType) << ", "
3817 if ( theIDsOfElements.length() > 0 )
3819 TIDSortedElemSet elements;
3820 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3821 mirror(elements, theAxis, theMirrorType, theCopy, false);
3826 //=======================================================================
3827 //function : MirrorObject
3829 //=======================================================================
3831 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3832 const SMESH::AxisStruct & theAxis,
3833 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3834 CORBA::Boolean theCopy)
3835 throw (SALOME::SALOME_Exception)
3837 if ( !myIsPreviewMode ) {
3838 TPythonDump() << this << ".MirrorObject( "
3839 << theObject << ", "
3841 << mirrorTypeName(theMirrorType) << ", "
3844 TIDSortedElemSet elements;
3846 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3848 prepareIdSource( theObject );
3849 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3850 mirror(elements, theAxis, theMirrorType, theCopy, false);
3853 //=======================================================================
3854 //function : MirrorMakeGroups
3856 //=======================================================================
3858 SMESH::ListOfGroups*
3859 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3860 const SMESH::AxisStruct& theMirror,
3861 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3862 throw (SALOME::SALOME_Exception)
3864 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3866 SMESH::ListOfGroups * aGroups = 0;
3867 if ( theIDsOfElements.length() > 0 )
3869 TIDSortedElemSet elements;
3870 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3871 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3873 if (!myIsPreviewMode) {
3874 dumpGroupsList(aPythonDump, aGroups);
3875 aPythonDump << this << ".MirrorMakeGroups( "
3876 << theIDsOfElements << ", "
3877 << theMirror << ", "
3878 << mirrorTypeName(theMirrorType) << " )";
3883 //=======================================================================
3884 //function : MirrorObjectMakeGroups
3886 //=======================================================================
3888 SMESH::ListOfGroups*
3889 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3890 const SMESH::AxisStruct& theMirror,
3891 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3892 throw (SALOME::SALOME_Exception)
3894 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3896 SMESH::ListOfGroups * aGroups = 0;
3897 TIDSortedElemSet elements;
3898 prepareIdSource( theObject );
3899 if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3900 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3902 if (!myIsPreviewMode)
3904 dumpGroupsList(aPythonDump,aGroups);
3905 aPythonDump << this << ".MirrorObjectMakeGroups( "
3906 << theObject << ", "
3907 << theMirror << ", "
3908 << mirrorTypeName(theMirrorType) << " )";
3913 //=======================================================================
3914 //function : MirrorMakeMesh
3916 //=======================================================================
3918 SMESH::SMESH_Mesh_ptr
3919 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
3920 const SMESH::AxisStruct& theMirror,
3921 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3922 CORBA::Boolean theCopyGroups,
3923 const char* theMeshName)
3924 throw (SALOME::SALOME_Exception)
3926 SMESH_Mesh_i* mesh_i;
3927 SMESH::SMESH_Mesh_var mesh;
3928 { // open new scope to dump "MakeMesh" command
3929 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3931 TPythonDump pydump; // to prevent dump at mesh creation
3933 mesh = makeMesh( theMeshName );
3934 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3935 if (mesh_i && theIDsOfElements.length() > 0 )
3937 TIDSortedElemSet elements;
3938 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3939 mirror(elements, theMirror, theMirrorType,
3940 false, theCopyGroups, & mesh_i->GetImpl());
3941 mesh_i->CreateGroupServants();
3944 if (!myIsPreviewMode) {
3945 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
3946 << theIDsOfElements << ", "
3947 << theMirror << ", "
3948 << mirrorTypeName(theMirrorType) << ", "
3949 << theCopyGroups << ", '"
3950 << theMeshName << "' )";
3955 if (!myIsPreviewMode && mesh_i)
3956 mesh_i->GetGroups();
3958 return mesh._retn();
3961 //=======================================================================
3962 //function : MirrorObjectMakeMesh
3964 //=======================================================================
3966 SMESH::SMESH_Mesh_ptr
3967 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3968 const SMESH::AxisStruct& theMirror,
3969 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3970 CORBA::Boolean theCopyGroups,
3971 const char* theMeshName)
3972 throw (SALOME::SALOME_Exception)
3974 SMESH_Mesh_i* mesh_i;
3975 SMESH::SMESH_Mesh_var mesh;
3976 { // open new scope to dump "MakeMesh" command
3977 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3979 TPythonDump pydump; // to prevent dump at mesh creation
3981 mesh = makeMesh( theMeshName );
3982 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3983 TIDSortedElemSet elements;
3984 prepareIdSource( theObject );
3986 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3988 mirror(elements, theMirror, theMirrorType,
3989 false, theCopyGroups, & mesh_i->GetImpl());
3990 mesh_i->CreateGroupServants();
3992 if (!myIsPreviewMode) {
3993 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
3994 << theObject << ", "
3995 << theMirror << ", "
3996 << mirrorTypeName(theMirrorType) << ", "
3997 << theCopyGroups << ", '"
3998 << theMeshName << "' )";
4003 if (!myIsPreviewMode && mesh_i)
4004 mesh_i->GetGroups();
4006 return mesh._retn();
4009 //=======================================================================
4010 //function : translate
4012 //=======================================================================
4014 SMESH::ListOfGroups*
4015 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
4016 const SMESH::DirStruct & theVector,
4017 CORBA::Boolean theCopy,
4019 ::SMESH_Mesh* theTargetMesh)
4020 throw (SALOME::SALOME_Exception)
4025 if ( theTargetMesh )
4029 const SMESH::PointStruct * P = &theVector.PS;
4030 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
4032 TIDSortedElemSet copyElements;
4033 TIDSortedElemSet* workElements = &theElements;
4035 if ( myIsPreviewMode )
4037 TPreviewMesh * tmpMesh = getPreviewMesh();
4038 tmpMesh->Copy( theElements, copyElements);
4039 if ( !theCopy && !theTargetMesh )
4041 TIDSortedElemSet elemsAround, elemsAroundCopy;
4042 getElementsAround( theElements, getMeshDS(), elemsAround );
4043 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4045 workElements = & copyElements;
4046 theMakeGroups = false;
4049 ::SMESH_MeshEditor::PGroupIDs groupIds =
4050 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4052 if ( theCopy && !myIsPreviewMode )
4054 if ( theTargetMesh )
4056 theTargetMesh->GetMeshDS()->Modified();
4060 declareMeshModified( /*isReComputeSafe=*/false );
4064 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4066 SMESH_CATCH( SMESH::throwCorbaException );
4070 //=======================================================================
4071 //function : Translate
4073 //=======================================================================
4075 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
4076 const SMESH::DirStruct & theVector,
4077 CORBA::Boolean theCopy)
4078 throw (SALOME::SALOME_Exception)
4080 if (!myIsPreviewMode) {
4081 TPythonDump() << this << ".Translate( "
4082 << theIDsOfElements << ", "
4083 << theVector << ", "
4086 if (theIDsOfElements.length()) {
4087 TIDSortedElemSet elements;
4088 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4089 translate(elements, theVector, theCopy, false);
4093 //=======================================================================
4094 //function : TranslateObject
4096 //=======================================================================
4098 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
4099 const SMESH::DirStruct & theVector,
4100 CORBA::Boolean theCopy)
4101 throw (SALOME::SALOME_Exception)
4103 if (!myIsPreviewMode) {
4104 TPythonDump() << this << ".TranslateObject( "
4105 << theObject << ", "
4106 << theVector << ", "
4109 TIDSortedElemSet elements;
4111 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4113 prepareIdSource( theObject );
4114 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4115 translate(elements, theVector, theCopy, false);
4118 //=======================================================================
4119 //function : TranslateMakeGroups
4121 //=======================================================================
4123 SMESH::ListOfGroups*
4124 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
4125 const SMESH::DirStruct& theVector)
4126 throw (SALOME::SALOME_Exception)
4128 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4130 SMESH::ListOfGroups * aGroups = 0;
4131 if (theIDsOfElements.length()) {
4132 TIDSortedElemSet elements;
4133 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4134 aGroups = translate(elements,theVector,true,true);
4136 if (!myIsPreviewMode) {
4137 dumpGroupsList(aPythonDump, aGroups);
4138 aPythonDump << this << ".TranslateMakeGroups( "
4139 << theIDsOfElements << ", "
4140 << theVector << " )";
4145 //=======================================================================
4146 //function : TranslateObjectMakeGroups
4148 //=======================================================================
4150 SMESH::ListOfGroups*
4151 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4152 const SMESH::DirStruct& theVector)
4153 throw (SALOME::SALOME_Exception)
4155 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4157 SMESH::ListOfGroups * aGroups = 0;
4158 TIDSortedElemSet elements;
4159 prepareIdSource( theObject );
4160 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4161 aGroups = translate(elements, theVector, true, true);
4163 if (!myIsPreviewMode) {
4164 dumpGroupsList(aPythonDump, aGroups);
4165 aPythonDump << this << ".TranslateObjectMakeGroups( "
4166 << theObject << ", "
4167 << theVector << " )";
4172 //=======================================================================
4173 //function : TranslateMakeMesh
4175 //=======================================================================
4177 SMESH::SMESH_Mesh_ptr
4178 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
4179 const SMESH::DirStruct& theVector,
4180 CORBA::Boolean theCopyGroups,
4181 const char* theMeshName)
4182 throw (SALOME::SALOME_Exception)
4184 SMESH_Mesh_i* mesh_i;
4185 SMESH::SMESH_Mesh_var mesh;
4187 { // open new scope to dump "MakeMesh" command
4188 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4190 TPythonDump pydump; // to prevent dump at mesh creation
4192 mesh = makeMesh( theMeshName );
4193 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4195 if ( mesh_i && theIDsOfElements.length() )
4197 TIDSortedElemSet elements;
4198 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4199 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
4200 mesh_i->CreateGroupServants();
4203 if ( !myIsPreviewMode ) {
4204 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
4205 << theIDsOfElements << ", "
4206 << theVector << ", "
4207 << theCopyGroups << ", '"
4208 << theMeshName << "' )";
4213 if (!myIsPreviewMode && mesh_i)
4214 mesh_i->GetGroups();
4216 return mesh._retn();
4219 //=======================================================================
4220 //function : TranslateObjectMakeMesh
4222 //=======================================================================
4224 SMESH::SMESH_Mesh_ptr
4225 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4226 const SMESH::DirStruct& theVector,
4227 CORBA::Boolean theCopyGroups,
4228 const char* theMeshName)
4229 throw (SALOME::SALOME_Exception)
4232 SMESH_Mesh_i* mesh_i;
4233 SMESH::SMESH_Mesh_var mesh;
4234 { // open new scope to dump "MakeMesh" command
4235 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4237 TPythonDump pydump; // to prevent dump at mesh creation
4238 mesh = makeMesh( theMeshName );
4239 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4241 TIDSortedElemSet elements;
4242 prepareIdSource( theObject );
4244 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4246 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
4247 mesh_i->CreateGroupServants();
4249 if ( !myIsPreviewMode ) {
4250 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
4251 << theObject << ", "
4252 << theVector << ", "
4253 << theCopyGroups << ", '"
4254 << theMeshName << "' )";
4259 if (!myIsPreviewMode && mesh_i)
4260 mesh_i->GetGroups();
4262 return mesh._retn();
4264 SMESH_CATCH( SMESH::throwCorbaException );
4268 //=======================================================================
4271 //=======================================================================
4273 SMESH::ListOfGroups*
4274 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
4275 const SMESH::AxisStruct & theAxis,
4276 CORBA::Double theAngle,
4277 CORBA::Boolean theCopy,
4279 ::SMESH_Mesh* theTargetMesh)
4280 throw (SALOME::SALOME_Exception)
4285 if ( theTargetMesh )
4288 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
4289 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
4292 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
4294 TIDSortedElemSet copyElements;
4295 TIDSortedElemSet* workElements = &theElements;
4296 if ( myIsPreviewMode ) {
4297 TPreviewMesh * tmpMesh = getPreviewMesh();
4298 tmpMesh->Copy( theElements, copyElements );
4299 if ( !theCopy && !theTargetMesh )
4301 TIDSortedElemSet elemsAround, elemsAroundCopy;
4302 getElementsAround( theElements, getMeshDS(), elemsAround );
4303 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4305 workElements = ©Elements;
4306 theMakeGroups = false;
4309 ::SMESH_MeshEditor::PGroupIDs groupIds =
4310 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4312 if ( theCopy && !myIsPreviewMode)
4314 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
4315 else declareMeshModified( /*isReComputeSafe=*/false );
4318 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4320 SMESH_CATCH( SMESH::throwCorbaException );
4324 //=======================================================================
4327 //=======================================================================
4329 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
4330 const SMESH::AxisStruct & theAxis,
4331 CORBA::Double theAngle,
4332 CORBA::Boolean theCopy)
4333 throw (SALOME::SALOME_Exception)
4335 if (!myIsPreviewMode) {
4336 TPythonDump() << this << ".Rotate( "
4337 << theIDsOfElements << ", "
4339 << TVar( theAngle ) << ", "
4342 if (theIDsOfElements.length() > 0)
4344 TIDSortedElemSet elements;
4345 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4346 rotate(elements,theAxis,theAngle,theCopy,false);
4350 //=======================================================================
4351 //function : RotateObject
4353 //=======================================================================
4355 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
4356 const SMESH::AxisStruct & theAxis,
4357 CORBA::Double theAngle,
4358 CORBA::Boolean theCopy)
4359 throw (SALOME::SALOME_Exception)
4361 if ( !myIsPreviewMode ) {
4362 TPythonDump() << this << ".RotateObject( "
4363 << theObject << ", "
4365 << TVar( theAngle ) << ", "
4368 TIDSortedElemSet elements;
4369 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4370 prepareIdSource( theObject );
4371 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4372 rotate(elements,theAxis,theAngle,theCopy,false);
4375 //=======================================================================
4376 //function : RotateMakeGroups
4378 //=======================================================================
4380 SMESH::ListOfGroups*
4381 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
4382 const SMESH::AxisStruct& theAxis,
4383 CORBA::Double theAngle)
4384 throw (SALOME::SALOME_Exception)
4386 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4388 SMESH::ListOfGroups * aGroups = 0;
4389 if (theIDsOfElements.length() > 0)
4391 TIDSortedElemSet elements;
4392 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4393 aGroups = rotate(elements,theAxis,theAngle,true,true);
4395 if (!myIsPreviewMode) {
4396 dumpGroupsList(aPythonDump, aGroups);
4397 aPythonDump << this << ".RotateMakeGroups( "
4398 << theIDsOfElements << ", "
4400 << TVar( theAngle ) << " )";
4405 //=======================================================================
4406 //function : RotateObjectMakeGroups
4408 //=======================================================================
4410 SMESH::ListOfGroups*
4411 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4412 const SMESH::AxisStruct& theAxis,
4413 CORBA::Double theAngle)
4414 throw (SALOME::SALOME_Exception)
4416 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4418 SMESH::ListOfGroups * aGroups = 0;
4419 TIDSortedElemSet elements;
4420 prepareIdSource( theObject );
4421 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4422 aGroups = rotate(elements, theAxis, theAngle, true, true);
4424 if (!myIsPreviewMode) {
4425 dumpGroupsList(aPythonDump, aGroups);
4426 aPythonDump << this << ".RotateObjectMakeGroups( "
4427 << theObject << ", "
4429 << TVar( theAngle ) << " )";
4434 //=======================================================================
4435 //function : RotateMakeMesh
4437 //=======================================================================
4439 SMESH::SMESH_Mesh_ptr
4440 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
4441 const SMESH::AxisStruct& theAxis,
4442 CORBA::Double theAngleInRadians,
4443 CORBA::Boolean theCopyGroups,
4444 const char* theMeshName)
4445 throw (SALOME::SALOME_Exception)
4448 SMESH::SMESH_Mesh_var mesh;
4449 SMESH_Mesh_i* mesh_i;
4451 { // open new scope to dump "MakeMesh" command
4452 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4454 TPythonDump pydump; // to prevent dump at mesh creation
4456 mesh = makeMesh( theMeshName );
4457 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4459 if ( mesh_i && theIDsOfElements.length() > 0 )
4461 TIDSortedElemSet elements;
4462 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4463 rotate(elements, theAxis, theAngleInRadians,
4464 false, theCopyGroups, & mesh_i->GetImpl());
4465 mesh_i->CreateGroupServants();
4467 if ( !myIsPreviewMode ) {
4468 pydump << mesh << " = " << this << ".RotateMakeMesh( "
4469 << theIDsOfElements << ", "
4471 << TVar( theAngleInRadians ) << ", "
4472 << theCopyGroups << ", '"
4473 << theMeshName << "' )";
4478 if (!myIsPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
4479 mesh_i->GetGroups();
4481 return mesh._retn();
4483 SMESH_CATCH( SMESH::throwCorbaException );
4487 //=======================================================================
4488 //function : RotateObjectMakeMesh
4490 //=======================================================================
4492 SMESH::SMESH_Mesh_ptr
4493 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4494 const SMESH::AxisStruct& theAxis,
4495 CORBA::Double theAngleInRadians,
4496 CORBA::Boolean theCopyGroups,
4497 const char* theMeshName)
4498 throw (SALOME::SALOME_Exception)
4501 SMESH::SMESH_Mesh_var mesh;
4502 SMESH_Mesh_i* mesh_i;
4504 {// open new scope to dump "MakeMesh" command
4505 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4507 TPythonDump pydump; // to prevent dump at mesh creation
4508 mesh = makeMesh( theMeshName );
4509 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4511 TIDSortedElemSet elements;
4512 prepareIdSource( theObject );
4514 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4516 rotate(elements, theAxis, theAngleInRadians,
4517 false, theCopyGroups, & mesh_i->GetImpl());
4518 mesh_i->CreateGroupServants();
4520 if ( !myIsPreviewMode ) {
4521 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
4522 << theObject << ", "
4524 << TVar( theAngleInRadians ) << ", "
4525 << theCopyGroups << ", '"
4526 << theMeshName << "' )";
4531 if (!myIsPreviewMode && mesh_i)
4532 mesh_i->GetGroups();
4534 return mesh._retn();
4536 SMESH_CATCH( SMESH::throwCorbaException );
4540 //=======================================================================
4543 //=======================================================================
4545 SMESH::ListOfGroups*
4546 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
4547 const SMESH::PointStruct& thePoint,
4548 const SMESH::double_array& theScaleFact,
4549 CORBA::Boolean theCopy,
4551 ::SMESH_Mesh* theTargetMesh)
4552 throw (SALOME::SALOME_Exception)
4556 if ( theScaleFact.length() < 1 )
4557 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
4558 if ( theScaleFact.length() == 2 )
4559 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
4561 if ( theTargetMesh )
4564 TIDSortedElemSet elements;
4565 prepareIdSource( theObject );
4566 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4567 if ( !idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4572 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
4573 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
4575 double tol = std::numeric_limits<double>::max();
4577 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
4578 0, S[1], 0, thePoint.y * (1-S[1]),
4579 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
4581 TIDSortedElemSet copyElements;
4582 TIDSortedElemSet* workElements = &elements;
4583 if ( myIsPreviewMode )
4585 TPreviewMesh * tmpMesh = getPreviewMesh();
4586 tmpMesh->Copy( elements, copyElements);
4587 if ( !theCopy && !theTargetMesh )
4589 TIDSortedElemSet elemsAround, elemsAroundCopy;
4590 getElementsAround( elements, getMeshDS(), elemsAround );
4591 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4593 workElements = & copyElements;
4594 theMakeGroups = false;
4597 ::SMESH_MeshEditor::PGroupIDs groupIds =
4598 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4600 if ( theCopy && !myIsPreviewMode )
4602 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
4603 else declareMeshModified( /*isReComputeSafe=*/false );
4605 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4607 SMESH_CATCH( SMESH::throwCorbaException );
4611 //=======================================================================
4614 //=======================================================================
4616 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
4617 const SMESH::PointStruct& thePoint,
4618 const SMESH::double_array& theScaleFact,
4619 CORBA::Boolean theCopy)
4620 throw (SALOME::SALOME_Exception)
4622 if ( !myIsPreviewMode ) {
4623 TPythonDump() << this << ".Scale( "
4624 << theObject << ", "
4626 << TVar( theScaleFact ) << ", "
4629 scale(theObject, thePoint, theScaleFact, theCopy, false);
4633 //=======================================================================
4634 //function : ScaleMakeGroups
4636 //=======================================================================
4638 SMESH::ListOfGroups*
4639 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4640 const SMESH::PointStruct& thePoint,
4641 const SMESH::double_array& theScaleFact)
4642 throw (SALOME::SALOME_Exception)
4644 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4646 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
4647 if (!myIsPreviewMode) {
4648 dumpGroupsList(aPythonDump, aGroups);
4649 aPythonDump << this << ".Scale("
4652 << TVar( theScaleFact ) << ",True,True)";
4658 //=======================================================================
4659 //function : ScaleMakeMesh
4661 //=======================================================================
4663 SMESH::SMESH_Mesh_ptr
4664 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4665 const SMESH::PointStruct& thePoint,
4666 const SMESH::double_array& theScaleFact,
4667 CORBA::Boolean theCopyGroups,
4668 const char* theMeshName)
4669 throw (SALOME::SALOME_Exception)
4671 SMESH_Mesh_i* mesh_i;
4672 SMESH::SMESH_Mesh_var mesh;
4673 { // open new scope to dump "MakeMesh" command
4674 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4676 TPythonDump pydump; // to prevent dump at mesh creation
4677 mesh = makeMesh( theMeshName );
4678 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4682 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
4683 mesh_i->CreateGroupServants();
4685 if ( !myIsPreviewMode )
4686 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
4687 << theObject << ", "
4689 << TVar( theScaleFact ) << ", "
4690 << theCopyGroups << ", '"
4691 << theMeshName << "' )";
4695 if (!myIsPreviewMode && mesh_i)
4696 mesh_i->GetGroups();
4698 return mesh._retn();
4702 //=======================================================================
4703 //function : FindCoincidentNodes
4705 //=======================================================================
4707 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance,
4708 SMESH::array_of_long_array_out GroupsOfNodes)
4709 throw (SALOME::SALOME_Exception)
4714 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4715 TIDSortedNodeSet nodes; // no input nodes
4716 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4718 GroupsOfNodes = new SMESH::array_of_long_array;
4719 GroupsOfNodes->length( aListOfListOfNodes.size() );
4720 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4721 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
4722 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4723 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4724 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4725 aGroup.length( aListOfNodes.size() );
4726 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4727 aGroup[ j ] = (*lIt)->GetID();
4729 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
4730 << Tolerance << " )";
4732 SMESH_CATCH( SMESH::throwCorbaException );
4735 //=======================================================================
4736 //function : FindCoincidentNodesOnPart
4738 //=======================================================================
4740 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
4741 CORBA::Double Tolerance,
4742 SMESH::array_of_long_array_out GroupsOfNodes)
4743 throw (SALOME::SALOME_Exception)
4748 TIDSortedNodeSet nodes;
4749 prepareIdSource( theObject );
4750 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4752 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4754 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4756 GroupsOfNodes = new SMESH::array_of_long_array;
4757 GroupsOfNodes->length( aListOfListOfNodes.size() );
4758 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4759 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4761 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4762 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4763 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4764 aGroup.length( aListOfNodes.size() );
4765 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4766 aGroup[ j ] = (*lIt)->GetID();
4768 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
4770 << Tolerance << " )";
4772 SMESH_CATCH( SMESH::throwCorbaException );
4775 //================================================================================
4777 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
4778 * ExceptSubMeshOrGroups
4780 //================================================================================
4782 void SMESH_MeshEditor_i::
4783 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
4784 CORBA::Double theTolerance,
4785 SMESH::array_of_long_array_out theGroupsOfNodes,
4786 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups)
4787 throw (SALOME::SALOME_Exception)
4792 TIDSortedNodeSet nodes;
4793 prepareIdSource( theObject );
4794 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4796 for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
4798 TIDSortedNodeSet exceptNodes;
4799 idSourceToNodeSet( theExceptSubMeshOrGroups[i], getMeshDS(), exceptNodes );
4800 TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
4801 for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
4802 nodes.erase( *avoidNode );
4804 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4806 getEditor().FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
4808 theGroupsOfNodes = new SMESH::array_of_long_array;
4809 theGroupsOfNodes->length( aListOfListOfNodes.size() );
4810 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4811 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4813 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4814 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4815 SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
4816 aGroup.length( aListOfNodes.size() );
4817 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4818 aGroup[ j ] = (*lIt)->GetID();
4820 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
4822 << theTolerance << ", "
4823 << theExceptSubMeshOrGroups << " )";
4825 SMESH_CATCH( SMESH::throwCorbaException );
4828 //=======================================================================
4829 //function : MergeNodes
4831 //=======================================================================
4833 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
4834 throw (SALOME::SALOME_Exception)
4839 SMESHDS_Mesh* aMesh = getMeshDS();
4841 TPythonDump aTPythonDump;
4842 aTPythonDump << this << ".MergeNodes([";
4843 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4844 for (int i = 0; i < GroupsOfNodes.length(); i++)
4846 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
4847 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
4848 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
4849 for ( int j = 0; j < aNodeGroup.length(); j++ )
4851 CORBA::Long index = aNodeGroup[ j ];
4852 const SMDS_MeshNode * node = aMesh->FindNode(index);
4854 aListOfNodes.push_back( node );
4856 if ( aListOfNodes.size() < 2 )
4857 aListOfListOfNodes.pop_back();
4859 if ( i > 0 ) aTPythonDump << ", ";
4860 aTPythonDump << aNodeGroup;
4862 getEditor().MergeNodes( aListOfListOfNodes );
4864 aTPythonDump << "])";
4866 declareMeshModified( /*isReComputeSafe=*/false );
4868 SMESH_CATCH( SMESH::throwCorbaException );
4871 //=======================================================================
4872 //function : FindEqualElements
4874 //=======================================================================
4876 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
4877 SMESH::array_of_long_array_out GroupsOfElementsID)
4878 throw (SALOME::SALOME_Exception)
4883 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
4884 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
4886 TIDSortedElemSet elems;
4887 prepareIdSource( theObject );
4888 idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true);
4890 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4891 getEditor().FindEqualElements( elems, aListOfListOfElementsID );
4893 GroupsOfElementsID = new SMESH::array_of_long_array;
4894 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
4896 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt =
4897 aListOfListOfElementsID.begin();
4898 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j)
4900 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
4901 list<int>& listOfIDs = *arraysIt;
4902 aGroup.length( listOfIDs.size() );
4903 list<int>::iterator idIt = listOfIDs.begin();
4904 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k )
4905 aGroup[ k ] = *idIt;
4908 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
4912 SMESH_CATCH( SMESH::throwCorbaException );
4915 //=======================================================================
4916 //function : MergeElements
4918 //=======================================================================
4920 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
4921 throw (SALOME::SALOME_Exception)
4926 TPythonDump aTPythonDump;
4927 aTPythonDump << this << ".MergeElements( [";
4929 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4931 for (int i = 0; i < GroupsOfElementsID.length(); i++) {
4932 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
4933 aListOfListOfElementsID.push_back( list< int >() );
4934 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
4935 for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
4936 CORBA::Long id = anElemsIDGroup[ j ];
4937 aListOfElemsID.push_back( id );
4939 if ( aListOfElemsID.size() < 2 )
4940 aListOfListOfElementsID.pop_back();
4941 if ( i > 0 ) aTPythonDump << ", ";
4942 aTPythonDump << anElemsIDGroup;
4945 getEditor().MergeElements(aListOfListOfElementsID);
4947 declareMeshModified( /*isReComputeSafe=*/true );
4949 aTPythonDump << "] )";
4951 SMESH_CATCH( SMESH::throwCorbaException );
4954 //=======================================================================
4955 //function : MergeEqualElements
4957 //=======================================================================
4959 void SMESH_MeshEditor_i::MergeEqualElements()
4960 throw (SALOME::SALOME_Exception)
4965 getEditor().MergeEqualElements();
4967 declareMeshModified( /*isReComputeSafe=*/true );
4969 TPythonDump() << this << ".MergeEqualElements()";
4971 SMESH_CATCH( SMESH::throwCorbaException );
4974 //=============================================================================
4976 * Move the node to a given point
4978 //=============================================================================
4980 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
4984 throw (SALOME::SALOME_Exception)
4987 initData(/*deleteSearchers=*/false);
4989 const SMDS_MeshNode * node = getMeshDS()->FindNode( NodeID );
4993 if ( theNodeSearcher )
4994 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4996 if ( myIsPreviewMode ) // make preview data
4998 // in a preview mesh, make edges linked to a node
4999 TPreviewMesh& tmpMesh = *getPreviewMesh();
5000 TIDSortedElemSet linkedNodes;
5001 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
5002 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
5003 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
5004 for ( ; nIt != linkedNodes.end(); ++nIt )
5006 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
5007 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
5011 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
5012 // fill preview data
5014 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
5015 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
5017 getMeshDS()->MoveNode(node, x, y, z);
5019 if ( !myIsPreviewMode )
5021 // Update Python script
5022 TPythonDump() << "isDone = " << this << ".MoveNode( "
5023 << NodeID << ", " << TVar(x) << ", " << TVar(y) << ", " << TVar(z) << " )";
5024 declareMeshModified( /*isReComputeSafe=*/false );
5027 SMESH_CATCH( SMESH::throwCorbaException );
5032 //================================================================================
5034 * \brief Return ID of node closest to a given point
5036 //================================================================================
5038 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
5041 throw (SALOME::SALOME_Exception)
5044 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5046 if ( !theNodeSearcher ) {
5047 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
5050 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
5051 return node->GetID();
5053 SMESH_CATCH( SMESH::throwCorbaException );
5057 //================================================================================
5059 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
5060 * move the node closest to the point to point's location and return ID of the node
5062 //================================================================================
5064 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
5067 CORBA::Long theNodeID)
5068 throw (SALOME::SALOME_Exception)
5071 // We keep theNodeSearcher until any mesh modification:
5072 // 1) initData() deletes theNodeSearcher at any edition,
5073 // 2) TSearchersDeleter - at any mesh compute event and mesh change
5075 initData(/*deleteSearchers=*/false);
5077 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5079 int nodeID = theNodeID;
5080 const SMDS_MeshNode* node = getMeshDS()->FindNode( nodeID );
5081 if ( !node ) // preview moving node
5083 if ( !theNodeSearcher ) {
5084 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
5087 node = theNodeSearcher->FindClosestTo( p );
5090 nodeID = node->GetID();
5091 if ( myIsPreviewMode ) // make preview data
5093 // in a preview mesh, make edges linked to a node
5094 TPreviewMesh tmpMesh = *getPreviewMesh();
5095 TIDSortedElemSet linkedNodes;
5096 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
5097 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
5098 for ( ; nIt != linkedNodes.end(); ++nIt )
5100 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
5101 tmpMesh.Copy( &edge );
5104 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
5106 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
5107 // fill preview data
5109 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
5111 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
5115 getMeshDS()->MoveNode(node, x, y, z);
5119 if ( !myIsPreviewMode )
5121 TPythonDump() << "nodeID = " << this
5122 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
5123 << ", " << nodeID << " )";
5125 declareMeshModified( /*isReComputeSafe=*/false );
5130 SMESH_CATCH( SMESH::throwCorbaException );
5134 //=======================================================================
5136 * Return elements of given type where the given point is IN or ON.
5138 * 'ALL' type means elements of any type excluding nodes
5140 //=======================================================================
5142 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
5145 SMESH::ElementType type)
5146 throw (SALOME::SALOME_Exception)
5149 SMESH::long_array_var res = new SMESH::long_array;
5150 vector< const SMDS_MeshElement* > foundElems;
5152 theSearchersDeleter.Set( myMesh );
5153 if ( !theElementSearcher ) {
5154 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
5156 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
5157 SMDSAbs_ElementType( type ),
5159 res->length( foundElems.size() );
5160 for ( int i = 0; i < foundElems.size(); ++i )
5161 res[i] = foundElems[i]->GetID();
5163 if ( !myIsPreviewMode ) // call from tui
5164 TPythonDump() << "res = " << this << ".FindElementsByPoint( "
5172 SMESH_CATCH( SMESH::throwCorbaException );
5176 //=======================================================================
5177 //function : FindAmongElementsByPoint
5178 //purpose : Searching among the given elements, return elements of given type
5179 // where the given point is IN or ON.
5180 // 'ALL' type means elements of any type excluding nodes
5181 //=======================================================================
5184 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
5188 SMESH::ElementType type)
5189 throw (SALOME::SALOME_Exception)
5192 SMESH::long_array_var res = new SMESH::long_array;
5194 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
5195 if ( types->length() == 1 && // a part contains only nodes or 0D elements
5196 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) &&
5197 type != types[0] ) // but search of elements of dim > 0
5200 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
5201 return FindElementsByPoint( x,y,z, type );
5203 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
5205 theSearchersDeleter.Set( myMesh, getPartIOR( elementIDs, type ));
5206 if ( !theElementSearcher )
5208 // create a searcher from elementIDs
5209 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
5210 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
5212 if ( !idSourceToSet( elementIDs, meshDS, elements,
5213 SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
5216 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5217 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
5219 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt );
5222 vector< const SMDS_MeshElement* > foundElems;
5224 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
5225 SMDSAbs_ElementType( type ),
5227 res->length( foundElems.size() );
5228 for ( int i = 0; i < foundElems.size(); ++i )
5229 res[i] = foundElems[i]->GetID();
5231 if ( !myIsPreviewMode ) // call from tui
5232 TPythonDump() << "res = " << this << ".FindAmongElementsByPoint( "
5233 << elementIDs << ", "
5241 SMESH_CATCH( SMESH::throwCorbaException );
5245 //=======================================================================
5246 //function : GetPointState
5247 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
5248 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
5249 //=======================================================================
5251 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
5254 throw (SALOME::SALOME_Exception)
5257 theSearchersDeleter.Set( myMesh );
5258 if ( !theElementSearcher ) {
5259 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
5261 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
5263 SMESH_CATCH( SMESH::throwCorbaException );
5267 //=======================================================================
5268 //function : convError
5270 //=======================================================================
5272 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
5274 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
5278 RETCASE( SEW_BORDER1_NOT_FOUND );
5279 RETCASE( SEW_BORDER2_NOT_FOUND );
5280 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
5281 RETCASE( SEW_BAD_SIDE_NODES );
5282 RETCASE( SEW_VOLUMES_TO_SPLIT );
5283 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
5284 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
5285 RETCASE( SEW_BAD_SIDE1_NODES );
5286 RETCASE( SEW_BAD_SIDE2_NODES );
5288 return SMESH::SMESH_MeshEditor::SEW_OK;
5291 //=======================================================================
5292 //function : SewFreeBorders
5294 //=======================================================================
5296 SMESH::SMESH_MeshEditor::Sew_Error
5297 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
5298 CORBA::Long SecondNodeID1,
5299 CORBA::Long LastNodeID1,
5300 CORBA::Long FirstNodeID2,
5301 CORBA::Long SecondNodeID2,
5302 CORBA::Long LastNodeID2,
5303 CORBA::Boolean CreatePolygons,
5304 CORBA::Boolean CreatePolyedrs)
5305 throw (SALOME::SALOME_Exception)
5310 SMESHDS_Mesh* aMesh = getMeshDS();
5312 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
5313 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
5314 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
5315 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
5316 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
5317 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
5319 if (!aBorderFirstNode ||
5320 !aBorderSecondNode||
5322 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5323 if (!aSide2FirstNode ||
5324 !aSide2SecondNode ||
5326 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
5328 TPythonDump() << "error = " << this << ".SewFreeBorders( "
5329 << FirstNodeID1 << ", "
5330 << SecondNodeID1 << ", "
5331 << LastNodeID1 << ", "
5332 << FirstNodeID2 << ", "
5333 << SecondNodeID2 << ", "
5334 << LastNodeID2 << ", "
5335 << CreatePolygons<< ", "
5336 << CreatePolyedrs<< " )";
5338 SMESH::SMESH_MeshEditor::Sew_Error error =
5339 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5350 declareMeshModified( /*isReComputeSafe=*/false );
5353 SMESH_CATCH( SMESH::throwCorbaException );
5354 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5358 //=======================================================================
5359 //function : SewConformFreeBorders
5361 //=======================================================================
5363 SMESH::SMESH_MeshEditor::Sew_Error
5364 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
5365 CORBA::Long SecondNodeID1,
5366 CORBA::Long LastNodeID1,
5367 CORBA::Long FirstNodeID2,
5368 CORBA::Long SecondNodeID2)
5369 throw (SALOME::SALOME_Exception)
5374 SMESHDS_Mesh* aMesh = getMeshDS();
5376 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
5377 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
5378 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
5379 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
5380 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
5381 const SMDS_MeshNode* aSide2ThirdNode = 0;
5383 if (!aBorderFirstNode ||
5384 !aBorderSecondNode||
5386 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5387 if (!aSide2FirstNode ||
5389 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
5391 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
5392 << FirstNodeID1 << ", "
5393 << SecondNodeID1 << ", "
5394 << LastNodeID1 << ", "
5395 << FirstNodeID2 << ", "
5396 << SecondNodeID2 << " )";
5398 SMESH::SMESH_MeshEditor::Sew_Error error =
5399 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5408 declareMeshModified( /*isReComputeSafe=*/false );
5411 SMESH_CATCH( SMESH::throwCorbaException );
5412 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5416 //=======================================================================
5417 //function : SewBorderToSide
5419 //=======================================================================
5421 SMESH::SMESH_MeshEditor::Sew_Error
5422 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
5423 CORBA::Long SecondNodeIDOnFreeBorder,
5424 CORBA::Long LastNodeIDOnFreeBorder,
5425 CORBA::Long FirstNodeIDOnSide,
5426 CORBA::Long LastNodeIDOnSide,
5427 CORBA::Boolean CreatePolygons,
5428 CORBA::Boolean CreatePolyedrs)
5429 throw (SALOME::SALOME_Exception)
5434 SMESHDS_Mesh* aMesh = getMeshDS();
5436 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
5437 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
5438 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
5439 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
5440 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
5441 const SMDS_MeshNode* aSide2ThirdNode = 0;
5443 if (!aBorderFirstNode ||
5444 !aBorderSecondNode||
5446 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5447 if (!aSide2FirstNode ||
5449 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
5451 TPythonDump() << "error = " << this << ".SewBorderToSide( "
5452 << FirstNodeIDOnFreeBorder << ", "
5453 << SecondNodeIDOnFreeBorder << ", "
5454 << LastNodeIDOnFreeBorder << ", "
5455 << FirstNodeIDOnSide << ", "
5456 << LastNodeIDOnSide << ", "
5457 << CreatePolygons << ", "
5458 << CreatePolyedrs << ") ";
5460 SMESH::SMESH_MeshEditor::Sew_Error error =
5461 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5471 declareMeshModified( /*isReComputeSafe=*/false );
5474 SMESH_CATCH( SMESH::throwCorbaException );
5475 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5479 //=======================================================================
5480 //function : SewSideElements
5482 //=======================================================================
5484 SMESH::SMESH_MeshEditor::Sew_Error
5485 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
5486 const SMESH::long_array& IDsOfSide2Elements,
5487 CORBA::Long NodeID1OfSide1ToMerge,
5488 CORBA::Long NodeID1OfSide2ToMerge,
5489 CORBA::Long NodeID2OfSide1ToMerge,
5490 CORBA::Long NodeID2OfSide2ToMerge)
5491 throw (SALOME::SALOME_Exception)
5496 SMESHDS_Mesh* aMesh = getMeshDS();
5498 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
5499 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
5500 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
5501 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
5503 if (!aFirstNode1ToMerge ||
5504 !aFirstNode2ToMerge )
5505 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
5506 if (!aSecondNode1ToMerge||
5507 !aSecondNode2ToMerge)
5508 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
5510 TIDSortedElemSet aSide1Elems, aSide2Elems;
5511 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
5512 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
5514 TPythonDump() << "error = " << this << ".SewSideElements( "
5515 << IDsOfSide1Elements << ", "
5516 << IDsOfSide2Elements << ", "
5517 << NodeID1OfSide1ToMerge << ", "
5518 << NodeID1OfSide2ToMerge << ", "
5519 << NodeID2OfSide1ToMerge << ", "
5520 << NodeID2OfSide2ToMerge << ")";
5522 SMESH::SMESH_MeshEditor::Sew_Error error =
5523 convError( getEditor().SewSideElements (aSide1Elems, aSide2Elems,
5526 aSecondNode1ToMerge,
5527 aSecondNode2ToMerge));
5529 declareMeshModified( /*isReComputeSafe=*/false );
5532 SMESH_CATCH( SMESH::throwCorbaException );
5533 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5536 //================================================================================
5538 * \brief Set new nodes for given element
5539 * \param ide - element id
5540 * \param newIDs - new node ids
5541 * \retval CORBA::Boolean - true if result is OK
5543 //================================================================================
5545 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
5546 const SMESH::long_array& newIDs)
5547 throw (SALOME::SALOME_Exception)
5552 const SMDS_MeshElement* elem = getMeshDS()->FindElement(ide);
5553 if(!elem) return false;
5555 int nbn = newIDs.length();
5557 vector<const SMDS_MeshNode*> aNodes(nbn);
5560 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(newIDs[i]);
5563 aNodes[nbn1] = aNode;
5566 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
5567 << ide << ", " << newIDs << " )";
5569 MESSAGE("ChangeElementNodes");
5570 bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
5572 declareMeshModified( /*isReComputeSafe=*/ !res );
5576 SMESH_CATCH( SMESH::throwCorbaException );
5580 //=======================================================================
5582 * \brief Makes a part of the mesh quadratic or bi-quadratic
5584 //=======================================================================
5586 void SMESH_MeshEditor_i::convertToQuadratic(CORBA::Boolean theForce3d,
5587 CORBA::Boolean theToBiQuad,
5588 SMESH::SMESH_IDSource_ptr theObject)
5589 throw (SALOME::SALOME_Exception)
5592 TIDSortedElemSet elems;
5594 if ( !( elemsOK = CORBA::is_nil( theObject )))
5596 prepareIdSource( theObject );
5597 elemsOK = idSourceToSet( theObject, getMeshDS(), elems,
5598 SMDSAbs_All, /*emptyIfIsMesh=*/true );
5602 if ( !elems.empty() && (*elems.begin())->GetType() == SMDSAbs_Node )
5603 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5605 if ( elems.empty() ) getEditor().ConvertToQuadratic(theForce3d, theToBiQuad);
5606 else getEditor().ConvertToQuadratic(theForce3d, elems, theToBiQuad);
5608 declareMeshModified( /*isReComputeSafe=*/false );
5611 SMESH_CATCH( SMESH::throwCorbaException );
5614 //=======================================================================
5615 //function : ConvertFromQuadratic
5617 //=======================================================================
5619 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
5620 throw (SALOME::SALOME_Exception)
5622 CORBA::Boolean isDone = getEditor().ConvertFromQuadratic();
5623 TPythonDump() << this << ".ConvertFromQuadratic()";
5624 declareMeshModified( /*isReComputeSafe=*/!isDone );
5628 //=======================================================================
5629 //function : ConvertToQuadratic
5631 //=======================================================================
5633 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
5634 throw (SALOME::SALOME_Exception)
5636 convertToQuadratic( theForce3d, false );
5637 TPythonDump() << this << ".ConvertToQuadratic("<<theForce3d<<")";
5640 //================================================================================
5642 * \brief Makes a part of the mesh quadratic
5644 //================================================================================
5646 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
5647 SMESH::SMESH_IDSource_ptr theObject)
5648 throw (SALOME::SALOME_Exception)
5650 convertToQuadratic( theForce3d, false, theObject );
5651 TPythonDump() << this << ".ConvertToQuadraticObject("<<theForce3d<<", "<<theObject<<")";
5654 //================================================================================
5656 * \brief Makes a part of the mesh bi-quadratic
5658 //================================================================================
5660 void SMESH_MeshEditor_i::ConvertToBiQuadratic(CORBA::Boolean theForce3d,
5661 SMESH::SMESH_IDSource_ptr theObject)
5662 throw (SALOME::SALOME_Exception)
5664 convertToQuadratic( theForce3d, true, theObject );
5665 TPythonDump() << this << ".ConvertToBiQuadratic("<<theForce3d<<", "<<theObject<<")";
5668 //================================================================================
5670 * \brief Makes a part of the mesh linear
5672 //================================================================================
5674 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
5675 throw (SALOME::SALOME_Exception)
5681 TIDSortedElemSet elems;
5682 prepareIdSource( theObject );
5683 if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5685 if ( elems.empty() )
5687 ConvertFromQuadratic();
5689 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5691 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5695 getEditor().ConvertFromQuadratic(elems);
5698 declareMeshModified( /*isReComputeSafe=*/false );
5700 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
5702 SMESH_CATCH( SMESH::throwCorbaException );
5705 //=======================================================================
5706 //function : makeMesh
5707 //purpose : create a named imported mesh
5708 //=======================================================================
5710 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
5712 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
5713 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
5714 SALOMEDS::Study_var study = gen->GetCurrentStudy();
5715 SALOMEDS::SObject_wrap meshSO = gen->ObjectToSObject( study, mesh );
5716 gen->SetName( meshSO, theMeshName, "Mesh" );
5717 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
5719 return mesh._retn();
5722 //=======================================================================
5723 //function : dumpGroupsList
5725 //=======================================================================
5727 void SMESH_MeshEditor_i::dumpGroupsList(TPythonDump & theDumpPython,
5728 const SMESH::ListOfGroups * theGroupList)
5730 bool isDumpGroupList = ( theGroupList && theGroupList->length() > 0 );
5731 if ( isDumpGroupList )
5732 theDumpPython << theGroupList << " = ";
5735 //================================================================================
5737 \brief Generates the unique group name.
5738 \param thePrefix name prefix
5741 //================================================================================
5743 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
5745 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5746 set<string> groupNames;
5748 // Get existing group names
5749 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
5750 SMESH::SMESH_GroupBase_var aGroup = groups[i];
5751 if (CORBA::is_nil(aGroup))
5754 CORBA::String_var name = aGroup->GetName();
5755 groupNames.insert( name.in() );
5759 string name = thePrefix;
5762 while (!groupNames.insert(name).second)
5763 name = SMESH_Comment( thePrefix ) << "_" << index++;
5768 //================================================================================
5770 * \brief Prepare SMESH_IDSource for work
5772 //================================================================================
5774 void SMESH_MeshEditor_i::prepareIdSource(SMESH::SMESH_IDSource_ptr theObject)
5776 if ( SMESH::Filter_i* filter = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5778 SMESH::SMESH_Mesh_var mesh = myMesh_i->_this();
5779 filter->SetMesh( mesh );
5783 //================================================================================
5785 * \brief Duplicates given elements, i.e. creates new elements based on the
5786 * same nodes as the given ones.
5787 * \param theElements - container of elements to duplicate.
5788 * \param theGroupName - a name of group to contain the generated elements.
5789 * If a group with such a name already exists, the new elements
5790 * are added to the existng group, else a new group is created.
5791 * If \a theGroupName is empty, new elements are not added
5793 * \return a group where the new elements are added. NULL if theGroupName == "".
5796 //================================================================================
5798 SMESH::SMESH_Group_ptr
5799 SMESH_MeshEditor_i::DoubleElements(SMESH::SMESH_IDSource_ptr theElements,
5800 const char* theGroupName)
5801 throw (SALOME::SALOME_Exception)
5803 SMESH::SMESH_Group_var newGroup;
5810 TIDSortedElemSet elems;
5811 prepareIdSource( theElements );
5812 if ( idSourceToSet( theElements, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true))
5814 getEditor().DoubleElements( elems );
5816 if ( strlen( theGroupName ) && !getEditor().GetLastCreatedElems().IsEmpty() )
5819 SMESH::ElementType type =
5820 SMESH::ElementType( getEditor().GetLastCreatedElems().Value(1)->GetType() );
5821 // find existing group
5822 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5823 for ( size_t i = 0; i < groups->length(); ++i )
5824 if ( groups[i]->GetType() == type )
5826 CORBA::String_var name = groups[i]->GetName();
5827 if ( strcmp( name, theGroupName ) == 0 ) {
5828 newGroup = SMESH::SMESH_Group::_narrow( groups[i] );
5832 // create a new group
5833 if ( newGroup->_is_nil() )
5834 newGroup = myMesh_i->CreateGroup( type, theGroupName );
5836 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* >( newGroup ))
5838 SMESHDS_Group* groupDS = static_cast< SMESHDS_Group* >( group_i->GetGroupDS() );
5839 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
5840 for ( int i = 1; i <= aSeq.Length(); i++ )
5841 groupDS->SMDSGroup().Add( aSeq(i) );
5846 if ( !newGroup->_is_nil() )
5847 pyDump << newGroup << " = ";
5848 pyDump << this << ".DoubleElements( "
5849 << theElements << ", " << "'" << theGroupName <<"')";
5851 SMESH_CATCH( SMESH::throwCorbaException );
5853 return newGroup._retn();
5856 //================================================================================
5858 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5859 \param theNodes - identifiers of nodes to be doubled
5860 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
5861 nodes. If list of element identifiers is empty then nodes are doubled but
5862 they not assigned to elements
5863 \return TRUE if operation has been completed successfully, FALSE otherwise
5864 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
5866 //================================================================================
5868 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
5869 const SMESH::long_array& theModifiedElems )
5870 throw (SALOME::SALOME_Exception)
5875 list< int > aListOfNodes;
5877 for ( i = 0, n = theNodes.length(); i < n; i++ )
5878 aListOfNodes.push_back( theNodes[ i ] );
5880 list< int > aListOfElems;
5881 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5882 aListOfElems.push_back( theModifiedElems[ i ] );
5884 bool aResult = getEditor().DoubleNodes( aListOfNodes, aListOfElems );
5886 declareMeshModified( /*isReComputeSafe=*/ !aResult );
5888 // Update Python script
5889 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
5893 SMESH_CATCH( SMESH::throwCorbaException );
5897 //================================================================================
5899 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5900 This method provided for convenience works as DoubleNodes() described above.
5901 \param theNodeId - identifier of node to be doubled.
5902 \param theModifiedElems - identifiers of elements to be updated.
5903 \return TRUE if operation has been completed successfully, FALSE otherwise
5904 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
5906 //================================================================================
5908 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
5909 const SMESH::long_array& theModifiedElems )
5910 throw (SALOME::SALOME_Exception)
5913 SMESH::long_array_var aNodes = new SMESH::long_array;
5914 aNodes->length( 1 );
5915 aNodes[ 0 ] = theNodeId;
5917 TPythonDump pyDump; // suppress dump by the next line
5919 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
5921 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
5925 SMESH_CATCH( SMESH::throwCorbaException );
5929 //================================================================================
5931 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5932 This method provided for convenience works as DoubleNodes() described above.
5933 \param theNodes - group of nodes to be doubled.
5934 \param theModifiedElems - group of elements to be updated.
5935 \return TRUE if operation has been completed successfully, FALSE otherwise
5936 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
5938 //================================================================================
5940 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
5941 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5942 throw (SALOME::SALOME_Exception)
5945 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5948 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5949 SMESH::long_array_var aModifiedElems;
5950 if ( !CORBA::is_nil( theModifiedElems ) )
5951 aModifiedElems = theModifiedElems->GetListOfID();
5954 aModifiedElems = new SMESH::long_array;
5955 aModifiedElems->length( 0 );
5958 TPythonDump pyDump; // suppress dump by the next line
5960 bool done = DoubleNodes( aNodes, aModifiedElems );
5962 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
5966 SMESH_CATCH( SMESH::throwCorbaException );
5970 //================================================================================
5972 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5973 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
5974 * \param theNodes - group of nodes to be doubled.
5975 * \param theModifiedElems - group of elements to be updated.
5976 * \return a new group with newly created nodes
5977 * \sa DoubleNodeGroup()
5979 //================================================================================
5981 SMESH::SMESH_Group_ptr
5982 SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
5983 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5984 throw (SALOME::SALOME_Exception)
5987 SMESH::SMESH_Group_var aNewGroup;
5989 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5990 return aNewGroup._retn();
5993 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5994 SMESH::long_array_var aModifiedElems;
5995 if ( !CORBA::is_nil( theModifiedElems ) )
5996 aModifiedElems = theModifiedElems->GetListOfID();
5998 aModifiedElems = new SMESH::long_array;
5999 aModifiedElems->length( 0 );
6002 TPythonDump pyDump; // suppress dump by the next line
6004 bool aResult = DoubleNodes( aNodes, aModifiedElems );
6007 // Create group with newly created nodes
6008 SMESH::long_array_var anIds = GetLastCreatedNodes();
6009 if (anIds->length() > 0) {
6010 string anUnindexedName (theNodes->GetName());
6011 string aNewName = generateGroupName(anUnindexedName + "_double");
6012 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6013 aNewGroup->Add(anIds);
6014 pyDump << aNewGroup << " = ";
6018 pyDump << this << ".DoubleNodeGroupNew( " << theNodes << ", "
6019 << theModifiedElems << " )";
6021 return aNewGroup._retn();
6023 SMESH_CATCH( SMESH::throwCorbaException );
6027 //================================================================================
6029 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6030 This method provided for convenience works as DoubleNodes() described above.
6031 \param theNodes - list of groups of nodes to be doubled
6032 \param theModifiedElems - list of groups of elements to be updated.
6033 \return TRUE if operation has been completed successfully, FALSE otherwise
6034 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
6036 //================================================================================
6038 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
6039 const SMESH::ListOfGroups& theModifiedElems )
6040 throw (SALOME::SALOME_Exception)
6045 std::list< int > aNodes;
6047 for ( i = 0, n = theNodes.length(); i < n; i++ )
6049 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
6050 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
6052 SMESH::long_array_var aCurr = aGrp->GetListOfID();
6053 for ( j = 0, m = aCurr->length(); j < m; j++ )
6054 aNodes.push_back( aCurr[ j ] );
6058 std::list< int > anElems;
6059 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
6061 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
6062 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
6064 SMESH::long_array_var aCurr = aGrp->GetListOfID();
6065 for ( j = 0, m = aCurr->length(); j < m; j++ )
6066 anElems.push_back( aCurr[ j ] );
6070 bool aResult = getEditor().DoubleNodes( aNodes, anElems );
6072 declareMeshModified( /*isReComputeSafe=*/false );
6074 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
6078 SMESH_CATCH( SMESH::throwCorbaException );
6082 //================================================================================
6084 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6085 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
6086 * \param theNodes - group of nodes to be doubled.
6087 * \param theModifiedElems - group of elements to be updated.
6088 * \return a new group with newly created nodes
6089 * \sa DoubleNodeGroups()
6091 //================================================================================
6093 SMESH::SMESH_Group_ptr
6094 SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
6095 const SMESH::ListOfGroups& theModifiedElems )
6096 throw (SALOME::SALOME_Exception)
6098 SMESH::SMESH_Group_var aNewGroup;
6100 TPythonDump pyDump; // suppress dump by the next line
6102 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
6106 // Create group with newly created nodes
6107 SMESH::long_array_var anIds = GetLastCreatedNodes();
6108 if (anIds->length() > 0) {
6109 string anUnindexedName (theNodes[0]->GetName());
6110 string aNewName = generateGroupName(anUnindexedName + "_double");
6111 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6112 aNewGroup->Add(anIds);
6113 pyDump << aNewGroup << " = ";
6117 pyDump << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
6118 << theModifiedElems << " )";
6120 return aNewGroup._retn();
6124 //================================================================================
6126 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6127 \param theElems - the list of elements (edges or faces) to be replicated
6128 The nodes for duplication could be found from these elements
6129 \param theNodesNot - list of nodes to NOT replicate
6130 \param theAffectedElems - the list of elements (cells and edges) to which the
6131 replicated nodes should be associated to.
6132 \return TRUE if operation has been completed successfully, FALSE otherwise
6133 \sa DoubleNodeGroup(), DoubleNodeGroups()
6135 //================================================================================
6137 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
6138 const SMESH::long_array& theNodesNot,
6139 const SMESH::long_array& theAffectedElems )
6140 throw (SALOME::SALOME_Exception)
6145 SMESHDS_Mesh* aMeshDS = getMeshDS();
6146 TIDSortedElemSet anElems, aNodes, anAffected;
6147 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
6148 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
6149 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
6151 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6153 // Update Python script
6154 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
6155 << theNodesNot << ", " << theAffectedElems << " )";
6157 declareMeshModified( /*isReComputeSafe=*/false );
6160 SMESH_CATCH( SMESH::throwCorbaException );
6164 //================================================================================
6166 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6167 \param theElems - the list of elements (edges or faces) to be replicated
6168 The nodes for duplication could be found from these elements
6169 \param theNodesNot - list of nodes to NOT replicate
6170 \param theShape - shape to detect affected elements (element which geometric center
6171 located on or inside shape).
6172 The replicated nodes should be associated to affected elements.
6173 \return TRUE if operation has been completed successfully, FALSE otherwise
6174 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
6176 //================================================================================
6178 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
6179 const SMESH::long_array& theNodesNot,
6180 GEOM::GEOM_Object_ptr theShape )
6181 throw (SALOME::SALOME_Exception)
6187 SMESHDS_Mesh* aMeshDS = getMeshDS();
6188 TIDSortedElemSet anElems, aNodes;
6189 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
6190 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
6192 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6193 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6195 // Update Python script
6196 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
6197 << theNodesNot << ", " << theShape << " )";
6199 declareMeshModified( /*isReComputeSafe=*/false );
6202 SMESH_CATCH( SMESH::throwCorbaException );
6206 //================================================================================
6208 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6209 \param theElems - group of of elements (edges or faces) to be replicated
6210 \param theNodesNot - group of nodes not to replicated
6211 \param theAffectedElems - group of elements to which the replicated nodes
6212 should be associated to.
6213 \return TRUE if operation has been completed successfully, FALSE otherwise
6214 \sa DoubleNodes(), DoubleNodeGroups()
6216 //================================================================================
6219 SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
6220 SMESH::SMESH_GroupBase_ptr theNodesNot,
6221 SMESH::SMESH_GroupBase_ptr theAffectedElems)
6222 throw (SALOME::SALOME_Exception)
6225 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6231 SMESHDS_Mesh* aMeshDS = getMeshDS();
6232 TIDSortedElemSet anElems, aNodes, anAffected;
6233 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6234 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6235 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
6237 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6239 // Update Python script
6240 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
6241 << theNodesNot << ", " << theAffectedElems << " )";
6243 declareMeshModified( /*isReComputeSafe=*/false );
6246 SMESH_CATCH( SMESH::throwCorbaException );
6250 //================================================================================
6252 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6253 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
6254 * \param theElems - group of of elements (edges or faces) to be replicated
6255 * \param theNodesNot - group of nodes not to replicated
6256 * \param theAffectedElems - group of elements to which the replicated nodes
6257 * should be associated to.
6258 * \return a new group with newly created elements
6259 * \sa DoubleNodeElemGroup()
6261 //================================================================================
6263 SMESH::SMESH_Group_ptr
6264 SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
6265 SMESH::SMESH_GroupBase_ptr theNodesNot,
6266 SMESH::SMESH_GroupBase_ptr theAffectedElems)
6267 throw (SALOME::SALOME_Exception)
6270 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroup2New( theElems,
6274 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
6275 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
6277 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupNew( "
6279 << theNodesNot << ", "
6280 << theAffectedElems << " )";
6282 return elemGroup._retn();
6285 //================================================================================
6287 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6288 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
6289 * \param theElems - group of of elements (edges or faces) to be replicated
6290 * \param theNodesNot - group of nodes not to replicated
6291 * \param theAffectedElems - group of elements to which the replicated nodes
6292 * should be associated to.
6293 * \return a new group with newly created elements
6294 * \sa DoubleNodeElemGroup()
6296 //================================================================================
6298 SMESH::ListOfGroups*
6299 SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
6300 SMESH::SMESH_GroupBase_ptr theNodesNot,
6301 SMESH::SMESH_GroupBase_ptr theAffectedElems,
6302 CORBA::Boolean theElemGroupNeeded,
6303 CORBA::Boolean theNodeGroupNeeded)
6304 throw (SALOME::SALOME_Exception)
6307 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
6308 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
6309 aTwoGroups->length( 2 );
6311 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6312 return aTwoGroups._retn();
6317 SMESHDS_Mesh* aMeshDS = getMeshDS();
6318 TIDSortedElemSet anElems, aNodes, anAffected;
6319 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6320 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6321 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
6324 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6326 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6332 // Create group with newly created elements
6333 CORBA::String_var elemGroupName = theElems->GetName();
6334 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
6335 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
6337 SMESH::long_array_var anIds = GetLastCreatedElems();
6338 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
6339 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
6340 aNewElemGroup->Add(anIds);
6342 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
6344 SMESH::long_array_var anIds = GetLastCreatedNodes();
6345 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6346 aNewNodeGroup->Add(anIds);
6350 // Update Python script
6353 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
6354 else pyDump << aNewElemGroup << ", ";
6355 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
6356 else pyDump << aNewNodeGroup << " ] = ";
6358 pyDump << this << ".DoubleNodeElemGroup2New( " << theElems << ", "
6359 << theNodesNot << ", "
6360 << theAffectedElems << ", "
6361 << theElemGroupNeeded << ", "
6362 << theNodeGroupNeeded <<" )";
6364 aTwoGroups[0] = aNewElemGroup._retn();
6365 aTwoGroups[1] = aNewNodeGroup._retn();
6366 return aTwoGroups._retn();
6368 SMESH_CATCH( SMESH::throwCorbaException );
6372 //================================================================================
6374 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6375 \param theElems - group of of elements (edges or faces) to be replicated
6376 \param theNodesNot - group of nodes not to replicated
6377 \param theShape - shape to detect affected elements (element which geometric center
6378 located on or inside shape).
6379 The replicated nodes should be associated to affected elements.
6380 \return TRUE if operation has been completed successfully, FALSE otherwise
6381 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
6383 //================================================================================
6386 SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
6387 SMESH::SMESH_GroupBase_ptr theNodesNot,
6388 GEOM::GEOM_Object_ptr theShape )
6389 throw (SALOME::SALOME_Exception)
6392 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6398 SMESHDS_Mesh* aMeshDS = getMeshDS();
6399 TIDSortedElemSet anElems, aNodes, anAffected;
6400 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6401 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6403 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6404 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6407 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6409 // Update Python script
6410 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
6411 << theNodesNot << ", " << theShape << " )";
6414 SMESH_CATCH( SMESH::throwCorbaException );
6418 //================================================================================
6420 * \brief Re-load elements from a list of groups into a TIDSortedElemSet
6421 * \param [in] theGrpList - groups
6422 * \param [in] theMeshDS - mesh
6423 * \param [out] theElemSet - set of elements
6424 * \param [in] theIsNodeGrp - is \a theGrpList includes goups of nodes
6426 //================================================================================
6428 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
6429 SMESHDS_Mesh* theMeshDS,
6430 TIDSortedElemSet& theElemSet,
6431 const bool theIsNodeGrp)
6433 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
6435 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
6436 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
6437 : aGrp->GetType() != SMESH::NODE ) )
6439 SMESH::long_array_var anIDs = aGrp->GetIDs();
6440 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
6445 //================================================================================
6447 \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6448 This method provided for convenience works as DoubleNodes() described above.
6449 \param theElems - list of groups of elements (edges or faces) to be replicated
6450 \param theNodesNot - list of groups of nodes not to replicated
6451 \param theAffectedElems - group of elements to which the replicated nodes
6452 should be associated to.
6453 \return TRUE if operation has been completed successfully, FALSE otherwise
6454 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
6456 //================================================================================
6459 SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
6460 const SMESH::ListOfGroups& theNodesNot,
6461 const SMESH::ListOfGroups& theAffectedElems)
6462 throw (SALOME::SALOME_Exception)
6468 SMESHDS_Mesh* aMeshDS = getMeshDS();
6469 TIDSortedElemSet anElems, aNodes, anAffected;
6470 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6471 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6472 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6474 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6476 // Update Python script
6477 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
6478 << &theNodesNot << ", " << &theAffectedElems << " )";
6480 declareMeshModified( /*isReComputeSafe=*/false );
6483 SMESH_CATCH( SMESH::throwCorbaException );
6487 //================================================================================
6489 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6490 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6491 \param theElems - list of groups of elements (edges or faces) to be replicated
6492 \param theNodesNot - list of groups of nodes not to replicated
6493 \param theAffectedElems - group of elements to which the replicated nodes
6494 should be associated to.
6495 * \return a new group with newly created elements
6496 * \sa DoubleNodeElemGroups()
6498 //================================================================================
6500 SMESH::SMESH_Group_ptr
6501 SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
6502 const SMESH::ListOfGroups& theNodesNot,
6503 const SMESH::ListOfGroups& theAffectedElems)
6504 throw (SALOME::SALOME_Exception)
6507 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroups2New( theElems,
6511 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
6512 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
6514 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupsNew( "
6516 << theNodesNot << ", "
6517 << theAffectedElems << " )";
6519 return elemGroup._retn();
6522 //================================================================================
6524 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6525 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6526 \param theElems - list of groups of elements (edges or faces) to be replicated
6527 \param theNodesNot - list of groups of nodes not to replicated
6528 \param theAffectedElems - group of elements to which the replicated nodes
6529 should be associated to.
6530 * \return a new group with newly created elements
6531 * \sa DoubleNodeElemGroups()
6533 //================================================================================
6535 SMESH::ListOfGroups*
6536 SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems,
6537 const SMESH::ListOfGroups& theNodesNot,
6538 const SMESH::ListOfGroups& theAffectedElems,
6539 CORBA::Boolean theElemGroupNeeded,
6540 CORBA::Boolean theNodeGroupNeeded)
6541 throw (SALOME::SALOME_Exception)
6544 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
6545 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
6546 aTwoGroups->length( 2 );
6551 SMESHDS_Mesh* aMeshDS = getMeshDS();
6552 TIDSortedElemSet anElems, aNodes, anAffected;
6553 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6554 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6555 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6557 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6559 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6564 // Create group with newly created elements
6565 CORBA::String_var elemGroupName = theElems[0]->GetName();
6566 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
6567 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
6569 SMESH::long_array_var anIds = GetLastCreatedElems();
6570 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
6571 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
6572 aNewElemGroup->Add(anIds);
6574 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
6576 SMESH::long_array_var anIds = GetLastCreatedNodes();
6577 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6578 aNewNodeGroup->Add(anIds);
6582 // Update Python script
6585 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
6586 else pyDump << aNewElemGroup << ", ";
6587 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
6588 else pyDump << aNewNodeGroup << " ] = ";
6590 pyDump << this << ".DoubleNodeElemGroups2New( " << &theElems << ", "
6591 << &theNodesNot << ", "
6592 << &theAffectedElems << ", "
6593 << theElemGroupNeeded << ", "
6594 << theNodeGroupNeeded << " )";
6596 aTwoGroups[0] = aNewElemGroup._retn();
6597 aTwoGroups[1] = aNewNodeGroup._retn();
6598 return aTwoGroups._retn();
6600 SMESH_CATCH( SMESH::throwCorbaException );
6604 //================================================================================
6606 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6607 This method provided for convenience works as DoubleNodes() described above.
6608 \param theElems - list of groups of elements (edges or faces) to be replicated
6609 \param theNodesNot - list of groups of nodes not to replicated
6610 \param theShape - shape to detect affected elements (element which geometric center
6611 located on or inside shape).
6612 The replicated nodes should be associated to affected elements.
6613 \return TRUE if operation has been completed successfully, FALSE otherwise
6614 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
6616 //================================================================================
6619 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
6620 const SMESH::ListOfGroups& theNodesNot,
6621 GEOM::GEOM_Object_ptr theShape )
6622 throw (SALOME::SALOME_Exception)
6628 SMESHDS_Mesh* aMeshDS = getMeshDS();
6629 TIDSortedElemSet anElems, aNodes;
6630 listOfGroupToSet(theElems, aMeshDS, anElems,false );
6631 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6633 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6634 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6636 // Update Python script
6637 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
6638 << &theNodesNot << ", " << theShape << " )";
6640 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6643 SMESH_CATCH( SMESH::throwCorbaException );
6647 //================================================================================
6649 \brief Identify the elements that will be affected by node duplication (actual
6650 duplication is not performed.
6651 This method is the first step of DoubleNodeElemGroupsInRegion.
6652 \param theElems - list of groups of elements (edges or faces) to be replicated
6653 \param theNodesNot - list of groups of nodes not to replicated
6654 \param theShape - shape to detect affected elements (element which geometric center
6655 located on or inside shape).
6656 The replicated nodes should be associated to affected elements.
6657 \return groups of affected elements
6658 \sa DoubleNodeElemGroupsInRegion()
6660 //================================================================================
6661 SMESH::ListOfGroups*
6662 SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theElems,
6663 const SMESH::ListOfGroups& theNodesNot,
6664 GEOM::GEOM_Object_ptr theShape )
6665 throw (SALOME::SALOME_Exception)
6668 MESSAGE("AffectedElemGroupsInRegion");
6669 SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
6670 bool isEdgeGroup = false;
6671 bool isFaceGroup = false;
6672 bool isVolumeGroup = false;
6673 SMESH::SMESH_Group_var aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE, "affectedEdges");
6674 SMESH::SMESH_Group_var aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE, "affectedFaces");
6675 SMESH::SMESH_Group_var aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME, "affectedVolumes");
6679 ::SMESH_MeshEditor aMeshEditor(myMesh);
6681 SMESHDS_Mesh* aMeshDS = getMeshDS();
6682 TIDSortedElemSet anElems, aNodes;
6683 listOfGroupToSet(theElems, aMeshDS, anElems, false);
6684 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true);
6686 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape(theShape);
6687 TIDSortedElemSet anAffected;
6688 bool aResult = aMeshEditor.AffectedElemGroupsInRegion(anElems, aNodes, aShape, anAffected);
6691 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6696 int lg = anAffected.size();
6697 MESSAGE("lg="<< lg);
6698 SMESH::long_array_var volumeIds = new SMESH::long_array;
6699 volumeIds->length(lg);
6700 SMESH::long_array_var faceIds = new SMESH::long_array;
6701 faceIds->length(lg);
6702 SMESH::long_array_var edgeIds = new SMESH::long_array;
6703 edgeIds->length(lg);
6708 TIDSortedElemSet::const_iterator eIt = anAffected.begin();
6709 for (; eIt != anAffected.end(); ++eIt)
6711 const SMDS_MeshElement* anElem = *eIt;
6714 int elemId = anElem->GetID();
6715 if (myMesh->GetElementType(elemId, true) == SMDSAbs_Volume)
6716 volumeIds[ivol++] = elemId;
6717 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Face)
6718 faceIds[iface++] = elemId;
6719 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Edge)
6720 edgeIds[iedge++] = elemId;
6722 volumeIds->length(ivol);
6723 faceIds->length(iface);
6724 edgeIds->length(iedge);
6726 aNewVolumeGroup->Add(volumeIds);
6727 aNewFaceGroup->Add(faceIds);
6728 aNewEdgeGroup->Add(edgeIds);
6729 isVolumeGroup = (aNewVolumeGroup->Size() > 0);
6730 isFaceGroup = (aNewFaceGroup->Size() > 0);
6731 isEdgeGroup = (aNewEdgeGroup->Size() > 0);
6735 if (isEdgeGroup) nbGroups++;
6736 if (isFaceGroup) nbGroups++;
6737 if (isVolumeGroup) nbGroups++;
6738 aListOfGroups->length(nbGroups);
6741 if (isEdgeGroup) aListOfGroups[i++] = aNewEdgeGroup._retn();
6742 if (isFaceGroup) aListOfGroups[i++] = aNewFaceGroup._retn();
6743 if (isVolumeGroup) aListOfGroups[i++] = aNewVolumeGroup._retn();
6745 // Update Python script
6748 if (isEdgeGroup) pyDump << aNewEdgeGroup << ", ";
6749 if (isFaceGroup) pyDump << aNewFaceGroup << ", ";
6750 if (isVolumeGroup) pyDump << aNewVolumeGroup << ", ";
6752 pyDump << this << ".AffectedElemGroupsInRegion( "
6753 << &theElems << ", " << &theNodesNot << ", " << theShape << " )";
6755 return aListOfGroups._retn();
6757 SMESH_CATCH( SMESH::throwCorbaException );
6761 //================================================================================
6763 \brief Generated skin mesh (containing 2D cells) from 3D mesh
6764 The created 2D mesh elements based on nodes of free faces of boundary volumes
6765 \return TRUE if operation has been completed successfully, FALSE otherwise
6767 //================================================================================
6769 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
6770 throw (SALOME::SALOME_Exception)
6775 bool aResult = getEditor().Make2DMeshFrom3D();
6777 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
6779 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6782 SMESH_CATCH( SMESH::throwCorbaException );
6786 //================================================================================
6788 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
6789 * The list of groups must contain at least two groups. The groups have to be disjoint:
6790 * no common element into two different groups.
6791 * The nodes of the internal faces at the boundaries of the groups are doubled.
6792 * Optionally, the internal faces are replaced by flat elements.
6793 * Triangles are transformed into prisms, and quadrangles into hexahedrons.
6794 * The flat elements are stored in groups of volumes.
6795 * These groups are named according to the position of the group in the list:
6796 * 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.
6797 * 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.
6798 * All the flat elements are gathered into the group named "joints3D" (or "joints2D" in 2D situation).
6799 * The flat element of the multiple junctions between the simple junction are stored in a group named "jointsMultiples".
6800 * @param theDomains - list of groups of volumes
6801 * @param createJointElems - if TRUE, create the elements
6802 * @return TRUE if operation has been completed successfully, FALSE otherwise
6804 //================================================================================
6807 SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
6808 CORBA::Boolean createJointElems )
6809 throw (SALOME::SALOME_Exception)
6811 bool aResult = false;
6816 SMESHDS_Mesh* aMeshDS = getMeshDS();
6818 // MESSAGE("theDomains.length = "<<theDomains.length());
6819 if ( theDomains.length() <= 1 )
6820 THROW_SALOME_CORBA_EXCEPTION("At least 2 groups are required.", SALOME::BAD_PARAM);
6821 vector<TIDSortedElemSet> domains;
6824 for ( int i = 0, n = theDomains.length(); i < n; i++ )
6826 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
6827 if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
6829 // if ( aGrp->GetType() != SMESH::VOLUME )
6830 // THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
6831 TIDSortedElemSet domain;
6833 domains.push_back(domain);
6834 SMESH::long_array_var anIDs = aGrp->GetIDs();
6835 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
6839 aResult = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems );
6840 // TODO publish the groups of flat elements in study
6842 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6844 // Update Python script
6845 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
6846 << ", " << createJointElems << " )";
6848 SMESH_CATCH( SMESH::throwCorbaException );
6853 //================================================================================
6855 * \brief Double nodes on some external faces and create flat elements.
6856 * Flat elements are mainly used by some types of mechanic calculations.
6858 * Each group of the list must be constituted of faces.
6859 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
6860 * @param theGroupsOfFaces - list of groups of faces
6861 * @return TRUE if operation has been completed successfully, FALSE otherwise
6863 //================================================================================
6866 SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
6867 throw (SALOME::SALOME_Exception)
6872 SMESHDS_Mesh* aMeshDS = getMeshDS();
6874 vector<TIDSortedElemSet> faceGroups;
6877 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
6879 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
6880 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
6882 TIDSortedElemSet faceGroup;
6884 faceGroups.push_back(faceGroup);
6885 SMESH::long_array_var anIDs = aGrp->GetIDs();
6886 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
6890 bool aResult = getEditor().CreateFlatElementsOnFacesGroups( faceGroups );
6891 // TODO publish the groups of flat elements in study
6893 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6895 // Update Python script
6896 TPythonDump() << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
6899 SMESH_CATCH( SMESH::throwCorbaException );
6903 //================================================================================
6905 * \brief Identify all the elements around a geom shape, get the faces delimiting
6908 * Build groups of volume to remove, groups of faces to replace on the skin of the
6909 * object, groups of faces to remove inside the object, (idem edges).
6910 * Build ordered list of nodes at the border of each group of faces to replace
6911 * (to be used to build a geom subshape).
6913 //================================================================================
6915 void SMESH_MeshEditor_i::CreateHoleSkin(CORBA::Double radius,
6916 GEOM::GEOM_Object_ptr theShape,
6917 const char* groupName,
6918 const SMESH::double_array& theNodesCoords,
6919 SMESH::array_of_long_array_out GroupsOfNodes)
6920 throw (SALOME::SALOME_Exception)
6925 std::vector<std::vector<int> > aListOfListOfNodes;
6926 ::SMESH_MeshEditor aMeshEditor( myMesh );
6928 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
6929 if ( !theNodeSearcher )
6930 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
6932 vector<double> nodesCoords;
6933 for (int i = 0; i < theNodesCoords.length(); i++)
6935 nodesCoords.push_back( theNodesCoords[i] );
6938 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6939 aMeshEditor.CreateHoleSkin(radius, aShape, theNodeSearcher, groupName,
6940 nodesCoords, aListOfListOfNodes);
6942 GroupsOfNodes = new SMESH::array_of_long_array;
6943 GroupsOfNodes->length( aListOfListOfNodes.size() );
6944 std::vector<std::vector<int> >::iterator llIt = aListOfListOfNodes.begin();
6945 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
6947 vector<int>& aListOfNodes = *llIt;
6948 vector<int>::iterator lIt = aListOfNodes.begin();;
6949 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
6950 aGroup.length( aListOfNodes.size() );
6951 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
6952 aGroup[ j ] = (*lIt);
6954 TPythonDump() << "lists_nodes = " << this << ".CreateHoleSkin( "
6957 << ", '" << groupName << "', "
6958 << theNodesCoords << " )";
6960 SMESH_CATCH( SMESH::throwCorbaException );
6963 // issue 20749 ===================================================================
6965 * \brief Creates missing boundary elements
6966 * \param elements - elements whose boundary is to be checked
6967 * \param dimension - defines type of boundary elements to create
6968 * \param groupName - a name of group to store created boundary elements in,
6969 * "" means not to create the group
6970 * \param meshName - a name of new mesh to store created boundary elements in,
6971 * "" means not to create the new mesh
6972 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
6973 * \param toCopyExistingBondary - if true, not only new but also pre-existing
6974 * boundary elements will be copied into the new mesh
6975 * \param group - returns the create group, if any
6976 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
6978 // ================================================================================
6980 SMESH::SMESH_Mesh_ptr
6981 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
6982 SMESH::Bnd_Dimension dim,
6983 const char* groupName,
6984 const char* meshName,
6985 CORBA::Boolean toCopyElements,
6986 CORBA::Boolean toCopyExistingBondary,
6987 SMESH::SMESH_Group_out group)
6988 throw (SALOME::SALOME_Exception)
6993 if ( dim > SMESH::BND_1DFROM2D )
6994 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
6996 SMESHDS_Mesh* aMeshDS = getMeshDS();
6998 SMESH::SMESH_Mesh_var mesh_var;
6999 SMESH::SMESH_Group_var group_var;
7003 TIDSortedElemSet elements;
7004 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
7005 prepareIdSource( idSource );
7006 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
7010 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
7011 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
7013 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
7015 // group of new boundary elements
7016 SMESH_Group* smesh_group = 0;
7017 if ( strlen(groupName) )
7019 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
7020 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
7021 smesh_group = group_i->GetSmeshGroup();
7025 getEditor().MakeBoundaryMesh( elements,
7026 ::SMESH_MeshEditor::Bnd_Dimension(dim),
7030 toCopyExistingBondary);
7033 smesh_mesh->GetMeshDS()->Modified();
7036 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
7038 // result of MakeBoundaryMesh() is a tuple (mesh, group)
7039 if ( mesh_var->_is_nil() )
7040 pyDump << myMesh_i->_this() << ", ";
7042 pyDump << mesh_var << ", ";
7043 if ( group_var->_is_nil() )
7044 pyDump << "_NoneGroup = "; // assignment to None is forbiden
7046 pyDump << group_var << " = ";
7047 pyDump << this << ".MakeBoundaryMesh( "
7049 << "SMESH." << dimName[int(dim)] << ", "
7050 << "'" << groupName << "', "
7051 << "'" << meshName<< "', "
7052 << toCopyElements << ", "
7053 << toCopyExistingBondary << ")";
7055 group = group_var._retn();
7056 return mesh_var._retn();
7058 SMESH_CATCH( SMESH::throwCorbaException );
7059 return SMESH::SMESH_Mesh::_nil();
7062 //================================================================================
7064 * \brief Creates missing boundary elements
7065 * \param dimension - defines type of boundary elements to create
7066 * \param groupName - a name of group to store all boundary elements in,
7067 * "" means not to create the group
7068 * \param meshName - a name of a new mesh, which is a copy of the initial
7069 * mesh + created boundary elements; "" means not to create the new mesh
7070 * \param toCopyAll - if true, the whole initial mesh will be copied into
7071 * the new mesh else only boundary elements will be copied into the new mesh
7072 * \param groups - optional groups of elements to make boundary around
7073 * \param mesh - returns the mesh where elements were added to
7074 * \param group - returns the created group, if any
7075 * \retval long - number of added boundary elements
7077 //================================================================================
7079 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
7080 const char* groupName,
7081 const char* meshName,
7082 CORBA::Boolean toCopyAll,
7083 const SMESH::ListOfIDSources& groups,
7084 SMESH::SMESH_Mesh_out mesh,
7085 SMESH::SMESH_Group_out group)
7086 throw (SALOME::SALOME_Exception)
7091 if ( dim > SMESH::BND_1DFROM2D )
7092 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
7094 // separate groups belonging to this and other mesh
7095 SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
7096 SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
7097 groupsOfThisMesh->length( groups.length() );
7098 groupsOfOtherMesh->length( groups.length() );
7099 int nbGroups = 0, nbGroupsOfOtherMesh = 0;
7100 for ( int i = 0; i < groups.length(); ++i )
7102 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
7103 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
7104 groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
7106 groupsOfThisMesh[ nbGroups++ ] = groups[i];
7107 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
7108 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
7110 groupsOfThisMesh->length( nbGroups );
7111 groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
7116 if ( nbGroupsOfOtherMesh > 0 )
7118 // process groups belonging to another mesh
7119 SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
7120 SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
7121 nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
7122 groupsOfOtherMesh, mesh, group );
7125 SMESH::SMESH_Mesh_var mesh_var;
7126 SMESH::SMESH_Group_var group_var;
7129 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
7130 const bool toCopyMesh = ( strlen( meshName ) > 0 );
7134 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
7136 /*toCopyGroups=*/false,
7137 /*toKeepIDs=*/true);
7139 mesh_var = makeMesh(meshName);
7141 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
7142 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
7145 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
7146 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
7148 // group of boundary elements
7149 SMESH_Group* smesh_group = 0;
7150 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
7151 if ( strlen(groupName) )
7153 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
7154 group_var = mesh_i->CreateGroup( groupType, groupName );
7155 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
7156 smesh_group = group_i->GetSmeshGroup();
7159 TIDSortedElemSet elements;
7161 if ( groups.length() > 0 )
7163 for ( int i = 0; i < nbGroups; ++i )
7166 if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
7168 SMESH::Bnd_Dimension bdim =
7169 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
7170 nbAdded += getEditor().MakeBoundaryMesh( elements,
7171 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
7174 /*toCopyElements=*/false,
7175 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
7176 /*toAddExistingBondary=*/true,
7177 /*aroundElements=*/true);
7183 nbAdded += getEditor().MakeBoundaryMesh( elements,
7184 ::SMESH_MeshEditor::Bnd_Dimension(dim),
7187 /*toCopyElements=*/false,
7188 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
7189 /*toAddExistingBondary=*/true);
7191 tgtMesh->GetMeshDS()->Modified();
7193 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
7195 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
7196 pyDump << "nbAdded, ";
7197 if ( mesh_var->_is_nil() )
7198 pyDump << myMesh_i->_this() << ", ";
7200 pyDump << mesh_var << ", ";
7201 if ( group_var->_is_nil() )
7202 pyDump << "_NoneGroup = "; // assignment to None is forbiden
7204 pyDump << group_var << " = ";
7205 pyDump << this << ".MakeBoundaryElements( "
7206 << "SMESH." << dimName[int(dim)] << ", "
7207 << "'" << groupName << "', "
7208 << "'" << meshName<< "', "
7209 << toCopyAll << ", "
7212 mesh = mesh_var._retn();
7213 group = group_var._retn();
7216 SMESH_CATCH( SMESH::throwCorbaException );