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 ( CORBA::ULong i = 0; i < IDs.length(); i++ ) {
289 const SMDS_MeshElement * elem = aMesh->FindNode( IDs[i] );
291 aMap.insert( aMap.end(), elem );
294 for ( CORBA::ULong 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 ( CORBA::ULong 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 ( CORBA::ULong 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 ) == (int) 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 ( CORBA::ULong 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 ( CORBA::ULong 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)
862 list< int > IdList( seq.begin(), seq.end() );
864 int nbNodesBefore = myMesh->NbNodes();
865 getEditor().Remove( IdList, true );
866 int nbNodesAfter = myMesh->NbNodes();
868 declareMeshModified( /*isReComputeSafe=*/ IdList.size() == 0 ); // issue 0020693
869 return nbNodesBefore - nbNodesAfter;
871 SMESH_CATCH( SMESH::throwCorbaException );
875 //=============================================================================
879 //=============================================================================
881 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,CORBA::Double y, CORBA::Double z)
882 throw (SALOME::SALOME_Exception)
887 const SMDS_MeshNode* N = getMeshDS()->AddNode(x, y, z);
889 // Update Python script
890 TPythonDump() << "nodeID = " << this << ".AddNode( "
891 << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )";
893 declareMeshModified( /*isReComputeSafe=*/false );
896 SMESH_CATCH( SMESH::throwCorbaException );
900 //=============================================================================
902 * Create 0D element on the given node.
904 //=============================================================================
906 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
907 throw (SALOME::SALOME_Exception)
912 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
913 SMDS_MeshElement* elem = getMeshDS()->Add0DElement(aNode);
915 // Update Python script
916 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
918 declareMeshModified( /*isReComputeSafe=*/false );
920 return elem ? elem->GetID() : 0;
922 SMESH_CATCH( SMESH::throwCorbaException );
926 //=============================================================================
928 * Create a ball element on the given node.
930 //=============================================================================
932 CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diameter)
933 throw (SALOME::SALOME_Exception)
938 if ( diameter < std::numeric_limits<double>::min() )
939 THROW_SALOME_CORBA_EXCEPTION("Invalid diameter", SALOME::BAD_PARAM);
941 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
942 SMDS_MeshElement* elem = getMeshDS()->AddBall(aNode, diameter);
944 // Update Python script
945 TPythonDump() << "ballElem = "
946 << this << ".AddBall( " << IDOfNode << ", " << diameter <<" )";
948 declareMeshModified( /*isReComputeSafe=*/false );
949 return elem ? elem->GetID() : 0;
951 SMESH_CATCH( SMESH::throwCorbaException );
955 //=============================================================================
957 * Create an edge, either linear and quadratic (this is determed
958 * by number of given nodes, two or three)
960 //=============================================================================
962 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
963 throw (SALOME::SALOME_Exception)
968 int NbNodes = IDsOfNodes.length();
969 SMDS_MeshElement* elem = 0;
972 CORBA::Long index1 = IDsOfNodes[0];
973 CORBA::Long index2 = IDsOfNodes[1];
974 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(index1),
975 getMeshDS()->FindNode(index2));
977 // Update Python script
978 TPythonDump() << "edge = " << this << ".AddEdge([ "
979 << index1 << ", " << index2 <<" ])";
982 CORBA::Long n1 = IDsOfNodes[0];
983 CORBA::Long n2 = IDsOfNodes[1];
984 CORBA::Long n12 = IDsOfNodes[2];
985 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(n1),
986 getMeshDS()->FindNode(n2),
987 getMeshDS()->FindNode(n12));
988 // Update Python script
989 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
990 <<n1<<", "<<n2<<", "<<n12<<" ])";
993 declareMeshModified( /*isReComputeSafe=*/false );
994 return elem ? elem->GetID() : 0;
996 SMESH_CATCH( SMESH::throwCorbaException );
1000 //=============================================================================
1004 //=============================================================================
1006 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
1007 throw (SALOME::SALOME_Exception)
1012 int NbNodes = IDsOfNodes.length();
1018 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1019 for (int i = 0; i < NbNodes; i++)
1020 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1022 SMDS_MeshElement* elem = 0;
1024 case 3: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]); break;
1025 case 4: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]); break;
1026 case 6: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1027 nodes[4], nodes[5]); break;
1028 case 7: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1029 nodes[4], nodes[5], nodes[6]); break;
1030 case 8: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1031 nodes[4], nodes[5], nodes[6], nodes[7]); break;
1032 case 9: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1033 nodes[4], nodes[5], nodes[6], nodes[7],
1035 default: elem = getMeshDS()->AddPolygonalFace(nodes);
1038 // Update Python script
1039 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
1041 declareMeshModified( /*isReComputeSafe=*/false );
1043 return elem ? elem->GetID() : 0;
1045 SMESH_CATCH( SMESH::throwCorbaException );
1049 //=============================================================================
1053 //=============================================================================
1055 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
1056 throw (SALOME::SALOME_Exception)
1061 int NbNodes = IDsOfNodes.length();
1062 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1063 for (int i = 0; i < NbNodes; i++)
1064 if ( ! ( nodes[i] = getMeshDS()->FindNode( IDsOfNodes[i] )))
1067 const SMDS_MeshElement* elem = getMeshDS()->AddPolygonalFace(nodes);
1069 // Update Python script
1070 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
1072 declareMeshModified( /*isReComputeSafe=*/false );
1073 return elem ? elem->GetID() : 0;
1075 SMESH_CATCH( SMESH::throwCorbaException );
1079 //=============================================================================
1081 * AddQuadPolygonalFace
1083 //=============================================================================
1085 CORBA::Long SMESH_MeshEditor_i::AddQuadPolygonalFace (const SMESH::long_array & IDsOfNodes)
1086 throw (SALOME::SALOME_Exception)
1091 int NbNodes = IDsOfNodes.length();
1092 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1093 for (int i = 0; i < NbNodes; i++)
1094 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1096 const SMDS_MeshElement* elem = getMeshDS()->AddQuadPolygonalFace(nodes);
1098 // Update Python script
1099 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
1101 declareMeshModified( /*isReComputeSafe=*/false );
1102 return elem ? elem->GetID() : 0;
1104 SMESH_CATCH( SMESH::throwCorbaException );
1108 //=============================================================================
1110 * Create volume, either linear and quadratic (this is determed
1111 * by number of given nodes)
1113 //=============================================================================
1115 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
1116 throw (SALOME::SALOME_Exception)
1121 int NbNodes = IDsOfNodes.length();
1122 vector< const SMDS_MeshNode*> n(NbNodes);
1123 for(int i=0;i<NbNodes;i++)
1124 n[i]= getMeshDS()->FindNode(IDsOfNodes[i]);
1126 SMDS_MeshElement* elem = 0;
1129 case 4 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
1130 case 5 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
1131 case 6 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
1132 case 8 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
1133 case 10:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1134 n[6],n[7],n[8],n[9]);
1136 case 12:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1137 n[6],n[7],n[8],n[9],n[10],n[11]);
1139 case 13:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
1140 n[7],n[8],n[9],n[10],n[11],n[12]);
1142 case 15:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
1143 n[9],n[10],n[11],n[12],n[13],n[14]);
1145 case 20:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1146 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1147 n[15],n[16],n[17],n[18],n[19]);
1149 case 27:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1150 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1151 n[15],n[16],n[17],n[18],n[19],
1152 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
1156 // Update Python script
1157 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
1159 declareMeshModified( /*isReComputeSafe=*/false );
1160 return elem ? elem->GetID() : 0;
1162 SMESH_CATCH( SMESH::throwCorbaException );
1166 //=============================================================================
1168 * AddPolyhedralVolume
1170 //=============================================================================
1171 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
1172 const SMESH::long_array & Quantities)
1173 throw (SALOME::SALOME_Exception)
1178 int NbNodes = IDsOfNodes.length();
1179 std::vector<const SMDS_MeshNode*> n (NbNodes);
1180 for (int i = 0; i < NbNodes; i++)
1182 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDsOfNodes[i]);
1183 if (!aNode) return 0;
1187 int NbFaces = Quantities.length();
1188 std::vector<int> q (NbFaces);
1189 for (int j = 0; j < NbFaces; j++)
1190 q[j] = Quantities[j];
1192 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(n, q);
1194 // Update Python script
1195 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
1196 << IDsOfNodes << ", " << Quantities << " )";
1198 declareMeshModified( /*isReComputeSafe=*/false );
1199 return elem ? elem->GetID() : 0;
1201 SMESH_CATCH( SMESH::throwCorbaException );
1205 //=============================================================================
1207 * AddPolyhedralVolumeByFaces
1209 //=============================================================================
1211 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
1212 throw (SALOME::SALOME_Exception)
1217 int NbFaces = IdsOfFaces.length();
1218 std::vector<const SMDS_MeshNode*> poly_nodes;
1219 std::vector<int> quantities (NbFaces);
1221 for (int i = 0; i < NbFaces; i++) {
1222 const SMDS_MeshElement* aFace = getMeshDS()->FindElement(IdsOfFaces[i]);
1223 quantities[i] = aFace->NbNodes();
1225 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
1226 while (It->more()) {
1227 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
1231 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
1233 // Update Python script
1234 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
1235 << IdsOfFaces << " )";
1237 declareMeshModified( /*isReComputeSafe=*/false );
1238 return elem ? elem->GetID() : 0;
1240 SMESH_CATCH( SMESH::throwCorbaException );
1244 //=============================================================================
1246 // \brief Create 0D elements on all nodes of the given object except those
1247 // nodes on which a 0D element already exists.
1248 // \param theObject object on whose nodes 0D elements will be created.
1249 // \param theGroupName optional name of a group to add 0D elements created
1250 // and/or found on nodes of \a theObject.
1251 // \return an object (a new group or a temporary SMESH_IDSource) holding
1252 // ids of new and/or found 0D elements.
1254 //=============================================================================
1256 SMESH::SMESH_IDSource_ptr
1257 SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObject,
1258 const char* theGroupName)
1259 throw (SALOME::SALOME_Exception)
1264 SMESH::SMESH_IDSource_var result;
1267 TIDSortedElemSet elements, elems0D;
1268 if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
1269 getEditor().Create0DElementsOnAllNodes( elements, elems0D );
1271 SMESH::long_array_var newElems = new SMESH::long_array;
1272 newElems->length( elems0D.size() );
1273 TIDSortedElemSet::iterator eIt = elems0D.begin();
1274 for ( size_t i = 0; i < elems0D.size(); ++i, ++eIt )
1275 newElems[ i ] = (*eIt)->GetID();
1277 SMESH::SMESH_GroupBase_var groupToFill;
1278 if ( theGroupName && strlen( theGroupName ))
1280 // Get existing group named theGroupName
1281 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
1282 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
1283 SMESH::SMESH_GroupBase_var group = groups[i];
1284 if ( !group->_is_nil() ) {
1285 CORBA::String_var name = group->GetName();
1286 if ( strcmp( name.in(), theGroupName ) == 0 && group->GetType() == SMESH::ELEM0D ) {
1287 groupToFill = group;
1292 if ( groupToFill->_is_nil() )
1293 groupToFill = myMesh_i->CreateGroup( SMESH::ELEM0D, theGroupName );
1294 else if ( !SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1295 groupToFill = myMesh_i->ConvertToStandalone( groupToFill );
1298 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1300 group_i->Add( newElems );
1301 result = SMESH::SMESH_IDSource::_narrow( groupToFill );
1302 pyDump << groupToFill;
1306 result = MakeIDSource( newElems, SMESH::ELEM0D );
1307 pyDump << "elem0DIDs";
1310 pyDump << " = " << this << ".Create0DElementsOnAllNodes( "
1311 << theObject << ", '" << theGroupName << "' )";
1313 return result._retn();
1315 SMESH_CATCH( SMESH::throwCorbaException );
1319 //=============================================================================
1321 * \brief Bind a node to a vertex
1322 * \param NodeID - node ID
1323 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1324 * \retval boolean - false if NodeID or VertexID is invalid
1326 //=============================================================================
1328 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
1329 throw (SALOME::SALOME_Exception)
1333 SMESHDS_Mesh * mesh = getMeshDS();
1334 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1336 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1338 if ( mesh->MaxShapeIndex() < VertexID )
1339 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1341 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
1342 if ( shape.ShapeType() != TopAbs_VERTEX )
1343 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1345 mesh->SetNodeOnVertex( node, VertexID );
1347 myMesh->SetIsModified( true );
1349 SMESH_CATCH( SMESH::throwCorbaException );
1352 //=============================================================================
1354 * \brief Store node position on an edge
1355 * \param NodeID - node ID
1356 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
1357 * \param paramOnEdge - parameter on edge where the node is located
1358 * \retval boolean - false if any parameter is invalid
1360 //=============================================================================
1362 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
1363 CORBA::Double paramOnEdge)
1364 throw (SALOME::SALOME_Exception)
1368 SMESHDS_Mesh * mesh = getMeshDS();
1369 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1371 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1373 if ( mesh->MaxShapeIndex() < EdgeID )
1374 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1376 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
1377 if ( shape.ShapeType() != TopAbs_EDGE )
1378 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1381 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
1382 if ( paramOnEdge < f || paramOnEdge > l )
1383 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
1385 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
1387 myMesh->SetIsModified( true );
1389 SMESH_CATCH( SMESH::throwCorbaException );
1392 //=============================================================================
1394 * \brief Store node position on a face
1395 * \param NodeID - node ID
1396 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
1397 * \param u - U parameter on face where the node is located
1398 * \param v - V parameter on face where the node is located
1399 * \retval boolean - false if any parameter is invalid
1401 //=============================================================================
1403 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
1404 CORBA::Double u, CORBA::Double v)
1405 throw (SALOME::SALOME_Exception)
1408 SMESHDS_Mesh * mesh = getMeshDS();
1409 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1411 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1413 if ( mesh->MaxShapeIndex() < FaceID )
1414 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1416 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
1417 if ( shape.ShapeType() != TopAbs_FACE )
1418 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1420 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
1421 bool isOut = ( u < surf.FirstUParameter() ||
1422 u > surf.LastUParameter() ||
1423 v < surf.FirstVParameter() ||
1424 v > surf.LastVParameter() );
1428 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
1429 << " u( " << surf.FirstUParameter()
1430 << "," << surf.LastUParameter()
1431 << ") v( " << surf.FirstVParameter()
1432 << "," << surf.LastVParameter() << ")" );
1434 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
1437 mesh->SetNodeOnFace( node, FaceID, u, v );
1438 myMesh->SetIsModified( true );
1440 SMESH_CATCH( SMESH::throwCorbaException );
1443 //=============================================================================
1445 * \brief Bind a node to a solid
1446 * \param NodeID - node ID
1447 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1448 * \retval boolean - false if NodeID or SolidID is invalid
1450 //=============================================================================
1452 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
1453 throw (SALOME::SALOME_Exception)
1456 SMESHDS_Mesh * mesh = getMeshDS();
1457 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1459 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1461 if ( mesh->MaxShapeIndex() < SolidID )
1462 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1464 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
1465 if ( shape.ShapeType() != TopAbs_SOLID &&
1466 shape.ShapeType() != TopAbs_SHELL)
1467 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1469 mesh->SetNodeInVolume( node, SolidID );
1471 SMESH_CATCH( SMESH::throwCorbaException );
1474 //=============================================================================
1476 * \brief Bind an element to a shape
1477 * \param ElementID - element ID
1478 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
1480 //=============================================================================
1482 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
1483 CORBA::Long ShapeID)
1484 throw (SALOME::SALOME_Exception)
1487 SMESHDS_Mesh * mesh = getMeshDS();
1488 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
1490 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
1492 if ( mesh->MaxShapeIndex() < ShapeID || ShapeID < 1 )
1493 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1495 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1496 if ( shape.ShapeType() != TopAbs_EDGE &&
1497 shape.ShapeType() != TopAbs_FACE &&
1498 shape.ShapeType() != TopAbs_SOLID &&
1499 shape.ShapeType() != TopAbs_SHELL )
1500 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1502 mesh->SetMeshElementOnShape( elem, ShapeID );
1504 myMesh->SetIsModified( true );
1506 SMESH_CATCH( SMESH::throwCorbaException );
1509 //=============================================================================
1513 //=============================================================================
1515 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1516 CORBA::Long NodeID2)
1517 throw (SALOME::SALOME_Exception)
1522 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1523 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1527 // Update Python script
1528 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1529 << NodeID1 << ", " << NodeID2 << " )";
1531 int ret = getEditor().InverseDiag ( n1, n2 );
1533 declareMeshModified( /*isReComputeSafe=*/false );
1536 SMESH_CATCH( SMESH::throwCorbaException );
1540 //=============================================================================
1544 //=============================================================================
1546 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1547 CORBA::Long NodeID2)
1548 throw (SALOME::SALOME_Exception)
1553 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1554 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1558 // Update Python script
1559 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1560 << NodeID1 << ", " << NodeID2 << " )";
1563 bool stat = getEditor().DeleteDiag ( n1, n2 );
1565 declareMeshModified( /*isReComputeSafe=*/!stat );
1569 SMESH_CATCH( SMESH::throwCorbaException );
1573 //=============================================================================
1577 //=============================================================================
1579 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1580 throw (SALOME::SALOME_Exception)
1585 for ( CORBA::ULong i = 0; i < IDsOfElements.length(); i++ )
1587 CORBA::Long index = IDsOfElements[i];
1588 const SMDS_MeshElement * elem = getMeshDS()->FindElement(index);
1590 getEditor().Reorient( elem );
1592 // Update Python script
1593 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1595 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 );
1598 SMESH_CATCH( SMESH::throwCorbaException );
1602 //=============================================================================
1606 //=============================================================================
1608 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1609 throw (SALOME::SALOME_Exception)
1614 TPythonDump aTPythonDump; // suppress dump in Reorient()
1616 prepareIdSource( theObject );
1618 SMESH::long_array_var anElementsId = theObject->GetIDs();
1619 CORBA::Boolean isDone = Reorient(anElementsId);
1621 // Update Python script
1622 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1624 declareMeshModified( /*isReComputeSafe=*/ anElementsId->length() == 0 );
1627 SMESH_CATCH( SMESH::throwCorbaException );
1631 //=======================================================================
1632 //function : Reorient2D
1633 //purpose : Reorient faces contained in \a the2Dgroup.
1634 // the2Dgroup - the mesh or its part to reorient
1635 // theDirection - desired direction of normal of \a theFace
1636 // theFace - ID of face whose orientation is checked.
1637 // It can be < 1 then \a thePoint is used to find a face.
1638 // thePoint - is used to find a face if \a theFace < 1.
1639 // return number of reoriented elements.
1640 //=======================================================================
1642 CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
1643 const SMESH::DirStruct& theDirection,
1644 CORBA::Long theFace,
1645 const SMESH::PointStruct& thePoint)
1646 throw (SALOME::SALOME_Exception)
1649 initData(/*deleteSearchers=*/false);
1651 TIDSortedElemSet elements;
1652 IDSource_Error error;
1653 idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error );
1654 if ( error == IDSource_EMPTY )
1656 if ( error == IDSource_INVALID )
1657 THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
1660 const SMDS_MeshElement* face = 0;
1663 face = getMeshDS()->FindElement( theFace );
1665 THROW_SALOME_CORBA_EXCEPTION("Inexistent face given", SALOME::BAD_PARAM);
1666 if ( face->GetType() != SMDSAbs_Face )
1667 THROW_SALOME_CORBA_EXCEPTION("Wrong element type", SALOME::BAD_PARAM);
1671 // create theElementSearcher if needed
1672 theSearchersDeleter.Set( myMesh, getPartIOR( the2Dgroup, SMESH::FACE ));
1673 if ( !theElementSearcher )
1675 if ( elements.empty() ) // search in the whole mesh
1677 if ( myMesh->NbFaces() == 0 )
1678 THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM);
1680 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
1684 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
1685 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
1687 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt);
1691 gp_Pnt p( thePoint.x, thePoint.y, thePoint.z );
1692 face = theElementSearcher->FindClosestTo( p, SMDSAbs_Face );
1695 THROW_SALOME_CORBA_EXCEPTION("No face found by point", SALOME::INTERNAL_ERROR );
1696 if ( !elements.empty() && !elements.count( face ))
1697 THROW_SALOME_CORBA_EXCEPTION("Found face is not in the group", SALOME::BAD_PARAM );
1700 const SMESH::PointStruct * P = &theDirection.PS;
1701 gp_Vec dirVec( P->x, P->y, P->z );
1702 if ( dirVec.Magnitude() < std::numeric_limits< double >::min() )
1703 THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM);
1705 int nbReori = getEditor().Reorient2D( elements, dirVec, face );
1708 declareMeshModified( /*isReComputeSafe=*/false );
1710 TPythonDump() << this << ".Reorient2D( "
1711 << the2Dgroup << ", "
1712 << theDirection << ", "
1714 << thePoint << " )";
1718 SMESH_CATCH( SMESH::throwCorbaException );
1722 //=======================================================================
1723 //function : Reorient2DBy3D
1724 //purpose : Reorient faces basing on orientation of adjacent volumes.
1725 //=======================================================================
1727 CORBA::Long SMESH_MeshEditor_i::Reorient2DBy3D(const SMESH::ListOfIDSources& faceGroups,
1728 SMESH::SMESH_IDSource_ptr volumeGroup,
1729 CORBA::Boolean outsideNormal)
1730 throw (SALOME::SALOME_Exception)
1735 TIDSortedElemSet volumes;
1736 IDSource_Error volsError;
1737 idSourceToSet( volumeGroup, getMeshDS(), volumes, SMDSAbs_Volume, /*emptyIfMesh=*/1, &volsError);
1740 for ( size_t i = 0; i < faceGroups.length(); ++i )
1742 SMESH::SMESH_IDSource_ptr faceGrp = faceGroups[i].in();
1744 TIDSortedElemSet faces;
1745 IDSource_Error error;
1746 idSourceToSet( faceGrp, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error );
1747 if ( error == IDSource_INVALID && faceGroups.length() == 1 )
1748 THROW_SALOME_CORBA_EXCEPTION("No faces in a given object", SALOME::BAD_PARAM);
1749 if ( error == IDSource_OK && volsError != IDSource_OK )
1750 THROW_SALOME_CORBA_EXCEPTION("No volumes in a given object", SALOME::BAD_PARAM);
1752 nbReori += getEditor().Reorient2DBy3D( faces, volumes, outsideNormal );
1754 if ( error != IDSource_EMPTY && faces.empty() ) // all faces in the mesh treated
1759 declareMeshModified( /*isReComputeSafe=*/false );
1761 TPythonDump() << this << ".Reorient2DBy3D( "
1762 << faceGroups << ", "
1763 << volumeGroup << ", "
1764 << outsideNormal << " )";
1768 SMESH_CATCH( SMESH::throwCorbaException );
1772 //=============================================================================
1774 * \brief Fuse neighbour triangles into quadrangles.
1776 //=============================================================================
1778 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1779 SMESH::NumericalFunctor_ptr Criterion,
1780 CORBA::Double MaxAngle)
1781 throw (SALOME::SALOME_Exception)
1786 SMESHDS_Mesh* aMesh = getMeshDS();
1787 TIDSortedElemSet faces,copyFaces;
1788 SMDS_MeshElement::GeomFilter triaFilter(SMDSGeom_TRIANGLE);
1789 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face, & triaFilter);
1790 TIDSortedElemSet* workElements = & faces;
1792 if ( myIsPreviewMode ) {
1793 SMDSAbs_ElementType select = SMDSAbs_Face;
1794 getPreviewMesh( SMDSAbs_Face )->Copy( faces, copyFaces, select );
1795 workElements = & copyFaces;
1798 SMESH::NumericalFunctor_i* aNumericalFunctor =
1799 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1800 SMESH::Controls::NumericalFunctorPtr aCrit;
1801 if ( !aNumericalFunctor )
1802 aCrit.reset( new SMESH::Controls::MaxElementLength2D() );
1804 aCrit = aNumericalFunctor->GetNumericalFunctor();
1806 if ( !myIsPreviewMode ) {
1807 // Update Python script
1808 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1809 << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1812 bool stat = getEditor().TriToQuad( *workElements, aCrit, MaxAngle );
1814 declareMeshModified( /*isReComputeSafe=*/!stat );
1817 SMESH_CATCH( SMESH::throwCorbaException );
1821 //=============================================================================
1823 * \brief Fuse neighbour triangles into quadrangles.
1825 //=============================================================================
1827 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1828 SMESH::NumericalFunctor_ptr Criterion,
1829 CORBA::Double MaxAngle)
1830 throw (SALOME::SALOME_Exception)
1835 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1837 prepareIdSource( theObject );
1838 SMESH::long_array_var anElementsId = theObject->GetIDs();
1839 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1841 if ( !myIsPreviewMode ) {
1842 SMESH::NumericalFunctor_i* aNumericalFunctor =
1843 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1845 // Update Python script
1846 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1847 << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1852 SMESH_CATCH( SMESH::throwCorbaException );
1856 //=============================================================================
1858 * \brief Split quadrangles into triangles.
1860 //=============================================================================
1862 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1863 SMESH::NumericalFunctor_ptr Criterion)
1864 throw (SALOME::SALOME_Exception)
1869 SMESHDS_Mesh* aMesh = getMeshDS();
1870 TIDSortedElemSet faces;
1871 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1873 SMESH::NumericalFunctor_i* aNumericalFunctor =
1874 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1875 SMESH::Controls::NumericalFunctorPtr aCrit;
1876 if ( !aNumericalFunctor )
1877 aCrit.reset( new SMESH::Controls::AspectRatio() );
1879 aCrit = aNumericalFunctor->GetNumericalFunctor();
1882 // Update Python script
1883 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1885 CORBA::Boolean stat = getEditor().QuadToTri( faces, aCrit );
1887 declareMeshModified( /*isReComputeSafe=*/false );
1890 SMESH_CATCH( SMESH::throwCorbaException );
1894 //=============================================================================
1896 * \brief Split quadrangles into triangles.
1898 //=============================================================================
1900 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1901 SMESH::NumericalFunctor_ptr Criterion)
1902 throw (SALOME::SALOME_Exception)
1907 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1909 prepareIdSource( theObject );
1910 SMESH::long_array_var anElementsId = theObject->GetIDs();
1911 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1913 SMESH::NumericalFunctor_i* aNumericalFunctor =
1914 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1916 // Update Python script
1917 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1919 declareMeshModified( /*isReComputeSafe=*/false );
1922 SMESH_CATCH( SMESH::throwCorbaException );
1926 //================================================================================
1928 * \brief Split each of quadrangles into 4 triangles.
1929 * \param [in] theObject - theQuads Container of quadrangles to split.
1931 //================================================================================
1933 void SMESH_MeshEditor_i::QuadTo4Tri (SMESH::SMESH_IDSource_ptr theObject)
1934 throw (SALOME::SALOME_Exception)
1939 TIDSortedElemSet faces;
1940 if ( !idSourceToSet( theObject, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/true ) &&
1942 THROW_SALOME_CORBA_EXCEPTION("No faces given", SALOME::BAD_PARAM);
1944 getEditor().QuadTo4Tri( faces );
1945 TPythonDump() << this << ".QuadTo4Tri( " << theObject << " )";
1947 SMESH_CATCH( SMESH::throwCorbaException );
1950 //=============================================================================
1952 * \brief Split quadrangles into triangles.
1954 //=============================================================================
1956 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1957 CORBA::Boolean Diag13)
1958 throw (SALOME::SALOME_Exception)
1963 SMESHDS_Mesh* aMesh = getMeshDS();
1964 TIDSortedElemSet faces;
1965 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1967 // Update Python script
1968 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1969 << IDsOfElements << ", " << Diag13 << " )";
1971 CORBA::Boolean stat = getEditor().QuadToTri( faces, Diag13 );
1973 declareMeshModified( /*isReComputeSafe=*/ !stat );
1976 SMESH_CATCH( SMESH::throwCorbaException );
1980 //=============================================================================
1982 * \brief Split quadrangles into triangles.
1984 //=============================================================================
1986 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1987 CORBA::Boolean Diag13)
1988 throw (SALOME::SALOME_Exception)
1993 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
1995 prepareIdSource( theObject );
1996 SMESH::long_array_var anElementsId = theObject->GetIDs();
1997 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
1999 // Update Python script
2000 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
2001 << theObject << ", " << Diag13 << " )";
2003 declareMeshModified( /*isReComputeSafe=*/!isDone );
2006 SMESH_CATCH( SMESH::throwCorbaException );
2011 //=============================================================================
2013 * Find better splitting of the given quadrangle.
2014 * \param IDOfQuad ID of the quadrangle to be splitted.
2015 * \param Criterion A criterion to choose a diagonal for splitting.
2016 * \return 1 if 1-3 diagonal is better, 2 if 2-4
2017 * diagonal is better, 0 if error occurs.
2019 //=============================================================================
2021 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
2022 SMESH::NumericalFunctor_ptr Criterion)
2023 throw (SALOME::SALOME_Exception)
2028 const SMDS_MeshElement* quad = getMeshDS()->FindElement(IDOfQuad);
2029 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
2031 SMESH::NumericalFunctor_i* aNumericalFunctor =
2032 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
2033 SMESH::Controls::NumericalFunctorPtr aCrit;
2034 if (aNumericalFunctor)
2035 aCrit = aNumericalFunctor->GetNumericalFunctor();
2037 aCrit.reset(new SMESH::Controls::AspectRatio());
2039 int id = getEditor().BestSplit(quad, aCrit);
2040 declareMeshModified( /*isReComputeSafe=*/ id < 1 );
2044 SMESH_CATCH( SMESH::throwCorbaException );
2048 //================================================================================
2050 * \brief Split volumic elements into tetrahedrons
2052 //================================================================================
2054 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
2055 CORBA::Short methodFlags)
2056 throw (SALOME::SALOME_Exception)
2061 ::SMESH_MeshEditor::TFacetOfElem elemSet;
2062 const int noneFacet = -1;
2063 SMDS_ElemIteratorPtr volIt = myMesh_i->GetElements( elems, SMESH::VOLUME );
2064 while( volIt->more() )
2065 elemSet.insert( elemSet.end(), make_pair( volIt->next(), noneFacet ));
2067 getEditor().SplitVolumes( elemSet, int( methodFlags ));
2068 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2070 TPythonDump() << this << ".SplitVolumesIntoTetra( "
2071 << elems << ", " << methodFlags << " )";
2073 SMESH_CATCH( SMESH::throwCorbaException );
2076 //================================================================================
2078 * \brief Split hexahedra into triangular prisms
2079 * \param elems - elements to split
2080 * \param facetToSplitNormal - normal used to find a facet of hexahedron
2081 * to split into triangles
2082 * \param methodFlags - flags passing splitting method:
2083 * 1 - split the hexahedron into 2 prisms
2084 * 2 - split the hexahedron into 4 prisms
2086 //================================================================================
2088 void SMESH_MeshEditor_i::SplitHexahedraIntoPrisms( SMESH::SMESH_IDSource_ptr elems,
2089 const SMESH::PointStruct & startHexPoint,
2090 const SMESH::DirStruct& facetToSplitNormal,
2091 CORBA::Short methodFlags,
2092 CORBA::Boolean allDomains)
2093 throw (SALOME::SALOME_Exception)
2097 prepareIdSource( elems );
2099 gp_Ax1 facetNorm( gp_Pnt( startHexPoint.x,
2102 gp_Dir( facetToSplitNormal.PS.x,
2103 facetToSplitNormal.PS.y,
2104 facetToSplitNormal.PS.z ));
2105 TIDSortedElemSet elemSet;
2106 SMESH::long_array_var anElementsId = elems->GetIDs();
2107 SMDS_MeshElement::GeomFilter filter( SMDSGeom_HEXA );
2108 arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume, &filter );
2110 ::SMESH_MeshEditor::TFacetOfElem elemFacets;
2111 while ( !elemSet.empty() )
2113 getEditor().GetHexaFacetsToSplit( elemSet, facetNorm, elemFacets );
2117 ::SMESH_MeshEditor::TFacetOfElem::iterator ef = elemFacets.begin();
2118 for ( ; ef != elemFacets.end(); ++ef )
2119 elemSet.erase( ef->first );
2122 if ( methodFlags == 2 )
2123 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_4_PRISMS );
2125 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_2_PRISMS );
2127 getEditor().SplitVolumes( elemFacets, int( methodFlags ));
2128 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2130 TPythonDump() << this << ".SplitHexahedraIntoPrisms( "
2132 << startHexPoint << ", "
2133 << facetToSplitNormal<< ", "
2134 << methodFlags<< ", "
2135 << allDomains << " )";
2137 SMESH_CATCH( SMESH::throwCorbaException );
2140 //================================================================================
2142 * \brief Split bi-quadratic elements into linear ones without creation of additional nodes:
2143 * - bi-quadratic triangle will be split into 3 linear quadrangles;
2144 * - bi-quadratic quadrangle will be split into 4 linear quadrangles;
2145 * - tri-quadratic hexahedron will be split into 8 linear hexahedra.
2146 * Quadratic elements of lower dimension adjacent to the split bi-quadratic element
2147 * will be split in order to keep the mesh conformal.
2148 * \param elems - elements to split
2150 //================================================================================
2152 void SMESH_MeshEditor_i::SplitBiQuadraticIntoLinear(const SMESH::ListOfIDSources& theElems)
2153 throw (SALOME::SALOME_Exception)
2158 TIDSortedElemSet elemSet;
2159 for ( size_t i = 0; i < theElems.length(); ++i )
2161 SMESH::SMESH_IDSource_ptr elems = theElems[i].in();
2162 SMESH::SMESH_Mesh_var mesh = elems->GetMesh();
2163 if ( mesh->GetId() != myMesh_i->GetId() )
2164 THROW_SALOME_CORBA_EXCEPTION("Wrong mesh of IDSource", SALOME::BAD_PARAM);
2166 idSourceToSet( elems, getMeshDS(), elemSet, SMDSAbs_All );
2168 getEditor().SplitBiQuadraticIntoLinear( elemSet );
2170 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2172 TPythonDump() << this << ".SplitBiQuadraticIntoLinear( "
2173 << theElems << " )";
2175 SMESH_CATCH( SMESH::throwCorbaException );
2178 //=======================================================================
2181 //=======================================================================
2184 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
2185 const SMESH::long_array & IDsOfFixedNodes,
2186 CORBA::Long MaxNbOfIterations,
2187 CORBA::Double MaxAspectRatio,
2188 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2189 throw (SALOME::SALOME_Exception)
2191 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2192 MaxAspectRatio, Method, false );
2196 //=======================================================================
2197 //function : SmoothParametric
2199 //=======================================================================
2202 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
2203 const SMESH::long_array & IDsOfFixedNodes,
2204 CORBA::Long MaxNbOfIterations,
2205 CORBA::Double MaxAspectRatio,
2206 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2207 throw (SALOME::SALOME_Exception)
2209 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2210 MaxAspectRatio, Method, true );
2214 //=======================================================================
2215 //function : SmoothObject
2217 //=======================================================================
2220 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
2221 const SMESH::long_array & IDsOfFixedNodes,
2222 CORBA::Long MaxNbOfIterations,
2223 CORBA::Double MaxAspectRatio,
2224 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2225 throw (SALOME::SALOME_Exception)
2227 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2228 MaxAspectRatio, Method, false);
2232 //=======================================================================
2233 //function : SmoothParametricObject
2235 //=======================================================================
2238 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
2239 const SMESH::long_array & IDsOfFixedNodes,
2240 CORBA::Long MaxNbOfIterations,
2241 CORBA::Double MaxAspectRatio,
2242 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2243 throw (SALOME::SALOME_Exception)
2245 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2246 MaxAspectRatio, Method, true);
2250 //=============================================================================
2254 //=============================================================================
2257 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
2258 const SMESH::long_array & IDsOfFixedNodes,
2259 CORBA::Long MaxNbOfIterations,
2260 CORBA::Double MaxAspectRatio,
2261 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2263 throw (SALOME::SALOME_Exception)
2268 SMESHDS_Mesh* aMesh = getMeshDS();
2270 TIDSortedElemSet elements;
2271 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
2273 set<const SMDS_MeshNode*> fixedNodes;
2274 for ( CORBA::ULong i = 0; i < IDsOfFixedNodes.length(); i++) {
2275 CORBA::Long index = IDsOfFixedNodes[i];
2276 const SMDS_MeshNode * node = aMesh->FindNode(index);
2278 fixedNodes.insert( node );
2280 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
2281 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
2282 method = ::SMESH_MeshEditor::CENTROIDAL;
2284 getEditor().Smooth(elements, fixedNodes, method,
2285 MaxNbOfIterations, MaxAspectRatio, IsParametric );
2287 declareMeshModified( /*isReComputeSafe=*/true ); // does not prevent re-compute
2289 // Update Python script
2290 TPythonDump() << "isDone = " << this << "."
2291 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
2292 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
2293 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2294 << "SMESH.SMESH_MeshEditor."
2295 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2296 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2300 SMESH_CATCH( SMESH::throwCorbaException );
2304 //=============================================================================
2308 //=============================================================================
2311 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
2312 const SMESH::long_array & IDsOfFixedNodes,
2313 CORBA::Long MaxNbOfIterations,
2314 CORBA::Double MaxAspectRatio,
2315 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2317 throw (SALOME::SALOME_Exception)
2322 TPythonDump aTPythonDump; // suppress dump in smooth()
2324 prepareIdSource( theObject );
2325 SMESH::long_array_var anElementsId = theObject->GetIDs();
2326 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
2327 MaxAspectRatio, Method, IsParametric);
2329 // Update Python script
2330 aTPythonDump << "isDone = " << this << "."
2331 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
2332 << theObject << ", " << IDsOfFixedNodes << ", "
2333 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2334 << "SMESH.SMESH_MeshEditor."
2335 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2336 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2340 SMESH_CATCH( SMESH::throwCorbaException );
2344 //=============================================================================
2348 //=============================================================================
2350 void SMESH_MeshEditor_i::RenumberNodes()
2351 throw (SALOME::SALOME_Exception)
2354 // Update Python script
2355 TPythonDump() << this << ".RenumberNodes()";
2357 getMeshDS()->Renumber( true );
2359 SMESH_CATCH( SMESH::throwCorbaException );
2362 //=============================================================================
2366 //=============================================================================
2368 void SMESH_MeshEditor_i::RenumberElements()
2369 throw (SALOME::SALOME_Exception)
2372 // Update Python script
2373 TPythonDump() << this << ".RenumberElements()";
2375 getMeshDS()->Renumber( false );
2377 SMESH_CATCH( SMESH::throwCorbaException );
2380 //=======================================================================
2382 * \brief Return groups by their IDs
2384 //=======================================================================
2386 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
2387 throw (SALOME::SALOME_Exception)
2392 myMesh_i->CreateGroupServants();
2393 return myMesh_i->GetGroups( *groupIDs );
2395 SMESH_CATCH( SMESH::throwCorbaException );
2399 //=======================================================================
2400 //function : RotationSweepObjects
2402 //=======================================================================
2404 SMESH::ListOfGroups*
2405 SMESH_MeshEditor_i::RotationSweepObjects(const SMESH::ListOfIDSources & theNodes,
2406 const SMESH::ListOfIDSources & theEdges,
2407 const SMESH::ListOfIDSources & theFaces,
2408 const SMESH::AxisStruct & theAxis,
2409 CORBA::Double theAngleInRadians,
2410 CORBA::Long theNbOfSteps,
2411 CORBA::Double theTolerance,
2412 const bool theMakeGroups)
2413 throw (SALOME::SALOME_Exception)
2418 TIDSortedElemSet elemsNodes[2];
2419 for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) {
2420 SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE );
2421 while ( nIt->more() ) elemsNodes[1].insert( nIt->next() );
2423 for ( int i = 0, nb = theEdges.length(); i < nb; ++i )
2424 idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge );
2425 for ( int i = 0, nb = theFaces.length(); i < nb; ++i )
2426 idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face );
2428 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2429 bool makeWalls=true;
2430 if ( myIsPreviewMode )
2432 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2433 TPreviewMesh * tmpMesh = getPreviewMesh();
2434 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2435 tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid );
2436 workElements = & copyElements[0];
2437 //makeWalls = false; -- faces are needed for preview
2440 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2442 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
2443 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
2445 ::SMESH_MeshEditor::PGroupIDs groupIds =
2446 getEditor().RotationSweep (workElements, Ax1, theAngleInRadians,
2447 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
2449 SMESH::ListOfGroups * aGroups = theMakeGroups ? getGroups( groupIds.get()) : 0;
2451 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2453 if ( !myIsPreviewMode )
2455 dumpGroupsList( aPythonDump, aGroups );
2456 aPythonDump << this<< ".RotationSweepObjects( "
2461 << TVar( theAngleInRadians ) << ", "
2462 << TVar( theNbOfSteps ) << ", "
2463 << TVar( theTolerance ) << ", "
2464 << theMakeGroups << " )";
2468 getPreviewMesh()->Remove( SMDSAbs_Volume );
2471 return aGroups ? aGroups : new SMESH::ListOfGroups;
2473 SMESH_CATCH( SMESH::throwCorbaException );
2477 namespace MeshEditor_I
2480 * \brief Structure used to pass extrusion parameters to ::SMESH_MeshEditor
2482 struct ExtrusionParams : public ::SMESH_MeshEditor::ExtrusParam
2484 bool myIsExtrusionByNormal;
2486 static int makeFlags( CORBA::Boolean MakeGroups,
2487 CORBA::Boolean ByAverageNormal = false,
2488 CORBA::Boolean UseInputElemsOnly = false,
2489 CORBA::Long Flags = 0,
2490 CORBA::Boolean MakeBoundary = true )
2492 if ( MakeGroups ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS;
2493 if ( ByAverageNormal ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BY_AVG_NORMAL;
2494 if ( UseInputElemsOnly) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY;
2495 if ( MakeBoundary ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BOUNDARY;
2499 ExtrusionParams(const SMESH::DirStruct & theDir,
2500 CORBA::Long theNbOfSteps,
2501 CORBA::Boolean theMakeGroups):
2502 ::SMESH_MeshEditor::ExtrusParam ( gp_Vec( theDir.PS.x,
2506 makeFlags( theMakeGroups )),
2507 myIsExtrusionByNormal( false )
2511 ExtrusionParams(const SMESH::DirStruct & theDir,
2512 CORBA::Long theNbOfSteps,
2513 CORBA::Boolean theMakeGroups,
2514 CORBA::Long theExtrFlags,
2515 CORBA::Double theSewTolerance):
2516 ::SMESH_MeshEditor::ExtrusParam ( gp_Vec( theDir.PS.x,
2520 makeFlags( theMakeGroups, false, false,
2521 theExtrFlags, false ),
2523 myIsExtrusionByNormal( false )
2526 // params for extrusion by normal
2527 ExtrusionParams(CORBA::Double theStepSize,
2528 CORBA::Long theNbOfSteps,
2529 CORBA::Short theDim,
2530 CORBA::Boolean theByAverageNormal,
2531 CORBA::Boolean theUseInputElemsOnly,
2532 CORBA::Boolean theMakeGroups ):
2533 ::SMESH_MeshEditor::ExtrusParam ( theStepSize,
2535 makeFlags( theMakeGroups,
2536 theByAverageNormal, theUseInputElemsOnly ),
2538 myIsExtrusionByNormal( true )
2544 Flags() &= ~(::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS);
2549 //=======================================================================
2551 * \brief Generate dim+1 elements by extrusion of elements along vector
2552 * \param [in] edges - edges to extrude: a list including groups, sub-meshes or a mesh
2553 * \param [in] faces - faces to extrude: a list including groups, sub-meshes or a mesh
2554 * \param [in] nodes - nodes to extrude: a list including groups, sub-meshes or a mesh
2555 * \param [in] stepVector - vector giving direction and distance of an extrusion step
2556 * \param [in] nbOfSteps - number of elements to generate from one element
2557 * \param [in] toMakeGroups - if true, new elements will be included into new groups
2558 * corresponding to groups the input elements included in.
2559 * \return ListOfGroups - new groups craeted if \a toMakeGroups is true
2561 //=======================================================================
2563 SMESH::ListOfGroups*
2564 SMESH_MeshEditor_i::ExtrusionSweepObjects(const SMESH::ListOfIDSources & theNodes,
2565 const SMESH::ListOfIDSources & theEdges,
2566 const SMESH::ListOfIDSources & theFaces,
2567 const SMESH::DirStruct & theStepVector,
2568 CORBA::Long theNbOfSteps,
2569 CORBA::Boolean theToMakeGroups)
2570 throw (SALOME::SALOME_Exception)
2575 ExtrusionParams params( theStepVector, theNbOfSteps, theToMakeGroups );
2577 TIDSortedElemSet elemsNodes[2];
2578 for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) {
2579 SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE );
2580 while ( nIt->more() ) elemsNodes[1].insert( nIt->next() );
2582 for ( int i = 0, nb = theEdges.length(); i < nb; ++i )
2583 idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge );
2584 for ( int i = 0, nb = theFaces.length(); i < nb; ++i )
2585 idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face );
2587 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2588 SMDSAbs_ElementType previewType = SMDSAbs_All; //SMDSAbs_Face;
2589 if ( myIsPreviewMode )
2591 // if ( (*elemsNodes.begin())->GetType() == SMDSAbs_Node )
2592 // previewType = SMDSAbs_Edge;
2594 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2595 TPreviewMesh * tmpMesh = getPreviewMesh( previewType );
2596 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2597 tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid );
2598 workElements = & copyElements[0];
2600 params.SetNoGroups();
2602 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2604 ::SMESH_MeshEditor::TTElemOfElemListMap aHistory;
2605 ::SMESH_MeshEditor::PGroupIDs groupIds =
2606 getEditor().ExtrusionSweep( workElements, params, aHistory );
2608 SMESH::ListOfGroups * aGroups = theToMakeGroups ? getGroups( groupIds.get()) : 0;
2610 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2612 if ( !myIsPreviewMode )
2614 dumpGroupsList( aPythonDump, aGroups );
2615 aPythonDump << this<< ".ExtrusionSweepObjects( "
2619 << theStepVector << ", "
2620 << TVar( theNbOfSteps ) << ", "
2621 << theToMakeGroups << " )";
2625 getPreviewMesh( previewType )->Remove( SMDSAbs_Volume );
2628 return aGroups ? aGroups : new SMESH::ListOfGroups;
2630 SMESH_CATCH( SMESH::throwCorbaException );
2634 //=======================================================================
2635 //function : ExtrusionByNormal
2637 //=======================================================================
2639 SMESH::ListOfGroups*
2640 SMESH_MeshEditor_i::ExtrusionByNormal(const SMESH::ListOfIDSources& objects,
2641 CORBA::Double stepSize,
2642 CORBA::Long nbOfSteps,
2643 CORBA::Boolean byAverageNormal,
2644 CORBA::Boolean useInputElemsOnly,
2645 CORBA::Boolean makeGroups,
2647 throw (SALOME::SALOME_Exception)
2652 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2654 ExtrusionParams params( stepSize, nbOfSteps, dim,
2655 byAverageNormal, useInputElemsOnly, makeGroups );
2657 SMDSAbs_ElementType elemType = ( dim == 1 ? SMDSAbs_Edge : SMDSAbs_Face );
2658 if ( objects.length() > 0 && !SMESH::DownCast<SMESH_Mesh_i*>( objects[0] ))
2660 SMESH::array_of_ElementType_var elemTypes = objects[0]->GetTypes();
2661 if (( elemTypes->length() == 1 ) &&
2662 ( elemTypes[0] == SMESH::EDGE || elemTypes[0] == SMESH::FACE ))
2663 elemType = ( SMDSAbs_ElementType ) elemTypes[0];
2666 TIDSortedElemSet elemsNodes[2];
2667 for ( int i = 0, nb = objects.length(); i < nb; ++i )
2668 idSourceToSet( objects[i], getMeshDS(), elemsNodes[0], elemType );
2670 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2671 SMDSAbs_ElementType previewType = SMDSAbs_Face;
2672 if ( myIsPreviewMode )
2674 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2675 TPreviewMesh * tmpMesh = getPreviewMesh( previewType );
2676 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2677 workElements = & copyElements[0];
2679 params.SetNoGroups();
2682 ::SMESH_MeshEditor::TTElemOfElemListMap aHistory;
2683 ::SMESH_MeshEditor::PGroupIDs groupIds =
2684 getEditor().ExtrusionSweep( workElements, params, aHistory );
2686 SMESH::ListOfGroups * aGroups = makeGroups ? getGroups( groupIds.get()) : 0;
2688 if (!myIsPreviewMode) {
2689 dumpGroupsList(aPythonDump, aGroups);
2690 aPythonDump << this << ".ExtrusionByNormal( " << objects
2691 << ", " << TVar( stepSize )
2692 << ", " << TVar( nbOfSteps )
2693 << ", " << byAverageNormal
2694 << ", " << useInputElemsOnly
2695 << ", " << makeGroups
2701 getPreviewMesh( previewType )->Remove( SMDSAbs_Volume );
2704 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2706 return aGroups ? aGroups : new SMESH::ListOfGroups;
2708 SMESH_CATCH( SMESH::throwCorbaException );
2712 //=======================================================================
2713 //function : AdvancedExtrusion
2715 //=======================================================================
2717 SMESH::ListOfGroups*
2718 SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2719 const SMESH::DirStruct & theStepVector,
2720 CORBA::Long theNbOfSteps,
2721 CORBA::Long theExtrFlags,
2722 CORBA::Double theSewTolerance,
2723 CORBA::Boolean theMakeGroups)
2724 throw (SALOME::SALOME_Exception)
2729 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2731 ExtrusionParams params( theStepVector, theNbOfSteps, theMakeGroups,
2732 theExtrFlags, theSewTolerance );
2734 TIDSortedElemSet elemsNodes[2];
2735 arrayToSet( theIDsOfElements, getMeshDS(), elemsNodes[0] );
2737 ::SMESH_MeshEditor::TTElemOfElemListMap aHistory;
2738 ::SMESH_MeshEditor::PGroupIDs groupIds =
2739 getEditor().ExtrusionSweep( elemsNodes, params, aHistory );
2741 SMESH::ListOfGroups * aGroups = theMakeGroups ? getGroups( groupIds.get()) : 0;
2743 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2745 if ( !myIsPreviewMode ) {
2746 dumpGroupsList(aPythonDump, aGroups);
2747 aPythonDump << this << ".AdvancedExtrusion( "
2748 << theIDsOfElements << ", "
2749 << theStepVector << ", "
2750 << theNbOfSteps << ", "
2751 << theExtrFlags << ", "
2752 << theSewTolerance << ", "
2753 << theMakeGroups << " )";
2757 getPreviewMesh()->Remove( SMDSAbs_Volume );
2760 return aGroups ? aGroups : new SMESH::ListOfGroups;
2762 SMESH_CATCH( SMESH::throwCorbaException );
2766 //================================================================================
2768 * \brief Convert extrusion error to IDL enum
2770 //================================================================================
2774 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
2776 SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( ::SMESH_MeshEditor::Extrusion_Error e )
2780 RETCASE( EXTR_NO_ELEMENTS );
2781 RETCASE( EXTR_PATH_NOT_EDGE );
2782 RETCASE( EXTR_BAD_PATH_SHAPE );
2783 RETCASE( EXTR_BAD_STARTING_NODE );
2784 RETCASE( EXTR_BAD_ANGLES_NUMBER );
2785 RETCASE( EXTR_CANT_GET_TANGENT );
2787 return SMESH::SMESH_MeshEditor::EXTR_OK;
2791 //=======================================================================
2792 //function : extrusionAlongPath
2794 //=======================================================================
2795 SMESH::ListOfGroups*
2796 SMESH_MeshEditor_i::ExtrusionAlongPathObjects(const SMESH::ListOfIDSources & theNodes,
2797 const SMESH::ListOfIDSources & theEdges,
2798 const SMESH::ListOfIDSources & theFaces,
2799 SMESH::SMESH_IDSource_ptr thePathMesh,
2800 GEOM::GEOM_Object_ptr thePathShape,
2801 CORBA::Long theNodeStart,
2802 CORBA::Boolean theHasAngles,
2803 const SMESH::double_array & theAngles,
2804 CORBA::Boolean theLinearVariation,
2805 CORBA::Boolean theHasRefPoint,
2806 const SMESH::PointStruct & theRefPoint,
2808 SMESH::SMESH_MeshEditor::Extrusion_Error& theError)
2809 throw (SALOME::SALOME_Exception)
2814 SMESH::ListOfGroups_var aGroups = new SMESH::ListOfGroups;
2816 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2817 if ( thePathMesh->_is_nil() )
2818 return aGroups._retn();
2821 SMESH_subMesh* aSubMesh = 0;
2822 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2823 if ( thePathShape->_is_nil() )
2825 // thePathMesh should be either a sub-mesh or a mesh with 1D elements only
2826 if ( SMESH_subMesh_i* sm = SMESH::DownCast<SMESH_subMesh_i*>( thePathMesh ))
2828 SMESH::SMESH_Mesh_var mesh = thePathMesh->GetMesh();
2829 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
2830 if ( !aMeshImp ) return aGroups._retn();
2831 aSubMesh = aMeshImp->GetImpl().GetSubMeshContaining( sm->GetId() );
2832 if ( !aSubMesh ) return aGroups._retn();
2834 else if ( !aMeshImp ||
2835 aMeshImp->NbEdges() != aMeshImp->NbElements() )
2837 return aGroups._retn();
2842 if ( !aMeshImp ) return aGroups._retn();
2843 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2844 aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2845 if ( !aSubMesh /*|| !aSubMesh->GetSubMeshDS()*/ )
2846 return aGroups._retn();
2849 SMDS_MeshNode* nodeStart =
2850 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
2852 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2853 return aGroups._retn();
2856 TIDSortedElemSet elemsNodes[2];
2857 for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) {
2858 SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE );
2859 while ( nIt->more() ) elemsNodes[1].insert( nIt->next() );
2861 for ( int i = 0, nb = theEdges.length(); i < nb; ++i )
2862 idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge );
2863 for ( int i = 0, nb = theFaces.length(); i < nb; ++i )
2864 idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face );
2866 list<double> angles;
2867 for ( CORBA::ULong i = 0; i < theAngles.length(); i++ ) {
2868 angles.push_back( theAngles[i] );
2871 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
2873 int nbOldGroups = myMesh->NbGroup();
2875 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2876 if ( myIsPreviewMode )
2878 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2879 TPreviewMesh * tmpMesh = getPreviewMesh();
2880 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2881 tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid );
2882 workElements = & copyElements[0];
2883 theMakeGroups = false;
2886 ::SMESH_MeshEditor::Extrusion_Error error;
2888 error = getEditor().ExtrusionAlongTrack( workElements, &(aMeshImp->GetImpl()), nodeStart,
2889 theHasAngles, angles, theLinearVariation,
2890 theHasRefPoint, refPnt, theMakeGroups );
2892 error = getEditor().ExtrusionAlongTrack( workElements, aSubMesh, nodeStart,
2893 theHasAngles, angles, theLinearVariation,
2894 theHasRefPoint, refPnt, theMakeGroups );
2896 declareMeshModified( /*isReComputeSafe=*/true );
2897 theError = convExtrError( error );
2899 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2900 if ( theMakeGroups ) {
2901 list<int> groupIDs = myMesh->GetGroupIds();
2902 list<int>::iterator newBegin = groupIDs.begin();
2903 std::advance( newBegin, nbOldGroups ); // skip old groups
2904 groupIDs.erase( groupIDs.begin(), newBegin );
2905 aGroups = getGroups( & groupIDs );
2906 if ( ! &aGroups.in() ) aGroups = new SMESH::ListOfGroups;
2909 if ( !myIsPreviewMode ) {
2910 aPythonDump << "(" << aGroups << ", error) = "
2911 << this << ".ExtrusionAlongPathObjects( "
2915 << thePathMesh << ", "
2916 << thePathShape << ", "
2917 << theNodeStart << ", "
2918 << theHasAngles << ", "
2919 << theAngles << ", "
2920 << theLinearVariation << ", "
2921 << theHasRefPoint << ", "
2922 << "SMESH.PointStruct( "
2923 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2924 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2925 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ), "
2926 << theMakeGroups << " )";
2930 getPreviewMesh()->Remove( SMDSAbs_Volume );
2933 return aGroups._retn();
2935 SMESH_CATCH( SMESH::throwCorbaException );
2939 //================================================================================
2941 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
2942 * of given angles along path steps
2943 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
2944 * which proceeds the extrusion
2945 * \param PathShape is shape(edge); as the mesh can be complex, the edge
2946 * is used to define the sub-mesh for the path
2948 //================================================================================
2950 SMESH::double_array*
2951 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
2952 GEOM::GEOM_Object_ptr thePathShape,
2953 const SMESH::double_array & theAngles)
2955 SMESH::double_array_var aResult = new SMESH::double_array();
2956 int nbAngles = theAngles.length();
2957 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
2959 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2960 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2961 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2962 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
2963 return aResult._retn();
2964 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
2965 if ( nbSteps == nbAngles )
2967 aResult.inout() = theAngles;
2971 aResult->length( nbSteps );
2972 double rAn2St = double( nbAngles ) / double( nbSteps );
2973 double angPrev = 0, angle;
2974 for ( int iSt = 0; iSt < nbSteps; ++iSt )
2976 double angCur = rAn2St * ( iSt+1 );
2977 double angCurFloor = floor( angCur );
2978 double angPrevFloor = floor( angPrev );
2979 if ( angPrevFloor == angCurFloor )
2980 angle = rAn2St * theAngles[ int( angCurFloor ) ];
2983 int iP = int( angPrevFloor );
2984 double angPrevCeil = ceil(angPrev);
2985 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
2987 int iC = int( angCurFloor );
2988 if ( iC < nbAngles )
2989 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
2991 iP = int( angPrevCeil );
2993 angle += theAngles[ iC ];
2995 aResult[ iSt ] = angle;
3000 // Update Python script
3001 TPythonDump() << "rotAngles = " << theAngles;
3002 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
3003 << thePathMesh << ", "
3004 << thePathShape << ", "
3007 return aResult._retn();
3010 //=======================================================================
3013 //=======================================================================
3015 SMESH::ListOfGroups*
3016 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
3017 const SMESH::AxisStruct & theAxis,
3018 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3019 CORBA::Boolean theCopy,
3021 ::SMESH_Mesh* theTargetMesh)
3022 throw (SALOME::SALOME_Exception)
3027 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3028 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3030 if ( theTargetMesh )
3034 switch ( theMirrorType ) {
3035 case SMESH::SMESH_MeshEditor::POINT:
3036 aTrsf.SetMirror( P );
3038 case SMESH::SMESH_MeshEditor::AXIS:
3039 aTrsf.SetMirror( gp_Ax1( P, V ));
3042 aTrsf.SetMirror( gp_Ax2( P, V ));
3045 TIDSortedElemSet copyElements;
3046 TIDSortedElemSet* workElements = & theElements;
3048 if ( myIsPreviewMode )
3050 TPreviewMesh * tmpMesh = getPreviewMesh();
3051 tmpMesh->Copy( theElements, copyElements);
3052 if ( !theCopy && !theTargetMesh )
3054 TIDSortedElemSet elemsAround, elemsAroundCopy;
3055 getElementsAround( theElements, getMeshDS(), elemsAround );
3056 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3058 workElements = & copyElements;
3059 theMakeGroups = false;
3062 ::SMESH_MeshEditor::PGroupIDs groupIds =
3063 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3065 if ( theCopy && !myIsPreviewMode)
3067 if ( theTargetMesh )
3069 theTargetMesh->GetMeshDS()->Modified();
3073 declareMeshModified( /*isReComputeSafe=*/false );
3076 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3078 SMESH_CATCH( SMESH::throwCorbaException );
3082 //=======================================================================
3085 //=======================================================================
3087 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3088 const SMESH::AxisStruct & theAxis,
3089 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3090 CORBA::Boolean theCopy)
3091 throw (SALOME::SALOME_Exception)
3093 if ( !myIsPreviewMode ) {
3094 TPythonDump() << this << ".Mirror( "
3095 << theIDsOfElements << ", "
3097 << mirrorTypeName(theMirrorType) << ", "
3100 if ( theIDsOfElements.length() > 0 )
3102 TIDSortedElemSet elements;
3103 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3104 mirror(elements, theAxis, theMirrorType, theCopy, false);
3109 //=======================================================================
3110 //function : MirrorObject
3112 //=======================================================================
3114 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3115 const SMESH::AxisStruct & theAxis,
3116 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3117 CORBA::Boolean theCopy)
3118 throw (SALOME::SALOME_Exception)
3120 if ( !myIsPreviewMode ) {
3121 TPythonDump() << this << ".MirrorObject( "
3122 << theObject << ", "
3124 << mirrorTypeName(theMirrorType) << ", "
3127 TIDSortedElemSet elements;
3129 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3131 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3132 mirror(elements, theAxis, theMirrorType, theCopy, false);
3135 //=======================================================================
3136 //function : MirrorMakeGroups
3138 //=======================================================================
3140 SMESH::ListOfGroups*
3141 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3142 const SMESH::AxisStruct& theMirror,
3143 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3144 throw (SALOME::SALOME_Exception)
3146 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3148 SMESH::ListOfGroups * aGroups = 0;
3149 if ( theIDsOfElements.length() > 0 )
3151 TIDSortedElemSet elements;
3152 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3153 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3155 if (!myIsPreviewMode) {
3156 dumpGroupsList(aPythonDump, aGroups);
3157 aPythonDump << this << ".MirrorMakeGroups( "
3158 << theIDsOfElements << ", "
3159 << theMirror << ", "
3160 << mirrorTypeName(theMirrorType) << " )";
3165 //=======================================================================
3166 //function : MirrorObjectMakeGroups
3168 //=======================================================================
3170 SMESH::ListOfGroups*
3171 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3172 const SMESH::AxisStruct& theMirror,
3173 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3174 throw (SALOME::SALOME_Exception)
3176 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3178 SMESH::ListOfGroups * aGroups = 0;
3179 TIDSortedElemSet elements;
3180 if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3181 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3183 if (!myIsPreviewMode)
3185 dumpGroupsList(aPythonDump,aGroups);
3186 aPythonDump << this << ".MirrorObjectMakeGroups( "
3187 << theObject << ", "
3188 << theMirror << ", "
3189 << mirrorTypeName(theMirrorType) << " )";
3194 //=======================================================================
3195 //function : MirrorMakeMesh
3197 //=======================================================================
3199 SMESH::SMESH_Mesh_ptr
3200 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
3201 const SMESH::AxisStruct& theMirror,
3202 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3203 CORBA::Boolean theCopyGroups,
3204 const char* theMeshName)
3205 throw (SALOME::SALOME_Exception)
3207 SMESH_Mesh_i* mesh_i;
3208 SMESH::SMESH_Mesh_var mesh;
3209 { // open new scope to dump "MakeMesh" command
3210 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3212 TPythonDump pydump; // to prevent dump at mesh creation
3214 mesh = makeMesh( theMeshName );
3215 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3216 if (mesh_i && theIDsOfElements.length() > 0 )
3218 TIDSortedElemSet elements;
3219 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3220 mirror(elements, theMirror, theMirrorType,
3221 false, theCopyGroups, & mesh_i->GetImpl());
3222 mesh_i->CreateGroupServants();
3225 if (!myIsPreviewMode) {
3226 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
3227 << theIDsOfElements << ", "
3228 << theMirror << ", "
3229 << mirrorTypeName(theMirrorType) << ", "
3230 << theCopyGroups << ", '"
3231 << theMeshName << "' )";
3236 if (!myIsPreviewMode && mesh_i)
3237 mesh_i->GetGroups();
3239 return mesh._retn();
3242 //=======================================================================
3243 //function : MirrorObjectMakeMesh
3245 //=======================================================================
3247 SMESH::SMESH_Mesh_ptr
3248 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3249 const SMESH::AxisStruct& theMirror,
3250 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3251 CORBA::Boolean theCopyGroups,
3252 const char* theMeshName)
3253 throw (SALOME::SALOME_Exception)
3255 SMESH_Mesh_i* mesh_i;
3256 SMESH::SMESH_Mesh_var mesh;
3257 { // open new scope to dump "MakeMesh" command
3258 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3260 TPythonDump pydump; // to prevent dump at mesh creation
3262 mesh = makeMesh( theMeshName );
3263 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3264 TIDSortedElemSet elements;
3266 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3268 mirror(elements, theMirror, theMirrorType,
3269 false, theCopyGroups, & mesh_i->GetImpl());
3270 mesh_i->CreateGroupServants();
3272 if (!myIsPreviewMode) {
3273 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
3274 << theObject << ", "
3275 << theMirror << ", "
3276 << mirrorTypeName(theMirrorType) << ", "
3277 << theCopyGroups << ", '"
3278 << theMeshName << "' )";
3283 if (!myIsPreviewMode && mesh_i)
3284 mesh_i->GetGroups();
3286 return mesh._retn();
3289 //=======================================================================
3290 //function : translate
3292 //=======================================================================
3294 SMESH::ListOfGroups*
3295 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
3296 const SMESH::DirStruct & theVector,
3297 CORBA::Boolean theCopy,
3299 ::SMESH_Mesh* theTargetMesh)
3300 throw (SALOME::SALOME_Exception)
3305 if ( theTargetMesh )
3309 const SMESH::PointStruct * P = &theVector.PS;
3310 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
3312 TIDSortedElemSet copyElements;
3313 TIDSortedElemSet* workElements = &theElements;
3315 if ( myIsPreviewMode )
3317 TPreviewMesh * tmpMesh = getPreviewMesh();
3318 tmpMesh->Copy( theElements, copyElements);
3319 if ( !theCopy && !theTargetMesh )
3321 TIDSortedElemSet elemsAround, elemsAroundCopy;
3322 getElementsAround( theElements, getMeshDS(), elemsAround );
3323 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3325 workElements = & copyElements;
3326 theMakeGroups = false;
3329 ::SMESH_MeshEditor::PGroupIDs groupIds =
3330 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3332 if ( theCopy && !myIsPreviewMode )
3334 if ( theTargetMesh )
3336 theTargetMesh->GetMeshDS()->Modified();
3340 declareMeshModified( /*isReComputeSafe=*/false );
3344 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3346 SMESH_CATCH( SMESH::throwCorbaException );
3350 //=======================================================================
3351 //function : Translate
3353 //=======================================================================
3355 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
3356 const SMESH::DirStruct & theVector,
3357 CORBA::Boolean theCopy)
3358 throw (SALOME::SALOME_Exception)
3360 if (!myIsPreviewMode) {
3361 TPythonDump() << this << ".Translate( "
3362 << theIDsOfElements << ", "
3363 << theVector << ", "
3366 if (theIDsOfElements.length()) {
3367 TIDSortedElemSet elements;
3368 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3369 translate(elements, theVector, theCopy, false);
3373 //=======================================================================
3374 //function : TranslateObject
3376 //=======================================================================
3378 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
3379 const SMESH::DirStruct & theVector,
3380 CORBA::Boolean theCopy)
3381 throw (SALOME::SALOME_Exception)
3383 if (!myIsPreviewMode) {
3384 TPythonDump() << this << ".TranslateObject( "
3385 << theObject << ", "
3386 << theVector << ", "
3389 TIDSortedElemSet elements;
3391 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3393 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3394 translate(elements, theVector, theCopy, false);
3397 //=======================================================================
3398 //function : TranslateMakeGroups
3400 //=======================================================================
3402 SMESH::ListOfGroups*
3403 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
3404 const SMESH::DirStruct& theVector)
3405 throw (SALOME::SALOME_Exception)
3407 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3409 SMESH::ListOfGroups * aGroups = 0;
3410 if (theIDsOfElements.length()) {
3411 TIDSortedElemSet elements;
3412 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3413 aGroups = translate(elements,theVector,true,true);
3415 if (!myIsPreviewMode) {
3416 dumpGroupsList(aPythonDump, aGroups);
3417 aPythonDump << this << ".TranslateMakeGroups( "
3418 << theIDsOfElements << ", "
3419 << theVector << " )";
3424 //=======================================================================
3425 //function : TranslateObjectMakeGroups
3427 //=======================================================================
3429 SMESH::ListOfGroups*
3430 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3431 const SMESH::DirStruct& theVector)
3432 throw (SALOME::SALOME_Exception)
3434 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3436 SMESH::ListOfGroups * aGroups = 0;
3437 TIDSortedElemSet elements;
3438 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3439 aGroups = translate(elements, theVector, true, true);
3441 if (!myIsPreviewMode) {
3442 dumpGroupsList(aPythonDump, aGroups);
3443 aPythonDump << this << ".TranslateObjectMakeGroups( "
3444 << theObject << ", "
3445 << theVector << " )";
3450 //=======================================================================
3451 //function : TranslateMakeMesh
3453 //=======================================================================
3455 SMESH::SMESH_Mesh_ptr
3456 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
3457 const SMESH::DirStruct& theVector,
3458 CORBA::Boolean theCopyGroups,
3459 const char* theMeshName)
3460 throw (SALOME::SALOME_Exception)
3462 SMESH_Mesh_i* mesh_i;
3463 SMESH::SMESH_Mesh_var mesh;
3465 { // open new scope to dump "MakeMesh" command
3466 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3468 TPythonDump pydump; // to prevent dump at mesh creation
3470 mesh = makeMesh( theMeshName );
3471 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3473 if ( mesh_i && theIDsOfElements.length() )
3475 TIDSortedElemSet elements;
3476 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3477 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
3478 mesh_i->CreateGroupServants();
3481 if ( !myIsPreviewMode ) {
3482 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
3483 << theIDsOfElements << ", "
3484 << theVector << ", "
3485 << theCopyGroups << ", '"
3486 << theMeshName << "' )";
3491 if (!myIsPreviewMode && mesh_i)
3492 mesh_i->GetGroups();
3494 return mesh._retn();
3497 //=======================================================================
3498 //function : TranslateObjectMakeMesh
3500 //=======================================================================
3502 SMESH::SMESH_Mesh_ptr
3503 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3504 const SMESH::DirStruct& theVector,
3505 CORBA::Boolean theCopyGroups,
3506 const char* theMeshName)
3507 throw (SALOME::SALOME_Exception)
3510 SMESH_Mesh_i* mesh_i;
3511 SMESH::SMESH_Mesh_var mesh;
3512 { // open new scope to dump "MakeMesh" command
3513 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3515 TPythonDump pydump; // to prevent dump at mesh creation
3516 mesh = makeMesh( theMeshName );
3517 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3519 TIDSortedElemSet elements;
3521 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3523 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
3524 mesh_i->CreateGroupServants();