1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_MeshEditor_i.cxx
23 // Author : Nicolas REJNERI
30 // A macro used in SMESH_TryCatch.hxx,
31 // it re-raises a CORBA SALOME exception thrown by SMESH_MeshEditor_i and caught by SMESH_CATCH
32 #define SMY_OWN_CATCH \
33 catch ( SALOME::SALOME_Exception & e ) { throw e; }
35 #include "SMESH_MeshEditor_i.hxx"
37 #include "SMDS_EdgePosition.hxx"
38 #include "SMDS_ElemIterator.hxx"
39 #include "SMDS_FacePosition.hxx"
40 #include "SMDS_IteratorOnIterators.hxx"
41 #include "SMDS_LinearEdge.hxx"
42 #include "SMDS_Mesh0DElement.hxx"
43 #include "SMDS_MeshFace.hxx"
44 #include "SMDS_MeshVolume.hxx"
45 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
46 #include "SMDS_SetIterator.hxx"
47 #include "SMDS_VolumeTool.hxx"
48 #include "SMESHDS_Group.hxx"
49 #include "SMESHDS_GroupOnGeom.hxx"
50 #include "SMESH_ControlsDef.hxx"
51 #include "SMESH_Filter_i.hxx"
52 #include "SMESH_Gen_i.hxx"
53 #include "SMESH_Group.hxx"
54 #include "SMESH_Group_i.hxx"
55 #include "SMESH_MeshAlgos.hxx"
56 #include "SMESH_MeshPartDS.hxx"
57 #include "SMESH_MesherHelper.hxx"
58 #include "SMESH_PythonDump.hxx"
59 #include "SMESH_subMeshEventListener.hxx"
60 #include "SMESH_subMesh_i.hxx"
62 #include <utilities.h>
63 #include <Utils_ExceptHandlers.hxx>
64 #include <Utils_CorbaException.hxx>
65 #include <SALOMEDS_wrap.hxx>
66 #include <SALOME_GenericObj_i.hh>
68 #include <BRepAdaptor_Surface.hxx>
69 #include <BRep_Tool.hxx>
70 #include <TopExp_Explorer.hxx>
72 #include <TopoDS_Edge.hxx>
73 #include <TopoDS_Face.hxx>
78 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
82 #include <Standard_Failure.hxx>
85 #include <Standard_ErrorHandler.hxx>
91 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
93 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
96 using SMESH::TPythonDump;
99 namespace MeshEditor_I {
101 //=============================================================================
103 * \brief Mesh to apply modifications for preview purposes
105 //=============================================================================
107 struct TPreviewMesh: public SMESH_Mesh
109 SMDSAbs_ElementType myPreviewType; // type to show
111 TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
112 _isShapeToMesh = (_id =_studyId = 0);
113 _myMeshDS = new SMESHDS_Mesh( _id, true );
114 myPreviewType = previewElements;
117 virtual ~TPreviewMesh() { delete _myMeshDS; _myMeshDS = 0; }
118 //!< Copy a set of elements
119 void Copy(const TIDSortedElemSet & theElements,
120 TIDSortedElemSet& theCopyElements,
121 SMDSAbs_ElementType theSelectType = SMDSAbs_All,
122 SMDSAbs_ElementType theAvoidType = SMDSAbs_All)
124 // loop on theIDsOfElements
125 TIDSortedElemSet::const_iterator eIt = theElements.begin();
126 for ( ; eIt != theElements.end(); ++eIt )
128 const SMDS_MeshElement* anElem = *eIt;
129 if ( !anElem ) continue;
130 SMDSAbs_ElementType type = anElem->GetType();
131 if ( type == theAvoidType ||
132 ( theSelectType != SMDSAbs_All && type != theSelectType ))
134 const SMDS_MeshElement* anElemCopy;
135 if ( type == SMDSAbs_Node)
136 anElemCopy = Copy( cast2Node(anElem) );
138 anElemCopy = Copy( anElem );
140 theCopyElements.insert( theCopyElements.end(), anElemCopy );
144 SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
146 // copy element nodes
147 int anElemNbNodes = anElem->NbNodes();
148 vector< int > anElemNodesID( anElemNbNodes ) ;
149 SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
150 for ( int i = 0; itElemNodes->more(); i++)
152 const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
154 anElemNodesID[i] = anElemNode->GetID();
157 // creates a corresponding element on copied nodes
158 SMDS_MeshElement* anElemCopy = 0;
159 if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
161 const SMDS_VtkVolume* ph =
162 dynamic_cast<const SMDS_VtkVolume*> (anElem);
164 anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
165 (anElemNodesID, ph->GetQuantities(),anElem->GetID());
168 anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
175 SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
177 return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(),
178 anElemNode->GetID());
182 GetMeshDS()->ClearMesh();
184 };// struct TPreviewMesh
186 static SMESH_NodeSearcher * theNodeSearcher = 0;
187 static SMESH_ElementSearcher * theElementSearcher = 0;
189 //=============================================================================
191 * \brief Deleter of theNodeSearcher at any compute event occured
193 //=============================================================================
195 struct TSearchersDeleter : public SMESH_subMeshEventListener
198 string myMeshPartIOR;
200 TSearchersDeleter(): SMESH_subMeshEventListener( false, // won't be deleted by submesh
201 "SMESH_MeshEditor_i::TSearchersDeleter"),
203 //!< Delete theNodeSearcher
206 if ( theNodeSearcher ) delete theNodeSearcher; theNodeSearcher = 0;
207 if ( theElementSearcher ) delete theElementSearcher; theElementSearcher = 0;
209 typedef map < int, SMESH_subMesh * > TDependsOnMap;
210 //!< The meshod called by submesh: do my main job
211 void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
212 SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
214 if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
216 Unset( sm->GetFather() );
219 //!< set self on all submeshes and delete theNodeSearcher if other mesh is set
220 void Set(SMESH_Mesh* mesh, const string& meshPartIOR = string())
222 if ( myMesh != mesh || myMeshPartIOR != meshPartIOR)
229 myMeshPartIOR = meshPartIOR;
230 SMESH_subMesh* sm = mesh->GetSubMesh( mesh->GetShapeToMesh() );
231 SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true );
232 while ( smIt->more() )
235 sm->SetEventListener( this, 0, sm );
239 //!< delete self from all submeshes
240 void Unset(SMESH_Mesh* mesh)
242 if ( SMESH_subMesh* sm = mesh->GetSubMeshContaining(1) ) {
243 SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true );
244 while ( smIt->more() )
245 smIt->next()->DeleteEventListener( this );
250 } theSearchersDeleter;
252 TCollection_AsciiString mirrorTypeName( SMESH::SMESH_MeshEditor::MirrorType theMirrorType )
254 TCollection_AsciiString typeStr;
255 switch ( theMirrorType ) {
256 case SMESH::SMESH_MeshEditor::POINT:
257 typeStr = "SMESH.SMESH_MeshEditor.POINT";
259 case SMESH::SMESH_MeshEditor::AXIS:
260 typeStr = "SMESH.SMESH_MeshEditor.AXIS";
263 typeStr = "SMESH.SMESH_MeshEditor.PLANE";
267 //================================================================================
269 * \brief function for conversion of long_array to TIDSortedElemSet
270 * \param IDs - array of IDs
271 * \param aMesh - mesh
272 * \param aMap - collection to fill
273 * \param aType - element type
275 //================================================================================
277 void arrayToSet(const SMESH::long_array & IDs,
278 const SMESHDS_Mesh* aMesh,
279 TIDSortedElemSet& aMap,
280 const SMDSAbs_ElementType aType = SMDSAbs_All,
281 SMDS_MeshElement::Filter* aFilter = NULL)
283 SMDS_MeshElement::NonNullFilter filter1;
284 SMDS_MeshElement::TypeFilter filter2( aType );
286 if ( aFilter == NULL )
287 aFilter = ( aType == SMDSAbs_All ) ? (SMDS_MeshElement::Filter*) &filter1 : (SMDS_MeshElement::Filter*) &filter2;
289 SMDS_MeshElement::Filter & filter = *aFilter;
291 if ( aType == SMDSAbs_Node )
292 for (int i=0; i<IDs.length(); i++) {
293 const SMDS_MeshElement * elem = aMesh->FindNode( IDs[i] );
295 aMap.insert( aMap.end(), elem );
298 for (int i=0; i<IDs.length(); i++) {
299 const SMDS_MeshElement * elem = aMesh->FindElement( IDs[i] );
301 aMap.insert( aMap.end(), elem );
304 //================================================================================
306 * \brief Retrieve elements of given type from SMESH_IDSource
308 //================================================================================
310 bool idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource,
311 const SMESHDS_Mesh* theMeshDS,
312 TIDSortedElemSet& theElemSet,
313 const SMDSAbs_ElementType theType,
314 const bool emptyIfIsMesh=false)
317 if ( CORBA::is_nil( theIDSource ) )
319 if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
322 SMESH::long_array_var anIDs = theIDSource->GetIDs();
323 if ( anIDs->length() == 0 )
325 SMESH::array_of_ElementType_var types = theIDSource->GetTypes();
326 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
328 if ( theType == SMDSAbs_All || theType == SMDSAbs_Node )
329 arrayToSet( anIDs, theMeshDS, theElemSet, SMDSAbs_Node );
335 arrayToSet( anIDs, theMeshDS, theElemSet, theType);
336 return bool(anIDs->length()) == bool(theElemSet.size());
340 //================================================================================
342 * \brief Retrieve nodes from SMESH_IDSource
344 //================================================================================
346 void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject,
347 const SMESHDS_Mesh* theMeshDS,
348 TIDSortedNodeSet& theNodeSet)
351 if ( CORBA::is_nil( theObject ) )
353 SMESH::array_of_ElementType_var types = theObject->GetTypes();
354 SMESH::long_array_var aElementsId = theObject->GetIDs();
355 if ( types->length() == 1 && types[0] == SMESH::NODE)
357 for(int i = 0; i < aElementsId->length(); i++)
358 if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] ))
359 theNodeSet.insert( theNodeSet.end(), n);
361 else if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
363 SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator();
364 while ( nIt->more( ))
365 if( const SMDS_MeshElement * elem = nIt->next() )
366 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
370 for(int i = 0; i < aElementsId->length(); i++)
371 if( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] ))
372 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
376 //================================================================================
378 * \brief Returns elements connected to the given elements
380 //================================================================================
382 void getElementsAround(const TIDSortedElemSet& theElements,
383 const SMESHDS_Mesh* theMeshDS,
384 TIDSortedElemSet& theElementsAround)
386 if ( theElements.empty() ) return;
388 SMDSAbs_ElementType elemType = (*theElements.begin())->GetType();
389 bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() );
391 theMeshDS->GetMeshInfo().NbElements( elemType ) == theElements.size() )
392 return; // all the elements are in theElements
395 elemType = SMDSAbs_All;
397 TIDSortedElemSet visitedNodes;
398 TIDSortedElemSet::const_iterator elemIt = theElements.begin();
399 for ( ; elemIt != theElements.end(); ++elemIt )
401 const SMDS_MeshElement* e = *elemIt;
402 int i = e->NbCornerNodes();
405 const SMDS_MeshNode* n = e->GetNode( i );
406 if ( visitedNodes.insert( n ).second )
408 SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
409 while ( invIt->more() )
411 const SMDS_MeshElement* elemAround = invIt->next();
412 if ( !theElements.count( elemAround ))
413 theElementsAround.insert( elemAround );
420 //================================================================================
422 * \brief Return a string used to detect change of mesh part on which theElementSearcher
423 * is going to be used
425 //================================================================================
427 string getPartIOR( SMESH::SMESH_IDSource_ptr theMeshPart, SMESH::ElementType type)
429 string partIOR = SMESH_Gen_i::GetORB()->object_to_string( theMeshPart );
430 if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( theMeshPart ))
431 // take into account passible group modification
432 partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() );
433 partIOR += SMESH_Comment( type );
437 } // namespace MeshEditor_I
439 using namespace MeshEditor_I;
441 //=============================================================================
445 //=============================================================================
447 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview):
449 myMesh( &theMesh->GetImpl() ),
451 myIsPreviewMode ( isPreview ),
457 //================================================================================
461 //================================================================================
463 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
465 PortableServer::POA_var poa = SMESH_Gen_i::GetPOA();
466 PortableServer::ObjectId_var anObjectId = poa->servant_to_id(this);
467 poa->deactivate_object(anObjectId.in());
469 //deleteAuxIDSources();
470 delete myPreviewMesh; myPreviewMesh = 0;
471 delete myPreviewEditor; myPreviewEditor = 0;
474 //================================================================================
476 * \brief Clear members
478 //================================================================================
480 void SMESH_MeshEditor_i::initData(bool deleteSearchers)
482 if ( myIsPreviewMode ) {
483 if ( myPreviewMesh ) myPreviewMesh->RemoveAll();
486 if ( deleteSearchers )
487 TSearchersDeleter::Delete();
489 getEditor().GetError().reset();
490 getEditor().CrearLastCreated();
493 //================================================================================
495 * \brief Increment mesh modif time and optionally record that the performed
496 * modification may influence futher mesh re-compute.
497 * \param [in] isReComputeSafe - true if the modification does not infulence
498 * futher mesh re-compute
500 //================================================================================
502 void SMESH_MeshEditor_i::declareMeshModified( bool isReComputeSafe )
504 myMesh->GetMeshDS()->Modified();
505 if ( !isReComputeSafe )
506 myMesh->SetIsModified( true );
509 //================================================================================
511 * \brief Return either myEditor or myPreviewEditor depending on myIsPreviewMode.
512 * WARNING: in preview mode call getPreviewMesh() before getEditor()!
514 //================================================================================
516 ::SMESH_MeshEditor& SMESH_MeshEditor_i::getEditor()
518 if ( myIsPreviewMode && !myPreviewEditor ) {
519 if ( !myPreviewMesh ) getPreviewMesh();
520 myPreviewEditor = new ::SMESH_MeshEditor( myPreviewMesh );
522 return myIsPreviewMode ? *myPreviewEditor : myEditor;
525 //================================================================================
527 * \brief Initialize and return myPreviewMesh
528 * \param previewElements - type of elements to show in preview
530 * WARNING: call it once par a method!
532 //================================================================================
534 TPreviewMesh * SMESH_MeshEditor_i::getPreviewMesh(SMDSAbs_ElementType previewElements)
536 if ( !myPreviewMesh || myPreviewMesh->myPreviewType != previewElements )
538 delete myPreviewEditor;
540 delete myPreviewMesh;
541 myPreviewMesh = new TPreviewMesh( previewElements );
543 myPreviewMesh->Clear();
544 return myPreviewMesh;
547 //================================================================================
549 * Return data of mesh edition preview
551 //================================================================================
553 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
554 throw (SALOME::SALOME_Exception)
557 const bool hasBadElems = ( getEditor().GetError() && getEditor().GetError()->HasBadElems() );
559 if ( myIsPreviewMode || hasBadElems ) { // --- MeshPreviewStruct filling ---
561 list<int> aNodesConnectivity;
562 typedef map<int, int> TNodesMap;
565 SMESHDS_Mesh* aMeshDS;
566 std::auto_ptr< SMESH_MeshPartDS > aMeshPartDS;
568 aMeshPartDS.reset( new SMESH_MeshPartDS( getEditor().GetError()->myBadElements ));
569 aMeshDS = aMeshPartDS.get();
572 aMeshDS = getEditor().GetMeshDS();
574 myPreviewData = new SMESH::MeshPreviewStruct();
575 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
578 SMDSAbs_ElementType previewType = SMDSAbs_All;
580 if (TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( getEditor().GetMesh() )) {
581 previewType = aPreviewMesh->myPreviewType;
582 switch ( previewType ) {
583 case SMDSAbs_Edge : break;
584 case SMDSAbs_Face : break;
585 case SMDSAbs_Volume: break;
587 if ( aMeshDS->GetMeshInfo().NbElements() == 0 ) previewType = SMDSAbs_Node;
591 myPreviewData->elementTypes.length( aMeshDS->GetMeshInfo().NbElements( previewType ));
593 SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator(previewType);
595 while ( itMeshElems->more() ) {
596 const SMDS_MeshElement* aMeshElem = itMeshElems->next();
597 SMDS_NodeIteratorPtr itElemNodes = aMeshElem->nodeIterator();
598 while ( itElemNodes->more() ) {
599 const SMDS_MeshNode* aMeshNode = itElemNodes->next();
600 int aNodeID = aMeshNode->GetID();
601 TNodesMap::iterator anIter = nodesMap.find(aNodeID);
602 if ( anIter == nodesMap.end() ) {
603 // filling the nodes coordinates
604 myPreviewData->nodesXYZ[j].x = aMeshNode->X();
605 myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
606 myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
607 anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
610 aNodesConnectivity.push_back(anIter->second);
613 // filling the elements types
614 SMDSAbs_ElementType aType = aMeshElem->GetType();
615 bool isPoly = aMeshElem->IsPoly();
616 myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
617 myPreviewData->elementTypes[i].isPoly = isPoly;
618 myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
621 myPreviewData->nodesXYZ.length( j );
623 // filling the elements connectivities
624 list<int>::iterator aConnIter = aNodesConnectivity.begin();
625 myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
626 for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
627 myPreviewData->elementConnectivities[i] = *aConnIter;
629 return myPreviewData._retn();
631 SMESH_CATCH( SMESH::throwCorbaException );
635 //================================================================================
637 * \brief Returns list of it's IDs of created nodes
638 * \retval SMESH::long_array* - list of node ID
640 //================================================================================
642 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
643 throw (SALOME::SALOME_Exception)
646 SMESH::long_array_var myLastCreatedNodes = new SMESH::long_array();
648 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedNodes();
649 myLastCreatedNodes->length( aSeq.Length() );
650 for (int i = 1; i <= aSeq.Length(); i++)
651 myLastCreatedNodes[i-1] = aSeq.Value(i)->GetID();
653 return myLastCreatedNodes._retn();
654 SMESH_CATCH( SMESH::throwCorbaException );
658 //================================================================================
660 * \brief Returns list of it's IDs of created elements
661 * \retval SMESH::long_array* - list of elements' ID
663 //================================================================================
665 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
666 throw (SALOME::SALOME_Exception)
669 SMESH::long_array_var myLastCreatedElems = new SMESH::long_array();
671 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
672 myLastCreatedElems->length( aSeq.Length() );
673 for ( int i = 1; i <= aSeq.Length(); i++ )
674 myLastCreatedElems[i-1] = aSeq.Value(i)->GetID();
676 return myLastCreatedElems._retn();
677 SMESH_CATCH( SMESH::throwCorbaException );
681 //=======================================================================
682 //function : ClearLastCreated
683 //purpose : Clears sequences of last created elements and nodes
684 //=======================================================================
686 void SMESH_MeshEditor_i::ClearLastCreated() throw (SALOME::SALOME_Exception)
689 getEditor().CrearLastCreated();
690 SMESH_CATCH( SMESH::throwCorbaException );
693 //=======================================================================
695 * Returns description of an error/warning occured during the last operation
696 * WARNING: ComputeError.code >= 100 and no corresponding enum in IDL API
698 //=======================================================================
700 SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError()
701 throw (SALOME::SALOME_Exception)
704 SMESH::ComputeError_var errOut = new SMESH::ComputeError;
705 SMESH_ComputeErrorPtr& errIn = getEditor().GetError();
706 if ( errIn && !errIn->IsOK() )
708 errOut->code = -( errIn->myName < 0 ? errIn->myName + 1: errIn->myName ); // -1 -> 0
709 errOut->comment = errIn->myComment.c_str();
710 errOut->subShapeID = -1;
711 errOut->hasBadMesh = !errIn->myBadElements.empty();
716 errOut->subShapeID = -1;
717 errOut->hasBadMesh = false;
720 return errOut._retn();
721 SMESH_CATCH( SMESH::throwCorbaException );
725 //=======================================================================
726 //function : MakeIDSource
727 //purpose : Wrap a sequence of ids in a SMESH_IDSource.
728 // Call UnRegister() as you fininsh using it!!
729 //=======================================================================
731 struct SMESH_MeshEditor_i::_IDSource : public virtual POA_SMESH::SMESH_IDSource,
732 public virtual SALOME::GenericObj_i
734 SMESH::long_array _ids;
735 SMESH::ElementType _type;
736 SMESH::SMESH_Mesh_ptr _mesh;
737 SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); }
738 SMESH::long_array* GetMeshInfo() { return 0; }
739 SMESH::long_array* GetNbElementsByType()
741 SMESH::long_array_var aRes = new SMESH::long_array();
742 aRes->length(SMESH::NB_ELEMENT_TYPES);
743 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
744 aRes[ i ] = ( i == _type ) ? _ids.length() : 0;
747 SMESH::SMESH_Mesh_ptr GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _mesh ); }
748 bool IsMeshInfoCorrect() { return true; }
749 SMESH::array_of_ElementType* GetTypes()
751 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
752 if ( _ids.length() > 0 ) {
756 return types._retn();
760 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
761 SMESH::ElementType type)
763 // if ( myAuxIDSources.size() > 10 ) {
764 // delete myAuxIDSources.front();
765 // myAuxIDSources.pop_front();
768 _IDSource* idSrc = new _IDSource;
769 idSrc->_mesh = myMesh_i->_this();
772 //myAuxIDSources.push_back( idSrc );
774 SMESH::SMESH_IDSource_var anIDSourceVar = idSrc->_this();
776 return anIDSourceVar._retn();
779 bool SMESH_MeshEditor_i::IsTemporaryIDSource( SMESH::SMESH_IDSource_ptr& idSource )
781 return SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource );
784 CORBA::Long* SMESH_MeshEditor_i::GetTemporaryIDs( SMESH::SMESH_IDSource_ptr& idSource,
787 if ( _IDSource* tmpIdSource = SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource ))
789 nbIds = (int) tmpIdSource->_ids.length();
790 return & tmpIdSource->_ids[0];
796 // void SMESH_MeshEditor_i::deleteAuxIDSources()
798 // std::list< _IDSource* >::iterator idSrcIt = myAuxIDSources.begin();
799 // for ( ; idSrcIt != myAuxIDSources.end(); ++idSrcIt )
801 // myAuxIDSources.clear();
804 //=============================================================================
808 //=============================================================================
811 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
812 throw (SALOME::SALOME_Exception)
819 for (int i = 0; i < IDsOfElements.length(); i++)
820 IdList.push_back( IDsOfElements[i] );
822 // Update Python script
823 TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
826 bool ret = getEditor().Remove( IdList, false );
828 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 ); // issue 0020693
831 SMESH_CATCH( SMESH::throwCorbaException );
835 //=============================================================================
839 //=============================================================================
841 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
842 throw (SALOME::SALOME_Exception)
848 for (int i = 0; i < IDsOfNodes.length(); i++)
849 IdList.push_back( IDsOfNodes[i] );
851 // Update Python script
852 TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
854 bool ret = getEditor().Remove( IdList, true );
856 declareMeshModified( /*isReComputeSafe=*/ !ret ); // issue 0020693
859 SMESH_CATCH( SMESH::throwCorbaException );
863 //=============================================================================
867 //=============================================================================
869 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
870 throw (SALOME::SALOME_Exception)
875 // Update Python script
876 TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
878 // Create filter to find all orphan nodes
879 SMESH::Controls::Filter::TIdSequence seq;
880 SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
881 SMESH::Controls::Filter::GetElementsId( getMeshDS(), predicate, seq );
883 // remove orphan nodes (if there are any)
885 for ( int i = 0; i < seq.size(); i++ )
886 IdList.push_back( seq[i] );
888 int nbNodesBefore = myMesh->NbNodes();
889 getEditor().Remove( IdList, true );
890 int nbNodesAfter = myMesh->NbNodes();
892 declareMeshModified( /*isReComputeSafe=*/ IdList.size() == 0 ); // issue 0020693
893 return nbNodesBefore - nbNodesAfter;
895 SMESH_CATCH( SMESH::throwCorbaException );
899 //=============================================================================
903 //=============================================================================
905 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,CORBA::Double y, CORBA::Double z)
906 throw (SALOME::SALOME_Exception)
911 const SMDS_MeshNode* N = getMeshDS()->AddNode(x, y, z);
913 // Update Python script
914 TPythonDump() << "nodeID = " << this << ".AddNode( "
915 << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )";
917 declareMeshModified( /*isReComputeSafe=*/false );
920 SMESH_CATCH( SMESH::throwCorbaException );
924 //=============================================================================
926 * Create 0D element on the given node.
928 //=============================================================================
930 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
931 throw (SALOME::SALOME_Exception)
936 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
937 SMDS_MeshElement* elem = getMeshDS()->Add0DElement(aNode);
939 // Update Python script
940 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
942 declareMeshModified( /*isReComputeSafe=*/false );
944 return elem ? elem->GetID() : 0;
946 SMESH_CATCH( SMESH::throwCorbaException );
950 //=============================================================================
952 * Create a ball element on the given node.
954 //=============================================================================
956 CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diameter)
957 throw (SALOME::SALOME_Exception)
962 if ( diameter < std::numeric_limits<double>::min() )
963 THROW_SALOME_CORBA_EXCEPTION("Invalid diameter", SALOME::BAD_PARAM);
965 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
966 SMDS_MeshElement* elem = getMeshDS()->AddBall(aNode, diameter);
968 // Update Python script
969 TPythonDump() << "ballElem = "
970 << this << ".AddBall( " << IDOfNode << ", " << diameter <<" )";
972 declareMeshModified( /*isReComputeSafe=*/false );
973 return elem ? elem->GetID() : 0;
975 SMESH_CATCH( SMESH::throwCorbaException );
979 //=============================================================================
981 * Create an edge, either linear and quadratic (this is determed
982 * by number of given nodes, two or three)
984 //=============================================================================
986 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
987 throw (SALOME::SALOME_Exception)
992 int NbNodes = IDsOfNodes.length();
993 SMDS_MeshElement* elem = 0;
996 CORBA::Long index1 = IDsOfNodes[0];
997 CORBA::Long index2 = IDsOfNodes[1];
998 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(index1),
999 getMeshDS()->FindNode(index2));
1001 // Update Python script
1002 TPythonDump() << "edge = " << this << ".AddEdge([ "
1003 << index1 << ", " << index2 <<" ])";
1006 CORBA::Long n1 = IDsOfNodes[0];
1007 CORBA::Long n2 = IDsOfNodes[1];
1008 CORBA::Long n12 = IDsOfNodes[2];
1009 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(n1),
1010 getMeshDS()->FindNode(n2),
1011 getMeshDS()->FindNode(n12));
1012 // Update Python script
1013 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
1014 <<n1<<", "<<n2<<", "<<n12<<" ])";
1017 declareMeshModified( /*isReComputeSafe=*/false );
1018 return elem ? elem->GetID() : 0;
1020 SMESH_CATCH( SMESH::throwCorbaException );
1024 //=============================================================================
1028 //=============================================================================
1030 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
1031 throw (SALOME::SALOME_Exception)
1036 int NbNodes = IDsOfNodes.length();
1042 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1043 for (int i = 0; i < NbNodes; i++)
1044 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1046 SMDS_MeshElement* elem = 0;
1048 case 3: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]); break;
1049 case 4: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]); break;
1050 case 6: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1051 nodes[4], nodes[5]); break;
1052 case 7: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1053 nodes[4], nodes[5], nodes[6]); break;
1054 case 8: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1055 nodes[4], nodes[5], nodes[6], nodes[7]); break;
1056 case 9: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1057 nodes[4], nodes[5], nodes[6], nodes[7],
1059 default: elem = getMeshDS()->AddPolygonalFace(nodes);
1062 // Update Python script
1063 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
1065 declareMeshModified( /*isReComputeSafe=*/false );
1067 return elem ? elem->GetID() : 0;
1069 SMESH_CATCH( SMESH::throwCorbaException );
1073 //=============================================================================
1077 //=============================================================================
1078 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
1079 throw (SALOME::SALOME_Exception)
1084 int NbNodes = IDsOfNodes.length();
1085 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1086 for (int i = 0; i < NbNodes; i++)
1087 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1089 const SMDS_MeshElement* elem = getMeshDS()->AddPolygonalFace(nodes);
1091 // Update Python script
1092 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
1094 declareMeshModified( /*isReComputeSafe=*/false );
1095 return elem ? elem->GetID() : 0;
1097 SMESH_CATCH( SMESH::throwCorbaException );
1101 //=============================================================================
1103 * Create volume, either linear and quadratic (this is determed
1104 * by number of given nodes)
1106 //=============================================================================
1108 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
1109 throw (SALOME::SALOME_Exception)
1114 int NbNodes = IDsOfNodes.length();
1115 vector< const SMDS_MeshNode*> n(NbNodes);
1116 for(int i=0;i<NbNodes;i++)
1117 n[i]= getMeshDS()->FindNode(IDsOfNodes[i]);
1119 SMDS_MeshElement* elem = 0;
1122 case 4 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
1123 case 5 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
1124 case 6 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
1125 case 8 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
1126 case 10:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1127 n[6],n[7],n[8],n[9]);
1129 case 12:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1130 n[6],n[7],n[8],n[9],n[10],n[11]);
1132 case 13:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
1133 n[7],n[8],n[9],n[10],n[11],n[12]);
1135 case 15:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
1136 n[9],n[10],n[11],n[12],n[13],n[14]);
1138 case 20:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1139 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1140 n[15],n[16],n[17],n[18],n[19]);
1142 case 27:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1143 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1144 n[15],n[16],n[17],n[18],n[19],
1145 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
1149 // Update Python script
1150 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
1152 declareMeshModified( /*isReComputeSafe=*/false );
1153 return elem ? elem->GetID() : 0;
1155 SMESH_CATCH( SMESH::throwCorbaException );
1159 //=============================================================================
1161 * AddPolyhedralVolume
1163 //=============================================================================
1164 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
1165 const SMESH::long_array & Quantities)
1166 throw (SALOME::SALOME_Exception)
1171 int NbNodes = IDsOfNodes.length();
1172 std::vector<const SMDS_MeshNode*> n (NbNodes);
1173 for (int i = 0; i < NbNodes; i++)
1175 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDsOfNodes[i]);
1176 if (!aNode) return 0;
1180 int NbFaces = Quantities.length();
1181 std::vector<int> q (NbFaces);
1182 for (int j = 0; j < NbFaces; j++)
1183 q[j] = Quantities[j];
1185 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(n, q);
1187 // Update Python script
1188 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
1189 << IDsOfNodes << ", " << Quantities << " )";
1191 declareMeshModified( /*isReComputeSafe=*/false );
1192 return elem ? elem->GetID() : 0;
1194 SMESH_CATCH( SMESH::throwCorbaException );
1198 //=============================================================================
1200 * AddPolyhedralVolumeByFaces
1202 //=============================================================================
1204 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
1205 throw (SALOME::SALOME_Exception)
1210 int NbFaces = IdsOfFaces.length();
1211 std::vector<const SMDS_MeshNode*> poly_nodes;
1212 std::vector<int> quantities (NbFaces);
1214 for (int i = 0; i < NbFaces; i++) {
1215 const SMDS_MeshElement* aFace = getMeshDS()->FindElement(IdsOfFaces[i]);
1216 quantities[i] = aFace->NbNodes();
1218 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
1219 while (It->more()) {
1220 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
1224 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
1226 // Update Python script
1227 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
1228 << IdsOfFaces << " )";
1230 declareMeshModified( /*isReComputeSafe=*/false );
1231 return elem ? elem->GetID() : 0;
1233 SMESH_CATCH( SMESH::throwCorbaException );
1237 //=============================================================================
1239 // \brief Create 0D elements on all nodes of the given object except those
1240 // nodes on which a 0D element already exists.
1241 // \param theObject object on whose nodes 0D elements will be created.
1242 // \param theGroupName optional name of a group to add 0D elements created
1243 // and/or found on nodes of \a theObject.
1244 // \return an object (a new group or a temporary SMESH_IDSource) holding
1245 // ids of new and/or found 0D elements.
1247 //=============================================================================
1249 SMESH::SMESH_IDSource_ptr
1250 SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObject,
1251 const char* theGroupName)
1252 throw (SALOME::SALOME_Exception)
1257 SMESH::SMESH_IDSource_var result;
1260 TIDSortedElemSet elements, elems0D;
1261 prepareIdSource( theObject );
1262 if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
1263 getEditor().Create0DElementsOnAllNodes( elements, elems0D );
1265 SMESH::long_array_var newElems = new SMESH::long_array;
1266 newElems->length( elems0D.size() );
1267 TIDSortedElemSet::iterator eIt = elems0D.begin();
1268 for ( size_t i = 0; i < elems0D.size(); ++i, ++eIt )
1269 newElems[ i ] = (*eIt)->GetID();
1271 SMESH::SMESH_GroupBase_var groupToFill;
1272 if ( theGroupName && strlen( theGroupName ))
1274 // Get existing group named theGroupName
1275 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
1276 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
1277 SMESH::SMESH_GroupBase_var group = groups[i];
1278 if ( !group->_is_nil() ) {
1279 CORBA::String_var name = group->GetName();
1280 if ( strcmp( name.in(), theGroupName ) == 0 && group->GetType() == SMESH::ELEM0D ) {
1281 groupToFill = group;
1286 if ( groupToFill->_is_nil() )
1287 groupToFill = myMesh_i->CreateGroup( SMESH::ELEM0D, theGroupName );
1288 else if ( !SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1289 groupToFill = myMesh_i->ConvertToStandalone( groupToFill );
1292 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1294 group_i->Add( newElems );
1295 result = SMESH::SMESH_IDSource::_narrow( groupToFill );
1296 pyDump << groupToFill;
1300 result = MakeIDSource( newElems, SMESH::ELEM0D );
1301 pyDump << "elem0DIDs";
1304 pyDump << " = " << this << ".Create0DElementsOnAllNodes( "
1305 << theObject << ", '" << theGroupName << "' )";
1307 return result._retn();
1309 SMESH_CATCH( SMESH::throwCorbaException );
1313 //=============================================================================
1315 * \brief Bind a node to a vertex
1316 * \param NodeID - node ID
1317 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1318 * \retval boolean - false if NodeID or VertexID is invalid
1320 //=============================================================================
1322 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
1323 throw (SALOME::SALOME_Exception)
1327 SMESHDS_Mesh * mesh = getMeshDS();
1328 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1330 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1332 if ( mesh->MaxShapeIndex() < VertexID )
1333 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1335 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
1336 if ( shape.ShapeType() != TopAbs_VERTEX )
1337 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1339 mesh->SetNodeOnVertex( node, VertexID );
1341 myMesh->SetIsModified( true );
1343 SMESH_CATCH( SMESH::throwCorbaException );
1346 //=============================================================================
1348 * \brief Store node position on an edge
1349 * \param NodeID - node ID
1350 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
1351 * \param paramOnEdge - parameter on edge where the node is located
1352 * \retval boolean - false if any parameter is invalid
1354 //=============================================================================
1356 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
1357 CORBA::Double paramOnEdge)
1358 throw (SALOME::SALOME_Exception)
1362 SMESHDS_Mesh * mesh = getMeshDS();
1363 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1365 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1367 if ( mesh->MaxShapeIndex() < EdgeID )
1368 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1370 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
1371 if ( shape.ShapeType() != TopAbs_EDGE )
1372 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1375 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
1376 if ( paramOnEdge < f || paramOnEdge > l )
1377 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
1379 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
1381 myMesh->SetIsModified( true );
1383 SMESH_CATCH( SMESH::throwCorbaException );
1386 //=============================================================================
1388 * \brief Store node position on a face
1389 * \param NodeID - node ID
1390 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
1391 * \param u - U parameter on face where the node is located
1392 * \param v - V parameter on face where the node is located
1393 * \retval boolean - false if any parameter is invalid
1395 //=============================================================================
1397 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
1398 CORBA::Double u, CORBA::Double v)
1399 throw (SALOME::SALOME_Exception)
1402 SMESHDS_Mesh * mesh = getMeshDS();
1403 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1405 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1407 if ( mesh->MaxShapeIndex() < FaceID )
1408 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1410 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
1411 if ( shape.ShapeType() != TopAbs_FACE )
1412 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1414 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
1415 bool isOut = ( u < surf.FirstUParameter() ||
1416 u > surf.LastUParameter() ||
1417 v < surf.FirstVParameter() ||
1418 v > surf.LastVParameter() );
1422 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
1423 << " u( " << surf.FirstUParameter()
1424 << "," << surf.LastUParameter()
1425 << ") v( " << surf.FirstVParameter()
1426 << "," << surf.LastVParameter() << ")" );
1428 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
1431 mesh->SetNodeOnFace( node, FaceID, u, v );
1432 myMesh->SetIsModified( true );
1434 SMESH_CATCH( SMESH::throwCorbaException );
1437 //=============================================================================
1439 * \brief Bind a node to a solid
1440 * \param NodeID - node ID
1441 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1442 * \retval boolean - false if NodeID or SolidID is invalid
1444 //=============================================================================
1446 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
1447 throw (SALOME::SALOME_Exception)
1450 SMESHDS_Mesh * mesh = getMeshDS();
1451 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1453 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1455 if ( mesh->MaxShapeIndex() < SolidID )
1456 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1458 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
1459 if ( shape.ShapeType() != TopAbs_SOLID &&
1460 shape.ShapeType() != TopAbs_SHELL)
1461 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1463 mesh->SetNodeInVolume( node, SolidID );
1465 SMESH_CATCH( SMESH::throwCorbaException );
1468 //=============================================================================
1470 * \brief Bind an element to a shape
1471 * \param ElementID - element ID
1472 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
1474 //=============================================================================
1476 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
1477 CORBA::Long ShapeID)
1478 throw (SALOME::SALOME_Exception)
1481 SMESHDS_Mesh * mesh = getMeshDS();
1482 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
1484 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
1486 if ( mesh->MaxShapeIndex() < ShapeID || ShapeID < 1 )
1487 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1489 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1490 if ( shape.ShapeType() != TopAbs_EDGE &&
1491 shape.ShapeType() != TopAbs_FACE &&
1492 shape.ShapeType() != TopAbs_SOLID &&
1493 shape.ShapeType() != TopAbs_SHELL )
1494 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1496 mesh->SetMeshElementOnShape( elem, ShapeID );
1498 myMesh->SetIsModified( true );
1500 SMESH_CATCH( SMESH::throwCorbaException );
1503 //=============================================================================
1507 //=============================================================================
1509 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1510 CORBA::Long NodeID2)
1511 throw (SALOME::SALOME_Exception)
1516 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1517 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1521 // Update Python script
1522 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1523 << NodeID1 << ", " << NodeID2 << " )";
1525 int ret = getEditor().InverseDiag ( n1, n2 );
1527 declareMeshModified( /*isReComputeSafe=*/false );
1530 SMESH_CATCH( SMESH::throwCorbaException );
1534 //=============================================================================
1538 //=============================================================================
1540 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1541 CORBA::Long NodeID2)
1542 throw (SALOME::SALOME_Exception)
1547 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1548 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1552 // Update Python script
1553 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1554 << NodeID1 << ", " << NodeID2 << " )";
1557 bool stat = getEditor().DeleteDiag ( n1, n2 );
1559 declareMeshModified( /*isReComputeSafe=*/!stat );
1563 SMESH_CATCH( SMESH::throwCorbaException );
1567 //=============================================================================
1571 //=============================================================================
1573 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1574 throw (SALOME::SALOME_Exception)
1579 for (int i = 0; i < IDsOfElements.length(); i++)
1581 CORBA::Long index = IDsOfElements[i];
1582 const SMDS_MeshElement * elem = getMeshDS()->FindElement(index);
1584 getEditor().Reorient( elem );
1586 // Update Python script
1587 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1589 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 );
1592 SMESH_CATCH( SMESH::throwCorbaException );
1596 //=============================================================================
1600 //=============================================================================
1602 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1603 throw (SALOME::SALOME_Exception)
1608 TPythonDump aTPythonDump; // suppress dump in Reorient()
1610 prepareIdSource( theObject );
1612 SMESH::long_array_var anElementsId = theObject->GetIDs();
1613 CORBA::Boolean isDone = Reorient(anElementsId);
1615 // Update Python script
1616 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1618 declareMeshModified( /*isReComputeSafe=*/ anElementsId->length() == 0 );
1621 SMESH_CATCH( SMESH::throwCorbaException );
1625 //=======================================================================
1626 //function : Reorient2D
1627 //purpose : Reorient faces contained in \a the2Dgroup.
1628 // the2Dgroup - the mesh or its part to reorient
1629 // theDirection - desired direction of normal of \a theFace
1630 // theFace - ID of face whose orientation is checked.
1631 // It can be < 1 then \a thePoint is used to find a face.
1632 // thePoint - is used to find a face if \a theFace < 1.
1633 // return number of reoriented elements.
1634 //=======================================================================
1636 CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
1637 const SMESH::DirStruct& theDirection,
1638 CORBA::Long theFace,
1639 const SMESH::PointStruct& thePoint)
1640 throw (SALOME::SALOME_Exception)
1643 initData(/*deleteSearchers=*/false);
1645 TIDSortedElemSet elements;
1646 prepareIdSource( the2Dgroup );
1647 if ( !idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1))
1648 THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
1651 const SMDS_MeshElement* face = 0;
1654 face = getMeshDS()->FindElement( theFace );
1656 THROW_SALOME_CORBA_EXCEPTION("Inexistent face given", SALOME::BAD_PARAM);
1657 if ( face->GetType() != SMDSAbs_Face )
1658 THROW_SALOME_CORBA_EXCEPTION("Wrong element type", SALOME::BAD_PARAM);
1662 // create theElementSearcher if needed
1663 theSearchersDeleter.Set( myMesh, getPartIOR( the2Dgroup, SMESH::FACE ));
1664 if ( !theElementSearcher )
1666 if ( elements.empty() ) // search in the whole mesh
1668 if ( myMesh->NbFaces() == 0 )
1669 THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM);
1671 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
1675 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
1676 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
1678 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt);
1682 gp_Pnt p( thePoint.x, thePoint.y, thePoint.z );
1683 face = theElementSearcher->FindClosestTo( p, SMDSAbs_Face );
1686 THROW_SALOME_CORBA_EXCEPTION("No face found by point", SALOME::INTERNAL_ERROR );
1687 if ( !elements.empty() && !elements.count( face ))
1688 THROW_SALOME_CORBA_EXCEPTION("Found face is not in the group", SALOME::BAD_PARAM );
1691 const SMESH::PointStruct * P = &theDirection.PS;
1692 gp_Vec dirVec( P->x, P->y, P->z );
1693 if ( dirVec.Magnitude() < std::numeric_limits< double >::min() )
1694 THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM);
1696 int nbReori = getEditor().Reorient2D( elements, dirVec, face );
1699 declareMeshModified( /*isReComputeSafe=*/false );
1701 TPythonDump() << this << ".Reorient2D( "
1702 << the2Dgroup << ", "
1703 << theDirection << ", "
1705 << thePoint << " )";
1709 SMESH_CATCH( SMESH::throwCorbaException );
1713 //=============================================================================
1715 * \brief Fuse neighbour triangles into quadrangles.
1717 //=============================================================================
1719 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1720 SMESH::NumericalFunctor_ptr Criterion,
1721 CORBA::Double MaxAngle)
1722 throw (SALOME::SALOME_Exception)
1727 SMESHDS_Mesh* aMesh = getMeshDS();
1728 TIDSortedElemSet faces,copyFaces;
1729 SMDS_MeshElement::GeomFilter triaFilter(SMDSGeom_TRIANGLE);
1730 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face, & triaFilter);
1731 TIDSortedElemSet* workElements = & faces;
1733 if ( myIsPreviewMode ) {
1734 SMDSAbs_ElementType select = SMDSAbs_Face;
1735 getPreviewMesh( SMDSAbs_Face )->Copy( faces, copyFaces, select );
1736 workElements = & copyFaces;
1739 SMESH::NumericalFunctor_i* aNumericalFunctor =
1740 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1741 SMESH::Controls::NumericalFunctorPtr aCrit;
1742 if ( !aNumericalFunctor )
1743 aCrit.reset( new SMESH::Controls::MaxElementLength2D() );
1745 aCrit = aNumericalFunctor->GetNumericalFunctor();
1747 if ( !myIsPreviewMode ) {
1748 // Update Python script
1749 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1750 << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1753 bool stat = getEditor().TriToQuad( *workElements, aCrit, MaxAngle );
1755 declareMeshModified( /*isReComputeSafe=*/!stat );
1758 SMESH_CATCH( SMESH::throwCorbaException );
1762 //=============================================================================
1764 * \brief Fuse neighbour triangles into quadrangles.
1766 //=============================================================================
1768 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1769 SMESH::NumericalFunctor_ptr Criterion,
1770 CORBA::Double MaxAngle)
1771 throw (SALOME::SALOME_Exception)
1776 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1778 prepareIdSource( theObject );
1779 SMESH::long_array_var anElementsId = theObject->GetIDs();
1780 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1782 if ( !myIsPreviewMode ) {
1783 SMESH::NumericalFunctor_i* aNumericalFunctor =
1784 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1786 // Update Python script
1787 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1788 << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1793 SMESH_CATCH( SMESH::throwCorbaException );
1797 //=============================================================================
1799 * \brief Split quadrangles into triangles.
1801 //=============================================================================
1803 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1804 SMESH::NumericalFunctor_ptr Criterion)
1805 throw (SALOME::SALOME_Exception)
1810 SMESHDS_Mesh* aMesh = getMeshDS();
1811 TIDSortedElemSet faces;
1812 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1814 SMESH::NumericalFunctor_i* aNumericalFunctor =
1815 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1816 SMESH::Controls::NumericalFunctorPtr aCrit;
1817 if ( !aNumericalFunctor )
1818 aCrit.reset( new SMESH::Controls::AspectRatio() );
1820 aCrit = aNumericalFunctor->GetNumericalFunctor();
1823 // Update Python script
1824 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1826 CORBA::Boolean stat = getEditor().QuadToTri( faces, aCrit );
1828 declareMeshModified( /*isReComputeSafe=*/false );
1831 SMESH_CATCH( SMESH::throwCorbaException );
1835 //=============================================================================
1837 * \brief Split quadrangles into triangles.
1839 //=============================================================================
1841 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1842 SMESH::NumericalFunctor_ptr Criterion)
1843 throw (SALOME::SALOME_Exception)
1848 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1850 prepareIdSource( theObject );
1851 SMESH::long_array_var anElementsId = theObject->GetIDs();
1852 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1854 SMESH::NumericalFunctor_i* aNumericalFunctor =
1855 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1857 // Update Python script
1858 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1860 declareMeshModified( /*isReComputeSafe=*/false );
1863 SMESH_CATCH( SMESH::throwCorbaException );
1867 //================================================================================
1869 * \brief Split each of quadrangles into 4 triangles.
1870 * \param [in] theObject - theQuads Container of quadrangles to split.
1872 //================================================================================
1874 void SMESH_MeshEditor_i::QuadTo4Tri (SMESH::SMESH_IDSource_ptr theObject)
1875 throw (SALOME::SALOME_Exception)
1880 TIDSortedElemSet faces;
1881 prepareIdSource( theObject );
1882 if ( !idSourceToSet( theObject, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/true ) &&
1884 THROW_SALOME_CORBA_EXCEPTION("No faces given", SALOME::BAD_PARAM);
1886 getEditor().QuadTo4Tri( faces );
1887 TPythonDump() << this << ".QuadTo4Tri( " << theObject << " )";
1889 SMESH_CATCH( SMESH::throwCorbaException );
1892 //=============================================================================
1894 * \brief Split quadrangles into triangles.
1896 //=============================================================================
1898 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1899 CORBA::Boolean Diag13)
1900 throw (SALOME::SALOME_Exception)
1905 SMESHDS_Mesh* aMesh = getMeshDS();
1906 TIDSortedElemSet faces;
1907 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1909 // Update Python script
1910 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1911 << IDsOfElements << ", " << Diag13 << " )";
1913 CORBA::Boolean stat = getEditor().QuadToTri( faces, Diag13 );
1915 declareMeshModified( /*isReComputeSafe=*/ !stat );
1918 SMESH_CATCH( SMESH::throwCorbaException );
1922 //=============================================================================
1924 * \brief Split quadrangles into triangles.
1926 //=============================================================================
1928 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1929 CORBA::Boolean Diag13)
1930 throw (SALOME::SALOME_Exception)
1935 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
1937 prepareIdSource( theObject );
1938 SMESH::long_array_var anElementsId = theObject->GetIDs();
1939 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
1941 // Update Python script
1942 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
1943 << theObject << ", " << Diag13 << " )";
1945 declareMeshModified( /*isReComputeSafe=*/!isDone );
1948 SMESH_CATCH( SMESH::throwCorbaException );
1953 //=============================================================================
1955 * Find better splitting of the given quadrangle.
1956 * \param IDOfQuad ID of the quadrangle to be splitted.
1957 * \param Criterion A criterion to choose a diagonal for splitting.
1958 * \return 1 if 1-3 diagonal is better, 2 if 2-4
1959 * diagonal is better, 0 if error occurs.
1961 //=============================================================================
1963 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
1964 SMESH::NumericalFunctor_ptr Criterion)
1965 throw (SALOME::SALOME_Exception)
1970 const SMDS_MeshElement* quad = getMeshDS()->FindElement(IDOfQuad);
1971 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
1973 SMESH::NumericalFunctor_i* aNumericalFunctor =
1974 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
1975 SMESH::Controls::NumericalFunctorPtr aCrit;
1976 if (aNumericalFunctor)
1977 aCrit = aNumericalFunctor->GetNumericalFunctor();
1979 aCrit.reset(new SMESH::Controls::AspectRatio());
1981 int id = getEditor().BestSplit(quad, aCrit);
1982 declareMeshModified( /*isReComputeSafe=*/ id < 1 );
1986 SMESH_CATCH( SMESH::throwCorbaException );
1990 //================================================================================
1992 * \brief Split volumic elements into tetrahedrons
1994 //================================================================================
1996 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
1997 CORBA::Short methodFlags)
1998 throw (SALOME::SALOME_Exception)
2002 prepareIdSource( elems );
2004 ::SMESH_MeshEditor::TFacetOfElem elemSet;
2005 const int noneFacet = -1;
2006 SMDS_ElemIteratorPtr volIt = myMesh_i->GetElements( elems, SMESH::VOLUME );
2007 while( volIt->more() )
2008 elemSet.insert( elemSet.end(), make_pair( volIt->next(), noneFacet ));
2010 getEditor().SplitVolumes( elemSet, int( methodFlags ));
2011 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2013 TPythonDump() << this << ".SplitVolumesIntoTetra( "
2014 << elems << ", " << methodFlags << " )";
2016 SMESH_CATCH( SMESH::throwCorbaException );
2019 //================================================================================
2021 * \brief Split hexahedra into triangular prisms
2022 * \param elems - elements to split
2023 * \param facetToSplitNormal - normal used to find a facet of hexahedron
2024 * to split into triangles
2025 * \param methodFlags - flags passing splitting method:
2026 * 1 - split the hexahedron into 2 prisms
2027 * 2 - split the hexahedron into 4 prisms
2029 //================================================================================
2031 void SMESH_MeshEditor_i::SplitHexahedraIntoPrisms (SMESH::SMESH_IDSource_ptr elems,
2032 CORBA::Short methodFlags,
2033 const SMESH::AxisStruct & facetToSplitNormal,
2034 CORBA::Boolean allDomains)
2035 throw (SALOME::SALOME_Exception)
2039 prepareIdSource( elems );
2041 gp_Ax1 facetNorm( gp_Pnt( facetToSplitNormal.x,
2042 facetToSplitNormal.y,
2043 facetToSplitNormal.z ),
2044 gp_Dir( facetToSplitNormal.vx,
2045 facetToSplitNormal.vy,
2046 facetToSplitNormal.vz ));
2047 TIDSortedElemSet elemSet;
2048 SMESH::long_array_var anElementsId = elems->GetIDs();
2049 SMDS_MeshElement::GeomFilter filter( SMDSGeom_HEXA );
2050 arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume, &filter );
2052 ::SMESH_MeshEditor::TFacetOfElem elemFacets;
2053 while ( !elemSet.empty() )
2055 getEditor().GetHexaFacetsToSplit( elemSet, facetNorm, elemFacets );
2059 ::SMESH_MeshEditor::TFacetOfElem::iterator ef = elemFacets.begin();
2060 for ( ; ef != elemFacets.end(); ++ef )
2061 elemSet.erase( ef->first );
2064 if ( methodFlags == 2 )
2065 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_4_PRISMS );
2067 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_2_PRISMS );
2069 getEditor().SplitVolumes( elemFacets, int( methodFlags ));
2070 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2072 TPythonDump() << this << ".SplitHexahedraIntoPrisms( "
2073 << elems << ", " << methodFlags<< ", "
2074 << facetToSplitNormal<< ", " << allDomains << " )";
2076 SMESH_CATCH( SMESH::throwCorbaException );
2079 //=======================================================================
2082 //=======================================================================
2085 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
2086 const SMESH::long_array & IDsOfFixedNodes,
2087 CORBA::Long MaxNbOfIterations,
2088 CORBA::Double MaxAspectRatio,
2089 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2090 throw (SALOME::SALOME_Exception)
2092 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2093 MaxAspectRatio, Method, false );
2097 //=======================================================================
2098 //function : SmoothParametric
2100 //=======================================================================
2103 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
2104 const SMESH::long_array & IDsOfFixedNodes,
2105 CORBA::Long MaxNbOfIterations,
2106 CORBA::Double MaxAspectRatio,
2107 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2108 throw (SALOME::SALOME_Exception)
2110 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2111 MaxAspectRatio, Method, true );
2115 //=======================================================================
2116 //function : SmoothObject
2118 //=======================================================================
2121 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
2122 const SMESH::long_array & IDsOfFixedNodes,
2123 CORBA::Long MaxNbOfIterations,
2124 CORBA::Double MaxAspectRatio,
2125 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2126 throw (SALOME::SALOME_Exception)
2128 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2129 MaxAspectRatio, Method, false);
2133 //=======================================================================
2134 //function : SmoothParametricObject
2136 //=======================================================================
2139 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
2140 const SMESH::long_array & IDsOfFixedNodes,
2141 CORBA::Long MaxNbOfIterations,
2142 CORBA::Double MaxAspectRatio,
2143 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2144 throw (SALOME::SALOME_Exception)
2146 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2147 MaxAspectRatio, Method, true);
2151 //=============================================================================
2155 //=============================================================================
2158 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
2159 const SMESH::long_array & IDsOfFixedNodes,
2160 CORBA::Long MaxNbOfIterations,
2161 CORBA::Double MaxAspectRatio,
2162 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2164 throw (SALOME::SALOME_Exception)
2169 SMESHDS_Mesh* aMesh = getMeshDS();
2171 TIDSortedElemSet elements;
2172 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
2174 set<const SMDS_MeshNode*> fixedNodes;
2175 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
2176 CORBA::Long index = IDsOfFixedNodes[i];
2177 const SMDS_MeshNode * node = aMesh->FindNode(index);
2179 fixedNodes.insert( node );
2181 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
2182 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
2183 method = ::SMESH_MeshEditor::CENTROIDAL;
2185 getEditor().Smooth(elements, fixedNodes, method,
2186 MaxNbOfIterations, MaxAspectRatio, IsParametric );
2188 declareMeshModified( /*isReComputeSafe=*/true ); // does not prevent re-compute
2190 // Update Python script
2191 TPythonDump() << "isDone = " << this << "."
2192 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
2193 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
2194 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2195 << "SMESH.SMESH_MeshEditor."
2196 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2197 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2201 SMESH_CATCH( SMESH::throwCorbaException );
2205 //=============================================================================
2209 //=============================================================================
2212 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
2213 const SMESH::long_array & IDsOfFixedNodes,
2214 CORBA::Long MaxNbOfIterations,
2215 CORBA::Double MaxAspectRatio,
2216 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2218 throw (SALOME::SALOME_Exception)
2223 TPythonDump aTPythonDump; // suppress dump in smooth()
2225 prepareIdSource( theObject );
2226 SMESH::long_array_var anElementsId = theObject->GetIDs();
2227 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
2228 MaxAspectRatio, Method, IsParametric);
2230 // Update Python script
2231 aTPythonDump << "isDone = " << this << "."
2232 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
2233 << theObject << ", " << IDsOfFixedNodes << ", "
2234 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2235 << "SMESH.SMESH_MeshEditor."
2236 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2237 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2241 SMESH_CATCH( SMESH::throwCorbaException );
2245 //=============================================================================
2249 //=============================================================================
2251 void SMESH_MeshEditor_i::RenumberNodes()
2252 throw (SALOME::SALOME_Exception)
2255 // Update Python script
2256 TPythonDump() << this << ".RenumberNodes()";
2258 getMeshDS()->Renumber( true );
2260 SMESH_CATCH( SMESH::throwCorbaException );
2263 //=============================================================================
2267 //=============================================================================
2269 void SMESH_MeshEditor_i::RenumberElements()
2270 throw (SALOME::SALOME_Exception)
2273 // Update Python script
2274 TPythonDump() << this << ".RenumberElements()";
2276 getMeshDS()->Renumber( false );
2278 SMESH_CATCH( SMESH::throwCorbaException );
2281 //=======================================================================
2283 * \brief Return groups by their IDs
2285 //=======================================================================
2287 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
2288 throw (SALOME::SALOME_Exception)
2293 myMesh_i->CreateGroupServants();
2294 return myMesh_i->GetGroups( *groupIDs );
2296 SMESH_CATCH( SMESH::throwCorbaException );
2300 //=======================================================================
2301 //function : rotationSweep
2303 //=======================================================================
2305 SMESH::ListOfGroups*
2306 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
2307 const SMESH::AxisStruct & theAxis,
2308 CORBA::Double theAngleInRadians,
2309 CORBA::Long theNbOfSteps,
2310 CORBA::Double theTolerance,
2311 const bool theMakeGroups,
2312 const SMDSAbs_ElementType theElementType)
2313 throw (SALOME::SALOME_Exception)
2318 TIDSortedElemSet inElements, copyElements;
2319 arrayToSet(theIDsOfElements, getMeshDS(), inElements, theElementType);
2321 TIDSortedElemSet* workElements = & inElements;
2322 bool makeWalls=true;
2323 if ( myIsPreviewMode )
2325 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2326 getPreviewMesh( SMDSAbs_Face )->Copy( inElements, copyElements, select, avoid );
2327 workElements = & copyElements;
2328 //makeWalls = false;
2331 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
2332 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
2334 ::SMESH_MeshEditor::PGroupIDs groupIds =
2335 getEditor().RotationSweep (*workElements, Ax1, theAngleInRadians,
2336 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
2338 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2340 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2342 SMESH_CATCH( SMESH::throwCorbaException );
2346 //=======================================================================
2347 //function : RotationSweep
2349 //=======================================================================
2351 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
2352 const SMESH::AxisStruct & theAxis,
2353 CORBA::Double theAngleInRadians,
2354 CORBA::Long theNbOfSteps,
2355 CORBA::Double theTolerance)
2356 throw (SALOME::SALOME_Exception)
2358 if ( !myIsPreviewMode ) {
2359 TPythonDump() << this << ".RotationSweep( "
2360 << theIDsOfElements << ", "
2362 << TVar( theAngleInRadians ) << ", "
2363 << TVar( theNbOfSteps ) << ", "
2364 << TVar( theTolerance ) << " )";
2366 rotationSweep(theIDsOfElements,
2374 //=======================================================================
2375 //function : RotationSweepMakeGroups
2377 //=======================================================================
2379 SMESH::ListOfGroups*
2380 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2381 const SMESH::AxisStruct& theAxis,
2382 CORBA::Double theAngleInRadians,
2383 CORBA::Long theNbOfSteps,
2384 CORBA::Double theTolerance)
2385 throw (SALOME::SALOME_Exception)
2387 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2389 SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
2395 if (!myIsPreviewMode) {
2396 dumpGroupsList(aPythonDump, aGroups);
2397 aPythonDump << this << ".RotationSweepMakeGroups( "
2398 << theIDsOfElements << ", "
2400 << TVar( theAngleInRadians ) << ", "
2401 << TVar( theNbOfSteps ) << ", "
2402 << TVar( theTolerance ) << " )";
2407 //=======================================================================
2408 //function : RotationSweepObject
2410 //=======================================================================
2412 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2413 const SMESH::AxisStruct & theAxis,
2414 CORBA::Double theAngleInRadians,
2415 CORBA::Long theNbOfSteps,
2416 CORBA::Double theTolerance)
2417 throw (SALOME::SALOME_Exception)
2419 if ( !myIsPreviewMode ) {
2420 TPythonDump() << this << ".RotationSweepObject( "
2421 << theObject << ", "
2423 << theAngleInRadians << ", "
2424 << theNbOfSteps << ", "
2425 << theTolerance << " )";
2427 prepareIdSource( theObject );
2428 SMESH::long_array_var anElementsId = theObject->GetIDs();
2429 rotationSweep(anElementsId,
2437 //=======================================================================
2438 //function : RotationSweepObject1D
2440 //=======================================================================
2442 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2443 const SMESH::AxisStruct & theAxis,
2444 CORBA::Double theAngleInRadians,
2445 CORBA::Long theNbOfSteps,
2446 CORBA::Double theTolerance)
2447 throw (SALOME::SALOME_Exception)
2449 if ( !myIsPreviewMode ) {
2450 TPythonDump() << this << ".RotationSweepObject1D( "
2451 << theObject << ", "
2453 << TVar( theAngleInRadians ) << ", "
2454 << TVar( theNbOfSteps ) << ", "
2455 << TVar( theTolerance ) << " )";
2457 prepareIdSource( theObject );
2458 SMESH::long_array_var anElementsId = theObject->GetIDs();
2459 rotationSweep(anElementsId,
2468 //=======================================================================
2469 //function : RotationSweepObject2D
2471 //=======================================================================
2473 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2474 const SMESH::AxisStruct & theAxis,
2475 CORBA::Double theAngleInRadians,
2476 CORBA::Long theNbOfSteps,
2477 CORBA::Double theTolerance)
2478 throw (SALOME::SALOME_Exception)
2480 if ( !myIsPreviewMode ) {
2481 TPythonDump() << this << ".RotationSweepObject2D( "
2482 << theObject << ", "
2484 << TVar( theAngleInRadians ) << ", "
2485 << TVar( theNbOfSteps ) << ", "
2486 << TVar( theTolerance ) << " )";
2488 prepareIdSource( theObject );
2489 SMESH::long_array_var anElementsId = theObject->GetIDs();
2490 rotationSweep(anElementsId,
2499 //=======================================================================
2500 //function : RotationSweepObjectMakeGroups
2502 //=======================================================================
2504 SMESH::ListOfGroups*
2505 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2506 const SMESH::AxisStruct& theAxis,
2507 CORBA::Double theAngleInRadians,
2508 CORBA::Long theNbOfSteps,
2509 CORBA::Double theTolerance)
2510 throw (SALOME::SALOME_Exception)
2512 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2514 prepareIdSource( theObject );
2515 SMESH::long_array_var anElementsId = theObject->GetIDs();
2516 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2522 if (!myIsPreviewMode) {
2523 dumpGroupsList(aPythonDump, aGroups);
2524 aPythonDump << this << ".RotationSweepObjectMakeGroups( "
2525 << theObject << ", "
2527 << theAngleInRadians << ", "
2528 << theNbOfSteps << ", "
2529 << theTolerance << " )";
2534 //=======================================================================
2535 //function : RotationSweepObject1DMakeGroups
2537 //=======================================================================
2539 SMESH::ListOfGroups*
2540 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2541 const SMESH::AxisStruct& theAxis,
2542 CORBA::Double theAngleInRadians,
2543 CORBA::Long theNbOfSteps,
2544 CORBA::Double theTolerance)
2545 throw (SALOME::SALOME_Exception)
2547 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2549 prepareIdSource( theObject );
2550 SMESH::long_array_var anElementsId = theObject->GetIDs();
2551 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2558 if (!myIsPreviewMode) {
2559 dumpGroupsList(aPythonDump, aGroups);
2560 aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
2561 << theObject << ", "
2563 << TVar( theAngleInRadians ) << ", "
2564 << TVar( theNbOfSteps ) << ", "
2565 << TVar( theTolerance ) << " )";
2570 //=======================================================================
2571 //function : RotationSweepObject2DMakeGroups
2573 //=======================================================================
2575 SMESH::ListOfGroups*
2576 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2577 const SMESH::AxisStruct& theAxis,
2578 CORBA::Double theAngleInRadians,
2579 CORBA::Long theNbOfSteps,
2580 CORBA::Double theTolerance)
2581 throw (SALOME::SALOME_Exception)
2583 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2585 prepareIdSource( theObject );
2586 SMESH::long_array_var anElementsId = theObject->GetIDs();
2587 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2594 if (!myIsPreviewMode) {
2595 dumpGroupsList(aPythonDump, aGroups);
2596 aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
2597 << theObject << ", "
2599 << TVar( theAngleInRadians ) << ", "
2600 << TVar( theNbOfSteps ) << ", "
2601 << TVar( theTolerance ) << " )";
2607 //=======================================================================
2608 //function : extrusionSweep
2610 //=======================================================================
2612 SMESH::ListOfGroups*
2613 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
2614 const SMESH::DirStruct & theStepVector,
2615 CORBA::Long theNbOfSteps,
2617 const SMDSAbs_ElementType theElementType)
2618 throw (SALOME::SALOME_Exception)
2623 TIDSortedElemSet elements, copyElements;
2624 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
2626 const SMESH::PointStruct * P = &theStepVector.PS;
2627 gp_Vec stepVec( P->x, P->y, P->z );
2629 TIDSortedElemSet* workElements = & elements;
2631 SMDSAbs_ElementType aType = SMDSAbs_Face;
2632 if (theElementType == SMDSAbs_Node)
2634 aType = SMDSAbs_Edge;
2636 if ( myIsPreviewMode ) {
2637 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2638 getPreviewMesh( aType )->Copy( elements, copyElements, select, avoid );
2639 workElements = & copyElements;
2640 theMakeGroups = false;
2643 ::SMESH_MeshEditor::TTElemOfElemListMap aHystory;
2644 ::SMESH_MeshEditor::PGroupIDs groupIds =
2645 getEditor().ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
2647 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2649 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2651 SMESH_CATCH( SMESH::throwCorbaException );
2655 //=======================================================================
2656 //function : ExtrusionSweep
2658 //=======================================================================
2660 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
2661 const SMESH::DirStruct & theStepVector,
2662 CORBA::Long theNbOfSteps)
2663 throw (SALOME::SALOME_Exception)
2665 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
2666 if (!myIsPreviewMode) {
2667 TPythonDump() << this << ".ExtrusionSweep( "
2668 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps) << " )";
2672 //=======================================================================
2673 //function : ExtrusionSweep0D
2675 //=======================================================================
2677 void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElements,
2678 const SMESH::DirStruct & theStepVector,
2679 CORBA::Long theNbOfSteps)
2680 throw (SALOME::SALOME_Exception)
2682 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2683 if (!myIsPreviewMode) {
2684 TPythonDump() << this << ".ExtrusionSweep0D( "
2685 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps)<< " )";
2689 //=======================================================================
2690 //function : ExtrusionSweepObject
2692 //=======================================================================
2694 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2695 const SMESH::DirStruct & theStepVector,
2696 CORBA::Long theNbOfSteps)
2697 throw (SALOME::SALOME_Exception)
2699 prepareIdSource( theObject );
2700 SMESH::long_array_var anElementsId = theObject->GetIDs();
2701 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
2702 if (!myIsPreviewMode) {
2703 TPythonDump() << this << ".ExtrusionSweepObject( "
2704 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
2708 //=======================================================================
2709 //function : ExtrusionSweepObject0D
2711 //=======================================================================
2713 void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObject,
2714 const SMESH::DirStruct & theStepVector,
2715 CORBA::Long theNbOfSteps)
2716 throw (SALOME::SALOME_Exception)
2718 prepareIdSource( theObject );
2719 SMESH::long_array_var anElementsId = theObject->GetIDs();
2720 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2721 if ( !myIsPreviewMode ) {
2722 TPythonDump() << this << ".ExtrusionSweepObject0D( "
2723 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2727 //=======================================================================
2728 //function : ExtrusionSweepObject1D
2730 //=======================================================================
2732 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2733 const SMESH::DirStruct & theStepVector,
2734 CORBA::Long theNbOfSteps)
2735 throw (SALOME::SALOME_Exception)
2737 prepareIdSource( theObject );
2738 SMESH::long_array_var anElementsId = theObject->GetIDs();
2739 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
2740 if ( !myIsPreviewMode ) {
2741 TPythonDump() << this << ".ExtrusionSweepObject1D( "
2742 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2746 //=======================================================================
2747 //function : ExtrusionSweepObject2D
2749 //=======================================================================
2751 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2752 const SMESH::DirStruct & theStepVector,
2753 CORBA::Long theNbOfSteps)
2754 throw (SALOME::SALOME_Exception)
2756 prepareIdSource( theObject );
2757 SMESH::long_array_var anElementsId = theObject->GetIDs();
2758 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
2759 if ( !myIsPreviewMode ) {
2760 TPythonDump() << this << ".ExtrusionSweepObject2D( "
2761 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2765 //=======================================================================
2766 //function : ExtrusionSweepMakeGroups
2768 //=======================================================================
2770 SMESH::ListOfGroups*
2771 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2772 const SMESH::DirStruct& theStepVector,
2773 CORBA::Long theNbOfSteps)
2774 throw (SALOME::SALOME_Exception)
2776 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2778 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
2780 if (!myIsPreviewMode) {
2781 dumpGroupsList(aPythonDump, aGroups);
2782 aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
2783 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2788 //=======================================================================
2789 //function : ExtrusionSweepMakeGroups0D
2791 //=======================================================================
2793 SMESH::ListOfGroups*
2794 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups0D(const SMESH::long_array& theIDsOfElements,
2795 const SMESH::DirStruct& theStepVector,
2796 CORBA::Long theNbOfSteps)
2797 throw (SALOME::SALOME_Exception)
2799 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2801 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true,SMDSAbs_Node);
2803 if (!myIsPreviewMode) {
2804 dumpGroupsList(aPythonDump, aGroups);
2805 aPythonDump << this << ".ExtrusionSweepMakeGroups0D( " << theIDsOfElements
2806 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2811 //=======================================================================
2812 //function : ExtrusionSweepObjectMakeGroups
2814 //=======================================================================
2816 SMESH::ListOfGroups*
2817 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2818 const SMESH::DirStruct& theStepVector,
2819 CORBA::Long theNbOfSteps)
2820 throw (SALOME::SALOME_Exception)
2822 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2824 prepareIdSource( theObject );
2825 SMESH::long_array_var anElementsId = theObject->GetIDs();
2826 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
2828 if (!myIsPreviewMode) {
2829 dumpGroupsList(aPythonDump, aGroups);
2830 aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
2831 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2836 //=======================================================================
2837 //function : ExtrusionSweepObject0DMakeGroups
2839 //=======================================================================
2841 SMESH::ListOfGroups*
2842 SMESH_MeshEditor_i::ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2843 const SMESH::DirStruct& theStepVector,
2844 CORBA::Long theNbOfSteps)
2845 throw (SALOME::SALOME_Exception)
2847 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2849 prepareIdSource( theObject );
2850 SMESH::long_array_var anElementsId = theObject->GetIDs();
2851 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2852 theNbOfSteps, true, SMDSAbs_Node);
2853 if (!myIsPreviewMode) {
2854 dumpGroupsList(aPythonDump, aGroups);
2855 aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject
2856 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2861 //=======================================================================
2862 //function : ExtrusionSweepObject1DMakeGroups
2864 //=======================================================================
2866 SMESH::ListOfGroups*
2867 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2868 const SMESH::DirStruct& theStepVector,
2869 CORBA::Long theNbOfSteps)
2870 throw (SALOME::SALOME_Exception)
2872 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2874 prepareIdSource( theObject );
2875 SMESH::long_array_var anElementsId = theObject->GetIDs();
2876 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2877 theNbOfSteps, true, SMDSAbs_Edge);
2878 if (!myIsPreviewMode) {
2879 dumpGroupsList(aPythonDump, aGroups);
2880 aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
2881 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2886 //=======================================================================
2887 //function : ExtrusionSweepObject2DMakeGroups
2889 //=======================================================================
2891 SMESH::ListOfGroups*
2892 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2893 const SMESH::DirStruct& theStepVector,
2894 CORBA::Long theNbOfSteps)
2895 throw (SALOME::SALOME_Exception)
2897 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2899 prepareIdSource( theObject );
2900 SMESH::long_array_var anElementsId = theObject->GetIDs();
2901 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2902 theNbOfSteps, true, SMDSAbs_Face);
2903 if (!myIsPreviewMode) {
2904 dumpGroupsList(aPythonDump, aGroups);
2905 aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
2906 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2912 //=======================================================================
2913 //function : advancedExtrusion
2915 //=======================================================================
2917 SMESH::ListOfGroups*
2918 SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
2919 const SMESH::DirStruct & theStepVector,
2920 CORBA::Long theNbOfSteps,
2921 CORBA::Long theExtrFlags,
2922 CORBA::Double theSewTolerance,
2923 const bool theMakeGroups)
2924 throw (SALOME::SALOME_Exception)
2929 TIDSortedElemSet elements;
2930 arrayToSet(theIDsOfElements, getMeshDS(), elements);
2932 const SMESH::PointStruct * P = &theStepVector.PS;
2933 gp_Vec stepVec( P->x, P->y, P->z );
2935 ::SMESH_MeshEditor::TTElemOfElemListMap aHystory;
2936 ::SMESH_MeshEditor::PGroupIDs groupIds =
2937 getEditor().ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
2938 theMakeGroups, theExtrFlags, theSewTolerance);
2940 declareMeshModified( /*isReComputeSafe=*/true );
2942 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2944 SMESH_CATCH( SMESH::throwCorbaException );
2948 //=======================================================================
2949 //function : AdvancedExtrusion
2951 //=======================================================================
2953 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2954 const SMESH::DirStruct & theStepVector,
2955 CORBA::Long theNbOfSteps,
2956 CORBA::Long theExtrFlags,
2957 CORBA::Double theSewTolerance)
2958 throw (SALOME::SALOME_Exception)
2960 if ( !myIsPreviewMode ) {
2961 TPythonDump() << "stepVector = " << theStepVector;
2962 TPythonDump() << this << ".AdvancedExtrusion("
2965 << theNbOfSteps << ","
2966 << theExtrFlags << ", "
2967 << theSewTolerance << " )";
2969 advancedExtrusion( theIDsOfElements,
2977 //=======================================================================
2978 //function : AdvancedExtrusionMakeGroups
2980 //=======================================================================
2981 SMESH::ListOfGroups*
2982 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
2983 const SMESH::DirStruct& theStepVector,
2984 CORBA::Long theNbOfSteps,
2985 CORBA::Long theExtrFlags,
2986 CORBA::Double theSewTolerance)
2987 throw (SALOME::SALOME_Exception)
2989 if (!myIsPreviewMode) {
2990 TPythonDump() << "stepVector = " << theStepVector;
2992 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2994 SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
3001 if (!myIsPreviewMode) {
3002 dumpGroupsList(aPythonDump, aGroups);
3003 aPythonDump << this << ".AdvancedExtrusionMakeGroups("
3006 << theNbOfSteps << ","
3007 << theExtrFlags << ", "
3008 << theSewTolerance << " )";
3014 //================================================================================
3016 * \brief Convert extrusion error to IDL enum
3018 //================================================================================
3020 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
3022 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
3026 RETCASE( EXTR_NO_ELEMENTS );
3027 RETCASE( EXTR_PATH_NOT_EDGE );
3028 RETCASE( EXTR_BAD_PATH_SHAPE );
3029 RETCASE( EXTR_BAD_STARTING_NODE );
3030 RETCASE( EXTR_BAD_ANGLES_NUMBER );
3031 RETCASE( EXTR_CANT_GET_TANGENT );
3033 return SMESH::SMESH_MeshEditor::EXTR_OK;
3037 //=======================================================================
3038 //function : extrusionAlongPath
3040 //=======================================================================
3041 SMESH::ListOfGroups*
3042 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfElements,
3043 SMESH::SMESH_Mesh_ptr thePathMesh,
3044 GEOM::GEOM_Object_ptr thePathShape,
3045 CORBA::Long theNodeStart,
3046 CORBA::Boolean theHasAngles,
3047 const SMESH::double_array & theAngles,
3048 CORBA::Boolean theHasRefPoint,
3049 const SMESH::PointStruct & theRefPoint,
3050 const bool theMakeGroups,
3051 SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
3052 const SMDSAbs_ElementType theElementType)
3053 throw (SALOME::SALOME_Exception)
3056 MESSAGE("extrusionAlongPath");
3059 if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
3060 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3063 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3065 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3066 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3068 if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
3069 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3073 SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
3075 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3079 TIDSortedElemSet elements;
3080 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
3082 list<double> angles;
3083 for (int i = 0; i < theAngles.length(); i++) {
3084 angles.push_back( theAngles[i] );
3087 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
3089 int nbOldGroups = myMesh->NbGroup();
3091 ::SMESH_MeshEditor::Extrusion_Error error =
3092 getEditor().ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
3093 theHasAngles, angles, false,
3094 theHasRefPoint, refPnt, theMakeGroups );
3096 declareMeshModified( /*isReComputeSafe=*/true );
3097 theError = convExtrError( error );
3099 if ( theMakeGroups ) {
3100 list<int> groupIDs = myMesh->GetGroupIds();
3101 list<int>::iterator newBegin = groupIDs.begin();
3102 std::advance( newBegin, nbOldGroups ); // skip old groups
3103 groupIDs.erase( groupIDs.begin(), newBegin );
3104 return getGroups( & groupIDs );
3108 SMESH_CATCH( SMESH::throwCorbaException );
3112 //=======================================================================
3113 //function : extrusionAlongPathX
3115 //=======================================================================
3117 SMESH::ListOfGroups*
3118 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements,
3119 SMESH::SMESH_IDSource_ptr Path,
3120 CORBA::Long NodeStart,
3121 CORBA::Boolean HasAngles,
3122 const SMESH::double_array& Angles,
3123 CORBA::Boolean LinearVariation,
3124 CORBA::Boolean HasRefPoint,
3125 const SMESH::PointStruct& RefPoint,
3127 const SMDSAbs_ElementType ElementType,
3128 SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
3129 throw (SALOME::SALOME_Exception)
3132 SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
3136 list<double> angles;
3137 for (int i = 0; i < Angles.length(); i++) {
3138 angles.push_back( Angles[i] );
3140 gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
3141 int nbOldGroups = myMesh->NbGroup();
3143 if ( Path->_is_nil() ) {
3144 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3148 TIDSortedElemSet elements, copyElements;
3149 arrayToSet(IDsOfElements, getMeshDS(), elements, ElementType);
3151 TIDSortedElemSet* workElements = &elements;
3153 if ( myIsPreviewMode )
3155 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
3156 getPreviewMesh( SMDSAbs_Face )->Copy( elements, copyElements, select, avoid );
3157 workElements = & copyElements;
3161 ::SMESH_MeshEditor::Extrusion_Error error;
3163 if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path ))
3166 SMDS_MeshNode* aNodeStart =
3167 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
3168 if ( !aNodeStart ) {
3169 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3172 error = getEditor().ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
3173 HasAngles, angles, LinearVariation,
3174 HasRefPoint, refPnt, MakeGroups );
3175 declareMeshModified( /*isReComputeSafe=*/true );
3177 else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
3180 SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
3181 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
3182 SMDS_MeshNode* aNodeStart =
3183 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
3184 if ( !aNodeStart ) {
3185 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3188 SMESH_subMesh* aSubMesh =
3189 aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
3190 error = getEditor().ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
3191 HasAngles, angles, LinearVariation,
3192 HasRefPoint, refPnt, MakeGroups );
3193 declareMeshModified( /*isReComputeSafe=*/true );
3195 else if ( SMESH::DownCast<SMESH_Group_i*>( Path ))
3197 // path as group of 1D elements
3203 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3207 Error = convExtrError( error );
3210 list<int> groupIDs = myMesh->GetGroupIds();
3211 list<int>::iterator newBegin = groupIDs.begin();
3212 std::advance( newBegin, nbOldGroups ); // skip old groups
3213 groupIDs.erase( groupIDs.begin(), newBegin );
3214 return getGroups( & groupIDs );
3218 SMESH_CATCH( SMESH::throwCorbaException );
3222 //=======================================================================
3223 //function : ExtrusionAlongPath
3225 //=======================================================================
3227 SMESH::SMESH_MeshEditor::Extrusion_Error
3228 SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements,
3229 SMESH::SMESH_Mesh_ptr thePathMesh,
3230 GEOM::GEOM_Object_ptr thePathShape,
3231 CORBA::Long theNodeStart,
3232 CORBA::Boolean theHasAngles,
3233 const SMESH::double_array & theAngles,
3234 CORBA::Boolean theHasRefPoint,
3235 const SMESH::PointStruct & theRefPoint)
3236 throw (SALOME::SALOME_Exception)
3238 MESSAGE("ExtrusionAlongPath");
3239 if ( !myIsPreviewMode ) {
3240 TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
3241 << theIDsOfElements << ", "
3242 << thePathMesh << ", "
3243 << thePathShape << ", "
3244 << theNodeStart << ", "
3245 << theHasAngles << ", "
3246 << theAngles << ", "
3247 << theHasRefPoint << ", "
3248 << "SMESH.PointStruct( "
3249 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3250 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3251 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3253 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3254 extrusionAlongPath( theIDsOfElements,
3267 //=======================================================================
3268 //function : ExtrusionAlongPathObject
3270 //=======================================================================
3272 SMESH::SMESH_MeshEditor::Extrusion_Error
3273 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject,
3274 SMESH::SMESH_Mesh_ptr thePathMesh,
3275 GEOM::GEOM_Object_ptr thePathShape,
3276 CORBA::Long theNodeStart,
3277 CORBA::Boolean theHasAngles,
3278 const SMESH::double_array & theAngles,
3279 CORBA::Boolean theHasRefPoint,
3280 const SMESH::PointStruct & theRefPoint)
3281 throw (SALOME::SALOME_Exception)
3283 if ( !myIsPreviewMode ) {
3284 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
3285 << theObject << ", "
3286 << thePathMesh << ", "
3287 << thePathShape << ", "
3288 << theNodeStart << ", "
3289 << theHasAngles << ", "
3290 << theAngles << ", "
3291 << theHasRefPoint << ", "
3292 << "SMESH.PointStruct( "
3293 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3294 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3295 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3297 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3298 prepareIdSource( theObject );
3299 SMESH::long_array_var anElementsId = theObject->GetIDs();
3300 extrusionAlongPath( anElementsId,
3313 //=======================================================================
3314 //function : ExtrusionAlongPathObject1D
3316 //=======================================================================
3318 SMESH::SMESH_MeshEditor::Extrusion_Error
3319 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject,
3320 SMESH::SMESH_Mesh_ptr thePathMesh,
3321 GEOM::GEOM_Object_ptr thePathShape,
3322 CORBA::Long theNodeStart,
3323 CORBA::Boolean theHasAngles,
3324 const SMESH::double_array & theAngles,
3325 CORBA::Boolean theHasRefPoint,
3326 const SMESH::PointStruct & theRefPoint)
3327 throw (SALOME::SALOME_Exception)
3329 if ( !myIsPreviewMode ) {
3330 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
3331 << theObject << ", "
3332 << thePathMesh << ", "
3333 << thePathShape << ", "
3334 << theNodeStart << ", "
3335 << theHasAngles << ", "
3336 << theAngles << ", "
3337 << theHasRefPoint << ", "
3338 << "SMESH.PointStruct( "
3339 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3340 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3341 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3343 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3344 prepareIdSource( theObject );
3345 SMESH::long_array_var anElementsId = theObject->GetIDs();
3346 extrusionAlongPath( anElementsId,
3360 //=======================================================================
3361 //function : ExtrusionAlongPathObject2D
3363 //=======================================================================
3365 SMESH::SMESH_MeshEditor::Extrusion_Error
3366 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject,
3367 SMESH::SMESH_Mesh_ptr thePathMesh,
3368 GEOM::GEOM_Object_ptr thePathShape,
3369 CORBA::Long theNodeStart,
3370 CORBA::Boolean theHasAngles,
3371 const SMESH::double_array & theAngles,
3372 CORBA::Boolean theHasRefPoint,
3373 const SMESH::PointStruct & theRefPoint)
3374 throw (SALOME::SALOME_Exception)
3376 if ( !myIsPreviewMode ) {
3377 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
3378 << theObject << ", "
3379 << thePathMesh << ", "
3380 << thePathShape << ", "
3381 << theNodeStart << ", "
3382 << theHasAngles << ", "
3383 << theAngles << ", "
3384 << theHasRefPoint << ", "
3385 << "SMESH.PointStruct( "
3386 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3387 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3388 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3390 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3391 prepareIdSource( theObject );
3392 SMESH::long_array_var anElementsId = theObject->GetIDs();
3393 extrusionAlongPath( anElementsId,
3408 //=======================================================================
3409 //function : ExtrusionAlongPathMakeGroups
3411 //=======================================================================
3413 SMESH::ListOfGroups*
3414 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theIDsOfElements,
3415 SMESH::SMESH_Mesh_ptr thePathMesh,
3416 GEOM::GEOM_Object_ptr thePathShape,
3417 CORBA::Long theNodeStart,
3418 CORBA::Boolean theHasAngles,
3419 const SMESH::double_array& theAngles,
3420 CORBA::Boolean theHasRefPoint,
3421 const SMESH::PointStruct& theRefPoint,
3422 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3423 throw (SALOME::SALOME_Exception)
3425 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3427 SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements,
3437 if (!myIsPreviewMode) {
3438 bool isDumpGroups = aGroups && aGroups->length() > 0;
3440 aPythonDump << "(" << aGroups << ", error)";
3442 aPythonDump <<"error";
3444 aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
3445 << theIDsOfElements << ", "
3446 << thePathMesh << ", "
3447 << thePathShape << ", "
3448 << theNodeStart << ", "
3449 << theHasAngles << ", "
3450 << theAngles << ", "
3451 << theHasRefPoint << ", "
3452 << "SMESH.PointStruct( "
3453 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3454 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3455 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3460 //=======================================================================
3461 //function : ExtrusionAlongPathObjectMakeGroups
3463 //=======================================================================
3465 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3466 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3467 SMESH::SMESH_Mesh_ptr thePathMesh,
3468 GEOM::GEOM_Object_ptr thePathShape,
3469 CORBA::Long theNodeStart,
3470 CORBA::Boolean theHasAngles,
3471 const SMESH::double_array& theAngles,
3472 CORBA::Boolean theHasRefPoint,
3473 const SMESH::PointStruct& theRefPoint,
3474 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3475 throw (SALOME::SALOME_Exception)
3477 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3479 prepareIdSource( theObject );
3480 SMESH::long_array_var anElementsId = theObject->GetIDs();
3481 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3492 if (!myIsPreviewMode) {
3493 bool isDumpGroups = aGroups && aGroups->length() > 0;
3495 aPythonDump << "(" << aGroups << ", error)";
3497 aPythonDump <<"error";
3499 aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
3500 << theObject << ", "
3501 << thePathMesh << ", "
3502 << thePathShape << ", "
3503 << theNodeStart << ", "
3504 << theHasAngles << ", "
3505 << theAngles << ", "
3506 << theHasRefPoint << ", "
3507 << "SMESH.PointStruct( "
3508 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3509 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3510 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3515 //=======================================================================
3516 //function : ExtrusionAlongPathObject1DMakeGroups
3518 //=======================================================================
3520 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3521 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3522 SMESH::SMESH_Mesh_ptr thePathMesh,
3523 GEOM::GEOM_Object_ptr thePathShape,
3524 CORBA::Long theNodeStart,
3525 CORBA::Boolean theHasAngles,
3526 const SMESH::double_array& theAngles,
3527 CORBA::Boolean theHasRefPoint,
3528 const SMESH::PointStruct& theRefPoint,
3529 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3530 throw (SALOME::SALOME_Exception)
3532 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3534 prepareIdSource( theObject );
3535 SMESH::long_array_var anElementsId = theObject->GetIDs();
3536 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3548 if (!myIsPreviewMode) {
3549 bool isDumpGroups = aGroups && aGroups->length() > 0;
3551 aPythonDump << "(" << aGroups << ", error)";
3553 aPythonDump << "error";
3555 aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
3556 << theObject << ", "
3557 << thePathMesh << ", "
3558 << thePathShape << ", "
3559 << theNodeStart << ", "
3560 << theHasAngles << ", "
3561 << theAngles << ", "
3562 << theHasRefPoint << ", "
3563 << "SMESH.PointStruct( "
3564 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3565 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3566 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3571 //=======================================================================
3572 //function : ExtrusionAlongPathObject2DMakeGroups
3574 //=======================================================================
3576 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3577 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3578 SMESH::SMESH_Mesh_ptr thePathMesh,
3579 GEOM::GEOM_Object_ptr thePathShape,
3580 CORBA::Long theNodeStart,
3581 CORBA::Boolean theHasAngles,
3582 const SMESH::double_array& theAngles,
3583 CORBA::Boolean theHasRefPoint,
3584 const SMESH::PointStruct& theRefPoint,
3585 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3586 throw (SALOME::SALOME_Exception)
3588 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3590 prepareIdSource( theObject );
3591 SMESH::long_array_var anElementsId = theObject->GetIDs();
3592 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3604 if (!myIsPreviewMode) {
3605 bool isDumpGroups = aGroups && aGroups->length() > 0;
3607 aPythonDump << "(" << aGroups << ", error)";
3609 aPythonDump << "error";
3611 aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
3612 << theObject << ", "
3613 << thePathMesh << ", "
3614 << thePathShape << ", "
3615 << theNodeStart << ", "
3616 << theHasAngles << ", "
3617 << theAngles << ", "
3618 << theHasRefPoint << ", "
3619 << "SMESH.PointStruct( "
3620 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3621 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3622 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3627 //=======================================================================
3628 //function : ExtrusionAlongPathObjX
3630 //=======================================================================
3632 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3633 ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr Object,
3634 SMESH::SMESH_IDSource_ptr Path,
3635 CORBA::Long NodeStart,
3636 CORBA::Boolean HasAngles,
3637 const SMESH::double_array& Angles,
3638 CORBA::Boolean LinearVariation,
3639 CORBA::Boolean HasRefPoint,
3640 const SMESH::PointStruct& RefPoint,
3641 CORBA::Boolean MakeGroups,
3642 SMESH::ElementType ElemType,
3643 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3644 throw (SALOME::SALOME_Exception)
3646 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3648 prepareIdSource( Object );
3649 SMESH::long_array_var anElementsId = Object->GetIDs();
3650 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
3659 (SMDSAbs_ElementType)ElemType,
3662 if (!myIsPreviewMode) {
3663 bool isDumpGroups = aGroups && aGroups->length() > 0;
3665 aPythonDump << "(" << *aGroups << ", error)";
3667 aPythonDump << "error";
3669 aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
3672 << NodeStart << ", "
3673 << HasAngles << ", "
3674 << TVar( Angles ) << ", "
3675 << LinearVariation << ", "
3676 << HasRefPoint << ", "
3677 << "SMESH.PointStruct( "
3678 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3679 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3680 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3681 << MakeGroups << ", "
3682 << ElemType << " )";
3687 //=======================================================================
3688 //function : ExtrusionAlongPathX
3690 //=======================================================================
3692 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3693 ExtrusionAlongPathX(const SMESH::long_array& IDsOfElements,
3694 SMESH::SMESH_IDSource_ptr Path,
3695 CORBA::Long NodeStart,
3696 CORBA::Boolean HasAngles,
3697 const SMESH::double_array& Angles,
3698 CORBA::Boolean LinearVariation,
3699 CORBA::Boolean HasRefPoint,
3700 const SMESH::PointStruct& RefPoint,
3701 CORBA::Boolean MakeGroups,
3702 SMESH::ElementType ElemType,
3703 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3704 throw (SALOME::SALOME_Exception)
3706 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3708 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
3717 (SMDSAbs_ElementType)ElemType,
3720 if (!myIsPreviewMode) {
3721 bool isDumpGroups = aGroups && aGroups->length() > 0;
3723 aPythonDump << "(" << *aGroups << ", error)";
3725 aPythonDump <<"error";
3727 aPythonDump << " = " << this << ".ExtrusionAlongPathX( "
3728 << IDsOfElements << ", "
3730 << NodeStart << ", "
3731 << HasAngles << ", "
3732 << TVar( Angles ) << ", "
3733 << LinearVariation << ", "
3734 << HasRefPoint << ", "
3735 << "SMESH.PointStruct( "
3736 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3737 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3738 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3739 << MakeGroups << ", "
3740 << ElemType << " )";
3745 //================================================================================
3747 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
3748 * of given angles along path steps
3749 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
3750 * which proceeds the extrusion
3751 * \param PathShape is shape(edge); as the mesh can be complex, the edge
3752 * is used to define the sub-mesh for the path
3754 //================================================================================
3756 SMESH::double_array*
3757 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
3758 GEOM::GEOM_Object_ptr thePathShape,
3759 const SMESH::double_array & theAngles)
3761 SMESH::double_array_var aResult = new SMESH::double_array();
3762 int nbAngles = theAngles.length();
3763 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
3765 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3766 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3767 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3768 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
3769 return aResult._retn();
3770 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
3771 if ( nbSteps == nbAngles )
3773 aResult.inout() = theAngles;
3777 aResult->length( nbSteps );
3778 double rAn2St = double( nbAngles ) / double( nbSteps );
3779 double angPrev = 0, angle;
3780 for ( int iSt = 0; iSt < nbSteps; ++iSt )
3782 double angCur = rAn2St * ( iSt+1 );
3783 double angCurFloor = floor( angCur );
3784 double angPrevFloor = floor( angPrev );
3785 if ( angPrevFloor == angCurFloor )
3786 angle = rAn2St * theAngles[ int( angCurFloor ) ];
3789 int iP = int( angPrevFloor );
3790 double angPrevCeil = ceil(angPrev);
3791 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
3793 int iC = int( angCurFloor );
3794 if ( iC < nbAngles )
3795 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
3797 iP = int( angPrevCeil );
3799 angle += theAngles[ iC ];
3801 aResult[ iSt ] = angle;
3806 // Update Python script
3807 TPythonDump() << "rotAngles = " << theAngles;
3808 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
3809 << thePathMesh << ", "
3810 << thePathShape << ", "
3813 return aResult._retn();
3816 //=======================================================================
3819 //=======================================================================
3821 SMESH::ListOfGroups*
3822 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
3823 const SMESH::AxisStruct & theAxis,
3824 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3825 CORBA::Boolean theCopy,
3827 ::SMESH_Mesh* theTargetMesh)
3828 throw (SALOME::SALOME_Exception)
3833 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3834 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3836 if ( theTargetMesh )
3840 switch ( theMirrorType ) {
3841 case SMESH::SMESH_MeshEditor::POINT:
3842 aTrsf.SetMirror( P );
3844 case SMESH::SMESH_MeshEditor::AXIS:
3845 aTrsf.SetMirror( gp_Ax1( P, V ));
3848 aTrsf.SetMirror( gp_Ax2( P, V ));
3851 TIDSortedElemSet copyElements;
3852 TIDSortedElemSet* workElements = & theElements;
3854 if ( myIsPreviewMode )
3856 TPreviewMesh * tmpMesh = getPreviewMesh();
3857 tmpMesh->Copy( theElements, copyElements);
3858 if ( !theCopy && !theTargetMesh )
3860 TIDSortedElemSet elemsAround, elemsAroundCopy;
3861 getElementsAround( theElements, getMeshDS(), elemsAround );
3862 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3864 workElements = & copyElements;
3865 theMakeGroups = false;
3868 ::SMESH_MeshEditor::PGroupIDs groupIds =
3869 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3871 if ( theCopy && !myIsPreviewMode)
3873 if ( theTargetMesh )
3875 theTargetMesh->GetMeshDS()->Modified();
3879 declareMeshModified( /*isReComputeSafe=*/false );
3882 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3884 SMESH_CATCH( SMESH::throwCorbaException );
3888 //=======================================================================
3891 //=======================================================================
3893 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3894 const SMESH::AxisStruct & theAxis,
3895 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3896 CORBA::Boolean theCopy)
3897 throw (SALOME::SALOME_Exception)
3899 if ( !myIsPreviewMode ) {
3900 TPythonDump() << this << ".Mirror( "
3901 << theIDsOfElements << ", "
3903 << mirrorTypeName(theMirrorType) << ", "
3906 if ( theIDsOfElements.length() > 0 )
3908 TIDSortedElemSet elements;
3909 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3910 mirror(elements, theAxis, theMirrorType, theCopy, false);
3915 //=======================================================================
3916 //function : MirrorObject
3918 //=======================================================================
3920 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3921 const SMESH::AxisStruct & theAxis,
3922 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3923 CORBA::Boolean theCopy)
3924 throw (SALOME::SALOME_Exception)
3926 if ( !myIsPreviewMode ) {
3927 TPythonDump() << this << ".MirrorObject( "
3928 << theObject << ", "
3930 << mirrorTypeName(theMirrorType) << ", "
3933 TIDSortedElemSet elements;
3935 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3937 prepareIdSource( theObject );
3938 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3939 mirror(elements, theAxis, theMirrorType, theCopy, false);
3942 //=======================================================================
3943 //function : MirrorMakeGroups
3945 //=======================================================================
3947 SMESH::ListOfGroups*
3948 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3949 const SMESH::AxisStruct& theMirror,
3950 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3951 throw (SALOME::SALOME_Exception)
3953 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3955 SMESH::ListOfGroups * aGroups = 0;
3956 if ( theIDsOfElements.length() > 0 )
3958 TIDSortedElemSet elements;
3959 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3960 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3962 if (!myIsPreviewMode) {
3963 dumpGroupsList(aPythonDump, aGroups);
3964 aPythonDump << this << ".MirrorMakeGroups( "
3965 << theIDsOfElements << ", "
3966 << theMirror << ", "
3967 << mirrorTypeName(theMirrorType) << " )";
3972 //=======================================================================
3973 //function : MirrorObjectMakeGroups
3975 //=======================================================================
3977 SMESH::ListOfGroups*
3978 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3979 const SMESH::AxisStruct& theMirror,
3980 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3981 throw (SALOME::SALOME_Exception)
3983 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3985 SMESH::ListOfGroups * aGroups = 0;
3986 TIDSortedElemSet elements;
3987 prepareIdSource( theObject );
3988 if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3989 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3991 if (!myIsPreviewMode)
3993 dumpGroupsList(aPythonDump,aGroups);
3994 aPythonDump << this << ".MirrorObjectMakeGroups( "
3995 << theObject << ", "
3996 << theMirror << ", "
3997 << mirrorTypeName(theMirrorType) << " )";
4002 //=======================================================================
4003 //function : MirrorMakeMesh
4005 //=======================================================================
4007 SMESH::SMESH_Mesh_ptr
4008 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
4009 const SMESH::AxisStruct& theMirror,
4010 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
4011 CORBA::Boolean theCopyGroups,
4012 const char* theMeshName)
4013 throw (SALOME::SALOME_Exception)
4015 SMESH_Mesh_i* mesh_i;
4016 SMESH::SMESH_Mesh_var mesh;
4017 { // open new scope to dump "MakeMesh" command
4018 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4020 TPythonDump pydump; // to prevent dump at mesh creation
4022 mesh = makeMesh( theMeshName );
4023 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4024 if (mesh_i && theIDsOfElements.length() > 0 )
4026 TIDSortedElemSet elements;
4027 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4028 mirror(elements, theMirror, theMirrorType,
4029 false, theCopyGroups, & mesh_i->GetImpl());
4030 mesh_i->CreateGroupServants();
4033 if (!myIsPreviewMode) {
4034 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
4035 << theIDsOfElements << ", "
4036 << theMirror << ", "
4037 << mirrorTypeName(theMirrorType) << ", "
4038 << theCopyGroups << ", '"
4039 << theMeshName << "' )";
4044 if (!myIsPreviewMode && mesh_i)
4045 mesh_i->GetGroups();
4047 return mesh._retn();
4050 //=======================================================================
4051 //function : MirrorObjectMakeMesh
4053 //=======================================================================
4055 SMESH::SMESH_Mesh_ptr
4056 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4057 const SMESH::AxisStruct& theMirror,
4058 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
4059 CORBA::Boolean theCopyGroups,
4060 const char* theMeshName)
4061 throw (SALOME::SALOME_Exception)
4063 SMESH_Mesh_i* mesh_i;
4064 SMESH::SMESH_Mesh_var mesh;
4065 { // open new scope to dump "MakeMesh" command
4066 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4068 TPythonDump pydump; // to prevent dump at mesh creation
4070 mesh = makeMesh( theMeshName );
4071 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4072 TIDSortedElemSet elements;
4073 prepareIdSource( theObject );
4075 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4077 mirror(elements, theMirror, theMirrorType,
4078 false, theCopyGroups, & mesh_i->GetImpl());
4079 mesh_i->CreateGroupServants();
4081 if (!myIsPreviewMode) {
4082 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
4083 << theObject << ", "
4084 << theMirror << ", "
4085 << mirrorTypeName(theMirrorType) << ", "
4086 << theCopyGroups << ", '"
4087 << theMeshName << "' )";
4092 if (!myIsPreviewMode && mesh_i)
4093 mesh_i->GetGroups();
4095 return mesh._retn();
4098 //=======================================================================
4099 //function : translate
4101 //=======================================================================
4103 SMESH::ListOfGroups*
4104 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
4105 const SMESH::DirStruct & theVector,
4106 CORBA::Boolean theCopy,
4108 ::SMESH_Mesh* theTargetMesh)
4109 throw (SALOME::SALOME_Exception)
4114 if ( theTargetMesh )
4118 const SMESH::PointStruct * P = &theVector.PS;
4119 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
4121 TIDSortedElemSet copyElements;
4122 TIDSortedElemSet* workElements = &theElements;
4124 if ( myIsPreviewMode )
4126 TPreviewMesh * tmpMesh = getPreviewMesh();
4127 tmpMesh->Copy( theElements, copyElements);
4128 if ( !theCopy && !theTargetMesh )
4130 TIDSortedElemSet elemsAround, elemsAroundCopy;
4131 getElementsAround( theElements, getMeshDS(), elemsAround );
4132 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4134 workElements = & copyElements;
4135 theMakeGroups = false;
4138 ::SMESH_MeshEditor::PGroupIDs groupIds =
4139 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4141 if ( theCopy && !myIsPreviewMode )
4143 if ( theTargetMesh )
4145 theTargetMesh->GetMeshDS()->Modified();
4149 declareMeshModified( /*isReComputeSafe=*/false );
4153 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4155 SMESH_CATCH( SMESH::throwCorbaException );
4159 //=======================================================================
4160 //function : Translate
4162 //=======================================================================
4164 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
4165 const SMESH::DirStruct & theVector,
4166 CORBA::Boolean theCopy)
4167 throw (SALOME::SALOME_Exception)
4169 if (!myIsPreviewMode) {
4170 TPythonDump() << this << ".Translate( "
4171 << theIDsOfElements << ", "
4172 << theVector << ", "
4175 if (theIDsOfElements.length()) {
4176 TIDSortedElemSet elements;
4177 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4178 translate(elements, theVector, theCopy, false);
4182 //=======================================================================
4183 //function : TranslateObject
4185 //=======================================================================
4187 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
4188 const SMESH::DirStruct & theVector,
4189 CORBA::Boolean theCopy)
4190 throw (SALOME::SALOME_Exception)
4192 if (!myIsPreviewMode) {
4193 TPythonDump() << this << ".TranslateObject( "
4194 << theObject << ", "
4195 << theVector << ", "
4198 TIDSortedElemSet elements;
4200 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4202 prepareIdSource( theObject );
4203 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4204 translate(elements, theVector, theCopy, false);
4207 //=======================================================================
4208 //function : TranslateMakeGroups
4210 //=======================================================================
4212 SMESH::ListOfGroups*
4213 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
4214 const SMESH::DirStruct& theVector)
4215 throw (SALOME::SALOME_Exception)
4217 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4219 SMESH::ListOfGroups * aGroups = 0;
4220 if (theIDsOfElements.length()) {
4221 TIDSortedElemSet elements;
4222 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4223 aGroups = translate(elements,theVector,true,true);
4225 if (!myIsPreviewMode) {
4226 dumpGroupsList(aPythonDump, aGroups);
4227 aPythonDump << this << ".TranslateMakeGroups( "
4228 << theIDsOfElements << ", "
4229 << theVector << " )";
4234 //=======================================================================
4235 //function : TranslateObjectMakeGroups
4237 //=======================================================================
4239 SMESH::ListOfGroups*
4240 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4241 const SMESH::DirStruct& theVector)
4242 throw (SALOME::SALOME_Exception)
4244 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4246 SMESH::ListOfGroups * aGroups = 0;
4247 TIDSortedElemSet elements;
4248 prepareIdSource( theObject );
4249 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4250 aGroups = translate(elements, theVector, true, true);
4252 if (!myIsPreviewMode) {
4253 dumpGroupsList(aPythonDump, aGroups);
4254 aPythonDump << this << ".TranslateObjectMakeGroups( "
4255 << theObject << ", "
4256 << theVector << " )";
4261 //=======================================================================
4262 //function : TranslateMakeMesh
4264 //=======================================================================
4266 SMESH::SMESH_Mesh_ptr
4267 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
4268 const SMESH::DirStruct& theVector,
4269 CORBA::Boolean theCopyGroups,
4270 const char* theMeshName)
4271 throw (SALOME::SALOME_Exception)
4273 SMESH_Mesh_i* mesh_i;
4274 SMESH::SMESH_Mesh_var mesh;
4276 { // open new scope to dump "MakeMesh" command
4277 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4279 TPythonDump pydump; // to prevent dump at mesh creation
4281 mesh = makeMesh( theMeshName );
4282 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4284 if ( mesh_i && theIDsOfElements.length() )
4286 TIDSortedElemSet elements;
4287 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4288 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
4289 mesh_i->CreateGroupServants();
4292 if ( !myIsPreviewMode ) {
4293 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
4294 << theIDsOfElements << ", "
4295 << theVector << ", "
4296 << theCopyGroups << ", '"
4297 << theMeshName << "' )";
4302 if (!myIsPreviewMode && mesh_i)
4303 mesh_i->GetGroups();
4305 return mesh._retn();
4308 //=======================================================================
4309 //function : TranslateObjectMakeMesh
4311 //=======================================================================
4313 SMESH::SMESH_Mesh_ptr
4314 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4315 const SMESH::DirStruct& theVector,
4316 CORBA::Boolean theCopyGroups,
4317 const char* theMeshName)
4318 throw (SALOME::SALOME_Exception)
4321 SMESH_Mesh_i* mesh_i;
4322 SMESH::SMESH_Mesh_var mesh;
4323 { // open new scope to dump "MakeMesh" command
4324 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4326 TPythonDump pydump; // to prevent dump at mesh creation
4327 mesh = makeMesh( theMeshName );
4328 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4330 TIDSortedElemSet elements;
4331 prepareIdSource( theObject );
4333 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4335 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
4336 mesh_i->CreateGroupServants();
4338 if ( !myIsPreviewMode ) {
4339 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
4340 << theObject << ", "
4341 << theVector << ", "
4342 << theCopyGroups << ", '"
4343 << theMeshName << "' )";
4348 if (!myIsPreviewMode && mesh_i)
4349 mesh_i->GetGroups();
4351 return mesh._retn();
4353 SMESH_CATCH( SMESH::throwCorbaException );
4357 //=======================================================================
4360 //=======================================================================
4362 SMESH::ListOfGroups*
4363 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
4364 const SMESH::AxisStruct & theAxis,
4365 CORBA::Double theAngle,
4366 CORBA::Boolean theCopy,
4368 ::SMESH_Mesh* theTargetMesh)
4369 throw (SALOME::SALOME_Exception)
4374 if ( theTargetMesh )
4377 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
4378 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
4381 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
4383 TIDSortedElemSet copyElements;
4384 TIDSortedElemSet* workElements = &theElements;
4385 if ( myIsPreviewMode ) {
4386 TPreviewMesh * tmpMesh = getPreviewMesh();
4387 tmpMesh->Copy( theElements, copyElements );
4388 if ( !theCopy && !theTargetMesh )
4390 TIDSortedElemSet elemsAround, elemsAroundCopy;
4391 getElementsAround( theElements, getMeshDS(), elemsAround );
4392 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4394 workElements = ©Elements;
4395 theMakeGroups = false;
4398 ::SMESH_MeshEditor::PGroupIDs groupIds =
4399 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4401 if ( theCopy && !myIsPreviewMode)
4403 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
4404 else declareMeshModified( /*isReComputeSafe=*/false );
4407 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4409 SMESH_CATCH( SMESH::throwCorbaException );
4413 //=======================================================================
4416 //=======================================================================
4418 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
4419 const SMESH::AxisStruct & theAxis,
4420 CORBA::Double theAngle,
4421 CORBA::Boolean theCopy)
4422 throw (SALOME::SALOME_Exception)
4424 if (!myIsPreviewMode) {
4425 TPythonDump() << this << ".Rotate( "
4426 << theIDsOfElements << ", "
4428 << TVar( theAngle ) << ", "
4431 if (theIDsOfElements.length() > 0)
4433 TIDSortedElemSet elements;
4434 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4435 rotate(elements,theAxis,theAngle,theCopy,false);
4439 //=======================================================================
4440 //function : RotateObject
4442 //=======================================================================
4444 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
4445 const SMESH::AxisStruct & theAxis,
4446 CORBA::Double theAngle,
4447 CORBA::Boolean theCopy)
4448 throw (SALOME::SALOME_Exception)
4450 if ( !myIsPreviewMode ) {
4451 TPythonDump() << this << ".RotateObject( "
4452 << theObject << ", "
4454 << TVar( theAngle ) << ", "
4457 TIDSortedElemSet elements;
4458 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4459 prepareIdSource( theObject );
4460 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4461 rotate(elements,theAxis,theAngle,theCopy,false);
4464 //=======================================================================
4465 //function : RotateMakeGroups
4467 //=======================================================================
4469 SMESH::ListOfGroups*
4470 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
4471 const SMESH::AxisStruct& theAxis,
4472 CORBA::Double theAngle)
4473 throw (SALOME::SALOME_Exception)
4475 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4477 SMESH::ListOfGroups * aGroups = 0;
4478 if (theIDsOfElements.length() > 0)
4480 TIDSortedElemSet elements;
4481 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4482 aGroups = rotate(elements,theAxis,theAngle,true,true);
4484 if (!myIsPreviewMode) {
4485 dumpGroupsList(aPythonDump, aGroups);
4486 aPythonDump << this << ".RotateMakeGroups( "
4487 << theIDsOfElements << ", "
4489 << TVar( theAngle ) << " )";
4494 //=======================================================================
4495 //function : RotateObjectMakeGroups
4497 //=======================================================================
4499 SMESH::ListOfGroups*
4500 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4501 const SMESH::AxisStruct& theAxis,
4502 CORBA::Double theAngle)
4503 throw (SALOME::SALOME_Exception)
4505 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4507 SMESH::ListOfGroups * aGroups = 0;
4508 TIDSortedElemSet elements;
4509 prepareIdSource( theObject );
4510 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4511 aGroups = rotate(elements, theAxis, theAngle, true, true);
4513 if (!myIsPreviewMode) {
4514 dumpGroupsList(aPythonDump, aGroups);
4515 aPythonDump << this << ".RotateObjectMakeGroups( "
4516 << theObject << ", "
4518 << TVar( theAngle ) << " )";
4523 //=======================================================================
4524 //function : RotateMakeMesh
4526 //=======================================================================
4528 SMESH::SMESH_Mesh_ptr
4529 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
4530 const SMESH::AxisStruct& theAxis,
4531 CORBA::Double theAngleInRadians,
4532 CORBA::Boolean theCopyGroups,
4533 const char* theMeshName)
4534 throw (SALOME::SALOME_Exception)
4537 SMESH::SMESH_Mesh_var mesh;
4538 SMESH_Mesh_i* mesh_i;
4540 { // open new scope to dump "MakeMesh" command
4541 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4543 TPythonDump pydump; // to prevent dump at mesh creation
4545 mesh = makeMesh( theMeshName );
4546 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4548 if ( mesh_i && theIDsOfElements.length() > 0 )
4550 TIDSortedElemSet elements;
4551 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4552 rotate(elements, theAxis, theAngleInRadians,
4553 false, theCopyGroups, & mesh_i->GetImpl());
4554 mesh_i->CreateGroupServants();
4556 if ( !myIsPreviewMode ) {
4557 pydump << mesh << " = " << this << ".RotateMakeMesh( "
4558 << theIDsOfElements << ", "
4560 << TVar( theAngleInRadians ) << ", "
4561 << theCopyGroups << ", '"
4562 << theMeshName << "' )";
4567 if (!myIsPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
4568 mesh_i->GetGroups();
4570 return mesh._retn();
4572 SMESH_CATCH( SMESH::throwCorbaException );
4576 //=======================================================================
4577 //function : RotateObjectMakeMesh
4579 //=======================================================================
4581 SMESH::SMESH_Mesh_ptr
4582 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4583 const SMESH::AxisStruct& theAxis,
4584 CORBA::Double theAngleInRadians,
4585 CORBA::Boolean theCopyGroups,
4586 const char* theMeshName)
4587 throw (SALOME::SALOME_Exception)
4590 SMESH::SMESH_Mesh_var mesh;
4591 SMESH_Mesh_i* mesh_i;
4593 {// open new scope to dump "MakeMesh" command
4594 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4596 TPythonDump pydump; // to prevent dump at mesh creation
4597 mesh = makeMesh( theMeshName );
4598 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4600 TIDSortedElemSet elements;
4601 prepareIdSource( theObject );
4603 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4605 rotate(elements, theAxis, theAngleInRadians,
4606 false, theCopyGroups, & mesh_i->GetImpl());
4607 mesh_i->CreateGroupServants();
4609 if ( !myIsPreviewMode ) {
4610 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
4611 << theObject << ", "
4613 << TVar( theAngleInRadians ) << ", "
4614 << theCopyGroups << ", '"
4615 << theMeshName << "' )";
4620 if (!myIsPreviewMode && mesh_i)
4621 mesh_i->GetGroups();
4623 return mesh._retn();
4625 SMESH_CATCH( SMESH::throwCorbaException );
4629 //=======================================================================
4632 //=======================================================================
4634 SMESH::ListOfGroups*
4635 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
4636 const SMESH::PointStruct& thePoint,
4637 const SMESH::double_array& theScaleFact,
4638 CORBA::Boolean theCopy,
4640 ::SMESH_Mesh* theTargetMesh)
4641 throw (SALOME::SALOME_Exception)
4645 if ( theScaleFact.length() < 1 )
4646 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
4647 if ( theScaleFact.length() == 2 )
4648 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
4650 if ( theTargetMesh )
4653 TIDSortedElemSet elements;
4654 prepareIdSource( theObject );
4655 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4656 if ( !idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4661 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
4662 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
4664 double tol = std::numeric_limits<double>::max();
4666 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
4667 0, S[1], 0, thePoint.y * (1-S[1]),
4668 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
4670 TIDSortedElemSet copyElements;
4671 TIDSortedElemSet* workElements = &elements;
4672 if ( myIsPreviewMode )
4674 TPreviewMesh * tmpMesh = getPreviewMesh();
4675 tmpMesh->Copy( elements, copyElements);
4676 if ( !theCopy && !theTargetMesh )
4678 TIDSortedElemSet elemsAround, elemsAroundCopy;
4679 getElementsAround( elements, getMeshDS(), elemsAround );
4680 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4682 workElements = & copyElements;
4683 theMakeGroups = false;
4686 ::SMESH_MeshEditor::PGroupIDs groupIds =
4687 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4689 if ( theCopy && !myIsPreviewMode )
4691 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
4692 else declareMeshModified( /*isReComputeSafe=*/false );
4694 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4696 SMESH_CATCH( SMESH::throwCorbaException );
4700 //=======================================================================
4703 //=======================================================================
4705 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
4706 const SMESH::PointStruct& thePoint,
4707 const SMESH::double_array& theScaleFact,
4708 CORBA::Boolean theCopy)
4709 throw (SALOME::SALOME_Exception)
4711 if ( !myIsPreviewMode ) {
4712 TPythonDump() << this << ".Scale( "
4713 << theObject << ", "
4715 << TVar( theScaleFact ) << ", "
4718 scale(theObject, thePoint, theScaleFact, theCopy, false);
4722 //=======================================================================
4723 //function : ScaleMakeGroups
4725 //=======================================================================
4727 SMESH::ListOfGroups*
4728 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4729 const SMESH::PointStruct& thePoint,
4730 const SMESH::double_array& theScaleFact)
4731 throw (SALOME::SALOME_Exception)
4733 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4735 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
4736 if (!myIsPreviewMode) {
4737 dumpGroupsList(aPythonDump, aGroups);
4738 aPythonDump << this << ".Scale("
4741 << TVar( theScaleFact ) << ",True,True)";
4747 //=======================================================================
4748 //function : ScaleMakeMesh
4750 //=======================================================================
4752 SMESH::SMESH_Mesh_ptr
4753 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4754 const SMESH::PointStruct& thePoint,
4755 const SMESH::double_array& theScaleFact,
4756 CORBA::Boolean theCopyGroups,
4757 const char* theMeshName)
4758 throw (SALOME::SALOME_Exception)
4760 SMESH_Mesh_i* mesh_i;
4761 SMESH::SMESH_Mesh_var mesh;
4762 { // open new scope to dump "MakeMesh" command
4763 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4765 TPythonDump pydump; // to prevent dump at mesh creation
4766 mesh = makeMesh( theMeshName );
4767 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4771 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
4772 mesh_i->CreateGroupServants();
4774 if ( !myIsPreviewMode )
4775 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
4776 << theObject << ", "
4778 << TVar( theScaleFact ) << ", "
4779 << theCopyGroups << ", '"
4780 << theMeshName << "' )";
4784 if (!myIsPreviewMode && mesh_i)
4785 mesh_i->GetGroups();
4787 return mesh._retn();
4791 //=======================================================================
4792 //function : FindCoincidentNodes
4794 //=======================================================================
4796 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance,
4797 SMESH::array_of_long_array_out GroupsOfNodes)
4798 throw (SALOME::SALOME_Exception)
4803 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4804 TIDSortedNodeSet nodes; // no input nodes
4805 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4807 GroupsOfNodes = new SMESH::array_of_long_array;
4808 GroupsOfNodes->length( aListOfListOfNodes.size() );
4809 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4810 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
4811 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4812 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4813 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4814 aGroup.length( aListOfNodes.size() );
4815 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4816 aGroup[ j ] = (*lIt)->GetID();
4818 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
4819 << Tolerance << " )";
4821 SMESH_CATCH( SMESH::throwCorbaException );
4824 //=======================================================================
4825 //function : FindCoincidentNodesOnPart
4827 //=======================================================================
4829 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
4830 CORBA::Double Tolerance,
4831 SMESH::array_of_long_array_out GroupsOfNodes)
4832 throw (SALOME::SALOME_Exception)
4837 TIDSortedNodeSet nodes;
4838 prepareIdSource( theObject );
4839 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4841 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4843 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4845 GroupsOfNodes = new SMESH::array_of_long_array;
4846 GroupsOfNodes->length( aListOfListOfNodes.size() );
4847 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4848 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4850 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4851 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4852 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4853 aGroup.length( aListOfNodes.size() );
4854 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4855 aGroup[ j ] = (*lIt)->GetID();
4857 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
4859 << Tolerance << " )";
4861 SMESH_CATCH( SMESH::throwCorbaException );
4864 //================================================================================
4866 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
4867 * ExceptSubMeshOrGroups
4869 //================================================================================
4871 void SMESH_MeshEditor_i::
4872 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
4873 CORBA::Double theTolerance,
4874 SMESH::array_of_long_array_out theGroupsOfNodes,
4875 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups)
4876 throw (SALOME::SALOME_Exception)
4881 TIDSortedNodeSet nodes;
4882 prepareIdSource( theObject );
4883 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4885 for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
4887 TIDSortedNodeSet exceptNodes;
4888 idSourceToNodeSet( theExceptSubMeshOrGroups[i], getMeshDS(), exceptNodes );
4889 TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
4890 for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
4891 nodes.erase( *avoidNode );
4893 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4895 getEditor().FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
4897 theGroupsOfNodes = new SMESH::array_of_long_array;
4898 theGroupsOfNodes->length( aListOfListOfNodes.size() );
4899 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4900 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4902 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4903 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4904 SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
4905 aGroup.length( aListOfNodes.size() );
4906 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4907 aGroup[ j ] = (*lIt)->GetID();
4909 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
4911 << theTolerance << ", "
4912 << theExceptSubMeshOrGroups << " )";
4914 SMESH_CATCH( SMESH::throwCorbaException );
4917 //=======================================================================
4918 //function : MergeNodes
4920 //=======================================================================
4922 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
4923 throw (SALOME::SALOME_Exception)
4928 SMESHDS_Mesh* aMesh = getMeshDS();
4930 TPythonDump aTPythonDump;
4931 aTPythonDump << this << ".MergeNodes([";
4932 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4933 for (int i = 0; i < GroupsOfNodes.length(); i++)
4935 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
4936 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
4937 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
4938 for ( int j = 0; j < aNodeGroup.length(); j++ )
4940 CORBA::Long index = aNodeGroup[ j ];
4941 const SMDS_MeshNode * node = aMesh->FindNode(index);
4943 aListOfNodes.push_back( node );
4945 if ( aListOfNodes.size() < 2 )
4946 aListOfListOfNodes.pop_back();
4948 if ( i > 0 ) aTPythonDump << ", ";
4949 aTPythonDump << aNodeGroup;
4951 getEditor().MergeNodes( aListOfListOfNodes );
4953 aTPythonDump << "])";
4955 declareMeshModified( /*isReComputeSafe=*/false );
4957 SMESH_CATCH( SMESH::throwCorbaException );
4960 //=======================================================================
4961 //function : FindEqualElements
4963 //=======================================================================
4965 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
4966 SMESH::array_of_long_array_out GroupsOfElementsID)
4967 throw (SALOME::SALOME_Exception)
4972 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
4973 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
4975 TIDSortedElemSet elems;
4976 prepareIdSource( theObject );
4977 idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true);
4979 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4980 getEditor().FindEqualElements( elems, aListOfListOfElementsID );
4982 GroupsOfElementsID = new SMESH::array_of_long_array;
4983 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
4985 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt =
4986 aListOfListOfElementsID.begin();
4987 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j)
4989 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
4990 list<int>& listOfIDs = *arraysIt;
4991 aGroup.length( listOfIDs.size() );
4992 list<int>::iterator idIt = listOfIDs.begin();
4993 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k )
4994 aGroup[ k ] = *idIt;
4997 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
5001 SMESH_CATCH( SMESH::throwCorbaException );
5004 //=======================================================================
5005 //function : MergeElements
5007 //=======================================================================
5009 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
5010 throw (SALOME::SALOME_Exception)
5015 TPythonDump aTPythonDump;
5016 aTPythonDump << this << ".MergeElements( [";
5018 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
5020 for (int i = 0; i < GroupsOfElementsID.length(); i++) {
5021 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
5022 aListOfListOfElementsID.push_back( list< int >() );
5023 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
5024 for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
5025 CORBA::Long id = anElemsIDGroup[ j ];
5026 aListOfElemsID.push_back( id );
5028 if ( aListOfElemsID.size() < 2 )
5029 aListOfListOfElementsID.pop_back();
5030 if ( i > 0 ) aTPythonDump << ", ";
5031 aTPythonDump << anElemsIDGroup;
5034 getEditor().MergeElements(aListOfListOfElementsID);
5036 declareMeshModified( /*isReComputeSafe=*/true );
5038 aTPythonDump << "] )";
5040 SMESH_CATCH( SMESH::throwCorbaException );
5043 //=======================================================================
5044 //function : MergeEqualElements
5046 //=======================================================================
5048 void SMESH_MeshEditor_i::MergeEqualElements()
5049 throw (SALOME::SALOME_Exception)
5054 getEditor().MergeEqualElements();
5056 declareMeshModified( /*isReComputeSafe=*/true );
5058 TPythonDump() << this << ".MergeEqualElements()";
5060 SMESH_CATCH( SMESH::throwCorbaException );
5063 //=============================================================================
5065 * Move the node to a given point
5067 //=============================================================================
5069 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
5073 throw (SALOME::SALOME_Exception)
5076 initData(/*deleteSearchers=*/false);
5078 const SMDS_MeshNode * node = getMeshDS()->FindNode( NodeID );
5082 if ( theNodeSearcher )
5083 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5085 if ( myIsPreviewMode ) // make preview data
5087 // in a preview mesh, make edges linked to a node
5088 TPreviewMesh& tmpMesh = *getPreviewMesh();
5089 TIDSortedElemSet linkedNodes;
5090 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
5091 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
5092 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
5093 for ( ; nIt != linkedNodes.end(); ++nIt )
5095 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
5096 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
5100 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
5101 // fill preview data
5103 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
5104 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
5106 getMeshDS()->MoveNode(node, x, y, z);
5108 if ( !myIsPreviewMode )
5110 // Update Python script
5111 TPythonDump() << "isDone = " << this << ".MoveNode( "
5112 << NodeID << ", " << TVar(x) << ", " << TVar(y) << ", " << TVar(z) << " )";
5113 declareMeshModified( /*isReComputeSafe=*/false );
5116 SMESH_CATCH( SMESH::throwCorbaException );
5121 //================================================================================
5123 * \brief Return ID of node closest to a given point
5125 //================================================================================
5127 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
5130 throw (SALOME::SALOME_Exception)
5133 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5135 if ( !theNodeSearcher ) {
5136 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
5139 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
5140 return node->GetID();
5142 SMESH_CATCH( SMESH::throwCorbaException );
5146 //================================================================================
5148 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
5149 * move the node closest to the point to point's location and return ID of the node
5151 //================================================================================
5153 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
5156 CORBA::Long theNodeID)
5157 throw (SALOME::SALOME_Exception)
5160 // We keep theNodeSearcher until any mesh modification:
5161 // 1) initData() deletes theNodeSearcher at any edition,
5162 // 2) TSearchersDeleter - at any mesh compute event and mesh change
5164 initData(/*deleteSearchers=*/false);
5166 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5168 int nodeID = theNodeID;
5169 const SMDS_MeshNode* node = getMeshDS()->FindNode( nodeID );
5170 if ( !node ) // preview moving node
5172 if ( !theNodeSearcher ) {
5173 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
5176 node = theNodeSearcher->FindClosestTo( p );
5179 nodeID = node->GetID();
5180 if ( myIsPreviewMode ) // make preview data
5182 // in a preview mesh, make edges linked to a node
5183 TPreviewMesh tmpMesh = *getPreviewMesh();
5184 TIDSortedElemSet linkedNodes;
5185 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
5186 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
5187 for ( ; nIt != linkedNodes.end(); ++nIt )
5189 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
5190 tmpMesh.Copy( &edge );
5193 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
5195 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
5196 // fill preview data
5198 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
5200 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
5204 getMeshDS()->MoveNode(node, x, y, z);
5208 if ( !myIsPreviewMode )
5210 TPythonDump() << "nodeID = " << this
5211 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
5212 << ", " << nodeID << " )";
5214 declareMeshModified( /*isReComputeSafe=*/false );
5219 SMESH_CATCH( SMESH::throwCorbaException );
5223 //=======================================================================
5225 * Return elements of given type where the given point is IN or ON.
5227 * 'ALL' type means elements of any type excluding nodes
5229 //=======================================================================
5231 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
5234 SMESH::ElementType type)
5235 throw (SALOME::SALOME_Exception)
5238 SMESH::long_array_var res = new SMESH::long_array;
5239 vector< const SMDS_MeshElement* > foundElems;
5241 theSearchersDeleter.Set( myMesh );
5242 if ( !theElementSearcher ) {
5243 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
5245 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
5246 SMDSAbs_ElementType( type ),
5248 res->length( foundElems.size() );
5249 for ( int i = 0; i < foundElems.size(); ++i )
5250 res[i] = foundElems[i]->GetID();
5252 if ( !myIsPreviewMode ) // call from tui
5253 TPythonDump() << "res = " << this << ".FindElementsByPoint( "
5261 SMESH_CATCH( SMESH::throwCorbaException );
5265 //=======================================================================
5266 //function : FindAmongElementsByPoint
5267 //purpose : Searching among the given elements, return elements of given type
5268 // where the given point is IN or ON.
5269 // 'ALL' type means elements of any type excluding nodes
5270 //=======================================================================
5273 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
5277 SMESH::ElementType type)
5278 throw (SALOME::SALOME_Exception)
5281 SMESH::long_array_var res = new SMESH::long_array;
5283 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
5284 if ( types->length() == 1 && // a part contains only nodes or 0D elements
5285 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) &&
5286 type != types[0] ) // but search of elements of dim > 0
5289 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
5290 return FindElementsByPoint( x,y,z, type );
5292 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
5294 theSearchersDeleter.Set( myMesh, getPartIOR( elementIDs, type ));
5295 if ( !theElementSearcher )
5297 // create a searcher from elementIDs
5298 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
5299 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
5301 if ( !idSourceToSet( elementIDs, meshDS, elements,
5302 SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
5305 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5306 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
5308 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt );
5311 vector< const SMDS_MeshElement* > foundElems;
5313 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
5314 SMDSAbs_ElementType( type ),
5316 res->length( foundElems.size() );
5317 for ( int i = 0; i < foundElems.size(); ++i )
5318 res[i] = foundElems[i]->GetID();
5320 if ( !myIsPreviewMode ) // call from tui
5321 TPythonDump() << "res = " << this << ".FindAmongElementsByPoint( "
5322 << elementIDs << ", "
5330 SMESH_CATCH( SMESH::throwCorbaException );
5334 //=======================================================================
5335 //function : GetPointState
5336 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
5337 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
5338 //=======================================================================
5340 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
5343 throw (SALOME::SALOME_Exception)
5346 theSearchersDeleter.Set( myMesh );
5347 if ( !theElementSearcher ) {
5348 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
5350 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
5352 SMESH_CATCH( SMESH::throwCorbaException );
5356 //=======================================================================
5357 //function : convError
5359 //=======================================================================
5361 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
5363 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
5367 RETCASE( SEW_BORDER1_NOT_FOUND );
5368 RETCASE( SEW_BORDER2_NOT_FOUND );
5369 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
5370 RETCASE( SEW_BAD_SIDE_NODES );
5371 RETCASE( SEW_VOLUMES_TO_SPLIT );
5372 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
5373 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
5374 RETCASE( SEW_BAD_SIDE1_NODES );
5375 RETCASE( SEW_BAD_SIDE2_NODES );
5377 return SMESH::SMESH_MeshEditor::SEW_OK;
5380 //=======================================================================
5381 //function : SewFreeBorders
5383 //=======================================================================
5385 SMESH::SMESH_MeshEditor::Sew_Error
5386 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
5387 CORBA::Long SecondNodeID1,
5388 CORBA::Long LastNodeID1,
5389 CORBA::Long FirstNodeID2,
5390 CORBA::Long SecondNodeID2,
5391 CORBA::Long LastNodeID2,
5392 CORBA::Boolean CreatePolygons,
5393 CORBA::Boolean CreatePolyedrs)
5394 throw (SALOME::SALOME_Exception)
5399 SMESHDS_Mesh* aMesh = getMeshDS();
5401 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
5402 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
5403 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
5404 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
5405 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
5406 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
5408 if (!aBorderFirstNode ||
5409 !aBorderSecondNode||
5411 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5412 if (!aSide2FirstNode ||
5413 !aSide2SecondNode ||
5415 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
5417 TPythonDump() << "error = " << this << ".SewFreeBorders( "
5418 << FirstNodeID1 << ", "
5419 << SecondNodeID1 << ", "
5420 << LastNodeID1 << ", "
5421 << FirstNodeID2 << ", "
5422 << SecondNodeID2 << ", "
5423 << LastNodeID2 << ", "
5424 << CreatePolygons<< ", "
5425 << CreatePolyedrs<< " )";
5427 SMESH::SMESH_MeshEditor::Sew_Error error =
5428 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5439 declareMeshModified( /*isReComputeSafe=*/false );
5442 SMESH_CATCH( SMESH::throwCorbaException );
5443 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5447 //=======================================================================
5448 //function : SewConformFreeBorders
5450 //=======================================================================
5452 SMESH::SMESH_MeshEditor::Sew_Error
5453 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
5454 CORBA::Long SecondNodeID1,
5455 CORBA::Long LastNodeID1,
5456 CORBA::Long FirstNodeID2,
5457 CORBA::Long SecondNodeID2)
5458 throw (SALOME::SALOME_Exception)
5463 SMESHDS_Mesh* aMesh = getMeshDS();
5465 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
5466 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
5467 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
5468 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
5469 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
5470 const SMDS_MeshNode* aSide2ThirdNode = 0;
5472 if (!aBorderFirstNode ||
5473 !aBorderSecondNode||
5475 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5476 if (!aSide2FirstNode ||
5478 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
5480 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
5481 << FirstNodeID1 << ", "
5482 << SecondNodeID1 << ", "
5483 << LastNodeID1 << ", "
5484 << FirstNodeID2 << ", "
5485 << SecondNodeID2 << " )";
5487 SMESH::SMESH_MeshEditor::Sew_Error error =
5488 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5497 declareMeshModified( /*isReComputeSafe=*/false );
5500 SMESH_CATCH( SMESH::throwCorbaException );
5501 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5505 //=======================================================================
5506 //function : SewBorderToSide
5508 //=======================================================================
5510 SMESH::SMESH_MeshEditor::Sew_Error
5511 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
5512 CORBA::Long SecondNodeIDOnFreeBorder,
5513 CORBA::Long LastNodeIDOnFreeBorder,
5514 CORBA::Long FirstNodeIDOnSide,
5515 CORBA::Long LastNodeIDOnSide,
5516 CORBA::Boolean CreatePolygons,
5517 CORBA::Boolean CreatePolyedrs)
5518 throw (SALOME::SALOME_Exception)
5523 SMESHDS_Mesh* aMesh = getMeshDS();
5525 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
5526 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
5527 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
5528 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
5529 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
5530 const SMDS_MeshNode* aSide2ThirdNode = 0;
5532 if (!aBorderFirstNode ||
5533 !aBorderSecondNode||
5535 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5536 if (!aSide2FirstNode ||
5538 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
5540 TPythonDump() << "error = " << this << ".SewBorderToSide( "
5541 << FirstNodeIDOnFreeBorder << ", "
5542 << SecondNodeIDOnFreeBorder << ", "
5543 << LastNodeIDOnFreeBorder << ", "
5544 << FirstNodeIDOnSide << ", "
5545 << LastNodeIDOnSide << ", "
5546 << CreatePolygons << ", "
5547 << CreatePolyedrs << ") ";
5549 SMESH::SMESH_MeshEditor::Sew_Error error =
5550 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5560 declareMeshModified( /*isReComputeSafe=*/false );
5563 SMESH_CATCH( SMESH::throwCorbaException );
5564 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5568 //=======================================================================
5569 //function : SewSideElements
5571 //=======================================================================
5573 SMESH::SMESH_MeshEditor::Sew_Error
5574 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
5575 const SMESH::long_array& IDsOfSide2Elements,
5576 CORBA::Long NodeID1OfSide1ToMerge,
5577 CORBA::Long NodeID1OfSide2ToMerge,
5578 CORBA::Long NodeID2OfSide1ToMerge,
5579 CORBA::Long NodeID2OfSide2ToMerge)
5580 throw (SALOME::SALOME_Exception)
5585 SMESHDS_Mesh* aMesh = getMeshDS();
5587 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
5588 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
5589 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
5590 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
5592 if (!aFirstNode1ToMerge ||
5593 !aFirstNode2ToMerge )
5594 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
5595 if (!aSecondNode1ToMerge||
5596 !aSecondNode2ToMerge)
5597 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
5599 TIDSortedElemSet aSide1Elems, aSide2Elems;
5600 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
5601 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
5603 TPythonDump() << "error = " << this << ".SewSideElements( "
5604 << IDsOfSide1Elements << ", "
5605 << IDsOfSide2Elements << ", "
5606 << NodeID1OfSide1ToMerge << ", "
5607 << NodeID1OfSide2ToMerge << ", "
5608 << NodeID2OfSide1ToMerge << ", "
5609 << NodeID2OfSide2ToMerge << ")";
5611 SMESH::SMESH_MeshEditor::Sew_Error error =
5612 convError( getEditor().SewSideElements (aSide1Elems, aSide2Elems,
5615 aSecondNode1ToMerge,
5616 aSecondNode2ToMerge));
5618 declareMeshModified( /*isReComputeSafe=*/false );
5621 SMESH_CATCH( SMESH::throwCorbaException );
5622 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5625 //================================================================================
5627 * \brief Set new nodes for given element
5628 * \param ide - element id
5629 * \param newIDs - new node ids
5630 * \retval CORBA::Boolean - true if result is OK
5632 //================================================================================
5634 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
5635 const SMESH::long_array& newIDs)
5636 throw (SALOME::SALOME_Exception)
5641 const SMDS_MeshElement* elem = getMeshDS()->FindElement(ide);
5642 if(!elem) return false;
5644 int nbn = newIDs.length();
5646 vector<const SMDS_MeshNode*> aNodes(nbn);
5649 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(newIDs[i]);
5652 aNodes[nbn1] = aNode;
5655 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
5656 << ide << ", " << newIDs << " )";
5658 MESSAGE("ChangeElementNodes");
5659 bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
5661 declareMeshModified( /*isReComputeSafe=*/ !res );
5665 SMESH_CATCH( SMESH::throwCorbaException );
5669 //=======================================================================
5671 * \brief Makes a part of the mesh quadratic or bi-quadratic
5673 //=======================================================================
5675 void SMESH_MeshEditor_i::convertToQuadratic(CORBA::Boolean theForce3d,
5676 CORBA::Boolean theToBiQuad,
5677 SMESH::SMESH_IDSource_ptr theObject)
5678 throw (SALOME::SALOME_Exception)
5681 TIDSortedElemSet elems;
5683 if ( !( elemsOK = CORBA::is_nil( theObject )))
5685 prepareIdSource( theObject );
5686 elemsOK = idSourceToSet( theObject, getMeshDS(), elems,
5687 SMDSAbs_All, /*emptyIfIsMesh=*/true );
5691 if ( !elems.empty() && (*elems.begin())->GetType() == SMDSAbs_Node )
5692 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5694 if ( elems.empty() ) getEditor().ConvertToQuadratic(theForce3d, theToBiQuad);
5695 else getEditor().ConvertToQuadratic(theForce3d, elems, theToBiQuad);
5697 declareMeshModified( /*isReComputeSafe=*/false );
5700 SMESH_CATCH( SMESH::throwCorbaException );
5703 //=======================================================================
5704 //function : ConvertFromQuadratic
5706 //=======================================================================
5708 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
5709 throw (SALOME::SALOME_Exception)
5711 CORBA::Boolean isDone = getEditor().ConvertFromQuadratic();
5712 TPythonDump() << this << ".ConvertFromQuadratic()";
5713 declareMeshModified( /*isReComputeSafe=*/!isDone );
5717 //=======================================================================
5718 //function : ConvertToQuadratic
5720 //=======================================================================
5722 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
5723 throw (SALOME::SALOME_Exception)
5725 convertToQuadratic( theForce3d, false );
5726 TPythonDump() << this << ".ConvertToQuadratic("<<theForce3d<<")";
5729 //================================================================================
5731 * \brief Makes a part of the mesh quadratic
5733 //================================================================================
5735 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
5736 SMESH::SMESH_IDSource_ptr theObject)
5737 throw (SALOME::SALOME_Exception)
5739 convertToQuadratic( theForce3d, false, theObject );
5740 TPythonDump() << this << ".ConvertToQuadraticObject("<<theForce3d<<", "<<theObject<<")";
5743 //================================================================================
5745 * \brief Makes a part of the mesh bi-quadratic
5747 //================================================================================
5749 void SMESH_MeshEditor_i::ConvertToBiQuadratic(CORBA::Boolean theForce3d,
5750 SMESH::SMESH_IDSource_ptr theObject)
5751 throw (SALOME::SALOME_Exception)
5753 convertToQuadratic( theForce3d, true, theObject );
5754 TPythonDump() << this << ".ConvertToBiQuadratic("<<theForce3d<<", "<<theObject<<")";
5757 //================================================================================
5759 * \brief Makes a part of the mesh linear
5761 //================================================================================
5763 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
5764 throw (SALOME::SALOME_Exception)
5770 TIDSortedElemSet elems;
5771 prepareIdSource( theObject );
5772 if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5774 if ( elems.empty() )
5776 ConvertFromQuadratic();
5778 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5780 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5784 getEditor().ConvertFromQuadratic(elems);
5787 declareMeshModified( /*isReComputeSafe=*/false );
5789 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
5791 SMESH_CATCH( SMESH::throwCorbaException );
5794 //=======================================================================
5795 //function : makeMesh
5796 //purpose : create a named imported mesh
5797 //=======================================================================
5799 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
5801 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
5802 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
5803 SALOMEDS::Study_var study = gen->GetCurrentStudy();
5804 SALOMEDS::SObject_wrap meshSO = gen->ObjectToSObject( study, mesh );
5805 gen->SetName( meshSO, theMeshName, "Mesh" );
5806 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
5808 return mesh._retn();
5811 //=======================================================================
5812 //function : dumpGroupsList
5814 //=======================================================================
5816 void SMESH_MeshEditor_i::dumpGroupsList(TPythonDump & theDumpPython,
5817 const SMESH::ListOfGroups * theGroupList)
5819 bool isDumpGroupList = ( theGroupList && theGroupList->length() > 0 );
5820 if ( isDumpGroupList )
5821 theDumpPython << theGroupList << " = ";
5824 //================================================================================
5826 \brief Generates the unique group name.
5827 \param thePrefix name prefix
5830 //================================================================================
5832 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
5834 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5835 set<string> groupNames;
5837 // Get existing group names
5838 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
5839 SMESH::SMESH_GroupBase_var aGroup = groups[i];
5840 if (CORBA::is_nil(aGroup))
5843 CORBA::String_var name = aGroup->GetName();
5844 groupNames.insert( name.in() );
5848 string name = thePrefix;
5851 while (!groupNames.insert(name).second)
5852 name = SMESH_Comment( thePrefix ) << "_" << index++;
5857 //================================================================================
5859 * \brief Prepare SMESH_IDSource for work
5861 //================================================================================
5863 void SMESH_MeshEditor_i::prepareIdSource(SMESH::SMESH_IDSource_ptr theObject)
5865 if ( SMESH::Filter_i* filter = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5867 SMESH::SMESH_Mesh_var mesh = myMesh_i->_this();
5868 filter->SetMesh( mesh );
5872 //================================================================================
5874 * \brief Duplicates given elements, i.e. creates new elements based on the
5875 * same nodes as the given ones.
5876 * \param theElements - container of elements to duplicate.
5877 * \param theGroupName - a name of group to contain the generated elements.
5878 * If a group with such a name already exists, the new elements
5879 * are added to the existng group, else a new group is created.
5880 * If \a theGroupName is empty, new elements are not added
5882 * \return a group where the new elements are added. NULL if theGroupName == "".
5885 //================================================================================
5887 SMESH::SMESH_Group_ptr
5888 SMESH_MeshEditor_i::DoubleElements(SMESH::SMESH_IDSource_ptr theElements,
5889 const char* theGroupName)
5890 throw (SALOME::SALOME_Exception)
5892 SMESH::SMESH_Group_var newGroup;
5899 TIDSortedElemSet elems;
5900 prepareIdSource( theElements );
5901 if ( idSourceToSet( theElements, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true))
5903 getEditor().DoubleElements( elems );
5905 if ( strlen( theGroupName ) && !getEditor().GetLastCreatedElems().IsEmpty() )
5908 SMESH::ElementType type =
5909 SMESH::ElementType( getEditor().GetLastCreatedElems().Value(1)->GetType() );
5910 // find existing group
5911 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5912 for ( size_t i = 0; i < groups->length(); ++i )
5913 if ( groups[i]->GetType() == type )
5915 CORBA::String_var name = groups[i]->GetName();
5916 if ( strcmp( name, theGroupName ) == 0 ) {
5917 newGroup = SMESH::SMESH_Group::_narrow( groups[i] );
5921 // create a new group
5922 if ( newGroup->_is_nil() )
5923 newGroup = myMesh_i->CreateGroup( type, theGroupName );
5925 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* >( newGroup ))
5927 SMESHDS_Group* groupDS = static_cast< SMESHDS_Group* >( group_i->GetGroupDS() );
5928 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
5929 for ( int i = 1; i <= aSeq.Length(); i++ )
5930 groupDS->SMDSGroup().Add( aSeq(i) );
5935 if ( !newGroup->_is_nil() )
5936 pyDump << newGroup << " = ";
5937 pyDump << this << ".DoubleElements( "
5938 << theElements << ", " << "'" << theGroupName <<"')";
5940 SMESH_CATCH( SMESH::throwCorbaException );
5942 return newGroup._retn();
5945 //================================================================================
5947 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5948 \param theNodes - identifiers of nodes to be doubled
5949 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
5950 nodes. If list of element identifiers is empty then nodes are doubled but
5951 they not assigned to elements
5952 \return TRUE if operation has been completed successfully, FALSE otherwise
5953 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
5955 //================================================================================
5957 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
5958 const SMESH::long_array& theModifiedElems )
5959 throw (SALOME::SALOME_Exception)
5964 list< int > aListOfNodes;
5966 for ( i = 0, n = theNodes.length(); i < n; i++ )
5967 aListOfNodes.push_back( theNodes[ i ] );
5969 list< int > aListOfElems;
5970 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5971 aListOfElems.push_back( theModifiedElems[ i ] );
5973 bool aResult = getEditor().DoubleNodes( aListOfNodes, aListOfElems );
5975 declareMeshModified( /*isReComputeSafe=*/ !aResult );
5977 // Update Python script
5978 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
5982 SMESH_CATCH( SMESH::throwCorbaException );
5986 //================================================================================
5988 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5989 This method provided for convenience works as DoubleNodes() described above.
5990 \param theNodeId - identifier of node to be doubled.
5991 \param theModifiedElems - identifiers of elements to be updated.
5992 \return TRUE if operation has been completed successfully, FALSE otherwise
5993 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
5995 //================================================================================
5997 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
5998 const SMESH::long_array& theModifiedElems )
5999 throw (SALOME::SALOME_Exception)
6002 SMESH::long_array_var aNodes = new SMESH::long_array;
6003 aNodes->length( 1 );
6004 aNodes[ 0 ] = theNodeId;
6006 TPythonDump pyDump; // suppress dump by the next line
6008 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
6010 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
6014 SMESH_CATCH( SMESH::throwCorbaException );
6018 //================================================================================
6020 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6021 This method provided for convenience works as DoubleNodes() described above.
6022 \param theNodes - group of nodes to be doubled.
6023 \param theModifiedElems - group of elements to be updated.
6024 \return TRUE if operation has been completed successfully, FALSE otherwise
6025 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
6027 //================================================================================
6029 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
6030 SMESH::SMESH_GroupBase_ptr theModifiedElems )
6031 throw (SALOME::SALOME_Exception)
6034 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
6037 SMESH::long_array_var aNodes = theNodes->GetListOfID();
6038 SMESH::long_array_var aModifiedElems;
6039 if ( !CORBA::is_nil( theModifiedElems ) )
6040 aModifiedElems = theModifiedElems->GetListOfID();
6043 aModifiedElems = new SMESH::long_array;
6044 aModifiedElems->length( 0 );
6047 TPythonDump pyDump; // suppress dump by the next line
6049 bool done = DoubleNodes( aNodes, aModifiedElems );
6051 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
6055 SMESH_CATCH( SMESH::throwCorbaException );
6059 //================================================================================
6061 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6062 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
6063 * \param theNodes - group of nodes to be doubled.
6064 * \param theModifiedElems - group of elements to be updated.
6065 * \return a new group with newly created nodes
6066 * \sa DoubleNodeGroup()
6068 //================================================================================
6070 SMESH::SMESH_Group_ptr
6071 SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
6072 SMESH::SMESH_GroupBase_ptr theModifiedElems )
6073 throw (SALOME::SALOME_Exception)
6076 SMESH::SMESH_Group_var aNewGroup;
6078 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
6079 return aNewGroup._retn();
6082 SMESH::long_array_var aNodes = theNodes->GetListOfID();
6083 SMESH::long_array_var aModifiedElems;
6084 if ( !CORBA::is_nil( theModifiedElems ) )
6085 aModifiedElems = theModifiedElems->GetListOfID();
6087 aModifiedElems = new SMESH::long_array;
6088 aModifiedElems->length( 0 );
6091 TPythonDump pyDump; // suppress dump by the next line
6093 bool aResult = DoubleNodes( aNodes, aModifiedElems );
6096 // Create group with newly created nodes
6097 SMESH::long_array_var anIds = GetLastCreatedNodes();
6098 if (anIds->length() > 0) {
6099 string anUnindexedName (theNodes->GetName());
6100 string aNewName = generateGroupName(anUnindexedName + "_double");
6101 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6102 aNewGroup->Add(anIds);
6103 pyDump << aNewGroup << " = ";
6107 pyDump << this << ".DoubleNodeGroupNew( " << theNodes << ", "
6108 << theModifiedElems << " )";
6110 return aNewGroup._retn();
6112 SMESH_CATCH( SMESH::throwCorbaException );
6116 //================================================================================
6118 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6119 This method provided for convenience works as DoubleNodes() described above.
6120 \param theNodes - list of groups of nodes to be doubled
6121 \param theModifiedElems - list of groups of elements to be updated.
6122 \return TRUE if operation has been completed successfully, FALSE otherwise
6123 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
6125 //================================================================================
6127 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
6128 const SMESH::ListOfGroups& theModifiedElems )
6129 throw (SALOME::SALOME_Exception)
6134 std::list< int > aNodes;
6136 for ( i = 0, n = theNodes.length(); i < n; i++ )
6138 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
6139 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
6141 SMESH::long_array_var aCurr = aGrp->GetListOfID();
6142 for ( j = 0, m = aCurr->length(); j < m; j++ )
6143 aNodes.push_back( aCurr[ j ] );
6147 std::list< int > anElems;
6148 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
6150 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
6151 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
6153 SMESH::long_array_var aCurr = aGrp->GetListOfID();
6154 for ( j = 0, m = aCurr->length(); j < m; j++ )
6155 anElems.push_back( aCurr[ j ] );
6159 bool aResult = getEditor().DoubleNodes( aNodes, anElems );
6161 declareMeshModified( /*isReComputeSafe=*/false );
6163 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
6167 SMESH_CATCH( SMESH::throwCorbaException );
6171 //================================================================================
6173 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6174 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
6175 * \param theNodes - group of nodes to be doubled.
6176 * \param theModifiedElems - group of elements to be updated.
6177 * \return a new group with newly created nodes
6178 * \sa DoubleNodeGroups()
6180 //================================================================================
6182 SMESH::SMESH_Group_ptr
6183 SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
6184 const SMESH::ListOfGroups& theModifiedElems )
6185 throw (SALOME::SALOME_Exception)
6187 SMESH::SMESH_Group_var aNewGroup;
6189 TPythonDump pyDump; // suppress dump by the next line
6191 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
6195 // Create group with newly created nodes
6196 SMESH::long_array_var anIds = GetLastCreatedNodes();
6197 if (anIds->length() > 0) {
6198 string anUnindexedName (theNodes[0]->GetName());
6199 string aNewName = generateGroupName(anUnindexedName + "_double");
6200 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6201 aNewGroup->Add(anIds);
6202 pyDump << aNewGroup << " = ";
6206 pyDump << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
6207 << theModifiedElems << " )";
6209 return aNewGroup._retn();
6213 //================================================================================
6215 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6216 \param theElems - the list of elements (edges or faces) to be replicated
6217 The nodes for duplication could be found from these elements
6218 \param theNodesNot - list of nodes to NOT replicate
6219 \param theAffectedElems - the list of elements (cells and edges) to which the
6220 replicated nodes should be associated to.
6221 \return TRUE if operation has been completed successfully, FALSE otherwise
6222 \sa DoubleNodeGroup(), DoubleNodeGroups()
6224 //================================================================================
6226 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
6227 const SMESH::long_array& theNodesNot,
6228 const SMESH::long_array& theAffectedElems )
6229 throw (SALOME::SALOME_Exception)
6234 SMESHDS_Mesh* aMeshDS = getMeshDS();
6235 TIDSortedElemSet anElems, aNodes, anAffected;
6236 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
6237 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
6238 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
6240 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6242 // Update Python script
6243 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
6244 << theNodesNot << ", " << theAffectedElems << " )";
6246 declareMeshModified( /*isReComputeSafe=*/false );
6249 SMESH_CATCH( SMESH::throwCorbaException );
6253 //================================================================================
6255 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6256 \param theElems - the list of elements (edges or faces) to be replicated
6257 The nodes for duplication could be found from these elements
6258 \param theNodesNot - list of nodes to NOT replicate
6259 \param theShape - shape to detect affected elements (element which geometric center
6260 located on or inside shape).
6261 The replicated nodes should be associated to affected elements.
6262 \return TRUE if operation has been completed successfully, FALSE otherwise
6263 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
6265 //================================================================================
6267 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
6268 const SMESH::long_array& theNodesNot,
6269 GEOM::GEOM_Object_ptr theShape )
6270 throw (SALOME::SALOME_Exception)
6276 SMESHDS_Mesh* aMeshDS = getMeshDS();
6277 TIDSortedElemSet anElems, aNodes;
6278 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
6279 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
6281 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6282 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6284 // Update Python script
6285 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
6286 << theNodesNot << ", " << theShape << " )";
6288 declareMeshModified( /*isReComputeSafe=*/false );
6291 SMESH_CATCH( SMESH::throwCorbaException );
6295 //================================================================================
6297 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6298 \param theElems - group of of elements (edges or faces) to be replicated
6299 \param theNodesNot - group of nodes not to replicated
6300 \param theAffectedElems - group of elements to which the replicated nodes
6301 should be associated to.
6302 \return TRUE if operation has been completed successfully, FALSE otherwise
6303 \sa DoubleNodes(), DoubleNodeGroups()
6305 //================================================================================
6308 SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
6309 SMESH::SMESH_GroupBase_ptr theNodesNot,
6310 SMESH::SMESH_GroupBase_ptr theAffectedElems)
6311 throw (SALOME::SALOME_Exception)
6314 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6320 SMESHDS_Mesh* aMeshDS = getMeshDS();
6321 TIDSortedElemSet anElems, aNodes, anAffected;
6322 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6323 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6324 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
6326 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6328 // Update Python script
6329 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
6330 << theNodesNot << ", " << theAffectedElems << " )";
6332 declareMeshModified( /*isReComputeSafe=*/false );
6335 SMESH_CATCH( SMESH::throwCorbaException );
6339 //================================================================================
6341 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6342 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
6343 * \param theElems - group of of elements (edges or faces) to be replicated
6344 * \param theNodesNot - group of nodes not to replicated
6345 * \param theAffectedElems - group of elements to which the replicated nodes
6346 * should be associated to.
6347 * \return a new group with newly created elements
6348 * \sa DoubleNodeElemGroup()
6350 //================================================================================
6352 SMESH::SMESH_Group_ptr
6353 SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
6354 SMESH::SMESH_GroupBase_ptr theNodesNot,
6355 SMESH::SMESH_GroupBase_ptr theAffectedElems)
6356 throw (SALOME::SALOME_Exception)
6359 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroup2New( theElems,
6363 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
6364 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
6366 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupNew( "
6368 << theNodesNot << ", "
6369 << theAffectedElems << " )";
6371 return elemGroup._retn();
6374 //================================================================================
6376 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6377 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
6378 * \param theElems - group of of elements (edges or faces) to be replicated
6379 * \param theNodesNot - group of nodes not to replicated
6380 * \param theAffectedElems - group of elements to which the replicated nodes
6381 * should be associated to.
6382 * \return a new group with newly created elements
6383 * \sa DoubleNodeElemGroup()
6385 //================================================================================
6387 SMESH::ListOfGroups*
6388 SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
6389 SMESH::SMESH_GroupBase_ptr theNodesNot,
6390 SMESH::SMESH_GroupBase_ptr theAffectedElems,
6391 CORBA::Boolean theElemGroupNeeded,
6392 CORBA::Boolean theNodeGroupNeeded)
6393 throw (SALOME::SALOME_Exception)
6396 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
6397 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
6398 aTwoGroups->length( 2 );
6400 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6401 return aTwoGroups._retn();
6406 SMESHDS_Mesh* aMeshDS = getMeshDS();
6407 TIDSortedElemSet anElems, aNodes, anAffected;
6408 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6409 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6410 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
6413 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6415 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6421 // Create group with newly created elements
6422 CORBA::String_var elemGroupName = theElems->GetName();
6423 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
6424 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
6426 SMESH::long_array_var anIds = GetLastCreatedElems();
6427 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
6428 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
6429 aNewElemGroup->Add(anIds);
6431 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
6433 SMESH::long_array_var anIds = GetLastCreatedNodes();
6434 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6435 aNewNodeGroup->Add(anIds);
6439 // Update Python script
6442 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
6443 else pyDump << aNewElemGroup << ", ";
6444 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
6445 else pyDump << aNewNodeGroup << " ] = ";
6447 pyDump << this << ".DoubleNodeElemGroup2New( " << theElems << ", "
6448 << theNodesNot << ", "
6449 << theAffectedElems << ", "
6450 << theElemGroupNeeded << ", "
6451 << theNodeGroupNeeded <<" )";
6453 aTwoGroups[0] = aNewElemGroup._retn();
6454 aTwoGroups[1] = aNewNodeGroup._retn();
6455 return aTwoGroups._retn();
6457 SMESH_CATCH( SMESH::throwCorbaException );
6461 //================================================================================
6463 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6464 \param theElems - group of of elements (edges or faces) to be replicated
6465 \param theNodesNot - group of nodes not to replicated
6466 \param theShape - shape to detect affected elements (element which geometric center
6467 located on or inside shape).
6468 The replicated nodes should be associated to affected elements.
6469 \return TRUE if operation has been completed successfully, FALSE otherwise
6470 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
6472 //================================================================================
6475 SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
6476 SMESH::SMESH_GroupBase_ptr theNodesNot,
6477 GEOM::GEOM_Object_ptr theShape )
6478 throw (SALOME::SALOME_Exception)
6481 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6487 SMESHDS_Mesh* aMeshDS = getMeshDS();
6488 TIDSortedElemSet anElems, aNodes, anAffected;
6489 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6490 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6492 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6493 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6496 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6498 // Update Python script
6499 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
6500 << theNodesNot << ", " << theShape << " )";
6503 SMESH_CATCH( SMESH::throwCorbaException );
6507 //================================================================================
6509 * \brief Re-load elements from a list of groups into a TIDSortedElemSet
6510 * \param [in] theGrpList - groups
6511 * \param [in] theMeshDS - mesh
6512 * \param [out] theElemSet - set of elements
6513 * \param [in] theIsNodeGrp - is \a theGrpList includes goups of nodes
6515 //================================================================================
6517 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
6518 SMESHDS_Mesh* theMeshDS,
6519 TIDSortedElemSet& theElemSet,
6520 const bool theIsNodeGrp)
6522 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
6524 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
6525 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
6526 : aGrp->GetType() != SMESH::NODE ) )
6528 SMESH::long_array_var anIDs = aGrp->GetIDs();
6529 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
6534 //================================================================================
6536 \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6537 This method provided for convenience works as DoubleNodes() described above.
6538 \param theElems - list of groups of elements (edges or faces) to be replicated
6539 \param theNodesNot - list of groups of nodes not to replicated
6540 \param theAffectedElems - group of elements to which the replicated nodes
6541 should be associated to.
6542 \return TRUE if operation has been completed successfully, FALSE otherwise
6543 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
6545 //================================================================================
6548 SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
6549 const SMESH::ListOfGroups& theNodesNot,
6550 const SMESH::ListOfGroups& theAffectedElems)
6551 throw (SALOME::SALOME_Exception)
6557 SMESHDS_Mesh* aMeshDS = getMeshDS();
6558 TIDSortedElemSet anElems, aNodes, anAffected;
6559 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6560 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6561 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6563 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6565 // Update Python script
6566 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
6567 << &theNodesNot << ", " << &theAffectedElems << " )";
6569 declareMeshModified( /*isReComputeSafe=*/false );
6572 SMESH_CATCH( SMESH::throwCorbaException );
6576 //================================================================================
6578 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6579 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6580 \param theElems - list of groups of elements (edges or faces) to be replicated
6581 \param theNodesNot - list of groups of nodes not to replicated
6582 \param theAffectedElems - group of elements to which the replicated nodes
6583 should be associated to.
6584 * \return a new group with newly created elements
6585 * \sa DoubleNodeElemGroups()
6587 //================================================================================
6589 SMESH::SMESH_Group_ptr
6590 SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
6591 const SMESH::ListOfGroups& theNodesNot,
6592 const SMESH::ListOfGroups& theAffectedElems)
6593 throw (SALOME::SALOME_Exception)
6596 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroups2New( theElems,
6600 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
6601 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
6603 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupsNew( "
6605 << theNodesNot << ", "
6606 << theAffectedElems << " )";
6608 return elemGroup._retn();
6611 //================================================================================
6613 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6614 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6615 \param theElems - list of groups of elements (edges or faces) to be replicated
6616 \param theNodesNot - list of groups of nodes not to replicated
6617 \param theAffectedElems - group of elements to which the replicated nodes
6618 should be associated to.
6619 * \return a new group with newly created elements
6620 * \sa DoubleNodeElemGroups()
6622 //================================================================================
6624 SMESH::ListOfGroups*
6625 SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems,
6626 const SMESH::ListOfGroups& theNodesNot,
6627 const SMESH::ListOfGroups& theAffectedElems,
6628 CORBA::Boolean theElemGroupNeeded,
6629 CORBA::Boolean theNodeGroupNeeded)
6630 throw (SALOME::SALOME_Exception)
6633 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
6634 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
6635 aTwoGroups->length( 2 );
6640 SMESHDS_Mesh* aMeshDS = getMeshDS();
6641 TIDSortedElemSet anElems, aNodes, anAffected;
6642 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6643 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6644 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6646 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6648 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6653 // Create group with newly created elements
6654 CORBA::String_var elemGroupName = theElems[0]->GetName();
6655 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
6656 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
6658 SMESH::long_array_var anIds = GetLastCreatedElems();
6659 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
6660 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
6661 aNewElemGroup->Add(anIds);
6663 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
6665 SMESH::long_array_var anIds = GetLastCreatedNodes();
6666 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6667 aNewNodeGroup->Add(anIds);
6671 // Update Python script
6674 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
6675 else pyDump << aNewElemGroup << ", ";
6676 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
6677 else pyDump << aNewNodeGroup << " ] = ";
6679 pyDump << this << ".DoubleNodeElemGroups2New( " << &theElems << ", "
6680 << &theNodesNot << ", "
6681 << &theAffectedElems << ", "
6682 << theElemGroupNeeded << ", "
6683 << theNodeGroupNeeded << " )";
6685 aTwoGroups[0] = aNewElemGroup._retn();
6686 aTwoGroups[1] = aNewNodeGroup._retn();
6687 return aTwoGroups._retn();
6689 SMESH_CATCH( SMESH::throwCorbaException );
6693 //================================================================================
6695 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6696 This method provided for convenience works as DoubleNodes() described above.
6697 \param theElems - list of groups of elements (edges or faces) to be replicated
6698 \param theNodesNot - list of groups of nodes not to replicated
6699 \param theShape - shape to detect affected elements (element which geometric center
6700 located on or inside shape).
6701 The replicated nodes should be associated to affected elements.
6702 \return TRUE if operation has been completed successfully, FALSE otherwise
6703 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
6705 //================================================================================
6708 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
6709 const SMESH::ListOfGroups& theNodesNot,
6710 GEOM::GEOM_Object_ptr theShape )
6711 throw (SALOME::SALOME_Exception)
6717 SMESHDS_Mesh* aMeshDS = getMeshDS();
6718 TIDSortedElemSet anElems, aNodes;
6719 listOfGroupToSet(theElems, aMeshDS, anElems,false );
6720 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6722 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6723 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6725 // Update Python script
6726 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
6727 << &theNodesNot << ", " << theShape << " )";
6729 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6732 SMESH_CATCH( SMESH::throwCorbaException );
6736 //================================================================================
6738 \brief Identify the elements that will be affected by node duplication (actual
6739 duplication is not performed.
6740 This method is the first step of DoubleNodeElemGroupsInRegion.
6741 \param theElems - list of groups of elements (edges or faces) to be replicated
6742 \param theNodesNot - list of groups of nodes not to replicated
6743 \param theShape - shape to detect affected elements (element which geometric center
6744 located on or inside shape).
6745 The replicated nodes should be associated to affected elements.
6746 \return groups of affected elements
6747 \sa DoubleNodeElemGroupsInRegion()
6749 //================================================================================
6750 SMESH::ListOfGroups*
6751 SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theElems,
6752 const SMESH::ListOfGroups& theNodesNot,
6753 GEOM::GEOM_Object_ptr theShape )
6754 throw (SALOME::SALOME_Exception)
6757 MESSAGE("AffectedElemGroupsInRegion");
6758 SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
6759 bool isEdgeGroup = false;
6760 bool isFaceGroup = false;
6761 bool isVolumeGroup = false;
6762 SMESH::SMESH_Group_var aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE, "affectedEdges");
6763 SMESH::SMESH_Group_var aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE, "affectedFaces");
6764 SMESH::SMESH_Group_var aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME, "affectedVolumes");
6768 ::SMESH_MeshEditor aMeshEditor(myMesh);
6770 SMESHDS_Mesh* aMeshDS = getMeshDS();
6771 TIDSortedElemSet anElems, aNodes;
6772 listOfGroupToSet(theElems, aMeshDS, anElems, false);
6773 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true);
6775 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape(theShape);
6776 TIDSortedElemSet anAffected;
6777 bool aResult = aMeshEditor.AffectedElemGroupsInRegion(anElems, aNodes, aShape, anAffected);
6780 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6785 int lg = anAffected.size();
6786 MESSAGE("lg="<< lg);
6787 SMESH::long_array_var volumeIds = new SMESH::long_array;
6788 volumeIds->length(lg);
6789 SMESH::long_array_var faceIds = new SMESH::long_array;
6790 faceIds->length(lg);
6791 SMESH::long_array_var edgeIds = new SMESH::long_array;
6792 edgeIds->length(lg);
6797 TIDSortedElemSet::const_iterator eIt = anAffected.begin();
6798 for (; eIt != anAffected.end(); ++eIt)
6800 const SMDS_MeshElement* anElem = *eIt;
6803 int elemId = anElem->GetID();
6804 if (myMesh->GetElementType(elemId, true) == SMDSAbs_Volume)
6805 volumeIds[ivol++] = elemId;
6806 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Face)
6807 faceIds[iface++] = elemId;
6808 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Edge)
6809 edgeIds[iedge++] = elemId;
6811 volumeIds->length(ivol);
6812 faceIds->length(iface);
6813 edgeIds->length(iedge);
6815 aNewVolumeGroup->Add(volumeIds);
6816 aNewFaceGroup->Add(faceIds);
6817 aNewEdgeGroup->Add(edgeIds);
6818 isVolumeGroup = (aNewVolumeGroup->Size() > 0);
6819 isFaceGroup = (aNewFaceGroup->Size() > 0);
6820 isEdgeGroup = (aNewEdgeGroup->Size() > 0);
6824 if (isEdgeGroup) nbGroups++;
6825 if (isFaceGroup) nbGroups++;
6826 if (isVolumeGroup) nbGroups++;
6827 aListOfGroups->length(nbGroups);
6830 if (isEdgeGroup) aListOfGroups[i++] = aNewEdgeGroup._retn();
6831 if (isFaceGroup) aListOfGroups[i++] = aNewFaceGroup._retn();
6832 if (isVolumeGroup) aListOfGroups[i++] = aNewVolumeGroup._retn();
6834 // Update Python script
6837 if (isEdgeGroup) pyDump << aNewEdgeGroup << ", ";
6838 if (isFaceGroup) pyDump << aNewFaceGroup << ", ";
6839 if (isVolumeGroup) pyDump << aNewVolumeGroup << ", ";
6841 pyDump << this << ".AffectedElemGroupsInRegion( "
6842 << &theElems << ", " << &theNodesNot << ", " << theShape << " )";
6844 return aListOfGroups._retn();
6846 SMESH_CATCH( SMESH::throwCorbaException );
6850 //================================================================================
6852 \brief Generated skin mesh (containing 2D cells) from 3D mesh
6853 The created 2D mesh elements based on nodes of free faces of boundary volumes
6854 \return TRUE if operation has been completed successfully, FALSE otherwise
6856 //================================================================================
6858 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
6859 throw (SALOME::SALOME_Exception)
6864 bool aResult = getEditor().Make2DMeshFrom3D();
6866 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
6868 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6871 SMESH_CATCH( SMESH::throwCorbaException );
6875 //================================================================================
6877 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
6878 * The list of groups must contain at least two groups. The groups have to be disjoint:
6879 * no common element into two different groups.
6880 * The nodes of the internal faces at the boundaries of the groups are doubled.
6881 * Optionally, the internal faces are replaced by flat elements.
6882 * Triangles are transformed into prisms, and quadrangles into hexahedrons.
6883 * The flat elements are stored in groups of volumes.
6884 * These groups are named according to the position of the group in the list:
6885 * 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.
6886 * 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.
6887 * All the flat elements are gathered into the group named "joints3D" (or "joints2D" in 2D situation).
6888 * The flat element of the multiple junctions between the simple junction are stored in a group named "jointsMultiples".
6889 * @param theDomains - list of groups of volumes
6890 * @param createJointElems - if TRUE, create the elements
6891 * @return TRUE if operation has been completed successfully, FALSE otherwise
6893 //================================================================================
6896 SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
6897 CORBA::Boolean createJointElems )
6898 throw (SALOME::SALOME_Exception)
6900 bool aResult = false;
6905 SMESHDS_Mesh* aMeshDS = getMeshDS();
6907 // MESSAGE("theDomains.length = "<<theDomains.length());
6908 if ( theDomains.length() <= 1 )
6909 THROW_SALOME_CORBA_EXCEPTION("At least 2 groups are required.", SALOME::BAD_PARAM);
6910 vector<TIDSortedElemSet> domains;
6913 for ( int i = 0, n = theDomains.length(); i < n; i++ )
6915 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
6916 if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
6918 // if ( aGrp->GetType() != SMESH::VOLUME )
6919 // THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
6920 TIDSortedElemSet domain;
6922 domains.push_back(domain);
6923 SMESH::long_array_var anIDs = aGrp->GetIDs();
6924 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
6928 aResult = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems );
6929 // TODO publish the groups of flat elements in study
6931 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6933 // Update Python script
6934 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
6935 << ", " << createJointElems << " )";
6937 SMESH_CATCH( SMESH::throwCorbaException );
6942 //================================================================================
6944 * \brief Double nodes on some external faces and create flat elements.
6945 * Flat elements are mainly used by some types of mechanic calculations.
6947 * Each group of the list must be constituted of faces.
6948 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
6949 * @param theGroupsOfFaces - list of groups of faces
6950 * @return TRUE if operation has been completed successfully, FALSE otherwise
6952 //================================================================================
6955 SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
6956 throw (SALOME::SALOME_Exception)
6961 SMESHDS_Mesh* aMeshDS = getMeshDS();
6963 vector<TIDSortedElemSet> faceGroups;
6966 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
6968 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
6969 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
6971 TIDSortedElemSet faceGroup;
6973 faceGroups.push_back(faceGroup);
6974 SMESH::long_array_var anIDs = aGrp->GetIDs();
6975 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
6979 bool aResult = getEditor().CreateFlatElementsOnFacesGroups( faceGroups );
6980 // TODO publish the groups of flat elements in study
6982 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6984 // Update Python script
6985 TPythonDump() << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
6988 SMESH_CATCH( SMESH::throwCorbaException );
6992 //================================================================================
6994 * \brief Identify all the elements around a geom shape, get the faces delimiting
6997 * Build groups of volume to remove, groups of faces to replace on the skin of the
6998 * object, groups of faces to remove inside the object, (idem edges).
6999 * Build ordered list of nodes at the border of each group of faces to replace
7000 * (to be used to build a geom subshape).
7002 //================================================================================
7004 void SMESH_MeshEditor_i::CreateHoleSkin(CORBA::Double radius,
7005 GEOM::GEOM_Object_ptr theShape,
7006 const char* groupName,
7007 const SMESH::double_array& theNodesCoords,
7008 SMESH::array_of_long_array_out GroupsOfNodes)
7009 throw (SALOME::SALOME_Exception)
7014 std::vector<std::vector<int> > aListOfListOfNodes;
7015 ::SMESH_MeshEditor aMeshEditor( myMesh );
7017 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
7018 if ( !theNodeSearcher )
7019 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
7021 vector<double> nodesCoords;
7022 for (int i = 0; i < theNodesCoords.length(); i++)
7024 nodesCoords.push_back( theNodesCoords[i] );
7027 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
7028 aMeshEditor.CreateHoleSkin(radius, aShape, theNodeSearcher, groupName,
7029 nodesCoords, aListOfListOfNodes);
7031 GroupsOfNodes = new SMESH::array_of_long_array;
7032 GroupsOfNodes->length( aListOfListOfNodes.size() );
7033 std::vector<std::vector<int> >::iterator llIt = aListOfListOfNodes.begin();
7034 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
7036 vector<int>& aListOfNodes = *llIt;
7037 vector<int>::iterator lIt = aListOfNodes.begin();;
7038 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
7039 aGroup.length( aListOfNodes.size() );
7040 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
7041 aGroup[ j ] = (*lIt);
7043 TPythonDump() << "lists_nodes = " << this << ".CreateHoleSkin( "
7046 << ", '" << groupName << "', "
7047 << theNodesCoords << " )";
7049 SMESH_CATCH( SMESH::throwCorbaException );
7052 // issue 20749 ===================================================================
7054 * \brief Creates missing boundary elements
7055 * \param elements - elements whose boundary is to be checked
7056 * \param dimension - defines type of boundary elements to create
7057 * \param groupName - a name of group to store created boundary elements in,
7058 * "" means not to create the group
7059 * \param meshName - a name of new mesh to store created boundary elements in,
7060 * "" means not to create the new mesh
7061 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
7062 * \param toCopyExistingBondary - if true, not only new but also pre-existing
7063 * boundary elements will be copied into the new mesh
7064 * \param group - returns the create group, if any
7065 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
7067 // ================================================================================
7069 SMESH::SMESH_Mesh_ptr
7070 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
7071 SMESH::Bnd_Dimension dim,
7072 const char* groupName,
7073 const char* meshName,
7074 CORBA::Boolean toCopyElements,
7075 CORBA::Boolean toCopyExistingBondary,
7076 SMESH::SMESH_Group_out group)
7077 throw (SALOME::SALOME_Exception)
7082 if ( dim > SMESH::BND_1DFROM2D )
7083 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
7085 SMESHDS_Mesh* aMeshDS = getMeshDS();
7087 SMESH::SMESH_Mesh_var mesh_var;
7088 SMESH::SMESH_Group_var group_var;
7092 TIDSortedElemSet elements;
7093 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
7094 prepareIdSource( idSource );
7095 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
7099 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
7100 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
7102 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
7104 // group of new boundary elements
7105 SMESH_Group* smesh_group = 0;
7106 if ( strlen(groupName) )
7108 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
7109 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
7110 smesh_group = group_i->GetSmeshGroup();
7114 getEditor().MakeBoundaryMesh( elements,
7115 ::SMESH_MeshEditor::Bnd_Dimension(dim),
7119 toCopyExistingBondary);
7122 smesh_mesh->GetMeshDS()->Modified();
7125 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
7127 // result of MakeBoundaryMesh() is a tuple (mesh, group)
7128 if ( mesh_var->_is_nil() )
7129 pyDump << myMesh_i->_this() << ", ";
7131 pyDump << mesh_var << ", ";
7132 if ( group_var->_is_nil() )
7133 pyDump << "_NoneGroup = "; // assignment to None is forbiden
7135 pyDump << group_var << " = ";
7136 pyDump << this << ".MakeBoundaryMesh( "
7138 << "SMESH." << dimName[int(dim)] << ", "
7139 << "'" << groupName << "', "
7140 << "'" << meshName<< "', "
7141 << toCopyElements << ", "
7142 << toCopyExistingBondary << ")";
7144 group = group_var._retn();
7145 return mesh_var._retn();
7147 SMESH_CATCH( SMESH::throwCorbaException );
7148 return SMESH::SMESH_Mesh::_nil();
7151 //================================================================================
7153 * \brief Creates missing boundary elements
7154 * \param dimension - defines type of boundary elements to create
7155 * \param groupName - a name of group to store all boundary elements in,
7156 * "" means not to create the group
7157 * \param meshName - a name of a new mesh, which is a copy of the initial
7158 * mesh + created boundary elements; "" means not to create the new mesh
7159 * \param toCopyAll - if true, the whole initial mesh will be copied into
7160 * the new mesh else only boundary elements will be copied into the new mesh
7161 * \param groups - optional groups of elements to make boundary around
7162 * \param mesh - returns the mesh where elements were added to
7163 * \param group - returns the created group, if any
7164 * \retval long - number of added boundary elements
7166 //================================================================================
7168 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
7169 const char* groupName,
7170 const char* meshName,
7171 CORBA::Boolean toCopyAll,
7172 const SMESH::ListOfIDSources& groups,
7173 SMESH::SMESH_Mesh_out mesh,
7174 SMESH::SMESH_Group_out group)
7175 throw (SALOME::SALOME_Exception)
7180 if ( dim > SMESH::BND_1DFROM2D )
7181 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
7183 // separate groups belonging to this and other mesh
7184 SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
7185 SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
7186 groupsOfThisMesh->length( groups.length() );
7187 groupsOfOtherMesh->length( groups.length() );
7188 int nbGroups = 0, nbGroupsOfOtherMesh = 0;
7189 for ( int i = 0; i < groups.length(); ++i )
7191 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
7192 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
7193 groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
7195 groupsOfThisMesh[ nbGroups++ ] = groups[i];
7196 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
7197 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
7199 groupsOfThisMesh->length( nbGroups );
7200 groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
7205 if ( nbGroupsOfOtherMesh > 0 )
7207 // process groups belonging to another mesh
7208 SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
7209 SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
7210 nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
7211 groupsOfOtherMesh, mesh, group );
7214 SMESH::SMESH_Mesh_var mesh_var;
7215 SMESH::SMESH_Group_var group_var;
7218 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
7219 const bool toCopyMesh = ( strlen( meshName ) > 0 );
7223 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
7225 /*toCopyGroups=*/false,
7226 /*toKeepIDs=*/true);
7228 mesh_var = makeMesh(meshName);
7230 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
7231 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
7234 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
7235 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
7237 // group of boundary elements
7238 SMESH_Group* smesh_group = 0;
7239 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
7240 if ( strlen(groupName) )
7242 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
7243 group_var = mesh_i->CreateGroup( groupType, groupName );
7244 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
7245 smesh_group = group_i->GetSmeshGroup();
7248 TIDSortedElemSet elements;
7250 if ( groups.length() > 0 )
7252 for ( int i = 0; i < nbGroups; ++i )
7255 if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
7257 SMESH::Bnd_Dimension bdim =
7258 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
7259 nbAdded += getEditor().MakeBoundaryMesh( elements,
7260 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
7263 /*toCopyElements=*/false,
7264 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
7265 /*toAddExistingBondary=*/true,
7266 /*aroundElements=*/true);
7272 nbAdded += getEditor().MakeBoundaryMesh( elements,
7273 ::SMESH_MeshEditor::Bnd_Dimension(dim),
7276 /*toCopyElements=*/false,
7277 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
7278 /*toAddExistingBondary=*/true);
7280 tgtMesh->GetMeshDS()->Modified();
7282 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
7284 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
7285 pyDump << "nbAdded, ";
7286 if ( mesh_var->_is_nil() )
7287 pyDump << myMesh_i->_this() << ", ";
7289 pyDump << mesh_var << ", ";
7290 if ( group_var->_is_nil() )
7291 pyDump << "_NoneGroup = "; // assignment to None is forbiden
7293 pyDump << group_var << " = ";
7294 pyDump << this << ".MakeBoundaryElements( "
7295 << "SMESH." << dimName[int(dim)] << ", "
7296 << "'" << groupName << "', "
7297 << "'" << meshName<< "', "
7298 << toCopyAll << ", "
7301 mesh = mesh_var._retn();
7302 group = group_var._retn();
7305 SMESH_CATCH( SMESH::throwCorbaException );