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 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1068 const SMDS_MeshElement* elem = getMeshDS()->AddPolygonalFace(nodes);
1070 // Update Python script
1071 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
1073 declareMeshModified( /*isReComputeSafe=*/false );
1074 return elem ? elem->GetID() : 0;
1076 SMESH_CATCH( SMESH::throwCorbaException );
1080 //=============================================================================
1082 * AddQuadPolygonalFace
1084 //=============================================================================
1086 CORBA::Long SMESH_MeshEditor_i::AddQuadPolygonalFace (const SMESH::long_array & IDsOfNodes)
1087 throw (SALOME::SALOME_Exception)
1092 int NbNodes = IDsOfNodes.length();
1093 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1094 for (int i = 0; i < NbNodes; i++)
1095 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1097 const SMDS_MeshElement* elem = getMeshDS()->AddQuadPolygonalFace(nodes);
1099 // Update Python script
1100 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
1102 declareMeshModified( /*isReComputeSafe=*/false );
1103 return elem ? elem->GetID() : 0;
1105 SMESH_CATCH( SMESH::throwCorbaException );
1109 //=============================================================================
1111 * Create volume, either linear and quadratic (this is determed
1112 * by number of given nodes)
1114 //=============================================================================
1116 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
1117 throw (SALOME::SALOME_Exception)
1122 int NbNodes = IDsOfNodes.length();
1123 vector< const SMDS_MeshNode*> n(NbNodes);
1124 for(int i=0;i<NbNodes;i++)
1125 n[i]= getMeshDS()->FindNode(IDsOfNodes[i]);
1127 SMDS_MeshElement* elem = 0;
1130 case 4 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
1131 case 5 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
1132 case 6 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
1133 case 8 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
1134 case 10:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1135 n[6],n[7],n[8],n[9]);
1137 case 12:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1138 n[6],n[7],n[8],n[9],n[10],n[11]);
1140 case 13:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
1141 n[7],n[8],n[9],n[10],n[11],n[12]);
1143 case 15:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
1144 n[9],n[10],n[11],n[12],n[13],n[14]);
1146 case 20:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1147 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1148 n[15],n[16],n[17],n[18],n[19]);
1150 case 27:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1151 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1152 n[15],n[16],n[17],n[18],n[19],
1153 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
1157 // Update Python script
1158 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
1160 declareMeshModified( /*isReComputeSafe=*/false );
1161 return elem ? elem->GetID() : 0;
1163 SMESH_CATCH( SMESH::throwCorbaException );
1167 //=============================================================================
1169 * AddPolyhedralVolume
1171 //=============================================================================
1172 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
1173 const SMESH::long_array & Quantities)
1174 throw (SALOME::SALOME_Exception)
1179 int NbNodes = IDsOfNodes.length();
1180 std::vector<const SMDS_MeshNode*> n (NbNodes);
1181 for (int i = 0; i < NbNodes; i++)
1183 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDsOfNodes[i]);
1184 if (!aNode) return 0;
1188 int NbFaces = Quantities.length();
1189 std::vector<int> q (NbFaces);
1190 for (int j = 0; j < NbFaces; j++)
1191 q[j] = Quantities[j];
1193 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(n, q);
1195 // Update Python script
1196 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
1197 << IDsOfNodes << ", " << Quantities << " )";
1199 declareMeshModified( /*isReComputeSafe=*/false );
1200 return elem ? elem->GetID() : 0;
1202 SMESH_CATCH( SMESH::throwCorbaException );
1206 //=============================================================================
1208 * AddPolyhedralVolumeByFaces
1210 //=============================================================================
1212 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
1213 throw (SALOME::SALOME_Exception)
1218 int NbFaces = IdsOfFaces.length();
1219 std::vector<const SMDS_MeshNode*> poly_nodes;
1220 std::vector<int> quantities (NbFaces);
1222 for (int i = 0; i < NbFaces; i++) {
1223 const SMDS_MeshElement* aFace = getMeshDS()->FindElement(IdsOfFaces[i]);
1224 quantities[i] = aFace->NbNodes();
1226 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
1227 while (It->more()) {
1228 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
1232 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
1234 // Update Python script
1235 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
1236 << IdsOfFaces << " )";
1238 declareMeshModified( /*isReComputeSafe=*/false );
1239 return elem ? elem->GetID() : 0;
1241 SMESH_CATCH( SMESH::throwCorbaException );
1245 //=============================================================================
1247 // \brief Create 0D elements on all nodes of the given object except those
1248 // nodes on which a 0D element already exists.
1249 // \param theObject object on whose nodes 0D elements will be created.
1250 // \param theGroupName optional name of a group to add 0D elements created
1251 // and/or found on nodes of \a theObject.
1252 // \return an object (a new group or a temporary SMESH_IDSource) holding
1253 // ids of new and/or found 0D elements.
1255 //=============================================================================
1257 SMESH::SMESH_IDSource_ptr
1258 SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObject,
1259 const char* theGroupName)
1260 throw (SALOME::SALOME_Exception)
1265 SMESH::SMESH_IDSource_var result;
1268 TIDSortedElemSet elements, elems0D;
1269 if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
1270 getEditor().Create0DElementsOnAllNodes( elements, elems0D );
1272 SMESH::long_array_var newElems = new SMESH::long_array;
1273 newElems->length( elems0D.size() );
1274 TIDSortedElemSet::iterator eIt = elems0D.begin();
1275 for ( size_t i = 0; i < elems0D.size(); ++i, ++eIt )
1276 newElems[ i ] = (*eIt)->GetID();
1278 SMESH::SMESH_GroupBase_var groupToFill;
1279 if ( theGroupName && strlen( theGroupName ))
1281 // Get existing group named theGroupName
1282 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
1283 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
1284 SMESH::SMESH_GroupBase_var group = groups[i];
1285 if ( !group->_is_nil() ) {
1286 CORBA::String_var name = group->GetName();
1287 if ( strcmp( name.in(), theGroupName ) == 0 && group->GetType() == SMESH::ELEM0D ) {
1288 groupToFill = group;
1293 if ( groupToFill->_is_nil() )
1294 groupToFill = myMesh_i->CreateGroup( SMESH::ELEM0D, theGroupName );
1295 else if ( !SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1296 groupToFill = myMesh_i->ConvertToStandalone( groupToFill );
1299 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1301 group_i->Add( newElems );
1302 result = SMESH::SMESH_IDSource::_narrow( groupToFill );
1303 pyDump << groupToFill;
1307 result = MakeIDSource( newElems, SMESH::ELEM0D );
1308 pyDump << "elem0DIDs";
1311 pyDump << " = " << this << ".Create0DElementsOnAllNodes( "
1312 << theObject << ", '" << theGroupName << "' )";
1314 return result._retn();
1316 SMESH_CATCH( SMESH::throwCorbaException );
1320 //=============================================================================
1322 * \brief Bind a node to a vertex
1323 * \param NodeID - node ID
1324 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1325 * \retval boolean - false if NodeID or VertexID is invalid
1327 //=============================================================================
1329 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
1330 throw (SALOME::SALOME_Exception)
1334 SMESHDS_Mesh * mesh = getMeshDS();
1335 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1337 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1339 if ( mesh->MaxShapeIndex() < VertexID )
1340 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1342 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
1343 if ( shape.ShapeType() != TopAbs_VERTEX )
1344 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1346 mesh->SetNodeOnVertex( node, VertexID );
1348 myMesh->SetIsModified( true );
1350 SMESH_CATCH( SMESH::throwCorbaException );
1353 //=============================================================================
1355 * \brief Store node position on an edge
1356 * \param NodeID - node ID
1357 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
1358 * \param paramOnEdge - parameter on edge where the node is located
1359 * \retval boolean - false if any parameter is invalid
1361 //=============================================================================
1363 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
1364 CORBA::Double paramOnEdge)
1365 throw (SALOME::SALOME_Exception)
1369 SMESHDS_Mesh * mesh = getMeshDS();
1370 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1372 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1374 if ( mesh->MaxShapeIndex() < EdgeID )
1375 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1377 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
1378 if ( shape.ShapeType() != TopAbs_EDGE )
1379 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1382 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
1383 if ( paramOnEdge < f || paramOnEdge > l )
1384 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
1386 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
1388 myMesh->SetIsModified( true );
1390 SMESH_CATCH( SMESH::throwCorbaException );
1393 //=============================================================================
1395 * \brief Store node position on a face
1396 * \param NodeID - node ID
1397 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
1398 * \param u - U parameter on face where the node is located
1399 * \param v - V parameter on face where the node is located
1400 * \retval boolean - false if any parameter is invalid
1402 //=============================================================================
1404 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
1405 CORBA::Double u, CORBA::Double v)
1406 throw (SALOME::SALOME_Exception)
1409 SMESHDS_Mesh * mesh = getMeshDS();
1410 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1412 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1414 if ( mesh->MaxShapeIndex() < FaceID )
1415 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1417 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
1418 if ( shape.ShapeType() != TopAbs_FACE )
1419 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1421 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
1422 bool isOut = ( u < surf.FirstUParameter() ||
1423 u > surf.LastUParameter() ||
1424 v < surf.FirstVParameter() ||
1425 v > surf.LastVParameter() );
1429 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
1430 << " u( " << surf.FirstUParameter()
1431 << "," << surf.LastUParameter()
1432 << ") v( " << surf.FirstVParameter()
1433 << "," << surf.LastVParameter() << ")" );
1435 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
1438 mesh->SetNodeOnFace( node, FaceID, u, v );
1439 myMesh->SetIsModified( true );
1441 SMESH_CATCH( SMESH::throwCorbaException );
1444 //=============================================================================
1446 * \brief Bind a node to a solid
1447 * \param NodeID - node ID
1448 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1449 * \retval boolean - false if NodeID or SolidID is invalid
1451 //=============================================================================
1453 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
1454 throw (SALOME::SALOME_Exception)
1457 SMESHDS_Mesh * mesh = getMeshDS();
1458 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1460 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1462 if ( mesh->MaxShapeIndex() < SolidID )
1463 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1465 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
1466 if ( shape.ShapeType() != TopAbs_SOLID &&
1467 shape.ShapeType() != TopAbs_SHELL)
1468 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1470 mesh->SetNodeInVolume( node, SolidID );
1472 SMESH_CATCH( SMESH::throwCorbaException );
1475 //=============================================================================
1477 * \brief Bind an element to a shape
1478 * \param ElementID - element ID
1479 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
1481 //=============================================================================
1483 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
1484 CORBA::Long ShapeID)
1485 throw (SALOME::SALOME_Exception)
1488 SMESHDS_Mesh * mesh = getMeshDS();
1489 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
1491 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
1493 if ( mesh->MaxShapeIndex() < ShapeID || ShapeID < 1 )
1494 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1496 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1497 if ( shape.ShapeType() != TopAbs_EDGE &&
1498 shape.ShapeType() != TopAbs_FACE &&
1499 shape.ShapeType() != TopAbs_SOLID &&
1500 shape.ShapeType() != TopAbs_SHELL )
1501 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1503 mesh->SetMeshElementOnShape( elem, ShapeID );
1505 myMesh->SetIsModified( true );
1507 SMESH_CATCH( SMESH::throwCorbaException );
1510 //=============================================================================
1514 //=============================================================================
1516 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1517 CORBA::Long NodeID2)
1518 throw (SALOME::SALOME_Exception)
1523 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1524 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1528 // Update Python script
1529 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1530 << NodeID1 << ", " << NodeID2 << " )";
1532 int ret = getEditor().InverseDiag ( n1, n2 );
1534 declareMeshModified( /*isReComputeSafe=*/false );
1537 SMESH_CATCH( SMESH::throwCorbaException );
1541 //=============================================================================
1545 //=============================================================================
1547 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1548 CORBA::Long NodeID2)
1549 throw (SALOME::SALOME_Exception)
1554 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1555 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1559 // Update Python script
1560 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1561 << NodeID1 << ", " << NodeID2 << " )";
1564 bool stat = getEditor().DeleteDiag ( n1, n2 );
1566 declareMeshModified( /*isReComputeSafe=*/!stat );
1570 SMESH_CATCH( SMESH::throwCorbaException );
1574 //=============================================================================
1578 //=============================================================================
1580 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1581 throw (SALOME::SALOME_Exception)
1586 for (int i = 0; i < IDsOfElements.length(); i++)
1588 CORBA::Long index = IDsOfElements[i];
1589 const SMDS_MeshElement * elem = getMeshDS()->FindElement(index);
1591 getEditor().Reorient( elem );
1593 // Update Python script
1594 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1596 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 );
1599 SMESH_CATCH( SMESH::throwCorbaException );
1603 //=============================================================================
1607 //=============================================================================
1609 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1610 throw (SALOME::SALOME_Exception)
1615 TPythonDump aTPythonDump; // suppress dump in Reorient()
1617 prepareIdSource( theObject );
1619 SMESH::long_array_var anElementsId = theObject->GetIDs();
1620 CORBA::Boolean isDone = Reorient(anElementsId);
1622 // Update Python script
1623 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1625 declareMeshModified( /*isReComputeSafe=*/ anElementsId->length() == 0 );
1628 SMESH_CATCH( SMESH::throwCorbaException );
1632 //=======================================================================
1633 //function : Reorient2D
1634 //purpose : Reorient faces contained in \a the2Dgroup.
1635 // the2Dgroup - the mesh or its part to reorient
1636 // theDirection - desired direction of normal of \a theFace
1637 // theFace - ID of face whose orientation is checked.
1638 // It can be < 1 then \a thePoint is used to find a face.
1639 // thePoint - is used to find a face if \a theFace < 1.
1640 // return number of reoriented elements.
1641 //=======================================================================
1643 CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
1644 const SMESH::DirStruct& theDirection,
1645 CORBA::Long theFace,
1646 const SMESH::PointStruct& thePoint)
1647 throw (SALOME::SALOME_Exception)
1650 initData(/*deleteSearchers=*/false);
1652 TIDSortedElemSet elements;
1653 IDSource_Error error;
1654 idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error );
1655 if ( error == IDSource_EMPTY )
1657 if ( error == IDSource_INVALID )
1658 THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
1661 const SMDS_MeshElement* face = 0;
1664 face = getMeshDS()->FindElement( theFace );
1666 THROW_SALOME_CORBA_EXCEPTION("Inexistent face given", SALOME::BAD_PARAM);
1667 if ( face->GetType() != SMDSAbs_Face )
1668 THROW_SALOME_CORBA_EXCEPTION("Wrong element type", SALOME::BAD_PARAM);
1672 // create theElementSearcher if needed
1673 theSearchersDeleter.Set( myMesh, getPartIOR( the2Dgroup, SMESH::FACE ));
1674 if ( !theElementSearcher )
1676 if ( elements.empty() ) // search in the whole mesh
1678 if ( myMesh->NbFaces() == 0 )
1679 THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM);
1681 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
1685 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
1686 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
1688 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt);
1692 gp_Pnt p( thePoint.x, thePoint.y, thePoint.z );
1693 face = theElementSearcher->FindClosestTo( p, SMDSAbs_Face );
1696 THROW_SALOME_CORBA_EXCEPTION("No face found by point", SALOME::INTERNAL_ERROR );
1697 if ( !elements.empty() && !elements.count( face ))
1698 THROW_SALOME_CORBA_EXCEPTION("Found face is not in the group", SALOME::BAD_PARAM );
1701 const SMESH::PointStruct * P = &theDirection.PS;
1702 gp_Vec dirVec( P->x, P->y, P->z );
1703 if ( dirVec.Magnitude() < std::numeric_limits< double >::min() )
1704 THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM);
1706 int nbReori = getEditor().Reorient2D( elements, dirVec, face );
1709 declareMeshModified( /*isReComputeSafe=*/false );
1711 TPythonDump() << this << ".Reorient2D( "
1712 << the2Dgroup << ", "
1713 << theDirection << ", "
1715 << thePoint << " )";
1719 SMESH_CATCH( SMESH::throwCorbaException );
1723 //=======================================================================
1724 //function : Reorient2DBy3D
1725 //purpose : Reorient faces basing on orientation of adjacent volumes.
1726 //=======================================================================
1728 CORBA::Long SMESH_MeshEditor_i::Reorient2DBy3D(const SMESH::ListOfIDSources& faceGroups,
1729 SMESH::SMESH_IDSource_ptr volumeGroup,
1730 CORBA::Boolean outsideNormal)
1731 throw (SALOME::SALOME_Exception)
1736 TIDSortedElemSet volumes;
1737 IDSource_Error volsError;
1738 idSourceToSet( volumeGroup, getMeshDS(), volumes, SMDSAbs_Volume, /*emptyIfMesh=*/1, &volsError);
1741 for ( size_t i = 0; i < faceGroups.length(); ++i )
1743 SMESH::SMESH_IDSource_ptr faceGrp = faceGroups[i].in();
1745 TIDSortedElemSet faces;
1746 IDSource_Error error;
1747 idSourceToSet( faceGrp, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error );
1748 if ( error == IDSource_INVALID && faceGroups.length() == 1 )
1749 THROW_SALOME_CORBA_EXCEPTION("No faces in a given object", SALOME::BAD_PARAM);
1750 if ( error == IDSource_OK && volsError != IDSource_OK )
1751 THROW_SALOME_CORBA_EXCEPTION("No volumes in a given object", SALOME::BAD_PARAM);
1753 nbReori += getEditor().Reorient2DBy3D( faces, volumes, outsideNormal );
1755 if ( error != IDSource_EMPTY && faces.empty() ) // all faces in the mesh treated
1760 declareMeshModified( /*isReComputeSafe=*/false );
1762 TPythonDump() << this << ".Reorient2DBy3D( "
1763 << faceGroups << ", "
1764 << volumeGroup << ", "
1765 << outsideNormal << " )";
1769 SMESH_CATCH( SMESH::throwCorbaException );
1773 //=============================================================================
1775 * \brief Fuse neighbour triangles into quadrangles.
1777 //=============================================================================
1779 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1780 SMESH::NumericalFunctor_ptr Criterion,
1781 CORBA::Double MaxAngle)
1782 throw (SALOME::SALOME_Exception)
1787 SMESHDS_Mesh* aMesh = getMeshDS();
1788 TIDSortedElemSet faces,copyFaces;
1789 SMDS_MeshElement::GeomFilter triaFilter(SMDSGeom_TRIANGLE);
1790 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face, & triaFilter);
1791 TIDSortedElemSet* workElements = & faces;
1793 if ( myIsPreviewMode ) {
1794 SMDSAbs_ElementType select = SMDSAbs_Face;
1795 getPreviewMesh( SMDSAbs_Face )->Copy( faces, copyFaces, select );
1796 workElements = & copyFaces;
1799 SMESH::NumericalFunctor_i* aNumericalFunctor =
1800 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1801 SMESH::Controls::NumericalFunctorPtr aCrit;
1802 if ( !aNumericalFunctor )
1803 aCrit.reset( new SMESH::Controls::MaxElementLength2D() );
1805 aCrit = aNumericalFunctor->GetNumericalFunctor();
1807 if ( !myIsPreviewMode ) {
1808 // Update Python script
1809 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1810 << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1813 bool stat = getEditor().TriToQuad( *workElements, aCrit, MaxAngle );
1815 declareMeshModified( /*isReComputeSafe=*/!stat );
1818 SMESH_CATCH( SMESH::throwCorbaException );
1822 //=============================================================================
1824 * \brief Fuse neighbour triangles into quadrangles.
1826 //=============================================================================
1828 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1829 SMESH::NumericalFunctor_ptr Criterion,
1830 CORBA::Double MaxAngle)
1831 throw (SALOME::SALOME_Exception)
1836 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1838 prepareIdSource( theObject );
1839 SMESH::long_array_var anElementsId = theObject->GetIDs();
1840 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1842 if ( !myIsPreviewMode ) {
1843 SMESH::NumericalFunctor_i* aNumericalFunctor =
1844 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1846 // Update Python script
1847 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1848 << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1853 SMESH_CATCH( SMESH::throwCorbaException );
1857 //=============================================================================
1859 * \brief Split quadrangles into triangles.
1861 //=============================================================================
1863 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1864 SMESH::NumericalFunctor_ptr Criterion)
1865 throw (SALOME::SALOME_Exception)
1870 SMESHDS_Mesh* aMesh = getMeshDS();
1871 TIDSortedElemSet faces;
1872 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1874 SMESH::NumericalFunctor_i* aNumericalFunctor =
1875 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1876 SMESH::Controls::NumericalFunctorPtr aCrit;
1877 if ( !aNumericalFunctor )
1878 aCrit.reset( new SMESH::Controls::AspectRatio() );
1880 aCrit = aNumericalFunctor->GetNumericalFunctor();
1883 // Update Python script
1884 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1886 CORBA::Boolean stat = getEditor().QuadToTri( faces, aCrit );
1888 declareMeshModified( /*isReComputeSafe=*/false );
1891 SMESH_CATCH( SMESH::throwCorbaException );
1895 //=============================================================================
1897 * \brief Split quadrangles into triangles.
1899 //=============================================================================
1901 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1902 SMESH::NumericalFunctor_ptr Criterion)
1903 throw (SALOME::SALOME_Exception)
1908 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1910 prepareIdSource( theObject );
1911 SMESH::long_array_var anElementsId = theObject->GetIDs();
1912 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1914 SMESH::NumericalFunctor_i* aNumericalFunctor =
1915 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1917 // Update Python script
1918 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1920 declareMeshModified( /*isReComputeSafe=*/false );
1923 SMESH_CATCH( SMESH::throwCorbaException );
1927 //================================================================================
1929 * \brief Split each of quadrangles into 4 triangles.
1930 * \param [in] theObject - theQuads Container of quadrangles to split.
1932 //================================================================================
1934 void SMESH_MeshEditor_i::QuadTo4Tri (SMESH::SMESH_IDSource_ptr theObject)
1935 throw (SALOME::SALOME_Exception)
1940 TIDSortedElemSet faces;
1941 if ( !idSourceToSet( theObject, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/true ) &&
1943 THROW_SALOME_CORBA_EXCEPTION("No faces given", SALOME::BAD_PARAM);
1945 getEditor().QuadTo4Tri( faces );
1946 TPythonDump() << this << ".QuadTo4Tri( " << theObject << " )";
1948 SMESH_CATCH( SMESH::throwCorbaException );
1951 //=============================================================================
1953 * \brief Split quadrangles into triangles.
1955 //=============================================================================
1957 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1958 CORBA::Boolean Diag13)
1959 throw (SALOME::SALOME_Exception)
1964 SMESHDS_Mesh* aMesh = getMeshDS();
1965 TIDSortedElemSet faces;
1966 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1968 // Update Python script
1969 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1970 << IDsOfElements << ", " << Diag13 << " )";
1972 CORBA::Boolean stat = getEditor().QuadToTri( faces, Diag13 );
1974 declareMeshModified( /*isReComputeSafe=*/ !stat );
1977 SMESH_CATCH( SMESH::throwCorbaException );
1981 //=============================================================================
1983 * \brief Split quadrangles into triangles.
1985 //=============================================================================
1987 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1988 CORBA::Boolean Diag13)
1989 throw (SALOME::SALOME_Exception)
1994 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
1996 prepareIdSource( theObject );
1997 SMESH::long_array_var anElementsId = theObject->GetIDs();
1998 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
2000 // Update Python script
2001 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
2002 << theObject << ", " << Diag13 << " )";
2004 declareMeshModified( /*isReComputeSafe=*/!isDone );
2007 SMESH_CATCH( SMESH::throwCorbaException );
2012 //=============================================================================
2014 * Find better splitting of the given quadrangle.
2015 * \param IDOfQuad ID of the quadrangle to be splitted.
2016 * \param Criterion A criterion to choose a diagonal for splitting.
2017 * \return 1 if 1-3 diagonal is better, 2 if 2-4
2018 * diagonal is better, 0 if error occurs.
2020 //=============================================================================
2022 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
2023 SMESH::NumericalFunctor_ptr Criterion)
2024 throw (SALOME::SALOME_Exception)
2029 const SMDS_MeshElement* quad = getMeshDS()->FindElement(IDOfQuad);
2030 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
2032 SMESH::NumericalFunctor_i* aNumericalFunctor =
2033 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
2034 SMESH::Controls::NumericalFunctorPtr aCrit;
2035 if (aNumericalFunctor)
2036 aCrit = aNumericalFunctor->GetNumericalFunctor();
2038 aCrit.reset(new SMESH::Controls::AspectRatio());
2040 int id = getEditor().BestSplit(quad, aCrit);
2041 declareMeshModified( /*isReComputeSafe=*/ id < 1 );
2045 SMESH_CATCH( SMESH::throwCorbaException );
2049 //================================================================================
2051 * \brief Split volumic elements into tetrahedrons
2053 //================================================================================
2055 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
2056 CORBA::Short methodFlags)
2057 throw (SALOME::SALOME_Exception)
2062 ::SMESH_MeshEditor::TFacetOfElem elemSet;
2063 const int noneFacet = -1;
2064 SMDS_ElemIteratorPtr volIt = myMesh_i->GetElements( elems, SMESH::VOLUME );
2065 while( volIt->more() )
2066 elemSet.insert( elemSet.end(), make_pair( volIt->next(), noneFacet ));
2068 getEditor().SplitVolumes( elemSet, int( methodFlags ));
2069 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2071 TPythonDump() << this << ".SplitVolumesIntoTetra( "
2072 << elems << ", " << methodFlags << " )";
2074 SMESH_CATCH( SMESH::throwCorbaException );
2077 //================================================================================
2079 * \brief Split hexahedra into triangular prisms
2080 * \param elems - elements to split
2081 * \param facetToSplitNormal - normal used to find a facet of hexahedron
2082 * to split into triangles
2083 * \param methodFlags - flags passing splitting method:
2084 * 1 - split the hexahedron into 2 prisms
2085 * 2 - split the hexahedron into 4 prisms
2087 //================================================================================
2089 void SMESH_MeshEditor_i::SplitHexahedraIntoPrisms( SMESH::SMESH_IDSource_ptr elems,
2090 const SMESH::PointStruct & startHexPoint,
2091 const SMESH::DirStruct& facetToSplitNormal,
2092 CORBA::Short methodFlags,
2093 CORBA::Boolean allDomains)
2094 throw (SALOME::SALOME_Exception)
2098 prepareIdSource( elems );
2100 gp_Ax1 facetNorm( gp_Pnt( startHexPoint.x,
2103 gp_Dir( facetToSplitNormal.PS.x,
2104 facetToSplitNormal.PS.y,
2105 facetToSplitNormal.PS.z ));
2106 TIDSortedElemSet elemSet;
2107 SMESH::long_array_var anElementsId = elems->GetIDs();
2108 SMDS_MeshElement::GeomFilter filter( SMDSGeom_HEXA );
2109 arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume, &filter );
2111 ::SMESH_MeshEditor::TFacetOfElem elemFacets;
2112 while ( !elemSet.empty() )
2114 getEditor().GetHexaFacetsToSplit( elemSet, facetNorm, elemFacets );
2118 ::SMESH_MeshEditor::TFacetOfElem::iterator ef = elemFacets.begin();
2119 for ( ; ef != elemFacets.end(); ++ef )
2120 elemSet.erase( ef->first );
2123 if ( methodFlags == 2 )
2124 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_4_PRISMS );
2126 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_2_PRISMS );
2128 getEditor().SplitVolumes( elemFacets, int( methodFlags ));
2129 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2131 TPythonDump() << this << ".SplitHexahedraIntoPrisms( "
2133 << startHexPoint << ", "
2134 << facetToSplitNormal<< ", "
2135 << methodFlags<< ", "
2136 << allDomains << " )";
2138 SMESH_CATCH( SMESH::throwCorbaException );
2141 //================================================================================
2143 * \brief Split bi-quadratic elements into linear ones without creation of additional nodes:
2144 * - bi-quadratic triangle will be split into 3 linear quadrangles;
2145 * - bi-quadratic quadrangle will be split into 4 linear quadrangles;
2146 * - tri-quadratic hexahedron will be split into 8 linear hexahedra.
2147 * Quadratic elements of lower dimension adjacent to the split bi-quadratic element
2148 * will be split in order to keep the mesh conformal.
2149 * \param elems - elements to split
2151 //================================================================================
2153 void SMESH_MeshEditor_i::SplitBiQuadraticIntoLinear(const SMESH::ListOfIDSources& theElems)
2154 throw (SALOME::SALOME_Exception)
2159 TIDSortedElemSet elemSet;
2160 for ( size_t i = 0; i < theElems.length(); ++i )
2162 SMESH::SMESH_IDSource_ptr elems = theElems[i].in();
2163 SMESH::SMESH_Mesh_var mesh = elems->GetMesh();
2164 if ( mesh->GetId() != myMesh_i->GetId() )
2165 THROW_SALOME_CORBA_EXCEPTION("Wrong mesh of IDSource", SALOME::BAD_PARAM);
2167 idSourceToSet( elems, getMeshDS(), elemSet, SMDSAbs_All );
2169 getEditor().SplitBiQuadraticIntoLinear( elemSet );
2171 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2173 TPythonDump() << this << ".SplitBiQuadraticIntoLinear( "
2174 << theElems << " )";
2176 SMESH_CATCH( SMESH::throwCorbaException );
2179 //=======================================================================
2182 //=======================================================================
2185 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
2186 const SMESH::long_array & IDsOfFixedNodes,
2187 CORBA::Long MaxNbOfIterations,
2188 CORBA::Double MaxAspectRatio,
2189 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2190 throw (SALOME::SALOME_Exception)
2192 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2193 MaxAspectRatio, Method, false );
2197 //=======================================================================
2198 //function : SmoothParametric
2200 //=======================================================================
2203 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
2204 const SMESH::long_array & IDsOfFixedNodes,
2205 CORBA::Long MaxNbOfIterations,
2206 CORBA::Double MaxAspectRatio,
2207 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2208 throw (SALOME::SALOME_Exception)
2210 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2211 MaxAspectRatio, Method, true );
2215 //=======================================================================
2216 //function : SmoothObject
2218 //=======================================================================
2221 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
2222 const SMESH::long_array & IDsOfFixedNodes,
2223 CORBA::Long MaxNbOfIterations,
2224 CORBA::Double MaxAspectRatio,
2225 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2226 throw (SALOME::SALOME_Exception)
2228 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2229 MaxAspectRatio, Method, false);
2233 //=======================================================================
2234 //function : SmoothParametricObject
2236 //=======================================================================
2239 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
2240 const SMESH::long_array & IDsOfFixedNodes,
2241 CORBA::Long MaxNbOfIterations,
2242 CORBA::Double MaxAspectRatio,
2243 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2244 throw (SALOME::SALOME_Exception)
2246 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2247 MaxAspectRatio, Method, true);
2251 //=============================================================================
2255 //=============================================================================
2258 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
2259 const SMESH::long_array & IDsOfFixedNodes,
2260 CORBA::Long MaxNbOfIterations,
2261 CORBA::Double MaxAspectRatio,
2262 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2264 throw (SALOME::SALOME_Exception)
2269 SMESHDS_Mesh* aMesh = getMeshDS();
2271 TIDSortedElemSet elements;
2272 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
2274 set<const SMDS_MeshNode*> fixedNodes;
2275 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
2276 CORBA::Long index = IDsOfFixedNodes[i];
2277 const SMDS_MeshNode * node = aMesh->FindNode(index);
2279 fixedNodes.insert( node );
2281 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
2282 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
2283 method = ::SMESH_MeshEditor::CENTROIDAL;
2285 getEditor().Smooth(elements, fixedNodes, method,
2286 MaxNbOfIterations, MaxAspectRatio, IsParametric );
2288 declareMeshModified( /*isReComputeSafe=*/true ); // does not prevent re-compute
2290 // Update Python script
2291 TPythonDump() << "isDone = " << this << "."
2292 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
2293 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
2294 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2295 << "SMESH.SMESH_MeshEditor."
2296 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2297 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2301 SMESH_CATCH( SMESH::throwCorbaException );
2305 //=============================================================================
2309 //=============================================================================
2312 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
2313 const SMESH::long_array & IDsOfFixedNodes,
2314 CORBA::Long MaxNbOfIterations,
2315 CORBA::Double MaxAspectRatio,
2316 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2318 throw (SALOME::SALOME_Exception)
2323 TPythonDump aTPythonDump; // suppress dump in smooth()
2325 prepareIdSource( theObject );
2326 SMESH::long_array_var anElementsId = theObject->GetIDs();
2327 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
2328 MaxAspectRatio, Method, IsParametric);
2330 // Update Python script
2331 aTPythonDump << "isDone = " << this << "."
2332 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
2333 << theObject << ", " << IDsOfFixedNodes << ", "
2334 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2335 << "SMESH.SMESH_MeshEditor."
2336 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2337 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2341 SMESH_CATCH( SMESH::throwCorbaException );
2345 //=============================================================================
2349 //=============================================================================
2351 void SMESH_MeshEditor_i::RenumberNodes()
2352 throw (SALOME::SALOME_Exception)
2355 // Update Python script
2356 TPythonDump() << this << ".RenumberNodes()";
2358 getMeshDS()->Renumber( true );
2360 SMESH_CATCH( SMESH::throwCorbaException );
2363 //=============================================================================
2367 //=============================================================================
2369 void SMESH_MeshEditor_i::RenumberElements()
2370 throw (SALOME::SALOME_Exception)
2373 // Update Python script
2374 TPythonDump() << this << ".RenumberElements()";
2376 getMeshDS()->Renumber( false );
2378 SMESH_CATCH( SMESH::throwCorbaException );
2381 //=======================================================================
2383 * \brief Return groups by their IDs
2385 //=======================================================================
2387 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
2388 throw (SALOME::SALOME_Exception)
2393 myMesh_i->CreateGroupServants();
2394 return myMesh_i->GetGroups( *groupIDs );
2396 SMESH_CATCH( SMESH::throwCorbaException );
2400 //=======================================================================
2401 //function : RotationSweepObjects
2403 //=======================================================================
2405 SMESH::ListOfGroups*
2406 SMESH_MeshEditor_i::RotationSweepObjects(const SMESH::ListOfIDSources & theNodes,
2407 const SMESH::ListOfIDSources & theEdges,
2408 const SMESH::ListOfIDSources & theFaces,
2409 const SMESH::AxisStruct & theAxis,
2410 CORBA::Double theAngleInRadians,
2411 CORBA::Long theNbOfSteps,
2412 CORBA::Double theTolerance,
2413 const bool theMakeGroups)
2414 throw (SALOME::SALOME_Exception)
2419 TIDSortedElemSet elemsNodes[2];
2420 for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) {
2421 SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE );
2422 while ( nIt->more() ) elemsNodes[1].insert( nIt->next() );
2424 for ( int i = 0, nb = theEdges.length(); i < nb; ++i )
2425 idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge );
2426 for ( int i = 0, nb = theFaces.length(); i < nb; ++i )
2427 idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face );
2429 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2430 bool makeWalls=true;
2431 if ( myIsPreviewMode )
2433 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2434 TPreviewMesh * tmpMesh = getPreviewMesh();
2435 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2436 tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid );
2437 workElements = & copyElements[0];
2438 //makeWalls = false; -- faces are needed for preview
2441 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2443 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
2444 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
2446 ::SMESH_MeshEditor::PGroupIDs groupIds =
2447 getEditor().RotationSweep (workElements, Ax1, theAngleInRadians,
2448 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
2450 SMESH::ListOfGroups * aGroups = theMakeGroups ? getGroups( groupIds.get()) : 0;
2452 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2454 if ( !myIsPreviewMode )
2456 dumpGroupsList( aPythonDump, aGroups );
2457 aPythonDump << this<< ".RotationSweepObjects( "
2462 << TVar( theAngleInRadians ) << ", "
2463 << TVar( theNbOfSteps ) << ", "
2464 << TVar( theTolerance ) << ", "
2465 << theMakeGroups << " )";
2469 getPreviewMesh()->Remove( SMDSAbs_Volume );
2472 return aGroups ? aGroups : new SMESH::ListOfGroups;
2474 SMESH_CATCH( SMESH::throwCorbaException );
2478 namespace MeshEditor_I
2481 * \brief Structure used to pass extrusion parameters to ::SMESH_MeshEditor
2483 struct ExtrusionParams : public ::SMESH_MeshEditor::ExtrusParam
2485 bool myIsExtrusionByNormal;
2487 static int makeFlags( CORBA::Boolean MakeGroups,
2488 CORBA::Boolean ByAverageNormal = false,
2489 CORBA::Boolean UseInputElemsOnly = false,
2490 CORBA::Long Flags = 0,
2491 CORBA::Boolean MakeBoundary = true )
2493 if ( MakeGroups ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS;
2494 if ( ByAverageNormal ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BY_AVG_NORMAL;
2495 if ( UseInputElemsOnly) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY;
2496 if ( MakeBoundary ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BOUNDARY;
2500 ExtrusionParams(const SMESH::DirStruct & theDir,
2501 CORBA::Long theNbOfSteps,
2502 CORBA::Boolean theMakeGroups):
2503 ::SMESH_MeshEditor::ExtrusParam ( gp_Vec( theDir.PS.x,
2507 makeFlags( theMakeGroups )),
2508 myIsExtrusionByNormal( false )
2512 ExtrusionParams(const SMESH::DirStruct & theDir,
2513 CORBA::Long theNbOfSteps,
2514 CORBA::Boolean theMakeGroups,
2515 CORBA::Long theExtrFlags,
2516 CORBA::Double theSewTolerance):
2517 ::SMESH_MeshEditor::ExtrusParam ( gp_Vec( theDir.PS.x,
2521 makeFlags( theMakeGroups, false, false,
2522 theExtrFlags, false ),
2524 myIsExtrusionByNormal( false )
2527 // params for extrusion by normal
2528 ExtrusionParams(CORBA::Double theStepSize,
2529 CORBA::Long theNbOfSteps,
2530 CORBA::Short theDim,
2531 CORBA::Boolean theByAverageNormal,
2532 CORBA::Boolean theUseInputElemsOnly,
2533 CORBA::Boolean theMakeGroups ):
2534 ::SMESH_MeshEditor::ExtrusParam ( theStepSize,
2536 makeFlags( theMakeGroups,
2537 theByAverageNormal, theUseInputElemsOnly ),
2539 myIsExtrusionByNormal( true )
2545 Flags() &= ~(::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS);
2550 //=======================================================================
2552 * \brief Generate dim+1 elements by extrusion of elements along vector
2553 * \param [in] edges - edges to extrude: a list including groups, sub-meshes or a mesh
2554 * \param [in] faces - faces to extrude: a list including groups, sub-meshes or a mesh
2555 * \param [in] nodes - nodes to extrude: a list including groups, sub-meshes or a mesh
2556 * \param [in] stepVector - vector giving direction and distance of an extrusion step
2557 * \param [in] nbOfSteps - number of elements to generate from one element
2558 * \param [in] toMakeGroups - if true, new elements will be included into new groups
2559 * corresponding to groups the input elements included in.
2560 * \return ListOfGroups - new groups craeted if \a toMakeGroups is true
2562 //=======================================================================
2564 SMESH::ListOfGroups*
2565 SMESH_MeshEditor_i::ExtrusionSweepObjects(const SMESH::ListOfIDSources & theNodes,
2566 const SMESH::ListOfIDSources & theEdges,
2567 const SMESH::ListOfIDSources & theFaces,
2568 const SMESH::DirStruct & theStepVector,
2569 CORBA::Long theNbOfSteps,
2570 CORBA::Boolean theToMakeGroups)
2571 throw (SALOME::SALOME_Exception)
2576 ExtrusionParams params( theStepVector, theNbOfSteps, theToMakeGroups );
2578 TIDSortedElemSet elemsNodes[2];
2579 for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) {
2580 SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE );
2581 while ( nIt->more() ) elemsNodes[1].insert( nIt->next() );
2583 for ( int i = 0, nb = theEdges.length(); i < nb; ++i )
2584 idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge );
2585 for ( int i = 0, nb = theFaces.length(); i < nb; ++i )
2586 idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face );
2588 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2589 SMDSAbs_ElementType previewType = SMDSAbs_All; //SMDSAbs_Face;
2590 if ( myIsPreviewMode )
2592 // if ( (*elemsNodes.begin())->GetType() == SMDSAbs_Node )
2593 // previewType = SMDSAbs_Edge;
2595 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2596 TPreviewMesh * tmpMesh = getPreviewMesh( previewType );
2597 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2598 tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid );
2599 workElements = & copyElements[0];
2601 params.SetNoGroups();
2603 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2605 ::SMESH_MeshEditor::TTElemOfElemListMap aHistory;
2606 ::SMESH_MeshEditor::PGroupIDs groupIds =
2607 getEditor().ExtrusionSweep( workElements, params, aHistory );
2609 SMESH::ListOfGroups * aGroups = theToMakeGroups ? getGroups( groupIds.get()) : 0;
2611 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2613 if ( !myIsPreviewMode )
2615 dumpGroupsList( aPythonDump, aGroups );
2616 aPythonDump << this<< ".ExtrusionSweepObjects( "
2620 << theStepVector << ", "
2621 << TVar( theNbOfSteps ) << ", "
2622 << theToMakeGroups << " )";
2626 getPreviewMesh( previewType )->Remove( SMDSAbs_Volume );
2629 return aGroups ? aGroups : new SMESH::ListOfGroups;
2631 SMESH_CATCH( SMESH::throwCorbaException );
2635 //=======================================================================
2636 //function : ExtrusionByNormal
2638 //=======================================================================
2640 SMESH::ListOfGroups*
2641 SMESH_MeshEditor_i::ExtrusionByNormal(const SMESH::ListOfIDSources& objects,
2642 CORBA::Double stepSize,
2643 CORBA::Long nbOfSteps,
2644 CORBA::Boolean byAverageNormal,
2645 CORBA::Boolean useInputElemsOnly,
2646 CORBA::Boolean makeGroups,
2648 throw (SALOME::SALOME_Exception)
2653 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2655 ExtrusionParams params( stepSize, nbOfSteps, dim,
2656 byAverageNormal, useInputElemsOnly, makeGroups );
2658 SMDSAbs_ElementType elemType = ( dim == 1 ? SMDSAbs_Edge : SMDSAbs_Face );
2659 if ( objects.length() > 0 && !SMESH::DownCast<SMESH_Mesh_i*>( objects[0] ))
2661 SMESH::array_of_ElementType_var elemTypes = objects[0]->GetTypes();
2662 if (( elemTypes->length() == 1 ) &&
2663 ( elemTypes[0] == SMESH::EDGE || elemTypes[0] == SMESH::FACE ))
2664 elemType = ( SMDSAbs_ElementType ) elemTypes[0];
2667 TIDSortedElemSet elemsNodes[2];
2668 for ( int i = 0, nb = objects.length(); i < nb; ++i )
2669 idSourceToSet( objects[i], getMeshDS(), elemsNodes[0], elemType );
2671 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2672 SMDSAbs_ElementType previewType = SMDSAbs_Face;
2673 if ( myIsPreviewMode )
2675 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2676 TPreviewMesh * tmpMesh = getPreviewMesh( previewType );
2677 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2678 workElements = & copyElements[0];
2680 params.SetNoGroups();
2683 ::SMESH_MeshEditor::TTElemOfElemListMap aHistory;
2684 ::SMESH_MeshEditor::PGroupIDs groupIds =
2685 getEditor().ExtrusionSweep( workElements, params, aHistory );
2687 SMESH::ListOfGroups * aGroups = makeGroups ? getGroups( groupIds.get()) : 0;
2689 if (!myIsPreviewMode) {
2690 dumpGroupsList(aPythonDump, aGroups);
2691 aPythonDump << this << ".ExtrusionByNormal( " << objects
2692 << ", " << TVar( stepSize )
2693 << ", " << TVar( nbOfSteps )
2694 << ", " << byAverageNormal
2695 << ", " << useInputElemsOnly
2696 << ", " << makeGroups
2702 getPreviewMesh( previewType )->Remove( SMDSAbs_Volume );
2705 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2707 return aGroups ? aGroups : new SMESH::ListOfGroups;
2709 SMESH_CATCH( SMESH::throwCorbaException );
2713 //=======================================================================
2714 //function : AdvancedExtrusion
2716 //=======================================================================
2718 SMESH::ListOfGroups*
2719 SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2720 const SMESH::DirStruct & theStepVector,
2721 CORBA::Long theNbOfSteps,
2722 CORBA::Long theExtrFlags,
2723 CORBA::Double theSewTolerance,
2724 CORBA::Boolean theMakeGroups)
2725 throw (SALOME::SALOME_Exception)
2730 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2732 ExtrusionParams params( theStepVector, theNbOfSteps, theMakeGroups,
2733 theExtrFlags, theSewTolerance );
2735 TIDSortedElemSet elemsNodes[2];
2736 arrayToSet( theIDsOfElements, getMeshDS(), elemsNodes[0] );
2738 ::SMESH_MeshEditor::TTElemOfElemListMap aHistory;
2739 ::SMESH_MeshEditor::PGroupIDs groupIds =
2740 getEditor().ExtrusionSweep( elemsNodes, params, aHistory );
2742 SMESH::ListOfGroups * aGroups = theMakeGroups ? getGroups( groupIds.get()) : 0;
2744 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2746 if ( !myIsPreviewMode ) {
2747 dumpGroupsList(aPythonDump, aGroups);
2748 aPythonDump << this << ".AdvancedExtrusion( "
2749 << theIDsOfElements << ", "
2750 << theStepVector << ", "
2751 << theNbOfSteps << ", "
2752 << theExtrFlags << ", "
2753 << theSewTolerance << ", "
2754 << theMakeGroups << " )";
2758 getPreviewMesh()->Remove( SMDSAbs_Volume );
2761 return aGroups ? aGroups : new SMESH::ListOfGroups;
2763 SMESH_CATCH( SMESH::throwCorbaException );
2767 //================================================================================
2769 * \brief Convert extrusion error to IDL enum
2771 //================================================================================
2775 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
2777 SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( ::SMESH_MeshEditor::Extrusion_Error e )
2781 RETCASE( EXTR_NO_ELEMENTS );
2782 RETCASE( EXTR_PATH_NOT_EDGE );
2783 RETCASE( EXTR_BAD_PATH_SHAPE );
2784 RETCASE( EXTR_BAD_STARTING_NODE );
2785 RETCASE( EXTR_BAD_ANGLES_NUMBER );
2786 RETCASE( EXTR_CANT_GET_TANGENT );
2788 return SMESH::SMESH_MeshEditor::EXTR_OK;
2792 //=======================================================================
2793 //function : extrusionAlongPath
2795 //=======================================================================
2796 SMESH::ListOfGroups*
2797 SMESH_MeshEditor_i::ExtrusionAlongPathObjects(const SMESH::ListOfIDSources & theNodes,
2798 const SMESH::ListOfIDSources & theEdges,
2799 const SMESH::ListOfIDSources & theFaces,
2800 SMESH::SMESH_IDSource_ptr thePathMesh,
2801 GEOM::GEOM_Object_ptr thePathShape,
2802 CORBA::Long theNodeStart,
2803 CORBA::Boolean theHasAngles,
2804 const SMESH::double_array & theAngles,
2805 CORBA::Boolean theLinearVariation,
2806 CORBA::Boolean theHasRefPoint,
2807 const SMESH::PointStruct & theRefPoint,
2809 SMESH::SMESH_MeshEditor::Extrusion_Error& theError)
2810 throw (SALOME::SALOME_Exception)
2815 SMESH::ListOfGroups_var aGroups = new SMESH::ListOfGroups;
2817 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2818 if ( thePathMesh->_is_nil() )
2819 return aGroups._retn();
2822 SMESH_subMesh* aSubMesh = 0;
2823 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2824 if ( thePathShape->_is_nil() )
2826 // thePathMesh should be either a sub-mesh or a mesh with 1D elements only
2827 if ( SMESH_subMesh_i* sm = SMESH::DownCast<SMESH_subMesh_i*>( thePathMesh ))
2829 SMESH::SMESH_Mesh_var mesh = thePathMesh->GetMesh();
2830 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
2831 if ( !aMeshImp ) return aGroups._retn();
2832 aSubMesh = aMeshImp->GetImpl().GetSubMeshContaining( sm->GetId() );
2833 if ( !aSubMesh ) return aGroups._retn();
2835 else if ( !aMeshImp ||
2836 aMeshImp->NbEdges() != aMeshImp->NbElements() )
2838 return aGroups._retn();
2843 if ( !aMeshImp ) return aGroups._retn();
2844 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2845 aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2846 if ( !aSubMesh || !aSubMesh->GetSubMeshDS() )
2847 return aGroups._retn();
2850 SMDS_MeshNode* nodeStart =
2851 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
2853 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2854 return aGroups._retn();
2857 TIDSortedElemSet elemsNodes[2];
2858 for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) {
2859 SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE );
2860 while ( nIt->more() ) elemsNodes[1].insert( nIt->next() );
2862 for ( int i = 0, nb = theEdges.length(); i < nb; ++i )
2863 idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge );
2864 for ( int i = 0, nb = theFaces.length(); i < nb; ++i )
2865 idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face );
2867 list<double> angles;
2868 for (int i = 0; i < theAngles.length(); i++) {
2869 angles.push_back( theAngles[i] );
2872 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
2874 int nbOldGroups = myMesh->NbGroup();
2876 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2877 if ( myIsPreviewMode )
2879 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2880 TPreviewMesh * tmpMesh = getPreviewMesh();
2881 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2882 tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid );
2883 workElements = & copyElements[0];
2884 theMakeGroups = false;
2887 ::SMESH_MeshEditor::Extrusion_Error error;
2889 error = getEditor().ExtrusionAlongTrack( workElements, &(aMeshImp->GetImpl()), nodeStart,
2890 theHasAngles, angles, theLinearVariation,
2891 theHasRefPoint, refPnt, theMakeGroups );
2893 error = getEditor().ExtrusionAlongTrack( workElements, aSubMesh, nodeStart,
2894 theHasAngles, angles, theLinearVariation,
2895 theHasRefPoint, refPnt, theMakeGroups );
2897 declareMeshModified( /*isReComputeSafe=*/true );
2898 theError = convExtrError( error );
2900 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2901 if ( theMakeGroups ) {
2902 list<int> groupIDs = myMesh->GetGroupIds();
2903 list<int>::iterator newBegin = groupIDs.begin();
2904 std::advance( newBegin, nbOldGroups ); // skip old groups
2905 groupIDs.erase( groupIDs.begin(), newBegin );
2906 aGroups = getGroups( & groupIDs );
2907 if ( ! &aGroups.in() ) aGroups = new SMESH::ListOfGroups;
2910 if ( !myIsPreviewMode ) {
2911 aPythonDump << "(" << aGroups << ", error) = "
2912 << this << ".ExtrusionAlongPathObjects( "
2916 << thePathMesh << ", "
2917 << thePathShape << ", "
2918 << theNodeStart << ", "
2919 << theHasAngles << ", "
2920 << theAngles << ", "
2921 << theLinearVariation << ", "
2922 << theHasRefPoint << ", "
2923 << "SMESH.PointStruct( "
2924 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2925 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2926 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ), "
2927 << theMakeGroups << " )";
2931 getPreviewMesh()->Remove( SMDSAbs_Volume );
2934 return aGroups._retn();
2936 SMESH_CATCH( SMESH::throwCorbaException );
2940 //================================================================================
2942 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
2943 * of given angles along path steps
2944 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
2945 * which proceeds the extrusion
2946 * \param PathShape is shape(edge); as the mesh can be complex, the edge
2947 * is used to define the sub-mesh for the path
2949 //================================================================================
2951 SMESH::double_array*
2952 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
2953 GEOM::GEOM_Object_ptr thePathShape,
2954 const SMESH::double_array & theAngles)
2956 SMESH::double_array_var aResult = new SMESH::double_array();
2957 int nbAngles = theAngles.length();
2958 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
2960 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2961 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2962 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2963 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
2964 return aResult._retn();
2965 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
2966 if ( nbSteps == nbAngles )
2968 aResult.inout() = theAngles;
2972 aResult->length( nbSteps );
2973 double rAn2St = double( nbAngles ) / double( nbSteps );
2974 double angPrev = 0, angle;
2975 for ( int iSt = 0; iSt < nbSteps; ++iSt )
2977 double angCur = rAn2St * ( iSt+1 );
2978 double angCurFloor = floor( angCur );
2979 double angPrevFloor = floor( angPrev );
2980 if ( angPrevFloor == angCurFloor )
2981 angle = rAn2St * theAngles[ int( angCurFloor ) ];
2984 int iP = int( angPrevFloor );
2985 double angPrevCeil = ceil(angPrev);
2986 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
2988 int iC = int( angCurFloor );
2989 if ( iC < nbAngles )
2990 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
2992 iP = int( angPrevCeil );
2994 angle += theAngles[ iC ];
2996 aResult[ iSt ] = angle;
3001 // Update Python script
3002 TPythonDump() << "rotAngles = " << theAngles;
3003 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
3004 << thePathMesh << ", "
3005 << thePathShape << ", "
3008 return aResult._retn();
3011 //=======================================================================
3014 //=======================================================================
3016 SMESH::ListOfGroups*
3017 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
3018 const SMESH::AxisStruct & theAxis,
3019 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3020 CORBA::Boolean theCopy,
3022 ::SMESH_Mesh* theTargetMesh)
3023 throw (SALOME::SALOME_Exception)
3028 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3029 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3031 if ( theTargetMesh )
3035 switch ( theMirrorType ) {
3036 case SMESH::SMESH_MeshEditor::POINT:
3037 aTrsf.SetMirror( P );
3039 case SMESH::SMESH_MeshEditor::AXIS:
3040 aTrsf.SetMirror( gp_Ax1( P, V ));
3043 aTrsf.SetMirror( gp_Ax2( P, V ));
3046 TIDSortedElemSet copyElements;
3047 TIDSortedElemSet* workElements = & theElements;
3049 if ( myIsPreviewMode )
3051 TPreviewMesh * tmpMesh = getPreviewMesh();
3052 tmpMesh->Copy( theElements, copyElements);
3053 if ( !theCopy && !theTargetMesh )
3055 TIDSortedElemSet elemsAround, elemsAroundCopy;
3056 getElementsAround( theElements, getMeshDS(), elemsAround );
3057 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3059 workElements = & copyElements;
3060 theMakeGroups = false;
3063 ::SMESH_MeshEditor::PGroupIDs groupIds =
3064 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3066 if ( theCopy && !myIsPreviewMode)
3068 if ( theTargetMesh )
3070 theTargetMesh->GetMeshDS()->Modified();
3074 declareMeshModified( /*isReComputeSafe=*/false );
3077 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3079 SMESH_CATCH( SMESH::throwCorbaException );
3083 //=======================================================================
3086 //=======================================================================
3088 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3089 const SMESH::AxisStruct & theAxis,
3090 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3091 CORBA::Boolean theCopy)
3092 throw (SALOME::SALOME_Exception)
3094 if ( !myIsPreviewMode ) {
3095 TPythonDump() << this << ".Mirror( "
3096 << theIDsOfElements << ", "
3098 << mirrorTypeName(theMirrorType) << ", "
3101 if ( theIDsOfElements.length() > 0 )
3103 TIDSortedElemSet elements;
3104 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3105 mirror(elements, theAxis, theMirrorType, theCopy, false);
3110 //=======================================================================
3111 //function : MirrorObject
3113 //=======================================================================
3115 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3116 const SMESH::AxisStruct & theAxis,
3117 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3118 CORBA::Boolean theCopy)
3119 throw (SALOME::SALOME_Exception)
3121 if ( !myIsPreviewMode ) {
3122 TPythonDump() << this << ".MirrorObject( "
3123 << theObject << ", "
3125 << mirrorTypeName(theMirrorType) << ", "
3128 TIDSortedElemSet elements;
3130 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3132 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3133 mirror(elements, theAxis, theMirrorType, theCopy, false);
3136 //=======================================================================
3137 //function : MirrorMakeGroups
3139 //=======================================================================
3141 SMESH::ListOfGroups*
3142 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3143 const SMESH::AxisStruct& theMirror,
3144 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3145 throw (SALOME::SALOME_Exception)
3147 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3149 SMESH::ListOfGroups * aGroups = 0;
3150 if ( theIDsOfElements.length() > 0 )
3152 TIDSortedElemSet elements;
3153 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3154 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3156 if (!myIsPreviewMode) {
3157 dumpGroupsList(aPythonDump, aGroups);
3158 aPythonDump << this << ".MirrorMakeGroups( "
3159 << theIDsOfElements << ", "
3160 << theMirror << ", "
3161 << mirrorTypeName(theMirrorType) << " )";
3166 //=======================================================================
3167 //function : MirrorObjectMakeGroups
3169 //=======================================================================
3171 SMESH::ListOfGroups*
3172 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3173 const SMESH::AxisStruct& theMirror,
3174 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3175 throw (SALOME::SALOME_Exception)
3177 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3179 SMESH::ListOfGroups * aGroups = 0;
3180 TIDSortedElemSet elements;
3181 if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3182 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3184 if (!myIsPreviewMode)
3186 dumpGroupsList(aPythonDump,aGroups);
3187 aPythonDump << this << ".MirrorObjectMakeGroups( "
3188 << theObject << ", "
3189 << theMirror << ", "
3190 << mirrorTypeName(theMirrorType) << " )";
3195 //=======================================================================
3196 //function : MirrorMakeMesh
3198 //=======================================================================
3200 SMESH::SMESH_Mesh_ptr
3201 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
3202 const SMESH::AxisStruct& theMirror,
3203 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3204 CORBA::Boolean theCopyGroups,
3205 const char* theMeshName)
3206 throw (SALOME::SALOME_Exception)
3208 SMESH_Mesh_i* mesh_i;
3209 SMESH::SMESH_Mesh_var mesh;
3210 { // open new scope to dump "MakeMesh" command
3211 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3213 TPythonDump pydump; // to prevent dump at mesh creation
3215 mesh = makeMesh( theMeshName );
3216 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3217 if (mesh_i && theIDsOfElements.length() > 0 )
3219 TIDSortedElemSet elements;
3220 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3221 mirror(elements, theMirror, theMirrorType,
3222 false, theCopyGroups, & mesh_i->GetImpl());
3223 mesh_i->CreateGroupServants();
3226 if (!myIsPreviewMode) {
3227 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
3228 << theIDsOfElements << ", "
3229 << theMirror << ", "
3230 << mirrorTypeName(theMirrorType) << ", "
3231 << theCopyGroups << ", '"
3232 << theMeshName << "' )";
3237 if (!myIsPreviewMode && mesh_i)
3238 mesh_i->GetGroups();
3240 return mesh._retn();
3243 //=======================================================================
3244 //function : MirrorObjectMakeMesh
3246 //=======================================================================
3248 SMESH::SMESH_Mesh_ptr
3249 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3250 const SMESH::AxisStruct& theMirror,
3251 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3252 CORBA::Boolean theCopyGroups,
3253 const char* theMeshName)
3254 throw (SALOME::SALOME_Exception)
3256 SMESH_Mesh_i* mesh_i;
3257 SMESH::SMESH_Mesh_var mesh;
3258 { // open new scope to dump "MakeMesh" command
3259 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3261 TPythonDump pydump; // to prevent dump at mesh creation
3263 mesh = makeMesh( theMeshName );
3264 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3265 TIDSortedElemSet elements;
3267 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3269 mirror(elements, theMirror, theMirrorType,
3270 false, theCopyGroups, & mesh_i->GetImpl());
3271 mesh_i->CreateGroupServants();
3273 if (!myIsPreviewMode) {
3274 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
3275 << theObject << ", "
3276 << theMirror << ", "
3277 << mirrorTypeName(theMirrorType) << ", "
3278 << theCopyGroups << ", '"
3279 << theMeshName << "' )";
3284 if (!myIsPreviewMode && mesh_i)
3285 mesh_i->GetGroups();
3287 return mesh._retn();
3290 //=======================================================================
3291 //function : translate
3293 //=======================================================================
3295 SMESH::ListOfGroups*
3296 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
3297 const SMESH::DirStruct & theVector,
3298 CORBA::Boolean theCopy,
3300 ::SMESH_Mesh* theTargetMesh)
3301 throw (SALOME::SALOME_Exception)
3306 if ( theTargetMesh )
3310 const SMESH::PointStruct * P = &theVector.PS;
3311 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
3313 TIDSortedElemSet copyElements;
3314 TIDSortedElemSet* workElements = &theElements;
3316 if ( myIsPreviewMode )
3318 TPreviewMesh * tmpMesh = getPreviewMesh();
3319 tmpMesh->Copy( theElements, copyElements);
3320 if ( !theCopy && !theTargetMesh )
3322 TIDSortedElemSet elemsAround, elemsAroundCopy;
3323 getElementsAround( theElements, getMeshDS(), elemsAround );
3324 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3326 workElements = & copyElements;
3327 theMakeGroups = false;
3330 ::SMESH_MeshEditor::PGroupIDs groupIds =
3331 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3333 if ( theCopy && !myIsPreviewMode )
3335 if ( theTargetMesh )
3337 theTargetMesh->GetMeshDS()->Modified();
3341 declareMeshModified( /*isReComputeSafe=*/false );
3345 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3347 SMESH_CATCH( SMESH::throwCorbaException );
3351 //=======================================================================
3352 //function : Translate
3354 //=======================================================================
3356 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
3357 const SMESH::DirStruct & theVector,
3358 CORBA::Boolean theCopy)
3359 throw (SALOME::SALOME_Exception)
3361 if (!myIsPreviewMode) {
3362 TPythonDump() << this << ".Translate( "
3363 << theIDsOfElements << ", "
3364 << theVector << ", "
3367 if (theIDsOfElements.length()) {
3368 TIDSortedElemSet elements;
3369 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3370 translate(elements, theVector, theCopy, false);
3374 //=======================================================================
3375 //function : TranslateObject
3377 //=======================================================================
3379 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
3380 const SMESH::DirStruct & theVector,
3381 CORBA::Boolean theCopy)
3382 throw (SALOME::SALOME_Exception)
3384 if (!myIsPreviewMode) {
3385 TPythonDump() << this << ".TranslateObject( "
3386 << theObject << ", "
3387 << theVector << ", "
3390 TIDSortedElemSet elements;
3392 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3394 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3395 translate(elements, theVector, theCopy, false);
3398 //=======================================================================
3399 //function : TranslateMakeGroups
3401 //=======================================================================
3403 SMESH::ListOfGroups*
3404 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
3405 const SMESH::DirStruct& theVector)
3406 throw (SALOME::SALOME_Exception)
3408 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3410 SMESH::ListOfGroups * aGroups = 0;
3411 if (theIDsOfElements.length()) {
3412 TIDSortedElemSet elements;
3413 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3414 aGroups = translate(elements,theVector,true,true);
3416 if (!myIsPreviewMode) {
3417 dumpGroupsList(aPythonDump, aGroups);
3418 aPythonDump << this << ".TranslateMakeGroups( "
3419 << theIDsOfElements << ", "
3420 << theVector << " )";
3425 //=======================================================================
3426 //function : TranslateObjectMakeGroups
3428 //=======================================================================
3430 SMESH::ListOfGroups*
3431 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3432 const SMESH::DirStruct& theVector)
3433 throw (SALOME::SALOME_Exception)
3435 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3437 SMESH::ListOfGroups * aGroups = 0;
3438 TIDSortedElemSet elements;
3439 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3440 aGroups = translate(elements, theVector, true, true);
3442 if (!myIsPreviewMode) {
3443 dumpGroupsList(aPythonDump, aGroups);
3444 aPythonDump << this << ".TranslateObjectMakeGroups( "
3445 << theObject << ", "
3446 << theVector << " )";
3451 //=======================================================================
3452 //function : TranslateMakeMesh
3454 //=======================================================================
3456 SMESH::SMESH_Mesh_ptr
3457 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
3458 const SMESH::DirStruct& theVector,
3459 CORBA::Boolean theCopyGroups,
3460 const char* theMeshName)
3461 throw (SALOME::SALOME_Exception)
3463 SMESH_Mesh_i* mesh_i;
3464 SMESH::SMESH_Mesh_var mesh;
3466 { // open new scope to dump "MakeMesh" command
3467 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3469 TPythonDump pydump; // to prevent dump at mesh creation
3471 mesh = makeMesh( theMeshName );
3472 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3474 if ( mesh_i && theIDsOfElements.length() )
3476 TIDSortedElemSet elements;
3477 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3478 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
3479 mesh_i->CreateGroupServants();
3482 if ( !myIsPreviewMode ) {
3483 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
3484 << theIDsOfElements << ", "
3485 << theVector << ", "
3486 << theCopyGroups << ", '"
3487 << theMeshName << "' )";
3492 if (!myIsPreviewMode && mesh_i)
3493 mesh_i->GetGroups();
3495 return mesh._retn();
3498 //=======================================================================
3499 //function : TranslateObjectMakeMesh
3501 //=======================================================================
3503 SMESH::SMESH_Mesh_ptr
3504 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3505 const SMESH::DirStruct& theVector,
3506 CORBA::Boolean theCopyGroups,
3507 const char* theMeshName)
3508 throw (SALOME::SALOME_Exception)
3511 SMESH_Mesh_i* mesh_i;
3512 SMESH::SMESH_Mesh_var mesh;
3513 { // open new scope to dump "MakeMesh" command
3514 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3516 TPythonDump pydump; // to prevent dump at mesh creation
3517 mesh = makeMesh( theMeshName );
3518 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3520 TIDSortedElemSet elements;
3522 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3524 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
3525 mesh_i->CreateGroupServants();