1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_MeshEditor_i.cxx
23 // Author : Nicolas REJNERI
30 // A macro used in SMESH_TryCatch.hxx,
31 // it re-raises a CORBA SALOME exception thrown by SMESH_MeshEditor_i and caught by SMESH_CATCH
32 #define SMY_OWN_CATCH \
33 catch ( SALOME::SALOME_Exception & e ) { throw e; }
35 #include "SMESH_MeshEditor_i.hxx"
37 #include "SMDS_EdgePosition.hxx"
38 #include "SMDS_ElemIterator.hxx"
39 #include "SMDS_FacePosition.hxx"
40 #include "SMDS_IteratorOnIterators.hxx"
41 #include "SMDS_LinearEdge.hxx"
42 #include "SMDS_Mesh0DElement.hxx"
43 #include "SMDS_MeshFace.hxx"
44 #include "SMDS_MeshVolume.hxx"
45 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
46 #include "SMDS_SetIterator.hxx"
47 #include "SMDS_VolumeTool.hxx"
48 #include "SMESHDS_Group.hxx"
49 #include "SMESHDS_GroupOnGeom.hxx"
50 #include "SMESH_ControlsDef.hxx"
51 #include "SMESH_Filter_i.hxx"
52 #include "SMESH_Gen_i.hxx"
53 #include "SMESH_Group.hxx"
54 #include "SMESH_Group_i.hxx"
55 #include "SMESH_MeshAlgos.hxx"
56 #include "SMESH_MeshPartDS.hxx"
57 #include "SMESH_MesherHelper.hxx"
58 #include "SMESH_PythonDump.hxx"
59 #include "SMESH_subMeshEventListener.hxx"
60 #include "SMESH_subMesh_i.hxx"
62 #include <utilities.h>
63 #include <Utils_ExceptHandlers.hxx>
64 #include <Utils_CorbaException.hxx>
65 #include <SALOMEDS_wrap.hxx>
66 #include <SALOME_GenericObj_i.hh>
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 const SMESH::PointStruct & startHexPoint,
2033 const SMESH::DirStruct& facetToSplitNormal,
2034 CORBA::Short methodFlags,
2035 CORBA::Boolean allDomains)
2036 throw (SALOME::SALOME_Exception)
2040 prepareIdSource( elems );
2042 gp_Ax1 facetNorm( gp_Pnt( startHexPoint.x,
2045 gp_Dir( facetToSplitNormal.PS.x,
2046 facetToSplitNormal.PS.y,
2047 facetToSplitNormal.PS.z ));
2048 TIDSortedElemSet elemSet;
2049 SMESH::long_array_var anElementsId = elems->GetIDs();
2050 SMDS_MeshElement::GeomFilter filter( SMDSGeom_HEXA );
2051 arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume, &filter );
2053 ::SMESH_MeshEditor::TFacetOfElem elemFacets;
2054 while ( !elemSet.empty() )
2056 getEditor().GetHexaFacetsToSplit( elemSet, facetNorm, elemFacets );
2060 ::SMESH_MeshEditor::TFacetOfElem::iterator ef = elemFacets.begin();
2061 for ( ; ef != elemFacets.end(); ++ef )
2062 elemSet.erase( ef->first );
2065 if ( methodFlags == 2 )
2066 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_4_PRISMS );
2068 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_2_PRISMS );
2070 getEditor().SplitVolumes( elemFacets, int( methodFlags ));
2071 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2073 TPythonDump() << this << ".SplitHexahedraIntoPrisms( "
2075 << startHexPoint << ", "
2076 << facetToSplitNormal<< ", "
2077 << methodFlags<< ", "
2078 << allDomains << " )";
2080 SMESH_CATCH( SMESH::throwCorbaException );
2083 //=======================================================================
2086 //=======================================================================
2089 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
2090 const SMESH::long_array & IDsOfFixedNodes,
2091 CORBA::Long MaxNbOfIterations,
2092 CORBA::Double MaxAspectRatio,
2093 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2094 throw (SALOME::SALOME_Exception)
2096 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2097 MaxAspectRatio, Method, false );
2101 //=======================================================================
2102 //function : SmoothParametric
2104 //=======================================================================
2107 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
2108 const SMESH::long_array & IDsOfFixedNodes,
2109 CORBA::Long MaxNbOfIterations,
2110 CORBA::Double MaxAspectRatio,
2111 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2112 throw (SALOME::SALOME_Exception)
2114 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2115 MaxAspectRatio, Method, true );
2119 //=======================================================================
2120 //function : SmoothObject
2122 //=======================================================================
2125 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
2126 const SMESH::long_array & IDsOfFixedNodes,
2127 CORBA::Long MaxNbOfIterations,
2128 CORBA::Double MaxAspectRatio,
2129 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2130 throw (SALOME::SALOME_Exception)
2132 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2133 MaxAspectRatio, Method, false);
2137 //=======================================================================
2138 //function : SmoothParametricObject
2140 //=======================================================================
2143 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
2144 const SMESH::long_array & IDsOfFixedNodes,
2145 CORBA::Long MaxNbOfIterations,
2146 CORBA::Double MaxAspectRatio,
2147 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2148 throw (SALOME::SALOME_Exception)
2150 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2151 MaxAspectRatio, Method, true);
2155 //=============================================================================
2159 //=============================================================================
2162 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
2163 const SMESH::long_array & IDsOfFixedNodes,
2164 CORBA::Long MaxNbOfIterations,
2165 CORBA::Double MaxAspectRatio,
2166 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2168 throw (SALOME::SALOME_Exception)
2173 SMESHDS_Mesh* aMesh = getMeshDS();
2175 TIDSortedElemSet elements;
2176 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
2178 set<const SMDS_MeshNode*> fixedNodes;
2179 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
2180 CORBA::Long index = IDsOfFixedNodes[i];
2181 const SMDS_MeshNode * node = aMesh->FindNode(index);
2183 fixedNodes.insert( node );
2185 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
2186 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
2187 method = ::SMESH_MeshEditor::CENTROIDAL;
2189 getEditor().Smooth(elements, fixedNodes, method,
2190 MaxNbOfIterations, MaxAspectRatio, IsParametric );
2192 declareMeshModified( /*isReComputeSafe=*/true ); // does not prevent re-compute
2194 // Update Python script
2195 TPythonDump() << "isDone = " << this << "."
2196 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
2197 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
2198 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2199 << "SMESH.SMESH_MeshEditor."
2200 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2201 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2205 SMESH_CATCH( SMESH::throwCorbaException );
2209 //=============================================================================
2213 //=============================================================================
2216 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
2217 const SMESH::long_array & IDsOfFixedNodes,
2218 CORBA::Long MaxNbOfIterations,
2219 CORBA::Double MaxAspectRatio,
2220 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2222 throw (SALOME::SALOME_Exception)
2227 TPythonDump aTPythonDump; // suppress dump in smooth()
2229 prepareIdSource( theObject );
2230 SMESH::long_array_var anElementsId = theObject->GetIDs();
2231 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
2232 MaxAspectRatio, Method, IsParametric);
2234 // Update Python script
2235 aTPythonDump << "isDone = " << this << "."
2236 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
2237 << theObject << ", " << IDsOfFixedNodes << ", "
2238 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2239 << "SMESH.SMESH_MeshEditor."
2240 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2241 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2245 SMESH_CATCH( SMESH::throwCorbaException );
2249 //=============================================================================
2253 //=============================================================================
2255 void SMESH_MeshEditor_i::RenumberNodes()
2256 throw (SALOME::SALOME_Exception)
2259 // Update Python script
2260 TPythonDump() << this << ".RenumberNodes()";
2262 getMeshDS()->Renumber( true );
2264 SMESH_CATCH( SMESH::throwCorbaException );
2267 //=============================================================================
2271 //=============================================================================
2273 void SMESH_MeshEditor_i::RenumberElements()
2274 throw (SALOME::SALOME_Exception)
2277 // Update Python script
2278 TPythonDump() << this << ".RenumberElements()";
2280 getMeshDS()->Renumber( false );
2282 SMESH_CATCH( SMESH::throwCorbaException );
2285 //=======================================================================
2287 * \brief Return groups by their IDs
2289 //=======================================================================
2291 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
2292 throw (SALOME::SALOME_Exception)
2297 myMesh_i->CreateGroupServants();
2298 return myMesh_i->GetGroups( *groupIDs );
2300 SMESH_CATCH( SMESH::throwCorbaException );
2304 //=======================================================================
2305 //function : rotationSweep
2307 //=======================================================================
2309 SMESH::ListOfGroups*
2310 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
2311 const SMESH::AxisStruct & theAxis,
2312 CORBA::Double theAngleInRadians,
2313 CORBA::Long theNbOfSteps,
2314 CORBA::Double theTolerance,
2315 const bool theMakeGroups,
2316 const SMDSAbs_ElementType theElementType)
2317 throw (SALOME::SALOME_Exception)
2322 TIDSortedElemSet inElements, copyElements;
2323 arrayToSet(theIDsOfElements, getMeshDS(), inElements, theElementType);
2325 TIDSortedElemSet* workElements = & inElements;
2326 bool makeWalls=true;
2327 if ( myIsPreviewMode )
2329 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2330 getPreviewMesh( SMDSAbs_Face )->Copy( inElements, copyElements, select, avoid );
2331 workElements = & copyElements;
2332 //makeWalls = false;
2335 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
2336 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
2338 ::SMESH_MeshEditor::PGroupIDs groupIds =
2339 getEditor().RotationSweep (*workElements, Ax1, theAngleInRadians,
2340 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
2342 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2344 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2346 SMESH_CATCH( SMESH::throwCorbaException );
2350 //=======================================================================
2351 //function : RotationSweep
2353 //=======================================================================
2355 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
2356 const SMESH::AxisStruct & theAxis,
2357 CORBA::Double theAngleInRadians,
2358 CORBA::Long theNbOfSteps,
2359 CORBA::Double theTolerance)
2360 throw (SALOME::SALOME_Exception)
2362 if ( !myIsPreviewMode ) {
2363 TPythonDump() << this << ".RotationSweep( "
2364 << theIDsOfElements << ", "
2366 << TVar( theAngleInRadians ) << ", "
2367 << TVar( theNbOfSteps ) << ", "
2368 << TVar( theTolerance ) << " )";
2370 rotationSweep(theIDsOfElements,
2378 //=======================================================================
2379 //function : RotationSweepMakeGroups
2381 //=======================================================================
2383 SMESH::ListOfGroups*
2384 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2385 const SMESH::AxisStruct& theAxis,
2386 CORBA::Double theAngleInRadians,
2387 CORBA::Long theNbOfSteps,
2388 CORBA::Double theTolerance)
2389 throw (SALOME::SALOME_Exception)
2391 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2393 SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
2399 if (!myIsPreviewMode) {
2400 dumpGroupsList(aPythonDump, aGroups);
2401 aPythonDump << this << ".RotationSweepMakeGroups( "
2402 << theIDsOfElements << ", "
2404 << TVar( theAngleInRadians ) << ", "
2405 << TVar( theNbOfSteps ) << ", "
2406 << TVar( theTolerance ) << " )";
2411 //=======================================================================
2412 //function : RotationSweepObject
2414 //=======================================================================
2416 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2417 const SMESH::AxisStruct & theAxis,
2418 CORBA::Double theAngleInRadians,
2419 CORBA::Long theNbOfSteps,
2420 CORBA::Double theTolerance)
2421 throw (SALOME::SALOME_Exception)
2423 if ( !myIsPreviewMode ) {
2424 TPythonDump() << this << ".RotationSweepObject( "
2425 << theObject << ", "
2427 << theAngleInRadians << ", "
2428 << theNbOfSteps << ", "
2429 << theTolerance << " )";
2431 prepareIdSource( theObject );
2432 SMESH::long_array_var anElementsId = theObject->GetIDs();
2433 rotationSweep(anElementsId,
2441 //=======================================================================
2442 //function : RotationSweepObject1D
2444 //=======================================================================
2446 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2447 const SMESH::AxisStruct & theAxis,
2448 CORBA::Double theAngleInRadians,
2449 CORBA::Long theNbOfSteps,
2450 CORBA::Double theTolerance)
2451 throw (SALOME::SALOME_Exception)
2453 if ( !myIsPreviewMode ) {
2454 TPythonDump() << this << ".RotationSweepObject1D( "
2455 << theObject << ", "
2457 << TVar( theAngleInRadians ) << ", "
2458 << TVar( theNbOfSteps ) << ", "
2459 << TVar( theTolerance ) << " )";
2461 prepareIdSource( theObject );
2462 SMESH::long_array_var anElementsId = theObject->GetIDs();
2463 rotationSweep(anElementsId,
2472 //=======================================================================
2473 //function : RotationSweepObject2D
2475 //=======================================================================
2477 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2478 const SMESH::AxisStruct & theAxis,
2479 CORBA::Double theAngleInRadians,
2480 CORBA::Long theNbOfSteps,
2481 CORBA::Double theTolerance)
2482 throw (SALOME::SALOME_Exception)
2484 if ( !myIsPreviewMode ) {
2485 TPythonDump() << this << ".RotationSweepObject2D( "
2486 << theObject << ", "
2488 << TVar( theAngleInRadians ) << ", "
2489 << TVar( theNbOfSteps ) << ", "
2490 << TVar( theTolerance ) << " )";
2492 prepareIdSource( theObject );
2493 SMESH::long_array_var anElementsId = theObject->GetIDs();
2494 rotationSweep(anElementsId,
2503 //=======================================================================
2504 //function : RotationSweepObjectMakeGroups
2506 //=======================================================================
2508 SMESH::ListOfGroups*
2509 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2510 const SMESH::AxisStruct& theAxis,
2511 CORBA::Double theAngleInRadians,
2512 CORBA::Long theNbOfSteps,
2513 CORBA::Double theTolerance)
2514 throw (SALOME::SALOME_Exception)
2516 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2518 prepareIdSource( theObject );
2519 SMESH::long_array_var anElementsId = theObject->GetIDs();
2520 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2526 if (!myIsPreviewMode) {
2527 dumpGroupsList(aPythonDump, aGroups);
2528 aPythonDump << this << ".RotationSweepObjectMakeGroups( "
2529 << theObject << ", "
2531 << theAngleInRadians << ", "
2532 << theNbOfSteps << ", "
2533 << theTolerance << " )";
2538 //=======================================================================
2539 //function : RotationSweepObject1DMakeGroups
2541 //=======================================================================
2543 SMESH::ListOfGroups*
2544 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2545 const SMESH::AxisStruct& theAxis,
2546 CORBA::Double theAngleInRadians,
2547 CORBA::Long theNbOfSteps,
2548 CORBA::Double theTolerance)
2549 throw (SALOME::SALOME_Exception)
2551 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2553 prepareIdSource( theObject );
2554 SMESH::long_array_var anElementsId = theObject->GetIDs();
2555 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2562 if (!myIsPreviewMode) {
2563 dumpGroupsList(aPythonDump, aGroups);
2564 aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
2565 << theObject << ", "
2567 << TVar( theAngleInRadians ) << ", "
2568 << TVar( theNbOfSteps ) << ", "
2569 << TVar( theTolerance ) << " )";
2574 //=======================================================================
2575 //function : RotationSweepObject2DMakeGroups
2577 //=======================================================================
2579 SMESH::ListOfGroups*
2580 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2581 const SMESH::AxisStruct& theAxis,
2582 CORBA::Double theAngleInRadians,
2583 CORBA::Long theNbOfSteps,
2584 CORBA::Double theTolerance)
2585 throw (SALOME::SALOME_Exception)
2587 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2589 prepareIdSource( theObject );
2590 SMESH::long_array_var anElementsId = theObject->GetIDs();
2591 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2598 if (!myIsPreviewMode) {
2599 dumpGroupsList(aPythonDump, aGroups);
2600 aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
2601 << theObject << ", "
2603 << TVar( theAngleInRadians ) << ", "
2604 << TVar( theNbOfSteps ) << ", "
2605 << TVar( theTolerance ) << " )";
2611 //=======================================================================
2612 //function : extrusionSweep
2614 //=======================================================================
2616 SMESH::ListOfGroups*
2617 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
2618 const SMESH::DirStruct & theStepVector,
2619 CORBA::Long theNbOfSteps,
2621 const SMDSAbs_ElementType theElementType)
2622 throw (SALOME::SALOME_Exception)
2627 TIDSortedElemSet elements, copyElements;
2628 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
2630 const SMESH::PointStruct * P = &theStepVector.PS;
2631 gp_Vec stepVec( P->x, P->y, P->z );
2633 TIDSortedElemSet* workElements = & elements;
2635 SMDSAbs_ElementType aType = SMDSAbs_Face;
2636 if (theElementType == SMDSAbs_Node)
2638 aType = SMDSAbs_Edge;
2640 if ( myIsPreviewMode ) {
2641 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2642 getPreviewMesh( aType )->Copy( elements, copyElements, select, avoid );
2643 workElements = & copyElements;
2644 theMakeGroups = false;
2647 ::SMESH_MeshEditor::TTElemOfElemListMap aHystory;
2648 ::SMESH_MeshEditor::PGroupIDs groupIds =
2649 getEditor().ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
2651 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2653 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2655 SMESH_CATCH( SMESH::throwCorbaException );
2659 //=======================================================================
2660 //function : ExtrusionSweep
2662 //=======================================================================
2664 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
2665 const SMESH::DirStruct & theStepVector,
2666 CORBA::Long theNbOfSteps)
2667 throw (SALOME::SALOME_Exception)
2669 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
2670 if (!myIsPreviewMode) {
2671 TPythonDump() << this << ".ExtrusionSweep( "
2672 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps) << " )";
2676 //=======================================================================
2677 //function : ExtrusionSweep0D
2679 //=======================================================================
2681 void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElements,
2682 const SMESH::DirStruct & theStepVector,
2683 CORBA::Long theNbOfSteps)
2684 throw (SALOME::SALOME_Exception)
2686 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2687 if (!myIsPreviewMode) {
2688 TPythonDump() << this << ".ExtrusionSweep0D( "
2689 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps)<< " )";
2693 //=======================================================================
2694 //function : ExtrusionSweepObject
2696 //=======================================================================
2698 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2699 const SMESH::DirStruct & theStepVector,
2700 CORBA::Long theNbOfSteps)
2701 throw (SALOME::SALOME_Exception)
2703 prepareIdSource( theObject );
2704 SMESH::long_array_var anElementsId = theObject->GetIDs();
2705 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
2706 if (!myIsPreviewMode) {
2707 TPythonDump() << this << ".ExtrusionSweepObject( "
2708 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
2712 //=======================================================================
2713 //function : ExtrusionSweepObject0D
2715 //=======================================================================
2717 void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObject,
2718 const SMESH::DirStruct & theStepVector,
2719 CORBA::Long theNbOfSteps)
2720 throw (SALOME::SALOME_Exception)
2722 prepareIdSource( theObject );
2723 SMESH::long_array_var anElementsId = theObject->GetIDs();
2724 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2725 if ( !myIsPreviewMode ) {
2726 TPythonDump() << this << ".ExtrusionSweepObject0D( "
2727 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2731 //=======================================================================
2732 //function : ExtrusionSweepObject1D
2734 //=======================================================================
2736 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2737 const SMESH::DirStruct & theStepVector,
2738 CORBA::Long theNbOfSteps)
2739 throw (SALOME::SALOME_Exception)
2741 prepareIdSource( theObject );
2742 SMESH::long_array_var anElementsId = theObject->GetIDs();
2743 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
2744 if ( !myIsPreviewMode ) {
2745 TPythonDump() << this << ".ExtrusionSweepObject1D( "
2746 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2750 //=======================================================================
2751 //function : ExtrusionSweepObject2D
2753 //=======================================================================
2755 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2756 const SMESH::DirStruct & theStepVector,
2757 CORBA::Long theNbOfSteps)
2758 throw (SALOME::SALOME_Exception)
2760 prepareIdSource( theObject );
2761 SMESH::long_array_var anElementsId = theObject->GetIDs();
2762 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
2763 if ( !myIsPreviewMode ) {
2764 TPythonDump() << this << ".ExtrusionSweepObject2D( "
2765 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2769 //=======================================================================
2770 //function : ExtrusionSweepMakeGroups
2772 //=======================================================================
2774 SMESH::ListOfGroups*
2775 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2776 const SMESH::DirStruct& theStepVector,
2777 CORBA::Long theNbOfSteps)
2778 throw (SALOME::SALOME_Exception)
2780 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2782 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
2784 if (!myIsPreviewMode) {
2785 dumpGroupsList(aPythonDump, aGroups);
2786 aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
2787 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2792 //=======================================================================
2793 //function : ExtrusionSweepMakeGroups0D
2795 //=======================================================================
2797 SMESH::ListOfGroups*
2798 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups0D(const SMESH::long_array& theIDsOfElements,
2799 const SMESH::DirStruct& theStepVector,
2800 CORBA::Long theNbOfSteps)
2801 throw (SALOME::SALOME_Exception)
2803 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2805 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true,SMDSAbs_Node);
2807 if (!myIsPreviewMode) {
2808 dumpGroupsList(aPythonDump, aGroups);
2809 aPythonDump << this << ".ExtrusionSweepMakeGroups0D( " << theIDsOfElements
2810 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2815 //=======================================================================
2816 //function : ExtrusionSweepObjectMakeGroups
2818 //=======================================================================
2820 SMESH::ListOfGroups*
2821 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2822 const SMESH::DirStruct& theStepVector,
2823 CORBA::Long theNbOfSteps)
2824 throw (SALOME::SALOME_Exception)
2826 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2828 prepareIdSource( theObject );
2829 SMESH::long_array_var anElementsId = theObject->GetIDs();
2830 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
2832 if (!myIsPreviewMode) {
2833 dumpGroupsList(aPythonDump, aGroups);
2834 aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
2835 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2840 //=======================================================================
2841 //function : ExtrusionSweepObject0DMakeGroups
2843 //=======================================================================
2845 SMESH::ListOfGroups*
2846 SMESH_MeshEditor_i::ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2847 const SMESH::DirStruct& theStepVector,
2848 CORBA::Long theNbOfSteps)
2849 throw (SALOME::SALOME_Exception)
2851 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2853 prepareIdSource( theObject );
2854 SMESH::long_array_var anElementsId = theObject->GetIDs();
2855 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2856 theNbOfSteps, true, SMDSAbs_Node);
2857 if (!myIsPreviewMode) {
2858 dumpGroupsList(aPythonDump, aGroups);
2859 aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject
2860 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2865 //=======================================================================
2866 //function : ExtrusionSweepObject1DMakeGroups
2868 //=======================================================================
2870 SMESH::ListOfGroups*
2871 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2872 const SMESH::DirStruct& theStepVector,
2873 CORBA::Long theNbOfSteps)
2874 throw (SALOME::SALOME_Exception)
2876 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2878 prepareIdSource( theObject );
2879 SMESH::long_array_var anElementsId = theObject->GetIDs();
2880 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2881 theNbOfSteps, true, SMDSAbs_Edge);
2882 if (!myIsPreviewMode) {
2883 dumpGroupsList(aPythonDump, aGroups);
2884 aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
2885 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2890 //=======================================================================
2891 //function : ExtrusionSweepObject2DMakeGroups
2893 //=======================================================================
2895 SMESH::ListOfGroups*
2896 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2897 const SMESH::DirStruct& theStepVector,
2898 CORBA::Long theNbOfSteps)
2899 throw (SALOME::SALOME_Exception)
2901 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2903 prepareIdSource( theObject );
2904 SMESH::long_array_var anElementsId = theObject->GetIDs();
2905 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2906 theNbOfSteps, true, SMDSAbs_Face);
2907 if (!myIsPreviewMode) {
2908 dumpGroupsList(aPythonDump, aGroups);
2909 aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
2910 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2916 //=======================================================================
2917 //function : advancedExtrusion
2919 //=======================================================================
2921 SMESH::ListOfGroups*
2922 SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
2923 const SMESH::DirStruct & theStepVector,
2924 CORBA::Long theNbOfSteps,
2925 CORBA::Long theExtrFlags,
2926 CORBA::Double theSewTolerance,
2927 const bool theMakeGroups)
2928 throw (SALOME::SALOME_Exception)
2933 TIDSortedElemSet elements;
2934 arrayToSet(theIDsOfElements, getMeshDS(), elements);
2936 const SMESH::PointStruct * P = &theStepVector.PS;
2937 gp_Vec stepVec( P->x, P->y, P->z );
2939 ::SMESH_MeshEditor::TTElemOfElemListMap aHystory;
2940 ::SMESH_MeshEditor::PGroupIDs groupIds =
2941 getEditor().ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
2942 theMakeGroups, theExtrFlags, theSewTolerance);
2944 declareMeshModified( /*isReComputeSafe=*/true );
2946 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2948 SMESH_CATCH( SMESH::throwCorbaException );
2952 //=======================================================================
2953 //function : AdvancedExtrusion
2955 //=======================================================================
2957 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2958 const SMESH::DirStruct & theStepVector,
2959 CORBA::Long theNbOfSteps,
2960 CORBA::Long theExtrFlags,
2961 CORBA::Double theSewTolerance)
2962 throw (SALOME::SALOME_Exception)
2964 if ( !myIsPreviewMode ) {
2965 TPythonDump() << "stepVector = " << theStepVector;
2966 TPythonDump() << this << ".AdvancedExtrusion("
2969 << theNbOfSteps << ","
2970 << theExtrFlags << ", "
2971 << theSewTolerance << " )";
2973 advancedExtrusion( theIDsOfElements,
2981 //=======================================================================
2982 //function : AdvancedExtrusionMakeGroups
2984 //=======================================================================
2985 SMESH::ListOfGroups*
2986 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
2987 const SMESH::DirStruct& theStepVector,
2988 CORBA::Long theNbOfSteps,
2989 CORBA::Long theExtrFlags,
2990 CORBA::Double theSewTolerance)
2991 throw (SALOME::SALOME_Exception)
2993 if (!myIsPreviewMode) {
2994 TPythonDump() << "stepVector = " << theStepVector;
2996 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2998 SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
3005 if (!myIsPreviewMode) {
3006 dumpGroupsList(aPythonDump, aGroups);
3007 aPythonDump << this << ".AdvancedExtrusionMakeGroups("
3010 << theNbOfSteps << ","
3011 << theExtrFlags << ", "
3012 << theSewTolerance << " )";
3018 //================================================================================
3020 * \brief Convert extrusion error to IDL enum
3022 //================================================================================
3024 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
3026 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
3030 RETCASE( EXTR_NO_ELEMENTS );
3031 RETCASE( EXTR_PATH_NOT_EDGE );
3032 RETCASE( EXTR_BAD_PATH_SHAPE );
3033 RETCASE( EXTR_BAD_STARTING_NODE );
3034 RETCASE( EXTR_BAD_ANGLES_NUMBER );
3035 RETCASE( EXTR_CANT_GET_TANGENT );
3037 return SMESH::SMESH_MeshEditor::EXTR_OK;
3041 //=======================================================================
3042 //function : extrusionAlongPath
3044 //=======================================================================
3045 SMESH::ListOfGroups*
3046 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfElements,
3047 SMESH::SMESH_Mesh_ptr thePathMesh,
3048 GEOM::GEOM_Object_ptr thePathShape,
3049 CORBA::Long theNodeStart,
3050 CORBA::Boolean theHasAngles,
3051 const SMESH::double_array & theAngles,
3052 CORBA::Boolean theHasRefPoint,
3053 const SMESH::PointStruct & theRefPoint,
3054 const bool theMakeGroups,
3055 SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
3056 const SMDSAbs_ElementType theElementType)
3057 throw (SALOME::SALOME_Exception)
3060 MESSAGE("extrusionAlongPath");
3063 if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
3064 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3067 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3069 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3070 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3072 if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
3073 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3077 SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
3079 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3083 TIDSortedElemSet elements;
3084 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
3086 list<double> angles;
3087 for (int i = 0; i < theAngles.length(); i++) {
3088 angles.push_back( theAngles[i] );
3091 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
3093 int nbOldGroups = myMesh->NbGroup();
3095 ::SMESH_MeshEditor::Extrusion_Error error =
3096 getEditor().ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
3097 theHasAngles, angles, false,
3098 theHasRefPoint, refPnt, theMakeGroups );
3100 declareMeshModified( /*isReComputeSafe=*/true );
3101 theError = convExtrError( error );
3103 if ( theMakeGroups ) {
3104 list<int> groupIDs = myMesh->GetGroupIds();
3105 list<int>::iterator newBegin = groupIDs.begin();
3106 std::advance( newBegin, nbOldGroups ); // skip old groups
3107 groupIDs.erase( groupIDs.begin(), newBegin );
3108 return getGroups( & groupIDs );
3112 SMESH_CATCH( SMESH::throwCorbaException );
3116 //=======================================================================
3117 //function : extrusionAlongPathX
3119 //=======================================================================
3121 SMESH::ListOfGroups*
3122 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements,
3123 SMESH::SMESH_IDSource_ptr Path,
3124 CORBA::Long NodeStart,
3125 CORBA::Boolean HasAngles,
3126 const SMESH::double_array& Angles,
3127 CORBA::Boolean LinearVariation,
3128 CORBA::Boolean HasRefPoint,
3129 const SMESH::PointStruct& RefPoint,
3131 const SMDSAbs_ElementType ElementType,
3132 SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
3133 throw (SALOME::SALOME_Exception)
3136 SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
3140 list<double> angles;
3141 for (int i = 0; i < Angles.length(); i++) {
3142 angles.push_back( Angles[i] );
3144 gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
3145 int nbOldGroups = myMesh->NbGroup();
3147 if ( Path->_is_nil() ) {
3148 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3152 TIDSortedElemSet elements, copyElements;
3153 arrayToSet(IDsOfElements, getMeshDS(), elements, ElementType);
3155 TIDSortedElemSet* workElements = &elements;
3157 if ( myIsPreviewMode )
3159 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
3160 getPreviewMesh( SMDSAbs_Face )->Copy( elements, copyElements, select, avoid );
3161 workElements = & copyElements;
3165 ::SMESH_MeshEditor::Extrusion_Error error;
3167 if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path ))
3170 SMDS_MeshNode* aNodeStart =
3171 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
3172 if ( !aNodeStart ) {
3173 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3176 error = getEditor().ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
3177 HasAngles, angles, LinearVariation,
3178 HasRefPoint, refPnt, MakeGroups );
3179 declareMeshModified( /*isReComputeSafe=*/true );
3181 else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
3184 SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
3185 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
3186 SMDS_MeshNode* aNodeStart =
3187 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
3188 if ( !aNodeStart ) {
3189 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3192 SMESH_subMesh* aSubMesh =
3193 aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
3194 error = getEditor().ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
3195 HasAngles, angles, LinearVariation,
3196 HasRefPoint, refPnt, MakeGroups );
3197 declareMeshModified( /*isReComputeSafe=*/true );
3199 else if ( SMESH::DownCast<SMESH_Group_i*>( Path ))
3201 // path as group of 1D elements
3207 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3211 Error = convExtrError( error );
3214 list<int> groupIDs = myMesh->GetGroupIds();
3215 list<int>::iterator newBegin = groupIDs.begin();
3216 std::advance( newBegin, nbOldGroups ); // skip old groups
3217 groupIDs.erase( groupIDs.begin(), newBegin );
3218 return getGroups( & groupIDs );
3222 SMESH_CATCH( SMESH::throwCorbaException );
3226 //=======================================================================
3227 //function : ExtrusionAlongPath
3229 //=======================================================================
3231 SMESH::SMESH_MeshEditor::Extrusion_Error
3232 SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements,
3233 SMESH::SMESH_Mesh_ptr thePathMesh,
3234 GEOM::GEOM_Object_ptr thePathShape,
3235 CORBA::Long theNodeStart,
3236 CORBA::Boolean theHasAngles,
3237 const SMESH::double_array & theAngles,
3238 CORBA::Boolean theHasRefPoint,
3239 const SMESH::PointStruct & theRefPoint)
3240 throw (SALOME::SALOME_Exception)
3242 MESSAGE("ExtrusionAlongPath");
3243 if ( !myIsPreviewMode ) {
3244 TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
3245 << theIDsOfElements << ", "
3246 << thePathMesh << ", "
3247 << thePathShape << ", "
3248 << theNodeStart << ", "
3249 << theHasAngles << ", "
3250 << theAngles << ", "
3251 << theHasRefPoint << ", "
3252 << "SMESH.PointStruct( "
3253 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3254 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3255 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3257 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3258 extrusionAlongPath( theIDsOfElements,
3271 //=======================================================================
3272 //function : ExtrusionAlongPathObject
3274 //=======================================================================
3276 SMESH::SMESH_MeshEditor::Extrusion_Error
3277 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject,
3278 SMESH::SMESH_Mesh_ptr thePathMesh,
3279 GEOM::GEOM_Object_ptr thePathShape,
3280 CORBA::Long theNodeStart,
3281 CORBA::Boolean theHasAngles,
3282 const SMESH::double_array & theAngles,
3283 CORBA::Boolean theHasRefPoint,
3284 const SMESH::PointStruct & theRefPoint)
3285 throw (SALOME::SALOME_Exception)
3287 if ( !myIsPreviewMode ) {
3288 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
3289 << theObject << ", "
3290 << thePathMesh << ", "
3291 << thePathShape << ", "
3292 << theNodeStart << ", "
3293 << theHasAngles << ", "
3294 << theAngles << ", "
3295 << theHasRefPoint << ", "
3296 << "SMESH.PointStruct( "
3297 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3298 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3299 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3301 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3302 prepareIdSource( theObject );
3303 SMESH::long_array_var anElementsId = theObject->GetIDs();
3304 extrusionAlongPath( anElementsId,
3317 //=======================================================================
3318 //function : ExtrusionAlongPathObject1D
3320 //=======================================================================
3322 SMESH::SMESH_MeshEditor::Extrusion_Error
3323 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject,
3324 SMESH::SMESH_Mesh_ptr thePathMesh,
3325 GEOM::GEOM_Object_ptr thePathShape,
3326 CORBA::Long theNodeStart,
3327 CORBA::Boolean theHasAngles,
3328 const SMESH::double_array & theAngles,
3329 CORBA::Boolean theHasRefPoint,
3330 const SMESH::PointStruct & theRefPoint)
3331 throw (SALOME::SALOME_Exception)
3333 if ( !myIsPreviewMode ) {
3334 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
3335 << theObject << ", "
3336 << thePathMesh << ", "
3337 << thePathShape << ", "
3338 << theNodeStart << ", "
3339 << theHasAngles << ", "
3340 << theAngles << ", "
3341 << theHasRefPoint << ", "
3342 << "SMESH.PointStruct( "
3343 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3344 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3345 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3347 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3348 prepareIdSource( theObject );
3349 SMESH::long_array_var anElementsId = theObject->GetIDs();
3350 extrusionAlongPath( anElementsId,
3364 //=======================================================================
3365 //function : ExtrusionAlongPathObject2D
3367 //=======================================================================
3369 SMESH::SMESH_MeshEditor::Extrusion_Error
3370 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject,
3371 SMESH::SMESH_Mesh_ptr thePathMesh,
3372 GEOM::GEOM_Object_ptr thePathShape,
3373 CORBA::Long theNodeStart,
3374 CORBA::Boolean theHasAngles,
3375 const SMESH::double_array & theAngles,
3376 CORBA::Boolean theHasRefPoint,
3377 const SMESH::PointStruct & theRefPoint)
3378 throw (SALOME::SALOME_Exception)
3380 if ( !myIsPreviewMode ) {
3381 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
3382 << theObject << ", "
3383 << thePathMesh << ", "
3384 << thePathShape << ", "
3385 << theNodeStart << ", "
3386 << theHasAngles << ", "
3387 << theAngles << ", "
3388 << theHasRefPoint << ", "
3389 << "SMESH.PointStruct( "
3390 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3391 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3392 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3394 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3395 prepareIdSource( theObject );
3396 SMESH::long_array_var anElementsId = theObject->GetIDs();
3397 extrusionAlongPath( anElementsId,
3412 //=======================================================================
3413 //function : ExtrusionAlongPathMakeGroups
3415 //=======================================================================
3417 SMESH::ListOfGroups*
3418 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theIDsOfElements,
3419 SMESH::SMESH_Mesh_ptr thePathMesh,
3420 GEOM::GEOM_Object_ptr thePathShape,
3421 CORBA::Long theNodeStart,
3422 CORBA::Boolean theHasAngles,
3423 const SMESH::double_array& theAngles,
3424 CORBA::Boolean theHasRefPoint,
3425 const SMESH::PointStruct& theRefPoint,
3426 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3427 throw (SALOME::SALOME_Exception)
3429 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3431 SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements,
3441 if (!myIsPreviewMode) {
3442 bool isDumpGroups = aGroups && aGroups->length() > 0;
3444 aPythonDump << "(" << aGroups << ", error)";
3446 aPythonDump <<"error";
3448 aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
3449 << theIDsOfElements << ", "
3450 << thePathMesh << ", "
3451 << thePathShape << ", "
3452 << theNodeStart << ", "
3453 << theHasAngles << ", "
3454 << theAngles << ", "
3455 << theHasRefPoint << ", "
3456 << "SMESH.PointStruct( "
3457 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3458 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3459 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3464 //=======================================================================
3465 //function : ExtrusionAlongPathObjectMakeGroups
3467 //=======================================================================
3469 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3470 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3471 SMESH::SMESH_Mesh_ptr thePathMesh,
3472 GEOM::GEOM_Object_ptr thePathShape,
3473 CORBA::Long theNodeStart,
3474 CORBA::Boolean theHasAngles,
3475 const SMESH::double_array& theAngles,
3476 CORBA::Boolean theHasRefPoint,
3477 const SMESH::PointStruct& theRefPoint,
3478 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3479 throw (SALOME::SALOME_Exception)
3481 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3483 prepareIdSource( theObject );
3484 SMESH::long_array_var anElementsId = theObject->GetIDs();
3485 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3496 if (!myIsPreviewMode) {
3497 bool isDumpGroups = aGroups && aGroups->length() > 0;
3499 aPythonDump << "(" << aGroups << ", error)";
3501 aPythonDump <<"error";
3503 aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
3504 << theObject << ", "
3505 << thePathMesh << ", "
3506 << thePathShape << ", "
3507 << theNodeStart << ", "
3508 << theHasAngles << ", "
3509 << theAngles << ", "
3510 << theHasRefPoint << ", "
3511 << "SMESH.PointStruct( "
3512 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3513 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3514 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3519 //=======================================================================
3520 //function : ExtrusionAlongPathObject1DMakeGroups
3522 //=======================================================================
3524 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3525 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3526 SMESH::SMESH_Mesh_ptr thePathMesh,
3527 GEOM::GEOM_Object_ptr thePathShape,
3528 CORBA::Long theNodeStart,
3529 CORBA::Boolean theHasAngles,
3530 const SMESH::double_array& theAngles,
3531 CORBA::Boolean theHasRefPoint,
3532 const SMESH::PointStruct& theRefPoint,
3533 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3534 throw (SALOME::SALOME_Exception)
3536 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3538 prepareIdSource( theObject );
3539 SMESH::long_array_var anElementsId = theObject->GetIDs();
3540 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3552 if (!myIsPreviewMode) {
3553 bool isDumpGroups = aGroups && aGroups->length() > 0;
3555 aPythonDump << "(" << aGroups << ", error)";
3557 aPythonDump << "error";
3559 aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
3560 << theObject << ", "
3561 << thePathMesh << ", "
3562 << thePathShape << ", "
3563 << theNodeStart << ", "
3564 << theHasAngles << ", "
3565 << theAngles << ", "
3566 << theHasRefPoint << ", "
3567 << "SMESH.PointStruct( "
3568 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3569 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3570 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3575 //=======================================================================
3576 //function : ExtrusionAlongPathObject2DMakeGroups
3578 //=======================================================================
3580 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3581 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3582 SMESH::SMESH_Mesh_ptr thePathMesh,
3583 GEOM::GEOM_Object_ptr thePathShape,
3584 CORBA::Long theNodeStart,
3585 CORBA::Boolean theHasAngles,
3586 const SMESH::double_array& theAngles,
3587 CORBA::Boolean theHasRefPoint,
3588 const SMESH::PointStruct& theRefPoint,
3589 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3590 throw (SALOME::SALOME_Exception)
3592 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3594 prepareIdSource( theObject );
3595 SMESH::long_array_var anElementsId = theObject->GetIDs();
3596 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3608 if (!myIsPreviewMode) {
3609 bool isDumpGroups = aGroups && aGroups->length() > 0;
3611 aPythonDump << "(" << aGroups << ", error)";
3613 aPythonDump << "error";
3615 aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
3616 << theObject << ", "
3617 << thePathMesh << ", "
3618 << thePathShape << ", "
3619 << theNodeStart << ", "
3620 << theHasAngles << ", "
3621 << theAngles << ", "
3622 << theHasRefPoint << ", "
3623 << "SMESH.PointStruct( "
3624 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3625 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3626 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3631 //=======================================================================
3632 //function : ExtrusionAlongPathObjX
3634 //=======================================================================
3636 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3637 ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr Object,
3638 SMESH::SMESH_IDSource_ptr Path,
3639 CORBA::Long NodeStart,
3640 CORBA::Boolean HasAngles,
3641 const SMESH::double_array& Angles,
3642 CORBA::Boolean LinearVariation,
3643 CORBA::Boolean HasRefPoint,
3644 const SMESH::PointStruct& RefPoint,
3645 CORBA::Boolean MakeGroups,
3646 SMESH::ElementType ElemType,
3647 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3648 throw (SALOME::SALOME_Exception)
3650 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3652 prepareIdSource( Object );
3653 SMESH::long_array_var anElementsId = Object->GetIDs();
3654 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
3663 (SMDSAbs_ElementType)ElemType,
3666 if (!myIsPreviewMode) {
3667 bool isDumpGroups = aGroups && aGroups->length() > 0;
3669 aPythonDump << "(" << *aGroups << ", error)";
3671 aPythonDump << "error";
3673 aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
3676 << NodeStart << ", "
3677 << HasAngles << ", "
3678 << TVar( Angles ) << ", "
3679 << LinearVariation << ", "
3680 << HasRefPoint << ", "
3681 << "SMESH.PointStruct( "
3682 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3683 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3684 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3685 << MakeGroups << ", "
3686 << ElemType << " )";
3691 //=======================================================================
3692 //function : ExtrusionAlongPathX
3694 //=======================================================================
3696 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3697 ExtrusionAlongPathX(const SMESH::long_array& IDsOfElements,
3698 SMESH::SMESH_IDSource_ptr Path,
3699 CORBA::Long NodeStart,
3700 CORBA::Boolean HasAngles,
3701 const SMESH::double_array& Angles,
3702 CORBA::Boolean LinearVariation,
3703 CORBA::Boolean HasRefPoint,
3704 const SMESH::PointStruct& RefPoint,
3705 CORBA::Boolean MakeGroups,
3706 SMESH::ElementType ElemType,
3707 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3708 throw (SALOME::SALOME_Exception)
3710 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3712 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
3721 (SMDSAbs_ElementType)ElemType,
3724 if (!myIsPreviewMode) {
3725 bool isDumpGroups = aGroups && aGroups->length() > 0;
3727 aPythonDump << "(" << *aGroups << ", error)";
3729 aPythonDump <<"error";
3731 aPythonDump << " = " << this << ".ExtrusionAlongPathX( "
3732 << IDsOfElements << ", "
3734 << NodeStart << ", "
3735 << HasAngles << ", "
3736 << TVar( Angles ) << ", "
3737 << LinearVariation << ", "
3738 << HasRefPoint << ", "
3739 << "SMESH.PointStruct( "
3740 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3741 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3742 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3743 << MakeGroups << ", "
3744 << ElemType << " )";
3749 //================================================================================
3751 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
3752 * of given angles along path steps
3753 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
3754 * which proceeds the extrusion
3755 * \param PathShape is shape(edge); as the mesh can be complex, the edge
3756 * is used to define the sub-mesh for the path
3758 //================================================================================
3760 SMESH::double_array*
3761 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
3762 GEOM::GEOM_Object_ptr thePathShape,
3763 const SMESH::double_array & theAngles)
3765 SMESH::double_array_var aResult = new SMESH::double_array();
3766 int nbAngles = theAngles.length();
3767 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
3769 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3770 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3771 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3772 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
3773 return aResult._retn();
3774 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
3775 if ( nbSteps == nbAngles )
3777 aResult.inout() = theAngles;
3781 aResult->length( nbSteps );
3782 double rAn2St = double( nbAngles ) / double( nbSteps );
3783 double angPrev = 0, angle;
3784 for ( int iSt = 0; iSt < nbSteps; ++iSt )
3786 double angCur = rAn2St * ( iSt+1 );
3787 double angCurFloor = floor( angCur );
3788 double angPrevFloor = floor( angPrev );
3789 if ( angPrevFloor == angCurFloor )
3790 angle = rAn2St * theAngles[ int( angCurFloor ) ];
3793 int iP = int( angPrevFloor );
3794 double angPrevCeil = ceil(angPrev);
3795 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
3797 int iC = int( angCurFloor );
3798 if ( iC < nbAngles )
3799 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
3801 iP = int( angPrevCeil );
3803 angle += theAngles[ iC ];
3805 aResult[ iSt ] = angle;
3810 // Update Python script
3811 TPythonDump() << "rotAngles = " << theAngles;
3812 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
3813 << thePathMesh << ", "
3814 << thePathShape << ", "
3817 return aResult._retn();
3820 //=======================================================================
3823 //=======================================================================
3825 SMESH::ListOfGroups*
3826 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
3827 const SMESH::AxisStruct & theAxis,
3828 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3829 CORBA::Boolean theCopy,
3831 ::SMESH_Mesh* theTargetMesh)
3832 throw (SALOME::SALOME_Exception)
3837 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3838 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3840 if ( theTargetMesh )
3844 switch ( theMirrorType ) {
3845 case SMESH::SMESH_MeshEditor::POINT:
3846 aTrsf.SetMirror( P );
3848 case SMESH::SMESH_MeshEditor::AXIS:
3849 aTrsf.SetMirror( gp_Ax1( P, V ));
3852 aTrsf.SetMirror( gp_Ax2( P, V ));
3855 TIDSortedElemSet copyElements;
3856 TIDSortedElemSet* workElements = & theElements;
3858 if ( myIsPreviewMode )
3860 TPreviewMesh * tmpMesh = getPreviewMesh();
3861 tmpMesh->Copy( theElements, copyElements);
3862 if ( !theCopy && !theTargetMesh )
3864 TIDSortedElemSet elemsAround, elemsAroundCopy;
3865 getElementsAround( theElements, getMeshDS(), elemsAround );
3866 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3868 workElements = & copyElements;
3869 theMakeGroups = false;
3872 ::SMESH_MeshEditor::PGroupIDs groupIds =
3873 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3875 if ( theCopy && !myIsPreviewMode)
3877 if ( theTargetMesh )
3879 theTargetMesh->GetMeshDS()->Modified();
3883 declareMeshModified( /*isReComputeSafe=*/false );
3886 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3888 SMESH_CATCH( SMESH::throwCorbaException );
3892 //=======================================================================
3895 //=======================================================================
3897 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3898 const SMESH::AxisStruct & theAxis,
3899 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3900 CORBA::Boolean theCopy)
3901 throw (SALOME::SALOME_Exception)
3903 if ( !myIsPreviewMode ) {
3904 TPythonDump() << this << ".Mirror( "
3905 << theIDsOfElements << ", "
3907 << mirrorTypeName(theMirrorType) << ", "
3910 if ( theIDsOfElements.length() > 0 )
3912 TIDSortedElemSet elements;
3913 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3914 mirror(elements, theAxis, theMirrorType, theCopy, false);
3919 //=======================================================================
3920 //function : MirrorObject
3922 //=======================================================================
3924 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3925 const SMESH::AxisStruct & theAxis,
3926 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3927 CORBA::Boolean theCopy)
3928 throw (SALOME::SALOME_Exception)
3930 if ( !myIsPreviewMode ) {
3931 TPythonDump() << this << ".MirrorObject( "
3932 << theObject << ", "
3934 << mirrorTypeName(theMirrorType) << ", "
3937 TIDSortedElemSet elements;
3939 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3941 prepareIdSource( theObject );
3942 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3943 mirror(elements, theAxis, theMirrorType, theCopy, false);
3946 //=======================================================================
3947 //function : MirrorMakeGroups
3949 //=======================================================================
3951 SMESH::ListOfGroups*
3952 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3953 const SMESH::AxisStruct& theMirror,
3954 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3955 throw (SALOME::SALOME_Exception)
3957 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3959 SMESH::ListOfGroups * aGroups = 0;
3960 if ( theIDsOfElements.length() > 0 )
3962 TIDSortedElemSet elements;
3963 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3964 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3966 if (!myIsPreviewMode) {
3967 dumpGroupsList(aPythonDump, aGroups);
3968 aPythonDump << this << ".MirrorMakeGroups( "
3969 << theIDsOfElements << ", "
3970 << theMirror << ", "
3971 << mirrorTypeName(theMirrorType) << " )";
3976 //=======================================================================
3977 //function : MirrorObjectMakeGroups
3979 //=======================================================================
3981 SMESH::ListOfGroups*
3982 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3983 const SMESH::AxisStruct& theMirror,
3984 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3985 throw (SALOME::SALOME_Exception)
3987 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3989 SMESH::ListOfGroups * aGroups = 0;
3990 TIDSortedElemSet elements;
3991 prepareIdSource( theObject );
3992 if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3993 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3995 if (!myIsPreviewMode)
3997 dumpGroupsList(aPythonDump,aGroups);
3998 aPythonDump << this << ".MirrorObjectMakeGroups( "
3999 << theObject << ", "
4000 << theMirror << ", "
4001 << mirrorTypeName(theMirrorType) << " )";
4006 //=======================================================================
4007 //function : MirrorMakeMesh
4009 //=======================================================================
4011 SMESH::SMESH_Mesh_ptr
4012 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
4013 const SMESH::AxisStruct& theMirror,
4014 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
4015 CORBA::Boolean theCopyGroups,
4016 const char* theMeshName)
4017 throw (SALOME::SALOME_Exception)
4019 SMESH_Mesh_i* mesh_i;
4020 SMESH::SMESH_Mesh_var mesh;
4021 { // open new scope to dump "MakeMesh" command
4022 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4024 TPythonDump pydump; // to prevent dump at mesh creation
4026 mesh = makeMesh( theMeshName );
4027 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4028 if (mesh_i && theIDsOfElements.length() > 0 )
4030 TIDSortedElemSet elements;
4031 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4032 mirror(elements, theMirror, theMirrorType,
4033 false, theCopyGroups, & mesh_i->GetImpl());
4034 mesh_i->CreateGroupServants();
4037 if (!myIsPreviewMode) {
4038 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
4039 << theIDsOfElements << ", "
4040 << theMirror << ", "
4041 << mirrorTypeName(theMirrorType) << ", "
4042 << theCopyGroups << ", '"
4043 << theMeshName << "' )";
4048 if (!myIsPreviewMode && mesh_i)
4049 mesh_i->GetGroups();
4051 return mesh._retn();
4054 //=======================================================================
4055 //function : MirrorObjectMakeMesh
4057 //=======================================================================
4059 SMESH::SMESH_Mesh_ptr
4060 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4061 const SMESH::AxisStruct& theMirror,
4062 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
4063 CORBA::Boolean theCopyGroups,
4064 const char* theMeshName)
4065 throw (SALOME::SALOME_Exception)
4067 SMESH_Mesh_i* mesh_i;
4068 SMESH::SMESH_Mesh_var mesh;
4069 { // open new scope to dump "MakeMesh" command
4070 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4072 TPythonDump pydump; // to prevent dump at mesh creation
4074 mesh = makeMesh( theMeshName );
4075 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4076 TIDSortedElemSet elements;
4077 prepareIdSource( theObject );
4079 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4081 mirror(elements, theMirror, theMirrorType,
4082 false, theCopyGroups, & mesh_i->GetImpl());
4083 mesh_i->CreateGroupServants();
4085 if (!myIsPreviewMode) {
4086 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
4087 << theObject << ", "
4088 << theMirror << ", "
4089 << mirrorTypeName(theMirrorType) << ", "
4090 << theCopyGroups << ", '"
4091 << theMeshName << "' )";
4096 if (!myIsPreviewMode && mesh_i)
4097 mesh_i->GetGroups();
4099 return mesh._retn();
4102 //=======================================================================
4103 //function : translate
4105 //=======================================================================
4107 SMESH::ListOfGroups*
4108 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
4109 const SMESH::DirStruct & theVector,
4110 CORBA::Boolean theCopy,
4112 ::SMESH_Mesh* theTargetMesh)
4113 throw (SALOME::SALOME_Exception)
4118 if ( theTargetMesh )
4122 const SMESH::PointStruct * P = &theVector.PS;
4123 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
4125 TIDSortedElemSet copyElements;
4126 TIDSortedElemSet* workElements = &theElements;
4128 if ( myIsPreviewMode )
4130 TPreviewMesh * tmpMesh = getPreviewMesh();
4131 tmpMesh->Copy( theElements, copyElements);
4132 if ( !theCopy && !theTargetMesh )
4134 TIDSortedElemSet elemsAround, elemsAroundCopy;
4135 getElementsAround( theElements, getMeshDS(), elemsAround );
4136 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4138 workElements = & copyElements;
4139 theMakeGroups = false;
4142 ::SMESH_MeshEditor::PGroupIDs groupIds =
4143 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4145 if ( theCopy && !myIsPreviewMode )
4147 if ( theTargetMesh )
4149 theTargetMesh->GetMeshDS()->Modified();
4153 declareMeshModified( /*isReComputeSafe=*/false );
4157 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4159 SMESH_CATCH( SMESH::throwCorbaException );
4163 //=======================================================================
4164 //function : Translate
4166 //=======================================================================
4168 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
4169 const SMESH::DirStruct & theVector,
4170 CORBA::Boolean theCopy)
4171 throw (SALOME::SALOME_Exception)
4173 if (!myIsPreviewMode) {
4174 TPythonDump() << this << ".Translate( "
4175 << theIDsOfElements << ", "
4176 << theVector << ", "
4179 if (theIDsOfElements.length()) {
4180 TIDSortedElemSet elements;
4181 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4182 translate(elements, theVector, theCopy, false);
4186 //=======================================================================
4187 //function : TranslateObject
4189 //=======================================================================
4191 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
4192 const SMESH::DirStruct & theVector,
4193 CORBA::Boolean theCopy)
4194 throw (SALOME::SALOME_Exception)
4196 if (!myIsPreviewMode) {
4197 TPythonDump() << this << ".TranslateObject( "
4198 << theObject << ", "
4199 << theVector << ", "
4202 TIDSortedElemSet elements;
4204 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4206 prepareIdSource( theObject );
4207 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4208 translate(elements, theVector, theCopy, false);
4211 //=======================================================================
4212 //function : TranslateMakeGroups
4214 //=======================================================================
4216 SMESH::ListOfGroups*
4217 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
4218 const SMESH::DirStruct& theVector)
4219 throw (SALOME::SALOME_Exception)
4221 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4223 SMESH::ListOfGroups * aGroups = 0;
4224 if (theIDsOfElements.length()) {
4225 TIDSortedElemSet elements;
4226 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4227 aGroups = translate(elements,theVector,true,true);
4229 if (!myIsPreviewMode) {
4230 dumpGroupsList(aPythonDump, aGroups);
4231 aPythonDump << this << ".TranslateMakeGroups( "
4232 << theIDsOfElements << ", "
4233 << theVector << " )";
4238 //=======================================================================
4239 //function : TranslateObjectMakeGroups
4241 //=======================================================================
4243 SMESH::ListOfGroups*
4244 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4245 const SMESH::DirStruct& theVector)
4246 throw (SALOME::SALOME_Exception)
4248 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4250 SMESH::ListOfGroups * aGroups = 0;
4251 TIDSortedElemSet elements;
4252 prepareIdSource( theObject );
4253 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4254 aGroups = translate(elements, theVector, true, true);
4256 if (!myIsPreviewMode) {
4257 dumpGroupsList(aPythonDump, aGroups);
4258 aPythonDump << this << ".TranslateObjectMakeGroups( "
4259 << theObject << ", "
4260 << theVector << " )";
4265 //=======================================================================
4266 //function : TranslateMakeMesh
4268 //=======================================================================
4270 SMESH::SMESH_Mesh_ptr
4271 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
4272 const SMESH::DirStruct& theVector,
4273 CORBA::Boolean theCopyGroups,
4274 const char* theMeshName)
4275 throw (SALOME::SALOME_Exception)
4277 SMESH_Mesh_i* mesh_i;
4278 SMESH::SMESH_Mesh_var mesh;
4280 { // open new scope to dump "MakeMesh" command
4281 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4283 TPythonDump pydump; // to prevent dump at mesh creation
4285 mesh = makeMesh( theMeshName );
4286 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4288 if ( mesh_i && theIDsOfElements.length() )
4290 TIDSortedElemSet elements;
4291 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4292 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
4293 mesh_i->CreateGroupServants();
4296 if ( !myIsPreviewMode ) {
4297 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
4298 << theIDsOfElements << ", "
4299 << theVector << ", "
4300 << theCopyGroups << ", '"
4301 << theMeshName << "' )";
4306 if (!myIsPreviewMode && mesh_i)
4307 mesh_i->GetGroups();
4309 return mesh._retn();
4312 //=======================================================================
4313 //function : TranslateObjectMakeMesh
4315 //=======================================================================
4317 SMESH::SMESH_Mesh_ptr
4318 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4319 const SMESH::DirStruct& theVector,
4320 CORBA::Boolean theCopyGroups,
4321 const char* theMeshName)
4322 throw (SALOME::SALOME_Exception)
4325 SMESH_Mesh_i* mesh_i;
4326 SMESH::SMESH_Mesh_var mesh;
4327 { // open new scope to dump "MakeMesh" command
4328 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4330 TPythonDump pydump; // to prevent dump at mesh creation
4331 mesh = makeMesh( theMeshName );
4332 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4334 TIDSortedElemSet elements;
4335 prepareIdSource( theObject );
4337 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4339 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
4340 mesh_i->CreateGroupServants();
4342 if ( !myIsPreviewMode ) {
4343 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
4344 << theObject << ", "
4345 << theVector << ", "
4346 << theCopyGroups << ", '"
4347 << theMeshName << "' )";
4352 if (!myIsPreviewMode && mesh_i)
4353 mesh_i->GetGroups();
4355 return mesh._retn();
4357 SMESH_CATCH( SMESH::throwCorbaException );
4361 //=======================================================================
4364 //=======================================================================
4366 SMESH::ListOfGroups*
4367 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
4368 const SMESH::AxisStruct & theAxis,
4369 CORBA::Double theAngle,
4370 CORBA::Boolean theCopy,
4372 ::SMESH_Mesh* theTargetMesh)
4373 throw (SALOME::SALOME_Exception)
4378 if ( theTargetMesh )
4381 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
4382 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
4385 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
4387 TIDSortedElemSet copyElements;
4388 TIDSortedElemSet* workElements = &theElements;
4389 if ( myIsPreviewMode ) {
4390 TPreviewMesh * tmpMesh = getPreviewMesh();
4391 tmpMesh->Copy( theElements, copyElements );
4392 if ( !theCopy && !theTargetMesh )
4394 TIDSortedElemSet elemsAround, elemsAroundCopy;
4395 getElementsAround( theElements, getMeshDS(), elemsAround );
4396 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4398 workElements = ©Elements;
4399 theMakeGroups = false;
4402 ::SMESH_MeshEditor::PGroupIDs groupIds =
4403 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4405 if ( theCopy && !myIsPreviewMode)
4407 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
4408 else declareMeshModified( /*isReComputeSafe=*/false );
4411 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4413 SMESH_CATCH( SMESH::throwCorbaException );
4417 //=======================================================================
4420 //=======================================================================
4422 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
4423 const SMESH::AxisStruct & theAxis,
4424 CORBA::Double theAngle,
4425 CORBA::Boolean theCopy)
4426 throw (SALOME::SALOME_Exception)
4428 if (!myIsPreviewMode) {
4429 TPythonDump() << this << ".Rotate( "
4430 << theIDsOfElements << ", "
4432 << TVar( theAngle ) << ", "
4435 if (theIDsOfElements.length() > 0)
4437 TIDSortedElemSet elements;
4438 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4439 rotate(elements,theAxis,theAngle,theCopy,false);
4443 //=======================================================================
4444 //function : RotateObject
4446 //=======================================================================
4448 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
4449 const SMESH::AxisStruct & theAxis,
4450 CORBA::Double theAngle,
4451 CORBA::Boolean theCopy)
4452 throw (SALOME::SALOME_Exception)
4454 if ( !myIsPreviewMode ) {
4455 TPythonDump() << this << ".RotateObject( "
4456 << theObject << ", "
4458 << TVar( theAngle ) << ", "
4461 TIDSortedElemSet elements;
4462 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4463 prepareIdSource( theObject );
4464 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4465 rotate(elements,theAxis,theAngle,theCopy,false);
4468 //=======================================================================
4469 //function : RotateMakeGroups
4471 //=======================================================================
4473 SMESH::ListOfGroups*
4474 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
4475 const SMESH::AxisStruct& theAxis,
4476 CORBA::Double theAngle)
4477 throw (SALOME::SALOME_Exception)
4479 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4481 SMESH::ListOfGroups * aGroups = 0;
4482 if (theIDsOfElements.length() > 0)
4484 TIDSortedElemSet elements;
4485 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4486 aGroups = rotate(elements,theAxis,theAngle,true,true);
4488 if (!myIsPreviewMode) {
4489 dumpGroupsList(aPythonDump, aGroups);
4490 aPythonDump << this << ".RotateMakeGroups( "
4491 << theIDsOfElements << ", "
4493 << TVar( theAngle ) << " )";
4498 //=======================================================================
4499 //function : RotateObjectMakeGroups
4501 //=======================================================================
4503 SMESH::ListOfGroups*
4504 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4505 const SMESH::AxisStruct& theAxis,
4506 CORBA::Double theAngle)
4507 throw (SALOME::SALOME_Exception)
4509 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4511 SMESH::ListOfGroups * aGroups = 0;
4512 TIDSortedElemSet elements;
4513 prepareIdSource( theObject );
4514 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4515 aGroups = rotate(elements, theAxis, theAngle, true, true);
4517 if (!myIsPreviewMode) {
4518 dumpGroupsList(aPythonDump, aGroups);
4519 aPythonDump << this << ".RotateObjectMakeGroups( "
4520 << theObject << ", "
4522 << TVar( theAngle ) << " )";
4527 //=======================================================================
4528 //function : RotateMakeMesh
4530 //=======================================================================
4532 SMESH::SMESH_Mesh_ptr
4533 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
4534 const SMESH::AxisStruct& theAxis,
4535 CORBA::Double theAngleInRadians,
4536 CORBA::Boolean theCopyGroups,
4537 const char* theMeshName)
4538 throw (SALOME::SALOME_Exception)
4541 SMESH::SMESH_Mesh_var mesh;
4542 SMESH_Mesh_i* mesh_i;
4544 { // open new scope to dump "MakeMesh" command
4545 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4547 TPythonDump pydump; // to prevent dump at mesh creation
4549 mesh = makeMesh( theMeshName );
4550 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4552 if ( mesh_i && theIDsOfElements.length() > 0 )
4554 TIDSortedElemSet elements;
4555 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4556 rotate(elements, theAxis, theAngleInRadians,
4557 false, theCopyGroups, & mesh_i->GetImpl());
4558 mesh_i->CreateGroupServants();
4560 if ( !myIsPreviewMode ) {
4561 pydump << mesh << " = " << this << ".RotateMakeMesh( "
4562 << theIDsOfElements << ", "
4564 << TVar( theAngleInRadians ) << ", "
4565 << theCopyGroups << ", '"
4566 << theMeshName << "' )";
4571 if (!myIsPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
4572 mesh_i->GetGroups();
4574 return mesh._retn();
4576 SMESH_CATCH( SMESH::throwCorbaException );
4580 //=======================================================================
4581 //function : RotateObjectMakeMesh
4583 //=======================================================================
4585 SMESH::SMESH_Mesh_ptr
4586 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4587 const SMESH::AxisStruct& theAxis,
4588 CORBA::Double theAngleInRadians,
4589 CORBA::Boolean theCopyGroups,
4590 const char* theMeshName)
4591 throw (SALOME::SALOME_Exception)
4594 SMESH::SMESH_Mesh_var mesh;
4595 SMESH_Mesh_i* mesh_i;
4597 {// open new scope to dump "MakeMesh" command
4598 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4600 TPythonDump pydump; // to prevent dump at mesh creation
4601 mesh = makeMesh( theMeshName );
4602 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4604 TIDSortedElemSet elements;
4605 prepareIdSource( theObject );
4607 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4609 rotate(elements, theAxis, theAngleInRadians,
4610 false, theCopyGroups, & mesh_i->GetImpl());
4611 mesh_i->CreateGroupServants();
4613 if ( !myIsPreviewMode ) {
4614 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
4615 << theObject << ", "
4617 << TVar( theAngleInRadians ) << ", "
4618 << theCopyGroups << ", '"
4619 << theMeshName << "' )";
4624 if (!myIsPreviewMode && mesh_i)
4625 mesh_i->GetGroups();
4627 return mesh._retn();
4629 SMESH_CATCH( SMESH::throwCorbaException );
4633 //=======================================================================
4636 //=======================================================================
4638 SMESH::ListOfGroups*
4639 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
4640 const SMESH::PointStruct& thePoint,
4641 const SMESH::double_array& theScaleFact,
4642 CORBA::Boolean theCopy,
4644 ::SMESH_Mesh* theTargetMesh)
4645 throw (SALOME::SALOME_Exception)
4649 if ( theScaleFact.length() < 1 )
4650 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
4651 if ( theScaleFact.length() == 2 )
4652 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
4654 if ( theTargetMesh )
4657 TIDSortedElemSet elements;
4658 prepareIdSource( theObject );
4659 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4660 if ( !idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4665 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
4666 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
4668 double tol = std::numeric_limits<double>::max();
4670 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
4671 0, S[1], 0, thePoint.y * (1-S[1]),
4672 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
4674 TIDSortedElemSet copyElements;
4675 TIDSortedElemSet* workElements = &elements;
4676 if ( myIsPreviewMode )
4678 TPreviewMesh * tmpMesh = getPreviewMesh();
4679 tmpMesh->Copy( elements, copyElements);
4680 if ( !theCopy && !theTargetMesh )
4682 TIDSortedElemSet elemsAround, elemsAroundCopy;
4683 getElementsAround( elements, getMeshDS(), elemsAround );
4684 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4686 workElements = & copyElements;
4687 theMakeGroups = false;
4690 ::SMESH_MeshEditor::PGroupIDs groupIds =
4691 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4693 if ( theCopy && !myIsPreviewMode )
4695 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
4696 else declareMeshModified( /*isReComputeSafe=*/false );
4698 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4700 SMESH_CATCH( SMESH::throwCorbaException );
4704 //=======================================================================
4707 //=======================================================================
4709 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
4710 const SMESH::PointStruct& thePoint,
4711 const SMESH::double_array& theScaleFact,
4712 CORBA::Boolean theCopy)
4713 throw (SALOME::SALOME_Exception)
4715 if ( !myIsPreviewMode ) {
4716 TPythonDump() << this << ".Scale( "
4717 << theObject << ", "
4719 << TVar( theScaleFact ) << ", "
4722 scale(theObject, thePoint, theScaleFact, theCopy, false);
4726 //=======================================================================
4727 //function : ScaleMakeGroups
4729 //=======================================================================
4731 SMESH::ListOfGroups*
4732 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4733 const SMESH::PointStruct& thePoint,
4734 const SMESH::double_array& theScaleFact)
4735 throw (SALOME::SALOME_Exception)
4737 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4739 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
4740 if (!myIsPreviewMode) {
4741 dumpGroupsList(aPythonDump, aGroups);
4742 aPythonDump << this << ".Scale("
4745 << TVar( theScaleFact ) << ",True,True)";
4751 //=======================================================================
4752 //function : ScaleMakeMesh
4754 //=======================================================================
4756 SMESH::SMESH_Mesh_ptr
4757 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4758 const SMESH::PointStruct& thePoint,
4759 const SMESH::double_array& theScaleFact,
4760 CORBA::Boolean theCopyGroups,
4761 const char* theMeshName)
4762 throw (SALOME::SALOME_Exception)
4764 SMESH_Mesh_i* mesh_i;
4765 SMESH::SMESH_Mesh_var mesh;
4766 { // open new scope to dump "MakeMesh" command
4767 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4769 TPythonDump pydump; // to prevent dump at mesh creation
4770 mesh = makeMesh( theMeshName );
4771 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4775 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
4776 mesh_i->CreateGroupServants();
4778 if ( !myIsPreviewMode )
4779 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
4780 << theObject << ", "
4782 << TVar( theScaleFact ) << ", "
4783 << theCopyGroups << ", '"
4784 << theMeshName << "' )";
4788 if (!myIsPreviewMode && mesh_i)
4789 mesh_i->GetGroups();
4791 return mesh._retn();
4795 //=======================================================================
4796 //function : FindCoincidentNodes
4798 //=======================================================================
4800 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance,
4801 SMESH::array_of_long_array_out GroupsOfNodes)
4802 throw (SALOME::SALOME_Exception)
4807 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4808 TIDSortedNodeSet nodes; // no input nodes
4809 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4811 GroupsOfNodes = new SMESH::array_of_long_array;
4812 GroupsOfNodes->length( aListOfListOfNodes.size() );
4813 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4814 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
4815 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4816 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4817 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4818 aGroup.length( aListOfNodes.size() );
4819 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4820 aGroup[ j ] = (*lIt)->GetID();
4822 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
4823 << Tolerance << " )";
4825 SMESH_CATCH( SMESH::throwCorbaException );
4828 //=======================================================================
4829 //function : FindCoincidentNodesOnPart
4831 //=======================================================================
4833 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
4834 CORBA::Double Tolerance,
4835 SMESH::array_of_long_array_out GroupsOfNodes)
4836 throw (SALOME::SALOME_Exception)
4841 TIDSortedNodeSet nodes;
4842 prepareIdSource( theObject );
4843 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4845 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4847 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4849 GroupsOfNodes = new SMESH::array_of_long_array;
4850 GroupsOfNodes->length( aListOfListOfNodes.size() );
4851 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4852 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4854 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4855 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4856 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4857 aGroup.length( aListOfNodes.size() );
4858 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4859 aGroup[ j ] = (*lIt)->GetID();
4861 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
4863 << Tolerance << " )";
4865 SMESH_CATCH( SMESH::throwCorbaException );
4868 //================================================================================
4870 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
4871 * ExceptSubMeshOrGroups
4873 //================================================================================
4875 void SMESH_MeshEditor_i::
4876 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
4877 CORBA::Double theTolerance,
4878 SMESH::array_of_long_array_out theGroupsOfNodes,
4879 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups)
4880 throw (SALOME::SALOME_Exception)
4885 TIDSortedNodeSet nodes;
4886 prepareIdSource( theObject );
4887 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4889 for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
4891 TIDSortedNodeSet exceptNodes;
4892 idSourceToNodeSet( theExceptSubMeshOrGroups[i], getMeshDS(), exceptNodes );
4893 TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
4894 for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
4895 nodes.erase( *avoidNode );
4897 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4899 getEditor().FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
4901 theGroupsOfNodes = new SMESH::array_of_long_array;
4902 theGroupsOfNodes->length( aListOfListOfNodes.size() );
4903 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4904 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4906 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4907 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4908 SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
4909 aGroup.length( aListOfNodes.size() );
4910 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4911 aGroup[ j ] = (*lIt)->GetID();
4913 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
4915 << theTolerance << ", "
4916 << theExceptSubMeshOrGroups << " )";
4918 SMESH_CATCH( SMESH::throwCorbaException );
4921 //=======================================================================
4922 //function : MergeNodes
4924 //=======================================================================
4926 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
4927 throw (SALOME::SALOME_Exception)
4932 SMESHDS_Mesh* aMesh = getMeshDS();
4934 TPythonDump aTPythonDump;
4935 aTPythonDump << this << ".MergeNodes([";
4936 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4937 for (int i = 0; i < GroupsOfNodes.length(); i++)
4939 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
4940 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
4941 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
4942 for ( int j = 0; j < aNodeGroup.length(); j++ )
4944 CORBA::Long index = aNodeGroup[ j ];
4945 const SMDS_MeshNode * node = aMesh->FindNode(index);
4947 aListOfNodes.push_back( node );
4949 if ( aListOfNodes.size() < 2 )
4950 aListOfListOfNodes.pop_back();
4952 if ( i > 0 ) aTPythonDump << ", ";
4953 aTPythonDump << aNodeGroup;
4955 getEditor().MergeNodes( aListOfListOfNodes );
4957 aTPythonDump << "])";
4959 declareMeshModified( /*isReComputeSafe=*/false );
4961 SMESH_CATCH( SMESH::throwCorbaException );
4964 //=======================================================================
4965 //function : FindEqualElements
4967 //=======================================================================
4969 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
4970 SMESH::array_of_long_array_out GroupsOfElementsID)
4971 throw (SALOME::SALOME_Exception)
4976 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
4977 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
4979 TIDSortedElemSet elems;
4980 prepareIdSource( theObject );
4981 idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true);
4983 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4984 getEditor().FindEqualElements( elems, aListOfListOfElementsID );
4986 GroupsOfElementsID = new SMESH::array_of_long_array;
4987 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
4989 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt =
4990 aListOfListOfElementsID.begin();
4991 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j)
4993 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
4994 list<int>& listOfIDs = *arraysIt;
4995 aGroup.length( listOfIDs.size() );
4996 list<int>::iterator idIt = listOfIDs.begin();
4997 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k )
4998 aGroup[ k ] = *idIt;
5001 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
5005 SMESH_CATCH( SMESH::throwCorbaException );
5008 //=======================================================================
5009 //function : MergeElements
5011 //=======================================================================
5013 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
5014 throw (SALOME::SALOME_Exception)
5019 TPythonDump aTPythonDump;
5020 aTPythonDump << this << ".MergeElements( [";
5022 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
5024 for (int i = 0; i < GroupsOfElementsID.length(); i++) {
5025 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
5026 aListOfListOfElementsID.push_back( list< int >() );
5027 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
5028 for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
5029 CORBA::Long id = anElemsIDGroup[ j ];
5030 aListOfElemsID.push_back( id );
5032 if ( aListOfElemsID.size() < 2 )
5033 aListOfListOfElementsID.pop_back();
5034 if ( i > 0 ) aTPythonDump << ", ";
5035 aTPythonDump << anElemsIDGroup;
5038 getEditor().MergeElements(aListOfListOfElementsID);
5040 declareMeshModified( /*isReComputeSafe=*/true );
5042 aTPythonDump << "] )";
5044 SMESH_CATCH( SMESH::throwCorbaException );
5047 //=======================================================================
5048 //function : MergeEqualElements
5050 //=======================================================================
5052 void SMESH_MeshEditor_i::MergeEqualElements()
5053 throw (SALOME::SALOME_Exception)
5058 getEditor().MergeEqualElements();
5060 declareMeshModified( /*isReComputeSafe=*/true );
5062 TPythonDump() << this << ".MergeEqualElements()";
5064 SMESH_CATCH( SMESH::throwCorbaException );
5067 //=============================================================================
5069 * Move the node to a given point
5071 //=============================================================================
5073 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
5077 throw (SALOME::SALOME_Exception)
5080 initData(/*deleteSearchers=*/false);
5082 const SMDS_MeshNode * node = getMeshDS()->FindNode( NodeID );
5086 if ( theNodeSearcher )
5087 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5089 if ( myIsPreviewMode ) // make preview data
5091 // in a preview mesh, make edges linked to a node
5092 TPreviewMesh& tmpMesh = *getPreviewMesh();
5093 TIDSortedElemSet linkedNodes;
5094 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
5095 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
5096 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
5097 for ( ; nIt != linkedNodes.end(); ++nIt )
5099 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
5100 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
5104 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
5105 // fill preview data
5107 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
5108 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
5110 getMeshDS()->MoveNode(node, x, y, z);
5112 if ( !myIsPreviewMode )
5114 // Update Python script
5115 TPythonDump() << "isDone = " << this << ".MoveNode( "
5116 << NodeID << ", " << TVar(x) << ", " << TVar(y) << ", " << TVar(z) << " )";
5117 declareMeshModified( /*isReComputeSafe=*/false );
5120 SMESH_CATCH( SMESH::throwCorbaException );
5125 //================================================================================
5127 * \brief Return ID of node closest to a given point
5129 //================================================================================
5131 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
5134 throw (SALOME::SALOME_Exception)
5137 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5139 if ( !theNodeSearcher ) {
5140 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
5143 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
5144 return node->GetID();
5146 SMESH_CATCH( SMESH::throwCorbaException );
5150 //================================================================================
5152 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
5153 * move the node closest to the point to point's location and return ID of the node
5155 //================================================================================
5157 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
5160 CORBA::Long theNodeID)
5161 throw (SALOME::SALOME_Exception)
5164 // We keep theNodeSearcher until any mesh modification:
5165 // 1) initData() deletes theNodeSearcher at any edition,
5166 // 2) TSearchersDeleter - at any mesh compute event and mesh change
5168 initData(/*deleteSearchers=*/false);
5170 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5172 int nodeID = theNodeID;
5173 const SMDS_MeshNode* node = getMeshDS()->FindNode( nodeID );
5174 if ( !node ) // preview moving node
5176 if ( !theNodeSearcher ) {
5177 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
5180 node = theNodeSearcher->FindClosestTo( p );
5183 nodeID = node->GetID();
5184 if ( myIsPreviewMode ) // make preview data
5186 // in a preview mesh, make edges linked to a node
5187 TPreviewMesh tmpMesh = *getPreviewMesh();
5188 TIDSortedElemSet linkedNodes;
5189 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
5190 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
5191 for ( ; nIt != linkedNodes.end(); ++nIt )
5193 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
5194 tmpMesh.Copy( &edge );
5197 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
5199 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
5200 // fill preview data
5202 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
5204 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
5208 getMeshDS()->MoveNode(node, x, y, z);
5212 if ( !myIsPreviewMode )
5214 TPythonDump() << "nodeID = " << this
5215 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
5216 << ", " << nodeID << " )";
5218 declareMeshModified( /*isReComputeSafe=*/false );
5223 SMESH_CATCH( SMESH::throwCorbaException );
5227 //=======================================================================
5229 * Return elements of given type where the given point is IN or ON.
5231 * 'ALL' type means elements of any type excluding nodes
5233 //=======================================================================
5235 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
5238 SMESH::ElementType type)
5239 throw (SALOME::SALOME_Exception)
5242 SMESH::long_array_var res = new SMESH::long_array;
5243 vector< const SMDS_MeshElement* > foundElems;
5245 theSearchersDeleter.Set( myMesh );
5246 if ( !theElementSearcher ) {
5247 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
5249 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
5250 SMDSAbs_ElementType( type ),
5252 res->length( foundElems.size() );
5253 for ( int i = 0; i < foundElems.size(); ++i )
5254 res[i] = foundElems[i]->GetID();
5258 SMESH_CATCH( SMESH::throwCorbaException );
5262 //=======================================================================
5263 //function : FindAmongElementsByPoint
5264 //purpose : Searching among the given elements, return elements of given type
5265 // where the given point is IN or ON.
5266 // 'ALL' type means elements of any type excluding nodes
5267 //=======================================================================
5270 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
5274 SMESH::ElementType type)
5275 throw (SALOME::SALOME_Exception)
5278 SMESH::long_array_var res = new SMESH::long_array;
5280 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
5281 if ( types->length() == 1 && // a part contains only nodes or 0D elements
5282 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) &&
5283 type != types[0] ) // but search of elements of dim > 0
5286 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
5287 return FindElementsByPoint( x,y,z, type );
5289 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
5291 theSearchersDeleter.Set( myMesh, getPartIOR( elementIDs, type ));
5292 if ( !theElementSearcher )
5294 // create a searcher from elementIDs
5295 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
5296 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
5298 if ( !idSourceToSet( elementIDs, meshDS, elements,
5299 SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
5302 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5303 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
5305 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt );
5308 vector< const SMDS_MeshElement* > foundElems;
5310 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
5311 SMDSAbs_ElementType( type ),
5313 res->length( foundElems.size() );
5314 for ( int i = 0; i < foundElems.size(); ++i )
5315 res[i] = foundElems[i]->GetID();
5319 SMESH_CATCH( SMESH::throwCorbaException );
5323 //=======================================================================
5324 //function : GetPointState
5325 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
5326 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
5327 //=======================================================================
5329 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
5332 throw (SALOME::SALOME_Exception)
5335 theSearchersDeleter.Set( myMesh );
5336 if ( !theElementSearcher ) {
5337 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
5339 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
5341 SMESH_CATCH( SMESH::throwCorbaException );
5345 //=======================================================================
5346 //function : convError
5348 //=======================================================================
5350 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
5352 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
5356 RETCASE( SEW_BORDER1_NOT_FOUND );
5357 RETCASE( SEW_BORDER2_NOT_FOUND );
5358 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
5359 RETCASE( SEW_BAD_SIDE_NODES );
5360 RETCASE( SEW_VOLUMES_TO_SPLIT );
5361 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
5362 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
5363 RETCASE( SEW_BAD_SIDE1_NODES );
5364 RETCASE( SEW_BAD_SIDE2_NODES );
5366 return SMESH::SMESH_MeshEditor::SEW_OK;
5369 //=======================================================================
5370 //function : SewFreeBorders
5372 //=======================================================================
5374 SMESH::SMESH_MeshEditor::Sew_Error
5375 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
5376 CORBA::Long SecondNodeID1,
5377 CORBA::Long LastNodeID1,
5378 CORBA::Long FirstNodeID2,
5379 CORBA::Long SecondNodeID2,
5380 CORBA::Long LastNodeID2,
5381 CORBA::Boolean CreatePolygons,
5382 CORBA::Boolean CreatePolyedrs)
5383 throw (SALOME::SALOME_Exception)
5388 SMESHDS_Mesh* aMesh = getMeshDS();
5390 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
5391 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
5392 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
5393 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
5394 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
5395 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
5397 if (!aBorderFirstNode ||
5398 !aBorderSecondNode||
5400 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5401 if (!aSide2FirstNode ||
5402 !aSide2SecondNode ||
5404 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
5406 TPythonDump() << "error = " << this << ".SewFreeBorders( "
5407 << FirstNodeID1 << ", "
5408 << SecondNodeID1 << ", "
5409 << LastNodeID1 << ", "
5410 << FirstNodeID2 << ", "
5411 << SecondNodeID2 << ", "
5412 << LastNodeID2 << ", "
5413 << CreatePolygons<< ", "
5414 << CreatePolyedrs<< " )";
5416 SMESH::SMESH_MeshEditor::Sew_Error error =
5417 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5428 declareMeshModified( /*isReComputeSafe=*/false );
5431 SMESH_CATCH( SMESH::throwCorbaException );
5432 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5436 //=======================================================================
5437 //function : SewConformFreeBorders
5439 //=======================================================================
5441 SMESH::SMESH_MeshEditor::Sew_Error
5442 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
5443 CORBA::Long SecondNodeID1,
5444 CORBA::Long LastNodeID1,
5445 CORBA::Long FirstNodeID2,
5446 CORBA::Long SecondNodeID2)
5447 throw (SALOME::SALOME_Exception)
5452 SMESHDS_Mesh* aMesh = getMeshDS();
5454 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
5455 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
5456 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
5457 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
5458 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
5459 const SMDS_MeshNode* aSide2ThirdNode = 0;
5461 if (!aBorderFirstNode ||
5462 !aBorderSecondNode||
5464 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5465 if (!aSide2FirstNode ||
5467 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
5469 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
5470 << FirstNodeID1 << ", "
5471 << SecondNodeID1 << ", "
5472 << LastNodeID1 << ", "
5473 << FirstNodeID2 << ", "
5474 << SecondNodeID2 << " )";
5476 SMESH::SMESH_MeshEditor::Sew_Error error =
5477 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5486 declareMeshModified( /*isReComputeSafe=*/false );
5489 SMESH_CATCH( SMESH::throwCorbaException );
5490 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5494 //=======================================================================
5495 //function : SewBorderToSide
5497 //=======================================================================
5499 SMESH::SMESH_MeshEditor::Sew_Error
5500 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
5501 CORBA::Long SecondNodeIDOnFreeBorder,
5502 CORBA::Long LastNodeIDOnFreeBorder,
5503 CORBA::Long FirstNodeIDOnSide,
5504 CORBA::Long LastNodeIDOnSide,
5505 CORBA::Boolean CreatePolygons,
5506 CORBA::Boolean CreatePolyedrs)
5507 throw (SALOME::SALOME_Exception)
5512 SMESHDS_Mesh* aMesh = getMeshDS();
5514 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
5515 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
5516 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
5517 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
5518 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
5519 const SMDS_MeshNode* aSide2ThirdNode = 0;
5521 if (!aBorderFirstNode ||
5522 !aBorderSecondNode||
5524 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5525 if (!aSide2FirstNode ||
5527 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
5529 TPythonDump() << "error = " << this << ".SewBorderToSide( "
5530 << FirstNodeIDOnFreeBorder << ", "
5531 << SecondNodeIDOnFreeBorder << ", "
5532 << LastNodeIDOnFreeBorder << ", "
5533 << FirstNodeIDOnSide << ", "
5534 << LastNodeIDOnSide << ", "
5535 << CreatePolygons << ", "
5536 << CreatePolyedrs << ") ";
5538 SMESH::SMESH_MeshEditor::Sew_Error error =
5539 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5549 declareMeshModified( /*isReComputeSafe=*/false );
5552 SMESH_CATCH( SMESH::throwCorbaException );
5553 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5557 //=======================================================================
5558 //function : SewSideElements
5560 //=======================================================================
5562 SMESH::SMESH_MeshEditor::Sew_Error
5563 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
5564 const SMESH::long_array& IDsOfSide2Elements,
5565 CORBA::Long NodeID1OfSide1ToMerge,
5566 CORBA::Long NodeID1OfSide2ToMerge,
5567 CORBA::Long NodeID2OfSide1ToMerge,
5568 CORBA::Long NodeID2OfSide2ToMerge)
5569 throw (SALOME::SALOME_Exception)
5574 SMESHDS_Mesh* aMesh = getMeshDS();
5576 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
5577 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
5578 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
5579 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
5581 if (!aFirstNode1ToMerge ||
5582 !aFirstNode2ToMerge )
5583 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
5584 if (!aSecondNode1ToMerge||
5585 !aSecondNode2ToMerge)
5586 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
5588 TIDSortedElemSet aSide1Elems, aSide2Elems;
5589 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
5590 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
5592 TPythonDump() << "error = " << this << ".SewSideElements( "
5593 << IDsOfSide1Elements << ", "
5594 << IDsOfSide2Elements << ", "
5595 << NodeID1OfSide1ToMerge << ", "
5596 << NodeID1OfSide2ToMerge << ", "
5597 << NodeID2OfSide1ToMerge << ", "
5598 << NodeID2OfSide2ToMerge << ")";
5600 SMESH::SMESH_MeshEditor::Sew_Error error =
5601 convError( getEditor().SewSideElements (aSide1Elems, aSide2Elems,
5604 aSecondNode1ToMerge,
5605 aSecondNode2ToMerge));
5607 declareMeshModified( /*isReComputeSafe=*/false );
5610 SMESH_CATCH( SMESH::throwCorbaException );
5611 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5614 //================================================================================
5616 * \brief Set new nodes for given element
5617 * \param ide - element id
5618 * \param newIDs - new node ids
5619 * \retval CORBA::Boolean - true if result is OK
5621 //================================================================================
5623 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
5624 const SMESH::long_array& newIDs)
5625 throw (SALOME::SALOME_Exception)
5630 const SMDS_MeshElement* elem = getMeshDS()->FindElement(ide);
5631 if(!elem) return false;
5633 int nbn = newIDs.length();
5635 vector<const SMDS_MeshNode*> aNodes(nbn);
5638 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(newIDs[i]);
5641 aNodes[nbn1] = aNode;
5644 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
5645 << ide << ", " << newIDs << " )";
5647 MESSAGE("ChangeElementNodes");
5648 bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
5650 declareMeshModified( /*isReComputeSafe=*/ !res );
5654 SMESH_CATCH( SMESH::throwCorbaException );
5658 //=======================================================================
5660 * \brief Makes a part of the mesh quadratic or bi-quadratic
5662 //=======================================================================
5664 void SMESH_MeshEditor_i::convertToQuadratic(CORBA::Boolean theForce3d,
5665 CORBA::Boolean theToBiQuad,
5666 SMESH::SMESH_IDSource_ptr theObject)
5667 throw (SALOME::SALOME_Exception)
5670 TIDSortedElemSet elems;
5672 if ( !( elemsOK = CORBA::is_nil( theObject )))
5674 prepareIdSource( theObject );
5675 elemsOK = idSourceToSet( theObject, getMeshDS(), elems,
5676 SMDSAbs_All, /*emptyIfIsMesh=*/true );
5680 if ( !elems.empty() && (*elems.begin())->GetType() == SMDSAbs_Node )
5681 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5683 if ( elems.empty() ) getEditor().ConvertToQuadratic(theForce3d, theToBiQuad);
5684 else getEditor().ConvertToQuadratic(theForce3d, elems, theToBiQuad);
5686 declareMeshModified( /*isReComputeSafe=*/false );
5689 SMESH_CATCH( SMESH::throwCorbaException );
5692 //=======================================================================
5693 //function : ConvertFromQuadratic
5695 //=======================================================================
5697 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
5698 throw (SALOME::SALOME_Exception)
5700 CORBA::Boolean isDone = getEditor().ConvertFromQuadratic();
5701 TPythonDump() << this << ".ConvertFromQuadratic()";
5702 declareMeshModified( /*isReComputeSafe=*/!isDone );
5706 //=======================================================================
5707 //function : ConvertToQuadratic
5709 //=======================================================================
5711 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
5712 throw (SALOME::SALOME_Exception)
5714 convertToQuadratic( theForce3d, false );
5715 TPythonDump() << this << ".ConvertToQuadratic("<<theForce3d<<")";
5718 //================================================================================
5720 * \brief Makes a part of the mesh quadratic
5722 //================================================================================
5724 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
5725 SMESH::SMESH_IDSource_ptr theObject)
5726 throw (SALOME::SALOME_Exception)
5728 convertToQuadratic( theForce3d, false, theObject );
5729 TPythonDump() << this << ".ConvertToQuadraticObject("<<theForce3d<<", "<<theObject<<")";
5732 //================================================================================
5734 * \brief Makes a part of the mesh bi-quadratic
5736 //================================================================================
5738 void SMESH_MeshEditor_i::ConvertToBiQuadratic(CORBA::Boolean theForce3d,
5739 SMESH::SMESH_IDSource_ptr theObject)
5740 throw (SALOME::SALOME_Exception)
5742 convertToQuadratic( theForce3d, true, theObject );
5743 TPythonDump() << this << ".ConvertToBiQuadratic("<<theForce3d<<", "<<theObject<<")";
5746 //================================================================================
5748 * \brief Makes a part of the mesh linear
5750 //================================================================================
5752 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
5753 throw (SALOME::SALOME_Exception)
5759 TIDSortedElemSet elems;
5760 prepareIdSource( theObject );
5761 if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5763 if ( elems.empty() )
5765 ConvertFromQuadratic();
5767 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5769 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5773 getEditor().ConvertFromQuadratic(elems);
5776 declareMeshModified( /*isReComputeSafe=*/false );
5778 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
5780 SMESH_CATCH( SMESH::throwCorbaException );
5783 //=======================================================================
5784 //function : makeMesh
5785 //purpose : create a named imported mesh
5786 //=======================================================================
5788 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
5790 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
5791 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
5792 SALOMEDS::Study_var study = gen->GetCurrentStudy();
5793 SALOMEDS::SObject_wrap meshSO = gen->ObjectToSObject( study, mesh );
5794 gen->SetName( meshSO, theMeshName, "Mesh" );
5795 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
5797 return mesh._retn();
5800 //=======================================================================
5801 //function : dumpGroupsList
5803 //=======================================================================
5805 void SMESH_MeshEditor_i::dumpGroupsList(TPythonDump & theDumpPython,
5806 const SMESH::ListOfGroups * theGroupList)
5808 bool isDumpGroupList = ( theGroupList && theGroupList->length() > 0 );
5809 if ( isDumpGroupList )
5810 theDumpPython << theGroupList << " = ";
5813 //================================================================================
5815 \brief Generates the unique group name.
5816 \param thePrefix name prefix
5819 //================================================================================
5821 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
5823 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5824 set<string> groupNames;
5826 // Get existing group names
5827 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
5828 SMESH::SMESH_GroupBase_var aGroup = groups[i];
5829 if (CORBA::is_nil(aGroup))
5832 CORBA::String_var name = aGroup->GetName();
5833 groupNames.insert( name.in() );
5837 string name = thePrefix;
5840 while (!groupNames.insert(name).second)
5841 name = SMESH_Comment( thePrefix ) << "_" << index++;
5846 //================================================================================
5848 * \brief Prepare SMESH_IDSource for work
5850 //================================================================================
5852 void SMESH_MeshEditor_i::prepareIdSource(SMESH::SMESH_IDSource_ptr theObject)
5854 if ( SMESH::Filter_i* filter = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5856 SMESH::SMESH_Mesh_var mesh = myMesh_i->_this();
5857 filter->SetMesh( mesh );
5861 //================================================================================
5863 * \brief Duplicates given elements, i.e. creates new elements based on the
5864 * same nodes as the given ones.
5865 * \param theElements - container of elements to duplicate.
5866 * \param theGroupName - a name of group to contain the generated elements.
5867 * If a group with such a name already exists, the new elements
5868 * are added to the existng group, else a new group is created.
5869 * If \a theGroupName is empty, new elements are not added
5871 * \return a group where the new elements are added. NULL if theGroupName == "".
5874 //================================================================================
5876 SMESH::SMESH_Group_ptr
5877 SMESH_MeshEditor_i::DoubleElements(SMESH::SMESH_IDSource_ptr theElements,
5878 const char* theGroupName)
5879 throw (SALOME::SALOME_Exception)
5881 SMESH::SMESH_Group_var newGroup;
5888 TIDSortedElemSet elems;
5889 prepareIdSource( theElements );
5890 if ( idSourceToSet( theElements, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true))
5892 getEditor().DoubleElements( elems );
5894 if ( strlen( theGroupName ) && !getEditor().GetLastCreatedElems().IsEmpty() )
5897 SMESH::ElementType type =
5898 SMESH::ElementType( getEditor().GetLastCreatedElems().Value(1)->GetType() );
5899 // find existing group
5900 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5901 for ( size_t i = 0; i < groups->length(); ++i )
5902 if ( groups[i]->GetType() == type )
5904 CORBA::String_var name = groups[i]->GetName();
5905 if ( strcmp( name, theGroupName ) == 0 ) {
5906 newGroup = SMESH::SMESH_Group::_narrow( groups[i] );
5910 // create a new group
5911 if ( newGroup->_is_nil() )
5912 newGroup = myMesh_i->CreateGroup( type, theGroupName );
5914 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* >( newGroup ))
5916 SMESHDS_Group* groupDS = static_cast< SMESHDS_Group* >( group_i->GetGroupDS() );
5917 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
5918 for ( int i = 1; i <= aSeq.Length(); i++ )
5919 groupDS->SMDSGroup().Add( aSeq(i) );
5924 if ( !newGroup->_is_nil() )
5925 pyDump << newGroup << " = ";
5926 pyDump << this << ".DoubleElements( "
5927 << theElements << ", " << "'" << theGroupName <<"')";
5929 SMESH_CATCH( SMESH::throwCorbaException );
5931 return newGroup._retn();
5934 //================================================================================
5936 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5937 \param theNodes - identifiers of nodes to be doubled
5938 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
5939 nodes. If list of element identifiers is empty then nodes are doubled but
5940 they not assigned to elements
5941 \return TRUE if operation has been completed successfully, FALSE otherwise
5942 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
5944 //================================================================================
5946 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
5947 const SMESH::long_array& theModifiedElems )
5948 throw (SALOME::SALOME_Exception)
5953 list< int > aListOfNodes;
5955 for ( i = 0, n = theNodes.length(); i < n; i++ )
5956 aListOfNodes.push_back( theNodes[ i ] );
5958 list< int > aListOfElems;
5959 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5960 aListOfElems.push_back( theModifiedElems[ i ] );
5962 bool aResult = getEditor().DoubleNodes( aListOfNodes, aListOfElems );
5964 declareMeshModified( /*isReComputeSafe=*/ !aResult );
5966 // Update Python script
5967 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
5971 SMESH_CATCH( SMESH::throwCorbaException );
5975 //================================================================================
5977 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5978 This method provided for convenience works as DoubleNodes() described above.
5979 \param theNodeId - identifier of node to be doubled.
5980 \param theModifiedElems - identifiers of elements to be updated.
5981 \return TRUE if operation has been completed successfully, FALSE otherwise
5982 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
5984 //================================================================================
5986 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
5987 const SMESH::long_array& theModifiedElems )
5988 throw (SALOME::SALOME_Exception)
5991 SMESH::long_array_var aNodes = new SMESH::long_array;
5992 aNodes->length( 1 );
5993 aNodes[ 0 ] = theNodeId;
5995 TPythonDump pyDump; // suppress dump by the next line
5997 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
5999 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
6003 SMESH_CATCH( SMESH::throwCorbaException );
6007 //================================================================================
6009 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6010 This method provided for convenience works as DoubleNodes() described above.
6011 \param theNodes - group of nodes to be doubled.
6012 \param theModifiedElems - group of elements to be updated.
6013 \return TRUE if operation has been completed successfully, FALSE otherwise
6014 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
6016 //================================================================================
6018 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
6019 SMESH::SMESH_GroupBase_ptr theModifiedElems )
6020 throw (SALOME::SALOME_Exception)
6023 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
6026 SMESH::long_array_var aNodes = theNodes->GetListOfID();
6027 SMESH::long_array_var aModifiedElems;
6028 if ( !CORBA::is_nil( theModifiedElems ) )
6029 aModifiedElems = theModifiedElems->GetListOfID();
6032 aModifiedElems = new SMESH::long_array;
6033 aModifiedElems->length( 0 );
6036 TPythonDump pyDump; // suppress dump by the next line
6038 bool done = DoubleNodes( aNodes, aModifiedElems );
6040 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
6044 SMESH_CATCH( SMESH::throwCorbaException );
6048 //================================================================================
6050 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6051 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
6052 * \param theNodes - group of nodes to be doubled.
6053 * \param theModifiedElems - group of elements to be updated.
6054 * \return a new group with newly created nodes
6055 * \sa DoubleNodeGroup()
6057 //================================================================================
6059 SMESH::SMESH_Group_ptr
6060 SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
6061 SMESH::SMESH_GroupBase_ptr theModifiedElems )
6062 throw (SALOME::SALOME_Exception)
6065 SMESH::SMESH_Group_var aNewGroup;
6067 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
6068 return aNewGroup._retn();
6071 SMESH::long_array_var aNodes = theNodes->GetListOfID();
6072 SMESH::long_array_var aModifiedElems;
6073 if ( !CORBA::is_nil( theModifiedElems ) )
6074 aModifiedElems = theModifiedElems->GetListOfID();
6076 aModifiedElems = new SMESH::long_array;
6077 aModifiedElems->length( 0 );
6080 TPythonDump pyDump; // suppress dump by the next line
6082 bool aResult = DoubleNodes( aNodes, aModifiedElems );
6085 // Create group with newly created nodes
6086 SMESH::long_array_var anIds = GetLastCreatedNodes();
6087 if (anIds->length() > 0) {
6088 string anUnindexedName (theNodes->GetName());
6089 string aNewName = generateGroupName(anUnindexedName + "_double");
6090 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6091 aNewGroup->Add(anIds);
6092 pyDump << aNewGroup << " = ";
6096 pyDump << this << ".DoubleNodeGroupNew( " << theNodes << ", "
6097 << theModifiedElems << " )";
6099 return aNewGroup._retn();
6101 SMESH_CATCH( SMESH::throwCorbaException );
6105 //================================================================================
6107 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6108 This method provided for convenience works as DoubleNodes() described above.
6109 \param theNodes - list of groups of nodes to be doubled
6110 \param theModifiedElems - list of groups of elements to be updated.
6111 \return TRUE if operation has been completed successfully, FALSE otherwise
6112 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
6114 //================================================================================
6116 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
6117 const SMESH::ListOfGroups& theModifiedElems )
6118 throw (SALOME::SALOME_Exception)
6123 std::list< int > aNodes;
6125 for ( i = 0, n = theNodes.length(); i < n; i++ )
6127 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
6128 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
6130 SMESH::long_array_var aCurr = aGrp->GetListOfID();
6131 for ( j = 0, m = aCurr->length(); j < m; j++ )
6132 aNodes.push_back( aCurr[ j ] );
6136 std::list< int > anElems;
6137 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
6139 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
6140 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
6142 SMESH::long_array_var aCurr = aGrp->GetListOfID();
6143 for ( j = 0, m = aCurr->length(); j < m; j++ )
6144 anElems.push_back( aCurr[ j ] );
6148 bool aResult = getEditor().DoubleNodes( aNodes, anElems );
6150 declareMeshModified( /*isReComputeSafe=*/false );
6152 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
6156 SMESH_CATCH( SMESH::throwCorbaException );
6160 //================================================================================
6162 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6163 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
6164 * \param theNodes - group of nodes to be doubled.
6165 * \param theModifiedElems - group of elements to be updated.
6166 * \return a new group with newly created nodes
6167 * \sa DoubleNodeGroups()
6169 //================================================================================
6171 SMESH::SMESH_Group_ptr
6172 SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
6173 const SMESH::ListOfGroups& theModifiedElems )
6174 throw (SALOME::SALOME_Exception)
6176 SMESH::SMESH_Group_var aNewGroup;
6178 TPythonDump pyDump; // suppress dump by the next line
6180 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
6184 // Create group with newly created nodes
6185 SMESH::long_array_var anIds = GetLastCreatedNodes();
6186 if (anIds->length() > 0) {
6187 string anUnindexedName (theNodes[0]->GetName());
6188 string aNewName = generateGroupName(anUnindexedName + "_double");
6189 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6190 aNewGroup->Add(anIds);
6191 pyDump << aNewGroup << " = ";
6195 pyDump << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
6196 << theModifiedElems << " )";
6198 return aNewGroup._retn();
6202 //================================================================================
6204 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6205 \param theElems - the list of elements (edges or faces) to be replicated
6206 The nodes for duplication could be found from these elements
6207 \param theNodesNot - list of nodes to NOT replicate
6208 \param theAffectedElems - the list of elements (cells and edges) to which the
6209 replicated nodes should be associated to.
6210 \return TRUE if operation has been completed successfully, FALSE otherwise
6211 \sa DoubleNodeGroup(), DoubleNodeGroups()
6213 //================================================================================
6215 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
6216 const SMESH::long_array& theNodesNot,
6217 const SMESH::long_array& theAffectedElems )
6218 throw (SALOME::SALOME_Exception)
6223 SMESHDS_Mesh* aMeshDS = getMeshDS();
6224 TIDSortedElemSet anElems, aNodes, anAffected;
6225 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
6226 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
6227 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
6229 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6231 // Update Python script
6232 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
6233 << theNodesNot << ", " << theAffectedElems << " )";
6235 declareMeshModified( /*isReComputeSafe=*/false );
6238 SMESH_CATCH( SMESH::throwCorbaException );
6242 //================================================================================
6244 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6245 \param theElems - the list of elements (edges or faces) to be replicated
6246 The nodes for duplication could be found from these elements
6247 \param theNodesNot - list of nodes to NOT replicate
6248 \param theShape - shape to detect affected elements (element which geometric center
6249 located on or inside shape).
6250 The replicated nodes should be associated to affected elements.
6251 \return TRUE if operation has been completed successfully, FALSE otherwise
6252 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
6254 //================================================================================
6256 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
6257 const SMESH::long_array& theNodesNot,
6258 GEOM::GEOM_Object_ptr theShape )
6259 throw (SALOME::SALOME_Exception)
6265 SMESHDS_Mesh* aMeshDS = getMeshDS();
6266 TIDSortedElemSet anElems, aNodes;
6267 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
6268 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
6270 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6271 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6273 // Update Python script
6274 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
6275 << theNodesNot << ", " << theShape << " )";
6277 declareMeshModified( /*isReComputeSafe=*/false );
6280 SMESH_CATCH( SMESH::throwCorbaException );
6284 //================================================================================
6286 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6287 \param theElems - group of of elements (edges or faces) to be replicated
6288 \param theNodesNot - group of nodes not to replicated
6289 \param theAffectedElems - group of elements to which the replicated nodes
6290 should be associated to.
6291 \return TRUE if operation has been completed successfully, FALSE otherwise
6292 \sa DoubleNodes(), DoubleNodeGroups()
6294 //================================================================================
6297 SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
6298 SMESH::SMESH_GroupBase_ptr theNodesNot,
6299 SMESH::SMESH_GroupBase_ptr theAffectedElems)
6300 throw (SALOME::SALOME_Exception)
6303 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6309 SMESHDS_Mesh* aMeshDS = getMeshDS();
6310 TIDSortedElemSet anElems, aNodes, anAffected;
6311 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6312 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6313 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
6315 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6317 // Update Python script
6318 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
6319 << theNodesNot << ", " << theAffectedElems << " )";
6321 declareMeshModified( /*isReComputeSafe=*/false );
6324 SMESH_CATCH( SMESH::throwCorbaException );
6328 //================================================================================
6330 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6331 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
6332 * \param theElems - group of of elements (edges or faces) to be replicated
6333 * \param theNodesNot - group of nodes not to replicated
6334 * \param theAffectedElems - group of elements to which the replicated nodes
6335 * should be associated to.
6336 * \return a new group with newly created elements
6337 * \sa DoubleNodeElemGroup()
6339 //================================================================================
6341 SMESH::SMESH_Group_ptr
6342 SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
6343 SMESH::SMESH_GroupBase_ptr theNodesNot,
6344 SMESH::SMESH_GroupBase_ptr theAffectedElems)
6345 throw (SALOME::SALOME_Exception)
6348 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroup2New( theElems,
6352 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
6353 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
6355 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupNew( "
6357 << theNodesNot << ", "
6358 << theAffectedElems << " )";
6360 return elemGroup._retn();
6363 //================================================================================
6365 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6366 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
6367 * \param theElems - group of of elements (edges or faces) to be replicated
6368 * \param theNodesNot - group of nodes not to replicated
6369 * \param theAffectedElems - group of elements to which the replicated nodes
6370 * should be associated to.
6371 * \return a new group with newly created elements
6372 * \sa DoubleNodeElemGroup()
6374 //================================================================================
6376 SMESH::ListOfGroups*
6377 SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
6378 SMESH::SMESH_GroupBase_ptr theNodesNot,
6379 SMESH::SMESH_GroupBase_ptr theAffectedElems,
6380 CORBA::Boolean theElemGroupNeeded,
6381 CORBA::Boolean theNodeGroupNeeded)
6382 throw (SALOME::SALOME_Exception)
6385 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
6386 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
6387 aTwoGroups->length( 2 );
6389 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6390 return aTwoGroups._retn();
6395 SMESHDS_Mesh* aMeshDS = getMeshDS();
6396 TIDSortedElemSet anElems, aNodes, anAffected;
6397 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6398 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6399 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
6402 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6404 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6410 // Create group with newly created elements
6411 CORBA::String_var elemGroupName = theElems->GetName();
6412 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
6413 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
6415 SMESH::long_array_var anIds = GetLastCreatedElems();
6416 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
6417 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
6418 aNewElemGroup->Add(anIds);
6420 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
6422 SMESH::long_array_var anIds = GetLastCreatedNodes();
6423 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6424 aNewNodeGroup->Add(anIds);
6428 // Update Python script
6431 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
6432 else pyDump << aNewElemGroup << ", ";
6433 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
6434 else pyDump << aNewNodeGroup << " ] = ";
6436 pyDump << this << ".DoubleNodeElemGroup2New( " << theElems << ", "
6437 << theNodesNot << ", "
6438 << theAffectedElems << ", "
6439 << theElemGroupNeeded << ", "
6440 << theNodeGroupNeeded <<" )";
6442 aTwoGroups[0] = aNewElemGroup._retn();
6443 aTwoGroups[1] = aNewNodeGroup._retn();
6444 return aTwoGroups._retn();
6446 SMESH_CATCH( SMESH::throwCorbaException );
6450 //================================================================================
6452 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6453 \param theElems - group of of elements (edges or faces) to be replicated
6454 \param theNodesNot - group of nodes not to replicated
6455 \param theShape - shape to detect affected elements (element which geometric center
6456 located on or inside shape).
6457 The replicated nodes should be associated to affected elements.
6458 \return TRUE if operation has been completed successfully, FALSE otherwise
6459 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
6461 //================================================================================
6464 SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
6465 SMESH::SMESH_GroupBase_ptr theNodesNot,
6466 GEOM::GEOM_Object_ptr theShape )
6467 throw (SALOME::SALOME_Exception)
6470 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6476 SMESHDS_Mesh* aMeshDS = getMeshDS();
6477 TIDSortedElemSet anElems, aNodes, anAffected;
6478 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6479 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6481 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6482 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6485 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6487 // Update Python script
6488 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
6489 << theNodesNot << ", " << theShape << " )";
6492 SMESH_CATCH( SMESH::throwCorbaException );
6496 //================================================================================
6498 * \brief Re-load elements from a list of groups into a TIDSortedElemSet
6499 * \param [in] theGrpList - groups
6500 * \param [in] theMeshDS - mesh
6501 * \param [out] theElemSet - set of elements
6502 * \param [in] theIsNodeGrp - is \a theGrpList includes goups of nodes
6504 //================================================================================
6506 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
6507 SMESHDS_Mesh* theMeshDS,
6508 TIDSortedElemSet& theElemSet,
6509 const bool theIsNodeGrp)
6511 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
6513 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
6514 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
6515 : aGrp->GetType() != SMESH::NODE ) )
6517 SMESH::long_array_var anIDs = aGrp->GetIDs();
6518 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
6523 //================================================================================
6525 \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6526 This method provided for convenience works as DoubleNodes() described above.
6527 \param theElems - list of groups of elements (edges or faces) to be replicated
6528 \param theNodesNot - list of groups of nodes not to replicated
6529 \param theAffectedElems - group of elements to which the replicated nodes
6530 should be associated to.
6531 \return TRUE if operation has been completed successfully, FALSE otherwise
6532 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
6534 //================================================================================
6537 SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
6538 const SMESH::ListOfGroups& theNodesNot,
6539 const SMESH::ListOfGroups& theAffectedElems)
6540 throw (SALOME::SALOME_Exception)
6546 SMESHDS_Mesh* aMeshDS = getMeshDS();
6547 TIDSortedElemSet anElems, aNodes, anAffected;
6548 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6549 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6550 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6552 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6554 // Update Python script
6555 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
6556 << &theNodesNot << ", " << &theAffectedElems << " )";
6558 declareMeshModified( /*isReComputeSafe=*/false );
6561 SMESH_CATCH( SMESH::throwCorbaException );
6565 //================================================================================
6567 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6568 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6569 \param theElems - list of groups of elements (edges or faces) to be replicated
6570 \param theNodesNot - list of groups of nodes not to replicated
6571 \param theAffectedElems - group of elements to which the replicated nodes
6572 should be associated to.
6573 * \return a new group with newly created elements
6574 * \sa DoubleNodeElemGroups()
6576 //================================================================================
6578 SMESH::SMESH_Group_ptr
6579 SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
6580 const SMESH::ListOfGroups& theNodesNot,
6581 const SMESH::ListOfGroups& theAffectedElems)
6582 throw (SALOME::SALOME_Exception)
6585 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroups2New( theElems,
6589 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
6590 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
6592 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupsNew( "
6594 << theNodesNot << ", "
6595 << theAffectedElems << " )";
6597 return elemGroup._retn();
6600 //================================================================================
6602 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6603 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6604 \param theElems - list of groups of elements (edges or faces) to be replicated
6605 \param theNodesNot - list of groups of nodes not to replicated
6606 \param theAffectedElems - group of elements to which the replicated nodes
6607 should be associated to.
6608 * \return a new group with newly created elements
6609 * \sa DoubleNodeElemGroups()
6611 //================================================================================
6613 SMESH::ListOfGroups*
6614 SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems,
6615 const SMESH::ListOfGroups& theNodesNot,
6616 const SMESH::ListOfGroups& theAffectedElems,
6617 CORBA::Boolean theElemGroupNeeded,
6618 CORBA::Boolean theNodeGroupNeeded)
6619 throw (SALOME::SALOME_Exception)
6622 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
6623 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
6624 aTwoGroups->length( 2 );
6629 SMESHDS_Mesh* aMeshDS = getMeshDS();
6630 TIDSortedElemSet anElems, aNodes, anAffected;
6631 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6632 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6633 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6635 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6637 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6642 // Create group with newly created elements
6643 CORBA::String_var elemGroupName = theElems[0]->GetName();
6644 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
6645 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
6647 SMESH::long_array_var anIds = GetLastCreatedElems();
6648 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
6649 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
6650 aNewElemGroup->Add(anIds);
6652 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
6654 SMESH::long_array_var anIds = GetLastCreatedNodes();
6655 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6656 aNewNodeGroup->Add(anIds);
6660 // Update Python script
6663 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
6664 else pyDump << aNewElemGroup << ", ";
6665 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
6666 else pyDump << aNewNodeGroup << " ] = ";
6668 pyDump << this << ".DoubleNodeElemGroups2New( " << &theElems << ", "
6669 << &theNodesNot << ", "
6670 << &theAffectedElems << ", "
6671 << theElemGroupNeeded << ", "
6672 << theNodeGroupNeeded << " )";
6674 aTwoGroups[0] = aNewElemGroup._retn();
6675 aTwoGroups[1] = aNewNodeGroup._retn();
6676 return aTwoGroups._retn();
6678 SMESH_CATCH( SMESH::throwCorbaException );
6682 //================================================================================
6684 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6685 This method provided for convenience works as DoubleNodes() described above.
6686 \param theElems - list of groups of elements (edges or faces) to be replicated
6687 \param theNodesNot - list of groups of nodes not to replicated
6688 \param theShape - shape to detect affected elements (element which geometric center
6689 located on or inside shape).
6690 The replicated nodes should be associated to affected elements.
6691 \return TRUE if operation has been completed successfully, FALSE otherwise
6692 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
6694 //================================================================================
6697 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
6698 const SMESH::ListOfGroups& theNodesNot,
6699 GEOM::GEOM_Object_ptr theShape )
6700 throw (SALOME::SALOME_Exception)
6706 SMESHDS_Mesh* aMeshDS = getMeshDS();
6707 TIDSortedElemSet anElems, aNodes;
6708 listOfGroupToSet(theElems, aMeshDS, anElems,false );
6709 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6711 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6712 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6714 // Update Python script
6715 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
6716 << &theNodesNot << ", " << theShape << " )";
6718 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6721 SMESH_CATCH( SMESH::throwCorbaException );
6725 //================================================================================
6727 \brief Identify the elements that will be affected by node duplication (actual
6728 duplication is not performed.
6729 This method is the first step of DoubleNodeElemGroupsInRegion.
6730 \param theElems - list of groups of elements (edges or faces) to be replicated
6731 \param theNodesNot - list of groups of nodes not to replicated
6732 \param theShape - shape to detect affected elements (element which geometric center
6733 located on or inside shape).
6734 The replicated nodes should be associated to affected elements.
6735 \return groups of affected elements
6736 \sa DoubleNodeElemGroupsInRegion()
6738 //================================================================================
6739 SMESH::ListOfGroups*
6740 SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theElems,
6741 const SMESH::ListOfGroups& theNodesNot,
6742 GEOM::GEOM_Object_ptr theShape )
6743 throw (SALOME::SALOME_Exception)
6746 MESSAGE("AffectedElemGroupsInRegion");
6747 SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
6748 bool isEdgeGroup = false;
6749 bool isFaceGroup = false;
6750 bool isVolumeGroup = false;
6751 SMESH::SMESH_Group_var aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE, "affectedEdges");
6752 SMESH::SMESH_Group_var aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE, "affectedFaces");
6753 SMESH::SMESH_Group_var aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME, "affectedVolumes");
6757 ::SMESH_MeshEditor aMeshEditor(myMesh);
6759 SMESHDS_Mesh* aMeshDS = getMeshDS();
6760 TIDSortedElemSet anElems, aNodes;
6761 listOfGroupToSet(theElems, aMeshDS, anElems, false);
6762 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true);
6764 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape(theShape);
6765 TIDSortedElemSet anAffected;
6766 bool aResult = aMeshEditor.AffectedElemGroupsInRegion(anElems, aNodes, aShape, anAffected);
6769 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6774 int lg = anAffected.size();
6775 MESSAGE("lg="<< lg);
6776 SMESH::long_array_var volumeIds = new SMESH::long_array;
6777 volumeIds->length(lg);
6778 SMESH::long_array_var faceIds = new SMESH::long_array;
6779 faceIds->length(lg);
6780 SMESH::long_array_var edgeIds = new SMESH::long_array;
6781 edgeIds->length(lg);
6786 TIDSortedElemSet::const_iterator eIt = anAffected.begin();
6787 for (; eIt != anAffected.end(); ++eIt)
6789 const SMDS_MeshElement* anElem = *eIt;
6792 int elemId = anElem->GetID();
6793 if (myMesh->GetElementType(elemId, true) == SMDSAbs_Volume)
6794 volumeIds[ivol++] = elemId;
6795 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Face)
6796 faceIds[iface++] = elemId;
6797 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Edge)
6798 edgeIds[iedge++] = elemId;
6800 volumeIds->length(ivol);
6801 faceIds->length(iface);
6802 edgeIds->length(iedge);
6804 aNewVolumeGroup->Add(volumeIds);
6805 aNewFaceGroup->Add(faceIds);
6806 aNewEdgeGroup->Add(edgeIds);
6807 isVolumeGroup = (aNewVolumeGroup->Size() > 0);
6808 isFaceGroup = (aNewFaceGroup->Size() > 0);
6809 isEdgeGroup = (aNewEdgeGroup->Size() > 0);
6813 if (isEdgeGroup) nbGroups++;
6814 if (isFaceGroup) nbGroups++;
6815 if (isVolumeGroup) nbGroups++;
6816 aListOfGroups->length(nbGroups);
6819 if (isEdgeGroup) aListOfGroups[i++] = aNewEdgeGroup._retn();
6820 if (isFaceGroup) aListOfGroups[i++] = aNewFaceGroup._retn();
6821 if (isVolumeGroup) aListOfGroups[i++] = aNewVolumeGroup._retn();
6823 // Update Python script
6826 if (isEdgeGroup) pyDump << aNewEdgeGroup << ", ";
6827 if (isFaceGroup) pyDump << aNewFaceGroup << ", ";
6828 if (isVolumeGroup) pyDump << aNewVolumeGroup << ", ";
6830 pyDump << this << ".AffectedElemGroupsInRegion( "
6831 << &theElems << ", " << &theNodesNot << ", " << theShape << " )";
6833 return aListOfGroups._retn();
6835 SMESH_CATCH( SMESH::throwCorbaException );
6839 //================================================================================
6841 \brief Generated skin mesh (containing 2D cells) from 3D mesh
6842 The created 2D mesh elements based on nodes of free faces of boundary volumes
6843 \return TRUE if operation has been completed successfully, FALSE otherwise
6845 //================================================================================
6847 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
6848 throw (SALOME::SALOME_Exception)
6853 bool aResult = getEditor().Make2DMeshFrom3D();
6855 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
6857 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6860 SMESH_CATCH( SMESH::throwCorbaException );
6864 //================================================================================
6866 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
6867 * The list of groups must contain at least two groups. The groups have to be disjoint:
6868 * no common element into two different groups.
6869 * The nodes of the internal faces at the boundaries of the groups are doubled.
6870 * Optionally, the internal faces are replaced by flat elements.
6871 * Triangles are transformed into prisms, and quadrangles into hexahedrons.
6872 * The flat elements are stored in groups of volumes.
6873 * These groups are named according to the position of the group in the list:
6874 * the group j_n_p is the group of the flat elements that are built between the group #n and the group #p in the list.
6875 * If there is no shared faces between the group #n and the group #p in the list, the group j_n_p is not created.
6876 * All the flat elements are gathered into the group named "joints3D" (or "joints2D" in 2D situation).
6877 * The flat element of the multiple junctions between the simple junction are stored in a group named "jointsMultiples".
6878 * \param theDomains - list of groups of volumes
6879 * \param createJointElems - if TRUE, create the elements
6880 * \param onAllBoundaries - if TRUE, the nodes and elements are also created on
6881 * the boundary between \a theDomains and the rest mesh
6882 * \return TRUE if operation has been completed successfully, FALSE otherwise
6884 //================================================================================
6887 SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
6888 CORBA::Boolean createJointElems,
6889 CORBA::Boolean onAllBoundaries )
6890 throw (SALOME::SALOME_Exception)
6897 SMESHDS_Mesh* aMeshDS = getMeshDS();
6899 // MESSAGE("theDomains.length = "<<theDomains.length());
6900 if ( theDomains.length() <= 1 && !onAllBoundaries )
6901 THROW_SALOME_CORBA_EXCEPTION("At least 2 groups are required.", SALOME::BAD_PARAM);
6903 vector<TIDSortedElemSet> domains;
6904 domains.resize( theDomains.length() );
6906 for ( int i = 0, n = theDomains.length(); i < n; i++ )
6908 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
6909 if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
6911 // if ( aGrp->GetType() != SMESH::VOLUME )
6912 // THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
6913 SMESH::long_array_var anIDs = aGrp->GetIDs();
6914 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
6918 isOK = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems, onAllBoundaries );
6919 // TODO publish the groups of flat elements in study
6921 declareMeshModified( /*isReComputeSafe=*/ !isOK );
6923 // Update Python script
6924 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
6925 << ", " << createJointElems << ", " << onAllBoundaries << " )";
6927 SMESH_CATCH( SMESH::throwCorbaException );
6929 myMesh_i->CreateGroupServants(); // publish created groups if any
6934 //================================================================================
6936 * \brief Double nodes on some external faces and create flat elements.
6937 * Flat elements are mainly used by some types of mechanic calculations.
6939 * Each group of the list must be constituted of faces.
6940 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
6941 * @param theGroupsOfFaces - list of groups of faces
6942 * @return TRUE if operation has been completed successfully, FALSE otherwise
6944 //================================================================================
6947 SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
6948 throw (SALOME::SALOME_Exception)
6953 SMESHDS_Mesh* aMeshDS = getMeshDS();
6955 vector<TIDSortedElemSet> faceGroups;
6958 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
6960 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
6961 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
6963 TIDSortedElemSet faceGroup;
6965 faceGroups.push_back(faceGroup);
6966 SMESH::long_array_var anIDs = aGrp->GetIDs();
6967 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
6971 bool aResult = getEditor().CreateFlatElementsOnFacesGroups( faceGroups );
6972 // TODO publish the groups of flat elements in study
6974 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6976 // Update Python script
6977 TPythonDump() << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
6980 SMESH_CATCH( SMESH::throwCorbaException );
6984 //================================================================================
6986 * \brief Identify all the elements around a geom shape, get the faces delimiting
6989 * Build groups of volume to remove, groups of faces to replace on the skin of the
6990 * object, groups of faces to remove inside the object, (idem edges).
6991 * Build ordered list of nodes at the border of each group of faces to replace
6992 * (to be used to build a geom subshape).
6994 //================================================================================
6996 void SMESH_MeshEditor_i::CreateHoleSkin(CORBA::Double radius,
6997 GEOM::GEOM_Object_ptr theShape,
6998 const char* groupName,
6999 const SMESH::double_array& theNodesCoords,
7000 SMESH::array_of_long_array_out GroupsOfNodes)
7001 throw (SALOME::SALOME_Exception)
7006 std::vector<std::vector<int> > aListOfListOfNodes;
7007 ::SMESH_MeshEditor aMeshEditor( myMesh );
7009 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
7010 if ( !theNodeSearcher )
7011 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
7013 vector<double> nodesCoords;
7014 for (int i = 0; i < theNodesCoords.length(); i++)
7016 nodesCoords.push_back( theNodesCoords[i] );
7019 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
7020 aMeshEditor.CreateHoleSkin(radius, aShape, theNodeSearcher, groupName,
7021 nodesCoords, aListOfListOfNodes);
7023 GroupsOfNodes = new SMESH::array_of_long_array;
7024 GroupsOfNodes->length( aListOfListOfNodes.size() );
7025 std::vector<std::vector<int> >::iterator llIt = aListOfListOfNodes.begin();
7026 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
7028 vector<int>& aListOfNodes = *llIt;
7029 vector<int>::iterator lIt = aListOfNodes.begin();;
7030 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
7031 aGroup.length( aListOfNodes.size() );
7032 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
7033 aGroup[ j ] = (*lIt);
7035 TPythonDump() << "lists_nodes = " << this << ".CreateHoleSkin( "
7038 << ", '" << groupName << "', "
7039 << theNodesCoords << " )";
7041 SMESH_CATCH( SMESH::throwCorbaException );
7044 // issue 20749 ===================================================================
7046 * \brief Creates missing boundary elements
7047 * \param elements - elements whose boundary is to be checked
7048 * \param dimension - defines type of boundary elements to create
7049 * \param groupName - a name of group to store created boundary elements in,
7050 * "" means not to create the group
7051 * \param meshName - a name of new mesh to store created boundary elements in,
7052 * "" means not to create the new mesh
7053 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
7054 * \param toCopyExistingBondary - if true, not only new but also pre-existing
7055 * boundary elements will be copied into the new mesh
7056 * \param group - returns the create group, if any
7057 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
7059 // ================================================================================
7061 SMESH::SMESH_Mesh_ptr
7062 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
7063 SMESH::Bnd_Dimension dim,
7064 const char* groupName,
7065 const char* meshName,
7066 CORBA::Boolean toCopyElements,
7067 CORBA::Boolean toCopyExistingBondary,
7068 SMESH::SMESH_Group_out group)
7069 throw (SALOME::SALOME_Exception)
7074 if ( dim > SMESH::BND_1DFROM2D )
7075 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
7077 SMESHDS_Mesh* aMeshDS = getMeshDS();
7079 SMESH::SMESH_Mesh_var mesh_var;
7080 SMESH::SMESH_Group_var group_var;
7084 TIDSortedElemSet elements;
7085 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
7086 prepareIdSource( idSource );
7087 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
7091 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
7092 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
7094 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
7096 // group of new boundary elements
7097 SMESH_Group* smesh_group = 0;
7098 if ( strlen(groupName) )
7100 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
7101 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
7102 smesh_group = group_i->GetSmeshGroup();
7106 getEditor().MakeBoundaryMesh( elements,
7107 ::SMESH_MeshEditor::Bnd_Dimension(dim),
7111 toCopyExistingBondary);
7114 smesh_mesh->GetMeshDS()->Modified();
7117 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
7119 // result of MakeBoundaryMesh() is a tuple (mesh, group)
7120 if ( mesh_var->_is_nil() )
7121 pyDump << myMesh_i->_this() << ", ";
7123 pyDump << mesh_var << ", ";
7124 if ( group_var->_is_nil() )
7125 pyDump << "_NoneGroup = "; // assignment to None is forbiden
7127 pyDump << group_var << " = ";
7128 pyDump << this << ".MakeBoundaryMesh( "
7130 << "SMESH." << dimName[int(dim)] << ", "
7131 << "'" << groupName << "', "
7132 << "'" << meshName<< "', "
7133 << toCopyElements << ", "
7134 << toCopyExistingBondary << ")";
7136 group = group_var._retn();
7137 return mesh_var._retn();
7139 SMESH_CATCH( SMESH::throwCorbaException );
7140 return SMESH::SMESH_Mesh::_nil();
7143 //================================================================================
7145 * \brief Creates missing boundary elements
7146 * \param dimension - defines type of boundary elements to create
7147 * \param groupName - a name of group to store all boundary elements in,
7148 * "" means not to create the group
7149 * \param meshName - a name of a new mesh, which is a copy of the initial
7150 * mesh + created boundary elements; "" means not to create the new mesh
7151 * \param toCopyAll - if true, the whole initial mesh will be copied into
7152 * the new mesh else only boundary elements will be copied into the new mesh
7153 * \param groups - optional groups of elements to make boundary around
7154 * \param mesh - returns the mesh where elements were added to
7155 * \param group - returns the created group, if any
7156 * \retval long - number of added boundary elements
7158 //================================================================================
7160 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
7161 const char* groupName,
7162 const char* meshName,
7163 CORBA::Boolean toCopyAll,
7164 const SMESH::ListOfIDSources& groups,
7165 SMESH::SMESH_Mesh_out mesh,
7166 SMESH::SMESH_Group_out group)
7167 throw (SALOME::SALOME_Exception)
7172 if ( dim > SMESH::BND_1DFROM2D )
7173 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
7175 // separate groups belonging to this and other mesh
7176 SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
7177 SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
7178 groupsOfThisMesh->length( groups.length() );
7179 groupsOfOtherMesh->length( groups.length() );
7180 int nbGroups = 0, nbGroupsOfOtherMesh = 0;
7181 for ( int i = 0; i < groups.length(); ++i )
7183 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
7184 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
7185 groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
7187 groupsOfThisMesh[ nbGroups++ ] = groups[i];
7188 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
7189 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
7191 groupsOfThisMesh->length( nbGroups );
7192 groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
7197 if ( nbGroupsOfOtherMesh > 0 )
7199 // process groups belonging to another mesh
7200 SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
7201 SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
7202 nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
7203 groupsOfOtherMesh, mesh, group );
7206 SMESH::SMESH_Mesh_var mesh_var;
7207 SMESH::SMESH_Group_var group_var;
7210 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
7211 const bool toCopyMesh = ( strlen( meshName ) > 0 );
7215 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
7217 /*toCopyGroups=*/false,
7218 /*toKeepIDs=*/true);
7220 mesh_var = makeMesh(meshName);
7222 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
7223 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
7226 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
7227 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
7229 // group of boundary elements
7230 SMESH_Group* smesh_group = 0;
7231 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
7232 if ( strlen(groupName) )
7234 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
7235 group_var = mesh_i->CreateGroup( groupType, groupName );
7236 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
7237 smesh_group = group_i->GetSmeshGroup();
7240 TIDSortedElemSet elements;
7242 if ( groups.length() > 0 )
7244 for ( int i = 0; i < nbGroups; ++i )
7247 if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
7249 SMESH::Bnd_Dimension bdim =
7250 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
7251 nbAdded += getEditor().MakeBoundaryMesh( elements,
7252 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
7255 /*toCopyElements=*/false,
7256 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
7257 /*toAddExistingBondary=*/true,
7258 /*aroundElements=*/true);
7264 nbAdded += getEditor().MakeBoundaryMesh( elements,
7265 ::SMESH_MeshEditor::Bnd_Dimension(dim),
7268 /*toCopyElements=*/false,
7269 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
7270 /*toAddExistingBondary=*/true);
7272 tgtMesh->GetMeshDS()->Modified();
7274 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
7276 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
7277 pyDump << "nbAdded, ";
7278 if ( mesh_var->_is_nil() )
7279 pyDump << myMesh_i->_this() << ", ";
7281 pyDump << mesh_var << ", ";
7282 if ( group_var->_is_nil() )
7283 pyDump << "_NoneGroup = "; // assignment to None is forbiden
7285 pyDump << group_var << " = ";
7286 pyDump << this << ".MakeBoundaryElements( "
7287 << "SMESH." << dimName[int(dim)] << ", "
7288 << "'" << groupName << "', "
7289 << "'" << meshName<< "', "
7290 << toCopyAll << ", "
7293 mesh = mesh_var._retn();
7294 group = group_var._retn();
7297 SMESH_CATCH( SMESH::throwCorbaException );