1 // Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_MeshEditor_i.cxx
23 // Author : Nicolas REJNERI
30 // A macro used in SMESH_TryCatch.hxx,
31 // it re-raises a CORBA SALOME exception thrown by SMESH_MeshEditor_i and caught by SMESH_CATCH
32 #define SMY_OWN_CATCH \
33 catch ( SALOME::SALOME_Exception & e ) { throw e; }
35 #include "SMESH_MeshEditor_i.hxx"
37 #include "SMDS_EdgePosition.hxx"
38 #include "SMDS_ElemIterator.hxx"
39 #include "SMDS_FacePosition.hxx"
40 #include "SMDS_IteratorOnIterators.hxx"
41 #include "SMDS_LinearEdge.hxx"
42 #include "SMDS_Mesh0DElement.hxx"
43 #include "SMDS_MeshFace.hxx"
44 #include "SMDS_MeshVolume.hxx"
45 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
46 #include "SMDS_SetIterator.hxx"
47 #include "SMDS_VolumeTool.hxx"
48 #include "SMESHDS_Group.hxx"
49 #include "SMESHDS_GroupOnGeom.hxx"
50 #include "SMESH_ControlsDef.hxx"
51 #include "SMESH_Filter_i.hxx"
52 #include "SMESH_Gen_i.hxx"
53 #include "SMESH_Group.hxx"
54 #include "SMESH_Group_i.hxx"
55 #include "SMESH_MeshAlgos.hxx"
56 #include "SMESH_MeshPartDS.hxx"
57 #include "SMESH_MesherHelper.hxx"
58 #include "SMESH_PythonDump.hxx"
59 #include "SMESH_subMeshEventListener.hxx"
60 #include "SMESH_subMesh_i.hxx"
62 #include <utilities.h>
63 #include <Utils_ExceptHandlers.hxx>
64 #include <Utils_CorbaException.hxx>
65 #include <SALOMEDS_wrap.hxx>
66 #include <SALOME_GenericObj_i.hh>
67 #include <Basics_OCCTVersion.hxx>
69 #include <BRepAdaptor_Surface.hxx>
70 #include <BRep_Tool.hxx>
71 #include <TopExp_Explorer.hxx>
73 #include <TopoDS_Edge.hxx>
74 #include <TopoDS_Face.hxx>
79 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
83 #include <Standard_Failure.hxx>
86 #include <Standard_ErrorHandler.hxx>
92 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
94 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
97 using SMESH::TPythonDump;
100 namespace MeshEditor_I {
102 //=============================================================================
104 * \brief Mesh to apply modifications for preview purposes
106 //=============================================================================
108 struct TPreviewMesh: public SMESH_Mesh
110 SMDSAbs_ElementType myPreviewType; // type to show
112 TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
113 _isShapeToMesh = (_id =_studyId = 0);
114 _myMeshDS = new SMESHDS_Mesh( _id, true );
115 myPreviewType = previewElements;
117 //!< Copy a set of elements
118 void Copy(const TIDSortedElemSet & theElements,
119 TIDSortedElemSet& theCopyElements,
120 SMDSAbs_ElementType theSelectType = SMDSAbs_All,
121 SMDSAbs_ElementType theAvoidType = SMDSAbs_All)
123 // loop on theIDsOfElements
124 TIDSortedElemSet::const_iterator eIt = theElements.begin();
125 for ( ; eIt != theElements.end(); ++eIt )
127 const SMDS_MeshElement* anElem = *eIt;
128 if ( !anElem ) continue;
129 SMDSAbs_ElementType type = anElem->GetType();
130 if ( type == theAvoidType ||
131 ( theSelectType != SMDSAbs_All && type != theSelectType ))
133 const SMDS_MeshElement* anElemCopy;
134 if ( type == SMDSAbs_Node)
135 anElemCopy = Copy( cast2Node(anElem) );
137 anElemCopy = Copy( anElem );
139 theCopyElements.insert( theCopyElements.end(), anElemCopy );
143 SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
145 // copy element nodes
146 int anElemNbNodes = anElem->NbNodes();
147 vector< int > anElemNodesID( anElemNbNodes ) ;
148 SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
149 for ( int i = 0; itElemNodes->more(); i++)
151 const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
153 anElemNodesID[i] = anElemNode->GetID();
156 // creates a corresponding element on copied nodes
157 ::SMESH_MeshEditor::ElemFeatures elemType;
158 elemType.Init( anElem, /*basicOnly=*/false );
159 elemType.SetID( anElem->GetID() );
160 SMDS_MeshElement* anElemCopy =
161 ::SMESH_MeshEditor(this).AddElement( anElemNodesID, elemType );
165 SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
167 return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(),
168 anElemNode->GetID());
172 GetMeshDS()->ClearMesh();
174 void Remove( SMDSAbs_ElementType type )
176 SMDS_ElemIteratorPtr eIt = GetMeshDS()->elementsIterator( type );
177 while ( eIt->more() )
178 GetMeshDS()->RemoveFreeElement( eIt->next(), /*sm=*/0, /*fromGroups=*/false );
180 };// struct TPreviewMesh
182 static SMESH_NodeSearcher * theNodeSearcher = 0;
183 static SMESH_ElementSearcher * theElementSearcher = 0;
185 //=============================================================================
187 * \brief Deleter of theNodeSearcher at any compute event occured
189 //=============================================================================
191 struct TSearchersDeleter : public SMESH_subMeshEventListener
194 string myMeshPartIOR;
196 TSearchersDeleter(): SMESH_subMeshEventListener( false, // won't be deleted by submesh
197 "SMESH_MeshEditor_i::TSearchersDeleter"),
199 //!< Delete theNodeSearcher
202 if ( theNodeSearcher ) delete theNodeSearcher; theNodeSearcher = 0;
203 if ( theElementSearcher ) delete theElementSearcher; theElementSearcher = 0;
205 typedef map < int, SMESH_subMesh * > TDependsOnMap;
206 //!< The meshod called by submesh: do my main job
207 void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
208 SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
210 if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
212 Unset( sm->GetFather() );
215 //!< set self on all submeshes and delete theNodeSearcher if other mesh is set
216 void Set(SMESH_Mesh* mesh, const string& meshPartIOR = string())
218 if ( myMesh != mesh || myMeshPartIOR != meshPartIOR)
225 myMeshPartIOR = meshPartIOR;
226 SMESH_subMesh* sm = mesh->GetSubMesh( mesh->GetShapeToMesh() );
227 SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true );
228 while ( smIt->more() )
231 sm->SetEventListener( this, 0, sm );
235 //!< delete self from all submeshes
236 void Unset(SMESH_Mesh* mesh)
238 if ( SMESH_subMesh* sm = mesh->GetSubMeshContaining(1) ) {
239 SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true );
240 while ( smIt->more() )
241 smIt->next()->DeleteEventListener( this );
246 } theSearchersDeleter;
248 TCollection_AsciiString mirrorTypeName( SMESH::SMESH_MeshEditor::MirrorType theMirrorType )
250 TCollection_AsciiString typeStr;
251 switch ( theMirrorType ) {
252 case SMESH::SMESH_MeshEditor::POINT:
253 typeStr = "SMESH.SMESH_MeshEditor.POINT";
255 case SMESH::SMESH_MeshEditor::AXIS:
256 typeStr = "SMESH.SMESH_MeshEditor.AXIS";
259 typeStr = "SMESH.SMESH_MeshEditor.PLANE";
263 //================================================================================
265 * \brief function for conversion of long_array to TIDSortedElemSet
266 * \param IDs - array of IDs
267 * \param aMesh - mesh
268 * \param aMap - collection to fill
269 * \param aType - element type
271 //================================================================================
273 void arrayToSet(const SMESH::long_array & IDs,
274 const SMESHDS_Mesh* aMesh,
275 TIDSortedElemSet& aMap,
276 const SMDSAbs_ElementType aType = SMDSAbs_All,
277 SMDS_MeshElement::Filter* aFilter = NULL)
279 SMDS_MeshElement::NonNullFilter filter1;
280 SMDS_MeshElement::TypeFilter filter2( aType );
282 if ( aFilter == NULL )
283 aFilter = ( aType == SMDSAbs_All ) ? (SMDS_MeshElement::Filter*) &filter1 : (SMDS_MeshElement::Filter*) &filter2;
285 SMDS_MeshElement::Filter & filter = *aFilter;
287 if ( aType == SMDSAbs_Node )
288 for (int i=0; i<IDs.length(); i++) {
289 const SMDS_MeshElement * elem = aMesh->FindNode( IDs[i] );
291 aMap.insert( aMap.end(), elem );
294 for (int i=0; i<IDs.length(); i++) {
295 const SMDS_MeshElement * elem = aMesh->FindElement( IDs[i] );
297 aMap.insert( aMap.end(), elem );
301 //================================================================================
303 * \brief Retrieve nodes from SMESH_IDSource
305 //================================================================================
307 void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject,
308 const SMESHDS_Mesh* theMeshDS,
309 TIDSortedNodeSet& theNodeSet)
312 if ( CORBA::is_nil( theObject ) )
314 SMESH::array_of_ElementType_var types = theObject->GetTypes();
315 SMESH::long_array_var aElementsId = theObject->GetIDs();
316 if ( types->length() == 1 && types[0] == SMESH::NODE)
318 for(int i = 0; i < aElementsId->length(); i++)
319 if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] ))
320 theNodeSet.insert( theNodeSet.end(), n);
322 else if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
324 SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator();
325 while ( nIt->more( ))
326 if( const SMDS_MeshElement * elem = nIt->next() )
327 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
331 for(int i = 0; i < aElementsId->length(); i++)
332 if( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] ))
333 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
337 //================================================================================
339 * \brief Returns elements connected to the given elements
341 //================================================================================
343 void getElementsAround(const TIDSortedElemSet& theElements,
344 const SMESHDS_Mesh* theMeshDS,
345 TIDSortedElemSet& theElementsAround)
347 if ( theElements.empty() ) return;
349 SMDSAbs_ElementType elemType = (*theElements.begin())->GetType();
350 bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() );
352 theMeshDS->GetMeshInfo().NbElements( elemType ) == theElements.size() )
353 return; // all the elements are in theElements
356 elemType = SMDSAbs_All;
358 vector<bool> isNodeChecked( theMeshDS->NbNodes(), false );
360 TIDSortedElemSet::const_iterator elemIt = theElements.begin();
361 for ( ; elemIt != theElements.end(); ++elemIt )
363 const SMDS_MeshElement* e = *elemIt;
364 int i = e->NbCornerNodes();
367 const SMDS_MeshNode* n = e->GetNode( i );
368 if ( !isNodeChecked[ n->GetID() ])
370 isNodeChecked[ n->GetID() ] = true;
371 SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
372 while ( invIt->more() )
374 const SMDS_MeshElement* elemAround = invIt->next();
375 if ( !theElements.count( elemAround ))
376 theElementsAround.insert( elemAround );
383 //================================================================================
385 * \brief Return a string used to detect change of mesh part on which theElementSearcher
386 * is going to be used
388 //================================================================================
390 string getPartIOR( SMESH::SMESH_IDSource_ptr theMeshPart, SMESH::ElementType type)
392 string partIOR = SMESH_Gen_i::GetORB()->object_to_string( theMeshPart );
393 if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( theMeshPart ))
394 // take into account passible group modification
395 partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() );
396 partIOR += SMESH_Comment( type );
400 } // namespace MeshEditor_I
402 using namespace MeshEditor_I;
404 //=============================================================================
408 //=============================================================================
410 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview):
412 myMesh( &theMesh->GetImpl() ),
414 myIsPreviewMode ( isPreview ),
420 //================================================================================
424 //================================================================================
426 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
428 PortableServer::POA_var poa = SMESH_Gen_i::GetPOA();
429 PortableServer::ObjectId_var anObjectId = poa->servant_to_id(this);
430 poa->deactivate_object(anObjectId.in());
432 //deleteAuxIDSources();
433 delete myPreviewMesh; myPreviewMesh = 0;
434 delete myPreviewEditor; myPreviewEditor = 0;
437 //================================================================================
439 * \brief Returns the mesh
441 //================================================================================
443 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::GetMesh()
445 return myMesh_i->_this();
448 //================================================================================
450 * \brief Clear members
452 //================================================================================
454 void SMESH_MeshEditor_i::initData(bool deleteSearchers)
456 if ( myIsPreviewMode ) {
457 if ( myPreviewMesh ) myPreviewMesh->RemoveAll();
460 if ( deleteSearchers )
461 TSearchersDeleter::Delete();
463 getEditor().GetError().reset();
464 getEditor().ClearLastCreated();
467 //================================================================================
469 * \brief Increment mesh modif time and optionally record that the performed
470 * modification may influence futher mesh re-compute.
471 * \param [in] isReComputeSafe - true if the modification does not influence
472 * futher mesh re-compute
474 //================================================================================
476 void SMESH_MeshEditor_i::declareMeshModified( bool isReComputeSafe )
478 myMesh->GetMeshDS()->Modified();
479 if ( !isReComputeSafe )
480 myMesh->SetIsModified( true );
483 //================================================================================
485 * \brief Return either myEditor or myPreviewEditor depending on myIsPreviewMode.
486 * WARNING: in preview mode call getPreviewMesh() before getEditor()!
488 //================================================================================
490 ::SMESH_MeshEditor& SMESH_MeshEditor_i::getEditor()
492 if ( myIsPreviewMode && !myPreviewEditor ) {
493 if ( !myPreviewMesh ) getPreviewMesh();
494 myPreviewEditor = new ::SMESH_MeshEditor( myPreviewMesh );
496 return myIsPreviewMode ? *myPreviewEditor : myEditor;
499 //================================================================================
501 * \brief Initialize and return myPreviewMesh
502 * \param previewElements - type of elements to show in preview
504 * WARNING: call it once par a method!
506 //================================================================================
508 TPreviewMesh * SMESH_MeshEditor_i::getPreviewMesh(SMDSAbs_ElementType previewElements)
510 if ( !myPreviewMesh || myPreviewMesh->myPreviewType != previewElements )
512 delete myPreviewEditor;
514 delete myPreviewMesh;
515 myPreviewMesh = new TPreviewMesh( previewElements );
517 myPreviewMesh->Clear();
518 return myPreviewMesh;
521 //================================================================================
523 * Return data of mesh edition preview
525 //================================================================================
527 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
528 throw (SALOME::SALOME_Exception)
531 const bool hasBadElems = ( getEditor().GetError() && getEditor().GetError()->HasBadElems() );
533 if ( myIsPreviewMode || hasBadElems ) { // --- MeshPreviewStruct filling ---
535 list<int> aNodesConnectivity;
536 typedef map<int, int> TNodesMap;
539 SMESHDS_Mesh* aMeshDS;
540 std::auto_ptr< SMESH_MeshPartDS > aMeshPartDS;
542 aMeshPartDS.reset( new SMESH_MeshPartDS( getEditor().GetError()->myBadElements ));
543 aMeshDS = aMeshPartDS.get();
546 aMeshDS = getEditor().GetMeshDS();
548 myPreviewData = new SMESH::MeshPreviewStruct();
549 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
552 SMDSAbs_ElementType previewType = SMDSAbs_All;
554 if (TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( getEditor().GetMesh() )) {
555 previewType = aPreviewMesh->myPreviewType;
556 switch ( previewType ) {
557 case SMDSAbs_Edge : break;
558 case SMDSAbs_Face : break;
559 case SMDSAbs_Volume: break;
561 if ( aMeshDS->GetMeshInfo().NbElements() == 0 ) previewType = SMDSAbs_Node;
565 myPreviewData->elementTypes.length( aMeshDS->GetMeshInfo().NbElements( previewType ));
567 SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator(previewType);
569 while ( itMeshElems->more() ) {
570 const SMDS_MeshElement* aMeshElem = itMeshElems->next();
571 SMDS_NodeIteratorPtr itElemNodes =
572 (( aMeshElem->GetEntityType() == SMDSEntity_Quad_Polygon ) ?
573 aMeshElem->interlacedNodesIterator() :
574 aMeshElem->nodeIterator() );
575 while ( itElemNodes->more() ) {
576 const SMDS_MeshNode* aMeshNode = itElemNodes->next();
577 int aNodeID = aMeshNode->GetID();
578 TNodesMap::iterator anIter = nodesMap.find(aNodeID);
579 if ( anIter == nodesMap.end() ) {
580 // filling the nodes coordinates
581 myPreviewData->nodesXYZ[j].x = aMeshNode->X();
582 myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
583 myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
584 anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
587 aNodesConnectivity.push_back(anIter->second);
590 // filling the elements types
591 SMDSAbs_ElementType aType = aMeshElem->GetType();
592 bool isPoly = aMeshElem->IsPoly();
593 myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
594 myPreviewData->elementTypes[i].isPoly = isPoly;
595 myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
598 myPreviewData->nodesXYZ.length( j );
600 // filling the elements connectivities
601 list<int>::iterator aConnIter = aNodesConnectivity.begin();
602 myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
603 for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
604 myPreviewData->elementConnectivities[i] = *aConnIter;
606 return myPreviewData._retn();
608 SMESH_CATCH( SMESH::throwCorbaException );
612 //================================================================================
614 * \brief Returns list of it's IDs of created nodes
615 * \retval SMESH::long_array* - list of node ID
617 //================================================================================
619 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
620 throw (SALOME::SALOME_Exception)
623 SMESH::long_array_var myLastCreatedNodes = new SMESH::long_array();
625 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedNodes();
626 myLastCreatedNodes->length( aSeq.Length() );
627 for (int i = 1; i <= aSeq.Length(); i++)
628 myLastCreatedNodes[i-1] = aSeq.Value(i)->GetID();
630 return myLastCreatedNodes._retn();
631 SMESH_CATCH( SMESH::throwCorbaException );
635 //================================================================================
637 * \brief Returns list of it's IDs of created elements
638 * \retval SMESH::long_array* - list of elements' ID
640 //================================================================================
642 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
643 throw (SALOME::SALOME_Exception)
646 SMESH::long_array_var myLastCreatedElems = new SMESH::long_array();
648 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
649 myLastCreatedElems->length( aSeq.Length() );
650 for ( int i = 1; i <= aSeq.Length(); i++ )
651 myLastCreatedElems[i-1] = aSeq.Value(i)->GetID();
653 return myLastCreatedElems._retn();
654 SMESH_CATCH( SMESH::throwCorbaException );
658 //=======================================================================
659 //function : ClearLastCreated
660 //purpose : Clears sequences of last created elements and nodes
661 //=======================================================================
663 void SMESH_MeshEditor_i::ClearLastCreated() throw (SALOME::SALOME_Exception)
666 getEditor().ClearLastCreated();
667 SMESH_CATCH( SMESH::throwCorbaException );
670 //=======================================================================
672 * Returns description of an error/warning occured during the last operation
673 * WARNING: ComputeError.code >= 100 and no corresponding enum in IDL API
675 //=======================================================================
677 SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError()
678 throw (SALOME::SALOME_Exception)
681 SMESH::ComputeError_var errOut = new SMESH::ComputeError;
682 SMESH_ComputeErrorPtr& errIn = getEditor().GetError();
683 if ( errIn && !errIn->IsOK() )
685 errOut->code = -( errIn->myName < 0 ? errIn->myName + 1: errIn->myName ); // -1 -> 0
686 errOut->comment = errIn->myComment.c_str();
687 errOut->subShapeID = -1;
688 errOut->hasBadMesh = !errIn->myBadElements.empty();
693 errOut->subShapeID = -1;
694 errOut->hasBadMesh = false;
697 return errOut._retn();
698 SMESH_CATCH( SMESH::throwCorbaException );
702 //=======================================================================
703 //function : MakeIDSource
704 //purpose : Wrap a sequence of ids in a SMESH_IDSource.
705 // Call UnRegister() as you fininsh using it!!
706 //=======================================================================
708 struct SMESH_MeshEditor_i::_IDSource : public virtual POA_SMESH::SMESH_IDSource,
709 public virtual SALOME::GenericObj_i
711 SMESH::long_array _ids;
712 SMESH::ElementType _type;
713 SMESH::SMESH_Mesh_ptr _mesh;
714 SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); }
715 SMESH::long_array* GetMeshInfo() { return 0; }
716 SMESH::long_array* GetNbElementsByType()
718 SMESH::long_array_var aRes = new SMESH::long_array();
719 aRes->length(SMESH::NB_ELEMENT_TYPES);
720 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
721 aRes[ i ] = ( i == _type ) ? _ids.length() : 0;
724 SMESH::SMESH_Mesh_ptr GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _mesh ); }
725 bool IsMeshInfoCorrect() { return true; }
726 SMESH::array_of_ElementType* GetTypes()
728 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
729 if ( _ids.length() > 0 ) {
733 return types._retn();
735 SALOMEDS::TMPFile* GetVtkUgStream()
737 SALOMEDS::TMPFile_var SeqFile;
738 return SeqFile._retn();
742 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
743 SMESH::ElementType type)
745 _IDSource* idSrc = new _IDSource;
746 idSrc->_mesh = myMesh_i->_this();
749 if ( type == SMESH::ALL && ids.length() > 0 )
750 idSrc->_type = myMesh_i->GetElementType( ids[0], true );
752 SMESH::SMESH_IDSource_var anIDSourceVar = idSrc->_this();
754 return anIDSourceVar._retn();
757 bool SMESH_MeshEditor_i::IsTemporaryIDSource( SMESH::SMESH_IDSource_ptr& idSource )
759 return SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource );
762 CORBA::Long* SMESH_MeshEditor_i::GetTemporaryIDs( SMESH::SMESH_IDSource_ptr& idSource,
765 if ( _IDSource* tmpIdSource = SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource ))
767 nbIds = (int) tmpIdSource->_ids.length();
768 return & tmpIdSource->_ids[0];
774 // void SMESH_MeshEditor_i::deleteAuxIDSources()
776 // std::list< _IDSource* >::iterator idSrcIt = myAuxIDSources.begin();
777 // for ( ; idSrcIt != myAuxIDSources.end(); ++idSrcIt )
779 // myAuxIDSources.clear();
782 //=============================================================================
786 //=============================================================================
789 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
790 throw (SALOME::SALOME_Exception)
797 for (int i = 0; i < IDsOfElements.length(); i++)
798 IdList.push_back( IDsOfElements[i] );
800 // Update Python script
801 TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
804 bool ret = getEditor().Remove( IdList, false );
806 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 ); // issue 0020693
809 SMESH_CATCH( SMESH::throwCorbaException );
813 //=============================================================================
817 //=============================================================================
819 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
820 throw (SALOME::SALOME_Exception)
826 for (int i = 0; i < IDsOfNodes.length(); i++)
827 IdList.push_back( IDsOfNodes[i] );
829 // Update Python script
830 TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
832 bool ret = getEditor().Remove( IdList, true );
834 declareMeshModified( /*isReComputeSafe=*/ !ret ); // issue 0020693
837 SMESH_CATCH( SMESH::throwCorbaException );
841 //=============================================================================
845 //=============================================================================
847 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
848 throw (SALOME::SALOME_Exception)
853 // Update Python script
854 TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
856 // Create filter to find all orphan nodes
857 SMESH::Controls::Filter::TIdSequence seq;
858 SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
859 SMESH::Controls::Filter::GetElementsId( getMeshDS(), predicate, seq );
861 // remove orphan nodes (if there are any)
863 for ( int i = 0; i < seq.size(); i++ )
864 IdList.push_back( seq[i] );
866 int nbNodesBefore = myMesh->NbNodes();
867 getEditor().Remove( IdList, true );
868 int nbNodesAfter = myMesh->NbNodes();
870 declareMeshModified( /*isReComputeSafe=*/ IdList.size() == 0 ); // issue 0020693
871 return nbNodesBefore - nbNodesAfter;
873 SMESH_CATCH( SMESH::throwCorbaException );
877 //=============================================================================
881 //=============================================================================
883 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,CORBA::Double y, CORBA::Double z)
884 throw (SALOME::SALOME_Exception)
889 const SMDS_MeshNode* N = getMeshDS()->AddNode(x, y, z);
891 // Update Python script
892 TPythonDump() << "nodeID = " << this << ".AddNode( "
893 << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )";
895 declareMeshModified( /*isReComputeSafe=*/false );
898 SMESH_CATCH( SMESH::throwCorbaException );
902 //=============================================================================
904 * Create 0D element on the given node.
906 //=============================================================================
908 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
909 throw (SALOME::SALOME_Exception)
914 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
915 SMDS_MeshElement* elem = getMeshDS()->Add0DElement(aNode);
917 // Update Python script
918 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
920 declareMeshModified( /*isReComputeSafe=*/false );
922 return elem ? elem->GetID() : 0;
924 SMESH_CATCH( SMESH::throwCorbaException );
928 //=============================================================================
930 * Create a ball element on the given node.
932 //=============================================================================
934 CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diameter)
935 throw (SALOME::SALOME_Exception)
940 if ( diameter < std::numeric_limits<double>::min() )
941 THROW_SALOME_CORBA_EXCEPTION("Invalid diameter", SALOME::BAD_PARAM);
943 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
944 SMDS_MeshElement* elem = getMeshDS()->AddBall(aNode, diameter);
946 // Update Python script
947 TPythonDump() << "ballElem = "
948 << this << ".AddBall( " << IDOfNode << ", " << diameter <<" )";
950 declareMeshModified( /*isReComputeSafe=*/false );
951 return elem ? elem->GetID() : 0;
953 SMESH_CATCH( SMESH::throwCorbaException );
957 //=============================================================================
959 * Create an edge, either linear and quadratic (this is determed
960 * by number of given nodes, two or three)
962 //=============================================================================
964 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
965 throw (SALOME::SALOME_Exception)
970 int NbNodes = IDsOfNodes.length();
971 SMDS_MeshElement* elem = 0;
974 CORBA::Long index1 = IDsOfNodes[0];
975 CORBA::Long index2 = IDsOfNodes[1];
976 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(index1),
977 getMeshDS()->FindNode(index2));
979 // Update Python script
980 TPythonDump() << "edge = " << this << ".AddEdge([ "
981 << index1 << ", " << index2 <<" ])";
984 CORBA::Long n1 = IDsOfNodes[0];
985 CORBA::Long n2 = IDsOfNodes[1];
986 CORBA::Long n12 = IDsOfNodes[2];
987 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(n1),
988 getMeshDS()->FindNode(n2),
989 getMeshDS()->FindNode(n12));
990 // Update Python script
991 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
992 <<n1<<", "<<n2<<", "<<n12<<" ])";
995 declareMeshModified( /*isReComputeSafe=*/false );
996 return elem ? elem->GetID() : 0;
998 SMESH_CATCH( SMESH::throwCorbaException );
1002 //=============================================================================
1006 //=============================================================================
1008 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
1009 throw (SALOME::SALOME_Exception)
1014 int NbNodes = IDsOfNodes.length();
1020 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1021 for (int i = 0; i < NbNodes; i++)
1022 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1024 SMDS_MeshElement* elem = 0;
1026 case 3: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]); break;
1027 case 4: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]); break;
1028 case 6: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1029 nodes[4], nodes[5]); break;
1030 case 7: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1031 nodes[4], nodes[5], nodes[6]); break;
1032 case 8: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1033 nodes[4], nodes[5], nodes[6], nodes[7]); break;
1034 case 9: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1035 nodes[4], nodes[5], nodes[6], nodes[7],
1037 default: elem = getMeshDS()->AddPolygonalFace(nodes);
1040 // Update Python script
1041 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
1043 declareMeshModified( /*isReComputeSafe=*/false );
1045 return elem ? elem->GetID() : 0;
1047 SMESH_CATCH( SMESH::throwCorbaException );
1051 //=============================================================================
1055 //=============================================================================
1057 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
1058 throw (SALOME::SALOME_Exception)
1063 int NbNodes = IDsOfNodes.length();
1064 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1065 for (int i = 0; i < NbNodes; i++)
1066 if ( ! ( nodes[i] = getMeshDS()->FindNode( IDsOfNodes[i] )))
1069 const SMDS_MeshElement* elem = getMeshDS()->AddPolygonalFace(nodes);
1071 // Update Python script
1072 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
1074 declareMeshModified( /*isReComputeSafe=*/false );
1075 return elem ? elem->GetID() : 0;
1077 SMESH_CATCH( SMESH::throwCorbaException );
1081 //=============================================================================
1083 * AddQuadPolygonalFace
1085 //=============================================================================
1087 CORBA::Long SMESH_MeshEditor_i::AddQuadPolygonalFace (const SMESH::long_array & IDsOfNodes)
1088 throw (SALOME::SALOME_Exception)
1093 int NbNodes = IDsOfNodes.length();
1094 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1095 for (int i = 0; i < NbNodes; i++)
1096 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1098 const SMDS_MeshElement* elem = getMeshDS()->AddQuadPolygonalFace(nodes);
1100 // Update Python script
1101 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
1103 declareMeshModified( /*isReComputeSafe=*/false );
1104 return elem ? elem->GetID() : 0;
1106 SMESH_CATCH( SMESH::throwCorbaException );
1110 //=============================================================================
1112 * Create volume, either linear and quadratic (this is determed
1113 * by number of given nodes)
1115 //=============================================================================
1117 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
1118 throw (SALOME::SALOME_Exception)
1123 int NbNodes = IDsOfNodes.length();
1124 vector< const SMDS_MeshNode*> n(NbNodes);
1125 for(int i=0;i<NbNodes;i++)
1126 n[i]= getMeshDS()->FindNode(IDsOfNodes[i]);
1128 SMDS_MeshElement* elem = 0;
1131 case 4 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
1132 case 5 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
1133 case 6 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
1134 case 8 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
1135 case 10:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1136 n[6],n[7],n[8],n[9]);
1138 case 12:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1139 n[6],n[7],n[8],n[9],n[10],n[11]);
1141 case 13:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
1142 n[7],n[8],n[9],n[10],n[11],n[12]);
1144 case 15:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
1145 n[9],n[10],n[11],n[12],n[13],n[14]);
1147 case 20:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1148 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1149 n[15],n[16],n[17],n[18],n[19]);
1151 case 27:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1152 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1153 n[15],n[16],n[17],n[18],n[19],
1154 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
1158 // Update Python script
1159 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
1161 declareMeshModified( /*isReComputeSafe=*/false );
1162 return elem ? elem->GetID() : 0;
1164 SMESH_CATCH( SMESH::throwCorbaException );
1168 //=============================================================================
1170 * AddPolyhedralVolume
1172 //=============================================================================
1173 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
1174 const SMESH::long_array & Quantities)
1175 throw (SALOME::SALOME_Exception)
1180 int NbNodes = IDsOfNodes.length();
1181 std::vector<const SMDS_MeshNode*> n (NbNodes);
1182 for (int i = 0; i < NbNodes; i++)
1184 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDsOfNodes[i]);
1185 if (!aNode) return 0;
1189 int NbFaces = Quantities.length();
1190 std::vector<int> q (NbFaces);
1191 for (int j = 0; j < NbFaces; j++)
1192 q[j] = Quantities[j];
1194 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(n, q);
1196 // Update Python script
1197 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
1198 << IDsOfNodes << ", " << Quantities << " )";
1200 declareMeshModified( /*isReComputeSafe=*/false );
1201 return elem ? elem->GetID() : 0;
1203 SMESH_CATCH( SMESH::throwCorbaException );
1207 //=============================================================================
1209 * AddPolyhedralVolumeByFaces
1211 //=============================================================================
1213 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
1214 throw (SALOME::SALOME_Exception)
1219 int NbFaces = IdsOfFaces.length();
1220 std::vector<const SMDS_MeshNode*> poly_nodes;
1221 std::vector<int> quantities (NbFaces);
1223 for (int i = 0; i < NbFaces; i++) {
1224 const SMDS_MeshElement* aFace = getMeshDS()->FindElement(IdsOfFaces[i]);
1225 quantities[i] = aFace->NbNodes();
1227 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
1228 while (It->more()) {
1229 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
1233 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
1235 // Update Python script
1236 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
1237 << IdsOfFaces << " )";
1239 declareMeshModified( /*isReComputeSafe=*/false );
1240 return elem ? elem->GetID() : 0;
1242 SMESH_CATCH( SMESH::throwCorbaException );
1246 //=============================================================================
1248 // \brief Create 0D elements on all nodes of the given object except those
1249 // nodes on which a 0D element already exists.
1250 // \param theObject object on whose nodes 0D elements will be created.
1251 // \param theGroupName optional name of a group to add 0D elements created
1252 // and/or found on nodes of \a theObject.
1253 // \return an object (a new group or a temporary SMESH_IDSource) holding
1254 // ids of new and/or found 0D elements.
1256 //=============================================================================
1258 SMESH::SMESH_IDSource_ptr
1259 SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObject,
1260 const char* theGroupName)
1261 throw (SALOME::SALOME_Exception)
1266 SMESH::SMESH_IDSource_var result;
1269 TIDSortedElemSet elements, elems0D;
1270 if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
1271 getEditor().Create0DElementsOnAllNodes( elements, elems0D );
1273 SMESH::long_array_var newElems = new SMESH::long_array;
1274 newElems->length( elems0D.size() );
1275 TIDSortedElemSet::iterator eIt = elems0D.begin();
1276 for ( size_t i = 0; i < elems0D.size(); ++i, ++eIt )
1277 newElems[ i ] = (*eIt)->GetID();
1279 SMESH::SMESH_GroupBase_var groupToFill;
1280 if ( theGroupName && strlen( theGroupName ))
1282 // Get existing group named theGroupName
1283 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
1284 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
1285 SMESH::SMESH_GroupBase_var group = groups[i];
1286 if ( !group->_is_nil() ) {
1287 CORBA::String_var name = group->GetName();
1288 if ( strcmp( name.in(), theGroupName ) == 0 && group->GetType() == SMESH::ELEM0D ) {
1289 groupToFill = group;
1294 if ( groupToFill->_is_nil() )
1295 groupToFill = myMesh_i->CreateGroup( SMESH::ELEM0D, theGroupName );
1296 else if ( !SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1297 groupToFill = myMesh_i->ConvertToStandalone( groupToFill );
1300 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1302 group_i->Add( newElems );
1303 result = SMESH::SMESH_IDSource::_narrow( groupToFill );
1304 pyDump << groupToFill;
1308 result = MakeIDSource( newElems, SMESH::ELEM0D );
1309 pyDump << "elem0DIDs";
1312 pyDump << " = " << this << ".Create0DElementsOnAllNodes( "
1313 << theObject << ", '" << theGroupName << "' )";
1315 return result._retn();
1317 SMESH_CATCH( SMESH::throwCorbaException );
1321 //=============================================================================
1323 * \brief Bind a node to a vertex
1324 * \param NodeID - node ID
1325 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1326 * \retval boolean - false if NodeID or VertexID is invalid
1328 //=============================================================================
1330 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
1331 throw (SALOME::SALOME_Exception)
1335 SMESHDS_Mesh * mesh = getMeshDS();
1336 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1338 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1340 if ( mesh->MaxShapeIndex() < VertexID )
1341 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1343 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
1344 if ( shape.ShapeType() != TopAbs_VERTEX )
1345 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1347 mesh->SetNodeOnVertex( node, VertexID );
1349 myMesh->SetIsModified( true );
1351 SMESH_CATCH( SMESH::throwCorbaException );
1354 //=============================================================================
1356 * \brief Store node position on an edge
1357 * \param NodeID - node ID
1358 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
1359 * \param paramOnEdge - parameter on edge where the node is located
1360 * \retval boolean - false if any parameter is invalid
1362 //=============================================================================
1364 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
1365 CORBA::Double paramOnEdge)
1366 throw (SALOME::SALOME_Exception)
1370 SMESHDS_Mesh * mesh = getMeshDS();
1371 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1373 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1375 if ( mesh->MaxShapeIndex() < EdgeID )
1376 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1378 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
1379 if ( shape.ShapeType() != TopAbs_EDGE )
1380 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1383 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
1384 if ( paramOnEdge < f || paramOnEdge > l )
1385 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
1387 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
1389 myMesh->SetIsModified( true );
1391 SMESH_CATCH( SMESH::throwCorbaException );
1394 //=============================================================================
1396 * \brief Store node position on a face
1397 * \param NodeID - node ID
1398 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
1399 * \param u - U parameter on face where the node is located
1400 * \param v - V parameter on face where the node is located
1401 * \retval boolean - false if any parameter is invalid
1403 //=============================================================================
1405 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
1406 CORBA::Double u, CORBA::Double v)
1407 throw (SALOME::SALOME_Exception)
1410 SMESHDS_Mesh * mesh = getMeshDS();
1411 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1413 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1415 if ( mesh->MaxShapeIndex() < FaceID )
1416 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1418 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
1419 if ( shape.ShapeType() != TopAbs_FACE )
1420 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1422 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
1423 bool isOut = ( u < surf.FirstUParameter() ||
1424 u > surf.LastUParameter() ||
1425 v < surf.FirstVParameter() ||
1426 v > surf.LastVParameter() );
1430 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
1431 << " u( " << surf.FirstUParameter()
1432 << "," << surf.LastUParameter()
1433 << ") v( " << surf.FirstVParameter()
1434 << "," << surf.LastVParameter() << ")" );
1436 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
1439 mesh->SetNodeOnFace( node, FaceID, u, v );
1440 myMesh->SetIsModified( true );
1442 SMESH_CATCH( SMESH::throwCorbaException );
1445 //=============================================================================
1447 * \brief Bind a node to a solid
1448 * \param NodeID - node ID
1449 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1450 * \retval boolean - false if NodeID or SolidID is invalid
1452 //=============================================================================
1454 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
1455 throw (SALOME::SALOME_Exception)
1458 SMESHDS_Mesh * mesh = getMeshDS();
1459 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1461 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1463 if ( mesh->MaxShapeIndex() < SolidID )
1464 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1466 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
1467 if ( shape.ShapeType() != TopAbs_SOLID &&
1468 shape.ShapeType() != TopAbs_SHELL)
1469 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1471 mesh->SetNodeInVolume( node, SolidID );
1473 SMESH_CATCH( SMESH::throwCorbaException );
1476 //=============================================================================
1478 * \brief Bind an element to a shape
1479 * \param ElementID - element ID
1480 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
1482 //=============================================================================
1484 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
1485 CORBA::Long ShapeID)
1486 throw (SALOME::SALOME_Exception)
1489 SMESHDS_Mesh * mesh = getMeshDS();
1490 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
1492 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
1494 if ( mesh->MaxShapeIndex() < ShapeID || ShapeID < 1 )
1495 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1497 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1498 if ( shape.ShapeType() != TopAbs_EDGE &&
1499 shape.ShapeType() != TopAbs_FACE &&
1500 shape.ShapeType() != TopAbs_SOLID &&
1501 shape.ShapeType() != TopAbs_SHELL )
1502 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1504 mesh->SetMeshElementOnShape( elem, ShapeID );
1506 myMesh->SetIsModified( true );
1508 SMESH_CATCH( SMESH::throwCorbaException );
1511 //=============================================================================
1515 //=============================================================================
1517 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1518 CORBA::Long NodeID2)
1519 throw (SALOME::SALOME_Exception)
1524 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1525 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1529 // Update Python script
1530 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1531 << NodeID1 << ", " << NodeID2 << " )";
1533 int ret = getEditor().InverseDiag ( n1, n2 );
1535 declareMeshModified( /*isReComputeSafe=*/false );
1538 SMESH_CATCH( SMESH::throwCorbaException );
1542 //=============================================================================
1546 //=============================================================================
1548 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1549 CORBA::Long NodeID2)
1550 throw (SALOME::SALOME_Exception)
1555 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1556 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1560 // Update Python script
1561 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1562 << NodeID1 << ", " << NodeID2 << " )";
1565 bool stat = getEditor().DeleteDiag ( n1, n2 );
1567 declareMeshModified( /*isReComputeSafe=*/!stat );
1571 SMESH_CATCH( SMESH::throwCorbaException );
1575 //=============================================================================
1579 //=============================================================================
1581 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1582 throw (SALOME::SALOME_Exception)
1587 for (int i = 0; i < IDsOfElements.length(); i++)
1589 CORBA::Long index = IDsOfElements[i];
1590 const SMDS_MeshElement * elem = getMeshDS()->FindElement(index);
1592 getEditor().Reorient( elem );
1594 // Update Python script
1595 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1597 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 );
1600 SMESH_CATCH( SMESH::throwCorbaException );
1604 //=============================================================================
1608 //=============================================================================
1610 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1611 throw (SALOME::SALOME_Exception)
1616 TPythonDump aTPythonDump; // suppress dump in Reorient()
1618 prepareIdSource( theObject );
1620 SMESH::long_array_var anElementsId = theObject->GetIDs();
1621 CORBA::Boolean isDone = Reorient(anElementsId);
1623 // Update Python script
1624 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1626 declareMeshModified( /*isReComputeSafe=*/ anElementsId->length() == 0 );
1629 SMESH_CATCH( SMESH::throwCorbaException );
1633 //=======================================================================
1634 //function : Reorient2D
1635 //purpose : Reorient faces contained in \a the2Dgroup.
1636 // the2Dgroup - the mesh or its part to reorient
1637 // theDirection - desired direction of normal of \a theFace
1638 // theFace - ID of face whose orientation is checked.
1639 // It can be < 1 then \a thePoint is used to find a face.
1640 // thePoint - is used to find a face if \a theFace < 1.
1641 // return number of reoriented elements.
1642 //=======================================================================
1644 CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
1645 const SMESH::DirStruct& theDirection,
1646 CORBA::Long theFace,
1647 const SMESH::PointStruct& thePoint)
1648 throw (SALOME::SALOME_Exception)
1651 initData(/*deleteSearchers=*/false);
1653 TIDSortedElemSet elements;
1654 IDSource_Error error;
1655 idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error );
1656 if ( error == IDSource_EMPTY )
1658 if ( error == IDSource_INVALID )
1659 THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
1662 const SMDS_MeshElement* face = 0;
1665 face = getMeshDS()->FindElement( theFace );
1667 THROW_SALOME_CORBA_EXCEPTION("Inexistent face given", SALOME::BAD_PARAM);
1668 if ( face->GetType() != SMDSAbs_Face )
1669 THROW_SALOME_CORBA_EXCEPTION("Wrong element type", SALOME::BAD_PARAM);
1673 // create theElementSearcher if needed
1674 theSearchersDeleter.Set( myMesh, getPartIOR( the2Dgroup, SMESH::FACE ));
1675 if ( !theElementSearcher )
1677 if ( elements.empty() ) // search in the whole mesh
1679 if ( myMesh->NbFaces() == 0 )
1680 THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM);
1682 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
1686 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
1687 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
1689 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt);
1693 gp_Pnt p( thePoint.x, thePoint.y, thePoint.z );
1694 face = theElementSearcher->FindClosestTo( p, SMDSAbs_Face );
1697 THROW_SALOME_CORBA_EXCEPTION("No face found by point", SALOME::INTERNAL_ERROR );
1698 if ( !elements.empty() && !elements.count( face ))
1699 THROW_SALOME_CORBA_EXCEPTION("Found face is not in the group", SALOME::BAD_PARAM );
1702 const SMESH::PointStruct * P = &theDirection.PS;
1703 gp_Vec dirVec( P->x, P->y, P->z );
1704 if ( dirVec.Magnitude() < std::numeric_limits< double >::min() )
1705 THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM);
1707 int nbReori = getEditor().Reorient2D( elements, dirVec, face );
1710 declareMeshModified( /*isReComputeSafe=*/false );
1712 TPythonDump() << this << ".Reorient2D( "
1713 << the2Dgroup << ", "
1714 << theDirection << ", "
1716 << thePoint << " )";
1720 SMESH_CATCH( SMESH::throwCorbaException );
1724 //=======================================================================
1725 //function : Reorient2DBy3D
1726 //purpose : Reorient faces basing on orientation of adjacent volumes.
1727 //=======================================================================
1729 CORBA::Long SMESH_MeshEditor_i::Reorient2DBy3D(const SMESH::ListOfIDSources& faceGroups,
1730 SMESH::SMESH_IDSource_ptr volumeGroup,
1731 CORBA::Boolean outsideNormal)
1732 throw (SALOME::SALOME_Exception)
1737 TIDSortedElemSet volumes;
1738 IDSource_Error volsError;
1739 idSourceToSet( volumeGroup, getMeshDS(), volumes, SMDSAbs_Volume, /*emptyIfMesh=*/1, &volsError);
1742 for ( size_t i = 0; i < faceGroups.length(); ++i )
1744 SMESH::SMESH_IDSource_ptr faceGrp = faceGroups[i].in();
1746 TIDSortedElemSet faces;
1747 IDSource_Error error;
1748 idSourceToSet( faceGrp, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error );
1749 if ( error == IDSource_INVALID && faceGroups.length() == 1 )
1750 THROW_SALOME_CORBA_EXCEPTION("No faces in a given object", SALOME::BAD_PARAM);
1751 if ( error == IDSource_OK && volsError != IDSource_OK )
1752 THROW_SALOME_CORBA_EXCEPTION("No volumes in a given object", SALOME::BAD_PARAM);
1754 nbReori += getEditor().Reorient2DBy3D( faces, volumes, outsideNormal );
1756 if ( error != IDSource_EMPTY && faces.empty() ) // all faces in the mesh treated
1761 declareMeshModified( /*isReComputeSafe=*/false );
1763 TPythonDump() << this << ".Reorient2DBy3D( "
1764 << faceGroups << ", "
1765 << volumeGroup << ", "
1766 << outsideNormal << " )";
1770 SMESH_CATCH( SMESH::throwCorbaException );
1774 //=============================================================================
1776 * \brief Fuse neighbour triangles into quadrangles.
1778 //=============================================================================
1780 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1781 SMESH::NumericalFunctor_ptr Criterion,
1782 CORBA::Double MaxAngle)
1783 throw (SALOME::SALOME_Exception)
1788 SMESHDS_Mesh* aMesh = getMeshDS();
1789 TIDSortedElemSet faces,copyFaces;
1790 SMDS_MeshElement::GeomFilter triaFilter(SMDSGeom_TRIANGLE);
1791 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face, & triaFilter);
1792 TIDSortedElemSet* workElements = & faces;
1794 if ( myIsPreviewMode ) {
1795 SMDSAbs_ElementType select = SMDSAbs_Face;
1796 getPreviewMesh( SMDSAbs_Face )->Copy( faces, copyFaces, select );
1797 workElements = & copyFaces;
1800 SMESH::NumericalFunctor_i* aNumericalFunctor =
1801 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1802 SMESH::Controls::NumericalFunctorPtr aCrit;
1803 if ( !aNumericalFunctor )
1804 aCrit.reset( new SMESH::Controls::MaxElementLength2D() );
1806 aCrit = aNumericalFunctor->GetNumericalFunctor();
1808 if ( !myIsPreviewMode ) {
1809 // Update Python script
1810 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1811 << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1814 bool stat = getEditor().TriToQuad( *workElements, aCrit, MaxAngle );
1816 declareMeshModified( /*isReComputeSafe=*/!stat );
1819 SMESH_CATCH( SMESH::throwCorbaException );
1823 //=============================================================================
1825 * \brief Fuse neighbour triangles into quadrangles.
1827 //=============================================================================
1829 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1830 SMESH::NumericalFunctor_ptr Criterion,
1831 CORBA::Double MaxAngle)
1832 throw (SALOME::SALOME_Exception)
1837 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1839 prepareIdSource( theObject );
1840 SMESH::long_array_var anElementsId = theObject->GetIDs();
1841 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1843 if ( !myIsPreviewMode ) {
1844 SMESH::NumericalFunctor_i* aNumericalFunctor =
1845 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1847 // Update Python script
1848 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1849 << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1854 SMESH_CATCH( SMESH::throwCorbaException );
1858 //=============================================================================
1860 * \brief Split quadrangles into triangles.
1862 //=============================================================================
1864 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1865 SMESH::NumericalFunctor_ptr Criterion)
1866 throw (SALOME::SALOME_Exception)
1871 SMESHDS_Mesh* aMesh = getMeshDS();
1872 TIDSortedElemSet faces;
1873 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1875 SMESH::NumericalFunctor_i* aNumericalFunctor =
1876 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1877 SMESH::Controls::NumericalFunctorPtr aCrit;
1878 if ( !aNumericalFunctor )
1879 aCrit.reset( new SMESH::Controls::AspectRatio() );
1881 aCrit = aNumericalFunctor->GetNumericalFunctor();
1884 // Update Python script
1885 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1887 CORBA::Boolean stat = getEditor().QuadToTri( faces, aCrit );
1889 declareMeshModified( /*isReComputeSafe=*/false );
1892 SMESH_CATCH( SMESH::throwCorbaException );
1896 //=============================================================================
1898 * \brief Split quadrangles into triangles.
1900 //=============================================================================
1902 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1903 SMESH::NumericalFunctor_ptr Criterion)
1904 throw (SALOME::SALOME_Exception)
1909 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1911 prepareIdSource( theObject );
1912 SMESH::long_array_var anElementsId = theObject->GetIDs();
1913 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1915 SMESH::NumericalFunctor_i* aNumericalFunctor =
1916 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1918 // Update Python script
1919 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1921 declareMeshModified( /*isReComputeSafe=*/false );
1924 SMESH_CATCH( SMESH::throwCorbaException );
1928 //================================================================================
1930 * \brief Split each of quadrangles into 4 triangles.
1931 * \param [in] theObject - theQuads Container of quadrangles to split.
1933 //================================================================================
1935 void SMESH_MeshEditor_i::QuadTo4Tri (SMESH::SMESH_IDSource_ptr theObject)
1936 throw (SALOME::SALOME_Exception)
1941 TIDSortedElemSet faces;
1942 if ( !idSourceToSet( theObject, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/true ) &&
1944 THROW_SALOME_CORBA_EXCEPTION("No faces given", SALOME::BAD_PARAM);
1946 getEditor().QuadTo4Tri( faces );
1947 TPythonDump() << this << ".QuadTo4Tri( " << theObject << " )";
1949 SMESH_CATCH( SMESH::throwCorbaException );
1952 //=============================================================================
1954 * \brief Split quadrangles into triangles.
1956 //=============================================================================
1958 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1959 CORBA::Boolean Diag13)
1960 throw (SALOME::SALOME_Exception)
1965 SMESHDS_Mesh* aMesh = getMeshDS();
1966 TIDSortedElemSet faces;
1967 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1969 // Update Python script
1970 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1971 << IDsOfElements << ", " << Diag13 << " )";
1973 CORBA::Boolean stat = getEditor().QuadToTri( faces, Diag13 );
1975 declareMeshModified( /*isReComputeSafe=*/ !stat );
1978 SMESH_CATCH( SMESH::throwCorbaException );
1982 //=============================================================================
1984 * \brief Split quadrangles into triangles.
1986 //=============================================================================
1988 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1989 CORBA::Boolean Diag13)
1990 throw (SALOME::SALOME_Exception)
1995 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
1997 prepareIdSource( theObject );
1998 SMESH::long_array_var anElementsId = theObject->GetIDs();
1999 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
2001 // Update Python script
2002 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
2003 << theObject << ", " << Diag13 << " )";
2005 declareMeshModified( /*isReComputeSafe=*/!isDone );
2008 SMESH_CATCH( SMESH::throwCorbaException );
2013 //=============================================================================
2015 * Find better splitting of the given quadrangle.
2016 * \param IDOfQuad ID of the quadrangle to be splitted.
2017 * \param Criterion A criterion to choose a diagonal for splitting.
2018 * \return 1 if 1-3 diagonal is better, 2 if 2-4
2019 * diagonal is better, 0 if error occurs.
2021 //=============================================================================
2023 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
2024 SMESH::NumericalFunctor_ptr Criterion)
2025 throw (SALOME::SALOME_Exception)
2030 const SMDS_MeshElement* quad = getMeshDS()->FindElement(IDOfQuad);
2031 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
2033 SMESH::NumericalFunctor_i* aNumericalFunctor =
2034 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
2035 SMESH::Controls::NumericalFunctorPtr aCrit;
2036 if (aNumericalFunctor)
2037 aCrit = aNumericalFunctor->GetNumericalFunctor();
2039 aCrit.reset(new SMESH::Controls::AspectRatio());
2041 int id = getEditor().BestSplit(quad, aCrit);
2042 declareMeshModified( /*isReComputeSafe=*/ id < 1 );
2046 SMESH_CATCH( SMESH::throwCorbaException );
2050 //================================================================================
2052 * \brief Split volumic elements into tetrahedrons
2054 //================================================================================
2056 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
2057 CORBA::Short methodFlags)
2058 throw (SALOME::SALOME_Exception)
2063 ::SMESH_MeshEditor::TFacetOfElem elemSet;
2064 const int noneFacet = -1;
2065 SMDS_ElemIteratorPtr volIt = myMesh_i->GetElements( elems, SMESH::VOLUME );
2066 while( volIt->more() )
2067 elemSet.insert( elemSet.end(), make_pair( volIt->next(), noneFacet ));
2069 getEditor().SplitVolumes( elemSet, int( methodFlags ));
2070 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2072 TPythonDump() << this << ".SplitVolumesIntoTetra( "
2073 << elems << ", " << methodFlags << " )";
2075 SMESH_CATCH( SMESH::throwCorbaException );
2078 //================================================================================
2080 * \brief Split hexahedra into triangular prisms
2081 * \param elems - elements to split
2082 * \param facetToSplitNormal - normal used to find a facet of hexahedron
2083 * to split into triangles
2084 * \param methodFlags - flags passing splitting method:
2085 * 1 - split the hexahedron into 2 prisms
2086 * 2 - split the hexahedron into 4 prisms
2088 //================================================================================
2090 void SMESH_MeshEditor_i::SplitHexahedraIntoPrisms( SMESH::SMESH_IDSource_ptr elems,
2091 const SMESH::PointStruct & startHexPoint,
2092 const SMESH::DirStruct& facetToSplitNormal,
2093 CORBA::Short methodFlags,
2094 CORBA::Boolean allDomains)
2095 throw (SALOME::SALOME_Exception)
2099 prepareIdSource( elems );
2101 gp_Ax1 facetNorm( gp_Pnt( startHexPoint.x,
2104 gp_Dir( facetToSplitNormal.PS.x,
2105 facetToSplitNormal.PS.y,
2106 facetToSplitNormal.PS.z ));
2107 TIDSortedElemSet elemSet;
2108 SMESH::long_array_var anElementsId = elems->GetIDs();
2109 SMDS_MeshElement::GeomFilter filter( SMDSGeom_HEXA );
2110 arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume, &filter );
2112 ::SMESH_MeshEditor::TFacetOfElem elemFacets;
2113 while ( !elemSet.empty() )
2115 getEditor().GetHexaFacetsToSplit( elemSet, facetNorm, elemFacets );
2119 ::SMESH_MeshEditor::TFacetOfElem::iterator ef = elemFacets.begin();
2120 for ( ; ef != elemFacets.end(); ++ef )
2121 elemSet.erase( ef->first );
2124 if ( methodFlags == 2 )
2125 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_4_PRISMS );
2127 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_2_PRISMS );
2129 getEditor().SplitVolumes( elemFacets, int( methodFlags ));
2130 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2132 TPythonDump() << this << ".SplitHexahedraIntoPrisms( "
2134 << startHexPoint << ", "
2135 << facetToSplitNormal<< ", "
2136 << methodFlags<< ", "
2137 << allDomains << " )";
2139 SMESH_CATCH( SMESH::throwCorbaException );
2142 //================================================================================
2144 * \brief Split bi-quadratic elements into linear ones without creation of additional nodes:
2145 * - bi-quadratic triangle will be split into 3 linear quadrangles;
2146 * - bi-quadratic quadrangle will be split into 4 linear quadrangles;
2147 * - tri-quadratic hexahedron will be split into 8 linear hexahedra.
2148 * Quadratic elements of lower dimension adjacent to the split bi-quadratic element
2149 * will be split in order to keep the mesh conformal.
2150 * \param elems - elements to split
2152 //================================================================================
2154 void SMESH_MeshEditor_i::SplitBiQuadraticIntoLinear(const SMESH::ListOfIDSources& theElems)
2155 throw (SALOME::SALOME_Exception)
2160 TIDSortedElemSet elemSet;
2161 for ( size_t i = 0; i < theElems.length(); ++i )
2163 SMESH::SMESH_IDSource_ptr elems = theElems[i].in();
2164 SMESH::SMESH_Mesh_var mesh = elems->GetMesh();
2165 if ( mesh->GetId() != myMesh_i->GetId() )
2166 THROW_SALOME_CORBA_EXCEPTION("Wrong mesh of IDSource", SALOME::BAD_PARAM);
2168 idSourceToSet( elems, getMeshDS(), elemSet, SMDSAbs_All );
2170 getEditor().SplitBiQuadraticIntoLinear( elemSet );
2172 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2174 TPythonDump() << this << ".SplitBiQuadraticIntoLinear( "
2175 << theElems << " )";
2177 SMESH_CATCH( SMESH::throwCorbaException );
2180 //=======================================================================
2183 //=======================================================================
2186 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
2187 const SMESH::long_array & IDsOfFixedNodes,
2188 CORBA::Long MaxNbOfIterations,
2189 CORBA::Double MaxAspectRatio,
2190 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2191 throw (SALOME::SALOME_Exception)
2193 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2194 MaxAspectRatio, Method, false );
2198 //=======================================================================
2199 //function : SmoothParametric
2201 //=======================================================================
2204 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
2205 const SMESH::long_array & IDsOfFixedNodes,
2206 CORBA::Long MaxNbOfIterations,
2207 CORBA::Double MaxAspectRatio,
2208 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2209 throw (SALOME::SALOME_Exception)
2211 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2212 MaxAspectRatio, Method, true );
2216 //=======================================================================
2217 //function : SmoothObject
2219 //=======================================================================
2222 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
2223 const SMESH::long_array & IDsOfFixedNodes,
2224 CORBA::Long MaxNbOfIterations,
2225 CORBA::Double MaxAspectRatio,
2226 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2227 throw (SALOME::SALOME_Exception)
2229 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2230 MaxAspectRatio, Method, false);
2234 //=======================================================================
2235 //function : SmoothParametricObject
2237 //=======================================================================
2240 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
2241 const SMESH::long_array & IDsOfFixedNodes,
2242 CORBA::Long MaxNbOfIterations,
2243 CORBA::Double MaxAspectRatio,
2244 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2245 throw (SALOME::SALOME_Exception)
2247 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2248 MaxAspectRatio, Method, true);
2252 //=============================================================================
2256 //=============================================================================
2259 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
2260 const SMESH::long_array & IDsOfFixedNodes,
2261 CORBA::Long MaxNbOfIterations,
2262 CORBA::Double MaxAspectRatio,
2263 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2265 throw (SALOME::SALOME_Exception)
2270 SMESHDS_Mesh* aMesh = getMeshDS();
2272 TIDSortedElemSet elements;
2273 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
2275 set<const SMDS_MeshNode*> fixedNodes;
2276 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
2277 CORBA::Long index = IDsOfFixedNodes[i];
2278 const SMDS_MeshNode * node = aMesh->FindNode(index);
2280 fixedNodes.insert( node );
2282 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
2283 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
2284 method = ::SMESH_MeshEditor::CENTROIDAL;
2286 getEditor().Smooth(elements, fixedNodes, method,
2287 MaxNbOfIterations, MaxAspectRatio, IsParametric );
2289 declareMeshModified( /*isReComputeSafe=*/true ); // does not prevent re-compute
2291 // Update Python script
2292 TPythonDump() << "isDone = " << this << "."
2293 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
2294 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
2295 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2296 << "SMESH.SMESH_MeshEditor."
2297 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2298 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2302 SMESH_CATCH( SMESH::throwCorbaException );
2306 //=============================================================================
2310 //=============================================================================
2313 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
2314 const SMESH::long_array & IDsOfFixedNodes,
2315 CORBA::Long MaxNbOfIterations,
2316 CORBA::Double MaxAspectRatio,
2317 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2319 throw (SALOME::SALOME_Exception)
2324 TPythonDump aTPythonDump; // suppress dump in smooth()
2326 prepareIdSource( theObject );
2327 SMESH::long_array_var anElementsId = theObject->GetIDs();
2328 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
2329 MaxAspectRatio, Method, IsParametric);
2331 // Update Python script
2332 aTPythonDump << "isDone = " << this << "."
2333 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
2334 << theObject << ", " << IDsOfFixedNodes << ", "
2335 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2336 << "SMESH.SMESH_MeshEditor."
2337 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2338 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2342 SMESH_CATCH( SMESH::throwCorbaException );
2346 //=============================================================================
2350 //=============================================================================
2352 void SMESH_MeshEditor_i::RenumberNodes()
2353 throw (SALOME::SALOME_Exception)
2356 // Update Python script
2357 TPythonDump() << this << ".RenumberNodes()";
2359 getMeshDS()->Renumber( true );
2361 SMESH_CATCH( SMESH::throwCorbaException );
2364 //=============================================================================
2368 //=============================================================================
2370 void SMESH_MeshEditor_i::RenumberElements()
2371 throw (SALOME::SALOME_Exception)
2374 // Update Python script
2375 TPythonDump() << this << ".RenumberElements()";
2377 getMeshDS()->Renumber( false );
2379 SMESH_CATCH( SMESH::throwCorbaException );
2382 //=======================================================================
2384 * \brief Return groups by their IDs
2386 //=======================================================================
2388 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
2389 throw (SALOME::SALOME_Exception)
2394 myMesh_i->CreateGroupServants();
2395 return myMesh_i->GetGroups( *groupIDs );
2397 SMESH_CATCH( SMESH::throwCorbaException );
2401 //=======================================================================
2402 //function : RotationSweepObjects
2404 //=======================================================================
2406 SMESH::ListOfGroups*
2407 SMESH_MeshEditor_i::RotationSweepObjects(const SMESH::ListOfIDSources & theNodes,
2408 const SMESH::ListOfIDSources & theEdges,
2409 const SMESH::ListOfIDSources & theFaces,
2410 const SMESH::AxisStruct & theAxis,
2411 CORBA::Double theAngleInRadians,
2412 CORBA::Long theNbOfSteps,
2413 CORBA::Double theTolerance,
2414 const bool theMakeGroups)
2415 throw (SALOME::SALOME_Exception)
2420 TIDSortedElemSet elemsNodes[2];
2421 for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) {
2422 SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE );
2423 while ( nIt->more() ) elemsNodes[1].insert( nIt->next() );
2425 for ( int i = 0, nb = theEdges.length(); i < nb; ++i )
2426 idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge );
2427 for ( int i = 0, nb = theFaces.length(); i < nb; ++i )
2428 idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face );
2430 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2431 bool makeWalls=true;
2432 if ( myIsPreviewMode )
2434 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2435 TPreviewMesh * tmpMesh = getPreviewMesh();
2436 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2437 tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid );
2438 workElements = & copyElements[0];
2439 //makeWalls = false; -- faces are needed for preview
2442 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2444 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
2445 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
2447 ::SMESH_MeshEditor::PGroupIDs groupIds =
2448 getEditor().RotationSweep (workElements, Ax1, theAngleInRadians,
2449 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
2451 SMESH::ListOfGroups * aGroups = theMakeGroups ? getGroups( groupIds.get()) : 0;
2453 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2455 if ( !myIsPreviewMode )
2457 dumpGroupsList( aPythonDump, aGroups );
2458 aPythonDump << this<< ".RotationSweepObjects( "
2463 << TVar( theAngleInRadians ) << ", "
2464 << TVar( theNbOfSteps ) << ", "
2465 << TVar( theTolerance ) << ", "
2466 << theMakeGroups << " )";
2470 getPreviewMesh()->Remove( SMDSAbs_Volume );
2473 return aGroups ? aGroups : new SMESH::ListOfGroups;
2475 SMESH_CATCH( SMESH::throwCorbaException );
2479 namespace MeshEditor_I
2482 * \brief Structure used to pass extrusion parameters to ::SMESH_MeshEditor
2484 struct ExtrusionParams : public ::SMESH_MeshEditor::ExtrusParam
2486 bool myIsExtrusionByNormal;
2488 static int makeFlags( CORBA::Boolean MakeGroups,
2489 CORBA::Boolean ByAverageNormal = false,
2490 CORBA::Boolean UseInputElemsOnly = false,
2491 CORBA::Long Flags = 0,
2492 CORBA::Boolean MakeBoundary = true )
2494 if ( MakeGroups ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS;
2495 if ( ByAverageNormal ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BY_AVG_NORMAL;
2496 if ( UseInputElemsOnly) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY;
2497 if ( MakeBoundary ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BOUNDARY;
2501 ExtrusionParams(const SMESH::DirStruct & theDir,
2502 CORBA::Long theNbOfSteps,
2503 CORBA::Boolean theMakeGroups):
2504 ::SMESH_MeshEditor::ExtrusParam ( gp_Vec( theDir.PS.x,
2508 makeFlags( theMakeGroups )),
2509 myIsExtrusionByNormal( false )
2513 ExtrusionParams(const SMESH::DirStruct & theDir,
2514 CORBA::Long theNbOfSteps,
2515 CORBA::Boolean theMakeGroups,
2516 CORBA::Long theExtrFlags,
2517 CORBA::Double theSewTolerance):
2518 ::SMESH_MeshEditor::ExtrusParam ( gp_Vec( theDir.PS.x,
2522 makeFlags( theMakeGroups, false, false,
2523 theExtrFlags, false ),
2525 myIsExtrusionByNormal( false )
2528 // params for extrusion by normal
2529 ExtrusionParams(CORBA::Double theStepSize,
2530 CORBA::Long theNbOfSteps,
2531 CORBA::Short theDim,
2532 CORBA::Boolean theByAverageNormal,
2533 CORBA::Boolean theUseInputElemsOnly,
2534 CORBA::Boolean theMakeGroups ):
2535 ::SMESH_MeshEditor::ExtrusParam ( theStepSize,
2537 makeFlags( theMakeGroups,
2538 theByAverageNormal, theUseInputElemsOnly ),
2540 myIsExtrusionByNormal( true )
2546 Flags() &= ~(::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS);
2551 //=======================================================================
2553 * \brief Generate dim+1 elements by extrusion of elements along vector
2554 * \param [in] edges - edges to extrude: a list including groups, sub-meshes or a mesh
2555 * \param [in] faces - faces to extrude: a list including groups, sub-meshes or a mesh
2556 * \param [in] nodes - nodes to extrude: a list including groups, sub-meshes or a mesh
2557 * \param [in] stepVector - vector giving direction and distance of an extrusion step
2558 * \param [in] nbOfSteps - number of elements to generate from one element
2559 * \param [in] toMakeGroups - if true, new elements will be included into new groups
2560 * corresponding to groups the input elements included in.
2561 * \return ListOfGroups - new groups craeted if \a toMakeGroups is true
2563 //=======================================================================
2565 SMESH::ListOfGroups*
2566 SMESH_MeshEditor_i::ExtrusionSweepObjects(const SMESH::ListOfIDSources & theNodes,
2567 const SMESH::ListOfIDSources & theEdges,
2568 const SMESH::ListOfIDSources & theFaces,
2569 const SMESH::DirStruct & theStepVector,
2570 CORBA::Long theNbOfSteps,
2571 CORBA::Boolean theToMakeGroups)
2572 throw (SALOME::SALOME_Exception)
2577 ExtrusionParams params( theStepVector, theNbOfSteps, theToMakeGroups );
2579 TIDSortedElemSet elemsNodes[2];
2580 for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) {
2581 SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE );
2582 while ( nIt->more() ) elemsNodes[1].insert( nIt->next() );
2584 for ( int i = 0, nb = theEdges.length(); i < nb; ++i )
2585 idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge );
2586 for ( int i = 0, nb = theFaces.length(); i < nb; ++i )
2587 idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face );
2589 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2590 SMDSAbs_ElementType previewType = SMDSAbs_All; //SMDSAbs_Face;
2591 if ( myIsPreviewMode )
2593 // if ( (*elemsNodes.begin())->GetType() == SMDSAbs_Node )
2594 // previewType = SMDSAbs_Edge;
2596 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2597 TPreviewMesh * tmpMesh = getPreviewMesh( previewType );
2598 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2599 tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid );
2600 workElements = & copyElements[0];
2602 params.SetNoGroups();
2604 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2606 ::SMESH_MeshEditor::TTElemOfElemListMap aHistory;
2607 ::SMESH_MeshEditor::PGroupIDs groupIds =
2608 getEditor().ExtrusionSweep( workElements, params, aHistory );
2610 SMESH::ListOfGroups * aGroups = theToMakeGroups ? getGroups( groupIds.get()) : 0;
2612 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2614 if ( !myIsPreviewMode )
2616 dumpGroupsList( aPythonDump, aGroups );
2617 aPythonDump << this<< ".ExtrusionSweepObjects( "
2621 << theStepVector << ", "
2622 << TVar( theNbOfSteps ) << ", "
2623 << theToMakeGroups << " )";
2627 getPreviewMesh( previewType )->Remove( SMDSAbs_Volume );
2630 return aGroups ? aGroups : new SMESH::ListOfGroups;
2632 SMESH_CATCH( SMESH::throwCorbaException );
2636 //=======================================================================
2637 //function : ExtrusionByNormal
2639 //=======================================================================
2641 SMESH::ListOfGroups*
2642 SMESH_MeshEditor_i::ExtrusionByNormal(const SMESH::ListOfIDSources& objects,
2643 CORBA::Double stepSize,
2644 CORBA::Long nbOfSteps,
2645 CORBA::Boolean byAverageNormal,
2646 CORBA::Boolean useInputElemsOnly,
2647 CORBA::Boolean makeGroups,
2649 throw (SALOME::SALOME_Exception)
2654 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2656 ExtrusionParams params( stepSize, nbOfSteps, dim,
2657 byAverageNormal, useInputElemsOnly, makeGroups );
2659 SMDSAbs_ElementType elemType = ( dim == 1 ? SMDSAbs_Edge : SMDSAbs_Face );
2660 if ( objects.length() > 0 && !SMESH::DownCast<SMESH_Mesh_i*>( objects[0] ))
2662 SMESH::array_of_ElementType_var elemTypes = objects[0]->GetTypes();
2663 if (( elemTypes->length() == 1 ) &&
2664 ( elemTypes[0] == SMESH::EDGE || elemTypes[0] == SMESH::FACE ))
2665 elemType = ( SMDSAbs_ElementType ) elemTypes[0];
2668 TIDSortedElemSet elemsNodes[2];
2669 for ( int i = 0, nb = objects.length(); i < nb; ++i )
2670 idSourceToSet( objects[i], getMeshDS(), elemsNodes[0], elemType );
2672 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2673 SMDSAbs_ElementType previewType = SMDSAbs_Face;
2674 if ( myIsPreviewMode )
2676 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2677 TPreviewMesh * tmpMesh = getPreviewMesh( previewType );
2678 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2679 workElements = & copyElements[0];
2681 params.SetNoGroups();
2684 ::SMESH_MeshEditor::TTElemOfElemListMap aHistory;
2685 ::SMESH_MeshEditor::PGroupIDs groupIds =
2686 getEditor().ExtrusionSweep( workElements, params, aHistory );
2688 SMESH::ListOfGroups * aGroups = makeGroups ? getGroups( groupIds.get()) : 0;
2690 if (!myIsPreviewMode) {
2691 dumpGroupsList(aPythonDump, aGroups);
2692 aPythonDump << this << ".ExtrusionByNormal( " << objects
2693 << ", " << TVar( stepSize )
2694 << ", " << TVar( nbOfSteps )
2695 << ", " << byAverageNormal
2696 << ", " << useInputElemsOnly
2697 << ", " << makeGroups
2703 getPreviewMesh( previewType )->Remove( SMDSAbs_Volume );
2706 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2708 return aGroups ? aGroups : new SMESH::ListOfGroups;
2710 SMESH_CATCH( SMESH::throwCorbaException );
2714 //=======================================================================
2715 //function : AdvancedExtrusion
2717 //=======================================================================
2719 SMESH::ListOfGroups*
2720 SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2721 const SMESH::DirStruct & theStepVector,
2722 CORBA::Long theNbOfSteps,
2723 CORBA::Long theExtrFlags,
2724 CORBA::Double theSewTolerance,
2725 CORBA::Boolean theMakeGroups)
2726 throw (SALOME::SALOME_Exception)
2731 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2733 ExtrusionParams params( theStepVector, theNbOfSteps, theMakeGroups,
2734 theExtrFlags, theSewTolerance );
2736 TIDSortedElemSet elemsNodes[2];
2737 arrayToSet( theIDsOfElements, getMeshDS(), elemsNodes[0] );
2739 ::SMESH_MeshEditor::TTElemOfElemListMap aHistory;
2740 ::SMESH_MeshEditor::PGroupIDs groupIds =
2741 getEditor().ExtrusionSweep( elemsNodes, params, aHistory );
2743 SMESH::ListOfGroups * aGroups = theMakeGroups ? getGroups( groupIds.get()) : 0;
2745 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2747 if ( !myIsPreviewMode ) {
2748 dumpGroupsList(aPythonDump, aGroups);
2749 aPythonDump << this << ".AdvancedExtrusion( "
2750 << theIDsOfElements << ", "
2751 << theStepVector << ", "
2752 << theNbOfSteps << ", "
2753 << theExtrFlags << ", "
2754 << theSewTolerance << ", "
2755 << theMakeGroups << " )";
2759 getPreviewMesh()->Remove( SMDSAbs_Volume );
2762 return aGroups ? aGroups : new SMESH::ListOfGroups;
2764 SMESH_CATCH( SMESH::throwCorbaException );
2768 //================================================================================
2770 * \brief Convert extrusion error to IDL enum
2772 //================================================================================
2776 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
2778 SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( ::SMESH_MeshEditor::Extrusion_Error e )
2782 RETCASE( EXTR_NO_ELEMENTS );
2783 RETCASE( EXTR_PATH_NOT_EDGE );
2784 RETCASE( EXTR_BAD_PATH_SHAPE );
2785 RETCASE( EXTR_BAD_STARTING_NODE );
2786 RETCASE( EXTR_BAD_ANGLES_NUMBER );
2787 RETCASE( EXTR_CANT_GET_TANGENT );
2789 return SMESH::SMESH_MeshEditor::EXTR_OK;
2793 //=======================================================================
2794 //function : extrusionAlongPath
2796 //=======================================================================
2797 SMESH::ListOfGroups*
2798 SMESH_MeshEditor_i::ExtrusionAlongPathObjects(const SMESH::ListOfIDSources & theNodes,
2799 const SMESH::ListOfIDSources & theEdges,
2800 const SMESH::ListOfIDSources & theFaces,
2801 SMESH::SMESH_IDSource_ptr thePathMesh,
2802 GEOM::GEOM_Object_ptr thePathShape,
2803 CORBA::Long theNodeStart,
2804 CORBA::Boolean theHasAngles,
2805 const SMESH::double_array & theAngles,
2806 CORBA::Boolean theLinearVariation,
2807 CORBA::Boolean theHasRefPoint,
2808 const SMESH::PointStruct & theRefPoint,
2810 SMESH::SMESH_MeshEditor::Extrusion_Error& theError)
2811 throw (SALOME::SALOME_Exception)
2816 SMESH::ListOfGroups_var aGroups = new SMESH::ListOfGroups;
2818 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2819 if ( thePathMesh->_is_nil() )
2820 return aGroups._retn();
2823 SMESH_subMesh* aSubMesh = 0;
2824 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2825 if ( thePathShape->_is_nil() )
2827 // thePathMesh should be either a sub-mesh or a mesh with 1D elements only
2828 if ( SMESH_subMesh_i* sm = SMESH::DownCast<SMESH_subMesh_i*>( thePathMesh ))
2830 SMESH::SMESH_Mesh_var mesh = thePathMesh->GetMesh();
2831 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
2832 if ( !aMeshImp ) return aGroups._retn();
2833 aSubMesh = aMeshImp->GetImpl().GetSubMeshContaining( sm->GetId() );
2834 if ( !aSubMesh ) return aGroups._retn();
2836 else if ( !aMeshImp ||
2837 aMeshImp->NbEdges() != aMeshImp->NbElements() )
2839 return aGroups._retn();
2844 if ( !aMeshImp ) return aGroups._retn();
2845 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2846 aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2847 if ( !aSubMesh || !aSubMesh->GetSubMeshDS() )
2848 return aGroups._retn();
2851 SMDS_MeshNode* nodeStart =
2852 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
2854 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2855 return aGroups._retn();
2858 TIDSortedElemSet elemsNodes[2];
2859 for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) {
2860 SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE );
2861 while ( nIt->more() ) elemsNodes[1].insert( nIt->next() );
2863 for ( int i = 0, nb = theEdges.length(); i < nb; ++i )
2864 idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge );
2865 for ( int i = 0, nb = theFaces.length(); i < nb; ++i )
2866 idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face );
2868 list<double> angles;
2869 for (int i = 0; i < theAngles.length(); i++) {
2870 angles.push_back( theAngles[i] );
2873 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
2875 int nbOldGroups = myMesh->NbGroup();
2877 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2878 if ( myIsPreviewMode )
2880 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2881 TPreviewMesh * tmpMesh = getPreviewMesh();
2882 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2883 tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid );
2884 workElements = & copyElements[0];
2885 theMakeGroups = false;
2888 ::SMESH_MeshEditor::Extrusion_Error error;
2890 error = getEditor().ExtrusionAlongTrack( workElements, &(aMeshImp->GetImpl()), nodeStart,
2891 theHasAngles, angles, theLinearVariation,
2892 theHasRefPoint, refPnt, theMakeGroups );
2894 error = getEditor().ExtrusionAlongTrack( workElements, aSubMesh, nodeStart,
2895 theHasAngles, angles, theLinearVariation,
2896 theHasRefPoint, refPnt, theMakeGroups );
2898 declareMeshModified( /*isReComputeSafe=*/true );
2899 theError = convExtrError( error );
2901 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2902 if ( theMakeGroups ) {
2903 list<int> groupIDs = myMesh->GetGroupIds();
2904 list<int>::iterator newBegin = groupIDs.begin();
2905 std::advance( newBegin, nbOldGroups ); // skip old groups
2906 groupIDs.erase( groupIDs.begin(), newBegin );
2907 aGroups = getGroups( & groupIDs );
2908 if ( ! &aGroups.in() ) aGroups = new SMESH::ListOfGroups;
2911 if ( !myIsPreviewMode ) {
2912 aPythonDump << "(" << aGroups << ", error) = "
2913 << this << ".ExtrusionAlongPathObjects( "
2917 << thePathMesh << ", "
2918 << thePathShape << ", "
2919 << theNodeStart << ", "
2920 << theHasAngles << ", "
2921 << theAngles << ", "
2922 << theLinearVariation << ", "
2923 << theHasRefPoint << ", "
2924 << "SMESH.PointStruct( "
2925 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2926 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2927 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ), "
2928 << theMakeGroups << " )";
2932 getPreviewMesh()->Remove( SMDSAbs_Volume );
2935 return aGroups._retn();
2937 SMESH_CATCH( SMESH::throwCorbaException );
2941 //================================================================================
2943 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
2944 * of given angles along path steps
2945 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
2946 * which proceeds the extrusion
2947 * \param PathShape is shape(edge); as the mesh can be complex, the edge
2948 * is used to define the sub-mesh for the path
2950 //================================================================================
2952 SMESH::double_array*
2953 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
2954 GEOM::GEOM_Object_ptr thePathShape,
2955 const SMESH::double_array & theAngles)
2957 SMESH::double_array_var aResult = new SMESH::double_array();
2958 int nbAngles = theAngles.length();
2959 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
2961 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2962 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2963 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2964 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
2965 return aResult._retn();
2966 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
2967 if ( nbSteps == nbAngles )
2969 aResult.inout() = theAngles;
2973 aResult->length( nbSteps );
2974 double rAn2St = double( nbAngles ) / double( nbSteps );
2975 double angPrev = 0, angle;
2976 for ( int iSt = 0; iSt < nbSteps; ++iSt )
2978 double angCur = rAn2St * ( iSt+1 );
2979 double angCurFloor = floor( angCur );
2980 double angPrevFloor = floor( angPrev );
2981 if ( angPrevFloor == angCurFloor )
2982 angle = rAn2St * theAngles[ int( angCurFloor ) ];
2985 int iP = int( angPrevFloor );
2986 double angPrevCeil = ceil(angPrev);
2987 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
2989 int iC = int( angCurFloor );
2990 if ( iC < nbAngles )
2991 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
2993 iP = int( angPrevCeil );
2995 angle += theAngles[ iC ];
2997 aResult[ iSt ] = angle;
3002 // Update Python script
3003 TPythonDump() << "rotAngles = " << theAngles;
3004 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
3005 << thePathMesh << ", "
3006 << thePathShape << ", "
3009 return aResult._retn();
3012 //=======================================================================
3015 //=======================================================================
3017 SMESH::ListOfGroups*
3018 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
3019 const SMESH::AxisStruct & theAxis,
3020 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3021 CORBA::Boolean theCopy,
3023 ::SMESH_Mesh* theTargetMesh)
3024 throw (SALOME::SALOME_Exception)
3029 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3030 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3032 if ( theTargetMesh )
3036 switch ( theMirrorType ) {
3037 case SMESH::SMESH_MeshEditor::POINT:
3038 aTrsf.SetMirror( P );
3040 case SMESH::SMESH_MeshEditor::AXIS:
3041 aTrsf.SetMirror( gp_Ax1( P, V ));
3044 aTrsf.SetMirror( gp_Ax2( P, V ));
3047 TIDSortedElemSet copyElements;
3048 TIDSortedElemSet* workElements = & theElements;
3050 if ( myIsPreviewMode )
3052 TPreviewMesh * tmpMesh = getPreviewMesh();
3053 tmpMesh->Copy( theElements, copyElements);
3054 if ( !theCopy && !theTargetMesh )
3056 TIDSortedElemSet elemsAround, elemsAroundCopy;
3057 getElementsAround( theElements, getMeshDS(), elemsAround );
3058 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3060 workElements = & copyElements;
3061 theMakeGroups = false;
3064 ::SMESH_MeshEditor::PGroupIDs groupIds =
3065 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3067 if ( theCopy && !myIsPreviewMode)
3069 if ( theTargetMesh )
3071 theTargetMesh->GetMeshDS()->Modified();
3075 declareMeshModified( /*isReComputeSafe=*/false );
3078 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3080 SMESH_CATCH( SMESH::throwCorbaException );
3084 //=======================================================================
3087 //=======================================================================
3089 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3090 const SMESH::AxisStruct & theAxis,
3091 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3092 CORBA::Boolean theCopy)
3093 throw (SALOME::SALOME_Exception)
3095 if ( !myIsPreviewMode ) {
3096 TPythonDump() << this << ".Mirror( "
3097 << theIDsOfElements << ", "
3099 << mirrorTypeName(theMirrorType) << ", "
3102 if ( theIDsOfElements.length() > 0 )
3104 TIDSortedElemSet elements;
3105 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3106 mirror(elements, theAxis, theMirrorType, theCopy, false);
3111 //=======================================================================
3112 //function : MirrorObject
3114 //=======================================================================
3116 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3117 const SMESH::AxisStruct & theAxis,
3118 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3119 CORBA::Boolean theCopy)
3120 throw (SALOME::SALOME_Exception)
3122 if ( !myIsPreviewMode ) {
3123 TPythonDump() << this << ".MirrorObject( "
3124 << theObject << ", "
3126 << mirrorTypeName(theMirrorType) << ", "
3129 TIDSortedElemSet elements;
3131 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3133 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3134 mirror(elements, theAxis, theMirrorType, theCopy, false);
3137 //=======================================================================
3138 //function : MirrorMakeGroups
3140 //=======================================================================
3142 SMESH::ListOfGroups*
3143 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3144 const SMESH::AxisStruct& theMirror,
3145 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3146 throw (SALOME::SALOME_Exception)
3148 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3150 SMESH::ListOfGroups * aGroups = 0;
3151 if ( theIDsOfElements.length() > 0 )
3153 TIDSortedElemSet elements;
3154 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3155 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3157 if (!myIsPreviewMode) {
3158 dumpGroupsList(aPythonDump, aGroups);
3159 aPythonDump << this << ".MirrorMakeGroups( "
3160 << theIDsOfElements << ", "
3161 << theMirror << ", "
3162 << mirrorTypeName(theMirrorType) << " )";
3167 //=======================================================================
3168 //function : MirrorObjectMakeGroups
3170 //=======================================================================
3172 SMESH::ListOfGroups*
3173 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3174 const SMESH::AxisStruct& theMirror,
3175 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3176 throw (SALOME::SALOME_Exception)
3178 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3180 SMESH::ListOfGroups * aGroups = 0;
3181 TIDSortedElemSet elements;
3182 if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3183 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3185 if (!myIsPreviewMode)
3187 dumpGroupsList(aPythonDump,aGroups);
3188 aPythonDump << this << ".MirrorObjectMakeGroups( "
3189 << theObject << ", "
3190 << theMirror << ", "
3191 << mirrorTypeName(theMirrorType) << " )";
3196 //=======================================================================
3197 //function : MirrorMakeMesh
3199 //=======================================================================
3201 SMESH::SMESH_Mesh_ptr
3202 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
3203 const SMESH::AxisStruct& theMirror,
3204 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3205 CORBA::Boolean theCopyGroups,
3206 const char* theMeshName)
3207 throw (SALOME::SALOME_Exception)
3209 SMESH_Mesh_i* mesh_i;
3210 SMESH::SMESH_Mesh_var mesh;
3211 { // open new scope to dump "MakeMesh" command
3212 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3214 TPythonDump pydump; // to prevent dump at mesh creation
3216 mesh = makeMesh( theMeshName );
3217 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3218 if (mesh_i && theIDsOfElements.length() > 0 )
3220 TIDSortedElemSet elements;
3221 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3222 mirror(elements, theMirror, theMirrorType,
3223 false, theCopyGroups, & mesh_i->GetImpl());
3224 mesh_i->CreateGroupServants();
3227 if (!myIsPreviewMode) {
3228 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
3229 << theIDsOfElements << ", "
3230 << theMirror << ", "
3231 << mirrorTypeName(theMirrorType) << ", "
3232 << theCopyGroups << ", '"
3233 << theMeshName << "' )";
3238 if (!myIsPreviewMode && mesh_i)
3239 mesh_i->GetGroups();
3241 return mesh._retn();
3244 //=======================================================================
3245 //function : MirrorObjectMakeMesh
3247 //=======================================================================
3249 SMESH::SMESH_Mesh_ptr
3250 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3251 const SMESH::AxisStruct& theMirror,
3252 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3253 CORBA::Boolean theCopyGroups,
3254 const char* theMeshName)
3255 throw (SALOME::SALOME_Exception)
3257 SMESH_Mesh_i* mesh_i;
3258 SMESH::SMESH_Mesh_var mesh;
3259 { // open new scope to dump "MakeMesh" command
3260 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3262 TPythonDump pydump; // to prevent dump at mesh creation
3264 mesh = makeMesh( theMeshName );
3265 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3266 TIDSortedElemSet elements;
3268 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3270 mirror(elements, theMirror, theMirrorType,
3271 false, theCopyGroups, & mesh_i->GetImpl());
3272 mesh_i->CreateGroupServants();
3274 if (!myIsPreviewMode) {
3275 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
3276 << theObject << ", "
3277 << theMirror << ", "
3278 << mirrorTypeName(theMirrorType) << ", "
3279 << theCopyGroups << ", '"
3280 << theMeshName << "' )";
3285 if (!myIsPreviewMode && mesh_i)
3286 mesh_i->GetGroups();
3288 return mesh._retn();
3291 //=======================================================================
3292 //function : translate
3294 //=======================================================================
3296 SMESH::ListOfGroups*
3297 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
3298 const SMESH::DirStruct & theVector,
3299 CORBA::Boolean theCopy,
3301 ::SMESH_Mesh* theTargetMesh)
3302 throw (SALOME::SALOME_Exception)
3307 if ( theTargetMesh )
3311 const SMESH::PointStruct * P = &theVector.PS;
3312 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
3314 TIDSortedElemSet copyElements;
3315 TIDSortedElemSet* workElements = &theElements;
3317 if ( myIsPreviewMode )
3319 TPreviewMesh * tmpMesh = getPreviewMesh();
3320 tmpMesh->Copy( theElements, copyElements);
3321 if ( !theCopy && !theTargetMesh )
3323 TIDSortedElemSet elemsAround, elemsAroundCopy;
3324 getElementsAround( theElements, getMeshDS(), elemsAround );
3325 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3327 workElements = & copyElements;
3328 theMakeGroups = false;
3331 ::SMESH_MeshEditor::PGroupIDs groupIds =
3332 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3334 if ( theCopy && !myIsPreviewMode )
3336 if ( theTargetMesh )
3338 theTargetMesh->GetMeshDS()->Modified();
3342 declareMeshModified( /*isReComputeSafe=*/false );
3346 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3348 SMESH_CATCH( SMESH::throwCorbaException );
3352 //=======================================================================
3353 //function : Translate
3355 //=======================================================================
3357 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
3358 const SMESH::DirStruct & theVector,
3359 CORBA::Boolean theCopy)
3360 throw (SALOME::SALOME_Exception)
3362 if (!myIsPreviewMode) {
3363 TPythonDump() << this << ".Translate( "
3364 << theIDsOfElements << ", "
3365 << theVector << ", "
3368 if (theIDsOfElements.length()) {
3369 TIDSortedElemSet elements;
3370 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3371 translate(elements, theVector, theCopy, false);
3375 //=======================================================================
3376 //function : TranslateObject
3378 //=======================================================================
3380 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
3381 const SMESH::DirStruct & theVector,
3382 CORBA::Boolean theCopy)
3383 throw (SALOME::SALOME_Exception)
3385 if (!myIsPreviewMode) {
3386 TPythonDump() << this << ".TranslateObject( "
3387 << theObject << ", "
3388 << theVector << ", "
3391 TIDSortedElemSet elements;
3393 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3395 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3396 translate(elements, theVector, theCopy, false);
3399 //=======================================================================
3400 //function : TranslateMakeGroups
3402 //=======================================================================
3404 SMESH::ListOfGroups*
3405 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
3406 const SMESH::DirStruct& theVector)
3407 throw (SALOME::SALOME_Exception)
3409 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3411 SMESH::ListOfGroups * aGroups = 0;
3412 if (theIDsOfElements.length()) {
3413 TIDSortedElemSet elements;
3414 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3415 aGroups = translate(elements,theVector,true,true);
3417 if (!myIsPreviewMode) {
3418 dumpGroupsList(aPythonDump, aGroups);
3419 aPythonDump << this << ".TranslateMakeGroups( "
3420 << theIDsOfElements << ", "
3421 << theVector << " )";
3426 //=======================================================================
3427 //function : TranslateObjectMakeGroups
3429 //=======================================================================
3431 SMESH::ListOfGroups*
3432 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3433 const SMESH::DirStruct& theVector)
3434 throw (SALOME::SALOME_Exception)
3436 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3438 SMESH::ListOfGroups * aGroups = 0;
3439 TIDSortedElemSet elements;
3440 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3441 aGroups = translate(elements, theVector, true, true);
3443 if (!myIsPreviewMode) {
3444 dumpGroupsList(aPythonDump, aGroups);
3445 aPythonDump << this << ".TranslateObjectMakeGroups( "
3446 << theObject << ", "
3447 << theVector << " )";
3452 //=======================================================================
3453 //function : TranslateMakeMesh
3455 //=======================================================================
3457 SMESH::SMESH_Mesh_ptr
3458 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
3459 const SMESH::DirStruct& theVector,
3460 CORBA::Boolean theCopyGroups,
3461 const char* theMeshName)
3462 throw (SALOME::SALOME_Exception)
3464 SMESH_Mesh_i* mesh_i;
3465 SMESH::SMESH_Mesh_var mesh;
3467 { // open new scope to dump "MakeMesh" command
3468 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3470 TPythonDump pydump; // to prevent dump at mesh creation
3472 mesh = makeMesh( theMeshName );
3473 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3475 if ( mesh_i && theIDsOfElements.length() )
3477 TIDSortedElemSet elements;
3478 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3479 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
3480 mesh_i->CreateGroupServants();
3483 if ( !myIsPreviewMode ) {
3484 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
3485 << theIDsOfElements << ", "
3486 << theVector << ", "
3487 << theCopyGroups << ", '"
3488 << theMeshName << "' )";
3493 if (!myIsPreviewMode && mesh_i)
3494 mesh_i->GetGroups();
3496 return mesh._retn();
3499 //=======================================================================
3500 //function : TranslateObjectMakeMesh
3502 //=======================================================================
3504 SMESH::SMESH_Mesh_ptr
3505 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3506 const SMESH::DirStruct& theVector,
3507 CORBA::Boolean theCopyGroups,
3508 const char* theMeshName)
3509 throw (SALOME::SALOME_Exception)
3512 SMESH_Mesh_i* mesh_i;
3513 SMESH::SMESH_Mesh_var mesh;
3514 { // open new scope to dump "MakeMesh" command
3515 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3517 TPythonDump pydump; // to prevent dump at mesh creation
3518 mesh = makeMesh( theMeshName );
3519 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3521 TIDSortedElemSet elements;
3523 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3525 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());