1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_MeshEditor_i.cxx
23 // Author : Nicolas REJNERI
30 // A macro used in SMESH_TryCatch.hxx,
31 // it re-raises a CORBA SALOME exception thrown by SMESH_MeshEditor_i and caught by SMESH_CATCH
32 #define SMY_OWN_CATCH \
33 catch ( SALOME::SALOME_Exception & e ) { throw e; }
35 #include "SMESH_MeshEditor_i.hxx"
37 #include "SMDS_EdgePosition.hxx"
38 #include "SMDS_ElemIterator.hxx"
39 #include "SMDS_FacePosition.hxx"
40 #include "SMDS_IteratorOnIterators.hxx"
41 #include "SMDS_LinearEdge.hxx"
42 #include "SMDS_Mesh0DElement.hxx"
43 #include "SMDS_MeshFace.hxx"
44 #include "SMDS_MeshVolume.hxx"
45 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
46 #include "SMDS_SetIterator.hxx"
47 #include "SMDS_VolumeTool.hxx"
48 #include "SMESHDS_Group.hxx"
49 #include "SMESHDS_GroupOnGeom.hxx"
50 #include "SMESH_ControlsDef.hxx"
51 #include "SMESH_Filter_i.hxx"
52 #include "SMESH_Gen_i.hxx"
53 #include "SMESH_Group.hxx"
54 #include "SMESH_Group_i.hxx"
55 #include "SMESH_MeshAlgos.hxx"
56 #include "SMESH_MeshPartDS.hxx"
57 #include "SMESH_MesherHelper.hxx"
58 #include "SMESH_PythonDump.hxx"
59 #include "SMESH_subMeshEventListener.hxx"
60 #include "SMESH_subMesh_i.hxx"
62 #include <utilities.h>
63 #include <Utils_ExceptHandlers.hxx>
64 #include <Utils_CorbaException.hxx>
65 #include <SALOMEDS_wrap.hxx>
66 #include <SALOME_GenericObj_i.hh>
68 #include <BRepAdaptor_Surface.hxx>
69 #include <BRep_Tool.hxx>
70 #include <TopExp_Explorer.hxx>
72 #include <TopoDS_Edge.hxx>
73 #include <TopoDS_Face.hxx>
78 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
82 #include <Standard_Failure.hxx>
85 #include <Standard_ErrorHandler.hxx>
91 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
93 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
96 using SMESH::TPythonDump;
99 namespace MeshEditor_I {
101 //=============================================================================
103 * \brief Mesh to apply modifications for preview purposes
105 //=============================================================================
107 struct TPreviewMesh: public SMESH_Mesh
109 SMDSAbs_ElementType myPreviewType; // type to show
111 TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
112 _isShapeToMesh = (_id =_studyId = 0);
113 _myMeshDS = new SMESHDS_Mesh( _id, true );
114 myPreviewType = previewElements;
117 virtual ~TPreviewMesh() { delete _myMeshDS; _myMeshDS = 0; }
118 //!< Copy a set of elements
119 void Copy(const TIDSortedElemSet & theElements,
120 TIDSortedElemSet& theCopyElements,
121 SMDSAbs_ElementType theSelectType = SMDSAbs_All,
122 SMDSAbs_ElementType theAvoidType = SMDSAbs_All)
124 // loop on theIDsOfElements
125 TIDSortedElemSet::const_iterator eIt = theElements.begin();
126 for ( ; eIt != theElements.end(); ++eIt )
128 const SMDS_MeshElement* anElem = *eIt;
129 if ( !anElem ) continue;
130 SMDSAbs_ElementType type = anElem->GetType();
131 if ( type == theAvoidType ||
132 ( theSelectType != SMDSAbs_All && type != theSelectType ))
134 const SMDS_MeshElement* anElemCopy;
135 if ( type == SMDSAbs_Node)
136 anElemCopy = Copy( cast2Node(anElem) );
138 anElemCopy = Copy( anElem );
140 theCopyElements.insert( theCopyElements.end(), anElemCopy );
144 SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
146 // copy element nodes
147 int anElemNbNodes = anElem->NbNodes();
148 vector< int > anElemNodesID( anElemNbNodes ) ;
149 SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
150 for ( int i = 0; itElemNodes->more(); i++)
152 const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
154 anElemNodesID[i] = anElemNode->GetID();
157 // creates a corresponding element on copied nodes
158 SMDS_MeshElement* anElemCopy = 0;
159 if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
161 const SMDS_VtkVolume* ph =
162 dynamic_cast<const SMDS_VtkVolume*> (anElem);
164 anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
165 (anElemNodesID, ph->GetQuantities(),anElem->GetID());
168 anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
175 SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
177 return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(),
178 anElemNode->GetID());
182 GetMeshDS()->ClearMesh();
184 };// struct TPreviewMesh
186 static SMESH_NodeSearcher * theNodeSearcher = 0;
187 static SMESH_ElementSearcher * theElementSearcher = 0;
189 //=============================================================================
191 * \brief Deleter of theNodeSearcher at any compute event occured
193 //=============================================================================
195 struct TSearchersDeleter : public SMESH_subMeshEventListener
198 string myMeshPartIOR;
200 TSearchersDeleter(): SMESH_subMeshEventListener( false, // won't be deleted by submesh
201 "SMESH_MeshEditor_i::TSearchersDeleter"),
203 //!< Delete theNodeSearcher
206 if ( theNodeSearcher ) delete theNodeSearcher; theNodeSearcher = 0;
207 if ( theElementSearcher ) delete theElementSearcher; theElementSearcher = 0;
209 typedef map < int, SMESH_subMesh * > TDependsOnMap;
210 //!< The meshod called by submesh: do my main job
211 void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
212 SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
214 if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
216 Unset( sm->GetFather() );
219 //!< set self on all submeshes and delete theNodeSearcher if other mesh is set
220 void Set(SMESH_Mesh* mesh, const string& meshPartIOR = string())
222 if ( myMesh != mesh || myMeshPartIOR != meshPartIOR)
229 myMeshPartIOR = meshPartIOR;
230 SMESH_subMesh* sm = mesh->GetSubMesh( mesh->GetShapeToMesh() );
231 SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true );
232 while ( smIt->more() )
235 sm->SetEventListener( this, 0, sm );
239 //!< delete self from all submeshes
240 void Unset(SMESH_Mesh* mesh)
242 if ( SMESH_subMesh* sm = mesh->GetSubMeshContaining(1) ) {
243 SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true );
244 while ( smIt->more() )
245 smIt->next()->DeleteEventListener( this );
250 } theSearchersDeleter;
252 TCollection_AsciiString mirrorTypeName( SMESH::SMESH_MeshEditor::MirrorType theMirrorType )
254 TCollection_AsciiString typeStr;
255 switch ( theMirrorType ) {
256 case SMESH::SMESH_MeshEditor::POINT:
257 typeStr = "SMESH.SMESH_MeshEditor.POINT";
259 case SMESH::SMESH_MeshEditor::AXIS:
260 typeStr = "SMESH.SMESH_MeshEditor.AXIS";
263 typeStr = "SMESH.SMESH_MeshEditor.PLANE";
267 //================================================================================
269 * \brief function for conversion of long_array to TIDSortedElemSet
270 * \param IDs - array of IDs
271 * \param aMesh - mesh
272 * \param aMap - collection to fill
273 * \param aType - element type
275 //================================================================================
277 void arrayToSet(const SMESH::long_array & IDs,
278 const SMESHDS_Mesh* aMesh,
279 TIDSortedElemSet& aMap,
280 const SMDSAbs_ElementType aType = SMDSAbs_All,
281 SMDS_MeshElement::Filter* aFilter = NULL)
283 SMDS_MeshElement::NonNullFilter filter1;
284 SMDS_MeshElement::TypeFilter filter2( aType );
286 if ( aFilter == NULL )
287 aFilter = ( aType == SMDSAbs_All ) ? (SMDS_MeshElement::Filter*) &filter1 : (SMDS_MeshElement::Filter*) &filter2;
289 SMDS_MeshElement::Filter & filter = *aFilter;
291 if ( aType == SMDSAbs_Node )
292 for (int i=0; i<IDs.length(); i++) {
293 const SMDS_MeshElement * elem = aMesh->FindNode( IDs[i] );
295 aMap.insert( aMap.end(), elem );
298 for (int i=0; i<IDs.length(); i++) {
299 const SMDS_MeshElement * elem = aMesh->FindElement( IDs[i] );
301 aMap.insert( aMap.end(), elem );
304 //================================================================================
306 * \brief Retrieve elements of given type from SMESH_IDSource
308 //================================================================================
310 bool idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource,
311 const SMESHDS_Mesh* theMeshDS,
312 TIDSortedElemSet& theElemSet,
313 const SMDSAbs_ElementType theType,
314 const bool emptyIfIsMesh=false)
317 if ( CORBA::is_nil( theIDSource ) )
319 if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
322 SMESH::long_array_var anIDs = theIDSource->GetIDs();
323 if ( anIDs->length() == 0 )
325 SMESH::array_of_ElementType_var types = theIDSource->GetTypes();
326 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
328 if ( theType == SMDSAbs_All || theType == SMDSAbs_Node )
329 arrayToSet( anIDs, theMeshDS, theElemSet, SMDSAbs_Node );
335 arrayToSet( anIDs, theMeshDS, theElemSet, theType);
336 return bool(anIDs->length()) == bool(theElemSet.size());
340 //================================================================================
342 * \brief Retrieve nodes from SMESH_IDSource
344 //================================================================================
346 void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject,
347 const SMESHDS_Mesh* theMeshDS,
348 TIDSortedNodeSet& theNodeSet)
351 if ( CORBA::is_nil( theObject ) )
353 SMESH::array_of_ElementType_var types = theObject->GetTypes();
354 SMESH::long_array_var aElementsId = theObject->GetIDs();
355 if ( types->length() == 1 && types[0] == SMESH::NODE)
357 for(int i = 0; i < aElementsId->length(); i++)
358 if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] ))
359 theNodeSet.insert( theNodeSet.end(), n);
361 else if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
363 SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator();
364 while ( nIt->more( ))
365 if( const SMDS_MeshElement * elem = nIt->next() )
366 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
370 for(int i = 0; i < aElementsId->length(); i++)
371 if( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] ))
372 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
376 //================================================================================
378 * \brief Returns elements connected to the given elements
380 //================================================================================
382 void getElementsAround(const TIDSortedElemSet& theElements,
383 const SMESHDS_Mesh* theMeshDS,
384 TIDSortedElemSet& theElementsAround)
386 if ( theElements.empty() ) return;
388 SMDSAbs_ElementType elemType = (*theElements.begin())->GetType();
389 bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() );
391 theMeshDS->GetMeshInfo().NbElements( elemType ) == theElements.size() )
392 return; // all the elements are in theElements
395 elemType = SMDSAbs_All;
397 TIDSortedElemSet visitedNodes;
398 TIDSortedElemSet::const_iterator elemIt = theElements.begin();
399 for ( ; elemIt != theElements.end(); ++elemIt )
401 const SMDS_MeshElement* e = *elemIt;
402 int i = e->NbCornerNodes();
405 const SMDS_MeshNode* n = e->GetNode( i );
406 if ( visitedNodes.insert( n ).second )
408 SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
409 while ( invIt->more() )
411 const SMDS_MeshElement* elemAround = invIt->next();
412 if ( !theElements.count( elemAround ))
413 theElementsAround.insert( elemAround );
420 //================================================================================
422 * \brief Return a string used to detect change of mesh part on which theElementSearcher
423 * is going to be used
425 //================================================================================
427 string getPartIOR( SMESH::SMESH_IDSource_ptr theMeshPart, SMESH::ElementType type)
429 string partIOR = SMESH_Gen_i::GetORB()->object_to_string( theMeshPart );
430 if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( theMeshPart ))
431 // take into account passible group modification
432 partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() );
433 partIOR += SMESH_Comment( type );
437 } // namespace MeshEditor_I
439 using namespace MeshEditor_I;
441 //=============================================================================
445 //=============================================================================
447 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview):
449 myMesh( &theMesh->GetImpl() ),
451 myIsPreviewMode ( isPreview ),
457 //================================================================================
461 //================================================================================
463 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
465 PortableServer::POA_var poa = SMESH_Gen_i::GetPOA();
466 PortableServer::ObjectId_var anObjectId = poa->servant_to_id(this);
467 poa->deactivate_object(anObjectId.in());
469 //deleteAuxIDSources();
470 delete myPreviewMesh; myPreviewMesh = 0;
471 delete myPreviewEditor; myPreviewEditor = 0;
474 //================================================================================
476 * \brief Clear members
478 //================================================================================
480 void SMESH_MeshEditor_i::initData(bool deleteSearchers)
482 if ( myIsPreviewMode ) {
483 if ( myPreviewMesh ) myPreviewMesh->RemoveAll();
486 if ( deleteSearchers )
487 TSearchersDeleter::Delete();
489 getEditor().GetError().reset();
490 getEditor().CrearLastCreated();
493 //================================================================================
495 * \brief Increment mesh modif time and optionally record that the performed
496 * modification may influence futher mesh re-compute.
497 * \param [in] isReComputeSafe - true if the modification does not infulence
498 * futher mesh re-compute
500 //================================================================================
502 void SMESH_MeshEditor_i::declareMeshModified( bool isReComputeSafe )
504 myMesh->GetMeshDS()->Modified();
505 if ( !isReComputeSafe )
506 myMesh->SetIsModified( true );
509 //================================================================================
511 * \brief Return either myEditor or myPreviewEditor depending on myIsPreviewMode.
512 * WARNING: in preview mode call getPreviewMesh() before getEditor()!
514 //================================================================================
516 ::SMESH_MeshEditor& SMESH_MeshEditor_i::getEditor()
518 if ( myIsPreviewMode && !myPreviewEditor ) {
519 if ( !myPreviewMesh ) getPreviewMesh();
520 myPreviewEditor = new ::SMESH_MeshEditor( myPreviewMesh );
522 return myIsPreviewMode ? *myPreviewEditor : myEditor;
525 //================================================================================
527 * \brief Initialize and return myPreviewMesh
528 * \param previewElements - type of elements to show in preview
530 * WARNING: call it once par a method!
532 //================================================================================
534 TPreviewMesh * SMESH_MeshEditor_i::getPreviewMesh(SMDSAbs_ElementType previewElements)
536 if ( !myPreviewMesh || myPreviewMesh->myPreviewType != previewElements )
538 delete myPreviewEditor;
540 delete myPreviewMesh;
541 myPreviewMesh = new TPreviewMesh( previewElements );
543 myPreviewMesh->Clear();
544 return myPreviewMesh;
547 //================================================================================
549 * Return data of mesh edition preview
551 //================================================================================
553 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
554 throw (SALOME::SALOME_Exception)
557 const bool hasBadElems = ( getEditor().GetError() && getEditor().GetError()->HasBadElems() );
559 if ( myIsPreviewMode || hasBadElems ) { // --- MeshPreviewStruct filling ---
561 list<int> aNodesConnectivity;
562 typedef map<int, int> TNodesMap;
565 SMESHDS_Mesh* aMeshDS;
566 std::auto_ptr< SMESH_MeshPartDS > aMeshPartDS;
568 aMeshPartDS.reset( new SMESH_MeshPartDS( getEditor().GetError()->myBadElements ));
569 aMeshDS = aMeshPartDS.get();
572 aMeshDS = getEditor().GetMeshDS();
574 myPreviewData = new SMESH::MeshPreviewStruct();
575 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
578 SMDSAbs_ElementType previewType = SMDSAbs_All;
580 if (TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( getEditor().GetMesh() )) {
581 previewType = aPreviewMesh->myPreviewType;
582 switch ( previewType ) {
583 case SMDSAbs_Edge : break;
584 case SMDSAbs_Face : break;
585 case SMDSAbs_Volume: break;
587 if ( aMeshDS->GetMeshInfo().NbElements() == 0 ) previewType = SMDSAbs_Node;
591 myPreviewData->elementTypes.length( aMeshDS->GetMeshInfo().NbElements( previewType ));
593 SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator(previewType);
595 while ( itMeshElems->more() ) {
596 const SMDS_MeshElement* aMeshElem = itMeshElems->next();
597 SMDS_NodeIteratorPtr itElemNodes = aMeshElem->nodeIterator();
598 while ( itElemNodes->more() ) {
599 const SMDS_MeshNode* aMeshNode = itElemNodes->next();
600 int aNodeID = aMeshNode->GetID();
601 TNodesMap::iterator anIter = nodesMap.find(aNodeID);
602 if ( anIter == nodesMap.end() ) {
603 // filling the nodes coordinates
604 myPreviewData->nodesXYZ[j].x = aMeshNode->X();
605 myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
606 myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
607 anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
610 aNodesConnectivity.push_back(anIter->second);
613 // filling the elements types
614 SMDSAbs_ElementType aType = aMeshElem->GetType();
615 bool isPoly = aMeshElem->IsPoly();
616 myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
617 myPreviewData->elementTypes[i].isPoly = isPoly;
618 myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
621 myPreviewData->nodesXYZ.length( j );
623 // filling the elements connectivities
624 list<int>::iterator aConnIter = aNodesConnectivity.begin();
625 myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
626 for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
627 myPreviewData->elementConnectivities[i] = *aConnIter;
629 return myPreviewData._retn();
631 SMESH_CATCH( SMESH::throwCorbaException );
635 //================================================================================
637 * \brief Returns list of it's IDs of created nodes
638 * \retval SMESH::long_array* - list of node ID
640 //================================================================================
642 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
643 throw (SALOME::SALOME_Exception)
646 SMESH::long_array_var myLastCreatedNodes = new SMESH::long_array();
648 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedNodes();
649 myLastCreatedNodes->length( aSeq.Length() );
650 for (int i = 1; i <= aSeq.Length(); i++)
651 myLastCreatedNodes[i-1] = aSeq.Value(i)->GetID();
653 return myLastCreatedNodes._retn();
654 SMESH_CATCH( SMESH::throwCorbaException );
658 //================================================================================
660 * \brief Returns list of it's IDs of created elements
661 * \retval SMESH::long_array* - list of elements' ID
663 //================================================================================
665 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
666 throw (SALOME::SALOME_Exception)
669 SMESH::long_array_var myLastCreatedElems = new SMESH::long_array();
671 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
672 myLastCreatedElems->length( aSeq.Length() );
673 for ( int i = 1; i <= aSeq.Length(); i++ )
674 myLastCreatedElems[i-1] = aSeq.Value(i)->GetID();
676 return myLastCreatedElems._retn();
677 SMESH_CATCH( SMESH::throwCorbaException );
681 //=======================================================================
682 //function : ClearLastCreated
683 //purpose : Clears sequences of last created elements and nodes
684 //=======================================================================
686 void SMESH_MeshEditor_i::ClearLastCreated() throw (SALOME::SALOME_Exception)
689 getEditor().CrearLastCreated();
690 SMESH_CATCH( SMESH::throwCorbaException );
693 //=======================================================================
695 * Returns description of an error/warning occured during the last operation
696 * WARNING: ComputeError.code >= 100 and no corresponding enum in IDL API
698 //=======================================================================
700 SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError()
701 throw (SALOME::SALOME_Exception)
704 SMESH::ComputeError_var errOut = new SMESH::ComputeError;
705 SMESH_ComputeErrorPtr& errIn = getEditor().GetError();
706 if ( errIn && !errIn->IsOK() )
708 errOut->code = -( errIn->myName < 0 ? errIn->myName + 1: errIn->myName ); // -1 -> 0
709 errOut->comment = errIn->myComment.c_str();
710 errOut->subShapeID = -1;
711 errOut->hasBadMesh = !errIn->myBadElements.empty();
716 errOut->subShapeID = -1;
717 errOut->hasBadMesh = false;
720 return errOut._retn();
721 SMESH_CATCH( SMESH::throwCorbaException );
725 //=======================================================================
726 //function : MakeIDSource
727 //purpose : Wrap a sequence of ids in a SMESH_IDSource.
728 // Call UnRegister() as you fininsh using it!!
729 //=======================================================================
731 struct SMESH_MeshEditor_i::_IDSource : public virtual POA_SMESH::SMESH_IDSource,
732 public virtual SALOME::GenericObj_i
734 SMESH::long_array _ids;
735 SMESH::ElementType _type;
736 SMESH::SMESH_Mesh_ptr _mesh;
737 SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); }
738 SMESH::long_array* GetMeshInfo() { return 0; }
739 SMESH::long_array* GetNbElementsByType()
741 SMESH::long_array_var aRes = new SMESH::long_array();
742 aRes->length(SMESH::NB_ELEMENT_TYPES);
743 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
744 aRes[ i ] = ( i == _type ) ? _ids.length() : 0;
747 SMESH::SMESH_Mesh_ptr GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _mesh ); }
748 bool IsMeshInfoCorrect() { return true; }
749 SMESH::array_of_ElementType* GetTypes()
751 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
752 if ( _ids.length() > 0 ) {
756 return types._retn();
760 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
761 SMESH::ElementType type)
763 // if ( myAuxIDSources.size() > 10 ) {
764 // delete myAuxIDSources.front();
765 // myAuxIDSources.pop_front();
768 _IDSource* idSrc = new _IDSource;
769 idSrc->_mesh = myMesh_i->_this();
772 //myAuxIDSources.push_back( idSrc );
774 SMESH::SMESH_IDSource_var anIDSourceVar = idSrc->_this();
776 return anIDSourceVar._retn();
779 bool SMESH_MeshEditor_i::IsTemporaryIDSource( SMESH::SMESH_IDSource_ptr& idSource )
781 return SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource );
784 CORBA::Long* SMESH_MeshEditor_i::GetTemporaryIDs( SMESH::SMESH_IDSource_ptr& idSource,
787 if ( _IDSource* tmpIdSource = SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource ))
789 nbIds = (int) tmpIdSource->_ids.length();
790 return & tmpIdSource->_ids[0];
796 // void SMESH_MeshEditor_i::deleteAuxIDSources()
798 // std::list< _IDSource* >::iterator idSrcIt = myAuxIDSources.begin();
799 // for ( ; idSrcIt != myAuxIDSources.end(); ++idSrcIt )
801 // myAuxIDSources.clear();
804 //=============================================================================
808 //=============================================================================
811 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
812 throw (SALOME::SALOME_Exception)
819 for (int i = 0; i < IDsOfElements.length(); i++)
820 IdList.push_back( IDsOfElements[i] );
822 // Update Python script
823 TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
826 bool ret = getEditor().Remove( IdList, false );
828 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 ); // issue 0020693
831 SMESH_CATCH( SMESH::throwCorbaException );
835 //=============================================================================
839 //=============================================================================
841 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
842 throw (SALOME::SALOME_Exception)
848 for (int i = 0; i < IDsOfNodes.length(); i++)
849 IdList.push_back( IDsOfNodes[i] );
851 // Update Python script
852 TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
854 bool ret = getEditor().Remove( IdList, true );
856 declareMeshModified( /*isReComputeSafe=*/ !ret ); // issue 0020693
859 SMESH_CATCH( SMESH::throwCorbaException );
863 //=============================================================================
867 //=============================================================================
869 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
870 throw (SALOME::SALOME_Exception)
875 // Update Python script
876 TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
878 // Create filter to find all orphan nodes
879 SMESH::Controls::Filter::TIdSequence seq;
880 SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
881 SMESH::Controls::Filter::GetElementsId( getMeshDS(), predicate, seq );
883 // remove orphan nodes (if there are any)
885 for ( int i = 0; i < seq.size(); i++ )
886 IdList.push_back( seq[i] );
888 int nbNodesBefore = myMesh->NbNodes();
889 getEditor().Remove( IdList, true );
890 int nbNodesAfter = myMesh->NbNodes();
892 declareMeshModified( /*isReComputeSafe=*/ IdList.size() == 0 ); // issue 0020693
893 return nbNodesBefore - nbNodesAfter;
895 SMESH_CATCH( SMESH::throwCorbaException );
899 //=============================================================================
903 //=============================================================================
905 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,CORBA::Double y, CORBA::Double z)
906 throw (SALOME::SALOME_Exception)
911 const SMDS_MeshNode* N = getMeshDS()->AddNode(x, y, z);
913 // Update Python script
914 TPythonDump() << "nodeID = " << this << ".AddNode( "
915 << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )";
917 declareMeshModified( /*isReComputeSafe=*/false );
920 SMESH_CATCH( SMESH::throwCorbaException );
924 //=============================================================================
926 * Create 0D element on the given node.
928 //=============================================================================
930 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
931 throw (SALOME::SALOME_Exception)
936 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
937 SMDS_MeshElement* elem = getMeshDS()->Add0DElement(aNode);
939 // Update Python script
940 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
942 declareMeshModified( /*isReComputeSafe=*/false );
944 return elem ? elem->GetID() : 0;
946 SMESH_CATCH( SMESH::throwCorbaException );
950 //=============================================================================
952 * Create a ball element on the given node.
954 //=============================================================================
956 CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diameter)
957 throw (SALOME::SALOME_Exception)
962 if ( diameter < std::numeric_limits<double>::min() )
963 THROW_SALOME_CORBA_EXCEPTION("Invalid diameter", SALOME::BAD_PARAM);
965 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
966 SMDS_MeshElement* elem = getMeshDS()->AddBall(aNode, diameter);
968 // Update Python script
969 TPythonDump() << "ballElem = "
970 << this << ".AddBall( " << IDOfNode << ", " << diameter <<" )";
972 declareMeshModified( /*isReComputeSafe=*/false );
973 return elem ? elem->GetID() : 0;
975 SMESH_CATCH( SMESH::throwCorbaException );
979 //=============================================================================
981 * Create an edge, either linear and quadratic (this is determed
982 * by number of given nodes, two or three)
984 //=============================================================================
986 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
987 throw (SALOME::SALOME_Exception)
992 int NbNodes = IDsOfNodes.length();
993 SMDS_MeshElement* elem = 0;
996 CORBA::Long index1 = IDsOfNodes[0];
997 CORBA::Long index2 = IDsOfNodes[1];
998 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(index1),
999 getMeshDS()->FindNode(index2));
1001 // Update Python script
1002 TPythonDump() << "edge = " << this << ".AddEdge([ "
1003 << index1 << ", " << index2 <<" ])";
1006 CORBA::Long n1 = IDsOfNodes[0];
1007 CORBA::Long n2 = IDsOfNodes[1];
1008 CORBA::Long n12 = IDsOfNodes[2];
1009 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(n1),
1010 getMeshDS()->FindNode(n2),
1011 getMeshDS()->FindNode(n12));
1012 // Update Python script
1013 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
1014 <<n1<<", "<<n2<<", "<<n12<<" ])";
1017 declareMeshModified( /*isReComputeSafe=*/false );
1018 return elem ? elem->GetID() : 0;
1020 SMESH_CATCH( SMESH::throwCorbaException );
1024 //=============================================================================
1028 //=============================================================================
1030 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
1031 throw (SALOME::SALOME_Exception)
1036 int NbNodes = IDsOfNodes.length();
1042 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1043 for (int i = 0; i < NbNodes; i++)
1044 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1046 SMDS_MeshElement* elem = 0;
1048 case 3: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]); break;
1049 case 4: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]); break;
1050 case 6: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1051 nodes[4], nodes[5]); break;
1052 case 7: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1053 nodes[4], nodes[5], nodes[6]); break;
1054 case 8: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1055 nodes[4], nodes[5], nodes[6], nodes[7]); break;
1056 case 9: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1057 nodes[4], nodes[5], nodes[6], nodes[7],
1059 default: elem = getMeshDS()->AddPolygonalFace(nodes);
1062 // Update Python script
1063 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
1065 declareMeshModified( /*isReComputeSafe=*/false );
1067 return elem ? elem->GetID() : 0;
1069 SMESH_CATCH( SMESH::throwCorbaException );
1073 //=============================================================================
1077 //=============================================================================
1078 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
1079 throw (SALOME::SALOME_Exception)
1084 int NbNodes = IDsOfNodes.length();
1085 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1086 for (int i = 0; i < NbNodes; i++)
1087 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1089 const SMDS_MeshElement* elem = getMeshDS()->AddPolygonalFace(nodes);
1091 // Update Python script
1092 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
1094 declareMeshModified( /*isReComputeSafe=*/false );
1095 return elem ? elem->GetID() : 0;
1097 SMESH_CATCH( SMESH::throwCorbaException );
1101 //=============================================================================
1103 * Create volume, either linear and quadratic (this is determed
1104 * by number of given nodes)
1106 //=============================================================================
1108 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
1109 throw (SALOME::SALOME_Exception)
1114 int NbNodes = IDsOfNodes.length();
1115 vector< const SMDS_MeshNode*> n(NbNodes);
1116 for(int i=0;i<NbNodes;i++)
1117 n[i]= getMeshDS()->FindNode(IDsOfNodes[i]);
1119 SMDS_MeshElement* elem = 0;
1122 case 4 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
1123 case 5 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
1124 case 6 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
1125 case 8 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
1126 case 10:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1127 n[6],n[7],n[8],n[9]);
1129 case 12:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1130 n[6],n[7],n[8],n[9],n[10],n[11]);
1132 case 13:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
1133 n[7],n[8],n[9],n[10],n[11],n[12]);
1135 case 15:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
1136 n[9],n[10],n[11],n[12],n[13],n[14]);
1138 case 20:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1139 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1140 n[15],n[16],n[17],n[18],n[19]);
1142 case 27:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1143 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1144 n[15],n[16],n[17],n[18],n[19],
1145 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
1149 // Update Python script
1150 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
1152 declareMeshModified( /*isReComputeSafe=*/false );
1153 return elem ? elem->GetID() : 0;
1155 SMESH_CATCH( SMESH::throwCorbaException );
1159 //=============================================================================
1161 * AddPolyhedralVolume
1163 //=============================================================================
1164 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
1165 const SMESH::long_array & Quantities)
1166 throw (SALOME::SALOME_Exception)
1171 int NbNodes = IDsOfNodes.length();
1172 std::vector<const SMDS_MeshNode*> n (NbNodes);
1173 for (int i = 0; i < NbNodes; i++)
1175 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDsOfNodes[i]);
1176 if (!aNode) return 0;
1180 int NbFaces = Quantities.length();
1181 std::vector<int> q (NbFaces);
1182 for (int j = 0; j < NbFaces; j++)
1183 q[j] = Quantities[j];
1185 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(n, q);
1187 // Update Python script
1188 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
1189 << IDsOfNodes << ", " << Quantities << " )";
1191 declareMeshModified( /*isReComputeSafe=*/false );
1192 return elem ? elem->GetID() : 0;
1194 SMESH_CATCH( SMESH::throwCorbaException );
1198 //=============================================================================
1200 * AddPolyhedralVolumeByFaces
1202 //=============================================================================
1204 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
1205 throw (SALOME::SALOME_Exception)
1210 int NbFaces = IdsOfFaces.length();
1211 std::vector<const SMDS_MeshNode*> poly_nodes;
1212 std::vector<int> quantities (NbFaces);
1214 for (int i = 0; i < NbFaces; i++) {
1215 const SMDS_MeshElement* aFace = getMeshDS()->FindElement(IdsOfFaces[i]);
1216 quantities[i] = aFace->NbNodes();
1218 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
1219 while (It->more()) {
1220 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
1224 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
1226 // Update Python script
1227 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
1228 << IdsOfFaces << " )";
1230 declareMeshModified( /*isReComputeSafe=*/false );
1231 return elem ? elem->GetID() : 0;
1233 SMESH_CATCH( SMESH::throwCorbaException );
1237 //=============================================================================
1239 // \brief Create 0D elements on all nodes of the given object except those
1240 // nodes on which a 0D element already exists.
1241 // \param theObject object on whose nodes 0D elements will be created.
1242 // \param theGroupName optional name of a group to add 0D elements created
1243 // and/or found on nodes of \a theObject.
1244 // \return an object (a new group or a temporary SMESH_IDSource) holding
1245 // ids of new and/or found 0D elements.
1247 //=============================================================================
1249 SMESH::SMESH_IDSource_ptr
1250 SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObject,
1251 const char* theGroupName)
1252 throw (SALOME::SALOME_Exception)
1257 SMESH::SMESH_IDSource_var result;
1260 TIDSortedElemSet elements, elems0D;
1261 prepareIdSource( theObject );
1262 if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
1263 getEditor().Create0DElementsOnAllNodes( elements, elems0D );
1265 SMESH::long_array_var newElems = new SMESH::long_array;
1266 newElems->length( elems0D.size() );
1267 TIDSortedElemSet::iterator eIt = elems0D.begin();
1268 for ( size_t i = 0; i < elems0D.size(); ++i, ++eIt )
1269 newElems[ i ] = (*eIt)->GetID();
1271 SMESH::SMESH_GroupBase_var groupToFill;
1272 if ( theGroupName && strlen( theGroupName ))
1274 // Get existing group named theGroupName
1275 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
1276 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
1277 SMESH::SMESH_GroupBase_var group = groups[i];
1278 if ( !group->_is_nil() ) {
1279 CORBA::String_var name = group->GetName();
1280 if ( strcmp( name.in(), theGroupName ) == 0 && group->GetType() == SMESH::ELEM0D ) {
1281 groupToFill = group;
1286 if ( groupToFill->_is_nil() )
1287 groupToFill = myMesh_i->CreateGroup( SMESH::ELEM0D, theGroupName );
1288 else if ( !SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1289 groupToFill = myMesh_i->ConvertToStandalone( groupToFill );
1292 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1294 group_i->Add( newElems );
1295 result = SMESH::SMESH_IDSource::_narrow( groupToFill );
1296 pyDump << groupToFill;
1300 result = MakeIDSource( newElems, SMESH::ELEM0D );
1301 pyDump << "elem0DIDs";
1304 pyDump << " = " << this << ".Create0DElementsOnAllNodes( "
1305 << theObject << ", '" << theGroupName << "' )";
1307 return result._retn();
1309 SMESH_CATCH( SMESH::throwCorbaException );
1313 //=============================================================================
1315 * \brief Bind a node to a vertex
1316 * \param NodeID - node ID
1317 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1318 * \retval boolean - false if NodeID or VertexID is invalid
1320 //=============================================================================
1322 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
1323 throw (SALOME::SALOME_Exception)
1327 SMESHDS_Mesh * mesh = getMeshDS();
1328 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1330 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1332 if ( mesh->MaxShapeIndex() < VertexID )
1333 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1335 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
1336 if ( shape.ShapeType() != TopAbs_VERTEX )
1337 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1339 mesh->SetNodeOnVertex( node, VertexID );
1341 myMesh->SetIsModified( true );
1343 SMESH_CATCH( SMESH::throwCorbaException );
1346 //=============================================================================
1348 * \brief Store node position on an edge
1349 * \param NodeID - node ID
1350 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
1351 * \param paramOnEdge - parameter on edge where the node is located
1352 * \retval boolean - false if any parameter is invalid
1354 //=============================================================================
1356 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
1357 CORBA::Double paramOnEdge)
1358 throw (SALOME::SALOME_Exception)
1362 SMESHDS_Mesh * mesh = getMeshDS();
1363 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1365 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1367 if ( mesh->MaxShapeIndex() < EdgeID )
1368 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1370 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
1371 if ( shape.ShapeType() != TopAbs_EDGE )
1372 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1375 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
1376 if ( paramOnEdge < f || paramOnEdge > l )
1377 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
1379 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
1381 myMesh->SetIsModified( true );
1383 SMESH_CATCH( SMESH::throwCorbaException );
1386 //=============================================================================
1388 * \brief Store node position on a face
1389 * \param NodeID - node ID
1390 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
1391 * \param u - U parameter on face where the node is located
1392 * \param v - V parameter on face where the node is located
1393 * \retval boolean - false if any parameter is invalid
1395 //=============================================================================
1397 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
1398 CORBA::Double u, CORBA::Double v)
1399 throw (SALOME::SALOME_Exception)
1402 SMESHDS_Mesh * mesh = getMeshDS();
1403 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1405 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1407 if ( mesh->MaxShapeIndex() < FaceID )
1408 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1410 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
1411 if ( shape.ShapeType() != TopAbs_FACE )
1412 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1414 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
1415 bool isOut = ( u < surf.FirstUParameter() ||
1416 u > surf.LastUParameter() ||
1417 v < surf.FirstVParameter() ||
1418 v > surf.LastVParameter() );
1422 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
1423 << " u( " << surf.FirstUParameter()
1424 << "," << surf.LastUParameter()
1425 << ") v( " << surf.FirstVParameter()
1426 << "," << surf.LastVParameter() << ")" );
1428 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
1431 mesh->SetNodeOnFace( node, FaceID, u, v );
1432 myMesh->SetIsModified( true );
1434 SMESH_CATCH( SMESH::throwCorbaException );
1437 //=============================================================================
1439 * \brief Bind a node to a solid
1440 * \param NodeID - node ID
1441 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1442 * \retval boolean - false if NodeID or SolidID is invalid
1444 //=============================================================================
1446 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
1447 throw (SALOME::SALOME_Exception)
1450 SMESHDS_Mesh * mesh = getMeshDS();
1451 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1453 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1455 if ( mesh->MaxShapeIndex() < SolidID )
1456 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1458 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
1459 if ( shape.ShapeType() != TopAbs_SOLID &&
1460 shape.ShapeType() != TopAbs_SHELL)
1461 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1463 mesh->SetNodeInVolume( node, SolidID );
1465 SMESH_CATCH( SMESH::throwCorbaException );
1468 //=============================================================================
1470 * \brief Bind an element to a shape
1471 * \param ElementID - element ID
1472 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
1474 //=============================================================================
1476 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
1477 CORBA::Long ShapeID)
1478 throw (SALOME::SALOME_Exception)
1481 SMESHDS_Mesh * mesh = getMeshDS();
1482 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
1484 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
1486 if ( mesh->MaxShapeIndex() < ShapeID || ShapeID < 1 )
1487 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1489 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1490 if ( shape.ShapeType() != TopAbs_EDGE &&
1491 shape.ShapeType() != TopAbs_FACE &&
1492 shape.ShapeType() != TopAbs_SOLID &&
1493 shape.ShapeType() != TopAbs_SHELL )
1494 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1496 mesh->SetMeshElementOnShape( elem, ShapeID );
1498 myMesh->SetIsModified( true );
1500 SMESH_CATCH( SMESH::throwCorbaException );
1503 //=============================================================================
1507 //=============================================================================
1509 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1510 CORBA::Long NodeID2)
1511 throw (SALOME::SALOME_Exception)
1516 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1517 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1521 // Update Python script
1522 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1523 << NodeID1 << ", " << NodeID2 << " )";
1525 int ret = getEditor().InverseDiag ( n1, n2 );
1527 declareMeshModified( /*isReComputeSafe=*/false );
1530 SMESH_CATCH( SMESH::throwCorbaException );
1534 //=============================================================================
1538 //=============================================================================
1540 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1541 CORBA::Long NodeID2)
1542 throw (SALOME::SALOME_Exception)
1547 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1548 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1552 // Update Python script
1553 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1554 << NodeID1 << ", " << NodeID2 << " )";
1557 bool stat = getEditor().DeleteDiag ( n1, n2 );
1559 declareMeshModified( /*isReComputeSafe=*/!stat );
1563 SMESH_CATCH( SMESH::throwCorbaException );
1567 //=============================================================================
1571 //=============================================================================
1573 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1574 throw (SALOME::SALOME_Exception)
1579 for (int i = 0; i < IDsOfElements.length(); i++)
1581 CORBA::Long index = IDsOfElements[i];
1582 const SMDS_MeshElement * elem = getMeshDS()->FindElement(index);
1584 getEditor().Reorient( elem );
1586 // Update Python script
1587 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1589 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 );
1592 SMESH_CATCH( SMESH::throwCorbaException );
1596 //=============================================================================
1600 //=============================================================================
1602 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1603 throw (SALOME::SALOME_Exception)
1608 TPythonDump aTPythonDump; // suppress dump in Reorient()
1610 prepareIdSource( theObject );
1612 SMESH::long_array_var anElementsId = theObject->GetIDs();
1613 CORBA::Boolean isDone = Reorient(anElementsId);
1615 // Update Python script
1616 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1618 declareMeshModified( /*isReComputeSafe=*/ anElementsId->length() == 0 );
1621 SMESH_CATCH( SMESH::throwCorbaException );
1625 //=======================================================================
1626 //function : Reorient2D
1627 //purpose : Reorient faces contained in \a the2Dgroup.
1628 // the2Dgroup - the mesh or its part to reorient
1629 // theDirection - desired direction of normal of \a theFace
1630 // theFace - ID of face whose orientation is checked.
1631 // It can be < 1 then \a thePoint is used to find a face.
1632 // thePoint - is used to find a face if \a theFace < 1.
1633 // return number of reoriented elements.
1634 //=======================================================================
1636 CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
1637 const SMESH::DirStruct& theDirection,
1638 CORBA::Long theFace,
1639 const SMESH::PointStruct& thePoint)
1640 throw (SALOME::SALOME_Exception)
1643 initData(/*deleteSearchers=*/false);
1645 TIDSortedElemSet elements;
1646 prepareIdSource( the2Dgroup );
1647 if ( !idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1))
1648 THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
1651 const SMDS_MeshElement* face = 0;
1654 face = getMeshDS()->FindElement( theFace );
1656 THROW_SALOME_CORBA_EXCEPTION("Inexistent face given", SALOME::BAD_PARAM);
1657 if ( face->GetType() != SMDSAbs_Face )
1658 THROW_SALOME_CORBA_EXCEPTION("Wrong element type", SALOME::BAD_PARAM);
1662 // create theElementSearcher if needed
1663 theSearchersDeleter.Set( myMesh, getPartIOR( the2Dgroup, SMESH::FACE ));
1664 if ( !theElementSearcher )
1666 if ( elements.empty() ) // search in the whole mesh
1668 if ( myMesh->NbFaces() == 0 )
1669 THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM);
1671 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
1675 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
1676 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
1678 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt);
1682 gp_Pnt p( thePoint.x, thePoint.y, thePoint.z );
1683 face = theElementSearcher->FindClosestTo( p, SMDSAbs_Face );
1686 THROW_SALOME_CORBA_EXCEPTION("No face found by point", SALOME::INTERNAL_ERROR );
1687 if ( !elements.empty() && !elements.count( face ))
1688 THROW_SALOME_CORBA_EXCEPTION("Found face is not in the group", SALOME::BAD_PARAM );
1691 const SMESH::PointStruct * P = &theDirection.PS;
1692 gp_Vec dirVec( P->x, P->y, P->z );
1693 if ( dirVec.Magnitude() < std::numeric_limits< double >::min() )
1694 THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM);
1696 int nbReori = getEditor().Reorient2D( elements, dirVec, face );
1699 declareMeshModified( /*isReComputeSafe=*/false );
1701 TPythonDump() << this << ".Reorient2D( "
1702 << the2Dgroup << ", "
1703 << theDirection << ", "
1705 << thePoint << " )";
1709 SMESH_CATCH( SMESH::throwCorbaException );
1713 //=============================================================================
1715 * \brief Fuse neighbour triangles into quadrangles.
1717 //=============================================================================
1719 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1720 SMESH::NumericalFunctor_ptr Criterion,
1721 CORBA::Double MaxAngle)
1722 throw (SALOME::SALOME_Exception)
1727 SMESHDS_Mesh* aMesh = getMeshDS();
1728 TIDSortedElemSet faces,copyFaces;
1729 SMDS_MeshElement::GeomFilter triaFilter(SMDSGeom_TRIANGLE);
1730 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face, & triaFilter);
1731 TIDSortedElemSet* workElements = & faces;
1733 if ( myIsPreviewMode ) {
1734 SMDSAbs_ElementType select = SMDSAbs_Face;
1735 getPreviewMesh( SMDSAbs_Face )->Copy( faces, copyFaces, select );
1736 workElements = & copyFaces;
1739 SMESH::NumericalFunctor_i* aNumericalFunctor =
1740 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1741 SMESH::Controls::NumericalFunctorPtr aCrit;
1742 if ( !aNumericalFunctor )
1743 aCrit.reset( new SMESH::Controls::MaxElementLength2D() );
1745 aCrit = aNumericalFunctor->GetNumericalFunctor();
1747 if ( !myIsPreviewMode ) {
1748 // Update Python script
1749 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1750 << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1753 bool stat = getEditor().TriToQuad( *workElements, aCrit, MaxAngle );
1755 declareMeshModified( /*isReComputeSafe=*/!stat );
1758 SMESH_CATCH( SMESH::throwCorbaException );
1762 //=============================================================================
1764 * \brief Fuse neighbour triangles into quadrangles.
1766 //=============================================================================
1768 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1769 SMESH::NumericalFunctor_ptr Criterion,
1770 CORBA::Double MaxAngle)
1771 throw (SALOME::SALOME_Exception)
1776 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1778 prepareIdSource( theObject );
1779 SMESH::long_array_var anElementsId = theObject->GetIDs();
1780 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1782 if ( !myIsPreviewMode ) {
1783 SMESH::NumericalFunctor_i* aNumericalFunctor =
1784 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1786 // Update Python script
1787 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1788 << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1793 SMESH_CATCH( SMESH::throwCorbaException );
1797 //=============================================================================
1799 * \brief Split quadrangles into triangles.
1801 //=============================================================================
1803 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1804 SMESH::NumericalFunctor_ptr Criterion)
1805 throw (SALOME::SALOME_Exception)
1810 SMESHDS_Mesh* aMesh = getMeshDS();
1811 TIDSortedElemSet faces;
1812 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1814 SMESH::NumericalFunctor_i* aNumericalFunctor =
1815 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1816 SMESH::Controls::NumericalFunctorPtr aCrit;
1817 if ( !aNumericalFunctor )
1818 aCrit.reset( new SMESH::Controls::AspectRatio() );
1820 aCrit = aNumericalFunctor->GetNumericalFunctor();
1823 // Update Python script
1824 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1826 CORBA::Boolean stat = getEditor().QuadToTri( faces, aCrit );
1828 declareMeshModified( /*isReComputeSafe=*/false );
1831 SMESH_CATCH( SMESH::throwCorbaException );
1835 //=============================================================================
1837 * \brief Split quadrangles into triangles.
1839 //=============================================================================
1841 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1842 SMESH::NumericalFunctor_ptr Criterion)
1843 throw (SALOME::SALOME_Exception)
1848 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1850 prepareIdSource( theObject );
1851 SMESH::long_array_var anElementsId = theObject->GetIDs();
1852 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1854 SMESH::NumericalFunctor_i* aNumericalFunctor =
1855 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1857 // Update Python script
1858 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1860 declareMeshModified( /*isReComputeSafe=*/false );
1863 SMESH_CATCH( SMESH::throwCorbaException );
1867 //================================================================================
1869 * \brief Split each of quadrangles into 4 triangles.
1870 * \param [in] theObject - theQuads Container of quadrangles to split.
1872 //================================================================================
1874 void SMESH_MeshEditor_i::QuadTo4Tri (SMESH::SMESH_IDSource_ptr theObject)
1875 throw (SALOME::SALOME_Exception)
1880 TIDSortedElemSet faces;
1881 prepareIdSource( theObject );
1882 if ( !idSourceToSet( theObject, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/true ) &&
1884 THROW_SALOME_CORBA_EXCEPTION("No faces given", SALOME::BAD_PARAM);
1886 getEditor().QuadTo4Tri( faces );
1887 TPythonDump() << this << ".QuadTo4Tri( " << theObject << " )";
1889 SMESH_CATCH( SMESH::throwCorbaException );
1892 //=============================================================================
1894 * \brief Split quadrangles into triangles.
1896 //=============================================================================
1898 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1899 CORBA::Boolean Diag13)
1900 throw (SALOME::SALOME_Exception)
1905 SMESHDS_Mesh* aMesh = getMeshDS();
1906 TIDSortedElemSet faces;
1907 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1909 // Update Python script
1910 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1911 << IDsOfElements << ", " << Diag13 << " )";
1913 CORBA::Boolean stat = getEditor().QuadToTri( faces, Diag13 );
1915 declareMeshModified( /*isReComputeSafe=*/ !stat );
1918 SMESH_CATCH( SMESH::throwCorbaException );
1922 //=============================================================================
1924 * \brief Split quadrangles into triangles.
1926 //=============================================================================
1928 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1929 CORBA::Boolean Diag13)
1930 throw (SALOME::SALOME_Exception)
1935 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
1937 prepareIdSource( theObject );
1938 SMESH::long_array_var anElementsId = theObject->GetIDs();
1939 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
1941 // Update Python script
1942 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
1943 << theObject << ", " << Diag13 << " )";
1945 declareMeshModified( /*isReComputeSafe=*/!isDone );
1948 SMESH_CATCH( SMESH::throwCorbaException );
1953 //=============================================================================
1955 * Find better splitting of the given quadrangle.
1956 * \param IDOfQuad ID of the quadrangle to be splitted.
1957 * \param Criterion A criterion to choose a diagonal for splitting.
1958 * \return 1 if 1-3 diagonal is better, 2 if 2-4
1959 * diagonal is better, 0 if error occurs.
1961 //=============================================================================
1963 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
1964 SMESH::NumericalFunctor_ptr Criterion)
1965 throw (SALOME::SALOME_Exception)
1970 const SMDS_MeshElement* quad = getMeshDS()->FindElement(IDOfQuad);
1971 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
1973 SMESH::NumericalFunctor_i* aNumericalFunctor =
1974 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
1975 SMESH::Controls::NumericalFunctorPtr aCrit;
1976 if (aNumericalFunctor)
1977 aCrit = aNumericalFunctor->GetNumericalFunctor();
1979 aCrit.reset(new SMESH::Controls::AspectRatio());
1981 int id = getEditor().BestSplit(quad, aCrit);
1982 declareMeshModified( /*isReComputeSafe=*/ id < 1 );
1986 SMESH_CATCH( SMESH::throwCorbaException );
1990 //================================================================================
1992 * \brief Split volumic elements into tetrahedrons
1994 //================================================================================
1996 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
1997 CORBA::Short methodFlags)
1998 throw (SALOME::SALOME_Exception)
2002 prepareIdSource( elems );
2004 ::SMESH_MeshEditor::TFacetOfElem elemSet;
2005 const int noneFacet = -1;
2006 SMDS_ElemIteratorPtr volIt = myMesh_i->GetElements( elems, SMESH::VOLUME );
2007 while( volIt->more() )
2008 elemSet.insert( elemSet.end(), make_pair( volIt->next(), noneFacet ));
2010 getEditor().SplitVolumes( elemSet, int( methodFlags ));
2011 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2013 TPythonDump() << this << ".SplitVolumesIntoTetra( "
2014 << elems << ", " << methodFlags << " )";
2016 SMESH_CATCH( SMESH::throwCorbaException );
2019 //================================================================================
2021 * \brief Split hexahedra into triangular prisms
2022 * \param elems - elements to split
2023 * \param facetToSplitNormal - normal used to find a facet of hexahedron
2024 * to split into triangles
2025 * \param methodFlags - flags passing splitting method:
2026 * 1 - split the hexahedron into 2 prisms
2027 * 2 - split the hexahedron into 4 prisms
2029 //================================================================================
2031 void SMESH_MeshEditor_i::SplitHexahedraIntoPrisms (SMESH::SMESH_IDSource_ptr elems,
2032 CORBA::Short methodFlags,
2033 const SMESH::AxisStruct & facetToSplitNormal,
2034 CORBA::Boolean allDomains)
2035 throw (SALOME::SALOME_Exception)
2039 prepareIdSource( elems );
2041 gp_Ax1 facetNorm( gp_Pnt( facetToSplitNormal.x,
2042 facetToSplitNormal.y,
2043 facetToSplitNormal.z ),
2044 gp_Dir( facetToSplitNormal.vx,
2045 facetToSplitNormal.vy,
2046 facetToSplitNormal.vz ));
2047 TIDSortedElemSet elemSet;
2048 SMESH::long_array_var anElementsId = elems->GetIDs();
2049 SMDS_MeshElement::GeomFilter filter( SMDSGeom_HEXA );
2050 arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume, &filter );
2052 ::SMESH_MeshEditor::TFacetOfElem elemFacets;
2053 while ( !elemSet.empty() )
2055 getEditor().GetHexaFacetsToSplit( elemSet, facetNorm, elemFacets );
2059 ::SMESH_MeshEditor::TFacetOfElem::iterator ef = elemFacets.begin();
2060 for ( ; ef != elemFacets.end(); ++ef )
2061 elemSet.erase( ef->first );
2064 if ( methodFlags == 2 )
2065 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_4_PRISMS );
2067 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_2_PRISMS );
2069 getEditor().SplitVolumes( elemFacets, int( methodFlags ));
2070 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2072 TPythonDump() << this << ".SplitHexahedraIntoPrisms( "
2073 << elems << ", " << methodFlags<< ", "
2074 << facetToSplitNormal<< ", " << allDomains << " )";
2076 SMESH_CATCH( SMESH::throwCorbaException );
2079 //=======================================================================
2082 //=======================================================================
2085 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
2086 const SMESH::long_array & IDsOfFixedNodes,
2087 CORBA::Long MaxNbOfIterations,
2088 CORBA::Double MaxAspectRatio,
2089 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2090 throw (SALOME::SALOME_Exception)
2092 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2093 MaxAspectRatio, Method, false );
2097 //=======================================================================
2098 //function : SmoothParametric
2100 //=======================================================================
2103 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
2104 const SMESH::long_array & IDsOfFixedNodes,
2105 CORBA::Long MaxNbOfIterations,
2106 CORBA::Double MaxAspectRatio,
2107 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2108 throw (SALOME::SALOME_Exception)
2110 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2111 MaxAspectRatio, Method, true );
2115 //=======================================================================
2116 //function : SmoothObject
2118 //=======================================================================
2121 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
2122 const SMESH::long_array & IDsOfFixedNodes,
2123 CORBA::Long MaxNbOfIterations,
2124 CORBA::Double MaxAspectRatio,
2125 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2126 throw (SALOME::SALOME_Exception)
2128 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2129 MaxAspectRatio, Method, false);
2133 //=======================================================================
2134 //function : SmoothParametricObject
2136 //=======================================================================
2139 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
2140 const SMESH::long_array & IDsOfFixedNodes,
2141 CORBA::Long MaxNbOfIterations,
2142 CORBA::Double MaxAspectRatio,
2143 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2144 throw (SALOME::SALOME_Exception)
2146 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2147 MaxAspectRatio, Method, true);
2151 //=============================================================================
2155 //=============================================================================
2158 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
2159 const SMESH::long_array & IDsOfFixedNodes,
2160 CORBA::Long MaxNbOfIterations,
2161 CORBA::Double MaxAspectRatio,
2162 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2164 throw (SALOME::SALOME_Exception)
2169 SMESHDS_Mesh* aMesh = getMeshDS();
2171 TIDSortedElemSet elements;
2172 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
2174 set<const SMDS_MeshNode*> fixedNodes;
2175 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
2176 CORBA::Long index = IDsOfFixedNodes[i];
2177 const SMDS_MeshNode * node = aMesh->FindNode(index);
2179 fixedNodes.insert( node );
2181 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
2182 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
2183 method = ::SMESH_MeshEditor::CENTROIDAL;
2185 getEditor().Smooth(elements, fixedNodes, method,
2186 MaxNbOfIterations, MaxAspectRatio, IsParametric );
2188 declareMeshModified( /*isReComputeSafe=*/true ); // does not prevent re-compute
2190 // Update Python script
2191 TPythonDump() << "isDone = " << this << "."
2192 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
2193 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
2194 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2195 << "SMESH.SMESH_MeshEditor."
2196 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2197 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2201 SMESH_CATCH( SMESH::throwCorbaException );
2205 //=============================================================================
2209 //=============================================================================
2212 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
2213 const SMESH::long_array & IDsOfFixedNodes,
2214 CORBA::Long MaxNbOfIterations,
2215 CORBA::Double MaxAspectRatio,
2216 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2218 throw (SALOME::SALOME_Exception)
2223 TPythonDump aTPythonDump; // suppress dump in smooth()
2225 prepareIdSource( theObject );
2226 SMESH::long_array_var anElementsId = theObject->GetIDs();
2227 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
2228 MaxAspectRatio, Method, IsParametric);
2230 // Update Python script
2231 aTPythonDump << "isDone = " << this << "."
2232 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
2233 << theObject << ", " << IDsOfFixedNodes << ", "
2234 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2235 << "SMESH.SMESH_MeshEditor."
2236 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2237 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2241 SMESH_CATCH( SMESH::throwCorbaException );
2245 //=============================================================================
2249 //=============================================================================
2251 void SMESH_MeshEditor_i::RenumberNodes()
2252 throw (SALOME::SALOME_Exception)
2255 // Update Python script
2256 TPythonDump() << this << ".RenumberNodes()";
2258 getMeshDS()->Renumber( true );
2260 SMESH_CATCH( SMESH::throwCorbaException );
2263 //=============================================================================
2267 //=============================================================================
2269 void SMESH_MeshEditor_i::RenumberElements()
2270 throw (SALOME::SALOME_Exception)
2273 // Update Python script
2274 TPythonDump() << this << ".RenumberElements()";
2276 getMeshDS()->Renumber( false );
2278 SMESH_CATCH( SMESH::throwCorbaException );
2281 //=======================================================================
2283 * \brief Return groups by their IDs
2285 //=======================================================================
2287 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
2288 throw (SALOME::SALOME_Exception)
2293 myMesh_i->CreateGroupServants();
2294 return myMesh_i->GetGroups( *groupIDs );
2296 SMESH_CATCH( SMESH::throwCorbaException );
2300 //=======================================================================
2301 //function : rotationSweep
2303 //=======================================================================
2305 SMESH::ListOfGroups*
2306 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
2307 const SMESH::AxisStruct & theAxis,
2308 CORBA::Double theAngleInRadians,
2309 CORBA::Long theNbOfSteps,
2310 CORBA::Double theTolerance,
2311 const bool theMakeGroups,
2312 const SMDSAbs_ElementType theElementType)
2313 throw (SALOME::SALOME_Exception)
2318 TIDSortedElemSet inElements, copyElements;
2319 arrayToSet(theIDsOfElements, getMeshDS(), inElements, theElementType);
2321 TIDSortedElemSet* workElements = & inElements;
2322 bool makeWalls=true;
2323 if ( myIsPreviewMode )
2325 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2326 getPreviewMesh( SMDSAbs_Face )->Copy( inElements, copyElements, select, avoid );
2327 workElements = & copyElements;
2328 //makeWalls = false;
2331 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
2332 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
2334 ::SMESH_MeshEditor::PGroupIDs groupIds =
2335 getEditor().RotationSweep (*workElements, Ax1, theAngleInRadians,
2336 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
2338 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2340 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2342 SMESH_CATCH( SMESH::throwCorbaException );
2346 //=======================================================================
2347 //function : RotationSweep
2349 //=======================================================================
2351 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
2352 const SMESH::AxisStruct & theAxis,
2353 CORBA::Double theAngleInRadians,
2354 CORBA::Long theNbOfSteps,
2355 CORBA::Double theTolerance)
2356 throw (SALOME::SALOME_Exception)
2358 if ( !myIsPreviewMode ) {
2359 TPythonDump() << this << ".RotationSweep( "
2360 << theIDsOfElements << ", "
2362 << TVar( theAngleInRadians ) << ", "
2363 << TVar( theNbOfSteps ) << ", "
2364 << TVar( theTolerance ) << " )";
2366 rotationSweep(theIDsOfElements,
2374 //=======================================================================
2375 //function : RotationSweepMakeGroups
2377 //=======================================================================
2379 SMESH::ListOfGroups*
2380 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2381 const SMESH::AxisStruct& theAxis,
2382 CORBA::Double theAngleInRadians,
2383 CORBA::Long theNbOfSteps,
2384 CORBA::Double theTolerance)
2385 throw (SALOME::SALOME_Exception)
2387 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2389 SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
2395 if (!myIsPreviewMode) {
2396 dumpGroupsList(aPythonDump, aGroups);
2397 aPythonDump << this << ".RotationSweepMakeGroups( "
2398 << theIDsOfElements << ", "
2400 << TVar( theAngleInRadians ) << ", "
2401 << TVar( theNbOfSteps ) << ", "
2402 << TVar( theTolerance ) << " )";
2407 //=======================================================================
2408 //function : RotationSweepObject
2410 //=======================================================================
2412 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2413 const SMESH::AxisStruct & theAxis,
2414 CORBA::Double theAngleInRadians,
2415 CORBA::Long theNbOfSteps,
2416 CORBA::Double theTolerance)
2417 throw (SALOME::SALOME_Exception)
2419 if ( !myIsPreviewMode ) {
2420 TPythonDump() << this << ".RotationSweepObject( "
2421 << theObject << ", "
2423 << theAngleInRadians << ", "
2424 << theNbOfSteps << ", "
2425 << theTolerance << " )";
2427 prepareIdSource( theObject );
2428 SMESH::long_array_var anElementsId = theObject->GetIDs();
2429 rotationSweep(anElementsId,
2437 //=======================================================================
2438 //function : RotationSweepObject1D
2440 //=======================================================================
2442 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2443 const SMESH::AxisStruct & theAxis,
2444 CORBA::Double theAngleInRadians,
2445 CORBA::Long theNbOfSteps,
2446 CORBA::Double theTolerance)
2447 throw (SALOME::SALOME_Exception)
2449 if ( !myIsPreviewMode ) {
2450 TPythonDump() << this << ".RotationSweepObject1D( "
2451 << theObject << ", "
2453 << TVar( theAngleInRadians ) << ", "
2454 << TVar( theNbOfSteps ) << ", "
2455 << TVar( theTolerance ) << " )";
2457 prepareIdSource( theObject );
2458 SMESH::long_array_var anElementsId = theObject->GetIDs();
2459 rotationSweep(anElementsId,
2468 //=======================================================================
2469 //function : RotationSweepObject2D
2471 //=======================================================================
2473 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2474 const SMESH::AxisStruct & theAxis,
2475 CORBA::Double theAngleInRadians,
2476 CORBA::Long theNbOfSteps,
2477 CORBA::Double theTolerance)
2478 throw (SALOME::SALOME_Exception)
2480 if ( !myIsPreviewMode ) {
2481 TPythonDump() << this << ".RotationSweepObject2D( "
2482 << theObject << ", "
2484 << TVar( theAngleInRadians ) << ", "
2485 << TVar( theNbOfSteps ) << ", "
2486 << TVar( theTolerance ) << " )";
2488 prepareIdSource( theObject );
2489 SMESH::long_array_var anElementsId = theObject->GetIDs();
2490 rotationSweep(anElementsId,
2499 //=======================================================================
2500 //function : RotationSweepObjectMakeGroups
2502 //=======================================================================
2504 SMESH::ListOfGroups*
2505 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2506 const SMESH::AxisStruct& theAxis,
2507 CORBA::Double theAngleInRadians,
2508 CORBA::Long theNbOfSteps,
2509 CORBA::Double theTolerance)
2510 throw (SALOME::SALOME_Exception)
2512 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2514 prepareIdSource( theObject );
2515 SMESH::long_array_var anElementsId = theObject->GetIDs();
2516 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2522 if (!myIsPreviewMode) {
2523 dumpGroupsList(aPythonDump, aGroups);
2524 aPythonDump << this << ".RotationSweepObjectMakeGroups( "
2525 << theObject << ", "
2527 << theAngleInRadians << ", "
2528 << theNbOfSteps << ", "
2529 << theTolerance << " )";
2534 //=======================================================================
2535 //function : RotationSweepObject1DMakeGroups
2537 //=======================================================================
2539 SMESH::ListOfGroups*
2540 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2541 const SMESH::AxisStruct& theAxis,
2542 CORBA::Double theAngleInRadians,
2543 CORBA::Long theNbOfSteps,
2544 CORBA::Double theTolerance)
2545 throw (SALOME::SALOME_Exception)
2547 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2549 prepareIdSource( theObject );
2550 SMESH::long_array_var anElementsId = theObject->GetIDs();
2551 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2558 if (!myIsPreviewMode) {
2559 dumpGroupsList(aPythonDump, aGroups);
2560 aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
2561 << theObject << ", "
2563 << TVar( theAngleInRadians ) << ", "
2564 << TVar( theNbOfSteps ) << ", "
2565 << TVar( theTolerance ) << " )";
2570 //=======================================================================
2571 //function : RotationSweepObject2DMakeGroups
2573 //=======================================================================
2575 SMESH::ListOfGroups*
2576 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2577 const SMESH::AxisStruct& theAxis,
2578 CORBA::Double theAngleInRadians,
2579 CORBA::Long theNbOfSteps,
2580 CORBA::Double theTolerance)
2581 throw (SALOME::SALOME_Exception)
2583 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2585 prepareIdSource( theObject );
2586 SMESH::long_array_var anElementsId = theObject->GetIDs();
2587 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2594 if (!myIsPreviewMode) {
2595 dumpGroupsList(aPythonDump, aGroups);
2596 aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
2597 << theObject << ", "
2599 << TVar( theAngleInRadians ) << ", "
2600 << TVar( theNbOfSteps ) << ", "
2601 << TVar( theTolerance ) << " )";
2607 //=======================================================================
2608 //function : extrusionSweep
2610 //=======================================================================
2612 SMESH::ListOfGroups*
2613 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
2614 const SMESH::DirStruct & theStepVector,
2615 CORBA::Long theNbOfSteps,
2617 const SMDSAbs_ElementType theElementType)
2618 throw (SALOME::SALOME_Exception)
2623 TIDSortedElemSet elements, copyElements;
2624 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
2626 const SMESH::PointStruct * P = &theStepVector.PS;
2627 gp_Vec stepVec( P->x, P->y, P->z );
2629 TIDSortedElemSet* workElements = & elements;
2631 SMDSAbs_ElementType aType = SMDSAbs_Face;
2632 if (theElementType == SMDSAbs_Node)
2634 aType = SMDSAbs_Edge;
2636 if ( myIsPreviewMode ) {
2637 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2638 getPreviewMesh( aType )->Copy( elements, copyElements, select, avoid );
2639 workElements = & copyElements;
2640 theMakeGroups = false;
2643 ::SMESH_MeshEditor::TTElemOfElemListMap aHystory;
2644 ::SMESH_MeshEditor::PGroupIDs groupIds =
2645 getEditor().ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
2647 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2649 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2651 SMESH_CATCH( SMESH::throwCorbaException );
2655 //=======================================================================
2656 //function : ExtrusionSweep
2658 //=======================================================================
2660 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
2661 const SMESH::DirStruct & theStepVector,
2662 CORBA::Long theNbOfSteps)
2663 throw (SALOME::SALOME_Exception)
2665 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
2666 if (!myIsPreviewMode) {
2667 TPythonDump() << this << ".ExtrusionSweep( "
2668 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps) << " )";
2672 //=======================================================================
2673 //function : ExtrusionSweep0D
2675 //=======================================================================
2677 void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElements,
2678 const SMESH::DirStruct & theStepVector,
2679 CORBA::Long theNbOfSteps)
2680 throw (SALOME::SALOME_Exception)
2682 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2683 if (!myIsPreviewMode) {
2684 TPythonDump() << this << ".ExtrusionSweep0D( "
2685 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps)<< " )";
2689 //=======================================================================
2690 //function : ExtrusionSweepObject
2692 //=======================================================================
2694 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2695 const SMESH::DirStruct & theStepVector,
2696 CORBA::Long theNbOfSteps)
2697 throw (SALOME::SALOME_Exception)
2699 prepareIdSource( theObject );
2700 SMESH::long_array_var anElementsId = theObject->GetIDs();
2701 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
2702 if (!myIsPreviewMode) {
2703 TPythonDump() << this << ".ExtrusionSweepObject( "
2704 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
2708 //=======================================================================
2709 //function : ExtrusionSweepObject0D
2711 //=======================================================================
2713 void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObject,
2714 const SMESH::DirStruct & theStepVector,
2715 CORBA::Long theNbOfSteps)
2716 throw (SALOME::SALOME_Exception)
2718 prepareIdSource( theObject );
2719 SMESH::long_array_var anElementsId = theObject->GetIDs();
2720 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2721 if ( !myIsPreviewMode ) {
2722 TPythonDump() << this << ".ExtrusionSweepObject0D( "
2723 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2727 //=======================================================================
2728 //function : ExtrusionSweepObject1D
2730 //=======================================================================
2732 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2733 const SMESH::DirStruct & theStepVector,
2734 CORBA::Long theNbOfSteps)
2735 throw (SALOME::SALOME_Exception)
2737 prepareIdSource( theObject );
2738 SMESH::long_array_var anElementsId = theObject->GetIDs();
2739 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
2740 if ( !myIsPreviewMode ) {
2741 TPythonDump() << this << ".ExtrusionSweepObject1D( "
2742 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2746 //=======================================================================
2747 //function : ExtrusionSweepObject2D
2749 //=======================================================================
2751 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2752 const SMESH::DirStruct & theStepVector,
2753 CORBA::Long theNbOfSteps)
2754 throw (SALOME::SALOME_Exception)
2756 prepareIdSource( theObject );
2757 SMESH::long_array_var anElementsId = theObject->GetIDs();
2758 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
2759 if ( !myIsPreviewMode ) {
2760 TPythonDump() << this << ".ExtrusionSweepObject2D( "
2761 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2765 //=======================================================================
2766 //function : ExtrusionSweepMakeGroups
2768 //=======================================================================
2770 SMESH::ListOfGroups*
2771 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2772 const SMESH::DirStruct& theStepVector,
2773 CORBA::Long theNbOfSteps)
2774 throw (SALOME::SALOME_Exception)
2776 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2778 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
2780 if (!myIsPreviewMode) {
2781 dumpGroupsList(aPythonDump, aGroups);
2782 aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
2783 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2788 //=======================================================================
2789 //function : ExtrusionSweepMakeGroups0D
2791 //=======================================================================
2793 SMESH::ListOfGroups*
2794 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups0D(const SMESH::long_array& theIDsOfElements,
2795 const SMESH::DirStruct& theStepVector,
2796 CORBA::Long theNbOfSteps)
2797 throw (SALOME::SALOME_Exception)
2799 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2801 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true,SMDSAbs_Node);
2803 if (!myIsPreviewMode) {
2804 dumpGroupsList(aPythonDump, aGroups);
2805 aPythonDump << this << ".ExtrusionSweepMakeGroups0D( " << theIDsOfElements
2806 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2811 //=======================================================================
2812 //function : ExtrusionSweepObjectMakeGroups
2814 //=======================================================================
2816 SMESH::ListOfGroups*
2817 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2818 const SMESH::DirStruct& theStepVector,
2819 CORBA::Long theNbOfSteps)
2820 throw (SALOME::SALOME_Exception)
2822 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2824 prepareIdSource( theObject );
2825 SMESH::long_array_var anElementsId = theObject->GetIDs();
2826 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
2828 if (!myIsPreviewMode) {
2829 dumpGroupsList(aPythonDump, aGroups);
2830 aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
2831 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2836 //=======================================================================
2837 //function : ExtrusionSweepObject0DMakeGroups
2839 //=======================================================================
2841 SMESH::ListOfGroups*
2842 SMESH_MeshEditor_i::ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2843 const SMESH::DirStruct& theStepVector,
2844 CORBA::Long theNbOfSteps)
2845 throw (SALOME::SALOME_Exception)
2847 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2849 prepareIdSource( theObject );
2850 SMESH::long_array_var anElementsId = theObject->GetIDs();
2851 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2852 theNbOfSteps, true, SMDSAbs_Node);
2853 if (!myIsPreviewMode) {
2854 dumpGroupsList(aPythonDump, aGroups);
2855 aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject
2856 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2861 //=======================================================================
2862 //function : ExtrusionSweepObject1DMakeGroups
2864 //=======================================================================
2866 SMESH::ListOfGroups*
2867 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2868 const SMESH::DirStruct& theStepVector,
2869 CORBA::Long theNbOfSteps)
2870 throw (SALOME::SALOME_Exception)
2872 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2874 prepareIdSource( theObject );
2875 SMESH::long_array_var anElementsId = theObject->GetIDs();
2876 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2877 theNbOfSteps, true, SMDSAbs_Edge);
2878 if (!myIsPreviewMode) {
2879 dumpGroupsList(aPythonDump, aGroups);
2880 aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
2881 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2886 //=======================================================================
2887 //function : ExtrusionSweepObject2DMakeGroups
2889 //=======================================================================
2891 SMESH::ListOfGroups*
2892 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2893 const SMESH::DirStruct& theStepVector,
2894 CORBA::Long theNbOfSteps)
2895 throw (SALOME::SALOME_Exception)
2897 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2899 prepareIdSource( theObject );
2900 SMESH::long_array_var anElementsId = theObject->GetIDs();
2901 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2902 theNbOfSteps, true, SMDSAbs_Face);
2903 if (!myIsPreviewMode) {
2904 dumpGroupsList(aPythonDump, aGroups);
2905 aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
2906 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2912 //=======================================================================
2913 //function : advancedExtrusion
2915 //=======================================================================
2917 SMESH::ListOfGroups*
2918 SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
2919 const SMESH::DirStruct & theStepVector,
2920 CORBA::Long theNbOfSteps,
2921 CORBA::Long theExtrFlags,
2922 CORBA::Double theSewTolerance,
2923 const bool theMakeGroups)
2924 throw (SALOME::SALOME_Exception)
2929 TIDSortedElemSet elements;
2930 arrayToSet(theIDsOfElements, getMeshDS(), elements);
2932 const SMESH::PointStruct * P = &theStepVector.PS;
2933 gp_Vec stepVec( P->x, P->y, P->z );
2935 ::SMESH_MeshEditor::TTElemOfElemListMap aHystory;
2936 ::SMESH_MeshEditor::PGroupIDs groupIds =
2937 getEditor().ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
2938 theMakeGroups, theExtrFlags, theSewTolerance);
2940 declareMeshModified( /*isReComputeSafe=*/true );
2942 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2944 SMESH_CATCH( SMESH::throwCorbaException );
2948 //=======================================================================
2949 //function : AdvancedExtrusion
2951 //=======================================================================
2953 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2954 const SMESH::DirStruct & theStepVector,
2955 CORBA::Long theNbOfSteps,
2956 CORBA::Long theExtrFlags,
2957 CORBA::Double theSewTolerance)
2958 throw (SALOME::SALOME_Exception)
2960 if ( !myIsPreviewMode ) {
2961 TPythonDump() << "stepVector = " << theStepVector;
2962 TPythonDump() << this << ".AdvancedExtrusion("
2965 << theNbOfSteps << ","
2966 << theExtrFlags << ", "
2967 << theSewTolerance << " )";
2969 advancedExtrusion( theIDsOfElements,
2977 //=======================================================================
2978 //function : AdvancedExtrusionMakeGroups
2980 //=======================================================================
2981 SMESH::ListOfGroups*
2982 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
2983 const SMESH::DirStruct& theStepVector,
2984 CORBA::Long theNbOfSteps,
2985 CORBA::Long theExtrFlags,
2986 CORBA::Double theSewTolerance)
2987 throw (SALOME::SALOME_Exception)
2989 if (!myIsPreviewMode) {
2990 TPythonDump() << "stepVector = " << theStepVector;
2992 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2994 SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
3001 if (!myIsPreviewMode) {
3002 dumpGroupsList(aPythonDump, aGroups);
3003 aPythonDump << this << ".AdvancedExtrusionMakeGroups("
3006 << theNbOfSteps << ","
3007 << theExtrFlags << ", "
3008 << theSewTolerance << " )";
3014 //================================================================================
3016 * \brief Convert extrusion error to IDL enum
3018 //================================================================================
3020 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
3022 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
3026 RETCASE( EXTR_NO_ELEMENTS );
3027 RETCASE( EXTR_PATH_NOT_EDGE );
3028 RETCASE( EXTR_BAD_PATH_SHAPE );
3029 RETCASE( EXTR_BAD_STARTING_NODE );
3030 RETCASE( EXTR_BAD_ANGLES_NUMBER );
3031 RETCASE( EXTR_CANT_GET_TANGENT );
3033 return SMESH::SMESH_MeshEditor::EXTR_OK;
3037 //=======================================================================
3038 //function : extrusionAlongPath
3040 //=======================================================================
3041 SMESH::ListOfGroups*
3042 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfElements,
3043 SMESH::SMESH_Mesh_ptr thePathMesh,
3044 GEOM::GEOM_Object_ptr thePathShape,
3045 CORBA::Long theNodeStart,
3046 CORBA::Boolean theHasAngles,
3047 const SMESH::double_array & theAngles,
3048 CORBA::Boolean theHasRefPoint,
3049 const SMESH::PointStruct & theRefPoint,
3050 const bool theMakeGroups,
3051 SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
3052 const SMDSAbs_ElementType theElementType)
3053 throw (SALOME::SALOME_Exception)
3056 MESSAGE("extrusionAlongPath");
3059 if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
3060 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3063 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3065 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3066 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3068 if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
3069 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3073 SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
3075 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3079 TIDSortedElemSet elements;
3080 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
3082 list<double> angles;
3083 for (int i = 0; i < theAngles.length(); i++) {
3084 angles.push_back( theAngles[i] );
3087 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
3089 int nbOldGroups = myMesh->NbGroup();
3091 ::SMESH_MeshEditor::Extrusion_Error error =
3092 getEditor().ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
3093 theHasAngles, angles, false,
3094 theHasRefPoint, refPnt, theMakeGroups );
3096 declareMeshModified( /*isReComputeSafe=*/true );
3097 theError = convExtrError( error );
3099 if ( theMakeGroups ) {
3100 list<int> groupIDs = myMesh->GetGroupIds();
3101 list<int>::iterator newBegin = groupIDs.begin();
3102 std::advance( newBegin, nbOldGroups ); // skip old groups
3103 groupIDs.erase( groupIDs.begin(), newBegin );
3104 return getGroups( & groupIDs );
3108 SMESH_CATCH( SMESH::throwCorbaException );
3112 //=======================================================================
3113 //function : extrusionAlongPathX
3115 //=======================================================================
3117 SMESH::ListOfGroups*
3118 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements,
3119 SMESH::SMESH_IDSource_ptr Path,
3120 CORBA::Long NodeStart,
3121 CORBA::Boolean HasAngles,
3122 const SMESH::double_array& Angles,
3123 CORBA::Boolean LinearVariation,
3124 CORBA::Boolean HasRefPoint,
3125 const SMESH::PointStruct& RefPoint,
3127 const SMDSAbs_ElementType ElementType,
3128 SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
3129 throw (SALOME::SALOME_Exception)
3132 SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
3136 list<double> angles;
3137 for (int i = 0; i < Angles.length(); i++) {
3138 angles.push_back( Angles[i] );
3140 gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
3141 int nbOldGroups = myMesh->NbGroup();
3143 if ( Path->_is_nil() ) {
3144 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3148 TIDSortedElemSet elements, copyElements;
3149 arrayToSet(IDsOfElements, getMeshDS(), elements, ElementType);
3151 TIDSortedElemSet* workElements = &elements;
3153 if ( myIsPreviewMode )
3155 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
3156 getPreviewMesh( SMDSAbs_Face )->Copy( elements, copyElements, select, avoid );
3157 workElements = & copyElements;
3161 ::SMESH_MeshEditor::Extrusion_Error error;
3163 if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path ))
3166 SMDS_MeshNode* aNodeStart =
3167 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
3168 if ( !aNodeStart ) {
3169 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3172 error = getEditor().ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
3173 HasAngles, angles, LinearVariation,
3174 HasRefPoint, refPnt, MakeGroups );
3175 declareMeshModified( /*isReComputeSafe=*/true );
3177 else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
3180 SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
3181 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
3182 SMDS_MeshNode* aNodeStart =
3183 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
3184 if ( !aNodeStart ) {
3185 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3188 SMESH_subMesh* aSubMesh =
3189 aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
3190 error = getEditor().ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
3191 HasAngles, angles, LinearVariation,
3192 HasRefPoint, refPnt, MakeGroups );
3193 declareMeshModified( /*isReComputeSafe=*/true );
3195 else if ( SMESH::DownCast<SMESH_Group_i*>( Path ))
3197 // path as group of 1D elements
3203 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3207 Error = convExtrError( error );
3210 list<int> groupIDs = myMesh->GetGroupIds();
3211 list<int>::iterator newBegin = groupIDs.begin();
3212 std::advance( newBegin, nbOldGroups ); // skip old groups
3213 groupIDs.erase( groupIDs.begin(), newBegin );
3214 return getGroups( & groupIDs );
3218 SMESH_CATCH( SMESH::throwCorbaException );
3222 //=======================================================================
3223 //function : ExtrusionAlongPath
3225 //=======================================================================
3227 SMESH::SMESH_MeshEditor::Extrusion_Error
3228 SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements,
3229 SMESH::SMESH_Mesh_ptr thePathMesh,
3230 GEOM::GEOM_Object_ptr thePathShape,
3231 CORBA::Long theNodeStart,
3232 CORBA::Boolean theHasAngles,
3233 const SMESH::double_array & theAngles,
3234 CORBA::Boolean theHasRefPoint,
3235 const SMESH::PointStruct & theRefPoint)
3236 throw (SALOME::SALOME_Exception)
3238 MESSAGE("ExtrusionAlongPath");
3239 if ( !myIsPreviewMode ) {
3240 TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
3241 << theIDsOfElements << ", "
3242 << thePathMesh << ", "
3243 << thePathShape << ", "
3244 << theNodeStart << ", "
3245 << theHasAngles << ", "
3246 << theAngles << ", "
3247 << theHasRefPoint << ", "
3248 << "SMESH.PointStruct( "
3249 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3250 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3251 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3253 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3254 extrusionAlongPath( theIDsOfElements,
3267 //=======================================================================
3268 //function : ExtrusionAlongPathObject
3270 //=======================================================================
3272 SMESH::SMESH_MeshEditor::Extrusion_Error
3273 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject,
3274 SMESH::SMESH_Mesh_ptr thePathMesh,
3275 GEOM::GEOM_Object_ptr thePathShape,
3276 CORBA::Long theNodeStart,
3277 CORBA::Boolean theHasAngles,
3278 const SMESH::double_array & theAngles,
3279 CORBA::Boolean theHasRefPoint,
3280 const SMESH::PointStruct & theRefPoint)
3281 throw (SALOME::SALOME_Exception)
3283 if ( !myIsPreviewMode ) {
3284 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
3285 << theObject << ", "
3286 << thePathMesh << ", "
3287 << thePathShape << ", "
3288 << theNodeStart << ", "
3289 << theHasAngles << ", "
3290 << theAngles << ", "
3291 << theHasRefPoint << ", "
3292 << "SMESH.PointStruct( "
3293 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3294 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3295 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3297 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3298 prepareIdSource( theObject );
3299 SMESH::long_array_var anElementsId = theObject->GetIDs();
3300 extrusionAlongPath( anElementsId,
3313 //=======================================================================
3314 //function : ExtrusionAlongPathObject1D
3316 //=======================================================================
3318 SMESH::SMESH_MeshEditor::Extrusion_Error
3319 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject,
3320 SMESH::SMESH_Mesh_ptr thePathMesh,
3321 GEOM::GEOM_Object_ptr thePathShape,
3322 CORBA::Long theNodeStart,
3323 CORBA::Boolean theHasAngles,
3324 const SMESH::double_array & theAngles,
3325 CORBA::Boolean theHasRefPoint,
3326 const SMESH::PointStruct & theRefPoint)
3327 throw (SALOME::SALOME_Exception)
3329 if ( !myIsPreviewMode ) {
3330 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
3331 << theObject << ", "
3332 << thePathMesh << ", "
3333 << thePathShape << ", "
3334 << theNodeStart << ", "
3335 << theHasAngles << ", "
3336 << theAngles << ", "
3337 << theHasRefPoint << ", "
3338 << "SMESH.PointStruct( "
3339 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3340 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3341 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3343 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3344 prepareIdSource( theObject );
3345 SMESH::long_array_var anElementsId = theObject->GetIDs();
3346 extrusionAlongPath( anElementsId,
3360 //=======================================================================
3361 //function : ExtrusionAlongPathObject2D
3363 //=======================================================================
3365 SMESH::SMESH_MeshEditor::Extrusion_Error
3366 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject,
3367 SMESH::SMESH_Mesh_ptr thePathMesh,
3368 GEOM::GEOM_Object_ptr thePathShape,
3369 CORBA::Long theNodeStart,
3370 CORBA::Boolean theHasAngles,
3371 const SMESH::double_array & theAngles,
3372 CORBA::Boolean theHasRefPoint,
3373 const SMESH::PointStruct & theRefPoint)
3374 throw (SALOME::SALOME_Exception)
3376 if ( !myIsPreviewMode ) {
3377 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
3378 << theObject << ", "
3379 << thePathMesh << ", "
3380 << thePathShape << ", "
3381 << theNodeStart << ", "
3382 << theHasAngles << ", "
3383 << theAngles << ", "
3384 << theHasRefPoint << ", "
3385 << "SMESH.PointStruct( "
3386 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3387 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3388 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3390 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3391 prepareIdSource( theObject );
3392 SMESH::long_array_var anElementsId = theObject->GetIDs();
3393 extrusionAlongPath( anElementsId,
3408 //=======================================================================
3409 //function : ExtrusionAlongPathMakeGroups
3411 //=======================================================================
3413 SMESH::ListOfGroups*
3414 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theIDsOfElements,
3415 SMESH::SMESH_Mesh_ptr thePathMesh,
3416 GEOM::GEOM_Object_ptr thePathShape,
3417 CORBA::Long theNodeStart,
3418 CORBA::Boolean theHasAngles,
3419 const SMESH::double_array& theAngles,
3420 CORBA::Boolean theHasRefPoint,
3421 const SMESH::PointStruct& theRefPoint,
3422 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3423 throw (SALOME::SALOME_Exception)
3425 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3427 SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements,