1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_MeshEditor_i.cxx
23 // Author : Nicolas REJNERI
30 // A macro used in SMESH_TryCatch.hxx,
31 // it re-raises a CORBA SALOME exception thrown by SMESH_MeshEditor_i and caught by SMESH_CATCH
32 #define SMY_OWN_CATCH \
33 catch ( SALOME::SALOME_Exception & e ) { throw e; }
35 #include "SMESH_MeshEditor_i.hxx"
37 #include "SMDS_EdgePosition.hxx"
38 #include "SMDS_ElemIterator.hxx"
39 #include "SMDS_FacePosition.hxx"
40 #include "SMDS_IteratorOnIterators.hxx"
41 #include "SMDS_LinearEdge.hxx"
42 #include "SMDS_Mesh0DElement.hxx"
43 #include "SMDS_MeshFace.hxx"
44 #include "SMDS_MeshVolume.hxx"
45 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
46 #include "SMDS_SetIterator.hxx"
47 #include "SMDS_VolumeTool.hxx"
48 #include "SMESHDS_Group.hxx"
49 #include "SMESHDS_GroupOnGeom.hxx"
50 #include "SMESH_ControlsDef.hxx"
51 #include "SMESH_Filter_i.hxx"
52 #include "SMESH_Gen_i.hxx"
53 #include "SMESH_Group.hxx"
54 #include "SMESH_Group_i.hxx"
55 #include "SMESH_MeshAlgos.hxx"
56 #include "SMESH_MeshPartDS.hxx"
57 #include "SMESH_MesherHelper.hxx"
58 #include "SMESH_PythonDump.hxx"
59 #include "SMESH_subMeshEventListener.hxx"
60 #include "SMESH_subMesh_i.hxx"
62 #include <utilities.h>
63 #include <Utils_ExceptHandlers.hxx>
64 #include <Utils_CorbaException.hxx>
65 #include <SALOMEDS_wrap.hxx>
66 #include <SALOME_GenericObj_i.hh>
68 #include <BRepAdaptor_Surface.hxx>
69 #include <BRep_Tool.hxx>
70 #include <TopExp_Explorer.hxx>
72 #include <TopoDS_Edge.hxx>
73 #include <TopoDS_Face.hxx>
78 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
82 #include <Standard_Failure.hxx>
85 #include <Standard_ErrorHandler.hxx>
91 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
93 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
96 using SMESH::TPythonDump;
99 namespace MeshEditor_I {
101 //=============================================================================
103 * \brief Mesh to apply modifications for preview purposes
105 //=============================================================================
107 struct TPreviewMesh: public SMESH_Mesh
109 SMDSAbs_ElementType myPreviewType; // type to show
111 TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
112 _isShapeToMesh = (_id =_studyId = 0);
113 _myMeshDS = new SMESHDS_Mesh( _id, true );
114 myPreviewType = previewElements;
117 virtual ~TPreviewMesh() { delete _myMeshDS; _myMeshDS = 0; }
118 //!< Copy a set of elements
119 void Copy(const TIDSortedElemSet & theElements,
120 TIDSortedElemSet& theCopyElements,
121 SMDSAbs_ElementType theSelectType = SMDSAbs_All,
122 SMDSAbs_ElementType theAvoidType = SMDSAbs_All)
124 // loop on theIDsOfElements
125 TIDSortedElemSet::const_iterator eIt = theElements.begin();
126 for ( ; eIt != theElements.end(); ++eIt )
128 const SMDS_MeshElement* anElem = *eIt;
129 if ( !anElem ) continue;
130 SMDSAbs_ElementType type = anElem->GetType();
131 if ( type == theAvoidType ||
132 ( theSelectType != SMDSAbs_All && type != theSelectType ))
134 const SMDS_MeshElement* anElemCopy;
135 if ( type == SMDSAbs_Node)
136 anElemCopy = Copy( cast2Node(anElem) );
138 anElemCopy = Copy( anElem );
140 theCopyElements.insert( theCopyElements.end(), anElemCopy );
144 SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
146 // copy element nodes
147 int anElemNbNodes = anElem->NbNodes();
148 vector< int > anElemNodesID( anElemNbNodes ) ;
149 SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
150 for ( int i = 0; itElemNodes->more(); i++)
152 const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
154 anElemNodesID[i] = anElemNode->GetID();
157 // creates a corresponding element on copied nodes
158 SMDS_MeshElement* anElemCopy = 0;
159 if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
161 const SMDS_VtkVolume* ph =
162 dynamic_cast<const SMDS_VtkVolume*> (anElem);
164 anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
165 (anElemNodesID, ph->GetQuantities(),anElem->GetID());
168 anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
175 SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
177 return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(),
178 anElemNode->GetID());
180 };// struct TPreviewMesh
182 static SMESH_NodeSearcher * theNodeSearcher = 0;
183 static SMESH_ElementSearcher * theElementSearcher = 0;
185 //=============================================================================
187 * \brief Deleter of theNodeSearcher at any compute event occured
189 //=============================================================================
191 struct TSearchersDeleter : public SMESH_subMeshEventListener
194 string myMeshPartIOR;
196 TSearchersDeleter(): SMESH_subMeshEventListener( false, // won't be deleted by submesh
197 "SMESH_MeshEditor_i::TSearchersDeleter"),
199 //!< Delete theNodeSearcher
202 if ( theNodeSearcher ) delete theNodeSearcher; theNodeSearcher = 0;
203 if ( theElementSearcher ) delete theElementSearcher; theElementSearcher = 0;
205 typedef map < int, SMESH_subMesh * > TDependsOnMap;
206 //!< The meshod called by submesh: do my main job
207 void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
208 SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
210 if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
212 Unset( sm->GetFather() );
215 //!< set self on all submeshes and delete theNodeSearcher if other mesh is set
216 void Set(SMESH_Mesh* mesh, const string& meshPartIOR = string())
218 if ( myMesh != mesh || myMeshPartIOR != meshPartIOR)
225 myMeshPartIOR = meshPartIOR;
226 if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
227 const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
228 TDependsOnMap::const_iterator sm;
229 for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
230 sm->second->SetEventListener( this, 0, sm->second );
234 //!< delete self from all submeshes
235 void Unset(SMESH_Mesh* mesh)
237 if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
238 const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
239 TDependsOnMap::const_iterator sm;
240 for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
241 sm->second->DeleteEventListener( this );
246 } theSearchersDeleter;
248 TCollection_AsciiString mirrorTypeName( SMESH::SMESH_MeshEditor::MirrorType theMirrorType )
250 TCollection_AsciiString typeStr;
251 switch ( theMirrorType ) {
252 case SMESH::SMESH_MeshEditor::POINT:
253 typeStr = "SMESH.SMESH_MeshEditor.POINT";
255 case SMESH::SMESH_MeshEditor::AXIS:
256 typeStr = "SMESH.SMESH_MeshEditor.AXIS";
259 typeStr = "SMESH.SMESH_MeshEditor.PLANE";
263 //================================================================================
265 * \brief function for conversion of long_array to TIDSortedElemSet
266 * \param IDs - array of IDs
267 * \param aMesh - mesh
268 * \param aMap - collection to fill
269 * \param aType - element type
271 //================================================================================
273 void arrayToSet(const SMESH::long_array & IDs,
274 const SMESHDS_Mesh* aMesh,
275 TIDSortedElemSet& aMap,
276 const SMDSAbs_ElementType aType = SMDSAbs_All )
278 SMDS_MeshElement::NonNullFilter filter1;
279 SMDS_MeshElement::TypeFilter filter2( aType );
280 SMDS_MeshElement::Filter & filter =
281 ( aType == SMDSAbs_All ) ? (SMDS_MeshElement::Filter&) filter1 : filter2;
283 if ( aType == SMDSAbs_Node )
284 for (int i=0; i<IDs.length(); i++) {
285 const SMDS_MeshElement * elem = aMesh->FindNode( IDs[i] );
287 aMap.insert( aMap.end(), elem );
290 for (int i=0; i<IDs.length(); i++) {
291 const SMDS_MeshElement * elem = aMesh->FindElement( IDs[i] );
293 aMap.insert( aMap.end(), elem );
296 //================================================================================
298 * \brief Retrieve elements of given type from SMESH_IDSource
300 //================================================================================
302 bool idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource,
303 const SMESHDS_Mesh* theMeshDS,
304 TIDSortedElemSet& theElemSet,
305 const SMDSAbs_ElementType theType,
306 const bool emptyIfIsMesh=false)
309 if ( CORBA::is_nil( theIDSource ) )
311 if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
314 SMESH::long_array_var anIDs = theIDSource->GetIDs();
315 if ( anIDs->length() == 0 )
317 SMESH::array_of_ElementType_var types = theIDSource->GetTypes();
318 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
320 if ( theType == SMDSAbs_All || theType == SMDSAbs_Node )
321 arrayToSet( anIDs, theMeshDS, theElemSet, SMDSAbs_Node );
327 arrayToSet( anIDs, theMeshDS, theElemSet, theType);
328 return bool(anIDs->length()) == bool(theElemSet.size());
332 //================================================================================
334 * \brief Retrieve nodes from SMESH_IDSource
336 //================================================================================
338 void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject,
339 const SMESHDS_Mesh* theMeshDS,
340 TIDSortedNodeSet& theNodeSet)
343 if ( CORBA::is_nil( theObject ) )
345 SMESH::array_of_ElementType_var types = theObject->GetTypes();
346 SMESH::long_array_var aElementsId = theObject->GetIDs();
347 if ( types->length() == 1 && types[0] == SMESH::NODE)
349 for(int i = 0; i < aElementsId->length(); i++)
350 if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] ))
351 theNodeSet.insert( theNodeSet.end(), n);
353 else if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
355 SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator();
356 while ( nIt->more( ))
357 if( const SMDS_MeshElement * elem = nIt->next() )
358 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
362 for(int i = 0; i < aElementsId->length(); i++)
363 if( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] ))
364 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
368 //================================================================================
370 * \brief Returns elements connected to the given elements
372 //================================================================================
374 void getElementsAround(const TIDSortedElemSet& theElements,
375 const SMESHDS_Mesh* theMeshDS,
376 TIDSortedElemSet& theElementsAround)
378 if ( theElements.empty() ) return;
380 SMDSAbs_ElementType elemType = (*theElements.begin())->GetType();
381 bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() );
383 theMeshDS->GetMeshInfo().NbElements( elemType ) == theElements.size() )
384 return; // all the elements are in theElements
387 elemType = SMDSAbs_All;
389 TIDSortedElemSet visitedNodes;
390 TIDSortedElemSet::const_iterator elemIt = theElements.begin();
391 for ( ; elemIt != theElements.end(); ++elemIt )
393 const SMDS_MeshElement* e = *elemIt;
394 int i = e->NbCornerNodes();
397 const SMDS_MeshNode* n = e->GetNode( i );
398 if ( visitedNodes.insert( n ).second )
400 SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
401 while ( invIt->more() )
403 const SMDS_MeshElement* elemAround = invIt->next();
404 if ( !theElements.count( elemAround ))
405 theElementsAround.insert( elemAround );
412 //================================================================================
414 * \brief Return a string used to detect change of mesh part on which theElementSearcher
415 * is going to be used
417 //================================================================================
419 string getPartIOR( SMESH::SMESH_IDSource_ptr theMeshPart, SMESH::ElementType type)
421 string partIOR = SMESH_Gen_i::GetORB()->object_to_string( theMeshPart );
422 if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( theMeshPart ))
423 // take into account passible group modification
424 partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() );
425 partIOR += SMESH_Comment( type );
429 } // namespace MeshEditor_I
431 using namespace MeshEditor_I;
433 //=============================================================================
437 //=============================================================================
439 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview):
441 myMesh( &theMesh->GetImpl() ),
443 myIsPreviewMode ( isPreview ),
449 //================================================================================
453 //================================================================================
455 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
457 //deleteAuxIDSources();
458 delete myPreviewMesh; myPreviewMesh = 0;
459 delete myPreviewEditor; myPreviewEditor = 0;
462 //================================================================================
464 * \brief Clear members
466 //================================================================================
468 void SMESH_MeshEditor_i::initData(bool deleteSearchers)
470 if ( myIsPreviewMode ) {
471 if ( myPreviewMesh ) myPreviewMesh->Clear();
474 if ( deleteSearchers )
475 TSearchersDeleter::Delete();
477 getEditor().GetError().reset();
478 getEditor().CrearLastCreated();
481 //================================================================================
483 * \brief Increment mesh modif time and optionally record that the performed
484 * modification may influence futher mesh re-compute.
485 * \param [in] isReComputeSafe - true if the modification does not infulence
486 * futher mesh re-compute
488 //================================================================================
490 void SMESH_MeshEditor_i::declareMeshModified( bool isReComputeSafe )
492 myMesh->GetMeshDS()->Modified();
493 if ( !isReComputeSafe )
494 myMesh->SetIsModified( true );
497 //================================================================================
499 * \brief Return either myEditor or myPreviewEditor depending on myIsPreviewMode.
500 * WARNING: in preview mode call getPreviewMesh() before getEditor()!
502 //================================================================================
504 ::SMESH_MeshEditor& SMESH_MeshEditor_i::getEditor()
506 if ( myIsPreviewMode && !myPreviewEditor ) {
507 if ( !myPreviewMesh ) getPreviewMesh();
508 myPreviewEditor = new ::SMESH_MeshEditor( myPreviewMesh );
510 return myIsPreviewMode ? *myPreviewEditor : myEditor;
513 //================================================================================
515 * \brief Initialize and return myPreviewMesh
516 * \param previewElements - type of elements to show in preview
518 * WARNING: call it once par a method!
520 //================================================================================
522 TPreviewMesh * SMESH_MeshEditor_i::getPreviewMesh(SMDSAbs_ElementType previewElements)
524 if ( !myPreviewMesh || myPreviewMesh->myPreviewType != previewElements )
526 delete myPreviewEditor;
528 delete myPreviewMesh;
529 myPreviewMesh = new TPreviewMesh( previewElements );
531 myPreviewMesh->Clear();
532 return myPreviewMesh;
535 //================================================================================
537 * Return data of mesh edition preview
539 //================================================================================
541 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
542 throw (SALOME::SALOME_Exception)
545 const bool hasBadElems = ( getEditor().GetError() && getEditor().GetError()->HasBadElems() );
547 if ( myIsPreviewMode || hasBadElems ) { // --- MeshPreviewStruct filling ---
549 list<int> aNodesConnectivity;
550 typedef map<int, int> TNodesMap;
553 SMESHDS_Mesh* aMeshDS;
554 std::auto_ptr< SMESH_MeshPartDS > aMeshPartDS;
556 aMeshPartDS.reset( new SMESH_MeshPartDS( getEditor().GetError()->myBadElements ));
557 aMeshDS = aMeshPartDS.get();
560 aMeshDS = getEditor().GetMeshDS();
562 myPreviewData = new SMESH::MeshPreviewStruct();
563 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
566 SMDSAbs_ElementType previewType = SMDSAbs_All;
568 if (TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( getEditor().GetMesh() )) {
569 previewType = aPreviewMesh->myPreviewType;
570 switch ( previewType ) {
571 case SMDSAbs_Edge : break;
572 case SMDSAbs_Face : break;
573 case SMDSAbs_Volume: break;
575 if ( aMeshDS->GetMeshInfo().NbElements() == 0 ) previewType = SMDSAbs_Node;
579 myPreviewData->elementTypes.length( aMeshDS->GetMeshInfo().NbElements( previewType ));
581 SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator(previewType);
583 while ( itMeshElems->more() ) {
584 const SMDS_MeshElement* aMeshElem = itMeshElems->next();
585 SMDS_NodeIteratorPtr itElemNodes = aMeshElem->nodeIterator();
586 while ( itElemNodes->more() ) {
587 const SMDS_MeshNode* aMeshNode = itElemNodes->next();
588 int aNodeID = aMeshNode->GetID();
589 TNodesMap::iterator anIter = nodesMap.find(aNodeID);
590 if ( anIter == nodesMap.end() ) {
591 // filling the nodes coordinates
592 myPreviewData->nodesXYZ[j].x = aMeshNode->X();
593 myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
594 myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
595 anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
598 aNodesConnectivity.push_back(anIter->second);
601 // filling the elements types
602 SMDSAbs_ElementType aType = aMeshElem->GetType();
603 bool isPoly = aMeshElem->IsPoly();
604 myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
605 myPreviewData->elementTypes[i].isPoly = isPoly;
606 myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
609 myPreviewData->nodesXYZ.length( j );
611 // filling the elements connectivities
612 list<int>::iterator aConnIter = aNodesConnectivity.begin();
613 myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
614 for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
615 myPreviewData->elementConnectivities[i] = *aConnIter;
617 return myPreviewData._retn();
619 SMESH_CATCH( SMESH::throwCorbaException );
623 //================================================================================
625 * \brief Returns list of it's IDs of created nodes
626 * \retval SMESH::long_array* - list of node ID
628 //================================================================================
630 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
631 throw (SALOME::SALOME_Exception)
634 SMESH::long_array_var myLastCreatedNodes = new SMESH::long_array();
636 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedNodes();
637 myLastCreatedNodes->length( aSeq.Length() );
638 for (int i = 1; i <= aSeq.Length(); i++)
639 myLastCreatedNodes[i-1] = aSeq.Value(i)->GetID();
641 return myLastCreatedNodes._retn();
642 SMESH_CATCH( SMESH::throwCorbaException );
646 //================================================================================
648 * \brief Returns list of it's IDs of created elements
649 * \retval SMESH::long_array* - list of elements' ID
651 //================================================================================
653 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
654 throw (SALOME::SALOME_Exception)
657 SMESH::long_array_var myLastCreatedElems = new SMESH::long_array();
659 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
660 myLastCreatedElems->length( aSeq.Length() );
661 for ( int i = 1; i <= aSeq.Length(); i++ )
662 myLastCreatedElems[i-1] = aSeq.Value(i)->GetID();
664 return myLastCreatedElems._retn();
665 SMESH_CATCH( SMESH::throwCorbaException );
669 //=======================================================================
670 //function : ClearLastCreated
671 //purpose : Clears sequences of last created elements and nodes
672 //=======================================================================
674 void SMESH_MeshEditor_i::ClearLastCreated() throw (SALOME::SALOME_Exception)
677 getEditor().CrearLastCreated();
678 SMESH_CATCH( SMESH::throwCorbaException );
681 //=======================================================================
683 * Returns description of an error/warning occured during the last operation
684 * WARNING: ComputeError.code >= 100 and no corresponding enum in IDL API
686 //=======================================================================
688 SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError()
689 throw (SALOME::SALOME_Exception)
692 SMESH::ComputeError_var errOut = new SMESH::ComputeError;
693 SMESH_ComputeErrorPtr& errIn = getEditor().GetError();
694 if ( errIn && !errIn->IsOK() )
696 errOut->code = -( errIn->myName < 0 ? errIn->myName + 1: errIn->myName ); // -1 -> 0
697 errOut->comment = errIn->myComment.c_str();
698 errOut->subShapeID = -1;
699 errOut->hasBadMesh = !errIn->myBadElements.empty();
704 errOut->subShapeID = -1;
705 errOut->hasBadMesh = false;
708 return errOut._retn();
709 SMESH_CATCH( SMESH::throwCorbaException );
713 //=======================================================================
714 //function : MakeIDSource
715 //purpose : Wrap a sequence of ids in a SMESH_IDSource.
716 // Call UnRegister() as you fininsh using it!!
717 //=======================================================================
719 struct SMESH_MeshEditor_i::_IDSource : public virtual POA_SMESH::SMESH_IDSource,
720 public virtual SALOME::GenericObj_i
722 SMESH::long_array _ids;
723 SMESH::ElementType _type;
724 SMESH::SMESH_Mesh_ptr _mesh;
725 SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); }
726 SMESH::long_array* GetMeshInfo() { return 0; }
727 SMESH::long_array* GetNbElementsByType()
729 SMESH::long_array_var aRes = new SMESH::long_array();
730 aRes->length(SMESH::NB_ELEMENT_TYPES);
731 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
732 aRes[ i ] = ( i == _type ) ? _ids.length() : 0;
735 SMESH::SMESH_Mesh_ptr GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _mesh ); }
736 bool IsMeshInfoCorrect() { return true; }
737 SMESH::array_of_ElementType* GetTypes()
739 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
740 if ( _ids.length() > 0 ) {
744 return types._retn();
748 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
749 SMESH::ElementType type)
751 // if ( myAuxIDSources.size() > 10 ) {
752 // delete myAuxIDSources.front();
753 // myAuxIDSources.pop_front();
756 _IDSource* idSrc = new _IDSource;
757 idSrc->_mesh = myMesh_i->_this();
760 //myAuxIDSources.push_back( idSrc );
762 SMESH::SMESH_IDSource_var anIDSourceVar = idSrc->_this();
764 return anIDSourceVar._retn();
767 bool SMESH_MeshEditor_i::IsTemporaryIDSource( SMESH::SMESH_IDSource_ptr& idSource )
769 return SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource );
772 CORBA::Long* SMESH_MeshEditor_i::GetTemporaryIDs( SMESH::SMESH_IDSource_ptr& idSource,
775 if ( _IDSource* tmpIdSource = SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource ))
777 nbIds = (int) tmpIdSource->_ids.length();
778 return & tmpIdSource->_ids[0];
784 // void SMESH_MeshEditor_i::deleteAuxIDSources()
786 // std::list< _IDSource* >::iterator idSrcIt = myAuxIDSources.begin();
787 // for ( ; idSrcIt != myAuxIDSources.end(); ++idSrcIt )
789 // myAuxIDSources.clear();
792 //=============================================================================
796 //=============================================================================
799 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
800 throw (SALOME::SALOME_Exception)
807 for (int i = 0; i < IDsOfElements.length(); i++)
808 IdList.push_back( IDsOfElements[i] );
810 // Update Python script
811 TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
814 bool ret = getEditor().Remove( IdList, false );
816 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 ); // issue 0020693
819 SMESH_CATCH( SMESH::throwCorbaException );
823 //=============================================================================
827 //=============================================================================
829 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
830 throw (SALOME::SALOME_Exception)
836 for (int i = 0; i < IDsOfNodes.length(); i++)
837 IdList.push_back( IDsOfNodes[i] );
839 // Update Python script
840 TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
842 bool ret = getEditor().Remove( IdList, true );
844 declareMeshModified( /*isReComputeSafe=*/ !ret ); // issue 0020693
847 SMESH_CATCH( SMESH::throwCorbaException );
851 //=============================================================================
855 //=============================================================================
857 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
858 throw (SALOME::SALOME_Exception)
863 // Update Python script
864 TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
866 // Create filter to find all orphan nodes
867 SMESH::Controls::Filter::TIdSequence seq;
868 SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
869 SMESH::Controls::Filter::GetElementsId( getMeshDS(), predicate, seq );
871 // remove orphan nodes (if there are any)
873 for ( int i = 0; i < seq.size(); i++ )
874 IdList.push_back( seq[i] );
876 int nbNodesBefore = myMesh->NbNodes();
877 getEditor().Remove( IdList, true );
878 int nbNodesAfter = myMesh->NbNodes();
880 declareMeshModified( /*isReComputeSafe=*/ IdList.size() == 0 ); // issue 0020693
881 return nbNodesBefore - nbNodesAfter;
883 SMESH_CATCH( SMESH::throwCorbaException );
887 //=============================================================================
891 //=============================================================================
893 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,CORBA::Double y, CORBA::Double z)
894 throw (SALOME::SALOME_Exception)
899 const SMDS_MeshNode* N = getMeshDS()->AddNode(x, y, z);
901 // Update Python script
902 TPythonDump() << "nodeID = " << this << ".AddNode( "
903 << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )";
905 declareMeshModified( /*isReComputeSafe=*/false );
908 SMESH_CATCH( SMESH::throwCorbaException );
912 //=============================================================================
914 * Create 0D element on the given node.
916 //=============================================================================
918 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
919 throw (SALOME::SALOME_Exception)
924 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
925 SMDS_MeshElement* elem = getMeshDS()->Add0DElement(aNode);
927 // Update Python script
928 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
930 declareMeshModified( /*isReComputeSafe=*/false );
932 return elem ? elem->GetID() : 0;
934 SMESH_CATCH( SMESH::throwCorbaException );
938 //=============================================================================
940 * Create a ball element on the given node.
942 //=============================================================================
944 CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diameter)
945 throw (SALOME::SALOME_Exception)
950 if ( diameter < std::numeric_limits<double>::min() )
951 THROW_SALOME_CORBA_EXCEPTION("Invalid diameter", SALOME::BAD_PARAM);
953 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
954 SMDS_MeshElement* elem = getMeshDS()->AddBall(aNode, diameter);
956 // Update Python script
957 TPythonDump() << "ballElem = "
958 << this << ".AddBall( " << IDOfNode << ", " << diameter <<" )";
960 declareMeshModified( /*isReComputeSafe=*/false );
961 return elem ? elem->GetID() : 0;
963 SMESH_CATCH( SMESH::throwCorbaException );
967 //=============================================================================
969 * Create an edge, either linear and quadratic (this is determed
970 * by number of given nodes, two or three)
972 //=============================================================================
974 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
975 throw (SALOME::SALOME_Exception)
980 int NbNodes = IDsOfNodes.length();
981 SMDS_MeshElement* elem = 0;
984 CORBA::Long index1 = IDsOfNodes[0];
985 CORBA::Long index2 = IDsOfNodes[1];
986 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(index1),
987 getMeshDS()->FindNode(index2));
989 // Update Python script
990 TPythonDump() << "edge = " << this << ".AddEdge([ "
991 << index1 << ", " << index2 <<" ])";
994 CORBA::Long n1 = IDsOfNodes[0];
995 CORBA::Long n2 = IDsOfNodes[1];
996 CORBA::Long n12 = IDsOfNodes[2];
997 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(n1),
998 getMeshDS()->FindNode(n2),
999 getMeshDS()->FindNode(n12));
1000 // Update Python script
1001 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
1002 <<n1<<", "<<n2<<", "<<n12<<" ])";
1005 declareMeshModified( /*isReComputeSafe=*/false );
1006 return elem ? elem->GetID() : 0;
1008 SMESH_CATCH( SMESH::throwCorbaException );
1012 //=============================================================================
1016 //=============================================================================
1018 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
1019 throw (SALOME::SALOME_Exception)
1024 int NbNodes = IDsOfNodes.length();
1030 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1031 for (int i = 0; i < NbNodes; i++)
1032 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1034 SMDS_MeshElement* elem = 0;
1036 case 3: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]); break;
1037 case 4: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]); break;
1038 case 6: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1039 nodes[4], nodes[5]); break;
1040 case 7: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1041 nodes[4], nodes[5], nodes[6]); break;
1042 case 8: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1043 nodes[4], nodes[5], nodes[6], nodes[7]); break;
1044 case 9: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1045 nodes[4], nodes[5], nodes[6], nodes[7],
1047 default: elem = getMeshDS()->AddPolygonalFace(nodes);
1050 // Update Python script
1051 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
1053 declareMeshModified( /*isReComputeSafe=*/false );
1055 return elem ? elem->GetID() : 0;
1057 SMESH_CATCH( SMESH::throwCorbaException );
1061 //=============================================================================
1065 //=============================================================================
1066 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
1067 throw (SALOME::SALOME_Exception)
1072 int NbNodes = IDsOfNodes.length();
1073 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1074 for (int i = 0; i < NbNodes; i++)
1075 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1077 const SMDS_MeshElement* elem = getMeshDS()->AddPolygonalFace(nodes);
1079 // Update Python script
1080 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
1082 declareMeshModified( /*isReComputeSafe=*/false );
1083 return elem ? elem->GetID() : 0;
1085 SMESH_CATCH( SMESH::throwCorbaException );
1089 //=============================================================================
1091 * Create volume, either linear and quadratic (this is determed
1092 * by number of given nodes)
1094 //=============================================================================
1096 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
1097 throw (SALOME::SALOME_Exception)
1102 int NbNodes = IDsOfNodes.length();
1103 vector< const SMDS_MeshNode*> n(NbNodes);
1104 for(int i=0;i<NbNodes;i++)
1105 n[i]= getMeshDS()->FindNode(IDsOfNodes[i]);
1107 SMDS_MeshElement* elem = 0;
1110 case 4 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
1111 case 5 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
1112 case 6 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
1113 case 8 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
1114 case 10:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1115 n[6],n[7],n[8],n[9]);
1117 case 12:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1118 n[6],n[7],n[8],n[9],n[10],n[11]);
1120 case 13:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
1121 n[7],n[8],n[9],n[10],n[11],n[12]);
1123 case 15:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
1124 n[9],n[10],n[11],n[12],n[13],n[14]);
1126 case 20:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1127 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1128 n[15],n[16],n[17],n[18],n[19]);
1130 case 27:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1131 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1132 n[15],n[16],n[17],n[18],n[19],
1133 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
1137 // Update Python script
1138 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
1140 declareMeshModified( /*isReComputeSafe=*/false );
1141 return elem ? elem->GetID() : 0;
1143 SMESH_CATCH( SMESH::throwCorbaException );
1147 //=============================================================================
1149 * AddPolyhedralVolume
1151 //=============================================================================
1152 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
1153 const SMESH::long_array & Quantities)
1154 throw (SALOME::SALOME_Exception)
1159 int NbNodes = IDsOfNodes.length();
1160 std::vector<const SMDS_MeshNode*> n (NbNodes);
1161 for (int i = 0; i < NbNodes; i++)
1163 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDsOfNodes[i]);
1164 if (!aNode) return 0;
1168 int NbFaces = Quantities.length();
1169 std::vector<int> q (NbFaces);
1170 for (int j = 0; j < NbFaces; j++)
1171 q[j] = Quantities[j];
1173 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(n, q);
1175 // Update Python script
1176 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
1177 << IDsOfNodes << ", " << Quantities << " )";
1179 declareMeshModified( /*isReComputeSafe=*/false );
1180 return elem ? elem->GetID() : 0;
1182 SMESH_CATCH( SMESH::throwCorbaException );
1186 //=============================================================================
1188 * AddPolyhedralVolumeByFaces
1190 //=============================================================================
1192 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
1193 throw (SALOME::SALOME_Exception)
1198 int NbFaces = IdsOfFaces.length();
1199 std::vector<const SMDS_MeshNode*> poly_nodes;
1200 std::vector<int> quantities (NbFaces);
1202 for (int i = 0; i < NbFaces; i++) {
1203 const SMDS_MeshElement* aFace = getMeshDS()->FindElement(IdsOfFaces[i]);
1204 quantities[i] = aFace->NbNodes();
1206 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
1207 while (It->more()) {
1208 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
1212 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
1214 // Update Python script
1215 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
1216 << IdsOfFaces << " )";
1218 declareMeshModified( /*isReComputeSafe=*/false );
1219 return elem ? elem->GetID() : 0;
1221 SMESH_CATCH( SMESH::throwCorbaException );
1225 //=============================================================================
1227 // \brief Create 0D elements on all nodes of the given object except those
1228 // nodes on which a 0D element already exists.
1229 // \param theObject object on whose nodes 0D elements will be created.
1230 // \param theGroupName optional name of a group to add 0D elements created
1231 // and/or found on nodes of \a theObject.
1232 // \return an object (a new group or a temporary SMESH_IDSource) holding
1233 // ids of new and/or found 0D elements.
1235 //=============================================================================
1237 SMESH::SMESH_IDSource_ptr
1238 SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObject,
1239 const char* theGroupName)
1240 throw (SALOME::SALOME_Exception)
1245 SMESH::SMESH_IDSource_var result;
1248 TIDSortedElemSet elements, elems0D;
1249 prepareIdSource( theObject );
1250 if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
1251 getEditor().Create0DElementsOnAllNodes( elements, elems0D );
1253 SMESH::long_array_var newElems = new SMESH::long_array;
1254 newElems->length( elems0D.size() );
1255 TIDSortedElemSet::iterator eIt = elems0D.begin();
1256 for ( size_t i = 0; i < elems0D.size(); ++i, ++eIt )
1257 newElems[ i ] = (*eIt)->GetID();
1259 SMESH::SMESH_GroupBase_var groupToFill;
1260 if ( theGroupName && strlen( theGroupName ))
1262 // Get existing group named theGroupName
1263 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
1264 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
1265 SMESH::SMESH_GroupBase_var group = groups[i];
1266 if ( !group->_is_nil() ) {
1267 CORBA::String_var name = group->GetName();
1268 if ( strcmp( name.in(), theGroupName ) == 0 && group->GetType() == SMESH::ELEM0D ) {
1269 groupToFill = group;
1274 if ( groupToFill->_is_nil() )
1275 groupToFill = myMesh_i->CreateGroup( SMESH::ELEM0D, theGroupName );
1276 else if ( !SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1277 groupToFill = myMesh_i->ConvertToStandalone( groupToFill );
1280 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1282 group_i->Add( newElems );
1283 result = SMESH::SMESH_IDSource::_narrow( groupToFill );
1284 pyDump << groupToFill;
1288 result = MakeIDSource( newElems, SMESH::ELEM0D );
1289 pyDump << "elem0DIDs";
1292 pyDump << " = " << this << ".Create0DElementsOnAllNodes( "
1293 << theObject << ", '" << theGroupName << "' )";
1295 return result._retn();
1297 SMESH_CATCH( SMESH::throwCorbaException );
1301 //=============================================================================
1303 * \brief Bind a node to a vertex
1304 * \param NodeID - node ID
1305 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1306 * \retval boolean - false if NodeID or VertexID is invalid
1308 //=============================================================================
1310 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
1311 throw (SALOME::SALOME_Exception)
1315 SMESHDS_Mesh * mesh = getMeshDS();
1316 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1318 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1320 if ( mesh->MaxShapeIndex() < VertexID )
1321 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1323 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
1324 if ( shape.ShapeType() != TopAbs_VERTEX )
1325 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1327 mesh->SetNodeOnVertex( node, VertexID );
1329 myMesh->SetIsModified( true );
1331 SMESH_CATCH( SMESH::throwCorbaException );
1334 //=============================================================================
1336 * \brief Store node position on an edge
1337 * \param NodeID - node ID
1338 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
1339 * \param paramOnEdge - parameter on edge where the node is located
1340 * \retval boolean - false if any parameter is invalid
1342 //=============================================================================
1344 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
1345 CORBA::Double paramOnEdge)
1346 throw (SALOME::SALOME_Exception)
1350 SMESHDS_Mesh * mesh = getMeshDS();
1351 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1353 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1355 if ( mesh->MaxShapeIndex() < EdgeID )
1356 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1358 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
1359 if ( shape.ShapeType() != TopAbs_EDGE )
1360 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1363 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
1364 if ( paramOnEdge < f || paramOnEdge > l )
1365 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
1367 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
1369 myMesh->SetIsModified( true );
1371 SMESH_CATCH( SMESH::throwCorbaException );
1374 //=============================================================================
1376 * \brief Store node position on a face
1377 * \param NodeID - node ID
1378 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
1379 * \param u - U parameter on face where the node is located
1380 * \param v - V parameter on face where the node is located
1381 * \retval boolean - false if any parameter is invalid
1383 //=============================================================================
1385 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
1386 CORBA::Double u, CORBA::Double v)
1387 throw (SALOME::SALOME_Exception)
1390 SMESHDS_Mesh * mesh = getMeshDS();
1391 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1393 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1395 if ( mesh->MaxShapeIndex() < FaceID )
1396 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1398 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
1399 if ( shape.ShapeType() != TopAbs_FACE )
1400 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1402 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
1403 bool isOut = ( u < surf.FirstUParameter() ||
1404 u > surf.LastUParameter() ||
1405 v < surf.FirstVParameter() ||
1406 v > surf.LastVParameter() );
1410 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
1411 << " u( " << surf.FirstUParameter()
1412 << "," << surf.LastUParameter()
1413 << ") v( " << surf.FirstVParameter()
1414 << "," << surf.LastVParameter() << ")" );
1416 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
1419 mesh->SetNodeOnFace( node, FaceID, u, v );
1420 myMesh->SetIsModified( true );
1422 SMESH_CATCH( SMESH::throwCorbaException );
1425 //=============================================================================
1427 * \brief Bind a node to a solid
1428 * \param NodeID - node ID
1429 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1430 * \retval boolean - false if NodeID or SolidID is invalid
1432 //=============================================================================
1434 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
1435 throw (SALOME::SALOME_Exception)
1438 SMESHDS_Mesh * mesh = getMeshDS();
1439 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1441 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1443 if ( mesh->MaxShapeIndex() < SolidID )
1444 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1446 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
1447 if ( shape.ShapeType() != TopAbs_SOLID &&
1448 shape.ShapeType() != TopAbs_SHELL)
1449 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1451 mesh->SetNodeInVolume( node, SolidID );
1453 SMESH_CATCH( SMESH::throwCorbaException );
1456 //=============================================================================
1458 * \brief Bind an element to a shape
1459 * \param ElementID - element ID
1460 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
1462 //=============================================================================
1464 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
1465 CORBA::Long ShapeID)
1466 throw (SALOME::SALOME_Exception)
1469 SMESHDS_Mesh * mesh = getMeshDS();
1470 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
1472 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
1474 if ( mesh->MaxShapeIndex() < ShapeID || ShapeID < 1 )
1475 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1477 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1478 if ( shape.ShapeType() != TopAbs_EDGE &&
1479 shape.ShapeType() != TopAbs_FACE &&
1480 shape.ShapeType() != TopAbs_SOLID &&
1481 shape.ShapeType() != TopAbs_SHELL )
1482 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1484 mesh->SetMeshElementOnShape( elem, ShapeID );
1486 myMesh->SetIsModified( true );
1488 SMESH_CATCH( SMESH::throwCorbaException );
1491 //=============================================================================
1495 //=============================================================================
1497 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1498 CORBA::Long NodeID2)
1499 throw (SALOME::SALOME_Exception)
1504 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1505 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1509 // Update Python script
1510 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1511 << NodeID1 << ", " << NodeID2 << " )";
1513 int ret = getEditor().InverseDiag ( n1, n2 );
1515 declareMeshModified( /*isReComputeSafe=*/false );
1518 SMESH_CATCH( SMESH::throwCorbaException );
1522 //=============================================================================
1526 //=============================================================================
1528 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1529 CORBA::Long NodeID2)
1530 throw (SALOME::SALOME_Exception)
1535 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1536 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1540 // Update Python script
1541 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1542 << NodeID1 << ", " << NodeID2 << " )";
1545 bool stat = getEditor().DeleteDiag ( n1, n2 );
1547 declareMeshModified( /*isReComputeSafe=*/!stat );
1551 SMESH_CATCH( SMESH::throwCorbaException );
1555 //=============================================================================
1559 //=============================================================================
1561 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1562 throw (SALOME::SALOME_Exception)
1567 for (int i = 0; i < IDsOfElements.length(); i++)
1569 CORBA::Long index = IDsOfElements[i];
1570 const SMDS_MeshElement * elem = getMeshDS()->FindElement(index);
1572 getEditor().Reorient( elem );
1574 // Update Python script
1575 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1577 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 );
1580 SMESH_CATCH( SMESH::throwCorbaException );
1584 //=============================================================================
1588 //=============================================================================
1590 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1591 throw (SALOME::SALOME_Exception)
1596 TPythonDump aTPythonDump; // suppress dump in Reorient()
1598 prepareIdSource( theObject );
1600 SMESH::long_array_var anElementsId = theObject->GetIDs();
1601 CORBA::Boolean isDone = Reorient(anElementsId);
1603 // Update Python script
1604 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1606 declareMeshModified( /*isReComputeSafe=*/ anElementsId->length() == 0 );
1609 SMESH_CATCH( SMESH::throwCorbaException );
1613 //=======================================================================
1614 //function : Reorient2D
1615 //purpose : Reorient faces contained in \a the2Dgroup.
1616 // the2Dgroup - the mesh or its part to reorient
1617 // theDirection - desired direction of normal of \a theFace
1618 // theFace - ID of face whose orientation is checked.
1619 // It can be < 1 then \a thePoint is used to find a face.
1620 // thePoint - is used to find a face if \a theFace < 1.
1621 // return number of reoriented elements.
1622 //=======================================================================
1624 CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
1625 const SMESH::DirStruct& theDirection,
1626 CORBA::Long theFace,
1627 const SMESH::PointStruct& thePoint)
1628 throw (SALOME::SALOME_Exception)
1631 initData(/*deleteSearchers=*/false);
1633 TIDSortedElemSet elements;
1634 prepareIdSource( the2Dgroup );
1635 if ( !idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1))
1636 THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
1639 const SMDS_MeshElement* face = 0;
1642 face = getMeshDS()->FindElement( theFace );
1644 THROW_SALOME_CORBA_EXCEPTION("Inexistent face given", SALOME::BAD_PARAM);
1645 if ( face->GetType() != SMDSAbs_Face )
1646 THROW_SALOME_CORBA_EXCEPTION("Wrong element type", SALOME::BAD_PARAM);
1650 // create theElementSearcher if needed
1651 theSearchersDeleter.Set( myMesh, getPartIOR( the2Dgroup, SMESH::FACE ));
1652 if ( !theElementSearcher )
1654 if ( elements.empty() ) // search in the whole mesh
1656 if ( myMesh->NbFaces() == 0 )
1657 THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM);
1659 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
1663 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
1664 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
1666 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt);
1670 gp_Pnt p( thePoint.x, thePoint.y, thePoint.z );
1671 face = theElementSearcher->FindClosestTo( p, SMDSAbs_Face );
1674 THROW_SALOME_CORBA_EXCEPTION("No face found by point", SALOME::INTERNAL_ERROR );
1675 if ( !elements.empty() && !elements.count( face ))
1676 THROW_SALOME_CORBA_EXCEPTION("Found face is not in the group", SALOME::BAD_PARAM );
1679 const SMESH::PointStruct * P = &theDirection.PS;
1680 gp_Vec dirVec( P->x, P->y, P->z );
1681 if ( dirVec.Magnitude() < std::numeric_limits< double >::min() )
1682 THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM);
1684 int nbReori = getEditor().Reorient2D( elements, dirVec, face );
1687 declareMeshModified( /*isReComputeSafe=*/false );
1689 TPythonDump() << this << ".Reorient2D( "
1690 << the2Dgroup << ", "
1691 << theDirection << ", "
1693 << thePoint << " )";
1697 SMESH_CATCH( SMESH::throwCorbaException );
1701 //=============================================================================
1703 * \brief Fuse neighbour triangles into quadrangles.
1705 //=============================================================================
1707 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1708 SMESH::NumericalFunctor_ptr Criterion,
1709 CORBA::Double MaxAngle)
1710 throw (SALOME::SALOME_Exception)
1715 SMESHDS_Mesh* aMesh = getMeshDS();
1716 TIDSortedElemSet faces;
1717 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1719 SMESH::NumericalFunctor_i* aNumericalFunctor =
1720 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1721 SMESH::Controls::NumericalFunctorPtr aCrit;
1722 if ( !aNumericalFunctor )
1723 aCrit.reset( new SMESH::Controls::MaxElementLength2D() );
1725 aCrit = aNumericalFunctor->GetNumericalFunctor();
1727 // Update Python script
1728 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1729 << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1732 bool stat = getEditor().TriToQuad( faces, aCrit, MaxAngle );
1734 declareMeshModified( /*isReComputeSafe=*/!stat );
1737 SMESH_CATCH( SMESH::throwCorbaException );
1741 //=============================================================================
1743 * \brief Fuse neighbour triangles into quadrangles.
1745 //=============================================================================
1747 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1748 SMESH::NumericalFunctor_ptr Criterion,
1749 CORBA::Double MaxAngle)
1750 throw (SALOME::SALOME_Exception)
1755 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1757 prepareIdSource( theObject );
1758 SMESH::long_array_var anElementsId = theObject->GetIDs();
1759 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1761 SMESH::NumericalFunctor_i* aNumericalFunctor =
1762 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1764 // Update Python script
1765 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1766 << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1770 SMESH_CATCH( SMESH::throwCorbaException );
1774 //=============================================================================
1776 * \brief Split quadrangles into triangles.
1778 //=============================================================================
1780 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1781 SMESH::NumericalFunctor_ptr Criterion)
1782 throw (SALOME::SALOME_Exception)
1787 SMESHDS_Mesh* aMesh = getMeshDS();
1788 TIDSortedElemSet faces;
1789 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1791 SMESH::NumericalFunctor_i* aNumericalFunctor =
1792 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1793 SMESH::Controls::NumericalFunctorPtr aCrit;
1794 if ( !aNumericalFunctor )
1795 aCrit.reset( new SMESH::Controls::AspectRatio() );
1797 aCrit = aNumericalFunctor->GetNumericalFunctor();
1800 // Update Python script
1801 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1803 CORBA::Boolean stat = getEditor().QuadToTri( faces, aCrit );
1805 declareMeshModified( /*isReComputeSafe=*/false );
1808 SMESH_CATCH( SMESH::throwCorbaException );
1812 //=============================================================================
1814 * \brief Split quadrangles into triangles.
1816 //=============================================================================
1818 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1819 SMESH::NumericalFunctor_ptr Criterion)
1820 throw (SALOME::SALOME_Exception)
1825 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1827 prepareIdSource( theObject );
1828 SMESH::long_array_var anElementsId = theObject->GetIDs();
1829 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1831 SMESH::NumericalFunctor_i* aNumericalFunctor =
1832 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1834 // Update Python script
1835 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1837 declareMeshModified( /*isReComputeSafe=*/false );
1840 SMESH_CATCH( SMESH::throwCorbaException );
1844 //================================================================================
1846 * \brief Split each of quadrangles into 4 triangles.
1847 * \param [in] theObject - theQuads Container of quadrangles to split.
1849 //================================================================================
1851 void SMESH_MeshEditor_i::QuadTo4Tri (SMESH::SMESH_IDSource_ptr theObject)
1852 throw (SALOME::SALOME_Exception)
1857 TIDSortedElemSet faces;
1858 prepareIdSource( theObject );
1859 if ( !idSourceToSet( theObject, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/true ) &&
1861 THROW_SALOME_CORBA_EXCEPTION("No faces given", SALOME::BAD_PARAM);
1863 getEditor().QuadTo4Tri( faces );
1864 TPythonDump() << this << ".QuadTo4Tri( " << theObject << " )";
1866 SMESH_CATCH( SMESH::throwCorbaException );
1869 //=============================================================================
1871 * \brief Split quadrangles into triangles.
1873 //=============================================================================
1875 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1876 CORBA::Boolean Diag13)
1877 throw (SALOME::SALOME_Exception)
1882 SMESHDS_Mesh* aMesh = getMeshDS();
1883 TIDSortedElemSet faces;
1884 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1886 // Update Python script
1887 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1888 << IDsOfElements << ", " << Diag13 << " )";
1890 CORBA::Boolean stat = getEditor().QuadToTri( faces, Diag13 );
1892 declareMeshModified( /*isReComputeSafe=*/ !stat );
1895 SMESH_CATCH( SMESH::throwCorbaException );
1899 //=============================================================================
1901 * \brief Split quadrangles into triangles.
1903 //=============================================================================
1905 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1906 CORBA::Boolean Diag13)
1907 throw (SALOME::SALOME_Exception)
1912 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
1914 prepareIdSource( theObject );
1915 SMESH::long_array_var anElementsId = theObject->GetIDs();
1916 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
1918 // Update Python script
1919 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
1920 << theObject << ", " << Diag13 << " )";
1922 declareMeshModified( /*isReComputeSafe=*/!isDone );
1925 SMESH_CATCH( SMESH::throwCorbaException );
1930 //=============================================================================
1932 * Find better splitting of the given quadrangle.
1933 * \param IDOfQuad ID of the quadrangle to be splitted.
1934 * \param Criterion A criterion to choose a diagonal for splitting.
1935 * \return 1 if 1-3 diagonal is better, 2 if 2-4
1936 * diagonal is better, 0 if error occurs.
1938 //=============================================================================
1940 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
1941 SMESH::NumericalFunctor_ptr Criterion)
1942 throw (SALOME::SALOME_Exception)
1947 const SMDS_MeshElement* quad = getMeshDS()->FindElement(IDOfQuad);
1948 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
1950 SMESH::NumericalFunctor_i* aNumericalFunctor =
1951 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
1952 SMESH::Controls::NumericalFunctorPtr aCrit;
1953 if (aNumericalFunctor)
1954 aCrit = aNumericalFunctor->GetNumericalFunctor();
1956 aCrit.reset(new SMESH::Controls::AspectRatio());
1958 int id = getEditor().BestSplit(quad, aCrit);
1959 declareMeshModified( /*isReComputeSafe=*/ id < 1 );
1962 SMESH_CATCH( SMESH::throwCorbaException );
1966 //================================================================================
1968 * \brief Split volumic elements into tetrahedrons
1970 //================================================================================
1972 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
1973 CORBA::Short methodFlags)
1974 throw (SALOME::SALOME_Exception)
1979 prepareIdSource( elems );
1980 SMESH::long_array_var anElementsId = elems->GetIDs();
1981 TIDSortedElemSet elemSet;
1982 arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume );
1984 getEditor().SplitVolumesIntoTetra( elemSet, int( methodFlags ));
1985 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
1987 TPythonDump() << this << ".SplitVolumesIntoTetra( "
1988 << elems << ", " << methodFlags << " )";
1990 SMESH_CATCH( SMESH::throwCorbaException );
1993 //=======================================================================
1996 //=======================================================================
1999 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
2000 const SMESH::long_array & IDsOfFixedNodes,
2001 CORBA::Long MaxNbOfIterations,
2002 CORBA::Double MaxAspectRatio,
2003 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2004 throw (SALOME::SALOME_Exception)
2006 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2007 MaxAspectRatio, Method, false );
2011 //=======================================================================
2012 //function : SmoothParametric
2014 //=======================================================================
2017 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
2018 const SMESH::long_array & IDsOfFixedNodes,
2019 CORBA::Long MaxNbOfIterations,
2020 CORBA::Double MaxAspectRatio,
2021 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2022 throw (SALOME::SALOME_Exception)
2024 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2025 MaxAspectRatio, Method, true );
2029 //=======================================================================
2030 //function : SmoothObject
2032 //=======================================================================
2035 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
2036 const SMESH::long_array & IDsOfFixedNodes,
2037 CORBA::Long MaxNbOfIterations,
2038 CORBA::Double MaxAspectRatio,
2039 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2040 throw (SALOME::SALOME_Exception)
2042 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2043 MaxAspectRatio, Method, false);
2047 //=======================================================================
2048 //function : SmoothParametricObject
2050 //=======================================================================
2053 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
2054 const SMESH::long_array & IDsOfFixedNodes,
2055 CORBA::Long MaxNbOfIterations,
2056 CORBA::Double MaxAspectRatio,
2057 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2058 throw (SALOME::SALOME_Exception)
2060 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2061 MaxAspectRatio, Method, true);
2065 //=============================================================================
2069 //=============================================================================
2072 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
2073 const SMESH::long_array & IDsOfFixedNodes,
2074 CORBA::Long MaxNbOfIterations,
2075 CORBA::Double MaxAspectRatio,
2076 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2078 throw (SALOME::SALOME_Exception)
2083 SMESHDS_Mesh* aMesh = getMeshDS();
2085 TIDSortedElemSet elements;
2086 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
2088 set<const SMDS_MeshNode*> fixedNodes;
2089 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
2090 CORBA::Long index = IDsOfFixedNodes[i];
2091 const SMDS_MeshNode * node = aMesh->FindNode(index);
2093 fixedNodes.insert( node );
2095 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
2096 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
2097 method = ::SMESH_MeshEditor::CENTROIDAL;
2099 getEditor().Smooth(elements, fixedNodes, method,
2100 MaxNbOfIterations, MaxAspectRatio, IsParametric );
2102 declareMeshModified( /*isReComputeSafe=*/true ); // does not prevent re-compute
2104 // Update Python script
2105 TPythonDump() << "isDone = " << this << "."
2106 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
2107 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
2108 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2109 << "SMESH.SMESH_MeshEditor."
2110 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2111 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2115 SMESH_CATCH( SMESH::throwCorbaException );
2119 //=============================================================================
2123 //=============================================================================
2126 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
2127 const SMESH::long_array & IDsOfFixedNodes,
2128 CORBA::Long MaxNbOfIterations,
2129 CORBA::Double MaxAspectRatio,
2130 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2132 throw (SALOME::SALOME_Exception)
2137 TPythonDump aTPythonDump; // suppress dump in smooth()
2139 prepareIdSource( theObject );
2140 SMESH::long_array_var anElementsId = theObject->GetIDs();
2141 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
2142 MaxAspectRatio, Method, IsParametric);
2144 // Update Python script
2145 aTPythonDump << "isDone = " << this << "."
2146 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
2147 << theObject << ", " << IDsOfFixedNodes << ", "
2148 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2149 << "SMESH.SMESH_MeshEditor."
2150 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2151 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2155 SMESH_CATCH( SMESH::throwCorbaException );
2159 //=============================================================================
2163 //=============================================================================
2165 void SMESH_MeshEditor_i::RenumberNodes()
2166 throw (SALOME::SALOME_Exception)
2169 // Update Python script
2170 TPythonDump() << this << ".RenumberNodes()";
2172 getMeshDS()->Renumber( true );
2174 SMESH_CATCH( SMESH::throwCorbaException );
2177 //=============================================================================
2181 //=============================================================================
2183 void SMESH_MeshEditor_i::RenumberElements()
2184 throw (SALOME::SALOME_Exception)
2187 // Update Python script
2188 TPythonDump() << this << ".RenumberElements()";
2190 getMeshDS()->Renumber( false );
2192 SMESH_CATCH( SMESH::throwCorbaException );
2195 //=======================================================================
2197 * \brief Return groups by their IDs
2199 //=======================================================================
2201 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
2202 throw (SALOME::SALOME_Exception)
2207 myMesh_i->CreateGroupServants();
2208 return myMesh_i->GetGroups( *groupIDs );
2210 SMESH_CATCH( SMESH::throwCorbaException );
2214 //=======================================================================
2215 //function : rotationSweep
2217 //=======================================================================
2219 SMESH::ListOfGroups*
2220 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
2221 const SMESH::AxisStruct & theAxis,
2222 CORBA::Double theAngleInRadians,
2223 CORBA::Long theNbOfSteps,
2224 CORBA::Double theTolerance,
2225 const bool theMakeGroups,
2226 const SMDSAbs_ElementType theElementType)
2227 throw (SALOME::SALOME_Exception)
2232 TIDSortedElemSet inElements, copyElements;
2233 arrayToSet(theIDsOfElements, getMeshDS(), inElements, theElementType);
2235 TIDSortedElemSet* workElements = & inElements;
2236 bool makeWalls=true;
2237 if ( myIsPreviewMode )
2239 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2240 getPreviewMesh( SMDSAbs_Face )->Copy( inElements, copyElements, select, avoid );
2241 workElements = & copyElements;
2242 //makeWalls = false;
2245 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
2246 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
2248 ::SMESH_MeshEditor::PGroupIDs groupIds =
2249 getEditor().RotationSweep (*workElements, Ax1, theAngleInRadians,
2250 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
2252 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2254 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2256 SMESH_CATCH( SMESH::throwCorbaException );
2260 //=======================================================================
2261 //function : RotationSweep
2263 //=======================================================================
2265 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
2266 const SMESH::AxisStruct & theAxis,
2267 CORBA::Double theAngleInRadians,
2268 CORBA::Long theNbOfSteps,
2269 CORBA::Double theTolerance)
2270 throw (SALOME::SALOME_Exception)
2272 if ( !myIsPreviewMode ) {
2273 TPythonDump() << this << ".RotationSweep( "
2274 << theIDsOfElements << ", "
2276 << TVar( theAngleInRadians ) << ", "
2277 << TVar( theNbOfSteps ) << ", "
2278 << TVar( theTolerance ) << " )";
2280 rotationSweep(theIDsOfElements,
2288 //=======================================================================
2289 //function : RotationSweepMakeGroups
2291 //=======================================================================
2293 SMESH::ListOfGroups*
2294 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2295 const SMESH::AxisStruct& theAxis,
2296 CORBA::Double theAngleInRadians,
2297 CORBA::Long theNbOfSteps,
2298 CORBA::Double theTolerance)
2299 throw (SALOME::SALOME_Exception)
2301 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2303 SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
2309 if (!myIsPreviewMode) {
2310 dumpGroupsList(aPythonDump, aGroups);
2311 aPythonDump << this << ".RotationSweepMakeGroups( "
2312 << theIDsOfElements << ", "
2314 << TVar( theAngleInRadians ) << ", "
2315 << TVar( theNbOfSteps ) << ", "
2316 << TVar( theTolerance ) << " )";
2321 //=======================================================================
2322 //function : RotationSweepObject
2324 //=======================================================================
2326 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2327 const SMESH::AxisStruct & theAxis,
2328 CORBA::Double theAngleInRadians,
2329 CORBA::Long theNbOfSteps,
2330 CORBA::Double theTolerance)
2331 throw (SALOME::SALOME_Exception)
2333 if ( !myIsPreviewMode ) {
2334 TPythonDump() << this << ".RotationSweepObject( "
2335 << theObject << ", "
2337 << theAngleInRadians << ", "
2338 << theNbOfSteps << ", "
2339 << theTolerance << " )";
2341 prepareIdSource( theObject );
2342 SMESH::long_array_var anElementsId = theObject->GetIDs();
2343 rotationSweep(anElementsId,
2351 //=======================================================================
2352 //function : RotationSweepObject1D
2354 //=======================================================================
2356 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2357 const SMESH::AxisStruct & theAxis,
2358 CORBA::Double theAngleInRadians,
2359 CORBA::Long theNbOfSteps,
2360 CORBA::Double theTolerance)
2361 throw (SALOME::SALOME_Exception)
2363 if ( !myIsPreviewMode ) {
2364 TPythonDump() << this << ".RotationSweepObject1D( "
2365 << theObject << ", "
2367 << TVar( theAngleInRadians ) << ", "
2368 << TVar( theNbOfSteps ) << ", "
2369 << TVar( theTolerance ) << " )";
2371 prepareIdSource( theObject );
2372 SMESH::long_array_var anElementsId = theObject->GetIDs();
2373 rotationSweep(anElementsId,
2382 //=======================================================================
2383 //function : RotationSweepObject2D
2385 //=======================================================================
2387 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2388 const SMESH::AxisStruct & theAxis,
2389 CORBA::Double theAngleInRadians,
2390 CORBA::Long theNbOfSteps,
2391 CORBA::Double theTolerance)
2392 throw (SALOME::SALOME_Exception)
2394 if ( !myIsPreviewMode ) {
2395 TPythonDump() << this << ".RotationSweepObject2D( "
2396 << theObject << ", "
2398 << TVar( theAngleInRadians ) << ", "
2399 << TVar( theNbOfSteps ) << ", "
2400 << TVar( theTolerance ) << " )";
2402 prepareIdSource( theObject );
2403 SMESH::long_array_var anElementsId = theObject->GetIDs();
2404 rotationSweep(anElementsId,
2413 //=======================================================================
2414 //function : RotationSweepObjectMakeGroups
2416 //=======================================================================
2418 SMESH::ListOfGroups*
2419 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2420 const SMESH::AxisStruct& theAxis,
2421 CORBA::Double theAngleInRadians,
2422 CORBA::Long theNbOfSteps,
2423 CORBA::Double theTolerance)
2424 throw (SALOME::SALOME_Exception)
2426 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2428 prepareIdSource( theObject );
2429 SMESH::long_array_var anElementsId = theObject->GetIDs();
2430 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2436 if (!myIsPreviewMode) {
2437 dumpGroupsList(aPythonDump, aGroups);
2438 aPythonDump << this << ".RotationSweepObjectMakeGroups( "
2439 << theObject << ", "
2441 << theAngleInRadians << ", "
2442 << theNbOfSteps << ", "
2443 << theTolerance << " )";
2448 //=======================================================================
2449 //function : RotationSweepObject1DMakeGroups
2451 //=======================================================================
2453 SMESH::ListOfGroups*
2454 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2455 const SMESH::AxisStruct& theAxis,
2456 CORBA::Double theAngleInRadians,
2457 CORBA::Long theNbOfSteps,
2458 CORBA::Double theTolerance)
2459 throw (SALOME::SALOME_Exception)
2461 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2463 prepareIdSource( theObject );
2464 SMESH::long_array_var anElementsId = theObject->GetIDs();
2465 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2472 if (!myIsPreviewMode) {
2473 dumpGroupsList(aPythonDump, aGroups);
2474 aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
2475 << theObject << ", "
2477 << TVar( theAngleInRadians ) << ", "
2478 << TVar( theNbOfSteps ) << ", "
2479 << TVar( theTolerance ) << " )";
2484 //=======================================================================
2485 //function : RotationSweepObject2DMakeGroups
2487 //=======================================================================
2489 SMESH::ListOfGroups*
2490 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2491 const SMESH::AxisStruct& theAxis,
2492 CORBA::Double theAngleInRadians,
2493 CORBA::Long theNbOfSteps,
2494 CORBA::Double theTolerance)
2495 throw (SALOME::SALOME_Exception)
2497 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2499 prepareIdSource( theObject );
2500 SMESH::long_array_var anElementsId = theObject->GetIDs();
2501 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2508 if (!myIsPreviewMode) {
2509 dumpGroupsList(aPythonDump, aGroups);
2510 aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
2511 << theObject << ", "
2513 << TVar( theAngleInRadians ) << ", "
2514 << TVar( theNbOfSteps ) << ", "
2515 << TVar( theTolerance ) << " )";
2521 //=======================================================================
2522 //function : extrusionSweep
2524 //=======================================================================
2526 SMESH::ListOfGroups*
2527 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
2528 const SMESH::DirStruct & theStepVector,
2529 CORBA::Long theNbOfSteps,
2531 const SMDSAbs_ElementType theElementType)
2532 throw (SALOME::SALOME_Exception)
2537 TIDSortedElemSet elements, copyElements;
2538 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
2540 const SMESH::PointStruct * P = &theStepVector.PS;
2541 gp_Vec stepVec( P->x, P->y, P->z );
2543 TIDSortedElemSet* workElements = & elements;
2545 SMDSAbs_ElementType aType = SMDSAbs_Face;
2546 if (theElementType == SMDSAbs_Node)
2548 aType = SMDSAbs_Edge;
2550 if ( myIsPreviewMode ) {
2551 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2552 getPreviewMesh( aType )->Copy( elements, copyElements, select, avoid );
2553 workElements = & copyElements;
2554 theMakeGroups = false;
2557 TElemOfElemListMap aHystory;
2558 ::SMESH_MeshEditor::PGroupIDs groupIds =
2559 getEditor().ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
2561 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2563 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2565 SMESH_CATCH( SMESH::throwCorbaException );
2569 //=======================================================================
2570 //function : ExtrusionSweep
2572 //=======================================================================
2574 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
2575 const SMESH::DirStruct & theStepVector,
2576 CORBA::Long theNbOfSteps)
2577 throw (SALOME::SALOME_Exception)
2579 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
2580 if (!myIsPreviewMode) {
2581 TPythonDump() << this << ".ExtrusionSweep( "
2582 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps) << " )";
2586 //=======================================================================
2587 //function : ExtrusionSweep0D
2589 //=======================================================================
2591 void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElements,
2592 const SMESH::DirStruct & theStepVector,
2593 CORBA::Long theNbOfSteps)
2594 throw (SALOME::SALOME_Exception)
2596 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2597 if (!myIsPreviewMode) {
2598 TPythonDump() << this << ".ExtrusionSweep0D( "
2599 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps)<< " )";
2603 //=======================================================================
2604 //function : ExtrusionSweepObject
2606 //=======================================================================
2608 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2609 const SMESH::DirStruct & theStepVector,
2610 CORBA::Long theNbOfSteps)
2611 throw (SALOME::SALOME_Exception)
2613 prepareIdSource( theObject );
2614 SMESH::long_array_var anElementsId = theObject->GetIDs();
2615 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
2616 if (!myIsPreviewMode) {
2617 TPythonDump() << this << ".ExtrusionSweepObject( "
2618 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
2622 //=======================================================================
2623 //function : ExtrusionSweepObject0D
2625 //=======================================================================
2627 void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObject,
2628 const SMESH::DirStruct & theStepVector,
2629 CORBA::Long theNbOfSteps)
2630 throw (SALOME::SALOME_Exception)
2632 prepareIdSource( theObject );
2633 SMESH::long_array_var anElementsId = theObject->GetIDs();
2634 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2635 if ( !myIsPreviewMode ) {
2636 TPythonDump() << this << ".ExtrusionSweepObject0D( "
2637 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2641 //=======================================================================
2642 //function : ExtrusionSweepObject1D
2644 //=======================================================================
2646 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2647 const SMESH::DirStruct & theStepVector,
2648 CORBA::Long theNbOfSteps)
2649 throw (SALOME::SALOME_Exception)
2651 prepareIdSource( theObject );
2652 SMESH::long_array_var anElementsId = theObject->GetIDs();
2653 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
2654 if ( !myIsPreviewMode ) {
2655 TPythonDump() << this << ".ExtrusionSweepObject1D( "
2656 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2660 //=======================================================================
2661 //function : ExtrusionSweepObject2D
2663 //=======================================================================
2665 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2666 const SMESH::DirStruct & theStepVector,
2667 CORBA::Long theNbOfSteps)
2668 throw (SALOME::SALOME_Exception)
2670 prepareIdSource( theObject );
2671 SMESH::long_array_var anElementsId = theObject->GetIDs();
2672 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
2673 if ( !myIsPreviewMode ) {
2674 TPythonDump() << this << ".ExtrusionSweepObject2D( "
2675 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2679 //=======================================================================
2680 //function : ExtrusionSweepMakeGroups
2682 //=======================================================================
2684 SMESH::ListOfGroups*
2685 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2686 const SMESH::DirStruct& theStepVector,
2687 CORBA::Long theNbOfSteps)
2688 throw (SALOME::SALOME_Exception)
2690 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2692 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
2694 if (!myIsPreviewMode) {
2695 dumpGroupsList(aPythonDump, aGroups);
2696 aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
2697 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2702 //=======================================================================
2703 //function : ExtrusionSweepMakeGroups0D
2705 //=======================================================================
2707 SMESH::ListOfGroups*
2708 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups0D(const SMESH::long_array& theIDsOfElements,
2709 const SMESH::DirStruct& theStepVector,
2710 CORBA::Long theNbOfSteps)
2711 throw (SALOME::SALOME_Exception)
2713 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2715 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true,SMDSAbs_Node);
2717 if (!myIsPreviewMode) {
2718 dumpGroupsList(aPythonDump, aGroups);
2719 aPythonDump << this << ".ExtrusionSweepMakeGroups0D( " << theIDsOfElements
2720 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2725 //=======================================================================
2726 //function : ExtrusionSweepObjectMakeGroups
2728 //=======================================================================
2730 SMESH::ListOfGroups*
2731 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2732 const SMESH::DirStruct& theStepVector,
2733 CORBA::Long theNbOfSteps)
2734 throw (SALOME::SALOME_Exception)
2736 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2738 prepareIdSource( theObject );
2739 SMESH::long_array_var anElementsId = theObject->GetIDs();
2740 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
2742 if (!myIsPreviewMode) {
2743 dumpGroupsList(aPythonDump, aGroups);
2744 aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
2745 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2750 //=======================================================================
2751 //function : ExtrusionSweepObject0DMakeGroups
2753 //=======================================================================
2755 SMESH::ListOfGroups*
2756 SMESH_MeshEditor_i::ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2757 const SMESH::DirStruct& theStepVector,
2758 CORBA::Long theNbOfSteps)
2759 throw (SALOME::SALOME_Exception)
2761 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2763 prepareIdSource( theObject );
2764 SMESH::long_array_var anElementsId = theObject->GetIDs();
2765 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2766 theNbOfSteps, true, SMDSAbs_Node);
2767 if (!myIsPreviewMode) {
2768 dumpGroupsList(aPythonDump, aGroups);
2769 aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject
2770 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2775 //=======================================================================
2776 //function : ExtrusionSweepObject1DMakeGroups
2778 //=======================================================================
2780 SMESH::ListOfGroups*
2781 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2782 const SMESH::DirStruct& theStepVector,
2783 CORBA::Long theNbOfSteps)
2784 throw (SALOME::SALOME_Exception)
2786 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2788 prepareIdSource( theObject );
2789 SMESH::long_array_var anElementsId = theObject->GetIDs();
2790 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2791 theNbOfSteps, true, SMDSAbs_Edge);
2792 if (!myIsPreviewMode) {
2793 dumpGroupsList(aPythonDump, aGroups);
2794 aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
2795 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2800 //=======================================================================
2801 //function : ExtrusionSweepObject2DMakeGroups
2803 //=======================================================================
2805 SMESH::ListOfGroups*
2806 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2807 const SMESH::DirStruct& theStepVector,
2808 CORBA::Long theNbOfSteps)
2809 throw (SALOME::SALOME_Exception)
2811 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2813 prepareIdSource( theObject );
2814 SMESH::long_array_var anElementsId = theObject->GetIDs();
2815 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2816 theNbOfSteps, true, SMDSAbs_Face);
2817 if (!myIsPreviewMode) {
2818 dumpGroupsList(aPythonDump, aGroups);
2819 aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
2820 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2826 //=======================================================================
2827 //function : advancedExtrusion
2829 //=======================================================================
2831 SMESH::ListOfGroups*
2832 SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
2833 const SMESH::DirStruct & theStepVector,
2834 CORBA::Long theNbOfSteps,
2835 CORBA::Long theExtrFlags,
2836 CORBA::Double theSewTolerance,
2837 const bool theMakeGroups)
2838 throw (SALOME::SALOME_Exception)
2843 TIDSortedElemSet elements;
2844 arrayToSet(theIDsOfElements, getMeshDS(), elements);
2846 const SMESH::PointStruct * P = &theStepVector.PS;
2847 gp_Vec stepVec( P->x, P->y, P->z );
2849 TElemOfElemListMap aHystory;
2850 ::SMESH_MeshEditor::PGroupIDs groupIds =
2851 getEditor().ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
2852 theMakeGroups, theExtrFlags, theSewTolerance);
2854 declareMeshModified( /*isReComputeSafe=*/true );
2856 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2858 SMESH_CATCH( SMESH::throwCorbaException );
2862 //=======================================================================
2863 //function : AdvancedExtrusion
2865 //=======================================================================
2867 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2868 const SMESH::DirStruct & theStepVector,
2869 CORBA::Long theNbOfSteps,
2870 CORBA::Long theExtrFlags,
2871 CORBA::Double theSewTolerance)
2872 throw (SALOME::SALOME_Exception)
2874 if ( !myIsPreviewMode ) {
2875 TPythonDump() << "stepVector = " << theStepVector;
2876 TPythonDump() << this << ".AdvancedExtrusion("
2879 << theNbOfSteps << ","
2880 << theExtrFlags << ", "
2881 << theSewTolerance << " )";
2883 advancedExtrusion( theIDsOfElements,
2891 //=======================================================================
2892 //function : AdvancedExtrusionMakeGroups
2894 //=======================================================================
2895 SMESH::ListOfGroups*
2896 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
2897 const SMESH::DirStruct& theStepVector,
2898 CORBA::Long theNbOfSteps,
2899 CORBA::Long theExtrFlags,
2900 CORBA::Double theSewTolerance)
2901 throw (SALOME::SALOME_Exception)
2903 if (!myIsPreviewMode) {
2904 TPythonDump() << "stepVector = " << theStepVector;
2906 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2908 SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
2915 if (!myIsPreviewMode) {
2916 dumpGroupsList(aPythonDump, aGroups);
2917 aPythonDump << this << ".AdvancedExtrusionMakeGroups("
2920 << theNbOfSteps << ","
2921 << theExtrFlags << ", "
2922 << theSewTolerance << " )";
2928 //================================================================================
2930 * \brief Convert extrusion error to IDL enum
2932 //================================================================================
2934 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
2936 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
2940 RETCASE( EXTR_NO_ELEMENTS );
2941 RETCASE( EXTR_PATH_NOT_EDGE );
2942 RETCASE( EXTR_BAD_PATH_SHAPE );
2943 RETCASE( EXTR_BAD_STARTING_NODE );
2944 RETCASE( EXTR_BAD_ANGLES_NUMBER );
2945 RETCASE( EXTR_CANT_GET_TANGENT );
2947 return SMESH::SMESH_MeshEditor::EXTR_OK;
2951 //=======================================================================
2952 //function : extrusionAlongPath
2954 //=======================================================================
2955 SMESH::ListOfGroups*
2956 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2957 SMESH::SMESH_Mesh_ptr thePathMesh,
2958 GEOM::GEOM_Object_ptr thePathShape,
2959 CORBA::Long theNodeStart,
2960 CORBA::Boolean theHasAngles,
2961 const SMESH::double_array & theAngles,
2962 CORBA::Boolean theHasRefPoint,
2963 const SMESH::PointStruct & theRefPoint,
2964 const bool theMakeGroups,
2965 SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
2966 const SMDSAbs_ElementType theElementType)
2967 throw (SALOME::SALOME_Exception)
2970 MESSAGE("extrusionAlongPath");
2973 if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
2974 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2977 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2979 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2980 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2982 if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
2983 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2987 SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
2989 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2993 TIDSortedElemSet elements;
2994 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
2996 list<double> angles;
2997 for (int i = 0; i < theAngles.length(); i++) {
2998 angles.push_back( theAngles[i] );
3001 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
3003 int nbOldGroups = myMesh->NbGroup();
3005 ::SMESH_MeshEditor::Extrusion_Error error =
3006 getEditor().ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
3007 theHasAngles, angles, false,
3008 theHasRefPoint, refPnt, theMakeGroups );
3010 declareMeshModified( /*isReComputeSafe=*/true );
3011 theError = convExtrError( error );
3013 if ( theMakeGroups ) {
3014 list<int> groupIDs = myMesh->GetGroupIds();
3015 list<int>::iterator newBegin = groupIDs.begin();
3016 std::advance( newBegin, nbOldGroups ); // skip old groups
3017 groupIDs.erase( groupIDs.begin(), newBegin );
3018 return getGroups( & groupIDs );
3022 SMESH_CATCH( SMESH::throwCorbaException );
3026 //=======================================================================
3027 //function : extrusionAlongPathX
3029 //=======================================================================
3031 SMESH::ListOfGroups*
3032 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements,
3033 SMESH::SMESH_IDSource_ptr Path,
3034 CORBA::Long NodeStart,
3035 CORBA::Boolean HasAngles,
3036 const SMESH::double_array& Angles,
3037 CORBA::Boolean LinearVariation,
3038 CORBA::Boolean HasRefPoint,
3039 const SMESH::PointStruct& RefPoint,
3041 const SMDSAbs_ElementType ElementType,
3042 SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
3043 throw (SALOME::SALOME_Exception)
3046 SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
3050 list<double> angles;
3051 for (int i = 0; i < Angles.length(); i++) {
3052 angles.push_back( Angles[i] );
3054 gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
3055 int nbOldGroups = myMesh->NbGroup();
3057 if ( Path->_is_nil() ) {
3058 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3062 TIDSortedElemSet elements, copyElements;
3063 arrayToSet(IDsOfElements, getMeshDS(), elements, ElementType);
3065 TIDSortedElemSet* workElements = &elements;
3067 if ( myIsPreviewMode )
3069 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
3070 getPreviewMesh( SMDSAbs_Face )->Copy( elements, copyElements, select, avoid );
3071 workElements = & copyElements;
3075 ::SMESH_MeshEditor::Extrusion_Error error;
3077 if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path ))
3080 SMDS_MeshNode* aNodeStart =
3081 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
3082 if ( !aNodeStart ) {
3083 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3086 error = getEditor().ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
3087 HasAngles, angles, LinearVariation,
3088 HasRefPoint, refPnt, MakeGroups );
3089 declareMeshModified( /*isReComputeSafe=*/true );
3091 else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
3094 SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
3095 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
3096 SMDS_MeshNode* aNodeStart =
3097 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
3098 if ( !aNodeStart ) {
3099 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3102 SMESH_subMesh* aSubMesh =
3103 aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
3104 error = getEditor().ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
3105 HasAngles, angles, LinearVariation,
3106 HasRefPoint, refPnt, MakeGroups );
3107 declareMeshModified( /*isReComputeSafe=*/true );
3109 else if ( SMESH::DownCast<SMESH_Group_i*>( Path ))
3111 // path as group of 1D elements
3117 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3121 Error = convExtrError( error );
3124 list<int> groupIDs = myMesh->GetGroupIds();
3125 list<int>::iterator newBegin = groupIDs.begin();
3126 std::advance( newBegin, nbOldGroups ); // skip old groups
3127 groupIDs.erase( groupIDs.begin(), newBegin );
3128 return getGroups( & groupIDs );
3132 SMESH_CATCH( SMESH::throwCorbaException );
3136 //=======================================================================
3137 //function : ExtrusionAlongPath
3139 //=======================================================================
3141 SMESH::SMESH_MeshEditor::Extrusion_Error
3142 SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements,
3143 SMESH::SMESH_Mesh_ptr thePathMesh,
3144 GEOM::GEOM_Object_ptr thePathShape,
3145 CORBA::Long theNodeStart,
3146 CORBA::Boolean theHasAngles,
3147 const SMESH::double_array & theAngles,
3148 CORBA::Boolean theHasRefPoint,
3149 const SMESH::PointStruct & theRefPoint)
3150 throw (SALOME::SALOME_Exception)
3152 MESSAGE("ExtrusionAlongPath");
3153 if ( !myIsPreviewMode ) {
3154 TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
3155 << theIDsOfElements << ", "
3156 << thePathMesh << ", "
3157 << thePathShape << ", "
3158 << theNodeStart << ", "
3159 << theHasAngles << ", "
3160 << theAngles << ", "
3161 << theHasRefPoint << ", "
3162 << "SMESH.PointStruct( "
3163 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3164 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3165 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3167 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3168 extrusionAlongPath( theIDsOfElements,
3181 //=======================================================================
3182 //function : ExtrusionAlongPathObject
3184 //=======================================================================
3186 SMESH::SMESH_MeshEditor::Extrusion_Error
3187 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject,
3188 SMESH::SMESH_Mesh_ptr thePathMesh,
3189 GEOM::GEOM_Object_ptr thePathShape,
3190 CORBA::Long theNodeStart,
3191 CORBA::Boolean theHasAngles,
3192 const SMESH::double_array & theAngles,
3193 CORBA::Boolean theHasRefPoint,
3194 const SMESH::PointStruct & theRefPoint)
3195 throw (SALOME::SALOME_Exception)
3197 if ( !myIsPreviewMode ) {
3198 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
3199 << theObject << ", "
3200 << thePathMesh << ", "
3201 << thePathShape << ", "
3202 << theNodeStart << ", "
3203 << theHasAngles << ", "
3204 << theAngles << ", "
3205 << theHasRefPoint << ", "
3206 << "SMESH.PointStruct( "
3207 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3208 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3209 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3211 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3212 prepareIdSource( theObject );
3213 SMESH::long_array_var anElementsId = theObject->GetIDs();
3214 extrusionAlongPath( anElementsId,
3227 //=======================================================================
3228 //function : ExtrusionAlongPathObject1D
3230 //=======================================================================
3232 SMESH::SMESH_MeshEditor::Extrusion_Error
3233 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject,
3234 SMESH::SMESH_Mesh_ptr thePathMesh,
3235 GEOM::GEOM_Object_ptr thePathShape,
3236 CORBA::Long theNodeStart,
3237 CORBA::Boolean theHasAngles,
3238 const SMESH::double_array & theAngles,
3239 CORBA::Boolean theHasRefPoint,
3240 const SMESH::PointStruct & theRefPoint)
3241 throw (SALOME::SALOME_Exception)
3243 if ( !myIsPreviewMode ) {
3244 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
3245 << theObject << ", "
3246 << thePathMesh << ", "
3247 << thePathShape << ", "
3248 << theNodeStart << ", "
3249 << theHasAngles << ", "
3250 << theAngles << ", "
3251 << theHasRefPoint << ", "
3252 << "SMESH.PointStruct( "
3253 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3254 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3255 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3257 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3258 prepareIdSource( theObject );
3259 SMESH::long_array_var anElementsId = theObject->GetIDs();
3260 extrusionAlongPath( anElementsId,
3274 //=======================================================================
3275 //function : ExtrusionAlongPathObject2D
3277 //=======================================================================
3279 SMESH::SMESH_MeshEditor::Extrusion_Error
3280 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject,
3281 SMESH::SMESH_Mesh_ptr thePathMesh,
3282 GEOM::GEOM_Object_ptr thePathShape,
3283 CORBA::Long theNodeStart,
3284 CORBA::Boolean theHasAngles,
3285 const SMESH::double_array & theAngles,
3286 CORBA::Boolean theHasRefPoint,
3287 const SMESH::PointStruct & theRefPoint)
3288 throw (SALOME::SALOME_Exception)
3290 if ( !myIsPreviewMode ) {
3291 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
3292 << theObject << ", "
3293 << thePathMesh << ", "
3294 << thePathShape << ", "
3295 << theNodeStart << ", "
3296 << theHasAngles << ", "
3297 << theAngles << ", "
3298 << theHasRefPoint << ", "
3299 << "SMESH.PointStruct( "
3300 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3301 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3302 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3304 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3305 prepareIdSource( theObject );
3306 SMESH::long_array_var anElementsId = theObject->GetIDs();
3307 extrusionAlongPath( anElementsId,
3322 //=======================================================================
3323 //function : ExtrusionAlongPathMakeGroups
3325 //=======================================================================
3327 SMESH::ListOfGroups*
3328 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theIDsOfElements,
3329 SMESH::SMESH_Mesh_ptr thePathMesh,
3330 GEOM::GEOM_Object_ptr thePathShape,
3331 CORBA::Long theNodeStart,
3332 CORBA::Boolean theHasAngles,
3333 const SMESH::double_array& theAngles,
3334 CORBA::Boolean theHasRefPoint,
3335 const SMESH::PointStruct& theRefPoint,
3336 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3337 throw (SALOME::SALOME_Exception)
3339 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3341 SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements,
3351 if (!myIsPreviewMode) {
3352 bool isDumpGroups = aGroups && aGroups->length() > 0;
3354 aPythonDump << "(" << aGroups << ", error)";
3356 aPythonDump <<"error";
3358 aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
3359 << theIDsOfElements << ", "
3360 << thePathMesh << ", "
3361 << thePathShape << ", "
3362 << theNodeStart << ", "
3363 << theHasAngles << ", "
3364 << theAngles << ", "
3365 << theHasRefPoint << ", "
3366 << "SMESH.PointStruct( "
3367 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3368 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3369 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3374 //=======================================================================
3375 //function : ExtrusionAlongPathObjectMakeGroups
3377 //=======================================================================
3379 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3380 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3381 SMESH::SMESH_Mesh_ptr thePathMesh,
3382 GEOM::GEOM_Object_ptr thePathShape,
3383 CORBA::Long theNodeStart,
3384 CORBA::Boolean theHasAngles,
3385 const SMESH::double_array& theAngles,
3386 CORBA::Boolean theHasRefPoint,
3387 const SMESH::PointStruct& theRefPoint,
3388 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3389 throw (SALOME::SALOME_Exception)
3391 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3393 prepareIdSource( theObject );
3394 SMESH::long_array_var anElementsId = theObject->GetIDs();
3395 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3406 if (!myIsPreviewMode) {
3407 bool isDumpGroups = aGroups && aGroups->length() > 0;
3409 aPythonDump << "(" << aGroups << ", error)";
3411 aPythonDump <<"error";
3413 aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
3414 << theObject << ", "
3415 << thePathMesh << ", "
3416 << thePathShape << ", "
3417 << theNodeStart << ", "
3418 << theHasAngles << ", "
3419 << theAngles << ", "
3420 << theHasRefPoint << ", "
3421 << "SMESH.PointStruct( "
3422 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3423 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3424 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3429 //=======================================================================
3430 //function : ExtrusionAlongPathObject1DMakeGroups
3432 //=======================================================================
3434 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3435 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3436 SMESH::SMESH_Mesh_ptr thePathMesh,
3437 GEOM::GEOM_Object_ptr thePathShape,
3438 CORBA::Long theNodeStart,
3439 CORBA::Boolean theHasAngles,
3440 const SMESH::double_array& theAngles,
3441 CORBA::Boolean theHasRefPoint,
3442 const SMESH::PointStruct& theRefPoint,
3443 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3444 throw (SALOME::SALOME_Exception)
3446 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3448 prepareIdSource( theObject );
3449 SMESH::long_array_var anElementsId = theObject->GetIDs();
3450 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3462 if (!myIsPreviewMode) {
3463 bool isDumpGroups = aGroups && aGroups->length() > 0;
3465 aPythonDump << "(" << aGroups << ", error)";
3467 aPythonDump << "error";
3469 aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
3470 << theObject << ", "
3471 << thePathMesh << ", "
3472 << thePathShape << ", "
3473 << theNodeStart << ", "
3474 << theHasAngles << ", "
3475 << theAngles << ", "
3476 << theHasRefPoint << ", "
3477 << "SMESH.PointStruct( "
3478 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3479 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3480 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3485 //=======================================================================
3486 //function : ExtrusionAlongPathObject2DMakeGroups
3488 //=======================================================================
3490 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3491 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3492 SMESH::SMESH_Mesh_ptr thePathMesh,
3493 GEOM::GEOM_Object_ptr thePathShape,
3494 CORBA::Long theNodeStart,
3495 CORBA::Boolean theHasAngles,
3496 const SMESH::double_array& theAngles,
3497 CORBA::Boolean theHasRefPoint,
3498 const SMESH::PointStruct& theRefPoint,
3499 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3500 throw (SALOME::SALOME_Exception)
3502 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3504 prepareIdSource( theObject );
3505 SMESH::long_array_var anElementsId = theObject->GetIDs();
3506 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3518 if (!myIsPreviewMode) {
3519 bool isDumpGroups = aGroups && aGroups->length() > 0;
3521 aPythonDump << "(" << aGroups << ", error)";
3523 aPythonDump << "error";
3525 aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
3526 << theObject << ", "
3527 << thePathMesh << ", "
3528 << thePathShape << ", "
3529 << theNodeStart << ", "
3530 << theHasAngles << ", "
3531 << theAngles << ", "
3532 << theHasRefPoint << ", "
3533 << "SMESH.PointStruct( "
3534 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3535 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3536 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3541 //=======================================================================
3542 //function : ExtrusionAlongPathObjX
3544 //=======================================================================
3546 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3547 ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr Object,
3548 SMESH::SMESH_IDSource_ptr Path,
3549 CORBA::Long NodeStart,
3550 CORBA::Boolean HasAngles,
3551 const SMESH::double_array& Angles,
3552 CORBA::Boolean LinearVariation,
3553 CORBA::Boolean HasRefPoint,
3554 const SMESH::PointStruct& RefPoint,
3555 CORBA::Boolean MakeGroups,
3556 SMESH::ElementType ElemType,
3557 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3558 throw (SALOME::SALOME_Exception)
3560 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3562 prepareIdSource( Object );
3563 SMESH::long_array_var anElementsId = Object->GetIDs();
3564 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
3573 (SMDSAbs_ElementType)ElemType,
3576 if (!myIsPreviewMode) {
3577 bool isDumpGroups = aGroups && aGroups->length() > 0;
3579 aPythonDump << "(" << *aGroups << ", error)";
3581 aPythonDump << "error";
3583 aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
3586 << NodeStart << ", "
3587 << HasAngles << ", "
3588 << TVar( Angles ) << ", "
3589 << LinearVariation << ", "
3590 << HasRefPoint << ", "
3591 << "SMESH.PointStruct( "
3592 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3593 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3594 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3595 << MakeGroups << ", "
3596 << ElemType << " )";
3601 //=======================================================================
3602 //function : ExtrusionAlongPathX
3604 //=======================================================================
3606 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3607 ExtrusionAlongPathX(const SMESH::long_array& IDsOfElements,
3608 SMESH::SMESH_IDSource_ptr Path,
3609 CORBA::Long NodeStart,
3610 CORBA::Boolean HasAngles,
3611 const SMESH::double_array& Angles,
3612 CORBA::Boolean LinearVariation,
3613 CORBA::Boolean HasRefPoint,
3614 const SMESH::PointStruct& RefPoint,
3615 CORBA::Boolean MakeGroups,
3616 SMESH::ElementType ElemType,
3617 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3618 throw (SALOME::SALOME_Exception)
3620 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3622 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
3631 (SMDSAbs_ElementType)ElemType,
3634 if (!myIsPreviewMode) {
3635 bool isDumpGroups = aGroups && aGroups->length() > 0;
3637 aPythonDump << "(" << *aGroups << ", error)";
3639 aPythonDump <<"error";
3641 aPythonDump << " = " << this << ".ExtrusionAlongPathX( "
3642 << IDsOfElements << ", "
3644 << NodeStart << ", "
3645 << HasAngles << ", "
3646 << TVar( Angles ) << ", "
3647 << LinearVariation << ", "
3648 << HasRefPoint << ", "
3649 << "SMESH.PointStruct( "
3650 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3651 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3652 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3653 << MakeGroups << ", "
3654 << ElemType << " )";
3659 //================================================================================
3661 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
3662 * of given angles along path steps
3663 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
3664 * which proceeds the extrusion
3665 * \param PathShape is shape(edge); as the mesh can be complex, the edge
3666 * is used to define the sub-mesh for the path
3668 //================================================================================
3670 SMESH::double_array*
3671 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
3672 GEOM::GEOM_Object_ptr thePathShape,
3673 const SMESH::double_array & theAngles)
3675 SMESH::double_array_var aResult = new SMESH::double_array();
3676 int nbAngles = theAngles.length();
3677 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
3679 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3680 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3681 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3682 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
3683 return aResult._retn();
3684 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
3685 if ( nbSteps == nbAngles )
3687 aResult.inout() = theAngles;
3691 aResult->length( nbSteps );
3692 double rAn2St = double( nbAngles ) / double( nbSteps );
3693 double angPrev = 0, angle;
3694 for ( int iSt = 0; iSt < nbSteps; ++iSt )
3696 double angCur = rAn2St * ( iSt+1 );
3697 double angCurFloor = floor( angCur );
3698 double angPrevFloor = floor( angPrev );
3699 if ( angPrevFloor == angCurFloor )
3700 angle = rAn2St * theAngles[ int( angCurFloor ) ];
3703 int iP = int( angPrevFloor );
3704 double angPrevCeil = ceil(angPrev);
3705 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
3707 int iC = int( angCurFloor );
3708 if ( iC < nbAngles )
3709 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
3711 iP = int( angPrevCeil );
3713 angle += theAngles[ iC ];
3715 aResult[ iSt ] = angle;
3720 // Update Python script
3721 TPythonDump() << "rotAngles = " << theAngles;
3722 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
3723 << thePathMesh << ", "
3724 << thePathShape << ", "
3727 return aResult._retn();
3730 //=======================================================================
3733 //=======================================================================
3735 SMESH::ListOfGroups*
3736 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
3737 const SMESH::AxisStruct & theAxis,
3738 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3739 CORBA::Boolean theCopy,
3741 ::SMESH_Mesh* theTargetMesh)
3742 throw (SALOME::SALOME_Exception)
3747 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3748 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3750 if ( theTargetMesh )
3754 switch ( theMirrorType ) {
3755 case SMESH::SMESH_MeshEditor::POINT:
3756 aTrsf.SetMirror( P );
3758 case SMESH::SMESH_MeshEditor::AXIS:
3759 aTrsf.SetMirror( gp_Ax1( P, V ));
3762 aTrsf.SetMirror( gp_Ax2( P, V ));
3765 TIDSortedElemSet copyElements;
3766 TIDSortedElemSet* workElements = & theElements;
3768 if ( myIsPreviewMode )
3770 TPreviewMesh * tmpMesh = getPreviewMesh();
3771 tmpMesh->Copy( theElements, copyElements);
3772 if ( !theCopy && !theTargetMesh )
3774 TIDSortedElemSet elemsAround, elemsAroundCopy;
3775 getElementsAround( theElements, getMeshDS(), elemsAround );
3776 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3778 workElements = & copyElements;
3779 theMakeGroups = false;
3782 ::SMESH_MeshEditor::PGroupIDs groupIds =
3783 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3785 if ( theCopy && !myIsPreviewMode)
3787 if ( theTargetMesh )
3789 theTargetMesh->GetMeshDS()->Modified();
3793 declareMeshModified( /*isReComputeSafe=*/false );
3796 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3798 SMESH_CATCH( SMESH::throwCorbaException );
3802 //=======================================================================
3805 //=======================================================================
3807 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3808 const SMESH::AxisStruct & theAxis,
3809 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3810 CORBA::Boolean theCopy)
3811 throw (SALOME::SALOME_Exception)
3813 if ( !myIsPreviewMode ) {
3814 TPythonDump() << this << ".Mirror( "
3815 << theIDsOfElements << ", "
3817 << mirrorTypeName(theMirrorType) << ", "
3820 if ( theIDsOfElements.length() > 0 )
3822 TIDSortedElemSet elements;
3823 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3824 mirror(elements, theAxis, theMirrorType, theCopy, false);
3829 //=======================================================================
3830 //function : MirrorObject
3832 //=======================================================================
3834 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3835 const SMESH::AxisStruct & theAxis,
3836 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3837 CORBA::Boolean theCopy)
3838 throw (SALOME::SALOME_Exception)
3840 if ( !myIsPreviewMode ) {
3841 TPythonDump() << this << ".MirrorObject( "
3842 << theObject << ", "
3844 << mirrorTypeName(theMirrorType) << ", "
3847 TIDSortedElemSet elements;
3849 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3851 prepareIdSource( theObject );
3852 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3853 mirror(elements, theAxis, theMirrorType, theCopy, false);
3856 //=======================================================================
3857 //function : MirrorMakeGroups
3859 //=======================================================================
3861 SMESH::ListOfGroups*
3862 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3863 const SMESH::AxisStruct& theMirror,
3864 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3865 throw (SALOME::SALOME_Exception)
3867 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3869 SMESH::ListOfGroups * aGroups = 0;
3870 if ( theIDsOfElements.length() > 0 )
3872 TIDSortedElemSet elements;
3873 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3874 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3876 if (!myIsPreviewMode) {
3877 dumpGroupsList(aPythonDump, aGroups);
3878 aPythonDump << this << ".MirrorMakeGroups( "
3879 << theIDsOfElements << ", "
3880 << theMirror << ", "
3881 << mirrorTypeName(theMirrorType) << " )";
3886 //=======================================================================
3887 //function : MirrorObjectMakeGroups
3889 //=======================================================================
3891 SMESH::ListOfGroups*
3892 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3893 const SMESH::AxisStruct& theMirror,
3894 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3895 throw (SALOME::SALOME_Exception)
3897 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3899 SMESH::ListOfGroups * aGroups = 0;
3900 TIDSortedElemSet elements;
3901 prepareIdSource( theObject );
3902 if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3903 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3905 if (!myIsPreviewMode)
3907 dumpGroupsList(aPythonDump,aGroups);
3908 aPythonDump << this << ".MirrorObjectMakeGroups( "
3909 << theObject << ", "
3910 << theMirror << ", "
3911 << mirrorTypeName(theMirrorType) << " )";
3916 //=======================================================================
3917 //function : MirrorMakeMesh
3919 //=======================================================================
3921 SMESH::SMESH_Mesh_ptr
3922 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
3923 const SMESH::AxisStruct& theMirror,
3924 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3925 CORBA::Boolean theCopyGroups,
3926 const char* theMeshName)
3927 throw (SALOME::SALOME_Exception)
3929 SMESH_Mesh_i* mesh_i;
3930 SMESH::SMESH_Mesh_var mesh;
3931 { // open new scope to dump "MakeMesh" command
3932 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3934 TPythonDump pydump; // to prevent dump at mesh creation
3936 mesh = makeMesh( theMeshName );
3937 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3938 if (mesh_i && theIDsOfElements.length() > 0 )
3940 TIDSortedElemSet elements;
3941 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3942 mirror(elements, theMirror, theMirrorType,
3943 false, theCopyGroups, & mesh_i->GetImpl());
3944 mesh_i->CreateGroupServants();
3947 if (!myIsPreviewMode) {
3948 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
3949 << theIDsOfElements << ", "
3950 << theMirror << ", "
3951 << mirrorTypeName(theMirrorType) << ", "
3952 << theCopyGroups << ", '"
3953 << theMeshName << "' )";
3958 if (!myIsPreviewMode && mesh_i)
3959 mesh_i->GetGroups();
3961 return mesh._retn();
3964 //=======================================================================
3965 //function : MirrorObjectMakeMesh
3967 //=======================================================================
3969 SMESH::SMESH_Mesh_ptr
3970 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3971 const SMESH::AxisStruct& theMirror,
3972 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3973 CORBA::Boolean theCopyGroups,
3974 const char* theMeshName)
3975 throw (SALOME::SALOME_Exception)
3977 SMESH_Mesh_i* mesh_i;
3978 SMESH::SMESH_Mesh_var mesh;
3979 { // open new scope to dump "MakeMesh" command
3980 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3982 TPythonDump pydump; // to prevent dump at mesh creation
3984 mesh = makeMesh( theMeshName );
3985 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3986 TIDSortedElemSet elements;
3987 prepareIdSource( theObject );
3989 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3991 mirror(elements, theMirror, theMirrorType,
3992 false, theCopyGroups, & mesh_i->GetImpl());
3993 mesh_i->CreateGroupServants();
3995 if (!myIsPreviewMode) {
3996 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
3997 << theObject << ", "
3998 << theMirror << ", "
3999 << mirrorTypeName(theMirrorType) << ", "
4000 << theCopyGroups << ", '"
4001 << theMeshName << "' )";
4006 if (!myIsPreviewMode && mesh_i)
4007 mesh_i->GetGroups();
4009 return mesh._retn();
4012 //=======================================================================
4013 //function : translate
4015 //=======================================================================
4017 SMESH::ListOfGroups*
4018 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
4019 const SMESH::DirStruct & theVector,
4020 CORBA::Boolean theCopy,
4022 ::SMESH_Mesh* theTargetMesh)
4023 throw (SALOME::SALOME_Exception)
4028 if ( theTargetMesh )
4032 const SMESH::PointStruct * P = &theVector.PS;
4033 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
4035 TIDSortedElemSet copyElements;
4036 TIDSortedElemSet* workElements = &theElements;
4038 if ( myIsPreviewMode )
4040 TPreviewMesh * tmpMesh = getPreviewMesh();
4041 tmpMesh->Copy( theElements, copyElements);
4042 if ( !theCopy && !theTargetMesh )
4044 TIDSortedElemSet elemsAround, elemsAroundCopy;
4045 getElementsAround( theElements, getMeshDS(), elemsAround );
4046 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4048 workElements = & copyElements;
4049 theMakeGroups = false;
4052 ::SMESH_MeshEditor::PGroupIDs groupIds =
4053 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4055 if ( theCopy && !myIsPreviewMode )
4057 if ( theTargetMesh )
4059 theTargetMesh->GetMeshDS()->Modified();
4063 declareMeshModified( /*isReComputeSafe=*/false );
4067 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4069 SMESH_CATCH( SMESH::throwCorbaException );
4073 //=======================================================================
4074 //function : Translate
4076 //=======================================================================
4078 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
4079 const SMESH::DirStruct & theVector,
4080 CORBA::Boolean theCopy)
4081 throw (SALOME::SALOME_Exception)
4083 if (!myIsPreviewMode) {
4084 TPythonDump() << this << ".Translate( "
4085 << theIDsOfElements << ", "
4086 << theVector << ", "
4089 if (theIDsOfElements.length()) {
4090 TIDSortedElemSet elements;
4091 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4092 translate(elements, theVector, theCopy, false);
4096 //=======================================================================
4097 //function : TranslateObject
4099 //=======================================================================
4101 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
4102 const SMESH::DirStruct & theVector,
4103 CORBA::Boolean theCopy)
4104 throw (SALOME::SALOME_Exception)
4106 if (!myIsPreviewMode) {
4107 TPythonDump() << this << ".TranslateObject( "
4108 << theObject << ", "
4109 << theVector << ", "
4112 TIDSortedElemSet elements;
4114 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4116 prepareIdSource( theObject );
4117 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4118 translate(elements, theVector, theCopy, false);
4121 //=======================================================================
4122 //function : TranslateMakeGroups
4124 //=======================================================================
4126 SMESH::ListOfGroups*
4127 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
4128 const SMESH::DirStruct& theVector)
4129 throw (SALOME::SALOME_Exception)
4131 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4133 SMESH::ListOfGroups * aGroups = 0;
4134 if (theIDsOfElements.length()) {
4135 TIDSortedElemSet elements;
4136 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4137 aGroups = translate(elements,theVector,true,true);
4139 if (!myIsPreviewMode) {
4140 dumpGroupsList(aPythonDump, aGroups);
4141 aPythonDump << this << ".TranslateMakeGroups( "
4142 << theIDsOfElements << ", "
4143 << theVector << " )";
4148 //=======================================================================
4149 //function : TranslateObjectMakeGroups
4151 //=======================================================================
4153 SMESH::ListOfGroups*
4154 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4155 const SMESH::DirStruct& theVector)
4156 throw (SALOME::SALOME_Exception)
4158 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4160 SMESH::ListOfGroups * aGroups = 0;
4161 TIDSortedElemSet elements;
4162 prepareIdSource( theObject );
4163 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4164 aGroups = translate(elements, theVector, true, true);
4166 if (!myIsPreviewMode) {
4167 dumpGroupsList(aPythonDump, aGroups);
4168 aPythonDump << this << ".TranslateObjectMakeGroups( "
4169 << theObject << ", "
4170 << theVector << " )";
4175 //=======================================================================
4176 //function : TranslateMakeMesh
4178 //=======================================================================
4180 SMESH::SMESH_Mesh_ptr
4181 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
4182 const SMESH::DirStruct& theVector,
4183 CORBA::Boolean theCopyGroups,
4184 const char* theMeshName)
4185 throw (SALOME::SALOME_Exception)
4187 SMESH_Mesh_i* mesh_i;
4188 SMESH::SMESH_Mesh_var mesh;
4190 { // open new scope to dump "MakeMesh" command
4191 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4193 TPythonDump pydump; // to prevent dump at mesh creation
4195 mesh = makeMesh( theMeshName );
4196 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4198 if ( mesh_i && theIDsOfElements.length() )
4200 TIDSortedElemSet elements;
4201 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4202 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
4203 mesh_i->CreateGroupServants();
4206 if ( !myIsPreviewMode ) {
4207 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
4208 << theIDsOfElements << ", "
4209 << theVector << ", "
4210 << theCopyGroups << ", '"
4211 << theMeshName << "' )";
4216 if (!myIsPreviewMode && mesh_i)
4217 mesh_i->GetGroups();
4219 return mesh._retn();
4222 //=======================================================================
4223 //function : TranslateObjectMakeMesh
4225 //=======================================================================
4227 SMESH::SMESH_Mesh_ptr
4228 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4229 const SMESH::DirStruct& theVector,
4230 CORBA::Boolean theCopyGroups,
4231 const char* theMeshName)
4232 throw (SALOME::SALOME_Exception)
4235 SMESH_Mesh_i* mesh_i;
4236 SMESH::SMESH_Mesh_var mesh;
4237 { // open new scope to dump "MakeMesh" command
4238 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4240 TPythonDump pydump; // to prevent dump at mesh creation
4241 mesh = makeMesh( theMeshName );
4242 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4244 TIDSortedElemSet elements;
4245 prepareIdSource( theObject );
4247 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4249 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
4250 mesh_i->CreateGroupServants();
4252 if ( !myIsPreviewMode ) {
4253 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
4254 << theObject << ", "
4255 << theVector << ", "
4256 << theCopyGroups << ", '"
4257 << theMeshName << "' )";
4262 if (!myIsPreviewMode && mesh_i)
4263 mesh_i->GetGroups();
4265 return mesh._retn();
4267 SMESH_CATCH( SMESH::throwCorbaException );
4271 //=======================================================================
4274 //=======================================================================
4276 SMESH::ListOfGroups*
4277 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
4278 const SMESH::AxisStruct & theAxis,
4279 CORBA::Double theAngle,
4280 CORBA::Boolean theCopy,
4282 ::SMESH_Mesh* theTargetMesh)
4283 throw (SALOME::SALOME_Exception)
4288 if ( theTargetMesh )
4291 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
4292 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
4295 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
4297 TIDSortedElemSet copyElements;
4298 TIDSortedElemSet* workElements = &theElements;
4299 if ( myIsPreviewMode ) {
4300 TPreviewMesh * tmpMesh = getPreviewMesh();
4301 tmpMesh->Copy( theElements, copyElements );
4302 if ( !theCopy && !theTargetMesh )
4304 TIDSortedElemSet elemsAround, elemsAroundCopy;
4305 getElementsAround( theElements, getMeshDS(), elemsAround );
4306 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4308 workElements = ©Elements;
4309 theMakeGroups = false;
4312 ::SMESH_MeshEditor::PGroupIDs groupIds =
4313 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4315 if ( theCopy && !myIsPreviewMode)
4317 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
4318 else declareMeshModified( /*isReComputeSafe=*/false );
4321 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4323 SMESH_CATCH( SMESH::throwCorbaException );
4327 //=======================================================================
4330 //=======================================================================
4332 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
4333 const SMESH::AxisStruct & theAxis,
4334 CORBA::Double theAngle,
4335 CORBA::Boolean theCopy)
4336 throw (SALOME::SALOME_Exception)
4338 if (!myIsPreviewMode) {
4339 TPythonDump() << this << ".Rotate( "
4340 << theIDsOfElements << ", "
4342 << TVar( theAngle ) << ", "
4345 if (theIDsOfElements.length() > 0)
4347 TIDSortedElemSet elements;
4348 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4349 rotate(elements,theAxis,theAngle,theCopy,false);
4353 //=======================================================================
4354 //function : RotateObject
4356 //=======================================================================
4358 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
4359 const SMESH::AxisStruct & theAxis,
4360 CORBA::Double theAngle,
4361 CORBA::Boolean theCopy)
4362 throw (SALOME::SALOME_Exception)
4364 if ( !myIsPreviewMode ) {
4365 TPythonDump() << this << ".RotateObject( "
4366 << theObject << ", "
4368 << TVar( theAngle ) << ", "
4371 TIDSortedElemSet elements;
4372 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4373 prepareIdSource( theObject );
4374 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4375 rotate(elements,theAxis,theAngle,theCopy,false);
4378 //=======================================================================
4379 //function : RotateMakeGroups
4381 //=======================================================================
4383 SMESH::ListOfGroups*
4384 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
4385 const SMESH::AxisStruct& theAxis,
4386 CORBA::Double theAngle)
4387 throw (SALOME::SALOME_Exception)
4389 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4391 SMESH::ListOfGroups * aGroups = 0;
4392 if (theIDsOfElements.length() > 0)
4394 TIDSortedElemSet elements;
4395 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4396 aGroups = rotate(elements,theAxis,theAngle,true,true);
4398 if (!myIsPreviewMode) {
4399 dumpGroupsList(aPythonDump, aGroups);
4400 aPythonDump << this << ".RotateMakeGroups( "
4401 << theIDsOfElements << ", "
4403 << TVar( theAngle ) << " )";
4408 //=======================================================================
4409 //function : RotateObjectMakeGroups
4411 //=======================================================================
4413 SMESH::ListOfGroups*
4414 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4415 const SMESH::AxisStruct& theAxis,
4416 CORBA::Double theAngle)
4417 throw (SALOME::SALOME_Exception)
4419 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4421 SMESH::ListOfGroups * aGroups = 0;
4422 TIDSortedElemSet elements;
4423 prepareIdSource( theObject );
4424 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4425 aGroups = rotate(elements, theAxis, theAngle, true, true);
4427 if (!myIsPreviewMode) {
4428 dumpGroupsList(aPythonDump, aGroups);
4429 aPythonDump << this << ".RotateObjectMakeGroups( "
4430 << theObject << ", "
4432 << TVar( theAngle ) << " )";
4437 //=======================================================================
4438 //function : RotateMakeMesh
4440 //=======================================================================
4442 SMESH::SMESH_Mesh_ptr
4443 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
4444 const SMESH::AxisStruct& theAxis,
4445 CORBA::Double theAngleInRadians,
4446 CORBA::Boolean theCopyGroups,
4447 const char* theMeshName)
4448 throw (SALOME::SALOME_Exception)
4451 SMESH::SMESH_Mesh_var mesh;
4452 SMESH_Mesh_i* mesh_i;
4454 { // open new scope to dump "MakeMesh" command
4455 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4457 TPythonDump pydump; // to prevent dump at mesh creation
4459 mesh = makeMesh( theMeshName );
4460 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4462 if ( mesh_i && theIDsOfElements.length() > 0 )
4464 TIDSortedElemSet elements;
4465 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4466 rotate(elements, theAxis, theAngleInRadians,
4467 false, theCopyGroups, & mesh_i->GetImpl());
4468 mesh_i->CreateGroupServants();
4470 if ( !myIsPreviewMode ) {
4471 pydump << mesh << " = " << this << ".RotateMakeMesh( "
4472 << theIDsOfElements << ", "
4474 << TVar( theAngleInRadians ) << ", "
4475 << theCopyGroups << ", '"
4476 << theMeshName << "' )";
4481 if (!myIsPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
4482 mesh_i->GetGroups();
4484 return mesh._retn();
4486 SMESH_CATCH( SMESH::throwCorbaException );
4490 //=======================================================================
4491 //function : RotateObjectMakeMesh
4493 //=======================================================================
4495 SMESH::SMESH_Mesh_ptr
4496 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4497 const SMESH::AxisStruct& theAxis,
4498 CORBA::Double theAngleInRadians,
4499 CORBA::Boolean theCopyGroups,
4500 const char* theMeshName)
4501 throw (SALOME::SALOME_Exception)
4504 SMESH::SMESH_Mesh_var mesh;
4505 SMESH_Mesh_i* mesh_i;
4507 {// open new scope to dump "MakeMesh" command
4508 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4510 TPythonDump pydump; // to prevent dump at mesh creation
4511 mesh = makeMesh( theMeshName );
4512 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4514 TIDSortedElemSet elements;
4515 prepareIdSource( theObject );
4517 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4519 rotate(elements, theAxis, theAngleInRadians,
4520 false, theCopyGroups, & mesh_i->GetImpl());
4521 mesh_i->CreateGroupServants();
4523 if ( !myIsPreviewMode ) {
4524 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
4525 << theObject << ", "
4527 << TVar( theAngleInRadians ) << ", "
4528 << theCopyGroups << ", '"
4529 << theMeshName << "' )";
4534 if (!myIsPreviewMode && mesh_i)
4535 mesh_i->GetGroups();
4537 return mesh._retn();
4539 SMESH_CATCH( SMESH::throwCorbaException );
4543 //=======================================================================
4546 //=======================================================================
4548 SMESH::ListOfGroups*
4549 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
4550 const SMESH::PointStruct& thePoint,
4551 const SMESH::double_array& theScaleFact,
4552 CORBA::Boolean theCopy,
4554 ::SMESH_Mesh* theTargetMesh)
4555 throw (SALOME::SALOME_Exception)
4559 if ( theScaleFact.length() < 1 )
4560 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
4561 if ( theScaleFact.length() == 2 )
4562 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
4564 if ( theTargetMesh )
4567 TIDSortedElemSet elements;
4568 prepareIdSource( theObject );
4569 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4570 if ( !idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4575 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
4576 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
4578 double tol = std::numeric_limits<double>::max();
4580 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
4581 0, S[1], 0, thePoint.y * (1-S[1]),
4582 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
4584 TIDSortedElemSet copyElements;
4585 TIDSortedElemSet* workElements = &elements;
4586 if ( myIsPreviewMode )
4588 TPreviewMesh * tmpMesh = getPreviewMesh();
4589 tmpMesh->Copy( elements, copyElements);
4590 if ( !theCopy && !theTargetMesh )
4592 TIDSortedElemSet elemsAround, elemsAroundCopy;
4593 getElementsAround( elements, getMeshDS(), elemsAround );
4594 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4596 workElements = & copyElements;
4597 theMakeGroups = false;
4600 ::SMESH_MeshEditor::PGroupIDs groupIds =
4601 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4603 if ( theCopy && !myIsPreviewMode )
4605 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
4606 else declareMeshModified( /*isReComputeSafe=*/false );
4608 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4610 SMESH_CATCH( SMESH::throwCorbaException );
4614 //=======================================================================
4617 //=======================================================================
4619 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
4620 const SMESH::PointStruct& thePoint,
4621 const SMESH::double_array& theScaleFact,
4622 CORBA::Boolean theCopy)
4623 throw (SALOME::SALOME_Exception)
4625 if ( !myIsPreviewMode ) {
4626 TPythonDump() << this << ".Scale( "
4627 << theObject << ", "
4629 << TVar( theScaleFact ) << ", "
4632 scale(theObject, thePoint, theScaleFact, theCopy, false);
4636 //=======================================================================
4637 //function : ScaleMakeGroups
4639 //=======================================================================
4641 SMESH::ListOfGroups*
4642 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4643 const SMESH::PointStruct& thePoint,
4644 const SMESH::double_array& theScaleFact)
4645 throw (SALOME::SALOME_Exception)
4647 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4649 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
4650 if (!myIsPreviewMode) {
4651 dumpGroupsList(aPythonDump, aGroups);
4652 aPythonDump << this << ".Scale("
4655 << TVar( theScaleFact ) << ",True,True)";
4661 //=======================================================================
4662 //function : ScaleMakeMesh
4664 //=======================================================================
4666 SMESH::SMESH_Mesh_ptr
4667 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4668 const SMESH::PointStruct& thePoint,
4669 const SMESH::double_array& theScaleFact,
4670 CORBA::Boolean theCopyGroups,
4671 const char* theMeshName)
4672 throw (SALOME::SALOME_Exception)
4674 SMESH_Mesh_i* mesh_i;
4675 SMESH::SMESH_Mesh_var mesh;
4676 { // open new scope to dump "MakeMesh" command
4677 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4679 TPythonDump pydump; // to prevent dump at mesh creation
4680 mesh = makeMesh( theMeshName );
4681 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4685 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
4686 mesh_i->CreateGroupServants();
4688 if ( !myIsPreviewMode )
4689 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
4690 << theObject << ", "
4692 << TVar( theScaleFact ) << ", "
4693 << theCopyGroups << ", '"
4694 << theMeshName << "' )";
4698 if (!myIsPreviewMode && mesh_i)
4699 mesh_i->GetGroups();
4701 return mesh._retn();
4705 //=======================================================================
4706 //function : FindCoincidentNodes
4708 //=======================================================================
4710 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance,
4711 SMESH::array_of_long_array_out GroupsOfNodes)
4712 throw (SALOME::SALOME_Exception)
4717 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4718 TIDSortedNodeSet nodes; // no input nodes
4719 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4721 GroupsOfNodes = new SMESH::array_of_long_array;
4722 GroupsOfNodes->length( aListOfListOfNodes.size() );
4723 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4724 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
4725 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4726 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4727 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4728 aGroup.length( aListOfNodes.size() );
4729 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4730 aGroup[ j ] = (*lIt)->GetID();
4732 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
4733 << Tolerance << " )";
4735 SMESH_CATCH( SMESH::throwCorbaException );
4738 //=======================================================================
4739 //function : FindCoincidentNodesOnPart
4741 //=======================================================================
4743 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
4744 CORBA::Double Tolerance,
4745 SMESH::array_of_long_array_out GroupsOfNodes)
4746 throw (SALOME::SALOME_Exception)
4751 TIDSortedNodeSet nodes;
4752 prepareIdSource( theObject );
4753 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4755 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4757 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4759 GroupsOfNodes = new SMESH::array_of_long_array;
4760 GroupsOfNodes->length( aListOfListOfNodes.size() );
4761 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4762 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4764 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4765 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4766 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4767 aGroup.length( aListOfNodes.size() );
4768 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4769 aGroup[ j ] = (*lIt)->GetID();
4771 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
4773 << Tolerance << " )";
4775 SMESH_CATCH( SMESH::throwCorbaException );
4778 //================================================================================
4780 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
4781 * ExceptSubMeshOrGroups
4783 //================================================================================
4785 void SMESH_MeshEditor_i::
4786 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
4787 CORBA::Double theTolerance,
4788 SMESH::array_of_long_array_out theGroupsOfNodes,
4789 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups)
4790 throw (SALOME::SALOME_Exception)
4795 TIDSortedNodeSet nodes;
4796 prepareIdSource( theObject );
4797 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4799 for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
4801 TIDSortedNodeSet exceptNodes;
4802 idSourceToNodeSet( theExceptSubMeshOrGroups[i], getMeshDS(), exceptNodes );
4803 TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
4804 for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
4805 nodes.erase( *avoidNode );
4807 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4809 getEditor().FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
4811 theGroupsOfNodes = new SMESH::array_of_long_array;
4812 theGroupsOfNodes->length( aListOfListOfNodes.size() );
4813 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4814 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4816 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4817 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4818 SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
4819 aGroup.length( aListOfNodes.size() );
4820 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4821 aGroup[ j ] = (*lIt)->GetID();
4823 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
4825 << theTolerance << ", "
4826 << theExceptSubMeshOrGroups << " )";
4828 SMESH_CATCH( SMESH::throwCorbaException );
4831 //=======================================================================
4832 //function : MergeNodes
4834 //=======================================================================
4836 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
4837 throw (SALOME::SALOME_Exception)
4842 SMESHDS_Mesh* aMesh = getMeshDS();
4844 TPythonDump aTPythonDump;
4845 aTPythonDump << this << ".MergeNodes([";
4846 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4847 for (int i = 0; i < GroupsOfNodes.length(); i++)
4849 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
4850 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
4851 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
4852 for ( int j = 0; j < aNodeGroup.length(); j++ )
4854 CORBA::Long index = aNodeGroup[ j ];
4855 const SMDS_MeshNode * node = aMesh->FindNode(index);
4857 aListOfNodes.push_back( node );
4859 if ( aListOfNodes.size() < 2 )
4860 aListOfListOfNodes.pop_back();
4862 if ( i > 0 ) aTPythonDump << ", ";
4863 aTPythonDump << aNodeGroup;
4865 getEditor().MergeNodes( aListOfListOfNodes );
4867 aTPythonDump << "])";
4869 declareMeshModified( /*isReComputeSafe=*/false );
4871 SMESH_CATCH( SMESH::throwCorbaException );
4874 //=======================================================================
4875 //function : FindEqualElements
4877 //=======================================================================
4879 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
4880 SMESH::array_of_long_array_out GroupsOfElementsID)
4881 throw (SALOME::SALOME_Exception)
4886 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
4887 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
4889 TIDSortedElemSet elems;
4890 prepareIdSource( theObject );
4891 idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true);
4893 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4894 getEditor().FindEqualElements( elems, aListOfListOfElementsID );
4896 GroupsOfElementsID = new SMESH::array_of_long_array;
4897 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
4899 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt =
4900 aListOfListOfElementsID.begin();
4901 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j)
4903 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
4904 list<int>& listOfIDs = *arraysIt;
4905 aGroup.length( listOfIDs.size() );
4906 list<int>::iterator idIt = listOfIDs.begin();
4907 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k )
4908 aGroup[ k ] = *idIt;
4911 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
4915 SMESH_CATCH( SMESH::throwCorbaException );
4918 //=======================================================================
4919 //function : MergeElements
4921 //=======================================================================
4923 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
4924 throw (SALOME::SALOME_Exception)
4929 TPythonDump aTPythonDump;
4930 aTPythonDump << this << ".MergeElements( [";
4932 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4934 for (int i = 0; i < GroupsOfElementsID.length(); i++) {
4935 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
4936 aListOfListOfElementsID.push_back( list< int >() );
4937 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
4938 for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
4939 CORBA::Long id = anElemsIDGroup[ j ];
4940 aListOfElemsID.push_back( id );
4942 if ( aListOfElemsID.size() < 2 )
4943 aListOfListOfElementsID.pop_back();
4944 if ( i > 0 ) aTPythonDump << ", ";
4945 aTPythonDump << anElemsIDGroup;
4948 getEditor().MergeElements(aListOfListOfElementsID);
4950 declareMeshModified( /*isReComputeSafe=*/true );
4952 aTPythonDump << "] )";
4954 SMESH_CATCH( SMESH::throwCorbaException );
4957 //=======================================================================
4958 //function : MergeEqualElements
4960 //=======================================================================
4962 void SMESH_MeshEditor_i::MergeEqualElements()
4963 throw (SALOME::SALOME_Exception)
4968 getEditor().MergeEqualElements();
4970 declareMeshModified( /*isReComputeSafe=*/true );
4972 TPythonDump() << this << ".MergeEqualElements()";
4974 SMESH_CATCH( SMESH::throwCorbaException );
4977 //=============================================================================
4979 * Move the node to a given point
4981 //=============================================================================
4983 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
4987 throw (SALOME::SALOME_Exception)
4990 initData(/*deleteSearchers=*/false);
4992 const SMDS_MeshNode * node = getMeshDS()->FindNode( NodeID );
4996 if ( theNodeSearcher )
4997 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4999 if ( myIsPreviewMode ) // make preview data
5001 // in a preview mesh, make edges linked to a node
5002 TPreviewMesh& tmpMesh = *getPreviewMesh();
5003 TIDSortedElemSet linkedNodes;
5004 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
5005 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
5006 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
5007 for ( ; nIt != linkedNodes.end(); ++nIt )
5009 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
5010 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
5014 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
5015 // fill preview data
5017 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
5018 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
5020 getMeshDS()->MoveNode(node, x, y, z);
5022 if ( !myIsPreviewMode )
5024 // Update Python script
5025 TPythonDump() << "isDone = " << this << ".MoveNode( "
5026 << NodeID << ", " << TVar(x) << ", " << TVar(y) << ", " << TVar(z) << " )";
5027 declareMeshModified( /*isReComputeSafe=*/false );
5030 SMESH_CATCH( SMESH::throwCorbaException );
5035 //================================================================================
5037 * \brief Return ID of node closest to a given point
5039 //================================================================================
5041 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
5044 throw (SALOME::SALOME_Exception)
5047 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5049 if ( !theNodeSearcher ) {
5050 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
5053 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
5054 return node->GetID();
5056 SMESH_CATCH( SMESH::throwCorbaException );
5060 //================================================================================
5062 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
5063 * move the node closest to the point to point's location and return ID of the node
5065 //================================================================================
5067 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
5070 CORBA::Long theNodeID)
5071 throw (SALOME::SALOME_Exception)
5074 // We keep theNodeSearcher until any mesh modification:
5075 // 1) initData() deletes theNodeSearcher at any edition,
5076 // 2) TSearchersDeleter - at any mesh compute event and mesh change
5078 initData(/*deleteSearchers=*/false);
5080 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5082 int nodeID = theNodeID;
5083 const SMDS_MeshNode* node = getMeshDS()->FindNode( nodeID );
5084 if ( !node ) // preview moving node
5086 if ( !theNodeSearcher ) {
5087 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
5090 node = theNodeSearcher->FindClosestTo( p );
5093 nodeID = node->GetID();
5094 if ( myIsPreviewMode ) // make preview data
5096 // in a preview mesh, make edges linked to a node
5097 TPreviewMesh tmpMesh = *getPreviewMesh();
5098 TIDSortedElemSet linkedNodes;
5099 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
5100 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
5101 for ( ; nIt != linkedNodes.end(); ++nIt )
5103 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
5104 tmpMesh.Copy( &edge );
5107 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
5109 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
5110 // fill preview data
5112 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
5114 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
5118 getMeshDS()->MoveNode(node, x, y, z);
5122 if ( !myIsPreviewMode )
5124 TPythonDump() << "nodeID = " << this
5125 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
5126 << ", " << nodeID << " )";
5128 declareMeshModified( /*isReComputeSafe=*/false );
5133 SMESH_CATCH( SMESH::throwCorbaException );
5137 //=======================================================================
5139 * Return elements of given type where the given point is IN or ON.
5141 * 'ALL' type means elements of any type excluding nodes
5143 //=======================================================================
5145 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
5148 SMESH::ElementType type)
5149 throw (SALOME::SALOME_Exception)
5152 SMESH::long_array_var res = new SMESH::long_array;
5153 vector< const SMDS_MeshElement* > foundElems;
5155 theSearchersDeleter.Set( myMesh );
5156 if ( !theElementSearcher ) {
5157 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
5159 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
5160 SMDSAbs_ElementType( type ),
5162 res->length( foundElems.size() );
5163 for ( int i = 0; i < foundElems.size(); ++i )
5164 res[i] = foundElems[i]->GetID();
5166 if ( !myIsPreviewMode ) // call from tui
5167 TPythonDump() << "res = " << this << ".FindElementsByPoint( "
5175 SMESH_CATCH( SMESH::throwCorbaException );
5179 //=======================================================================
5180 //function : FindAmongElementsByPoint
5181 //purpose : Searching among the given elements, return elements of given type
5182 // where the given point is IN or ON.
5183 // 'ALL' type means elements of any type excluding nodes
5184 //=======================================================================
5187 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
5191 SMESH::ElementType type)
5192 throw (SALOME::SALOME_Exception)
5195 SMESH::long_array_var res = new SMESH::long_array;
5197 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
5198 if ( types->length() == 1 && // a part contains only nodes or 0D elements
5199 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) &&
5200 type != types[0] ) // but search of elements of dim > 0
5203 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
5204 return FindElementsByPoint( x,y,z, type );
5206 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
5208 theSearchersDeleter.Set( myMesh, getPartIOR( elementIDs, type ));
5209 if ( !theElementSearcher )
5211 // create a searcher from elementIDs
5212 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
5213 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
5215 if ( !idSourceToSet( elementIDs, meshDS, elements,
5216 SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
5219 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5220 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
5222 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt );
5225 vector< const SMDS_MeshElement* > foundElems;
5227 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
5228 SMDSAbs_ElementType( type ),
5230 res->length( foundElems.size() );
5231 for ( int i = 0; i < foundElems.size(); ++i )
5232 res[i] = foundElems[i]->GetID();
5234 if ( !myIsPreviewMode ) // call from tui
5235 TPythonDump() << "res = " << this << ".FindAmongElementsByPoint( "
5236 << elementIDs << ", "
5244 SMESH_CATCH( SMESH::throwCorbaException );
5248 //=======================================================================
5249 //function : GetPointState
5250 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
5251 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
5252 //=======================================================================
5254 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
5257 throw (SALOME::SALOME_Exception)
5260 theSearchersDeleter.Set( myMesh );
5261 if ( !theElementSearcher ) {
5262 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
5264 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
5266 SMESH_CATCH( SMESH::throwCorbaException );
5270 //=======================================================================
5271 //function : convError
5273 //=======================================================================
5275 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
5277 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
5281 RETCASE( SEW_BORDER1_NOT_FOUND );
5282 RETCASE( SEW_BORDER2_NOT_FOUND );
5283 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
5284 RETCASE( SEW_BAD_SIDE_NODES );
5285 RETCASE( SEW_VOLUMES_TO_SPLIT );
5286 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
5287 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
5288 RETCASE( SEW_BAD_SIDE1_NODES );
5289 RETCASE( SEW_BAD_SIDE2_NODES );
5291 return SMESH::SMESH_MeshEditor::SEW_OK;
5294 //=======================================================================
5295 //function : SewFreeBorders
5297 //=======================================================================
5299 SMESH::SMESH_MeshEditor::Sew_Error
5300 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
5301 CORBA::Long SecondNodeID1,
5302 CORBA::Long LastNodeID1,
5303 CORBA::Long FirstNodeID2,
5304 CORBA::Long SecondNodeID2,
5305 CORBA::Long LastNodeID2,
5306 CORBA::Boolean CreatePolygons,
5307 CORBA::Boolean CreatePolyedrs)
5308 throw (SALOME::SALOME_Exception)
5313 SMESHDS_Mesh* aMesh = getMeshDS();
5315 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
5316 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
5317 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
5318 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
5319 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
5320 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
5322 if (!aBorderFirstNode ||
5323 !aBorderSecondNode||
5325 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5326 if (!aSide2FirstNode ||
5327 !aSide2SecondNode ||
5329 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
5331 TPythonDump() << "error = " << this << ".SewFreeBorders( "
5332 << FirstNodeID1 << ", "
5333 << SecondNodeID1 << ", "
5334 << LastNodeID1 << ", "
5335 << FirstNodeID2 << ", "
5336 << SecondNodeID2 << ", "
5337 << LastNodeID2 << ", "
5338 << CreatePolygons<< ", "
5339 << CreatePolyedrs<< " )";
5341 SMESH::SMESH_MeshEditor::Sew_Error error =
5342 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5353 declareMeshModified( /*isReComputeSafe=*/false );
5356 SMESH_CATCH( SMESH::throwCorbaException );
5357 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5361 //=======================================================================
5362 //function : SewConformFreeBorders
5364 //=======================================================================
5366 SMESH::SMESH_MeshEditor::Sew_Error
5367 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
5368 CORBA::Long SecondNodeID1,
5369 CORBA::Long LastNodeID1,
5370 CORBA::Long FirstNodeID2,
5371 CORBA::Long SecondNodeID2)
5372 throw (SALOME::SALOME_Exception)
5377 SMESHDS_Mesh* aMesh = getMeshDS();
5379 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
5380 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
5381 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
5382 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
5383 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
5384 const SMDS_MeshNode* aSide2ThirdNode = 0;
5386 if (!aBorderFirstNode ||
5387 !aBorderSecondNode||
5389 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5390 if (!aSide2FirstNode ||
5392 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
5394 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
5395 << FirstNodeID1 << ", "
5396 << SecondNodeID1 << ", "
5397 << LastNodeID1 << ", "
5398 << FirstNodeID2 << ", "
5399 << SecondNodeID2 << " )";
5401 SMESH::SMESH_MeshEditor::Sew_Error error =
5402 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5411 declareMeshModified( /*isReComputeSafe=*/false );
5414 SMESH_CATCH( SMESH::throwCorbaException );
5415 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5419 //=======================================================================
5420 //function : SewBorderToSide
5422 //=======================================================================
5424 SMESH::SMESH_MeshEditor::Sew_Error
5425 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
5426 CORBA::Long SecondNodeIDOnFreeBorder,
5427 CORBA::Long LastNodeIDOnFreeBorder,
5428 CORBA::Long FirstNodeIDOnSide,
5429 CORBA::Long LastNodeIDOnSide,
5430 CORBA::Boolean CreatePolygons,
5431 CORBA::Boolean CreatePolyedrs)
5432 throw (SALOME::SALOME_Exception)
5437 SMESHDS_Mesh* aMesh = getMeshDS();
5439 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
5440 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
5441 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
5442 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
5443 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
5444 const SMDS_MeshNode* aSide2ThirdNode = 0;
5446 if (!aBorderFirstNode ||
5447 !aBorderSecondNode||
5449 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5450 if (!aSide2FirstNode ||
5452 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
5454 TPythonDump() << "error = " << this << ".SewBorderToSide( "
5455 << FirstNodeIDOnFreeBorder << ", "
5456 << SecondNodeIDOnFreeBorder << ", "
5457 << LastNodeIDOnFreeBorder << ", "
5458 << FirstNodeIDOnSide << ", "
5459 << LastNodeIDOnSide << ", "
5460 << CreatePolygons << ", "
5461 << CreatePolyedrs << ") ";
5463 SMESH::SMESH_MeshEditor::Sew_Error error =
5464 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5474 declareMeshModified( /*isReComputeSafe=*/false );
5477 SMESH_CATCH( SMESH::throwCorbaException );
5478 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5482 //=======================================================================
5483 //function : SewSideElements
5485 //=======================================================================
5487 SMESH::SMESH_MeshEditor::Sew_Error
5488 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
5489 const SMESH::long_array& IDsOfSide2Elements,
5490 CORBA::Long NodeID1OfSide1ToMerge,
5491 CORBA::Long NodeID1OfSide2ToMerge,
5492 CORBA::Long NodeID2OfSide1ToMerge,
5493 CORBA::Long NodeID2OfSide2ToMerge)
5494 throw (SALOME::SALOME_Exception)
5499 SMESHDS_Mesh* aMesh = getMeshDS();
5501 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
5502 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
5503 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
5504 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
5506 if (!aFirstNode1ToMerge ||
5507 !aFirstNode2ToMerge )
5508 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
5509 if (!aSecondNode1ToMerge||
5510 !aSecondNode2ToMerge)
5511 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
5513 TIDSortedElemSet aSide1Elems, aSide2Elems;
5514 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
5515 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
5517 TPythonDump() << "error = " << this << ".SewSideElements( "
5518 << IDsOfSide1Elements << ", "
5519 << IDsOfSide2Elements << ", "
5520 << NodeID1OfSide1ToMerge << ", "
5521 << NodeID1OfSide2ToMerge << ", "
5522 << NodeID2OfSide1ToMerge << ", "
5523 << NodeID2OfSide2ToMerge << ")";
5525 SMESH::SMESH_MeshEditor::Sew_Error error =
5526 convError( getEditor().SewSideElements (aSide1Elems, aSide2Elems,
5529 aSecondNode1ToMerge,
5530 aSecondNode2ToMerge));
5532 declareMeshModified( /*isReComputeSafe=*/false );
5535 SMESH_CATCH( SMESH::throwCorbaException );
5536 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5539 //================================================================================
5541 * \brief Set new nodes for given element
5542 * \param ide - element id
5543 * \param newIDs - new node ids
5544 * \retval CORBA::Boolean - true if result is OK
5546 //================================================================================
5548 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
5549 const SMESH::long_array& newIDs)
5550 throw (SALOME::SALOME_Exception)
5555 const SMDS_MeshElement* elem = getMeshDS()->FindElement(ide);
5556 if(!elem) return false;
5558 int nbn = newIDs.length();
5560 vector<const SMDS_MeshNode*> aNodes(nbn);
5563 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(newIDs[i]);
5566 aNodes[nbn1] = aNode;
5569 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
5570 << ide << ", " << newIDs << " )";
5572 MESSAGE("ChangeElementNodes");
5573 bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
5575 declareMeshModified( /*isReComputeSafe=*/ !res );
5579 SMESH_CATCH( SMESH::throwCorbaException );
5583 //=======================================================================
5585 * \brief Makes a part of the mesh quadratic or bi-quadratic
5587 //=======================================================================
5589 void SMESH_MeshEditor_i::convertToQuadratic(CORBA::Boolean theForce3d,
5590 CORBA::Boolean theToBiQuad,
5591 SMESH::SMESH_IDSource_ptr theObject)
5592 throw (SALOME::SALOME_Exception)
5595 TIDSortedElemSet elems;
5597 if ( !( elemsOK = CORBA::is_nil( theObject )))
5599 prepareIdSource( theObject );
5600 elemsOK = idSourceToSet( theObject, getMeshDS(), elems,
5601 SMDSAbs_All, /*emptyIfIsMesh=*/true );
5605 if ( !elems.empty() && (*elems.begin())->GetType() == SMDSAbs_Node )
5606 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5608 if ( elems.empty() ) getEditor().ConvertToQuadratic(theForce3d, theToBiQuad);
5609 else getEditor().ConvertToQuadratic(theForce3d, elems, theToBiQuad);
5611 declareMeshModified( /*isReComputeSafe=*/false );
5614 SMESH_CATCH( SMESH::throwCorbaException );
5617 //=======================================================================
5618 //function : ConvertFromQuadratic
5620 //=======================================================================
5622 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
5623 throw (SALOME::SALOME_Exception)
5625 CORBA::Boolean isDone = getEditor().ConvertFromQuadratic();
5626 TPythonDump() << this << ".ConvertFromQuadratic()";
5627 declareMeshModified( /*isReComputeSafe=*/!isDone );
5631 //=======================================================================
5632 //function : ConvertToQuadratic
5634 //=======================================================================
5636 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
5637 throw (SALOME::SALOME_Exception)
5639 convertToQuadratic( theForce3d, false );
5640 TPythonDump() << this << ".ConvertToQuadratic("<<theForce3d<<")";
5643 //================================================================================
5645 * \brief Makes a part of the mesh quadratic
5647 //================================================================================
5649 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
5650 SMESH::SMESH_IDSource_ptr theObject)
5651 throw (SALOME::SALOME_Exception)
5653 convertToQuadratic( theForce3d, false, theObject );
5654 TPythonDump() << this << ".ConvertToQuadraticObject("<<theForce3d<<", "<<theObject<<")";
5657 //================================================================================
5659 * \brief Makes a part of the mesh bi-quadratic
5661 //================================================================================
5663 void SMESH_MeshEditor_i::ConvertToBiQuadratic(CORBA::Boolean theForce3d,
5664 SMESH::SMESH_IDSource_ptr theObject)
5665 throw (SALOME::SALOME_Exception)
5667 convertToQuadratic( theForce3d, true, theObject );
5668 TPythonDump() << this << ".ConvertToBiQuadratic("<<theForce3d<<", "<<theObject<<")";
5671 //================================================================================
5673 * \brief Makes a part of the mesh linear
5675 //================================================================================
5677 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
5678 throw (SALOME::SALOME_Exception)
5684 TIDSortedElemSet elems;
5685 prepareIdSource( theObject );
5686 if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5688 if ( elems.empty() )
5690 ConvertFromQuadratic();
5692 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5694 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5698 getEditor().ConvertFromQuadratic(elems);
5701 declareMeshModified( /*isReComputeSafe=*/false );
5703 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
5705 SMESH_CATCH( SMESH::throwCorbaException );
5708 //=======================================================================
5709 //function : makeMesh
5710 //purpose : create a named imported mesh
5711 //=======================================================================
5713 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
5715 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
5716 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
5717 SALOMEDS::Study_var study = gen->GetCurrentStudy();
5718 SALOMEDS::SObject_wrap meshSO = gen->ObjectToSObject( study, mesh );
5719 gen->SetName( meshSO, theMeshName, "Mesh" );
5720 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
5722 return mesh._retn();
5725 //=======================================================================
5726 //function : dumpGroupsList
5728 //=======================================================================
5730 void SMESH_MeshEditor_i::dumpGroupsList(TPythonDump & theDumpPython,
5731 const SMESH::ListOfGroups * theGroupList)
5733 bool isDumpGroupList = ( theGroupList && theGroupList->length() > 0 );
5734 if ( isDumpGroupList )
5735 theDumpPython << theGroupList << " = ";
5738 //================================================================================
5740 \brief Generates the unique group name.
5741 \param thePrefix name prefix
5744 //================================================================================
5746 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
5748 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5749 set<string> groupNames;
5751 // Get existing group names
5752 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
5753 SMESH::SMESH_GroupBase_var aGroup = groups[i];
5754 if (CORBA::is_nil(aGroup))
5757 CORBA::String_var name = aGroup->GetName();
5758 groupNames.insert( name.in() );
5762 string name = thePrefix;
5765 while (!groupNames.insert(name).second)
5766 name = SMESH_Comment( thePrefix ) << "_" << index++;
5771 //================================================================================
5773 * \brief Prepare SMESH_IDSource for work
5775 //================================================================================
5777 void SMESH_MeshEditor_i::prepareIdSource(SMESH::SMESH_IDSource_ptr theObject)
5779 if ( SMESH::Filter_i* filter = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5781 SMESH::SMESH_Mesh_var mesh = myMesh_i->_this();
5782 filter->SetMesh( mesh );
5786 //================================================================================
5788 * \brief Duplicates given elements, i.e. creates new elements based on the
5789 * same nodes as the given ones.
5790 * \param theElements - container of elements to duplicate.
5791 * \param theGroupName - a name of group to contain the generated elements.
5792 * If a group with such a name already exists, the new elements
5793 * are added to the existng group, else a new group is created.
5794 * If \a theGroupName is empty, new elements are not added
5796 * \return a group where the new elements are added. NULL if theGroupName == "".
5799 //================================================================================
5801 SMESH::SMESH_Group_ptr
5802 SMESH_MeshEditor_i::DoubleElements(SMESH::SMESH_IDSource_ptr theElements,
5803 const char* theGroupName)
5804 throw (SALOME::SALOME_Exception)
5806 SMESH::SMESH_Group_var newGroup;
5813 TIDSortedElemSet elems;
5814 prepareIdSource( theElements );
5815 if ( idSourceToSet( theElements, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true))
5817 getEditor().DoubleElements( elems );
5819 if ( strlen( theGroupName ) && !getEditor().GetLastCreatedElems().IsEmpty() )
5822 SMESH::ElementType type =
5823 SMESH::ElementType( getEditor().GetLastCreatedElems().Value(1)->GetType() );
5824 // find existing group
5825 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5826 for ( size_t i = 0; i < groups->length(); ++i )
5827 if ( groups[i]->GetType() == type )
5829 CORBA::String_var name = groups[i]->GetName();
5830 if ( strcmp( name, theGroupName ) == 0 ) {
5831 newGroup = SMESH::SMESH_Group::_narrow( groups[i] );
5835 // create a new group
5836 if ( newGroup->_is_nil() )
5837 newGroup = myMesh_i->CreateGroup( type, theGroupName );
5839 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* >( newGroup ))
5841 SMESHDS_Group* groupDS = static_cast< SMESHDS_Group* >( group_i->GetGroupDS() );
5842 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
5843 for ( int i = 1; i <= aSeq.Length(); i++ )
5844 groupDS->SMDSGroup().Add( aSeq(i) );
5849 if ( !newGroup->_is_nil() )
5850 pyDump << newGroup << " = ";
5851 pyDump << this << ".DoubleElements( "
5852 << theElements << ", " << "'" << theGroupName <<"')";
5854 SMESH_CATCH( SMESH::throwCorbaException );
5856 return newGroup._retn();
5859 //================================================================================
5861 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5862 \param theNodes - identifiers of nodes to be doubled
5863 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
5864 nodes. If list of element identifiers is empty then nodes are doubled but
5865 they not assigned to elements
5866 \return TRUE if operation has been completed successfully, FALSE otherwise
5867 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
5869 //================================================================================
5871 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
5872 const SMESH::long_array& theModifiedElems )
5873 throw (SALOME::SALOME_Exception)
5878 list< int > aListOfNodes;
5880 for ( i = 0, n = theNodes.length(); i < n; i++ )
5881 aListOfNodes.push_back( theNodes[ i ] );
5883 list< int > aListOfElems;
5884 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5885 aListOfElems.push_back( theModifiedElems[ i ] );
5887 bool aResult = getEditor().DoubleNodes( aListOfNodes, aListOfElems );
5889 declareMeshModified( /*isReComputeSafe=*/ !aResult );
5891 // Update Python script
5892 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
5896 SMESH_CATCH( SMESH::throwCorbaException );
5900 //================================================================================
5902 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5903 This method provided for convenience works as DoubleNodes() described above.
5904 \param theNodeId - identifier of node to be doubled.
5905 \param theModifiedElems - identifiers of elements to be updated.
5906 \return TRUE if operation has been completed successfully, FALSE otherwise
5907 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
5909 //================================================================================
5911 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
5912 const SMESH::long_array& theModifiedElems )
5913 throw (SALOME::SALOME_Exception)
5916 SMESH::long_array_var aNodes = new SMESH::long_array;
5917 aNodes->length( 1 );
5918 aNodes[ 0 ] = theNodeId;
5920 TPythonDump pyDump; // suppress dump by the next line
5922 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
5924 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
5928 SMESH_CATCH( SMESH::throwCorbaException );
5932 //================================================================================
5934 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5935 This method provided for convenience works as DoubleNodes() described above.
5936 \param theNodes - group of nodes to be doubled.
5937 \param theModifiedElems - group of elements to be updated.
5938 \return TRUE if operation has been completed successfully, FALSE otherwise
5939 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
5941 //================================================================================
5943 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
5944 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5945 throw (SALOME::SALOME_Exception)
5948 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5951 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5952 SMESH::long_array_var aModifiedElems;
5953 if ( !CORBA::is_nil( theModifiedElems ) )
5954 aModifiedElems = theModifiedElems->GetListOfID();
5957 aModifiedElems = new SMESH::long_array;
5958 aModifiedElems->length( 0 );
5961 TPythonDump pyDump; // suppress dump by the next line
5963 bool done = DoubleNodes( aNodes, aModifiedElems );
5965 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
5969 SMESH_CATCH( SMESH::throwCorbaException );
5973 //================================================================================
5975 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5976 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
5977 * \param theNodes - group of nodes to be doubled.
5978 * \param theModifiedElems - group of elements to be updated.
5979 * \return a new group with newly created nodes
5980 * \sa DoubleNodeGroup()
5982 //================================================================================
5984 SMESH::SMESH_Group_ptr
5985 SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
5986 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5987 throw (SALOME::SALOME_Exception)
5990 SMESH::SMESH_Group_var aNewGroup;
5992 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5993 return aNewGroup._retn();
5996 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5997 SMESH::long_array_var aModifiedElems;
5998 if ( !CORBA::is_nil( theModifiedElems ) )
5999 aModifiedElems = theModifiedElems->GetListOfID();
6001 aModifiedElems = new SMESH::long_array;
6002 aModifiedElems->length( 0 );
6005 TPythonDump pyDump; // suppress dump by the next line
6007 bool aResult = DoubleNodes( aNodes, aModifiedElems );
6010 // Create group with newly created nodes
6011 SMESH::long_array_var anIds = GetLastCreatedNodes();
6012 if (anIds->length() > 0) {
6013 string anUnindexedName (theNodes->GetName());
6014 string aNewName = generateGroupName(anUnindexedName + "_double");
6015 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6016 aNewGroup->Add(anIds);
6017 pyDump << aNewGroup << " = ";
6021 pyDump << this << ".DoubleNodeGroupNew( " << theNodes << ", "
6022 << theModifiedElems << " )";
6024 return aNewGroup._retn();
6026 SMESH_CATCH( SMESH::throwCorbaException );
6030 //================================================================================
6032 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6033 This method provided for convenience works as DoubleNodes() described above.
6034 \param theNodes - list of groups of nodes to be doubled
6035 \param theModifiedElems - list of groups of elements to be updated.
6036 \return TRUE if operation has been completed successfully, FALSE otherwise
6037 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
6039 //================================================================================
6041 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
6042 const SMESH::ListOfGroups& theModifiedElems )
6043 throw (SALOME::SALOME_Exception)
6048 std::list< int > aNodes;
6050 for ( i = 0, n = theNodes.length(); i < n; i++ )
6052 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
6053 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
6055 SMESH::long_array_var aCurr = aGrp->GetListOfID();
6056 for ( j = 0, m = aCurr->length(); j < m; j++ )
6057 aNodes.push_back( aCurr[ j ] );
6061 std::list< int > anElems;
6062 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
6064 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
6065 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
6067 SMESH::long_array_var aCurr = aGrp->GetListOfID();
6068 for ( j = 0, m = aCurr->length(); j < m; j++ )
6069 anElems.push_back( aCurr[ j ] );
6073 bool aResult = getEditor().DoubleNodes( aNodes, anElems );
6075 declareMeshModified( /*isReComputeSafe=*/false );
6077 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
6081 SMESH_CATCH( SMESH::throwCorbaException );
6085 //================================================================================
6087 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6088 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
6089 * \param theNodes - group of nodes to be doubled.
6090 * \param theModifiedElems - group of elements to be updated.
6091 * \return a new group with newly created nodes
6092 * \sa DoubleNodeGroups()
6094 //================================================================================
6096 SMESH::SMESH_Group_ptr
6097 SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
6098 const SMESH::ListOfGroups& theModifiedElems )
6099 throw (SALOME::SALOME_Exception)
6101 SMESH::SMESH_Group_var aNewGroup;
6103 TPythonDump pyDump; // suppress dump by the next line
6105 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
6109 // Create group with newly created nodes
6110 SMESH::long_array_var anIds = GetLastCreatedNodes();
6111 if (anIds->length() > 0) {
6112 string anUnindexedName (theNodes[0]->GetName());
6113 string aNewName = generateGroupName(anUnindexedName + "_double");
6114 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6115 aNewGroup->Add(anIds);
6116 pyDump << aNewGroup << " = ";
6120 pyDump << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
6121 << theModifiedElems << " )";
6123 return aNewGroup._retn();
6127 //================================================================================
6129 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6130 \param theElems - the list of elements (edges or faces) to be replicated
6131 The nodes for duplication could be found from these elements
6132 \param theNodesNot - list of nodes to NOT replicate
6133 \param theAffectedElems - the list of elements (cells and edges) to which the
6134 replicated nodes should be associated to.
6135 \return TRUE if operation has been completed successfully, FALSE otherwise
6136 \sa DoubleNodeGroup(), DoubleNodeGroups()
6138 //================================================================================
6140 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
6141 const SMESH::long_array& theNodesNot,
6142 const SMESH::long_array& theAffectedElems )
6143 throw (SALOME::SALOME_Exception)
6148 SMESHDS_Mesh* aMeshDS = getMeshDS();
6149 TIDSortedElemSet anElems, aNodes, anAffected;
6150 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
6151 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
6152 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
6154 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6156 // Update Python script
6157 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
6158 << theNodesNot << ", " << theAffectedElems << " )";
6160 declareMeshModified( /*isReComputeSafe=*/false );
6163 SMESH_CATCH( SMESH::throwCorbaException );
6167 //================================================================================
6169 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6170 \param theElems - the list of elements (edges or faces) to be replicated
6171 The nodes for duplication could be found from these elements
6172 \param theNodesNot - list of nodes to NOT replicate
6173 \param theShape - shape to detect affected elements (element which geometric center
6174 located on or inside shape).
6175 The replicated nodes should be associated to affected elements.
6176 \return TRUE if operation has been completed successfully, FALSE otherwise
6177 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
6179 //================================================================================
6181 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
6182 const SMESH::long_array& theNodesNot,
6183 GEOM::GEOM_Object_ptr theShape )
6184 throw (SALOME::SALOME_Exception)
6190 SMESHDS_Mesh* aMeshDS = getMeshDS();
6191 TIDSortedElemSet anElems, aNodes;
6192 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
6193 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
6195 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6196 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6198 // Update Python script
6199 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
6200 << theNodesNot << ", " << theShape << " )";
6202 declareMeshModified( /*isReComputeSafe=*/false );
6205 SMESH_CATCH( SMESH::throwCorbaException );
6209 //================================================================================
6211 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6212 \param theElems - group of of elements (edges or faces) to be replicated
6213 \param theNodesNot - group of nodes not to replicated
6214 \param theAffectedElems - group of elements to which the replicated nodes
6215 should be associated to.
6216 \return TRUE if operation has been completed successfully, FALSE otherwise
6217 \sa DoubleNodes(), DoubleNodeGroups()
6219 //================================================================================
6222 SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
6223 SMESH::SMESH_GroupBase_ptr theNodesNot,
6224 SMESH::SMESH_GroupBase_ptr theAffectedElems)
6225 throw (SALOME::SALOME_Exception)
6228 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6234 SMESHDS_Mesh* aMeshDS = getMeshDS();
6235 TIDSortedElemSet anElems, aNodes, anAffected;
6236 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6237 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6238 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
6240 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6242 // Update Python script
6243 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
6244 << theNodesNot << ", " << theAffectedElems << " )";
6246 declareMeshModified( /*isReComputeSafe=*/false );
6249 SMESH_CATCH( SMESH::throwCorbaException );
6253 //================================================================================
6255 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6256 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
6257 * \param theElems - group of of elements (edges or faces) to be replicated
6258 * \param theNodesNot - group of nodes not to replicated
6259 * \param theAffectedElems - group of elements to which the replicated nodes
6260 * should be associated to.
6261 * \return a new group with newly created elements
6262 * \sa DoubleNodeElemGroup()
6264 //================================================================================
6266 SMESH::SMESH_Group_ptr
6267 SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
6268 SMESH::SMESH_GroupBase_ptr theNodesNot,
6269 SMESH::SMESH_GroupBase_ptr theAffectedElems)
6270 throw (SALOME::SALOME_Exception)
6273 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroup2New( theElems,
6277 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
6278 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
6280 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupNew( "
6282 << theNodesNot << ", "
6283 << theAffectedElems << " )";
6285 return elemGroup._retn();
6288 //================================================================================
6290 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6291 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
6292 * \param theElems - group of of elements (edges or faces) to be replicated
6293 * \param theNodesNot - group of nodes not to replicated
6294 * \param theAffectedElems - group of elements to which the replicated nodes
6295 * should be associated to.
6296 * \return a new group with newly created elements
6297 * \sa DoubleNodeElemGroup()
6299 //================================================================================
6301 SMESH::ListOfGroups*
6302 SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
6303 SMESH::SMESH_GroupBase_ptr theNodesNot,
6304 SMESH::SMESH_GroupBase_ptr theAffectedElems,
6305 CORBA::Boolean theElemGroupNeeded,
6306 CORBA::Boolean theNodeGroupNeeded)
6307 throw (SALOME::SALOME_Exception)
6310 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
6311 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
6312 aTwoGroups->length( 2 );
6314 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6315 return aTwoGroups._retn();
6320 SMESHDS_Mesh* aMeshDS = getMeshDS();
6321 TIDSortedElemSet anElems, aNodes, anAffected;
6322 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6323 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6324 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
6327 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6329 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6335 // Create group with newly created elements
6336 CORBA::String_var elemGroupName = theElems->GetName();
6337 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
6338 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
6340 SMESH::long_array_var anIds = GetLastCreatedElems();
6341 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
6342 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
6343 aNewElemGroup->Add(anIds);
6345 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
6347 SMESH::long_array_var anIds = GetLastCreatedNodes();
6348 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6349 aNewNodeGroup->Add(anIds);
6353 // Update Python script
6356 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
6357 else pyDump << aNewElemGroup << ", ";
6358 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
6359 else pyDump << aNewNodeGroup << " ] = ";
6361 pyDump << this << ".DoubleNodeElemGroup2New( " << theElems << ", "
6362 << theNodesNot << ", "
6363 << theAffectedElems << ", "
6364 << theElemGroupNeeded << ", "
6365 << theNodeGroupNeeded <<" )";
6367 aTwoGroups[0] = aNewElemGroup._retn();
6368 aTwoGroups[1] = aNewNodeGroup._retn();
6369 return aTwoGroups._retn();
6371 SMESH_CATCH( SMESH::throwCorbaException );
6375 //================================================================================
6377 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6378 \param theElems - group of of elements (edges or faces) to be replicated
6379 \param theNodesNot - group of nodes not to replicated
6380 \param theShape - shape to detect affected elements (element which geometric center
6381 located on or inside shape).
6382 The replicated nodes should be associated to affected elements.
6383 \return TRUE if operation has been completed successfully, FALSE otherwise
6384 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
6386 //================================================================================
6389 SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
6390 SMESH::SMESH_GroupBase_ptr theNodesNot,
6391 GEOM::GEOM_Object_ptr theShape )
6392 throw (SALOME::SALOME_Exception)
6395 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6401 SMESHDS_Mesh* aMeshDS = getMeshDS();
6402 TIDSortedElemSet anElems, aNodes, anAffected;
6403 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6404 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6406 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6407 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6410 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6412 // Update Python script
6413 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
6414 << theNodesNot << ", " << theShape << " )";
6417 SMESH_CATCH( SMESH::throwCorbaException );
6421 //================================================================================
6423 * \brief Re-load elements from a list of groups into a TIDSortedElemSet
6424 * \param [in] theGrpList - groups
6425 * \param [in] theMeshDS - mesh
6426 * \param [out] theElemSet - set of elements
6427 * \param [in] theIsNodeGrp - is \a theGrpList includes goups of nodes
6429 //================================================================================
6431 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
6432 SMESHDS_Mesh* theMeshDS,
6433 TIDSortedElemSet& theElemSet,
6434 const bool theIsNodeGrp)
6436 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
6438 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
6439 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
6440 : aGrp->GetType() != SMESH::NODE ) )
6442 SMESH::long_array_var anIDs = aGrp->GetIDs();
6443 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
6448 //================================================================================
6450 \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6451 This method provided for convenience works as DoubleNodes() described above.
6452 \param theElems - list of groups of elements (edges or faces) to be replicated
6453 \param theNodesNot - list of groups of nodes not to replicated
6454 \param theAffectedElems - group of elements to which the replicated nodes
6455 should be associated to.
6456 \return TRUE if operation has been completed successfully, FALSE otherwise
6457 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
6459 //================================================================================
6462 SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
6463 const SMESH::ListOfGroups& theNodesNot,
6464 const SMESH::ListOfGroups& theAffectedElems)
6465 throw (SALOME::SALOME_Exception)
6471 SMESHDS_Mesh* aMeshDS = getMeshDS();
6472 TIDSortedElemSet anElems, aNodes, anAffected;
6473 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6474 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6475 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6477 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6479 // Update Python script
6480 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
6481 << &theNodesNot << ", " << &theAffectedElems << " )";
6483 declareMeshModified( /*isReComputeSafe=*/false );
6486 SMESH_CATCH( SMESH::throwCorbaException );
6490 //================================================================================
6492 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6493 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6494 \param theElems - list of groups of elements (edges or faces) to be replicated
6495 \param theNodesNot - list of groups of nodes not to replicated
6496 \param theAffectedElems - group of elements to which the replicated nodes
6497 should be associated to.
6498 * \return a new group with newly created elements
6499 * \sa DoubleNodeElemGroups()
6501 //================================================================================
6503 SMESH::SMESH_Group_ptr
6504 SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
6505 const SMESH::ListOfGroups& theNodesNot,
6506 const SMESH::ListOfGroups& theAffectedElems)
6507 throw (SALOME::SALOME_Exception)
6510 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroups2New( theElems,
6514 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
6515 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
6517 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupsNew( "
6519 << theNodesNot << ", "
6520 << theAffectedElems << " )";
6522 return elemGroup._retn();
6525 //================================================================================
6527 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6528 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6529 \param theElems - list of groups of elements (edges or faces) to be replicated
6530 \param theNodesNot - list of groups of nodes not to replicated
6531 \param theAffectedElems - group of elements to which the replicated nodes
6532 should be associated to.
6533 * \return a new group with newly created elements
6534 * \sa DoubleNodeElemGroups()
6536 //================================================================================
6538 SMESH::ListOfGroups*
6539 SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems,
6540 const SMESH::ListOfGroups& theNodesNot,
6541 const SMESH::ListOfGroups& theAffectedElems,
6542 CORBA::Boolean theElemGroupNeeded,
6543 CORBA::Boolean theNodeGroupNeeded)
6544 throw (SALOME::SALOME_Exception)
6547 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
6548 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
6549 aTwoGroups->length( 2 );
6554 SMESHDS_Mesh* aMeshDS = getMeshDS();
6555 TIDSortedElemSet anElems, aNodes, anAffected;
6556 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6557 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6558 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6560 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6562 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6567 // Create group with newly created elements
6568 CORBA::String_var elemGroupName = theElems[0]->GetName();
6569 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
6570 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
6572 SMESH::long_array_var anIds = GetLastCreatedElems();
6573 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
6574 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
6575 aNewElemGroup->Add(anIds);
6577 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
6579 SMESH::long_array_var anIds = GetLastCreatedNodes();
6580 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6581 aNewNodeGroup->Add(anIds);
6585 // Update Python script
6588 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
6589 else pyDump << aNewElemGroup << ", ";
6590 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
6591 else pyDump << aNewNodeGroup << " ] = ";
6593 pyDump << this << ".DoubleNodeElemGroups2New( " << &theElems << ", "
6594 << &theNodesNot << ", "
6595 << &theAffectedElems << ", "
6596 << theElemGroupNeeded << ", "
6597 << theNodeGroupNeeded << " )";
6599 aTwoGroups[0] = aNewElemGroup._retn();
6600 aTwoGroups[1] = aNewNodeGroup._retn();
6601 return aTwoGroups._retn();
6603 SMESH_CATCH( SMESH::throwCorbaException );
6607 //================================================================================
6609 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6610 This method provided for convenience works as DoubleNodes() described above.
6611 \param theElems - list of groups of elements (edges or faces) to be replicated
6612 \param theNodesNot - list of groups of nodes not to replicated
6613 \param theShape - shape to detect affected elements (element which geometric center
6614 located on or inside shape).
6615 The replicated nodes should be associated to affected elements.
6616 \return TRUE if operation has been completed successfully, FALSE otherwise
6617 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
6619 //================================================================================
6622 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
6623 const SMESH::ListOfGroups& theNodesNot,
6624 GEOM::GEOM_Object_ptr theShape )
6625 throw (SALOME::SALOME_Exception)
6631 SMESHDS_Mesh* aMeshDS = getMeshDS();
6632 TIDSortedElemSet anElems, aNodes;
6633 listOfGroupToSet(theElems, aMeshDS, anElems,false );
6634 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6636 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6637 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6639 // Update Python script
6640 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
6641 << &theNodesNot << ", " << theShape << " )";
6643 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6646 SMESH_CATCH( SMESH::throwCorbaException );
6650 //================================================================================
6652 \brief Identify the elements that will be affected by node duplication (actual
6653 duplication is not performed.
6654 This method is the first step of DoubleNodeElemGroupsInRegion.
6655 \param theElems - list of groups of elements (edges or faces) to be replicated
6656 \param theNodesNot - list of groups of nodes not to replicated
6657 \param theShape - shape to detect affected elements (element which geometric center
6658 located on or inside shape).
6659 The replicated nodes should be associated to affected elements.
6660 \return groups of affected elements
6661 \sa DoubleNodeElemGroupsInRegion()
6663 //================================================================================
6664 SMESH::ListOfGroups*
6665 SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theElems,
6666 const SMESH::ListOfGroups& theNodesNot,
6667 GEOM::GEOM_Object_ptr theShape )
6668 throw (SALOME::SALOME_Exception)
6671 MESSAGE("AffectedElemGroupsInRegion");
6672 SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
6673 bool isEdgeGroup = false;
6674 bool isFaceGroup = false;
6675 bool isVolumeGroup = false;
6676 SMESH::SMESH_Group_var aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE, "affectedEdges");
6677 SMESH::SMESH_Group_var aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE, "affectedFaces");
6678 SMESH::SMESH_Group_var aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME, "affectedVolumes");
6682 ::SMESH_MeshEditor aMeshEditor(myMesh);
6684 SMESHDS_Mesh* aMeshDS = getMeshDS();
6685 TIDSortedElemSet anElems, aNodes;
6686 listOfGroupToSet(theElems, aMeshDS, anElems, false);
6687 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true);
6689 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape(theShape);
6690 TIDSortedElemSet anAffected;
6691 bool aResult = aMeshEditor.AffectedElemGroupsInRegion(anElems, aNodes, aShape, anAffected);
6694 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6699 int lg = anAffected.size();
6700 MESSAGE("lg="<< lg);
6701 SMESH::long_array_var volumeIds = new SMESH::long_array;
6702 volumeIds->length(lg);
6703 SMESH::long_array_var faceIds = new SMESH::long_array;
6704 faceIds->length(lg);
6705 SMESH::long_array_var edgeIds = new SMESH::long_array;
6706 edgeIds->length(lg);
6711 TIDSortedElemSet::const_iterator eIt = anAffected.begin();
6712 for (; eIt != anAffected.end(); ++eIt)
6714 const SMDS_MeshElement* anElem = *eIt;
6717 int elemId = anElem->GetID();
6718 if (myMesh->GetElementType(elemId, true) == SMDSAbs_Volume)
6719 volumeIds[ivol++] = elemId;
6720 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Face)
6721 faceIds[iface++] = elemId;
6722 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Edge)
6723 edgeIds[iedge++] = elemId;
6725 volumeIds->length(ivol);
6726 faceIds->length(iface);
6727 edgeIds->length(iedge);
6729 aNewVolumeGroup->Add(volumeIds);
6730 aNewFaceGroup->Add(faceIds);
6731 aNewEdgeGroup->Add(edgeIds);
6732 isVolumeGroup = (aNewVolumeGroup->Size() > 0);
6733 isFaceGroup = (aNewFaceGroup->Size() > 0);
6734 isEdgeGroup = (aNewEdgeGroup->Size() > 0);
6738 if (isEdgeGroup) nbGroups++;
6739 if (isFaceGroup) nbGroups++;
6740 if (isVolumeGroup) nbGroups++;
6741 aListOfGroups->length(nbGroups);
6744 if (isEdgeGroup) aListOfGroups[i++] = aNewEdgeGroup._retn();
6745 if (isFaceGroup) aListOfGroups[i++] = aNewFaceGroup._retn();
6746 if (isVolumeGroup) aListOfGroups[i++] = aNewVolumeGroup._retn();
6748 // Update Python script
6751 if (isEdgeGroup) pyDump << aNewEdgeGroup << ", ";
6752 if (isFaceGroup) pyDump << aNewFaceGroup << ", ";
6753 if (isVolumeGroup) pyDump << aNewVolumeGroup << ", ";
6755 pyDump << this << ".AffectedElemGroupsInRegion( "
6756 << &theElems << ", " << &theNodesNot << ", " << theShape << " )";
6758 return aListOfGroups._retn();
6760 SMESH_CATCH( SMESH::throwCorbaException );
6764 //================================================================================
6766 \brief Generated skin mesh (containing 2D cells) from 3D mesh
6767 The created 2D mesh elements based on nodes of free faces of boundary volumes
6768 \return TRUE if operation has been completed successfully, FALSE otherwise
6770 //================================================================================
6772 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
6773 throw (SALOME::SALOME_Exception)
6778 bool aResult = getEditor().Make2DMeshFrom3D();
6780 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
6782 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6785 SMESH_CATCH( SMESH::throwCorbaException );
6789 //================================================================================
6791 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
6792 * The list of groups must contain at least two groups. The groups have to be disjoint:
6793 * no common element into two different groups.
6794 * The nodes of the internal faces at the boundaries of the groups are doubled.
6795 * Optionally, the internal faces are replaced by flat elements.
6796 * Triangles are transformed into prisms, and quadrangles into hexahedrons.
6797 * The flat elements are stored in groups of volumes.
6798 * These groups are named according to the position of the group in the list:
6799 * 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.
6800 * 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.
6801 * All the flat elements are gathered into the group named "joints3D" (or "joints2D" in 2D situation).
6802 * The flat element of the multiple junctions between the simple junction are stored in a group named "jointsMultiples".
6803 * @param theDomains - list of groups of volumes
6804 * @param createJointElems - if TRUE, create the elements
6805 * @return TRUE if operation has been completed successfully, FALSE otherwise
6807 //================================================================================
6810 SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
6811 CORBA::Boolean createJointElems )
6812 throw (SALOME::SALOME_Exception)
6814 bool aResult = false;
6819 SMESHDS_Mesh* aMeshDS = getMeshDS();
6821 // MESSAGE("theDomains.length = "<<theDomains.length());
6822 if ( theDomains.length() <= 1 )
6823 THROW_SALOME_CORBA_EXCEPTION("At least 2 groups are required.", SALOME::BAD_PARAM);
6824 vector<TIDSortedElemSet> domains;
6827 for ( int i = 0, n = theDomains.length(); i < n; i++ )
6829 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
6830 if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
6832 // if ( aGrp->GetType() != SMESH::VOLUME )
6833 // THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
6834 TIDSortedElemSet domain;
6836 domains.push_back(domain);
6837 SMESH::long_array_var anIDs = aGrp->GetIDs();
6838 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
6842 aResult = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems );
6843 // TODO publish the groups of flat elements in study
6845 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6847 // Update Python script
6848 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
6849 << ", " << createJointElems << " )";
6851 SMESH_CATCH( SMESH::throwCorbaException );
6856 //================================================================================
6858 * \brief Double nodes on some external faces and create flat elements.
6859 * Flat elements are mainly used by some types of mechanic calculations.
6861 * Each group of the list must be constituted of faces.
6862 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
6863 * @param theGroupsOfFaces - list of groups of faces
6864 * @return TRUE if operation has been completed successfully, FALSE otherwise
6866 //================================================================================
6869 SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
6870 throw (SALOME::SALOME_Exception)
6875 SMESHDS_Mesh* aMeshDS = getMeshDS();
6877 vector<TIDSortedElemSet> faceGroups;
6880 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
6882 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
6883 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
6885 TIDSortedElemSet faceGroup;
6887 faceGroups.push_back(faceGroup);
6888 SMESH::long_array_var anIDs = aGrp->GetIDs();
6889 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
6893 bool aResult = getEditor().CreateFlatElementsOnFacesGroups( faceGroups );
6894 // TODO publish the groups of flat elements in study
6896 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6898 // Update Python script
6899 TPythonDump() << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
6902 SMESH_CATCH( SMESH::throwCorbaException );
6906 //================================================================================
6908 * \brief Identify all the elements around a geom shape, get the faces delimiting
6911 * Build groups of volume to remove, groups of faces to replace on the skin of the
6912 * object, groups of faces to remove inside the object, (idem edges).
6913 * Build ordered list of nodes at the border of each group of faces to replace
6914 * (to be used to build a geom subshape).
6916 //================================================================================
6918 void SMESH_MeshEditor_i::CreateHoleSkin(CORBA::Double radius,
6919 GEOM::GEOM_Object_ptr theShape,
6920 const char* groupName,
6921 const SMESH::double_array& theNodesCoords,
6922 SMESH::array_of_long_array_out GroupsOfNodes)
6923 throw (SALOME::SALOME_Exception)
6928 std::vector<std::vector<int> > aListOfListOfNodes;
6929 ::SMESH_MeshEditor aMeshEditor( myMesh );
6931 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
6932 if ( !theNodeSearcher )
6933 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
6935 vector<double> nodesCoords;
6936 for (int i = 0; i < theNodesCoords.length(); i++)
6938 nodesCoords.push_back( theNodesCoords[i] );
6941 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6942 aMeshEditor.CreateHoleSkin(radius, aShape, theNodeSearcher, groupName,
6943 nodesCoords, aListOfListOfNodes);
6945 GroupsOfNodes = new SMESH::array_of_long_array;
6946 GroupsOfNodes->length( aListOfListOfNodes.size() );
6947 std::vector<std::vector<int> >::iterator llIt = aListOfListOfNodes.begin();
6948 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
6950 vector<int>& aListOfNodes = *llIt;
6951 vector<int>::iterator lIt = aListOfNodes.begin();;
6952 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
6953 aGroup.length( aListOfNodes.size() );
6954 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
6955 aGroup[ j ] = (*lIt);
6957 TPythonDump() << "lists_nodes = " << this << ".CreateHoleSkin( "
6960 << ", '" << groupName << "', "
6961 << theNodesCoords << " )";
6963 SMESH_CATCH( SMESH::throwCorbaException );
6966 // issue 20749 ===================================================================
6968 * \brief Creates missing boundary elements
6969 * \param elements - elements whose boundary is to be checked
6970 * \param dimension - defines type of boundary elements to create
6971 * \param groupName - a name of group to store created boundary elements in,
6972 * "" means not to create the group
6973 * \param meshName - a name of new mesh to store created boundary elements in,
6974 * "" means not to create the new mesh
6975 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
6976 * \param toCopyExistingBondary - if true, not only new but also pre-existing
6977 * boundary elements will be copied into the new mesh
6978 * \param group - returns the create group, if any
6979 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
6981 // ================================================================================
6983 SMESH::SMESH_Mesh_ptr
6984 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
6985 SMESH::Bnd_Dimension dim,
6986 const char* groupName,
6987 const char* meshName,
6988 CORBA::Boolean toCopyElements,
6989 CORBA::Boolean toCopyExistingBondary,
6990 SMESH::SMESH_Group_out group)
6991 throw (SALOME::SALOME_Exception)
6996 if ( dim > SMESH::BND_1DFROM2D )
6997 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
6999 SMESHDS_Mesh* aMeshDS = getMeshDS();
7001 SMESH::SMESH_Mesh_var mesh_var;
7002 SMESH::SMESH_Group_var group_var;
7006 TIDSortedElemSet elements;
7007 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
7008 prepareIdSource( idSource );
7009 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
7013 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
7014 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
7016 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
7018 // group of new boundary elements
7019 SMESH_Group* smesh_group = 0;
7020 if ( strlen(groupName) )
7022 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
7023 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
7024 smesh_group = group_i->GetSmeshGroup();
7028 getEditor().MakeBoundaryMesh( elements,
7029 ::SMESH_MeshEditor::Bnd_Dimension(dim),
7033 toCopyExistingBondary);
7036 smesh_mesh->GetMeshDS()->Modified();
7039 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
7041 // result of MakeBoundaryMesh() is a tuple (mesh, group)
7042 if ( mesh_var->_is_nil() )
7043 pyDump << myMesh_i->_this() << ", ";
7045 pyDump << mesh_var << ", ";
7046 if ( group_var->_is_nil() )
7047 pyDump << "_NoneGroup = "; // assignment to None is forbiden
7049 pyDump << group_var << " = ";
7050 pyDump << this << ".MakeBoundaryMesh( "
7052 << "SMESH." << dimName[int(dim)] << ", "
7053 << "'" << groupName << "', "
7054 << "'" << meshName<< "', "
7055 << toCopyElements << ", "
7056 << toCopyExistingBondary << ")";
7058 group = group_var._retn();
7059 return mesh_var._retn();
7061 SMESH_CATCH( SMESH::throwCorbaException );
7062 return SMESH::SMESH_Mesh::_nil();
7065 //================================================================================
7067 * \brief Creates missing boundary elements
7068 * \param dimension - defines type of boundary elements to create
7069 * \param groupName - a name of group to store all boundary elements in,
7070 * "" means not to create the group
7071 * \param meshName - a name of a new mesh, which is a copy of the initial
7072 * mesh + created boundary elements; "" means not to create the new mesh
7073 * \param toCopyAll - if true, the whole initial mesh will be copied into
7074 * the new mesh else only boundary elements will be copied into the new mesh
7075 * \param groups - optional groups of elements to make boundary around
7076 * \param mesh - returns the mesh where elements were added to
7077 * \param group - returns the created group, if any
7078 * \retval long - number of added boundary elements
7080 //================================================================================
7082 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
7083 const char* groupName,
7084 const char* meshName,
7085 CORBA::Boolean toCopyAll,
7086 const SMESH::ListOfIDSources& groups,
7087 SMESH::SMESH_Mesh_out mesh,
7088 SMESH::SMESH_Group_out group)
7089 throw (SALOME::SALOME_Exception)
7094 if ( dim > SMESH::BND_1DFROM2D )
7095 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
7097 // separate groups belonging to this and other mesh
7098 SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
7099 SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
7100 groupsOfThisMesh->length( groups.length() );
7101 groupsOfOtherMesh->length( groups.length() );
7102 int nbGroups = 0, nbGroupsOfOtherMesh = 0;
7103 for ( int i = 0; i < groups.length(); ++i )
7105 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
7106 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
7107 groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
7109 groupsOfThisMesh[ nbGroups++ ] = groups[i];
7110 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
7111 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
7113 groupsOfThisMesh->length( nbGroups );
7114 groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
7119 if ( nbGroupsOfOtherMesh > 0 )
7121 // process groups belonging to another mesh
7122 SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
7123 SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
7124 nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
7125 groupsOfOtherMesh, mesh, group );
7128 SMESH::SMESH_Mesh_var mesh_var;
7129 SMESH::SMESH_Group_var group_var;
7132 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
7133 const bool toCopyMesh = ( strlen( meshName ) > 0 );
7137 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
7139 /*toCopyGroups=*/false,
7140 /*toKeepIDs=*/true);
7142 mesh_var = makeMesh(meshName);
7144 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
7145 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
7148 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
7149 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
7151 // group of boundary elements
7152 SMESH_Group* smesh_group = 0;
7153 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
7154 if ( strlen(groupName) )
7156 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
7157 group_var = mesh_i->CreateGroup( groupType, groupName );
7158 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
7159 smesh_group = group_i->GetSmeshGroup();
7162 TIDSortedElemSet elements;
7164 if ( groups.length() > 0 )
7166 for ( int i = 0; i < nbGroups; ++i )
7169 if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
7171 SMESH::Bnd_Dimension bdim =
7172 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
7173 nbAdded += getEditor().MakeBoundaryMesh( elements,
7174 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
7177 /*toCopyElements=*/false,
7178 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
7179 /*toAddExistingBondary=*/true,
7180 /*aroundElements=*/true);
7186 nbAdded += getEditor().MakeBoundaryMesh( elements,
7187 ::SMESH_MeshEditor::Bnd_Dimension(dim),
7190 /*toCopyElements=*/false,
7191 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
7192 /*toAddExistingBondary=*/true);
7194 tgtMesh->GetMeshDS()->Modified();
7196 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
7198 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
7199 pyDump << "nbAdded, ";
7200 if ( mesh_var->_is_nil() )
7201 pyDump << myMesh_i->_this() << ", ";
7203 pyDump << mesh_var << ", ";
7204 if ( group_var->_is_nil() )
7205 pyDump << "_NoneGroup = "; // assignment to None is forbiden
7207 pyDump << group_var << " = ";
7208 pyDump << this << ".MakeBoundaryElements( "
7209 << "SMESH." << dimName[int(dim)] << ", "
7210 << "'" << groupName << "', "
7211 << "'" << meshName<< "', "
7212 << toCopyAll << ", "
7215 mesh = mesh_var._retn();
7216 group = group_var._retn();
7219 SMESH_CATCH( SMESH::throwCorbaException );