1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_MeshEditor_i.cxx
23 // Author : Nicolas REJNERI
30 // A macro used in SMESH_TryCatch.hxx,
31 // it re-raises a CORBA SALOME exception thrown by SMESH_MeshEditor_i and caught by SMESH_CATCH
32 #define SMY_OWN_CATCH \
33 catch ( SALOME::SALOME_Exception & e ) { throw e; }
35 #include "SMESH_MeshEditor_i.hxx"
37 #include "SMDS_EdgePosition.hxx"
38 #include "SMDS_ElemIterator.hxx"
39 #include "SMDS_FacePosition.hxx"
40 #include "SMDS_IteratorOnIterators.hxx"
41 #include "SMDS_LinearEdge.hxx"
42 #include "SMDS_Mesh0DElement.hxx"
43 #include "SMDS_MeshFace.hxx"
44 #include "SMDS_MeshVolume.hxx"
45 #include "SMDS_SetIterator.hxx"
46 #include "SMDS_VolumeTool.hxx"
47 #include "SMESHDS_Group.hxx"
48 #include "SMESHDS_GroupOnGeom.hxx"
49 #include "SMESH_ControlsDef.hxx"
50 #include "SMESH_Filter_i.hxx"
51 #include "SMESH_Gen_i.hxx"
52 #include "SMESH_Group.hxx"
53 #include "SMESH_Group_i.hxx"
54 #include "SMESH_MeshAlgos.hxx"
55 #include "SMESH_MeshPartDS.hxx"
56 #include "SMESH_MesherHelper.hxx"
57 #include "SMESH_PythonDump.hxx"
58 #include "SMESH_subMeshEventListener.hxx"
59 #include "SMESH_subMesh_i.hxx"
61 #include <utilities.h>
62 #include <Utils_ExceptHandlers.hxx>
63 #include <Utils_CorbaException.hxx>
64 #include <SALOMEDS_wrap.hxx>
65 #include <SALOME_GenericObj_i.hh>
67 #include <BRepAdaptor_Surface.hxx>
68 #include <BRep_Tool.hxx>
69 #include <TopExp_Explorer.hxx>
71 #include <TopoDS_Edge.hxx>
72 #include <TopoDS_Face.hxx>
77 #include <Standard_Failure.hxx>
78 #include <Standard_ErrorHandler.hxx>
83 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
85 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
88 using SMESH::TPythonDump;
91 namespace MeshEditor_I {
93 //=============================================================================
95 * \brief Mesh to apply modifications for preview purposes
97 //=============================================================================
99 struct TPreviewMesh: public SMESH_Mesh
101 SMDSAbs_ElementType myPreviewType; // type to show
103 TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
104 _isShapeToMesh = (_id = 0);
105 _myMeshDS = new SMESHDS_Mesh( _id, true );
106 myPreviewType = previewElements;
108 //!< Copy a set of elements
109 void Copy(const TIDSortedElemSet & theElements,
110 TIDSortedElemSet& theCopyElements,
111 SMDSAbs_ElementType theSelectType = SMDSAbs_All,
112 SMDSAbs_ElementType theAvoidType = SMDSAbs_All)
114 // loop on theIDsOfElements
115 TIDSortedElemSet::const_iterator eIt = theElements.begin();
116 for ( ; eIt != theElements.end(); ++eIt )
118 const SMDS_MeshElement* anElem = *eIt;
119 if ( !anElem ) continue;
120 SMDSAbs_ElementType type = anElem->GetType();
121 if ( type == theAvoidType ||
122 ( theSelectType != SMDSAbs_All && type != theSelectType ))
124 const SMDS_MeshElement* anElemCopy;
125 if ( type == SMDSAbs_Node)
126 anElemCopy = Copy( cast2Node(anElem) );
128 anElemCopy = Copy( anElem );
130 theCopyElements.insert( theCopyElements.end(), anElemCopy );
134 SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
136 // copy element nodes
137 int anElemNbNodes = anElem->NbNodes();
138 vector< int > anElemNodesID( anElemNbNodes ) ;
139 SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
140 for ( int i = 0; itElemNodes->more(); i++)
142 const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
144 anElemNodesID[i] = anElemNode->GetID();
147 // creates a corresponding element on copied nodes
148 ::SMESH_MeshEditor::ElemFeatures elemType;
149 elemType.Init( anElem, /*basicOnly=*/false );
150 elemType.SetID( anElem->GetID() );
151 SMDS_MeshElement* anElemCopy =
152 ::SMESH_MeshEditor(this).AddElement( anElemNodesID, elemType );
156 SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
158 return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(),
159 anElemNode->GetID());
163 GetMeshDS()->ClearMesh();
165 void Remove( SMDSAbs_ElementType type )
167 Remove( GetMeshDS()->elementsIterator( type ));
169 void Remove( SMDS_ElemIteratorPtr eIt )
171 while ( eIt->more() )
172 GetMeshDS()->RemoveFreeElement( eIt->next(), /*sm=*/0, /*fromGroups=*/false );
174 };// struct TPreviewMesh
176 static SMESH_NodeSearcher * theNodeSearcher = 0;
177 static SMESH_ElementSearcher * theElementSearcher = 0;
179 //=============================================================================
181 * \brief Deleter of theNodeSearcher at any compute event occurred
183 //=============================================================================
185 struct TSearchersDeleter : public SMESH_subMeshEventListener
188 string myMeshPartIOR;
190 TSearchersDeleter(): SMESH_subMeshEventListener( false, // won't be deleted by submesh
191 "SMESH_MeshEditor_i::TSearchersDeleter"),
193 //!< Delete theNodeSearcher
196 if ( theNodeSearcher ) delete theNodeSearcher; theNodeSearcher = 0;
197 if ( theElementSearcher ) delete theElementSearcher; theElementSearcher = 0;
199 typedef map < int, SMESH_subMesh * > TDependsOnMap;
200 //!< The meshod called by submesh: do my main job
201 void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
202 SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
204 if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
206 Unset( sm->GetFather() );
209 //!< set self on all submeshes and delete theNodeSearcher if other mesh is set
210 void Set(SMESH_Mesh* mesh, const string& meshPartIOR = string())
212 if ( myMesh != mesh || myMeshPartIOR != meshPartIOR)
219 myMeshPartIOR = meshPartIOR;
220 SMESH_subMesh* sm = mesh->GetSubMesh( mesh->GetShapeToMesh() );
221 SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true );
222 while ( smIt->more() )
225 sm->SetEventListener( this, 0, sm );
229 //!< delete self from all submeshes
230 void Unset(SMESH_Mesh* mesh)
232 if ( SMESH_subMesh* sm = mesh->GetSubMeshContaining(1) ) {
233 SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true );
234 while ( smIt->more() )
235 smIt->next()->DeleteEventListener( this );
240 } theSearchersDeleter;
242 TCollection_AsciiString mirrorTypeName( SMESH::SMESH_MeshEditor::MirrorType theMirrorType )
244 TCollection_AsciiString typeStr;
245 switch ( theMirrorType ) {
246 case SMESH::SMESH_MeshEditor::POINT:
247 typeStr = "SMESH.SMESH_MeshEditor.POINT";
249 case SMESH::SMESH_MeshEditor::AXIS:
250 typeStr = "SMESH.SMESH_MeshEditor.AXIS";
253 typeStr = "SMESH.SMESH_MeshEditor.PLANE";
257 //================================================================================
259 * \brief function for conversion of long_array to TIDSortedElemSet
260 * \param IDs - array of IDs
261 * \param aMesh - mesh
262 * \param aMap - collection to fill
263 * \param aType - element type
265 //================================================================================
267 void arrayToSet(const SMESH::long_array & IDs,
268 const SMESHDS_Mesh* aMesh,
269 TIDSortedElemSet& aMap,
270 const SMDSAbs_ElementType aType = SMDSAbs_All,
271 SMDS_MeshElement::Filter* aFilter = NULL)
273 SMDS_MeshElement::NonNullFilter filter1;
274 SMDS_MeshElement::TypeFilter filter2( aType );
276 if ( aFilter == NULL )
277 aFilter = ( aType == SMDSAbs_All ) ? (SMDS_MeshElement::Filter*) &filter1 : (SMDS_MeshElement::Filter*) &filter2;
279 SMDS_MeshElement::Filter & filter = *aFilter;
281 if ( aType == SMDSAbs_Node )
282 for ( CORBA::ULong i = 0; i < IDs.length(); i++ ) {
283 const SMDS_MeshElement * elem = aMesh->FindNode( IDs[i] );
285 aMap.insert( aMap.end(), elem );
288 for ( CORBA::ULong i = 0; i<IDs.length(); i++) {
289 const SMDS_MeshElement * elem = aMesh->FindElement( IDs[i] );
291 aMap.insert( aMap.end(), elem );
295 //================================================================================
297 * \brief Retrieve nodes from SMESH_IDSource
299 //================================================================================
301 void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject,
302 const SMESHDS_Mesh* theMeshDS,
303 TIDSortedNodeSet& theNodeSet)
306 if ( CORBA::is_nil( theObject ) )
308 SMESH::array_of_ElementType_var types = theObject->GetTypes();
309 SMESH::long_array_var aElementsId = theObject->GetIDs();
310 if ( types->length() == 1 && types[0] == SMESH::NODE)
312 for ( CORBA::ULong i = 0; i < aElementsId->length(); i++ )
313 if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] ))
314 theNodeSet.insert( theNodeSet.end(), n);
316 else if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
318 SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator();
319 while ( nIt->more( ))
320 if ( const SMDS_MeshElement * elem = nIt->next() )
321 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
325 for ( CORBA::ULong i = 0; i < aElementsId->length(); i++ )
326 if ( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] ))
327 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
331 //================================================================================
333 * \brief Returns elements connected to the given elements
335 //================================================================================
337 void getElementsAround(const TIDSortedElemSet& theElements,
338 const SMESHDS_Mesh* theMeshDS,
339 TIDSortedElemSet& theElementsAround)
341 if ( theElements.empty() ) return;
343 SMDSAbs_ElementType elemType = (*theElements.begin())->GetType();
344 bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() );
346 theMeshDS->GetMeshInfo().NbElements( elemType ) == (int) theElements.size() )
347 return; // all the elements are in theElements
350 elemType = SMDSAbs_All;
352 vector<bool> isNodeChecked( theMeshDS->NbNodes(), false );
354 TIDSortedElemSet::const_iterator elemIt = theElements.begin();
355 for ( ; elemIt != theElements.end(); ++elemIt )
357 const SMDS_MeshElement* e = *elemIt;
358 int i = e->NbCornerNodes();
361 const SMDS_MeshNode* n = e->GetNode( i );
362 if ( !isNodeChecked[ n->GetID() ])
364 isNodeChecked[ n->GetID() ] = true;
365 SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
366 while ( invIt->more() )
368 const SMDS_MeshElement* elemAround = invIt->next();
369 if ( !theElements.count( elemAround ))
370 theElementsAround.insert( elemAround );
377 //================================================================================
379 * \brief Return a string used to detect change of mesh part on which theElementSearcher
380 * is going to be used
382 //================================================================================
384 string getPartIOR( SMESH::SMESH_IDSource_ptr theMeshPart, SMESH::ElementType type)
386 string partIOR = SMESH_Gen_i::GetORB()->object_to_string( theMeshPart );
387 if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( theMeshPart ))
388 // take into account passible group modification
389 partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() );
390 partIOR += SMESH_Comment( type );
394 } // namespace MeshEditor_I
396 using namespace MeshEditor_I;
398 //=============================================================================
402 //=============================================================================
404 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview):
406 myMesh( &theMesh->GetImpl() ),
408 myIsPreviewMode ( isPreview ),
414 //================================================================================
418 //================================================================================
420 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
422 PortableServer::POA_var poa = SMESH_Gen_i::GetPOA();
423 PortableServer::ObjectId_var anObjectId = poa->servant_to_id(this);
424 poa->deactivate_object(anObjectId.in());
426 //deleteAuxIDSources();
427 delete myPreviewMesh; myPreviewMesh = 0;
428 delete myPreviewEditor; myPreviewEditor = 0;
431 //================================================================================
433 * \brief Returns the mesh
435 //================================================================================
437 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::GetMesh()
439 return myMesh_i->_this();
442 //================================================================================
444 * \brief Clear members
446 //================================================================================
448 void SMESH_MeshEditor_i::initData(bool deleteSearchers)
450 if ( myIsPreviewMode ) {
451 if ( myPreviewMesh ) myPreviewMesh->RemoveAll();
454 if ( deleteSearchers )
455 TSearchersDeleter::Delete();
457 getEditor().GetError().reset();
458 getEditor().ClearLastCreated();
461 //================================================================================
463 * \brief Increment mesh modif time and optionally record that the performed
464 * modification may influence further mesh re-compute.
465 * \param [in] isReComputeSafe - true if the modification does not influence
466 * further mesh re-compute
468 //================================================================================
470 void SMESH_MeshEditor_i::declareMeshModified( bool isReComputeSafe )
472 myMesh->GetMeshDS()->Modified();
473 if ( !isReComputeSafe )
474 myMesh->SetIsModified( true );
477 //================================================================================
479 * \brief Return either myEditor or myPreviewEditor depending on myIsPreviewMode.
480 * WARNING: in preview mode call getPreviewMesh() before getEditor()!
482 //================================================================================
484 ::SMESH_MeshEditor& SMESH_MeshEditor_i::getEditor()
486 if ( myIsPreviewMode && !myPreviewEditor ) {
487 if ( !myPreviewMesh ) getPreviewMesh();
488 myPreviewEditor = new ::SMESH_MeshEditor( myPreviewMesh );
490 return myIsPreviewMode ? *myPreviewEditor : myEditor;
493 //================================================================================
495 * \brief Initialize and return myPreviewMesh
496 * \param previewElements - type of elements to show in preview
498 * WARNING: call it once per method!
500 //================================================================================
502 TPreviewMesh * SMESH_MeshEditor_i::getPreviewMesh(SMDSAbs_ElementType previewElements)
504 if ( !myPreviewMesh || myPreviewMesh->myPreviewType != previewElements )
506 delete myPreviewEditor;
508 delete myPreviewMesh;
509 myPreviewMesh = new TPreviewMesh( previewElements );
511 myPreviewMesh->Clear();
512 return myPreviewMesh;
515 //================================================================================
517 * Return data of mesh edition preview
519 //================================================================================
521 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
522 throw (SALOME::SALOME_Exception)
525 const bool hasBadElems = ( getEditor().GetError() && getEditor().GetError()->HasBadElems() );
527 if ( myIsPreviewMode || hasBadElems )
529 list<int> aNodesConnectivity;
530 typedef map<int, int> TNodesMap;
533 SMESHDS_Mesh* aMeshDS;
534 std::unique_ptr< SMESH_MeshPartDS > aMeshPartDS;
536 const list<const SMDS_MeshElement*>& badElems =
537 static_cast<SMESH_BadInputElements*>( getEditor().GetError().get() )->myBadElements;
538 aMeshPartDS.reset( new SMESH_MeshPartDS( badElems ));
539 aMeshDS = aMeshPartDS.get();
542 aMeshDS = getEditor().GetMeshDS();
544 myPreviewData = new SMESH::MeshPreviewStruct();
545 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
548 SMDSAbs_ElementType previewType = SMDSAbs_All;
550 if (TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( getEditor().GetMesh() )) {
551 previewType = aPreviewMesh->myPreviewType;
552 switch ( previewType ) {
553 case SMDSAbs_Edge : break;
554 case SMDSAbs_Face : break;
555 case SMDSAbs_Volume: break;
557 if ( aMeshDS->GetMeshInfo().NbElements() == 0 ) previewType = SMDSAbs_Node;
561 myPreviewData->elementTypes.length( aMeshDS->GetMeshInfo().NbElements( previewType ));
563 SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator(previewType);
565 while ( itMeshElems->more() ) {
566 const SMDS_MeshElement* aMeshElem = itMeshElems->next();
567 SMDS_NodeIteratorPtr itElemNodes =
568 (( aMeshElem->GetEntityType() == SMDSEntity_Quad_Polygon ) ?
569 aMeshElem->interlacedNodesIterator() :
570 aMeshElem->nodeIterator() );
571 while ( itElemNodes->more() ) {
572 const SMDS_MeshNode* aMeshNode = itElemNodes->next();
573 int aNodeID = aMeshNode->GetID();
574 TNodesMap::iterator anIter = nodesMap.find(aNodeID);
575 if ( anIter == nodesMap.end() ) {
576 // filling the nodes coordinates
577 myPreviewData->nodesXYZ[j].x = aMeshNode->X();
578 myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
579 myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
580 anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
583 aNodesConnectivity.push_back(anIter->second);
586 // filling the elements types
587 SMDSAbs_ElementType aType = aMeshElem->GetType();
588 bool isPoly = aMeshElem->IsPoly();
589 myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
590 myPreviewData->elementTypes[i].isPoly = isPoly;
591 myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
594 myPreviewData->nodesXYZ.length( j );
596 // filling the elements connectivities
597 list<int>::iterator aConnIter = aNodesConnectivity.begin();
598 myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
599 for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
600 myPreviewData->elementConnectivities[i] = *aConnIter;
602 return myPreviewData._retn();
604 SMESH_CATCH( SMESH::throwCorbaException );
608 //================================================================================
610 * \brief Returns list of it's IDs of created nodes
611 * \retval SMESH::long_array* - list of node ID
613 //================================================================================
615 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
616 throw (SALOME::SALOME_Exception)
619 SMESH::long_array_var myLastCreatedNodes = new SMESH::long_array();
621 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedNodes();
622 myLastCreatedNodes->length( aSeq.size() );
623 for ( size_t i = 0; i < aSeq.size(); i++)
624 myLastCreatedNodes[i] = aSeq[i]->GetID();
626 return myLastCreatedNodes._retn();
627 SMESH_CATCH( SMESH::throwCorbaException );
631 //================================================================================
633 * \brief Returns list of it's IDs of created elements
634 * \retval SMESH::long_array* - list of elements' ID
636 //================================================================================
638 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
639 throw (SALOME::SALOME_Exception)
642 SMESH::long_array_var myLastCreatedElems = new SMESH::long_array();
644 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
645 myLastCreatedElems->length( aSeq.size() );
646 for ( size_t i = 0; i < aSeq.size(); i++ )
647 myLastCreatedElems[i] = aSeq[i]->GetID();
649 return myLastCreatedElems._retn();
650 SMESH_CATCH( SMESH::throwCorbaException );
654 //=======================================================================
655 //function : ClearLastCreated
656 //purpose : Clears sequences of last created elements and nodes
657 //=======================================================================
659 void SMESH_MeshEditor_i::ClearLastCreated() throw (SALOME::SALOME_Exception)
662 getEditor().ClearLastCreated();
663 SMESH_CATCH( SMESH::throwCorbaException );
666 //=======================================================================
668 * Returns description of an error/warning occurred during the last operation
669 * WARNING: ComputeError.code >= 100 and no corresponding enum in IDL API
671 //=======================================================================
673 SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError()
674 throw (SALOME::SALOME_Exception)
677 SMESH::ComputeError_var errOut = new SMESH::ComputeError;
678 SMESH_ComputeErrorPtr& errIn = getEditor().GetError();
679 if ( errIn && !errIn->IsOK() )
681 errOut->code = -( errIn->myName < 0 ? errIn->myName + 1: errIn->myName ); // -1 -> 0
682 errOut->comment = errIn->myComment.c_str();
683 errOut->subShapeID = -1;
684 errOut->hasBadMesh = errIn->HasBadElems();
689 errOut->subShapeID = -1;
690 errOut->hasBadMesh = false;
693 return errOut._retn();
694 SMESH_CATCH( SMESH::throwCorbaException );
698 //=======================================================================
699 //function : MakeIDSource
700 //purpose : Wrap a sequence of ids in a SMESH_IDSource.
701 // Call UnRegister() as you fininsh using it!!
702 //=======================================================================
704 struct SMESH_MeshEditor_i::_IDSource : public virtual POA_SMESH::SMESH_IDSource,
705 public virtual SALOME::GenericObj_i
707 SMESH::long_array _ids;
708 SMESH::ElementType _type;
709 SMESH::SMESH_Mesh_ptr _mesh;
710 SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); }
711 SMESH::long_array* GetMeshInfo() { return 0; }
712 SMESH::long_array* GetNbElementsByType()
714 SMESH::long_array_var aRes = new SMESH::long_array();
715 aRes->length(SMESH::NB_ELEMENT_TYPES);
716 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
717 aRes[ i ] = ( i == _type ) ? _ids.length() : 0;
720 SMESH::SMESH_Mesh_ptr GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _mesh ); }
721 bool IsMeshInfoCorrect() { return true; }
722 SMESH::array_of_ElementType* GetTypes()
724 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
725 if ( _ids.length() > 0 ) {
729 return types._retn();
731 SALOMEDS::TMPFile* GetVtkUgStream()
733 SALOMEDS::TMPFile_var SeqFile;
734 return SeqFile._retn();
738 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
739 SMESH::ElementType type)
741 _IDSource* idSrc = new _IDSource;
742 idSrc->_mesh = myMesh_i->_this();
745 if ( type == SMESH::ALL && ids.length() > 0 )
746 idSrc->_type = myMesh_i->GetElementType( ids[0], true );
748 SMESH::SMESH_IDSource_var anIDSourceVar = idSrc->_this();
750 return anIDSourceVar._retn();
753 bool SMESH_MeshEditor_i::IsTemporaryIDSource( SMESH::SMESH_IDSource_ptr& idSource )
755 return SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource );
758 CORBA::Long* SMESH_MeshEditor_i::GetTemporaryIDs( SMESH::SMESH_IDSource_ptr& idSource,
761 if ( _IDSource* tmpIdSource = SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource ))
763 nbIds = (int) tmpIdSource->_ids.length();
764 return & tmpIdSource->_ids[0];
770 // void SMESH_MeshEditor_i::deleteAuxIDSources()
772 // std::list< _IDSource* >::iterator idSrcIt = myAuxIDSources.begin();
773 // for ( ; idSrcIt != myAuxIDSources.end(); ++idSrcIt )
775 // myAuxIDSources.clear();
778 //=============================================================================
782 //=============================================================================
785 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
786 throw (SALOME::SALOME_Exception)
793 for ( CORBA::ULong i = 0; i < IDsOfElements.length(); i++ )
794 IdList.push_back( IDsOfElements[i] );
796 // Update Python script
797 TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
800 bool ret = getEditor().Remove( IdList, false );
802 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 ); // issue 0020693
805 SMESH_CATCH( SMESH::throwCorbaException );
809 //=============================================================================
813 //=============================================================================
815 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
816 throw (SALOME::SALOME_Exception)
822 for ( CORBA::ULong i = 0; i < IDsOfNodes.length(); i++)
823 IdList.push_back( IDsOfNodes[i] );
825 // Update Python script
826 TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
828 bool ret = getEditor().Remove( IdList, true );
830 declareMeshModified( /*isReComputeSafe=*/ !ret ); // issue 0020693
833 SMESH_CATCH( SMESH::throwCorbaException );
837 //=============================================================================
841 //=============================================================================
843 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
844 throw (SALOME::SALOME_Exception)
849 // Update Python script
850 TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
852 // Create filter to find all orphan nodes
853 SMESH::Controls::Filter::TIdSequence seq;
854 SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
855 SMESH::Controls::Filter::GetElementsId( getMeshDS(), predicate, seq );
857 // remove orphan nodes (if there are any)
858 list< int > IdList( seq.begin(), seq.end() );
860 int nbNodesBefore = myMesh->NbNodes();
861 getEditor().Remove( IdList, true );
862 int nbNodesAfter = myMesh->NbNodes();
864 declareMeshModified( /*isReComputeSafe=*/ IdList.size() == 0 ); // issue 0020693
865 return nbNodesBefore - nbNodesAfter;
867 SMESH_CATCH( SMESH::throwCorbaException );
871 //=============================================================================
875 //=============================================================================
877 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,CORBA::Double y, CORBA::Double z)
878 throw (SALOME::SALOME_Exception)
883 const SMDS_MeshNode* N = getMeshDS()->AddNode(x, y, z);
885 // Update Python script
886 TPythonDump() << "nodeID = " << this << ".AddNode( "
887 << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )";
889 declareMeshModified( /*isReComputeSafe=*/false );
892 SMESH_CATCH( SMESH::throwCorbaException );
896 //=============================================================================
898 * Create 0D element on the given node.
900 //=============================================================================
902 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode,
903 CORBA::Boolean DuplicateElements)
904 throw (SALOME::SALOME_Exception)
909 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
910 SMDS_ElemIteratorPtr it0D = aNode->GetInverseElementIterator( SMDSAbs_0DElement );
912 SMDS_MeshElement* elem = 0;
913 if ( DuplicateElements || !it0D->more() )
914 elem = getMeshDS()->Add0DElement(aNode);
916 // Update Python script
917 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
919 declareMeshModified( /*isReComputeSafe=*/false );
921 return elem ? elem->GetID() : 0;
923 SMESH_CATCH( SMESH::throwCorbaException );
927 //=============================================================================
929 * Create a ball element on the given node.
931 //=============================================================================
933 CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diameter)
934 throw (SALOME::SALOME_Exception)
939 if ( diameter < std::numeric_limits<double>::min() )
940 THROW_SALOME_CORBA_EXCEPTION("Invalid diameter", SALOME::BAD_PARAM);
942 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
943 SMDS_MeshElement* elem = getMeshDS()->AddBall(aNode, diameter);
945 // Update Python script
946 TPythonDump() << "ballElem = "
947 << this << ".AddBall( " << IDOfNode << ", " << diameter <<" )";
949 declareMeshModified( /*isReComputeSafe=*/false );
950 return elem ? elem->GetID() : 0;
952 SMESH_CATCH( SMESH::throwCorbaException );
956 //=============================================================================
958 * Create an edge, either linear and quadratic (this is determed
959 * by number of given nodes, two or three)
961 //=============================================================================
963 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
964 throw (SALOME::SALOME_Exception)
969 int NbNodes = IDsOfNodes.length();
970 SMDS_MeshElement* elem = 0;
973 CORBA::Long index1 = IDsOfNodes[0];
974 CORBA::Long index2 = IDsOfNodes[1];
975 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(index1),
976 getMeshDS()->FindNode(index2));
978 // Update Python script
979 TPythonDump() << "edge = " << this << ".AddEdge([ "
980 << index1 << ", " << index2 <<" ])";
983 CORBA::Long n1 = IDsOfNodes[0];
984 CORBA::Long n2 = IDsOfNodes[1];
985 CORBA::Long n12 = IDsOfNodes[2];
986 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(n1),
987 getMeshDS()->FindNode(n2),
988 getMeshDS()->FindNode(n12));
989 // Update Python script
990 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
991 <<n1<<", "<<n2<<", "<<n12<<" ])";
994 declareMeshModified( /*isReComputeSafe=*/false );
995 return elem ? elem->GetID() : 0;
997 SMESH_CATCH( SMESH::throwCorbaException );
1001 //=============================================================================
1005 //=============================================================================
1007 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
1008 throw (SALOME::SALOME_Exception)
1013 int NbNodes = IDsOfNodes.length();
1019 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1020 for (int i = 0; i < NbNodes; i++)
1021 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1023 SMDS_MeshElement* elem = 0;
1025 case 3: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]); break;
1026 case 4: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]); break;
1027 case 6: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1028 nodes[4], nodes[5]); break;
1029 case 7: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1030 nodes[4], nodes[5], nodes[6]); break;
1031 case 8: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1032 nodes[4], nodes[5], nodes[6], nodes[7]); break;
1033 case 9: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1034 nodes[4], nodes[5], nodes[6], nodes[7],
1036 default: elem = getMeshDS()->AddPolygonalFace(nodes);
1039 // Update Python script
1040 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
1042 declareMeshModified( /*isReComputeSafe=*/false );
1044 return elem ? elem->GetID() : 0;
1046 SMESH_CATCH( SMESH::throwCorbaException );
1050 //=============================================================================
1054 //=============================================================================
1056 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
1057 throw (SALOME::SALOME_Exception)
1062 int NbNodes = IDsOfNodes.length();
1063 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1064 for (int i = 0; i < NbNodes; i++)
1065 if ( ! ( nodes[i] = getMeshDS()->FindNode( IDsOfNodes[i] )))
1068 const SMDS_MeshElement* elem = getMeshDS()->AddPolygonalFace(nodes);
1070 // Update Python script
1071 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
1073 declareMeshModified( /*isReComputeSafe=*/false );
1074 return elem ? elem->GetID() : 0;
1076 SMESH_CATCH( SMESH::throwCorbaException );
1080 //=============================================================================
1082 * AddQuadPolygonalFace
1084 //=============================================================================
1086 CORBA::Long SMESH_MeshEditor_i::AddQuadPolygonalFace (const SMESH::long_array & IDsOfNodes)
1087 throw (SALOME::SALOME_Exception)
1092 int NbNodes = IDsOfNodes.length();
1093 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1094 for (int i = 0; i < NbNodes; i++)
1095 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1097 const SMDS_MeshElement* elem = getMeshDS()->AddQuadPolygonalFace(nodes);
1099 // Update Python script
1100 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
1102 declareMeshModified( /*isReComputeSafe=*/false );
1103 return elem ? elem->GetID() : 0;
1105 SMESH_CATCH( SMESH::throwCorbaException );
1109 //=============================================================================
1111 * Create volume, either linear and quadratic (this is determed
1112 * by number of given nodes)
1114 //=============================================================================
1116 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
1117 throw (SALOME::SALOME_Exception)
1122 int NbNodes = IDsOfNodes.length();
1123 vector< const SMDS_MeshNode*> n(NbNodes);
1124 for(int i=0;i<NbNodes;i++)
1125 n[i]= getMeshDS()->FindNode(IDsOfNodes[i]);
1127 SMDS_MeshElement* elem = 0;
1130 case 4 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
1131 case 5 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
1132 case 6 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
1133 case 8 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
1134 case 10:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1135 n[6],n[7],n[8],n[9]);
1137 case 12:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1138 n[6],n[7],n[8],n[9],n[10],n[11]);
1140 case 13:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
1141 n[7],n[8],n[9],n[10],n[11],n[12]);
1143 case 15:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
1144 n[9],n[10],n[11],n[12],n[13],n[14]);
1146 case 20:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1147 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1148 n[15],n[16],n[17],n[18],n[19]);
1150 case 18:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1151 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1154 case 27:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1155 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1156 n[15],n[16],n[17],n[18],n[19],
1157 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
1161 // Update Python script
1162 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
1164 declareMeshModified( /*isReComputeSafe=*/false );
1165 return elem ? elem->GetID() : 0;
1167 SMESH_CATCH( SMESH::throwCorbaException );
1171 //=============================================================================
1173 * AddPolyhedralVolume
1175 //=============================================================================
1176 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
1177 const SMESH::long_array & Quantities)
1178 throw (SALOME::SALOME_Exception)
1183 int NbNodes = IDsOfNodes.length();
1184 std::vector<const SMDS_MeshNode*> n (NbNodes);
1185 for (int i = 0; i < NbNodes; i++)
1187 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDsOfNodes[i]);
1188 if (!aNode) return 0;
1192 int NbFaces = Quantities.length();
1193 std::vector<int> q (NbFaces);
1194 for (int j = 0; j < NbFaces; j++)
1195 q[j] = Quantities[j];
1197 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(n, q);
1199 // Update Python script
1200 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
1201 << IDsOfNodes << ", " << Quantities << " )";
1203 declareMeshModified( /*isReComputeSafe=*/false );
1204 return elem ? elem->GetID() : 0;
1206 SMESH_CATCH( SMESH::throwCorbaException );
1210 //=============================================================================
1212 * AddPolyhedralVolumeByFaces
1214 //=============================================================================
1216 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
1217 throw (SALOME::SALOME_Exception)
1222 int NbFaces = IdsOfFaces.length();
1223 std::vector<const SMDS_MeshNode*> poly_nodes;
1224 std::vector<int> quantities (NbFaces);
1226 for (int i = 0; i < NbFaces; i++) {
1227 const SMDS_MeshElement* aFace = getMeshDS()->FindElement(IdsOfFaces[i]);
1228 quantities[i] = aFace->NbNodes();
1230 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
1231 while (It->more()) {
1232 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
1236 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
1238 // Update Python script
1239 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
1240 << IdsOfFaces << " )";
1242 declareMeshModified( /*isReComputeSafe=*/false );
1243 return elem ? elem->GetID() : 0;
1245 SMESH_CATCH( SMESH::throwCorbaException );
1249 //=============================================================================
1251 // \brief Create 0D elements on all nodes of the given object.
1252 // \param theObject object on whose nodes 0D elements will be created.
1253 // \param theGroupName optional name of a group to add 0D elements created
1254 // and/or found on nodes of \a theObject.
1255 // \param DuplicateElements to add one more 0D element to a node or not.
1256 // \return an object (a new group or a temporary SMESH_IDSource) holding
1257 // ids of new and/or found 0D elements.
1259 //=============================================================================
1261 SMESH::SMESH_IDSource_ptr
1262 SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObject,
1263 const char* theGroupName,
1264 CORBA::Boolean theDuplicateElements)
1265 throw (SALOME::SALOME_Exception)
1270 SMESH::SMESH_IDSource_var result;
1273 TIDSortedElemSet elements, elems0D;
1274 if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
1275 getEditor().Create0DElementsOnAllNodes( elements, elems0D, theDuplicateElements );
1277 SMESH::long_array_var newElems = new SMESH::long_array;
1278 newElems->length( elems0D.size() );
1279 TIDSortedElemSet::iterator eIt = elems0D.begin();
1280 for ( size_t i = 0; i < elems0D.size(); ++i, ++eIt )
1281 newElems[ i ] = (*eIt)->GetID();
1283 SMESH::SMESH_GroupBase_var groupToFill;
1284 if ( theGroupName && strlen( theGroupName ))
1286 // Get existing group named theGroupName
1287 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
1288 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
1289 SMESH::SMESH_GroupBase_var group = groups[i];
1290 if ( !group->_is_nil() ) {
1291 CORBA::String_var name = group->GetName();
1292 if ( strcmp( name.in(), theGroupName ) == 0 && group->GetType() == SMESH::ELEM0D ) {
1293 groupToFill = group;
1298 if ( groupToFill->_is_nil() )
1299 groupToFill = myMesh_i->CreateGroup( SMESH::ELEM0D, theGroupName );
1300 else if ( !SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1301 groupToFill = myMesh_i->ConvertToStandalone( groupToFill );
1304 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1306 group_i->Add( newElems );
1307 result = SMESH::SMESH_IDSource::_narrow( groupToFill );
1308 pyDump << groupToFill;
1312 result = MakeIDSource( newElems, SMESH::ELEM0D );
1313 pyDump << "elem0DIDs";
1316 pyDump << " = " << this << ".Create0DElementsOnAllNodes( "
1317 << theObject << ", '" << theGroupName << "' )";
1319 return result._retn();
1321 SMESH_CATCH( SMESH::throwCorbaException );
1325 //=============================================================================
1327 * \brief Bind a node to a vertex
1328 * \param NodeID - node ID
1329 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1330 * \retval boolean - false if NodeID or VertexID is invalid
1332 //=============================================================================
1334 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
1335 throw (SALOME::SALOME_Exception)
1339 SMESHDS_Mesh * mesh = getMeshDS();
1340 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1342 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1344 if ( mesh->MaxShapeIndex() < VertexID )
1345 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1347 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
1348 if ( shape.ShapeType() != TopAbs_VERTEX )
1349 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1351 mesh->SetNodeOnVertex( node, VertexID );
1353 myMesh->SetIsModified( true );
1355 SMESH_CATCH( SMESH::throwCorbaException );
1358 //=============================================================================
1360 * \brief Store node position on an edge
1361 * \param NodeID - node ID
1362 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
1363 * \param paramOnEdge - parameter on edge where the node is located
1364 * \retval boolean - false if any parameter is invalid
1366 //=============================================================================
1368 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
1369 CORBA::Double paramOnEdge)
1370 throw (SALOME::SALOME_Exception)
1374 SMESHDS_Mesh * mesh = getMeshDS();
1375 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1377 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1379 if ( mesh->MaxShapeIndex() < EdgeID )
1380 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1382 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
1383 if ( shape.ShapeType() != TopAbs_EDGE )
1384 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1387 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
1388 if ( paramOnEdge < f || paramOnEdge > l )
1389 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
1391 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
1393 myMesh->SetIsModified( true );
1395 SMESH_CATCH( SMESH::throwCorbaException );
1398 //=============================================================================
1400 * \brief Store node position on a face
1401 * \param NodeID - node ID
1402 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
1403 * \param u - U parameter on face where the node is located
1404 * \param v - V parameter on face where the node is located
1405 * \retval boolean - false if any parameter is invalid
1407 //=============================================================================
1409 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
1410 CORBA::Double u, CORBA::Double v)
1411 throw (SALOME::SALOME_Exception)
1414 SMESHDS_Mesh * mesh = getMeshDS();
1415 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1417 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1419 if ( mesh->MaxShapeIndex() < FaceID )
1420 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1422 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
1423 if ( shape.ShapeType() != TopAbs_FACE )
1424 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1426 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
1427 bool isOut = ( u < surf.FirstUParameter() ||
1428 u > surf.LastUParameter() ||
1429 v < surf.FirstVParameter() ||
1430 v > surf.LastVParameter() );
1434 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
1435 << " u( " << surf.FirstUParameter()
1436 << "," << surf.LastUParameter()
1437 << ") v( " << surf.FirstVParameter()
1438 << "," << surf.LastVParameter() << ")" );
1440 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
1443 mesh->SetNodeOnFace( node, FaceID, u, v );
1444 myMesh->SetIsModified( true );
1446 SMESH_CATCH( SMESH::throwCorbaException );
1449 //=============================================================================
1451 * \brief Bind a node to a solid
1452 * \param NodeID - node ID
1453 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1454 * \retval boolean - false if NodeID or SolidID is invalid
1456 //=============================================================================
1458 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
1459 throw (SALOME::SALOME_Exception)
1462 SMESHDS_Mesh * mesh = getMeshDS();
1463 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1465 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1467 if ( mesh->MaxShapeIndex() < SolidID )
1468 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1470 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
1471 if ( shape.ShapeType() != TopAbs_SOLID &&
1472 shape.ShapeType() != TopAbs_SHELL)
1473 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1475 mesh->SetNodeInVolume( node, SolidID );
1477 SMESH_CATCH( SMESH::throwCorbaException );
1480 //=============================================================================
1482 * \brief Bind an element to a shape
1483 * \param ElementID - element ID
1484 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
1486 //=============================================================================
1488 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
1489 CORBA::Long ShapeID)
1490 throw (SALOME::SALOME_Exception)
1493 SMESHDS_Mesh * mesh = getMeshDS();
1494 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
1496 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
1498 if ( mesh->MaxShapeIndex() < ShapeID || ShapeID < 1 )
1499 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1501 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1502 if ( shape.ShapeType() != TopAbs_EDGE &&
1503 shape.ShapeType() != TopAbs_FACE &&
1504 shape.ShapeType() != TopAbs_SOLID &&
1505 shape.ShapeType() != TopAbs_SHELL )
1506 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1508 mesh->SetMeshElementOnShape( elem, ShapeID );
1510 myMesh->SetIsModified( true );
1512 SMESH_CATCH( SMESH::throwCorbaException );
1515 //=============================================================================
1519 //=============================================================================
1521 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1522 CORBA::Long NodeID2)
1523 throw (SALOME::SALOME_Exception)
1528 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1529 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1533 // Update Python script
1534 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1535 << NodeID1 << ", " << NodeID2 << " )";
1537 int ret = getEditor().InverseDiag ( n1, n2 );
1539 declareMeshModified( /*isReComputeSafe=*/false );
1542 SMESH_CATCH( SMESH::throwCorbaException );
1546 //=============================================================================
1550 //=============================================================================
1552 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1553 CORBA::Long NodeID2)
1554 throw (SALOME::SALOME_Exception)
1559 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1560 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1564 // Update Python script
1565 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1566 << NodeID1 << ", " << NodeID2 << " )";
1569 bool stat = getEditor().DeleteDiag ( n1, n2 );
1571 declareMeshModified( /*isReComputeSafe=*/!stat );
1575 SMESH_CATCH( SMESH::throwCorbaException );
1579 //=============================================================================
1583 //=============================================================================
1585 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1586 throw (SALOME::SALOME_Exception)
1591 for ( CORBA::ULong i = 0; i < IDsOfElements.length(); i++ )
1593 CORBA::Long index = IDsOfElements[i];
1594 const SMDS_MeshElement * elem = getMeshDS()->FindElement(index);
1596 getEditor().Reorient( elem );
1598 // Update Python script
1599 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1601 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 );
1604 SMESH_CATCH( SMESH::throwCorbaException );
1608 //=============================================================================
1612 //=============================================================================
1614 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1615 throw (SALOME::SALOME_Exception)
1620 TPythonDump aTPythonDump; // suppress dump in Reorient()
1622 prepareIdSource( theObject );
1624 SMESH::long_array_var anElementsId = theObject->GetIDs();
1625 CORBA::Boolean isDone = Reorient(anElementsId);
1627 // Update Python script
1628 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1630 declareMeshModified( /*isReComputeSafe=*/ anElementsId->length() == 0 );
1633 SMESH_CATCH( SMESH::throwCorbaException );
1637 //=======================================================================
1638 //function : Reorient2D
1639 //purpose : Reorient faces contained in \a the2Dgroup.
1640 // the2Dgroup - the mesh or its part to reorient
1641 // theDirection - desired direction of normal of \a theFace
1642 // theFace - ID of face whose orientation is checked.
1643 // It can be < 1 then \a thePoint is used to find a face.
1644 // thePoint - is used to find a face if \a theFace < 1.
1645 // return number of reoriented elements.
1646 //=======================================================================
1648 CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
1649 const SMESH::DirStruct& theDirection,
1650 CORBA::Long theFace,
1651 const SMESH::PointStruct& thePoint)
1652 throw (SALOME::SALOME_Exception)
1655 initData(/*deleteSearchers=*/false);
1657 TIDSortedElemSet elements;
1658 IDSource_Error error;
1659 idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error );
1660 if ( error == IDSource_EMPTY )
1662 if ( error == IDSource_INVALID )
1663 THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
1666 const SMDS_MeshElement* face = 0;
1669 face = getMeshDS()->FindElement( theFace );
1671 THROW_SALOME_CORBA_EXCEPTION("Inexistent face given", SALOME::BAD_PARAM);
1672 if ( face->GetType() != SMDSAbs_Face )
1673 THROW_SALOME_CORBA_EXCEPTION("Wrong element type", SALOME::BAD_PARAM);
1677 // create theElementSearcher if needed
1678 theSearchersDeleter.Set( myMesh, getPartIOR( the2Dgroup, SMESH::FACE ));
1679 if ( !theElementSearcher )
1681 if ( elements.empty() ) // search in the whole mesh
1683 if ( myMesh->NbFaces() == 0 )
1684 THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM);
1686 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
1690 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
1691 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
1693 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt);
1697 gp_Pnt p( thePoint.x, thePoint.y, thePoint.z );
1698 face = theElementSearcher->FindClosestTo( p, SMDSAbs_Face );
1701 THROW_SALOME_CORBA_EXCEPTION("No face found by point", SALOME::INTERNAL_ERROR );
1702 if ( !elements.empty() && !elements.count( face ))
1703 THROW_SALOME_CORBA_EXCEPTION("Found face is not in the group", SALOME::BAD_PARAM );
1706 const SMESH::PointStruct * P = &theDirection.PS;
1707 gp_Vec dirVec( P->x, P->y, P->z );
1708 if ( dirVec.Magnitude() < std::numeric_limits< double >::min() )
1709 THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM);
1711 int nbReori = getEditor().Reorient2D( elements, dirVec, face );
1714 declareMeshModified( /*isReComputeSafe=*/false );
1716 TPythonDump() << this << ".Reorient2D( "
1717 << the2Dgroup << ", "
1718 << theDirection << ", "
1720 << thePoint << " )";
1724 SMESH_CATCH( SMESH::throwCorbaException );
1728 //=======================================================================
1729 //function : Reorient2DBy3D
1730 //purpose : Reorient faces basing on orientation of adjacent volumes.
1731 //=======================================================================
1733 CORBA::Long SMESH_MeshEditor_i::Reorient2DBy3D(const SMESH::ListOfIDSources& faceGroups,
1734 SMESH::SMESH_IDSource_ptr volumeGroup,
1735 CORBA::Boolean outsideNormal)
1736 throw (SALOME::SALOME_Exception)
1741 TIDSortedElemSet volumes;
1742 IDSource_Error volsError;
1743 idSourceToSet( volumeGroup, getMeshDS(), volumes, SMDSAbs_Volume, /*emptyIfMesh=*/1, &volsError);
1746 for ( size_t i = 0; i < faceGroups.length(); ++i )
1748 SMESH::SMESH_IDSource_ptr faceGrp = faceGroups[i].in();
1750 TIDSortedElemSet faces;
1751 IDSource_Error error;
1752 idSourceToSet( faceGrp, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error );
1753 if ( error == IDSource_INVALID && faceGroups.length() == 1 )
1754 THROW_SALOME_CORBA_EXCEPTION("No faces in a given object", SALOME::BAD_PARAM);
1755 if ( error == IDSource_OK && volsError != IDSource_OK )
1756 THROW_SALOME_CORBA_EXCEPTION("No volumes in a given object", SALOME::BAD_PARAM);
1758 nbReori += getEditor().Reorient2DBy3D( faces, volumes, outsideNormal );
1760 if ( error != IDSource_EMPTY && faces.empty() ) // all faces in the mesh treated
1765 declareMeshModified( /*isReComputeSafe=*/false );
1767 TPythonDump() << this << ".Reorient2DBy3D( "
1768 << faceGroups << ", "
1769 << volumeGroup << ", "
1770 << outsideNormal << " )";
1774 SMESH_CATCH( SMESH::throwCorbaException );
1778 //=============================================================================
1780 * \brief Fuse neighbour triangles into quadrangles.
1782 //=============================================================================
1784 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1785 SMESH::NumericalFunctor_ptr Criterion,
1786 CORBA::Double MaxAngle)
1787 throw (SALOME::SALOME_Exception)
1792 SMESHDS_Mesh* aMesh = getMeshDS();
1793 TIDSortedElemSet faces,copyFaces;
1794 SMDS_MeshElement::GeomFilter triaFilter(SMDSGeom_TRIANGLE);
1795 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face, & triaFilter);
1796 TIDSortedElemSet* workElements = & faces;
1798 if ( myIsPreviewMode ) {
1799 SMDSAbs_ElementType select = SMDSAbs_Face;
1800 getPreviewMesh( SMDSAbs_Face )->Copy( faces, copyFaces, select );
1801 workElements = & copyFaces;
1804 SMESH::NumericalFunctor_i* aNumericalFunctor =
1805 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1806 SMESH::Controls::NumericalFunctorPtr aCrit;
1807 if ( !aNumericalFunctor )
1808 aCrit.reset( new SMESH::Controls::MaxElementLength2D() );
1810 aCrit = aNumericalFunctor->GetNumericalFunctor();
1812 if ( !myIsPreviewMode ) {
1813 // Update Python script
1814 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1815 << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1818 bool stat = getEditor().TriToQuad( *workElements, aCrit, MaxAngle );
1820 declareMeshModified( /*isReComputeSafe=*/!stat );
1823 SMESH_CATCH( SMESH::throwCorbaException );
1827 //=============================================================================
1829 * \brief Fuse neighbour triangles into quadrangles.
1831 //=============================================================================
1833 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1834 SMESH::NumericalFunctor_ptr Criterion,
1835 CORBA::Double MaxAngle)
1836 throw (SALOME::SALOME_Exception)
1841 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1843 prepareIdSource( theObject );
1844 SMESH::long_array_var anElementsId = theObject->GetIDs();
1845 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1847 if ( !myIsPreviewMode ) {
1848 SMESH::NumericalFunctor_i* aNumericalFunctor =
1849 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1851 // Update Python script
1852 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1853 << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1858 SMESH_CATCH( SMESH::throwCorbaException );
1862 //=============================================================================
1864 * \brief Split quadrangles into triangles.
1866 //=============================================================================
1868 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1869 SMESH::NumericalFunctor_ptr Criterion)
1870 throw (SALOME::SALOME_Exception)
1875 SMESHDS_Mesh* aMesh = getMeshDS();
1876 TIDSortedElemSet faces;
1877 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1879 SMESH::NumericalFunctor_i* aNumericalFunctor =
1880 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1881 SMESH::Controls::NumericalFunctorPtr aCrit;
1882 if ( !aNumericalFunctor )
1883 aCrit.reset( new SMESH::Controls::AspectRatio() );
1885 aCrit = aNumericalFunctor->GetNumericalFunctor();
1888 // Update Python script
1889 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1891 CORBA::Boolean stat = getEditor().QuadToTri( faces, aCrit );
1893 declareMeshModified( /*isReComputeSafe=*/false );
1896 SMESH_CATCH( SMESH::throwCorbaException );
1900 //=============================================================================
1902 * \brief Split quadrangles into triangles.
1904 //=============================================================================
1906 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1907 SMESH::NumericalFunctor_ptr Criterion)
1908 throw (SALOME::SALOME_Exception)
1913 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1915 prepareIdSource( theObject );
1916 SMESH::long_array_var anElementsId = theObject->GetIDs();
1917 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1919 SMESH::NumericalFunctor_i* aNumericalFunctor =
1920 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1922 // Update Python script
1923 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1925 declareMeshModified( /*isReComputeSafe=*/false );
1928 SMESH_CATCH( SMESH::throwCorbaException );
1932 //================================================================================
1934 * \brief Split each of quadrangles into 4 triangles.
1935 * \param [in] theObject - theQuads Container of quadrangles to split.
1937 //================================================================================
1939 void SMESH_MeshEditor_i::QuadTo4Tri (SMESH::SMESH_IDSource_ptr theObject)
1940 throw (SALOME::SALOME_Exception)
1945 TIDSortedElemSet faces;
1946 if ( !idSourceToSet( theObject, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/true ) &&
1948 THROW_SALOME_CORBA_EXCEPTION("No faces given", SALOME::BAD_PARAM);
1950 getEditor().QuadTo4Tri( faces );
1951 TPythonDump() << this << ".QuadTo4Tri( " << theObject << " )";
1953 SMESH_CATCH( SMESH::throwCorbaException );
1956 //=============================================================================
1958 * \brief Split quadrangles into triangles.
1960 //=============================================================================
1962 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1963 CORBA::Boolean Diag13)
1964 throw (SALOME::SALOME_Exception)
1969 SMESHDS_Mesh* aMesh = getMeshDS();
1970 TIDSortedElemSet faces;
1971 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1973 // Update Python script
1974 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1975 << IDsOfElements << ", " << Diag13 << " )";
1977 CORBA::Boolean stat = getEditor().QuadToTri( faces, Diag13 );
1979 declareMeshModified( /*isReComputeSafe=*/ !stat );
1982 SMESH_CATCH( SMESH::throwCorbaException );
1986 //=============================================================================
1988 * \brief Split quadrangles into triangles.
1990 //=============================================================================
1992 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1993 CORBA::Boolean Diag13)
1994 throw (SALOME::SALOME_Exception)
1999 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
2001 prepareIdSource( theObject );
2002 SMESH::long_array_var anElementsId = theObject->GetIDs();
2003 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
2005 // Update Python script
2006 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
2007 << theObject << ", " << Diag13 << " )";
2009 declareMeshModified( /*isReComputeSafe=*/!isDone );
2012 SMESH_CATCH( SMESH::throwCorbaException );
2017 //=============================================================================
2019 * Find better splitting of the given quadrangle.
2020 * \param IDOfQuad ID of the quadrangle to be split.
2021 * \param Criterion A criterion to choose a diagonal for splitting.
2022 * \return 1 if 1-3 diagonal is better, 2 if 2-4
2023 * diagonal is better, 0 if error occurs.
2025 //=============================================================================
2027 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
2028 SMESH::NumericalFunctor_ptr Criterion)
2029 throw (SALOME::SALOME_Exception)
2034 const SMDS_MeshElement* quad = getMeshDS()->FindElement(IDOfQuad);
2035 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
2037 SMESH::NumericalFunctor_i* aNumericalFunctor =
2038 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
2039 SMESH::Controls::NumericalFunctorPtr aCrit;
2040 if (aNumericalFunctor)
2041 aCrit = aNumericalFunctor->GetNumericalFunctor();
2043 aCrit.reset(new SMESH::Controls::AspectRatio());
2045 int id = getEditor().BestSplit(quad, aCrit);
2046 declareMeshModified( /*isReComputeSafe=*/ id < 1 );
2050 SMESH_CATCH( SMESH::throwCorbaException );
2054 //================================================================================
2056 * \brief Split volumic elements into tetrahedrons
2058 //================================================================================
2060 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
2061 CORBA::Short methodFlags)
2062 throw (SALOME::SALOME_Exception)
2067 ::SMESH_MeshEditor::TFacetOfElem elemSet;
2068 const int noneFacet = -1;
2069 SMDS_ElemIteratorPtr volIt = myMesh_i->GetElements( elems, SMESH::VOLUME );
2070 while( volIt->more() )
2071 elemSet.insert( elemSet.end(), make_pair( volIt->next(), noneFacet ));
2073 getEditor().SplitVolumes( elemSet, int( methodFlags ));
2074 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2076 TPythonDump() << this << ".SplitVolumesIntoTetra( "
2077 << elems << ", " << methodFlags << " )";
2079 SMESH_CATCH( SMESH::throwCorbaException );
2082 //================================================================================
2084 * \brief Split hexahedra into triangular prisms
2085 * \param elems - elements to split
2086 * \param facetToSplitNormal - normal used to find a facet of hexahedron
2087 * to split into triangles
2088 * \param methodFlags - flags passing splitting method:
2089 * 1 - split the hexahedron into 2 prisms
2090 * 2 - split the hexahedron into 4 prisms
2092 //================================================================================
2094 void SMESH_MeshEditor_i::SplitHexahedraIntoPrisms( SMESH::SMESH_IDSource_ptr elems,
2095 const SMESH::PointStruct & startHexPoint,
2096 const SMESH::DirStruct& facetToSplitNormal,
2097 CORBA::Short methodFlags,
2098 CORBA::Boolean allDomains)
2099 throw (SALOME::SALOME_Exception)
2103 prepareIdSource( elems );
2105 gp_Ax1 facetNorm( gp_Pnt( startHexPoint.x,
2108 gp_Dir( facetToSplitNormal.PS.x,
2109 facetToSplitNormal.PS.y,
2110 facetToSplitNormal.PS.z ));
2111 TIDSortedElemSet elemSet;
2112 SMESH::long_array_var anElementsId = elems->GetIDs();
2113 SMDS_MeshElement::GeomFilter filter( SMDSGeom_HEXA );
2114 arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume, &filter );
2116 ::SMESH_MeshEditor::TFacetOfElem elemFacets;
2117 while ( !elemSet.empty() )
2119 getEditor().GetHexaFacetsToSplit( elemSet, facetNorm, elemFacets );
2123 ::SMESH_MeshEditor::TFacetOfElem::iterator ef = elemFacets.begin();
2124 for ( ; ef != elemFacets.end(); ++ef )
2125 elemSet.erase( ef->first );
2128 if ( methodFlags == 2 )
2129 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_4_PRISMS );
2131 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_2_PRISMS );
2133 getEditor().SplitVolumes( elemFacets, int( methodFlags ));
2134 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2136 TPythonDump() << this << ".SplitHexahedraIntoPrisms( "
2138 << startHexPoint << ", "
2139 << facetToSplitNormal<< ", "
2140 << methodFlags<< ", "
2141 << allDomains << " )";
2143 SMESH_CATCH( SMESH::throwCorbaException );
2146 //================================================================================
2148 * \brief Split bi-quadratic elements into linear ones without creation of additional nodes:
2149 * - bi-quadratic triangle will be split into 3 linear quadrangles;
2150 * - bi-quadratic quadrangle will be split into 4 linear quadrangles;
2151 * - tri-quadratic hexahedron will be split into 8 linear hexahedra.
2152 * Quadratic elements of lower dimension adjacent to the split bi-quadratic element
2153 * will be split in order to keep the mesh conformal.
2154 * \param elems - elements to split
2156 //================================================================================
2158 void SMESH_MeshEditor_i::SplitBiQuadraticIntoLinear(const SMESH::ListOfIDSources& theElems)
2159 throw (SALOME::SALOME_Exception)
2164 TIDSortedElemSet elemSet;
2165 for ( size_t i = 0; i < theElems.length(); ++i )
2167 SMESH::SMESH_IDSource_ptr elems = theElems[i].in();
2168 SMESH::SMESH_Mesh_var mesh = elems->GetMesh();
2169 if ( mesh->GetId() != myMesh_i->GetId() )
2170 THROW_SALOME_CORBA_EXCEPTION("Wrong mesh of IDSource", SALOME::BAD_PARAM);
2172 idSourceToSet( elems, getMeshDS(), elemSet, SMDSAbs_All );
2174 getEditor().SplitBiQuadraticIntoLinear( elemSet );
2176 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2178 TPythonDump() << this << ".SplitBiQuadraticIntoLinear( "
2179 << theElems << " )";
2181 SMESH_CATCH( SMESH::throwCorbaException );
2184 //=======================================================================
2187 //=======================================================================
2190 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
2191 const SMESH::long_array & IDsOfFixedNodes,
2192 CORBA::Long MaxNbOfIterations,
2193 CORBA::Double MaxAspectRatio,
2194 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2195 throw (SALOME::SALOME_Exception)
2197 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2198 MaxAspectRatio, Method, false );
2202 //=======================================================================
2203 //function : SmoothParametric
2205 //=======================================================================
2208 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
2209 const SMESH::long_array & IDsOfFixedNodes,
2210 CORBA::Long MaxNbOfIterations,
2211 CORBA::Double MaxAspectRatio,
2212 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2213 throw (SALOME::SALOME_Exception)
2215 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2216 MaxAspectRatio, Method, true );
2220 //=======================================================================
2221 //function : SmoothObject
2223 //=======================================================================
2226 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
2227 const SMESH::long_array & IDsOfFixedNodes,
2228 CORBA::Long MaxNbOfIterations,
2229 CORBA::Double MaxAspectRatio,
2230 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2231 throw (SALOME::SALOME_Exception)
2233 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2234 MaxAspectRatio, Method, false);
2238 //=======================================================================
2239 //function : SmoothParametricObject
2241 //=======================================================================
2244 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
2245 const SMESH::long_array & IDsOfFixedNodes,
2246 CORBA::Long MaxNbOfIterations,
2247 CORBA::Double MaxAspectRatio,
2248 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2249 throw (SALOME::SALOME_Exception)
2251 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2252 MaxAspectRatio, Method, true);
2256 //=============================================================================
2260 //=============================================================================
2263 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
2264 const SMESH::long_array & IDsOfFixedNodes,
2265 CORBA::Long MaxNbOfIterations,
2266 CORBA::Double MaxAspectRatio,
2267 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2269 throw (SALOME::SALOME_Exception)
2274 SMESHDS_Mesh* aMesh = getMeshDS();
2276 TIDSortedElemSet elements;
2277 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
2279 set<const SMDS_MeshNode*> fixedNodes;
2280 for ( CORBA::ULong i = 0; i < IDsOfFixedNodes.length(); i++) {
2281 CORBA::Long index = IDsOfFixedNodes[i];
2282 const SMDS_MeshNode * node = aMesh->FindNode(index);
2284 fixedNodes.insert( node );
2286 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
2287 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
2288 method = ::SMESH_MeshEditor::CENTROIDAL;
2290 getEditor().Smooth(elements, fixedNodes, method,
2291 MaxNbOfIterations, MaxAspectRatio, IsParametric );
2293 declareMeshModified( /*isReComputeSafe=*/true ); // does not prevent re-compute
2295 // Update Python script
2296 TPythonDump() << "isDone = " << this << "."
2297 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
2298 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
2299 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2300 << "SMESH.SMESH_MeshEditor."
2301 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2302 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2306 SMESH_CATCH( SMESH::throwCorbaException );
2310 //=============================================================================
2314 //=============================================================================
2317 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
2318 const SMESH::long_array & IDsOfFixedNodes,
2319 CORBA::Long MaxNbOfIterations,
2320 CORBA::Double MaxAspectRatio,
2321 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2323 throw (SALOME::SALOME_Exception)
2328 TPythonDump aTPythonDump; // suppress dump in smooth()
2330 prepareIdSource( theObject );
2331 SMESH::long_array_var anElementsId = theObject->GetIDs();
2332 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
2333 MaxAspectRatio, Method, IsParametric);
2335 // Update Python script
2336 aTPythonDump << "isDone = " << this << "."
2337 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
2338 << theObject << ", " << IDsOfFixedNodes << ", "
2339 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2340 << "SMESH.SMESH_MeshEditor."
2341 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2342 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2346 SMESH_CATCH( SMESH::throwCorbaException );
2350 //=============================================================================
2354 //=============================================================================
2356 void SMESH_MeshEditor_i::RenumberNodes()
2357 throw (SALOME::SALOME_Exception)
2360 // Update Python script
2361 TPythonDump() << this << ".RenumberNodes()";
2363 getMeshDS()->Renumber( true );
2365 SMESH_CATCH( SMESH::throwCorbaException );
2368 //=============================================================================
2372 //=============================================================================
2374 void SMESH_MeshEditor_i::RenumberElements()
2375 throw (SALOME::SALOME_Exception)
2378 // Update Python script
2379 TPythonDump() << this << ".RenumberElements()";
2381 getMeshDS()->Renumber( false );
2383 SMESH_CATCH( SMESH::throwCorbaException );
2386 //=======================================================================
2388 * \brief Return groups by their IDs
2390 //=======================================================================
2392 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
2393 throw (SALOME::SALOME_Exception)
2398 myMesh_i->CreateGroupServants();
2399 return myMesh_i->GetGroups( *groupIDs );
2401 SMESH_CATCH( SMESH::throwCorbaException );
2405 //=======================================================================
2406 //function : RotationSweepObjects
2408 //=======================================================================
2410 SMESH::ListOfGroups*
2411 SMESH_MeshEditor_i::RotationSweepObjects(const SMESH::ListOfIDSources & theNodes,
2412 const SMESH::ListOfIDSources & theEdges,
2413 const SMESH::ListOfIDSources & theFaces,
2414 const SMESH::AxisStruct & theAxis,
2415 CORBA::Double theAngleInRadians,
2416 CORBA::Long theNbOfSteps,
2417 CORBA::Double theTolerance,
2418 const bool theMakeGroups)
2419 throw (SALOME::SALOME_Exception)
2424 TIDSortedElemSet elemsNodes[2];
2425 for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) {
2426 SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE );
2427 while ( nIt->more() ) elemsNodes[1].insert( nIt->next() );
2429 for ( int i = 0, nb = theEdges.length(); i < nb; ++i )
2430 idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge );
2431 for ( int i = 0, nb = theFaces.length(); i < nb; ++i )
2432 idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face );
2434 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2435 bool makeWalls=true;
2436 if ( myIsPreviewMode )
2438 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2439 TPreviewMesh * tmpMesh = getPreviewMesh();
2440 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2441 tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid );
2442 workElements = & copyElements[0];
2443 //makeWalls = false; -- faces are needed for preview
2446 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2448 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
2449 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
2451 ::SMESH_MeshEditor::PGroupIDs groupIds =
2452 getEditor().RotationSweep (workElements, Ax1, theAngleInRadians,
2453 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
2455 SMESH::ListOfGroups * aGroups = theMakeGroups ? getGroups( groupIds.get()) : 0;
2457 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2459 if ( !myIsPreviewMode )
2461 dumpGroupsList( aPythonDump, aGroups );
2462 aPythonDump << this<< ".RotationSweepObjects( "
2467 << TVar( theAngleInRadians ) << ", "
2468 << TVar( theNbOfSteps ) << ", "
2469 << TVar( theTolerance ) << ", "
2470 << theMakeGroups << " )";
2474 getPreviewMesh()->Remove( SMDSAbs_Volume );
2477 return aGroups ? aGroups : new SMESH::ListOfGroups;
2479 SMESH_CATCH( SMESH::throwCorbaException );
2483 namespace MeshEditor_I
2486 * \brief Structure used to pass extrusion parameters to ::SMESH_MeshEditor
2488 struct ExtrusionParams : public ::SMESH_MeshEditor::ExtrusParam
2490 bool myIsExtrusionByNormal;
2492 static int makeFlags( CORBA::Boolean MakeGroups,
2493 CORBA::Boolean LinearVariation = false,
2494 CORBA::Boolean ByAverageNormal = false,
2495 CORBA::Boolean UseInputElemsOnly = false,
2496 CORBA::Long Flags = 0,
2497 CORBA::Boolean MakeBoundary = true )
2499 if ( MakeGroups ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS;
2500 if ( ByAverageNormal ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BY_AVG_NORMAL;
2501 if ( UseInputElemsOnly) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY;
2502 if ( LinearVariation ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_SCALE_LINEAR_VARIATION;
2503 if ( MakeBoundary ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BOUNDARY;
2507 ExtrusionParams(const SMESH::DirStruct & theDir,
2508 CORBA::Long theNbOfSteps,
2509 const SMESH::double_array & theScaleFactors,
2510 CORBA::Boolean theLinearVariation,
2511 const SMESH::double_array & theBasePoint,
2512 CORBA::Boolean theMakeGroups):
2513 ::SMESH_MeshEditor::ExtrusParam ( gp_Vec( theDir.PS.x,
2517 toList( theScaleFactors ),
2518 TBasePoint( theBasePoint ),
2519 makeFlags( theMakeGroups, theLinearVariation )),
2520 myIsExtrusionByNormal( false )
2524 ExtrusionParams(const SMESH::DirStruct & theDir,
2525 CORBA::Long theNbOfSteps,
2526 CORBA::Boolean theMakeGroups,
2527 CORBA::Long theExtrFlags,
2528 CORBA::Double theSewTolerance):
2529 ::SMESH_MeshEditor::ExtrusParam ( gp_Vec( theDir.PS.x,
2533 std::list<double>(),
2535 makeFlags( theMakeGroups, false, false, false,
2536 theExtrFlags, false ),
2538 myIsExtrusionByNormal( false )
2541 // params for extrusion by normal
2542 ExtrusionParams(CORBA::Double theStepSize,
2543 CORBA::Long theNbOfSteps,
2544 CORBA::Short theDim,
2545 CORBA::Boolean theByAverageNormal,
2546 CORBA::Boolean theUseInputElemsOnly,
2547 CORBA::Boolean theMakeGroups ):
2548 ::SMESH_MeshEditor::ExtrusParam ( theStepSize,
2550 makeFlags( theMakeGroups, false,
2551 theByAverageNormal, theUseInputElemsOnly ),
2553 myIsExtrusionByNormal( true )
2559 Flags() &= ~(::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS);
2564 static std::list<double> toList( const SMESH::double_array & theScaleFactors )
2566 std::list<double> scales;
2567 for ( CORBA::ULong i = 0; i < theScaleFactors.length(); ++i )
2568 scales.push_back( theScaleFactors[i] );
2572 // structure used to convert SMESH::double_array to gp_XYZ*
2576 TBasePoint( const SMESH::double_array & theBasePoint )
2579 if ( theBasePoint.length() == 3 )
2581 p.SetCoord( theBasePoint[0], theBasePoint[1], theBasePoint[2] );
2585 operator const gp_XYZ*() const { return pp; }
2590 //=======================================================================
2592 * \brief Generate dim+1 elements by extrusion of elements along vector
2593 * \param [in] edges - edges to extrude: a list including groups, sub-meshes or a mesh
2594 * \param [in] faces - faces to extrude: a list including groups, sub-meshes or a mesh
2595 * \param [in] nodes - nodes to extrude: a list including groups, sub-meshes or a mesh
2596 * \param [in] stepVector - vector giving direction and distance of an extrusion step
2597 * \param [in] nbOfSteps - number of elements to generate from one element
2598 * \param [in] toMakeGroups - if true, new elements will be included into new groups
2599 * corresponding to groups the input elements included in.
2600 * \return ListOfGroups - new groups created if \a toMakeGroups is true
2602 //=======================================================================
2604 SMESH::ListOfGroups*
2605 SMESH_MeshEditor_i::ExtrusionSweepObjects(const SMESH::ListOfIDSources & theNodes,
2606 const SMESH::ListOfIDSources & theEdges,
2607 const SMESH::ListOfIDSources & theFaces,
2608 const SMESH::DirStruct & theStepVector,
2609 CORBA::Long theNbOfSteps,
2610 const SMESH::double_array & theScaleFactors,
2611 CORBA::Boolean theLinearVariation,
2612 const SMESH::double_array & theBasePoint,
2613 CORBA::Boolean theToMakeGroups)
2614 throw (SALOME::SALOME_Exception)
2619 ExtrusionParams params( theStepVector, theNbOfSteps, theScaleFactors,
2620 theLinearVariation, theBasePoint, theToMakeGroups );
2622 TIDSortedElemSet elemsNodes[2];
2623 for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) {
2624 SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE );
2625 while ( nIt->more() ) elemsNodes[1].insert( nIt->next() );
2627 for ( int i = 0, nb = theEdges.length(); i < nb; ++i )
2628 idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge );
2629 for ( int i = 0, nb = theFaces.length(); i < nb; ++i )
2630 idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face );
2632 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2633 SMDSAbs_ElementType previewType = SMDSAbs_All; //SMDSAbs_Face;
2634 if ( myIsPreviewMode )
2636 // if ( (*elemsNodes.begin())->GetType() == SMDSAbs_Node )
2637 // previewType = SMDSAbs_Edge;
2639 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2640 TPreviewMesh * tmpMesh = getPreviewMesh( previewType );
2641 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2642 tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid );
2643 workElements = & copyElements[0];
2645 params.SetNoGroups();
2647 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2649 ::SMESH_MeshEditor::TTElemOfElemListMap aHistory;
2650 ::SMESH_MeshEditor::PGroupIDs groupIds =
2651 getEditor().ExtrusionSweep( workElements, params, aHistory );
2653 SMESH::ListOfGroups * aGroups = theToMakeGroups ? getGroups( groupIds.get()) : 0;
2655 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2657 if ( !myIsPreviewMode )
2659 dumpGroupsList( aPythonDump, aGroups );
2660 aPythonDump << this<< ".ExtrusionSweepObjects( "
2664 << theStepVector << ", "
2665 << TVar( theNbOfSteps ) << ", "
2666 << theToMakeGroups << " )";
2670 getPreviewMesh( previewType )->Remove( SMDSAbs_Volume );
2673 return aGroups ? aGroups : new SMESH::ListOfGroups;
2675 SMESH_CATCH( SMESH::throwCorbaException );
2679 //=======================================================================
2680 //function : ExtrusionByNormal
2682 //=======================================================================
2684 SMESH::ListOfGroups*
2685 SMESH_MeshEditor_i::ExtrusionByNormal(const SMESH::ListOfIDSources& objects,
2686 CORBA::Double stepSize,
2687 CORBA::Long nbOfSteps,
2688 CORBA::Boolean byAverageNormal,
2689 CORBA::Boolean useInputElemsOnly,
2690 CORBA::Boolean makeGroups,
2692 throw (SALOME::SALOME_Exception)
2697 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2699 ExtrusionParams params( stepSize, nbOfSteps, dim,
2700 byAverageNormal, useInputElemsOnly, makeGroups );
2702 SMDSAbs_ElementType elemType = ( dim == 1 ? SMDSAbs_Edge : SMDSAbs_Face );
2703 if ( objects.length() > 0 && !SMESH::DownCast<SMESH_Mesh_i*>( objects[0] ))
2705 SMESH::array_of_ElementType_var elemTypes = objects[0]->GetTypes();
2706 if (( elemTypes->length() == 1 ) &&
2707 ( elemTypes[0] == SMESH::EDGE || elemTypes[0] == SMESH::FACE ))
2708 elemType = ( SMDSAbs_ElementType ) elemTypes[0];
2711 TIDSortedElemSet elemsNodes[2];
2712 for ( int i = 0, nb = objects.length(); i < nb; ++i )
2713 idSourceToSet( objects[i], getMeshDS(), elemsNodes[0], elemType );
2715 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2716 SMDSAbs_ElementType previewType = SMDSAbs_Face;
2717 if ( myIsPreviewMode )
2719 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2720 TPreviewMesh * tmpMesh = getPreviewMesh( previewType );
2721 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2722 workElements = & copyElements[0];
2724 params.SetNoGroups();
2727 ::SMESH_MeshEditor::TTElemOfElemListMap aHistory;
2728 ::SMESH_MeshEditor::PGroupIDs groupIds =
2729 getEditor().ExtrusionSweep( workElements, params, aHistory );
2731 SMESH::ListOfGroups * aGroups = makeGroups ? getGroups( groupIds.get()) : 0;
2733 if (!myIsPreviewMode) {
2734 dumpGroupsList(aPythonDump, aGroups);
2735 aPythonDump << this << ".ExtrusionByNormal( " << objects
2736 << ", " << TVar( stepSize )
2737 << ", " << TVar( nbOfSteps )
2738 << ", " << byAverageNormal
2739 << ", " << useInputElemsOnly
2740 << ", " << makeGroups
2746 getPreviewMesh( previewType )->Remove( SMDSAbs_Volume );
2749 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2751 return aGroups ? aGroups : new SMESH::ListOfGroups;
2753 SMESH_CATCH( SMESH::throwCorbaException );
2757 //=======================================================================
2758 //function : AdvancedExtrusion
2760 //=======================================================================
2762 SMESH::ListOfGroups*
2763 SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2764 const SMESH::DirStruct & theStepVector,
2765 CORBA::Long theNbOfSteps,
2766 CORBA::Long theExtrFlags,
2767 CORBA::Double theSewTolerance,
2768 CORBA::Boolean theMakeGroups)
2769 throw (SALOME::SALOME_Exception)
2774 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2776 ExtrusionParams params( theStepVector, theNbOfSteps, theMakeGroups,
2777 theExtrFlags, theSewTolerance );
2779 TIDSortedElemSet elemsNodes[2];
2780 arrayToSet( theIDsOfElements, getMeshDS(), elemsNodes[0] );
2782 ::SMESH_MeshEditor::TTElemOfElemListMap aHistory;
2783 ::SMESH_MeshEditor::PGroupIDs groupIds =
2784 getEditor().ExtrusionSweep( elemsNodes, params, aHistory );
2786 SMESH::ListOfGroups * aGroups = theMakeGroups ? getGroups( groupIds.get()) : 0;
2788 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2790 if ( !myIsPreviewMode ) {
2791 dumpGroupsList(aPythonDump, aGroups);
2792 aPythonDump << this << ".AdvancedExtrusion( "
2793 << theIDsOfElements << ", "
2794 << theStepVector << ", "
2795 << theNbOfSteps << ", "
2796 << theExtrFlags << ", "
2797 << theSewTolerance << ", "
2798 << theMakeGroups << " )";
2802 getPreviewMesh()->Remove( SMDSAbs_Volume );
2805 return aGroups ? aGroups : new SMESH::ListOfGroups;
2807 SMESH_CATCH( SMESH::throwCorbaException );
2811 //================================================================================
2813 * \brief Convert extrusion error to IDL enum
2815 //================================================================================
2819 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
2821 SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( ::SMESH_MeshEditor::Extrusion_Error e )
2825 RETCASE( EXTR_NO_ELEMENTS );
2826 RETCASE( EXTR_PATH_NOT_EDGE );
2827 RETCASE( EXTR_BAD_PATH_SHAPE );
2828 RETCASE( EXTR_BAD_STARTING_NODE );
2829 RETCASE( EXTR_BAD_ANGLES_NUMBER );
2830 RETCASE( EXTR_CANT_GET_TANGENT );
2832 return SMESH::SMESH_MeshEditor::EXTR_OK;
2836 //=======================================================================
2837 //function : extrusionAlongPath
2839 //=======================================================================
2840 SMESH::ListOfGroups*
2841 SMESH_MeshEditor_i::ExtrusionAlongPathObjects(const SMESH::ListOfIDSources & theNodes,
2842 const SMESH::ListOfIDSources & theEdges,
2843 const SMESH::ListOfIDSources & theFaces,
2844 SMESH::SMESH_IDSource_ptr thePathMesh,
2845 GEOM::GEOM_Object_ptr thePathShape,
2846 CORBA::Long theNodeStart,
2847 CORBA::Boolean theHasAngles,
2848 const SMESH::double_array & theAngles,
2849 CORBA::Boolean theLinearVariation,
2850 CORBA::Boolean theHasRefPoint,
2851 const SMESH::PointStruct & theRefPoint,
2853 SMESH::SMESH_MeshEditor::Extrusion_Error& theError)
2854 throw (SALOME::SALOME_Exception)
2859 SMESH::ListOfGroups_var aGroups = new SMESH::ListOfGroups;
2861 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2862 if ( thePathMesh->_is_nil() )
2863 return aGroups._retn();
2866 SMESH_subMesh* aSubMesh = 0;
2867 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2868 if ( thePathShape->_is_nil() )
2870 // thePathMesh should be either a sub-mesh or a mesh with 1D elements only
2871 if ( SMESH_subMesh_i* sm = SMESH::DownCast<SMESH_subMesh_i*>( thePathMesh ))
2873 SMESH::SMESH_Mesh_var mesh = thePathMesh->GetMesh();
2874 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
2875 if ( !aMeshImp ) return aGroups._retn();
2876 aSubMesh = aMeshImp->GetImpl().GetSubMeshContaining( sm->GetId() );
2877 if ( !aSubMesh ) return aGroups._retn();
2879 else if ( !aMeshImp ||
2880 aMeshImp->NbEdges() != aMeshImp->NbElements() )
2882 return aGroups._retn();
2887 if ( !aMeshImp ) return aGroups._retn();
2888 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2889 aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2890 if ( !aSubMesh /*|| !aSubMesh->GetSubMeshDS()*/ )
2891 return aGroups._retn();
2894 SMDS_MeshNode* nodeStart =
2895 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
2897 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2898 return aGroups._retn();
2901 TIDSortedElemSet elemsNodes[2];
2902 for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) {
2903 SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE );
2904 while ( nIt->more() ) elemsNodes[1].insert( nIt->next() );
2906 for ( int i = 0, nb = theEdges.length(); i < nb; ++i )
2907 idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge );
2908 for ( int i = 0, nb = theFaces.length(); i < nb; ++i )
2909 idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face );
2911 list<double> angles;
2912 for ( CORBA::ULong i = 0; i < theAngles.length(); i++ ) {
2913 angles.push_back( theAngles[i] );
2916 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
2918 int nbOldGroups = myMesh->NbGroup();
2920 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2921 if ( myIsPreviewMode )
2923 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2924 TPreviewMesh * tmpMesh = getPreviewMesh();
2925 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2926 tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid );
2927 workElements = & copyElements[0];
2928 theMakeGroups = false;
2931 ::SMESH_MeshEditor::Extrusion_Error error;
2933 error = getEditor().ExtrusionAlongTrack( workElements, &(aMeshImp->GetImpl()), nodeStart,
2934 theHasAngles, angles, theLinearVariation,
2935 theHasRefPoint, refPnt, theMakeGroups );
2937 error = getEditor().ExtrusionAlongTrack( workElements, aSubMesh, nodeStart,
2938 theHasAngles, angles, theLinearVariation,
2939 theHasRefPoint, refPnt, theMakeGroups );
2941 declareMeshModified( /*isReComputeSafe=*/true );
2942 theError = convExtrError( error );
2944 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2945 if ( theMakeGroups ) {
2946 list<int> groupIDs = myMesh->GetGroupIds();
2947 list<int>::iterator newBegin = groupIDs.begin();
2948 std::advance( newBegin, nbOldGroups ); // skip old groups
2949 groupIDs.erase( groupIDs.begin(), newBegin );
2950 aGroups = getGroups( & groupIDs );
2951 if ( ! &aGroups.in() ) aGroups = new SMESH::ListOfGroups;
2954 if ( !myIsPreviewMode ) {
2955 if ( aGroups->length() > 0 ) aPythonDump << "(" << aGroups << ", error) = ";
2956 else aPythonDump << "(_noGroups, error) = ";
2957 aPythonDump << this << ".ExtrusionAlongPathObjects( "
2961 << thePathMesh << ", "
2962 << thePathShape << ", "
2963 << theNodeStart << ", "
2964 << theHasAngles << ", "
2965 << TVar( theAngles ) << ", "
2966 << theLinearVariation << ", "
2967 << theHasRefPoint << ", "
2968 << "SMESH.PointStruct( "
2969 << TVar( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2970 << TVar( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2971 << TVar( theHasRefPoint ? theRefPoint.z : 0 ) << " ), "
2972 << theMakeGroups << " )";
2976 getPreviewMesh()->Remove( SMDSAbs_Volume );
2979 return aGroups._retn();
2981 SMESH_CATCH( SMESH::throwCorbaException );
2985 //================================================================================
2987 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
2988 * of given angles along path steps
2989 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
2990 * which proceeds the extrusion
2991 * \param PathShape is shape(edge); as the mesh can be complex, the edge
2992 * is used to define the sub-mesh for the path
2994 //================================================================================
2996 SMESH::double_array*
2997 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
2998 GEOM::GEOM_Object_ptr thePathShape,
2999 const SMESH::double_array & theAngles)
3001 SMESH::double_array_var aResult = new SMESH::double_array();
3002 int nbAngles = theAngles.length();
3003 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
3005 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3006 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3007 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3008 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
3009 return aResult._retn();
3010 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
3011 if ( nbSteps == nbAngles )
3013 aResult.inout() = theAngles;
3017 aResult->length( nbSteps );
3018 double rAn2St = double( nbAngles ) / double( nbSteps );
3019 double angPrev = 0, angle;
3020 for ( int iSt = 0; iSt < nbSteps; ++iSt )
3022 double angCur = rAn2St * ( iSt+1 );
3023 double angCurFloor = floor( angCur );
3024 double angPrevFloor = floor( angPrev );
3025 if ( angPrevFloor == angCurFloor )
3026 angle = rAn2St * theAngles[ int( angCurFloor ) ];
3029 int iP = int( angPrevFloor );
3030 double angPrevCeil = ceil(angPrev);
3031 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
3033 int iC = int( angCurFloor );
3034 if ( iC < nbAngles )
3035 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
3037 iP = int( angPrevCeil );
3039 angle += theAngles[ iC ];
3041 aResult[ iSt ] = angle;
3046 // Update Python script
3047 TPythonDump() << "rotAngles = " << theAngles;
3048 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
3049 << thePathMesh << ", "
3050 << thePathShape << ", "
3053 return aResult._retn();
3056 //=======================================================================
3059 //=======================================================================
3061 SMESH::ListOfGroups*
3062 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
3063 const SMESH::AxisStruct & theAxis,
3064 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3065 CORBA::Boolean theCopy,
3067 ::SMESH_Mesh* theTargetMesh)
3068 throw (SALOME::SALOME_Exception)
3073 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3074 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3076 if ( theTargetMesh )
3080 switch ( theMirrorType ) {
3081 case SMESH::SMESH_MeshEditor::POINT:
3082 aTrsf.SetMirror( P );
3084 case SMESH::SMESH_MeshEditor::AXIS:
3085 aTrsf.SetMirror( gp_Ax1( P, V ));
3088 aTrsf.SetMirror( gp_Ax2( P, V ));
3091 TIDSortedElemSet copyElements;
3092 TIDSortedElemSet* workElements = & theElements;
3094 if ( myIsPreviewMode )
3096 TPreviewMesh * tmpMesh = getPreviewMesh();
3097 tmpMesh->Copy( theElements, copyElements);
3098 if ( !theCopy && !theTargetMesh )
3100 TIDSortedElemSet elemsAround, elemsAroundCopy;
3101 getElementsAround( theElements, getMeshDS(), elemsAround );
3102 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3104 workElements = & copyElements;
3105 theMakeGroups = false;
3108 ::SMESH_MeshEditor::PGroupIDs groupIds =
3109 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3111 if ( !myIsPreviewMode )
3113 if ( theTargetMesh )
3114 theTargetMesh->GetMeshDS()->Modified();
3116 declareMeshModified( /*isReComputeSafe=*/false );
3119 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3121 SMESH_CATCH( SMESH::throwCorbaException );
3125 //=======================================================================
3128 //=======================================================================
3130 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3131 const SMESH::AxisStruct & theAxis,
3132 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3133 CORBA::Boolean theCopy)
3134 throw (SALOME::SALOME_Exception)
3136 if ( !myIsPreviewMode ) {
3137 TPythonDump() << this << ".Mirror( "
3138 << theIDsOfElements << ", "
3140 << mirrorTypeName(theMirrorType) << ", "
3143 if ( theIDsOfElements.length() > 0 )
3145 TIDSortedElemSet elements;
3146 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3147 mirror(elements, theAxis, theMirrorType, theCopy, false);
3152 //=======================================================================
3153 //function : MirrorObject
3155 //=======================================================================
3157 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3158 const SMESH::AxisStruct & theAxis,
3159 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3160 CORBA::Boolean theCopy)
3161 throw (SALOME::SALOME_Exception)
3163 if ( !myIsPreviewMode ) {
3164 TPythonDump() << this << ".MirrorObject( "
3165 << theObject << ", "
3167 << mirrorTypeName(theMirrorType) << ", "
3170 TIDSortedElemSet elements;
3172 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3174 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3175 mirror(elements, theAxis, theMirrorType, theCopy, false);
3178 //=======================================================================
3179 //function : MirrorMakeGroups
3181 //=======================================================================
3183 SMESH::ListOfGroups*
3184 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3185 const SMESH::AxisStruct& theMirror,
3186 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3187 throw (SALOME::SALOME_Exception)
3189 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3191 SMESH::ListOfGroups * aGroups = 0;
3192 if ( theIDsOfElements.length() > 0 )
3194 TIDSortedElemSet elements;
3195 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3196 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3198 if (!myIsPreviewMode) {
3199 dumpGroupsList(aPythonDump, aGroups);
3200 aPythonDump << this << ".MirrorMakeGroups( "
3201 << theIDsOfElements << ", "
3202 << theMirror << ", "
3203 << mirrorTypeName(theMirrorType) << " )";
3208 //=======================================================================
3209 //function : MirrorObjectMakeGroups
3211 //=======================================================================
3213 SMESH::ListOfGroups*
3214 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3215 const SMESH::AxisStruct& theMirror,
3216 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3217 throw (SALOME::SALOME_Exception)
3219 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3221 SMESH::ListOfGroups * aGroups = 0;
3222 TIDSortedElemSet elements;
3223 if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3224 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3226 if (!myIsPreviewMode)
3228 dumpGroupsList(aPythonDump,aGroups);
3229 aPythonDump << this << ".MirrorObjectMakeGroups( "
3230 << theObject << ", "
3231 << theMirror << ", "
3232 << mirrorTypeName(theMirrorType) << " )";
3237 //=======================================================================
3238 //function : MirrorMakeMesh
3240 //=======================================================================
3242 SMESH::SMESH_Mesh_ptr
3243 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
3244 const SMESH::AxisStruct& theMirror,
3245 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3246 CORBA::Boolean theCopyGroups,
3247 const char* theMeshName)
3248 throw (SALOME::SALOME_Exception)
3250 SMESH_Mesh_i* mesh_i;
3251 SMESH::SMESH_Mesh_var mesh;
3252 { // open new scope to dump "MakeMesh" command
3253 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3255 TPythonDump pydump; // to prevent dump at mesh creation
3257 mesh = makeMesh( theMeshName );
3258 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3259 if (mesh_i && theIDsOfElements.length() > 0 )
3261 TIDSortedElemSet elements;
3262 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3263 mirror(elements, theMirror, theMirrorType,
3264 false, theCopyGroups, & mesh_i->GetImpl());
3265 mesh_i->CreateGroupServants();
3268 if (!myIsPreviewMode) {
3269 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
3270 << theIDsOfElements << ", "
3271 << theMirror << ", "
3272 << mirrorTypeName(theMirrorType) << ", "
3273 << theCopyGroups << ", '"
3274 << theMeshName << "' )";
3279 if (!myIsPreviewMode && mesh_i)
3280 mesh_i->GetGroups();
3282 return mesh._retn();
3285 //=======================================================================
3286 //function : MirrorObjectMakeMesh
3288 //=======================================================================
3290 SMESH::SMESH_Mesh_ptr
3291 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3292 const SMESH::AxisStruct& theMirror,
3293 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3294 CORBA::Boolean theCopyGroups,
3295 const char* theMeshName)
3296 throw (SALOME::SALOME_Exception)
3298 SMESH_Mesh_i* mesh_i;
3299 SMESH::SMESH_Mesh_var mesh;
3300 { // open new scope to dump "MakeMesh" command
3301 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3303 TPythonDump pydump; // to prevent dump at mesh creation
3305 mesh = makeMesh( theMeshName );
3306 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3307 TIDSortedElemSet elements;
3309 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3311 mirror(elements, theMirror, theMirrorType,
3312 false, theCopyGroups, & mesh_i->GetImpl());
3313 mesh_i->CreateGroupServants();
3315 if (!myIsPreviewMode) {
3316 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
3317 << theObject << ", "
3318 << theMirror << ", "
3319 << mirrorTypeName(theMirrorType) << ", "
3320 << theCopyGroups << ", '"
3321 << theMeshName << "' )";
3326 if (!myIsPreviewMode && mesh_i)
3327 mesh_i->GetGroups();
3329 return mesh._retn();
3332 //=======================================================================
3333 //function : translate
3335 //=======================================================================
3337 SMESH::ListOfGroups*
3338 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
3339 const SMESH::DirStruct & theVector,
3340 CORBA::Boolean theCopy,
3342 ::SMESH_Mesh* theTargetMesh)
3343 throw (SALOME::SALOME_Exception)
3348 if ( theTargetMesh )
3352 const SMESH::PointStruct * P = &theVector.PS;
3353 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
3355 TIDSortedElemSet copyElements;
3356 TIDSortedElemSet* workElements = &theElements;
3358 if ( myIsPreviewMode )
3360 TPreviewMesh * tmpMesh = getPreviewMesh();
3361 tmpMesh->Copy( theElements, copyElements);
3362 if ( !theCopy && !theTargetMesh )
3364 TIDSortedElemSet elemsAround, elemsAroundCopy;
3365 getElementsAround( theElements, getMeshDS(), elemsAround );
3366 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3368 workElements = & copyElements;
3369 theMakeGroups = false;
3372 ::SMESH_MeshEditor::PGroupIDs groupIds =
3373 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3375 if ( !myIsPreviewMode )
3377 if ( theTargetMesh )
3378 theTargetMesh->GetMeshDS()->Modified();
3380 declareMeshModified( /*isReComputeSafe=*/false );
3383 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3385 SMESH_CATCH( SMESH::throwCorbaException );
3389 //=======================================================================
3390 //function : Translate
3392 //=======================================================================
3394 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
3395 const SMESH::DirStruct & theVector,
3396 CORBA::Boolean theCopy)
3397 throw (SALOME::SALOME_Exception)
3399 if (!myIsPreviewMode) {
3400 TPythonDump() << this << ".Translate( "
3401 << theIDsOfElements << ", "
3402 << theVector << ", "
3405 if (theIDsOfElements.length()) {
3406 TIDSortedElemSet elements;
3407 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3408 translate(elements, theVector, theCopy, false);
3412 //=======================================================================
3413 //function : TranslateObject
3415 //=======================================================================
3417 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
3418 const SMESH::DirStruct & theVector,
3419 CORBA::Boolean theCopy)
3420 throw (SALOME::SALOME_Exception)
3422 if (!myIsPreviewMode) {
3423 TPythonDump() << this << ".TranslateObject( "
3424 << theObject << ", "
3425 << theVector << ", "
3428 TIDSortedElemSet elements;
3430 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3432 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3433 translate(elements, theVector, theCopy, false);
3436 //=======================================================================
3437 //function : TranslateMakeGroups
3439 //=======================================================================
3441 SMESH::ListOfGroups*
3442 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
3443 const SMESH::DirStruct& theVector)
3444 throw (SALOME::SALOME_Exception)
3446 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3448 SMESH::ListOfGroups * aGroups = 0;
3449 if (theIDsOfElements.length()) {
3450 TIDSortedElemSet elements;
3451 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3452 aGroups = translate(elements,theVector,true,true);
3454 if (!myIsPreviewMode) {
3455 dumpGroupsList(aPythonDump, aGroups);
3456 aPythonDump << this << ".TranslateMakeGroups( "
3457 << theIDsOfElements << ", "
3458 << theVector << " )";
3463 //=======================================================================
3464 //function : TranslateObjectMakeGroups
3466 //=======================================================================
3468 SMESH::ListOfGroups*
3469 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3470 const SMESH::DirStruct& theVector)
3471 throw (SALOME::SALOME_Exception)
3473 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3475 SMESH::ListOfGroups * aGroups = 0;
3476 TIDSortedElemSet elements;
3477 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3478 aGroups = translate(elements, theVector, true, true);
3480 if (!myIsPreviewMode) {
3481 dumpGroupsList(aPythonDump, aGroups);
3482 aPythonDump << this << ".TranslateObjectMakeGroups( "
3483 << theObject << ", "
3484 << theVector << " )";
3489 //=======================================================================
3490 //function : TranslateMakeMesh
3492 //=======================================================================
3494 SMESH::SMESH_Mesh_ptr
3495 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
3496 const SMESH::DirStruct& theVector,
3497 CORBA::Boolean theCopyGroups,
3498 const char* theMeshName)
3499 throw (SALOME::SALOME_Exception)
3501 SMESH_Mesh_i* mesh_i;
3502 SMESH::SMESH_Mesh_var mesh;
3504 { // open new scope to dump "MakeMesh" command
3505 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3507 TPythonDump pydump; // to prevent dump at mesh creation
3509 mesh = makeMesh( theMeshName );
3510 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3512 if ( mesh_i && theIDsOfElements.length() )