1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_MeshEditor_i.cxx
23 // Author : Nicolas REJNERI
30 // A macro used in SMESH_TryCatch.hxx,
31 // it re-raises a CORBA SALOME exception thrown by SMESH_MeshEditor_i and caught by SMESH_CATCH
32 #define SMY_OWN_CATCH \
33 catch ( SALOME::SALOME_Exception & e ) { throw e; }
35 #include "SMESH_MeshEditor_i.hxx"
37 #include "SMDS_EdgePosition.hxx"
38 #include "SMDS_ElemIterator.hxx"
39 #include "SMDS_FacePosition.hxx"
40 #include "SMDS_IteratorOnIterators.hxx"
41 #include "SMDS_LinearEdge.hxx"
42 #include "SMDS_Mesh0DElement.hxx"
43 #include "SMDS_MeshFace.hxx"
44 #include "SMDS_MeshVolume.hxx"
45 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
46 #include "SMDS_SetIterator.hxx"
47 #include "SMDS_VolumeTool.hxx"
48 #include "SMESHDS_Group.hxx"
49 #include "SMESHDS_GroupOnGeom.hxx"
50 #include "SMESH_ControlsDef.hxx"
51 #include "SMESH_Filter_i.hxx"
52 #include "SMESH_Gen_i.hxx"
53 #include "SMESH_Group.hxx"
54 #include "SMESH_Group_i.hxx"
55 #include "SMESH_MeshAlgos.hxx"
56 #include "SMESH_MeshPartDS.hxx"
57 #include "SMESH_MesherHelper.hxx"
58 #include "SMESH_PythonDump.hxx"
59 #include "SMESH_subMeshEventListener.hxx"
60 #include "SMESH_subMesh_i.hxx"
62 #include <utilities.h>
63 #include <Utils_ExceptHandlers.hxx>
64 #include <Utils_CorbaException.hxx>
65 #include <SALOMEDS_wrap.hxx>
66 #include <SALOME_GenericObj_i.hh>
68 #include <BRepAdaptor_Surface.hxx>
69 #include <BRep_Tool.hxx>
70 #include <TopExp_Explorer.hxx>
72 #include <TopoDS_Edge.hxx>
73 #include <TopoDS_Face.hxx>
78 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
82 #include <Standard_Failure.hxx>
85 #include <Standard_ErrorHandler.hxx>
91 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
93 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
96 using SMESH::TPythonDump;
99 namespace MeshEditor_I {
101 //=============================================================================
103 * \brief Mesh to apply modifications for preview purposes
105 //=============================================================================
107 struct TPreviewMesh: public SMESH_Mesh
109 SMDSAbs_ElementType myPreviewType; // type to show
111 TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
112 _isShapeToMesh = (_id =_studyId = 0);
113 _myMeshDS = new SMESHDS_Mesh( _id, true );
114 myPreviewType = previewElements;
117 virtual ~TPreviewMesh() { delete _myMeshDS; _myMeshDS = 0; }
118 //!< Copy a set of elements
119 void Copy(const TIDSortedElemSet & theElements,
120 TIDSortedElemSet& theCopyElements,
121 SMDSAbs_ElementType theSelectType = SMDSAbs_All,
122 SMDSAbs_ElementType theAvoidType = SMDSAbs_All)
124 // loop on theIDsOfElements
125 TIDSortedElemSet::const_iterator eIt = theElements.begin();
126 for ( ; eIt != theElements.end(); ++eIt )
128 const SMDS_MeshElement* anElem = *eIt;
129 if ( !anElem ) continue;
130 SMDSAbs_ElementType type = anElem->GetType();
131 if ( type == theAvoidType ||
132 ( theSelectType != SMDSAbs_All && type != theSelectType ))
134 const SMDS_MeshElement* anElemCopy;
135 if ( type == SMDSAbs_Node)
136 anElemCopy = Copy( cast2Node(anElem) );
138 anElemCopy = Copy( anElem );
140 theCopyElements.insert( theCopyElements.end(), anElemCopy );
144 SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
146 // copy element nodes
147 int anElemNbNodes = anElem->NbNodes();
148 vector< int > anElemNodesID( anElemNbNodes ) ;
149 SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
150 for ( int i = 0; itElemNodes->more(); i++)
152 const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
154 anElemNodesID[i] = anElemNode->GetID();
157 // creates a corresponding element on copied nodes
158 SMDS_MeshElement* anElemCopy = 0;
159 if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
161 const SMDS_VtkVolume* ph =
162 dynamic_cast<const SMDS_VtkVolume*> (anElem);
164 anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
165 (anElemNodesID, ph->GetQuantities(),anElem->GetID());
168 anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
175 SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
177 return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(),
178 anElemNode->GetID());
182 GetMeshDS()->ClearMesh();
184 };// struct TPreviewMesh
186 static SMESH_NodeSearcher * theNodeSearcher = 0;
187 static SMESH_ElementSearcher * theElementSearcher = 0;
189 //=============================================================================
191 * \brief Deleter of theNodeSearcher at any compute event occured
193 //=============================================================================
195 struct TSearchersDeleter : public SMESH_subMeshEventListener
198 string myMeshPartIOR;
200 TSearchersDeleter(): SMESH_subMeshEventListener( false, // won't be deleted by submesh
201 "SMESH_MeshEditor_i::TSearchersDeleter"),
203 //!< Delete theNodeSearcher
206 if ( theNodeSearcher ) delete theNodeSearcher; theNodeSearcher = 0;
207 if ( theElementSearcher ) delete theElementSearcher; theElementSearcher = 0;
209 typedef map < int, SMESH_subMesh * > TDependsOnMap;
210 //!< The meshod called by submesh: do my main job
211 void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
212 SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
214 if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
216 Unset( sm->GetFather() );
219 //!< set self on all submeshes and delete theNodeSearcher if other mesh is set
220 void Set(SMESH_Mesh* mesh, const string& meshPartIOR = string())
222 if ( myMesh != mesh || myMeshPartIOR != meshPartIOR)
229 myMeshPartIOR = meshPartIOR;
230 SMESH_subMesh* sm = mesh->GetSubMesh( mesh->GetShapeToMesh() );
231 SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true );
232 while ( smIt->more() )
235 sm->SetEventListener( this, 0, sm );
239 //!< delete self from all submeshes
240 void Unset(SMESH_Mesh* mesh)
242 if ( SMESH_subMesh* sm = mesh->GetSubMeshContaining(1) ) {
243 SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true );
244 while ( smIt->more() )
245 smIt->next()->DeleteEventListener( this );
250 } theSearchersDeleter;
252 TCollection_AsciiString mirrorTypeName( SMESH::SMESH_MeshEditor::MirrorType theMirrorType )
254 TCollection_AsciiString typeStr;
255 switch ( theMirrorType ) {
256 case SMESH::SMESH_MeshEditor::POINT:
257 typeStr = "SMESH.SMESH_MeshEditor.POINT";
259 case SMESH::SMESH_MeshEditor::AXIS:
260 typeStr = "SMESH.SMESH_MeshEditor.AXIS";
263 typeStr = "SMESH.SMESH_MeshEditor.PLANE";
267 //================================================================================
269 * \brief function for conversion of long_array to TIDSortedElemSet
270 * \param IDs - array of IDs
271 * \param aMesh - mesh
272 * \param aMap - collection to fill
273 * \param aType - element type
275 //================================================================================
277 void arrayToSet(const SMESH::long_array & IDs,
278 const SMESHDS_Mesh* aMesh,
279 TIDSortedElemSet& aMap,
280 const SMDSAbs_ElementType aType = SMDSAbs_All,
281 SMDS_MeshElement::Filter* aFilter = NULL)
283 SMDS_MeshElement::NonNullFilter filter1;
284 SMDS_MeshElement::TypeFilter filter2( aType );
286 if ( aFilter == NULL )
287 aFilter = ( aType == SMDSAbs_All ) ? (SMDS_MeshElement::Filter*) &filter1 : (SMDS_MeshElement::Filter*) &filter2;
289 SMDS_MeshElement::Filter & filter = *aFilter;
291 if ( aType == SMDSAbs_Node )
292 for (int i=0; i<IDs.length(); i++) {
293 const SMDS_MeshElement * elem = aMesh->FindNode( IDs[i] );
295 aMap.insert( aMap.end(), elem );
298 for (int i=0; i<IDs.length(); i++) {
299 const SMDS_MeshElement * elem = aMesh->FindElement( IDs[i] );
301 aMap.insert( aMap.end(), elem );
304 //================================================================================
306 * \brief Retrieve elements of given type from SMESH_IDSource
308 //================================================================================
310 bool idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource,
311 const SMESHDS_Mesh* theMeshDS,
312 TIDSortedElemSet& theElemSet,
313 const SMDSAbs_ElementType theType,
314 const bool emptyIfIsMesh=false)
317 if ( CORBA::is_nil( theIDSource ) )
319 if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
322 SMESH::long_array_var anIDs = theIDSource->GetIDs();
323 if ( anIDs->length() == 0 )
325 SMESH::array_of_ElementType_var types = theIDSource->GetTypes();
326 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
328 if ( theType == SMDSAbs_All || theType == SMDSAbs_Node )
329 arrayToSet( anIDs, theMeshDS, theElemSet, SMDSAbs_Node );
335 arrayToSet( anIDs, theMeshDS, theElemSet, theType);
336 return bool(anIDs->length()) == bool(theElemSet.size());
340 //================================================================================
342 * \brief Retrieve nodes from SMESH_IDSource
344 //================================================================================
346 void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject,
347 const SMESHDS_Mesh* theMeshDS,
348 TIDSortedNodeSet& theNodeSet)
351 if ( CORBA::is_nil( theObject ) )
353 SMESH::array_of_ElementType_var types = theObject->GetTypes();
354 SMESH::long_array_var aElementsId = theObject->GetIDs();
355 if ( types->length() == 1 && types[0] == SMESH::NODE)
357 for(int i = 0; i < aElementsId->length(); i++)
358 if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] ))
359 theNodeSet.insert( theNodeSet.end(), n);
361 else if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
363 SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator();
364 while ( nIt->more( ))
365 if( const SMDS_MeshElement * elem = nIt->next() )
366 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
370 for(int i = 0; i < aElementsId->length(); i++)
371 if( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] ))
372 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
376 //================================================================================
378 * \brief Returns elements connected to the given elements
380 //================================================================================
382 void getElementsAround(const TIDSortedElemSet& theElements,
383 const SMESHDS_Mesh* theMeshDS,
384 TIDSortedElemSet& theElementsAround)
386 if ( theElements.empty() ) return;
388 SMDSAbs_ElementType elemType = (*theElements.begin())->GetType();
389 bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() );
391 theMeshDS->GetMeshInfo().NbElements( elemType ) == theElements.size() )
392 return; // all the elements are in theElements
395 elemType = SMDSAbs_All;
397 TIDSortedElemSet visitedNodes;
398 TIDSortedElemSet::const_iterator elemIt = theElements.begin();
399 for ( ; elemIt != theElements.end(); ++elemIt )
401 const SMDS_MeshElement* e = *elemIt;
402 int i = e->NbCornerNodes();
405 const SMDS_MeshNode* n = e->GetNode( i );
406 if ( visitedNodes.insert( n ).second )
408 SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
409 while ( invIt->more() )
411 const SMDS_MeshElement* elemAround = invIt->next();
412 if ( !theElements.count( elemAround ))
413 theElementsAround.insert( elemAround );
420 //================================================================================
422 * \brief Return a string used to detect change of mesh part on which theElementSearcher
423 * is going to be used
425 //================================================================================
427 string getPartIOR( SMESH::SMESH_IDSource_ptr theMeshPart, SMESH::ElementType type)
429 string partIOR = SMESH_Gen_i::GetORB()->object_to_string( theMeshPart );
430 if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( theMeshPart ))
431 // take into account passible group modification
432 partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() );
433 partIOR += SMESH_Comment( type );
437 } // namespace MeshEditor_I
439 using namespace MeshEditor_I;
441 //=============================================================================
445 //=============================================================================
447 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview):
449 myMesh( &theMesh->GetImpl() ),
451 myIsPreviewMode ( isPreview ),
457 //================================================================================
461 //================================================================================
463 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
465 PortableServer::POA_var poa = SMESH_Gen_i::GetPOA();
466 PortableServer::ObjectId_var anObjectId = poa->servant_to_id(this);
467 poa->deactivate_object(anObjectId.in());
469 //deleteAuxIDSources();
470 delete myPreviewMesh; myPreviewMesh = 0;
471 delete myPreviewEditor; myPreviewEditor = 0;
474 //================================================================================
476 * \brief Clear members
478 //================================================================================
480 void SMESH_MeshEditor_i::initData(bool deleteSearchers)
482 if ( myIsPreviewMode ) {
483 if ( myPreviewMesh ) myPreviewMesh->RemoveAll();
486 if ( deleteSearchers )
487 TSearchersDeleter::Delete();
489 getEditor().GetError().reset();
490 getEditor().CrearLastCreated();
493 //================================================================================
495 * \brief Increment mesh modif time and optionally record that the performed
496 * modification may influence futher mesh re-compute.
497 * \param [in] isReComputeSafe - true if the modification does not infulence
498 * futher mesh re-compute
500 //================================================================================
502 void SMESH_MeshEditor_i::declareMeshModified( bool isReComputeSafe )
504 myMesh->GetMeshDS()->Modified();
505 if ( !isReComputeSafe )
506 myMesh->SetIsModified( true );
509 //================================================================================
511 * \brief Return either myEditor or myPreviewEditor depending on myIsPreviewMode.
512 * WARNING: in preview mode call getPreviewMesh() before getEditor()!
514 //================================================================================
516 ::SMESH_MeshEditor& SMESH_MeshEditor_i::getEditor()
518 if ( myIsPreviewMode && !myPreviewEditor ) {
519 if ( !myPreviewMesh ) getPreviewMesh();
520 myPreviewEditor = new ::SMESH_MeshEditor( myPreviewMesh );
522 return myIsPreviewMode ? *myPreviewEditor : myEditor;
525 //================================================================================
527 * \brief Initialize and return myPreviewMesh
528 * \param previewElements - type of elements to show in preview
530 * WARNING: call it once par a method!
532 //================================================================================
534 TPreviewMesh * SMESH_MeshEditor_i::getPreviewMesh(SMDSAbs_ElementType previewElements)
536 if ( !myPreviewMesh || myPreviewMesh->myPreviewType != previewElements )
538 delete myPreviewEditor;
540 delete myPreviewMesh;
541 myPreviewMesh = new TPreviewMesh( previewElements );
543 myPreviewMesh->Clear();
544 return myPreviewMesh;
547 //================================================================================
549 * Return data of mesh edition preview
551 //================================================================================
553 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
554 throw (SALOME::SALOME_Exception)
557 const bool hasBadElems = ( getEditor().GetError() && getEditor().GetError()->HasBadElems() );
559 if ( myIsPreviewMode || hasBadElems ) { // --- MeshPreviewStruct filling ---
561 list<int> aNodesConnectivity;
562 typedef map<int, int> TNodesMap;
565 SMESHDS_Mesh* aMeshDS;
566 std::auto_ptr< SMESH_MeshPartDS > aMeshPartDS;
568 aMeshPartDS.reset( new SMESH_MeshPartDS( getEditor().GetError()->myBadElements ));
569 aMeshDS = aMeshPartDS.get();
572 aMeshDS = getEditor().GetMeshDS();
574 myPreviewData = new SMESH::MeshPreviewStruct();
575 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
578 SMDSAbs_ElementType previewType = SMDSAbs_All;
580 if (TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( getEditor().GetMesh() )) {
581 previewType = aPreviewMesh->myPreviewType;
582 switch ( previewType ) {
583 case SMDSAbs_Edge : break;
584 case SMDSAbs_Face : break;
585 case SMDSAbs_Volume: break;
587 if ( aMeshDS->GetMeshInfo().NbElements() == 0 ) previewType = SMDSAbs_Node;
591 myPreviewData->elementTypes.length( aMeshDS->GetMeshInfo().NbElements( previewType ));
593 SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator(previewType);
595 while ( itMeshElems->more() ) {
596 const SMDS_MeshElement* aMeshElem = itMeshElems->next();
597 SMDS_NodeIteratorPtr itElemNodes = aMeshElem->nodeIterator();
598 while ( itElemNodes->more() ) {
599 const SMDS_MeshNode* aMeshNode = itElemNodes->next();
600 int aNodeID = aMeshNode->GetID();
601 TNodesMap::iterator anIter = nodesMap.find(aNodeID);
602 if ( anIter == nodesMap.end() ) {
603 // filling the nodes coordinates
604 myPreviewData->nodesXYZ[j].x = aMeshNode->X();
605 myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
606 myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
607 anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
610 aNodesConnectivity.push_back(anIter->second);
613 // filling the elements types
614 SMDSAbs_ElementType aType = aMeshElem->GetType();
615 bool isPoly = aMeshElem->IsPoly();
616 myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
617 myPreviewData->elementTypes[i].isPoly = isPoly;
618 myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
621 myPreviewData->nodesXYZ.length( j );
623 // filling the elements connectivities
624 list<int>::iterator aConnIter = aNodesConnectivity.begin();
625 myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
626 for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
627 myPreviewData->elementConnectivities[i] = *aConnIter;
629 return myPreviewData._retn();
631 SMESH_CATCH( SMESH::throwCorbaException );
635 //================================================================================
637 * \brief Returns list of it's IDs of created nodes
638 * \retval SMESH::long_array* - list of node ID
640 //================================================================================
642 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
643 throw (SALOME::SALOME_Exception)
646 SMESH::long_array_var myLastCreatedNodes = new SMESH::long_array();
648 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedNodes();
649 myLastCreatedNodes->length( aSeq.Length() );
650 for (int i = 1; i <= aSeq.Length(); i++)
651 myLastCreatedNodes[i-1] = aSeq.Value(i)->GetID();
653 return myLastCreatedNodes._retn();
654 SMESH_CATCH( SMESH::throwCorbaException );
658 //================================================================================
660 * \brief Returns list of it's IDs of created elements
661 * \retval SMESH::long_array* - list of elements' ID
663 //================================================================================
665 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
666 throw (SALOME::SALOME_Exception)
669 SMESH::long_array_var myLastCreatedElems = new SMESH::long_array();
671 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
672 myLastCreatedElems->length( aSeq.Length() );
673 for ( int i = 1; i <= aSeq.Length(); i++ )
674 myLastCreatedElems[i-1] = aSeq.Value(i)->GetID();
676 return myLastCreatedElems._retn();
677 SMESH_CATCH( SMESH::throwCorbaException );
681 //=======================================================================
682 //function : ClearLastCreated
683 //purpose : Clears sequences of last created elements and nodes
684 //=======================================================================
686 void SMESH_MeshEditor_i::ClearLastCreated() throw (SALOME::SALOME_Exception)
689 getEditor().CrearLastCreated();
690 SMESH_CATCH( SMESH::throwCorbaException );
693 //=======================================================================
695 * Returns description of an error/warning occured during the last operation
696 * WARNING: ComputeError.code >= 100 and no corresponding enum in IDL API
698 //=======================================================================
700 SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError()
701 throw (SALOME::SALOME_Exception)
704 SMESH::ComputeError_var errOut = new SMESH::ComputeError;
705 SMESH_ComputeErrorPtr& errIn = getEditor().GetError();
706 if ( errIn && !errIn->IsOK() )
708 errOut->code = -( errIn->myName < 0 ? errIn->myName + 1: errIn->myName ); // -1 -> 0
709 errOut->comment = errIn->myComment.c_str();
710 errOut->subShapeID = -1;
711 errOut->hasBadMesh = !errIn->myBadElements.empty();
716 errOut->subShapeID = -1;
717 errOut->hasBadMesh = false;
720 return errOut._retn();
721 SMESH_CATCH( SMESH::throwCorbaException );
725 //=======================================================================
726 //function : MakeIDSource
727 //purpose : Wrap a sequence of ids in a SMESH_IDSource.
728 // Call UnRegister() as you fininsh using it!!
729 //=======================================================================
731 struct SMESH_MeshEditor_i::_IDSource : public virtual POA_SMESH::SMESH_IDSource,
732 public virtual SALOME::GenericObj_i
734 SMESH::long_array _ids;
735 SMESH::ElementType _type;
736 SMESH::SMESH_Mesh_ptr _mesh;
737 SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); }
738 SMESH::long_array* GetMeshInfo() { return 0; }
739 SMESH::long_array* GetNbElementsByType()
741 SMESH::long_array_var aRes = new SMESH::long_array();
742 aRes->length(SMESH::NB_ELEMENT_TYPES);
743 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
744 aRes[ i ] = ( i == _type ) ? _ids.length() : 0;
747 SMESH::SMESH_Mesh_ptr GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _mesh ); }
748 bool IsMeshInfoCorrect() { return true; }
749 SMESH::array_of_ElementType* GetTypes()
751 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
752 if ( _ids.length() > 0 ) {
756 return types._retn();
760 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
761 SMESH::ElementType type)
763 // if ( myAuxIDSources.size() > 10 ) {
764 // delete myAuxIDSources.front();
765 // myAuxIDSources.pop_front();
768 _IDSource* idSrc = new _IDSource;
769 idSrc->_mesh = myMesh_i->_this();
772 //myAuxIDSources.push_back( idSrc );
774 SMESH::SMESH_IDSource_var anIDSourceVar = idSrc->_this();
776 return anIDSourceVar._retn();
779 bool SMESH_MeshEditor_i::IsTemporaryIDSource( SMESH::SMESH_IDSource_ptr& idSource )
781 return SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource );
784 CORBA::Long* SMESH_MeshEditor_i::GetTemporaryIDs( SMESH::SMESH_IDSource_ptr& idSource,
787 if ( _IDSource* tmpIdSource = SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource ))
789 nbIds = (int) tmpIdSource->_ids.length();
790 return & tmpIdSource->_ids[0];
796 // void SMESH_MeshEditor_i::deleteAuxIDSources()
798 // std::list< _IDSource* >::iterator idSrcIt = myAuxIDSources.begin();
799 // for ( ; idSrcIt != myAuxIDSources.end(); ++idSrcIt )
801 // myAuxIDSources.clear();
804 //=============================================================================
808 //=============================================================================
811 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
812 throw (SALOME::SALOME_Exception)
819 for (int i = 0; i < IDsOfElements.length(); i++)
820 IdList.push_back( IDsOfElements[i] );
822 // Update Python script
823 TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
826 bool ret = getEditor().Remove( IdList, false );
828 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 ); // issue 0020693
831 SMESH_CATCH( SMESH::throwCorbaException );
835 //=============================================================================
839 //=============================================================================
841 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
842 throw (SALOME::SALOME_Exception)
848 for (int i = 0; i < IDsOfNodes.length(); i++)
849 IdList.push_back( IDsOfNodes[i] );
851 // Update Python script
852 TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
854 bool ret = getEditor().Remove( IdList, true );
856 declareMeshModified( /*isReComputeSafe=*/ !ret ); // issue 0020693
859 SMESH_CATCH( SMESH::throwCorbaException );
863 //=============================================================================
867 //=============================================================================
869 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
870 throw (SALOME::SALOME_Exception)
875 // Update Python script
876 TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
878 // Create filter to find all orphan nodes
879 SMESH::Controls::Filter::TIdSequence seq;
880 SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
881 SMESH::Controls::Filter::GetElementsId( getMeshDS(), predicate, seq );
883 // remove orphan nodes (if there are any)
885 for ( int i = 0; i < seq.size(); i++ )
886 IdList.push_back( seq[i] );
888 int nbNodesBefore = myMesh->NbNodes();
889 getEditor().Remove( IdList, true );
890 int nbNodesAfter = myMesh->NbNodes();
892 declareMeshModified( /*isReComputeSafe=*/ IdList.size() == 0 ); // issue 0020693
893 return nbNodesBefore - nbNodesAfter;
895 SMESH_CATCH( SMESH::throwCorbaException );
899 //=============================================================================
903 //=============================================================================
905 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,CORBA::Double y, CORBA::Double z)
906 throw (SALOME::SALOME_Exception)
911 const SMDS_MeshNode* N = getMeshDS()->AddNode(x, y, z);
913 // Update Python script
914 TPythonDump() << "nodeID = " << this << ".AddNode( "
915 << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )";
917 declareMeshModified( /*isReComputeSafe=*/false );
920 SMESH_CATCH( SMESH::throwCorbaException );
924 //=============================================================================
926 * Create 0D element on the given node.
928 //=============================================================================
930 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
931 throw (SALOME::SALOME_Exception)
936 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
937 SMDS_MeshElement* elem = getMeshDS()->Add0DElement(aNode);
939 // Update Python script
940 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
942 declareMeshModified( /*isReComputeSafe=*/false );
944 return elem ? elem->GetID() : 0;
946 SMESH_CATCH( SMESH::throwCorbaException );
950 //=============================================================================
952 * Create a ball element on the given node.
954 //=============================================================================
956 CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diameter)
957 throw (SALOME::SALOME_Exception)
962 if ( diameter < std::numeric_limits<double>::min() )
963 THROW_SALOME_CORBA_EXCEPTION("Invalid diameter", SALOME::BAD_PARAM);
965 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
966 SMDS_MeshElement* elem = getMeshDS()->AddBall(aNode, diameter);
968 // Update Python script
969 TPythonDump() << "ballElem = "
970 << this << ".AddBall( " << IDOfNode << ", " << diameter <<" )";
972 declareMeshModified( /*isReComputeSafe=*/false );
973 return elem ? elem->GetID() : 0;
975 SMESH_CATCH( SMESH::throwCorbaException );
979 //=============================================================================
981 * Create an edge, either linear and quadratic (this is determed
982 * by number of given nodes, two or three)
984 //=============================================================================
986 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
987 throw (SALOME::SALOME_Exception)
992 int NbNodes = IDsOfNodes.length();
993 SMDS_MeshElement* elem = 0;
996 CORBA::Long index1 = IDsOfNodes[0];
997 CORBA::Long index2 = IDsOfNodes[1];
998 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(index1),
999 getMeshDS()->FindNode(index2));
1001 // Update Python script
1002 TPythonDump() << "edge = " << this << ".AddEdge([ "
1003 << index1 << ", " << index2 <<" ])";
1006 CORBA::Long n1 = IDsOfNodes[0];
1007 CORBA::Long n2 = IDsOfNodes[1];
1008 CORBA::Long n12 = IDsOfNodes[2];
1009 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(n1),
1010 getMeshDS()->FindNode(n2),
1011 getMeshDS()->FindNode(n12));
1012 // Update Python script
1013 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
1014 <<n1<<", "<<n2<<", "<<n12<<" ])";
1017 declareMeshModified( /*isReComputeSafe=*/false );
1018 return elem ? elem->GetID() : 0;
1020 SMESH_CATCH( SMESH::throwCorbaException );
1024 //=============================================================================
1028 //=============================================================================
1030 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
1031 throw (SALOME::SALOME_Exception)
1036 int NbNodes = IDsOfNodes.length();
1042 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1043 for (int i = 0; i < NbNodes; i++)
1044 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1046 SMDS_MeshElement* elem = 0;
1048 case 3: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]); break;
1049 case 4: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]); break;
1050 case 6: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1051 nodes[4], nodes[5]); break;
1052 case 7: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1053 nodes[4], nodes[5], nodes[6]); break;
1054 case 8: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1055 nodes[4], nodes[5], nodes[6], nodes[7]); break;
1056 case 9: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1057 nodes[4], nodes[5], nodes[6], nodes[7],
1059 default: elem = getMeshDS()->AddPolygonalFace(nodes);
1062 // Update Python script
1063 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
1065 declareMeshModified( /*isReComputeSafe=*/false );
1067 return elem ? elem->GetID() : 0;
1069 SMESH_CATCH( SMESH::throwCorbaException );
1073 //=============================================================================
1077 //=============================================================================
1078 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
1079 throw (SALOME::SALOME_Exception)
1084 int NbNodes = IDsOfNodes.length();
1085 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1086 for (int i = 0; i < NbNodes; i++)
1087 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1089 const SMDS_MeshElement* elem = getMeshDS()->AddPolygonalFace(nodes);
1091 // Update Python script
1092 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
1094 declareMeshModified( /*isReComputeSafe=*/false );
1095 return elem ? elem->GetID() : 0;
1097 SMESH_CATCH( SMESH::throwCorbaException );
1101 //=============================================================================
1103 * Create volume, either linear and quadratic (this is determed
1104 * by number of given nodes)
1106 //=============================================================================
1108 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
1109 throw (SALOME::SALOME_Exception)
1114 int NbNodes = IDsOfNodes.length();
1115 vector< const SMDS_MeshNode*> n(NbNodes);
1116 for(int i=0;i<NbNodes;i++)
1117 n[i]= getMeshDS()->FindNode(IDsOfNodes[i]);
1119 SMDS_MeshElement* elem = 0;
1122 case 4 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
1123 case 5 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
1124 case 6 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
1125 case 8 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
1126 case 10:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1127 n[6],n[7],n[8],n[9]);
1129 case 12:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1130 n[6],n[7],n[8],n[9],n[10],n[11]);
1132 case 13:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
1133 n[7],n[8],n[9],n[10],n[11],n[12]);
1135 case 15:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
1136 n[9],n[10],n[11],n[12],n[13],n[14]);
1138 case 20:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1139 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1140 n[15],n[16],n[17],n[18],n[19]);
1142 case 27:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1143 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1144 n[15],n[16],n[17],n[18],n[19],
1145 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
1149 // Update Python script
1150 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
1152 declareMeshModified( /*isReComputeSafe=*/false );
1153 return elem ? elem->GetID() : 0;
1155 SMESH_CATCH( SMESH::throwCorbaException );
1159 //=============================================================================
1161 * AddPolyhedralVolume
1163 //=============================================================================
1164 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
1165 const SMESH::long_array & Quantities)
1166 throw (SALOME::SALOME_Exception)
1171 int NbNodes = IDsOfNodes.length();
1172 std::vector<const SMDS_MeshNode*> n (NbNodes);
1173 for (int i = 0; i < NbNodes; i++)
1175 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDsOfNodes[i]);
1176 if (!aNode) return 0;
1180 int NbFaces = Quantities.length();
1181 std::vector<int> q (NbFaces);
1182 for (int j = 0; j < NbFaces; j++)
1183 q[j] = Quantities[j];
1185 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(n, q);
1187 // Update Python script
1188 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
1189 << IDsOfNodes << ", " << Quantities << " )";
1191 declareMeshModified( /*isReComputeSafe=*/false );
1192 return elem ? elem->GetID() : 0;
1194 SMESH_CATCH( SMESH::throwCorbaException );
1198 //=============================================================================
1200 * AddPolyhedralVolumeByFaces
1202 //=============================================================================
1204 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
1205 throw (SALOME::SALOME_Exception)
1210 int NbFaces = IdsOfFaces.length();
1211 std::vector<const SMDS_MeshNode*> poly_nodes;
1212 std::vector<int> quantities (NbFaces);
1214 for (int i = 0; i < NbFaces; i++) {
1215 const SMDS_MeshElement* aFace = getMeshDS()->FindElement(IdsOfFaces[i]);
1216 quantities[i] = aFace->NbNodes();
1218 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
1219 while (It->more()) {
1220 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
1224 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
1226 // Update Python script
1227 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
1228 << IdsOfFaces << " )";
1230 declareMeshModified( /*isReComputeSafe=*/false );
1231 return elem ? elem->GetID() : 0;
1233 SMESH_CATCH( SMESH::throwCorbaException );
1237 //=============================================================================
1239 // \brief Create 0D elements on all nodes of the given object except those
1240 // nodes on which a 0D element already exists.
1241 // \param theObject object on whose nodes 0D elements will be created.
1242 // \param theGroupName optional name of a group to add 0D elements created
1243 // and/or found on nodes of \a theObject.
1244 // \return an object (a new group or a temporary SMESH_IDSource) holding
1245 // ids of new and/or found 0D elements.
1247 //=============================================================================
1249 SMESH::SMESH_IDSource_ptr
1250 SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObject,
1251 const char* theGroupName)
1252 throw (SALOME::SALOME_Exception)
1257 SMESH::SMESH_IDSource_var result;
1260 TIDSortedElemSet elements, elems0D;
1261 prepareIdSource( theObject );
1262 if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
1263 getEditor().Create0DElementsOnAllNodes( elements, elems0D );
1265 SMESH::long_array_var newElems = new SMESH::long_array;
1266 newElems->length( elems0D.size() );
1267 TIDSortedElemSet::iterator eIt = elems0D.begin();
1268 for ( size_t i = 0; i < elems0D.size(); ++i, ++eIt )
1269 newElems[ i ] = (*eIt)->GetID();
1271 SMESH::SMESH_GroupBase_var groupToFill;
1272 if ( theGroupName && strlen( theGroupName ))
1274 // Get existing group named theGroupName
1275 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
1276 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
1277 SMESH::SMESH_GroupBase_var group = groups[i];
1278 if ( !group->_is_nil() ) {
1279 CORBA::String_var name = group->GetName();
1280 if ( strcmp( name.in(), theGroupName ) == 0 && group->GetType() == SMESH::ELEM0D ) {
1281 groupToFill = group;
1286 if ( groupToFill->_is_nil() )
1287 groupToFill = myMesh_i->CreateGroup( SMESH::ELEM0D, theGroupName );
1288 else if ( !SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1289 groupToFill = myMesh_i->ConvertToStandalone( groupToFill );
1292 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1294 group_i->Add( newElems );
1295 result = SMESH::SMESH_IDSource::_narrow( groupToFill );
1296 pyDump << groupToFill;
1300 result = MakeIDSource( newElems, SMESH::ELEM0D );
1301 pyDump << "elem0DIDs";
1304 pyDump << " = " << this << ".Create0DElementsOnAllNodes( "
1305 << theObject << ", '" << theGroupName << "' )";
1307 return result._retn();
1309 SMESH_CATCH( SMESH::throwCorbaException );
1313 //=============================================================================
1315 * \brief Bind a node to a vertex
1316 * \param NodeID - node ID
1317 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1318 * \retval boolean - false if NodeID or VertexID is invalid
1320 //=============================================================================
1322 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
1323 throw (SALOME::SALOME_Exception)
1327 SMESHDS_Mesh * mesh = getMeshDS();
1328 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1330 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1332 if ( mesh->MaxShapeIndex() < VertexID )
1333 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1335 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
1336 if ( shape.ShapeType() != TopAbs_VERTEX )
1337 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1339 mesh->SetNodeOnVertex( node, VertexID );
1341 myMesh->SetIsModified( true );
1343 SMESH_CATCH( SMESH::throwCorbaException );
1346 //=============================================================================
1348 * \brief Store node position on an edge
1349 * \param NodeID - node ID
1350 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
1351 * \param paramOnEdge - parameter on edge where the node is located
1352 * \retval boolean - false if any parameter is invalid
1354 //=============================================================================
1356 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
1357 CORBA::Double paramOnEdge)
1358 throw (SALOME::SALOME_Exception)
1362 SMESHDS_Mesh * mesh = getMeshDS();
1363 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1365 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1367 if ( mesh->MaxShapeIndex() < EdgeID )
1368 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1370 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
1371 if ( shape.ShapeType() != TopAbs_EDGE )
1372 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1375 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
1376 if ( paramOnEdge < f || paramOnEdge > l )
1377 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
1379 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
1381 myMesh->SetIsModified( true );
1383 SMESH_CATCH( SMESH::throwCorbaException );
1386 //=============================================================================
1388 * \brief Store node position on a face
1389 * \param NodeID - node ID
1390 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
1391 * \param u - U parameter on face where the node is located
1392 * \param v - V parameter on face where the node is located
1393 * \retval boolean - false if any parameter is invalid
1395 //=============================================================================
1397 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
1398 CORBA::Double u, CORBA::Double v)
1399 throw (SALOME::SALOME_Exception)
1402 SMESHDS_Mesh * mesh = getMeshDS();
1403 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1405 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1407 if ( mesh->MaxShapeIndex() < FaceID )
1408 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1410 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
1411 if ( shape.ShapeType() != TopAbs_FACE )
1412 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1414 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
1415 bool isOut = ( u < surf.FirstUParameter() ||
1416 u > surf.LastUParameter() ||
1417 v < surf.FirstVParameter() ||
1418 v > surf.LastVParameter() );
1422 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
1423 << " u( " << surf.FirstUParameter()
1424 << "," << surf.LastUParameter()
1425 << ") v( " << surf.FirstVParameter()
1426 << "," << surf.LastVParameter() << ")" );
1428 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
1431 mesh->SetNodeOnFace( node, FaceID, u, v );
1432 myMesh->SetIsModified( true );
1434 SMESH_CATCH( SMESH::throwCorbaException );
1437 //=============================================================================
1439 * \brief Bind a node to a solid
1440 * \param NodeID - node ID
1441 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1442 * \retval boolean - false if NodeID or SolidID is invalid
1444 //=============================================================================
1446 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
1447 throw (SALOME::SALOME_Exception)
1450 SMESHDS_Mesh * mesh = getMeshDS();
1451 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1453 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1455 if ( mesh->MaxShapeIndex() < SolidID )
1456 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1458 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
1459 if ( shape.ShapeType() != TopAbs_SOLID &&
1460 shape.ShapeType() != TopAbs_SHELL)
1461 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1463 mesh->SetNodeInVolume( node, SolidID );
1465 SMESH_CATCH( SMESH::throwCorbaException );
1468 //=============================================================================
1470 * \brief Bind an element to a shape
1471 * \param ElementID - element ID
1472 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
1474 //=============================================================================
1476 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
1477 CORBA::Long ShapeID)
1478 throw (SALOME::SALOME_Exception)
1481 SMESHDS_Mesh * mesh = getMeshDS();
1482 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
1484 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
1486 if ( mesh->MaxShapeIndex() < ShapeID || ShapeID < 1 )
1487 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1489 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1490 if ( shape.ShapeType() != TopAbs_EDGE &&
1491 shape.ShapeType() != TopAbs_FACE &&
1492 shape.ShapeType() != TopAbs_SOLID &&
1493 shape.ShapeType() != TopAbs_SHELL )
1494 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1496 mesh->SetMeshElementOnShape( elem, ShapeID );
1498 myMesh->SetIsModified( true );
1500 SMESH_CATCH( SMESH::throwCorbaException );
1503 //=============================================================================
1507 //=============================================================================
1509 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1510 CORBA::Long NodeID2)
1511 throw (SALOME::SALOME_Exception)
1516 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1517 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1521 // Update Python script
1522 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1523 << NodeID1 << ", " << NodeID2 << " )";
1525 int ret = getEditor().InverseDiag ( n1, n2 );
1527 declareMeshModified( /*isReComputeSafe=*/false );
1530 SMESH_CATCH( SMESH::throwCorbaException );
1534 //=============================================================================
1538 //=============================================================================
1540 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1541 CORBA::Long NodeID2)
1542 throw (SALOME::SALOME_Exception)
1547 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1548 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1552 // Update Python script
1553 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1554 << NodeID1 << ", " << NodeID2 << " )";
1557 bool stat = getEditor().DeleteDiag ( n1, n2 );
1559 declareMeshModified( /*isReComputeSafe=*/!stat );
1563 SMESH_CATCH( SMESH::throwCorbaException );
1567 //=============================================================================
1571 //=============================================================================
1573 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1574 throw (SALOME::SALOME_Exception)
1579 for (int i = 0; i < IDsOfElements.length(); i++)
1581 CORBA::Long index = IDsOfElements[i];
1582 const SMDS_MeshElement * elem = getMeshDS()->FindElement(index);
1584 getEditor().Reorient( elem );
1586 // Update Python script
1587 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1589 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 );
1592 SMESH_CATCH( SMESH::throwCorbaException );
1596 //=============================================================================
1600 //=============================================================================
1602 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1603 throw (SALOME::SALOME_Exception)
1608 TPythonDump aTPythonDump; // suppress dump in Reorient()
1610 prepareIdSource( theObject );
1612 SMESH::long_array_var anElementsId = theObject->GetIDs();
1613 CORBA::Boolean isDone = Reorient(anElementsId);
1615 // Update Python script
1616 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1618 declareMeshModified( /*isReComputeSafe=*/ anElementsId->length() == 0 );
1621 SMESH_CATCH( SMESH::throwCorbaException );
1625 //=======================================================================
1626 //function : Reorient2D
1627 //purpose : Reorient faces contained in \a the2Dgroup.
1628 // the2Dgroup - the mesh or its part to reorient
1629 // theDirection - desired direction of normal of \a theFace
1630 // theFace - ID of face whose orientation is checked.
1631 // It can be < 1 then \a thePoint is used to find a face.
1632 // thePoint - is used to find a face if \a theFace < 1.
1633 // return number of reoriented elements.
1634 //=======================================================================
1636 CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
1637 const SMESH::DirStruct& theDirection,
1638 CORBA::Long theFace,
1639 const SMESH::PointStruct& thePoint)
1640 throw (SALOME::SALOME_Exception)
1643 initData(/*deleteSearchers=*/false);
1645 TIDSortedElemSet elements;
1646 prepareIdSource( the2Dgroup );
1647 if ( !idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1))
1648 return 0;//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 //=======================================================================
1714 //function : Reorient2DBy3D
1715 //purpose : Reorient faces basing on orientation of adjacent volumes.
1716 //=======================================================================
1718 CORBA::Long SMESH_MeshEditor_i::Reorient2DBy3D(const SMESH::ListOfIDSources& faceGroups,
1719 SMESH::SMESH_IDSource_ptr volumeGroup,
1720 CORBA::Boolean outsideNormal)
1721 throw (SALOME::SALOME_Exception)
1726 TIDSortedElemSet volumes;
1727 prepareIdSource( volumeGroup );
1728 if ( !idSourceToSet( volumeGroup, getMeshDS(), volumes, SMDSAbs_Volume, /*emptyIfIsMesh=*/1))
1729 THROW_SALOME_CORBA_EXCEPTION("No volumes in a given object", SALOME::BAD_PARAM);
1732 for ( size_t i = 0; i < faceGroups.length(); ++i )
1734 SMESH::SMESH_IDSource_ptr faceGrp = faceGroups[i].in();
1735 prepareIdSource( faceGrp );
1737 TIDSortedElemSet faces;
1738 if ( !idSourceToSet( faceGrp, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/1) &&
1739 faceGroups.length() == 1 )
1740 ; //THROW_SALOME_CORBA_EXCEPTION("No faces in a given object", SALOME::BAD_PARAM);
1742 nbReori += getEditor().Reorient2DBy3D( faces, volumes, outsideNormal );
1744 if ( faces.empty() ) // all faces in the mesh treated
1749 declareMeshModified( /*isReComputeSafe=*/false );
1751 TPythonDump() << this << ".Reorient2DBy3D( "
1752 << faceGroups << ", "
1753 << volumeGroup << ", "
1754 << outsideNormal << " )";
1758 SMESH_CATCH( SMESH::throwCorbaException );
1762 //=============================================================================
1764 * \brief Fuse neighbour triangles into quadrangles.
1766 //=============================================================================
1768 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1769 SMESH::NumericalFunctor_ptr Criterion,
1770 CORBA::Double MaxAngle)
1771 throw (SALOME::SALOME_Exception)
1776 SMESHDS_Mesh* aMesh = getMeshDS();
1777 TIDSortedElemSet faces,copyFaces;
1778 SMDS_MeshElement::GeomFilter triaFilter(SMDSGeom_TRIANGLE);
1779 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face, & triaFilter);
1780 TIDSortedElemSet* workElements = & faces;
1782 if ( myIsPreviewMode ) {
1783 SMDSAbs_ElementType select = SMDSAbs_Face;
1784 getPreviewMesh( SMDSAbs_Face )->Copy( faces, copyFaces, select );
1785 workElements = & copyFaces;
1788 SMESH::NumericalFunctor_i* aNumericalFunctor =
1789 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1790 SMESH::Controls::NumericalFunctorPtr aCrit;
1791 if ( !aNumericalFunctor )
1792 aCrit.reset( new SMESH::Controls::MaxElementLength2D() );
1794 aCrit = aNumericalFunctor->GetNumericalFunctor();
1796 if ( !myIsPreviewMode ) {
1797 // Update Python script
1798 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1799 << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1802 bool stat = getEditor().TriToQuad( *workElements, aCrit, MaxAngle );
1804 declareMeshModified( /*isReComputeSafe=*/!stat );
1807 SMESH_CATCH( SMESH::throwCorbaException );
1811 //=============================================================================
1813 * \brief Fuse neighbour triangles into quadrangles.
1815 //=============================================================================
1817 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1818 SMESH::NumericalFunctor_ptr Criterion,
1819 CORBA::Double MaxAngle)
1820 throw (SALOME::SALOME_Exception)
1825 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1827 prepareIdSource( theObject );
1828 SMESH::long_array_var anElementsId = theObject->GetIDs();
1829 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1831 if ( !myIsPreviewMode ) {
1832 SMESH::NumericalFunctor_i* aNumericalFunctor =
1833 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1835 // Update Python script
1836 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1837 << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1842 SMESH_CATCH( SMESH::throwCorbaException );
1846 //=============================================================================
1848 * \brief Split quadrangles into triangles.
1850 //=============================================================================
1852 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1853 SMESH::NumericalFunctor_ptr Criterion)
1854 throw (SALOME::SALOME_Exception)
1859 SMESHDS_Mesh* aMesh = getMeshDS();
1860 TIDSortedElemSet faces;
1861 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1863 SMESH::NumericalFunctor_i* aNumericalFunctor =
1864 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1865 SMESH::Controls::NumericalFunctorPtr aCrit;
1866 if ( !aNumericalFunctor )
1867 aCrit.reset( new SMESH::Controls::AspectRatio() );
1869 aCrit = aNumericalFunctor->GetNumericalFunctor();
1872 // Update Python script
1873 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1875 CORBA::Boolean stat = getEditor().QuadToTri( faces, aCrit );
1877 declareMeshModified( /*isReComputeSafe=*/false );
1880 SMESH_CATCH( SMESH::throwCorbaException );
1884 //=============================================================================
1886 * \brief Split quadrangles into triangles.
1888 //=============================================================================
1890 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1891 SMESH::NumericalFunctor_ptr Criterion)
1892 throw (SALOME::SALOME_Exception)
1897 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1899 prepareIdSource( theObject );
1900 SMESH::long_array_var anElementsId = theObject->GetIDs();
1901 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1903 SMESH::NumericalFunctor_i* aNumericalFunctor =
1904 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1906 // Update Python script
1907 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1909 declareMeshModified( /*isReComputeSafe=*/false );
1912 SMESH_CATCH( SMESH::throwCorbaException );
1916 //================================================================================
1918 * \brief Split each of quadrangles into 4 triangles.
1919 * \param [in] theObject - theQuads Container of quadrangles to split.
1921 //================================================================================
1923 void SMESH_MeshEditor_i::QuadTo4Tri (SMESH::SMESH_IDSource_ptr theObject)
1924 throw (SALOME::SALOME_Exception)
1929 TIDSortedElemSet faces;
1930 prepareIdSource( theObject );
1931 if ( !idSourceToSet( theObject, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/true ) &&
1933 THROW_SALOME_CORBA_EXCEPTION("No faces given", SALOME::BAD_PARAM);
1935 getEditor().QuadTo4Tri( faces );
1936 TPythonDump() << this << ".QuadTo4Tri( " << theObject << " )";
1938 SMESH_CATCH( SMESH::throwCorbaException );
1941 //=============================================================================
1943 * \brief Split quadrangles into triangles.
1945 //=============================================================================
1947 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1948 CORBA::Boolean Diag13)
1949 throw (SALOME::SALOME_Exception)
1954 SMESHDS_Mesh* aMesh = getMeshDS();
1955 TIDSortedElemSet faces;
1956 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1958 // Update Python script
1959 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1960 << IDsOfElements << ", " << Diag13 << " )";
1962 CORBA::Boolean stat = getEditor().QuadToTri( faces, Diag13 );
1964 declareMeshModified( /*isReComputeSafe=*/ !stat );
1967 SMESH_CATCH( SMESH::throwCorbaException );
1971 //=============================================================================
1973 * \brief Split quadrangles into triangles.
1975 //=============================================================================
1977 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1978 CORBA::Boolean Diag13)
1979 throw (SALOME::SALOME_Exception)
1984 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
1986 prepareIdSource( theObject );
1987 SMESH::long_array_var anElementsId = theObject->GetIDs();
1988 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
1990 // Update Python script
1991 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
1992 << theObject << ", " << Diag13 << " )";
1994 declareMeshModified( /*isReComputeSafe=*/!isDone );
1997 SMESH_CATCH( SMESH::throwCorbaException );
2002 //=============================================================================
2004 * Find better splitting of the given quadrangle.
2005 * \param IDOfQuad ID of the quadrangle to be splitted.
2006 * \param Criterion A criterion to choose a diagonal for splitting.
2007 * \return 1 if 1-3 diagonal is better, 2 if 2-4
2008 * diagonal is better, 0 if error occurs.
2010 //=============================================================================
2012 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
2013 SMESH::NumericalFunctor_ptr Criterion)
2014 throw (SALOME::SALOME_Exception)
2019 const SMDS_MeshElement* quad = getMeshDS()->FindElement(IDOfQuad);
2020 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
2022 SMESH::NumericalFunctor_i* aNumericalFunctor =
2023 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
2024 SMESH::Controls::NumericalFunctorPtr aCrit;
2025 if (aNumericalFunctor)
2026 aCrit = aNumericalFunctor->GetNumericalFunctor();
2028 aCrit.reset(new SMESH::Controls::AspectRatio());
2030 int id = getEditor().BestSplit(quad, aCrit);
2031 declareMeshModified( /*isReComputeSafe=*/ id < 1 );
2035 SMESH_CATCH( SMESH::throwCorbaException );
2039 //================================================================================
2041 * \brief Split volumic elements into tetrahedrons
2043 //================================================================================
2045 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
2046 CORBA::Short methodFlags)
2047 throw (SALOME::SALOME_Exception)
2051 prepareIdSource( elems );
2053 ::SMESH_MeshEditor::TFacetOfElem elemSet;
2054 const int noneFacet = -1;
2055 SMDS_ElemIteratorPtr volIt = myMesh_i->GetElements( elems, SMESH::VOLUME );
2056 while( volIt->more() )
2057 elemSet.insert( elemSet.end(), make_pair( volIt->next(), noneFacet ));
2059 getEditor().SplitVolumes( elemSet, int( methodFlags ));
2060 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2062 TPythonDump() << this << ".SplitVolumesIntoTetra( "
2063 << elems << ", " << methodFlags << " )";
2065 SMESH_CATCH( SMESH::throwCorbaException );
2068 //================================================================================
2070 * \brief Split hexahedra into triangular prisms
2071 * \param elems - elements to split
2072 * \param facetToSplitNormal - normal used to find a facet of hexahedron
2073 * to split into triangles
2074 * \param methodFlags - flags passing splitting method:
2075 * 1 - split the hexahedron into 2 prisms
2076 * 2 - split the hexahedron into 4 prisms
2078 //================================================================================
2080 void SMESH_MeshEditor_i::SplitHexahedraIntoPrisms (SMESH::SMESH_IDSource_ptr elems,
2081 const SMESH::PointStruct & startHexPoint,
2082 const SMESH::DirStruct& facetToSplitNormal,
2083 CORBA::Short methodFlags,
2084 CORBA::Boolean allDomains)
2085 throw (SALOME::SALOME_Exception)
2089 prepareIdSource( elems );
2091 gp_Ax1 facetNorm( gp_Pnt( startHexPoint.x,
2094 gp_Dir( facetToSplitNormal.PS.x,
2095 facetToSplitNormal.PS.y,
2096 facetToSplitNormal.PS.z ));
2097 TIDSortedElemSet elemSet;
2098 SMESH::long_array_var anElementsId = elems->GetIDs();
2099 SMDS_MeshElement::GeomFilter filter( SMDSGeom_HEXA );
2100 arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume, &filter );
2102 ::SMESH_MeshEditor::TFacetOfElem elemFacets;
2103 while ( !elemSet.empty() )
2105 getEditor().GetHexaFacetsToSplit( elemSet, facetNorm, elemFacets );
2109 ::SMESH_MeshEditor::TFacetOfElem::iterator ef = elemFacets.begin();
2110 for ( ; ef != elemFacets.end(); ++ef )
2111 elemSet.erase( ef->first );
2114 if ( methodFlags == 2 )
2115 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_4_PRISMS );
2117 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_2_PRISMS );
2119 getEditor().SplitVolumes( elemFacets, int( methodFlags ));
2120 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2122 TPythonDump() << this << ".SplitHexahedraIntoPrisms( "
2124 << startHexPoint << ", "
2125 << facetToSplitNormal<< ", "
2126 << methodFlags<< ", "
2127 << allDomains << " )";
2129 SMESH_CATCH( SMESH::throwCorbaException );
2132 //=======================================================================
2135 //=======================================================================
2138 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
2139 const SMESH::long_array & IDsOfFixedNodes,
2140 CORBA::Long MaxNbOfIterations,
2141 CORBA::Double MaxAspectRatio,
2142 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2143 throw (SALOME::SALOME_Exception)
2145 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2146 MaxAspectRatio, Method, false );
2150 //=======================================================================
2151 //function : SmoothParametric
2153 //=======================================================================
2156 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
2157 const SMESH::long_array & IDsOfFixedNodes,
2158 CORBA::Long MaxNbOfIterations,
2159 CORBA::Double MaxAspectRatio,
2160 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2161 throw (SALOME::SALOME_Exception)
2163 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2164 MaxAspectRatio, Method, true );
2168 //=======================================================================
2169 //function : SmoothObject
2171 //=======================================================================
2174 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
2175 const SMESH::long_array & IDsOfFixedNodes,
2176 CORBA::Long MaxNbOfIterations,
2177 CORBA::Double MaxAspectRatio,
2178 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2179 throw (SALOME::SALOME_Exception)
2181 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2182 MaxAspectRatio, Method, false);
2186 //=======================================================================
2187 //function : SmoothParametricObject
2189 //=======================================================================
2192 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
2193 const SMESH::long_array & IDsOfFixedNodes,
2194 CORBA::Long MaxNbOfIterations,
2195 CORBA::Double MaxAspectRatio,
2196 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2197 throw (SALOME::SALOME_Exception)
2199 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2200 MaxAspectRatio, Method, true);
2204 //=============================================================================
2208 //=============================================================================
2211 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
2212 const SMESH::long_array & IDsOfFixedNodes,
2213 CORBA::Long MaxNbOfIterations,
2214 CORBA::Double MaxAspectRatio,
2215 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2217 throw (SALOME::SALOME_Exception)
2222 SMESHDS_Mesh* aMesh = getMeshDS();
2224 TIDSortedElemSet elements;
2225 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
2227 set<const SMDS_MeshNode*> fixedNodes;
2228 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
2229 CORBA::Long index = IDsOfFixedNodes[i];
2230 const SMDS_MeshNode * node = aMesh->FindNode(index);
2232 fixedNodes.insert( node );
2234 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
2235 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
2236 method = ::SMESH_MeshEditor::CENTROIDAL;
2238 getEditor().Smooth(elements, fixedNodes, method,
2239 MaxNbOfIterations, MaxAspectRatio, IsParametric );
2241 declareMeshModified( /*isReComputeSafe=*/true ); // does not prevent re-compute
2243 // Update Python script
2244 TPythonDump() << "isDone = " << this << "."
2245 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
2246 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
2247 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2248 << "SMESH.SMESH_MeshEditor."
2249 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2250 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2254 SMESH_CATCH( SMESH::throwCorbaException );
2258 //=============================================================================
2262 //=============================================================================
2265 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
2266 const SMESH::long_array & IDsOfFixedNodes,
2267 CORBA::Long MaxNbOfIterations,
2268 CORBA::Double MaxAspectRatio,
2269 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2271 throw (SALOME::SALOME_Exception)
2276 TPythonDump aTPythonDump; // suppress dump in smooth()
2278 prepareIdSource( theObject );
2279 SMESH::long_array_var anElementsId = theObject->GetIDs();
2280 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
2281 MaxAspectRatio, Method, IsParametric);
2283 // Update Python script
2284 aTPythonDump << "isDone = " << this << "."
2285 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
2286 << theObject << ", " << IDsOfFixedNodes << ", "
2287 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2288 << "SMESH.SMESH_MeshEditor."
2289 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2290 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2294 SMESH_CATCH( SMESH::throwCorbaException );
2298 //=============================================================================
2302 //=============================================================================
2304 void SMESH_MeshEditor_i::RenumberNodes()
2305 throw (SALOME::SALOME_Exception)
2308 // Update Python script
2309 TPythonDump() << this << ".RenumberNodes()";
2311 getMeshDS()->Renumber( true );
2313 SMESH_CATCH( SMESH::throwCorbaException );
2316 //=============================================================================
2320 //=============================================================================
2322 void SMESH_MeshEditor_i::RenumberElements()
2323 throw (SALOME::SALOME_Exception)
2326 // Update Python script
2327 TPythonDump() << this << ".RenumberElements()";
2329 getMeshDS()->Renumber( false );
2331 SMESH_CATCH( SMESH::throwCorbaException );
2334 //=======================================================================
2336 * \brief Return groups by their IDs
2338 //=======================================================================
2340 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
2341 throw (SALOME::SALOME_Exception)
2346 myMesh_i->CreateGroupServants();
2347 return myMesh_i->GetGroups( *groupIDs );
2349 SMESH_CATCH( SMESH::throwCorbaException );
2353 //=======================================================================
2354 //function : rotationSweep
2356 //=======================================================================
2358 SMESH::ListOfGroups*
2359 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
2360 const SMESH::AxisStruct & theAxis,
2361 CORBA::Double theAngleInRadians,
2362 CORBA::Long theNbOfSteps,
2363 CORBA::Double theTolerance,
2364 const bool theMakeGroups,
2365 const SMDSAbs_ElementType theElementType)
2366 throw (SALOME::SALOME_Exception)
2371 TIDSortedElemSet inElements, copyElements;
2372 arrayToSet(theIDsOfElements, getMeshDS(), inElements, theElementType);
2374 TIDSortedElemSet* workElements = & inElements;
2375 bool makeWalls=true;
2376 if ( myIsPreviewMode )
2378 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2379 getPreviewMesh( SMDSAbs_Face )->Copy( inElements, copyElements, select, avoid );
2380 workElements = & copyElements;
2381 //makeWalls = false;
2384 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
2385 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
2387 ::SMESH_MeshEditor::PGroupIDs groupIds =
2388 getEditor().RotationSweep (*workElements, Ax1, theAngleInRadians,
2389 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
2391 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2393 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2395 SMESH_CATCH( SMESH::throwCorbaException );
2399 //=======================================================================
2400 //function : RotationSweep
2402 //=======================================================================
2404 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
2405 const SMESH::AxisStruct & theAxis,
2406 CORBA::Double theAngleInRadians,
2407 CORBA::Long theNbOfSteps,
2408 CORBA::Double theTolerance)
2409 throw (SALOME::SALOME_Exception)
2411 if ( !myIsPreviewMode ) {
2412 TPythonDump() << this << ".RotationSweep( "
2413 << theIDsOfElements << ", "
2415 << TVar( theAngleInRadians ) << ", "
2416 << TVar( theNbOfSteps ) << ", "
2417 << TVar( theTolerance ) << " )";
2419 rotationSweep(theIDsOfElements,
2427 //=======================================================================
2428 //function : RotationSweepMakeGroups
2430 //=======================================================================
2432 SMESH::ListOfGroups*
2433 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2434 const SMESH::AxisStruct& theAxis,
2435 CORBA::Double theAngleInRadians,
2436 CORBA::Long theNbOfSteps,
2437 CORBA::Double theTolerance)
2438 throw (SALOME::SALOME_Exception)
2440 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2442 SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
2448 if (!myIsPreviewMode) {
2449 dumpGroupsList(aPythonDump, aGroups);
2450 aPythonDump << this << ".RotationSweepMakeGroups( "
2451 << theIDsOfElements << ", "
2453 << TVar( theAngleInRadians ) << ", "
2454 << TVar( theNbOfSteps ) << ", "
2455 << TVar( theTolerance ) << " )";
2460 //=======================================================================
2461 //function : RotationSweepObject
2463 //=======================================================================
2465 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2466 const SMESH::AxisStruct & theAxis,
2467 CORBA::Double theAngleInRadians,
2468 CORBA::Long theNbOfSteps,
2469 CORBA::Double theTolerance)
2470 throw (SALOME::SALOME_Exception)
2472 if ( !myIsPreviewMode ) {
2473 TPythonDump() << this << ".RotationSweepObject( "
2474 << theObject << ", "
2476 << theAngleInRadians << ", "
2477 << theNbOfSteps << ", "
2478 << theTolerance << " )";
2480 prepareIdSource( theObject );
2481 SMESH::long_array_var anElementsId = theObject->GetIDs();
2482 rotationSweep(anElementsId,
2490 //=======================================================================
2491 //function : RotationSweepObject1D
2493 //=======================================================================
2495 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2496 const SMESH::AxisStruct & theAxis,
2497 CORBA::Double theAngleInRadians,
2498 CORBA::Long theNbOfSteps,
2499 CORBA::Double theTolerance)
2500 throw (SALOME::SALOME_Exception)
2502 if ( !myIsPreviewMode ) {
2503 TPythonDump() << this << ".RotationSweepObject1D( "
2504 << theObject << ", "
2506 << TVar( theAngleInRadians ) << ", "
2507 << TVar( theNbOfSteps ) << ", "
2508 << TVar( theTolerance ) << " )";
2510 prepareIdSource( theObject );
2511 SMESH::long_array_var anElementsId = theObject->GetIDs();
2512 rotationSweep(anElementsId,
2521 //=======================================================================
2522 //function : RotationSweepObject2D
2524 //=======================================================================
2526 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2527 const SMESH::AxisStruct & theAxis,
2528 CORBA::Double theAngleInRadians,
2529 CORBA::Long theNbOfSteps,
2530 CORBA::Double theTolerance)
2531 throw (SALOME::SALOME_Exception)
2533 if ( !myIsPreviewMode ) {
2534 TPythonDump() << this << ".RotationSweepObject2D( "
2535 << theObject << ", "
2537 << TVar( theAngleInRadians ) << ", "
2538 << TVar( theNbOfSteps ) << ", "
2539 << TVar( theTolerance ) << " )";
2541 prepareIdSource( theObject );
2542 SMESH::long_array_var anElementsId = theObject->GetIDs();
2543 rotationSweep(anElementsId,
2552 //=======================================================================
2553 //function : RotationSweepObjectMakeGroups
2555 //=======================================================================
2557 SMESH::ListOfGroups*
2558 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2559 const SMESH::AxisStruct& theAxis,
2560 CORBA::Double theAngleInRadians,
2561 CORBA::Long theNbOfSteps,
2562 CORBA::Double theTolerance)
2563 throw (SALOME::SALOME_Exception)
2565 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2567 prepareIdSource( theObject );
2568 SMESH::long_array_var anElementsId = theObject->GetIDs();
2569 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2575 if (!myIsPreviewMode) {
2576 dumpGroupsList(aPythonDump, aGroups);
2577 aPythonDump << this << ".RotationSweepObjectMakeGroups( "
2578 << theObject << ", "
2580 << theAngleInRadians << ", "
2581 << theNbOfSteps << ", "
2582 << theTolerance << " )";
2587 //=======================================================================
2588 //function : RotationSweepObject1DMakeGroups
2590 //=======================================================================
2592 SMESH::ListOfGroups*
2593 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2594 const SMESH::AxisStruct& theAxis,
2595 CORBA::Double theAngleInRadians,
2596 CORBA::Long theNbOfSteps,
2597 CORBA::Double theTolerance)
2598 throw (SALOME::SALOME_Exception)
2600 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2602 prepareIdSource( theObject );
2603 SMESH::long_array_var anElementsId = theObject->GetIDs();
2604 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2611 if (!myIsPreviewMode) {
2612 dumpGroupsList(aPythonDump, aGroups);
2613 aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
2614 << theObject << ", "
2616 << TVar( theAngleInRadians ) << ", "
2617 << TVar( theNbOfSteps ) << ", "
2618 << TVar( theTolerance ) << " )";
2623 //=======================================================================
2624 //function : RotationSweepObject2DMakeGroups
2626 //=======================================================================
2628 SMESH::ListOfGroups*
2629 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2630 const SMESH::AxisStruct& theAxis,
2631 CORBA::Double theAngleInRadians,
2632 CORBA::Long theNbOfSteps,
2633 CORBA::Double theTolerance)
2634 throw (SALOME::SALOME_Exception)
2636 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2638 prepareIdSource( theObject );
2639 SMESH::long_array_var anElementsId = theObject->GetIDs();
2640 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2647 if (!myIsPreviewMode) {
2648 dumpGroupsList(aPythonDump, aGroups);
2649 aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
2650 << theObject << ", "
2652 << TVar( theAngleInRadians ) << ", "
2653 << TVar( theNbOfSteps ) << ", "
2654 << TVar( theTolerance ) << " )";
2660 //=======================================================================
2661 //function : extrusionSweep
2663 //=======================================================================
2665 SMESH::ListOfGroups*
2666 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
2667 const SMESH::DirStruct & theStepVector,
2668 CORBA::Long theNbOfSteps,
2670 const SMDSAbs_ElementType theElementType)
2671 throw (SALOME::SALOME_Exception)
2676 TIDSortedElemSet elements, copyElements;
2677 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
2679 const SMESH::PointStruct * P = &theStepVector.PS;
2680 gp_Vec stepVec( P->x, P->y, P->z );
2682 TIDSortedElemSet* workElements = & elements;
2684 SMDSAbs_ElementType aType = SMDSAbs_Face;
2685 if (theElementType == SMDSAbs_Node)
2687 aType = SMDSAbs_Edge;
2689 if ( myIsPreviewMode ) {
2690 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2691 getPreviewMesh( aType )->Copy( elements, copyElements, select, avoid );
2692 workElements = & copyElements;
2693 theMakeGroups = false;
2696 ::SMESH_MeshEditor::TTElemOfElemListMap aHystory;
2697 ::SMESH_MeshEditor::PGroupIDs groupIds =
2698 getEditor().ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
2700 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2702 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2704 SMESH_CATCH( SMESH::throwCorbaException );
2708 //=======================================================================
2709 //function : ExtrusionSweep
2711 //=======================================================================
2713 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
2714 const SMESH::DirStruct & theStepVector,
2715 CORBA::Long theNbOfSteps)
2716 throw (SALOME::SALOME_Exception)
2718 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
2719 if (!myIsPreviewMode) {
2720 TPythonDump() << this << ".ExtrusionSweep( "
2721 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps) << " )";
2725 //=======================================================================
2726 //function : ExtrusionSweep0D
2728 //=======================================================================
2730 void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElements,
2731 const SMESH::DirStruct & theStepVector,
2732 CORBA::Long theNbOfSteps)
2733 throw (SALOME::SALOME_Exception)
2735 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2736 if (!myIsPreviewMode) {
2737 TPythonDump() << this << ".ExtrusionSweep0D( "
2738 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps)<< " )";
2742 //=======================================================================
2743 //function : ExtrusionSweepObject
2745 //=======================================================================
2747 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2748 const SMESH::DirStruct & theStepVector,
2749 CORBA::Long theNbOfSteps)
2750 throw (SALOME::SALOME_Exception)
2752 prepareIdSource( theObject );
2753 SMESH::long_array_var anElementsId = theObject->GetIDs();
2754 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
2755 if (!myIsPreviewMode) {
2756 TPythonDump() << this << ".ExtrusionSweepObject( "
2757 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
2761 //=======================================================================
2762 //function : ExtrusionSweepObject0D
2764 //=======================================================================
2766 void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObject,
2767 const SMESH::DirStruct & theStepVector,
2768 CORBA::Long theNbOfSteps)
2769 throw (SALOME::SALOME_Exception)
2771 prepareIdSource( theObject );
2772 SMESH::long_array_var anElementsId = theObject->GetIDs();
2773 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2774 if ( !myIsPreviewMode ) {
2775 TPythonDump() << this << ".ExtrusionSweepObject0D( "
2776 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2780 //=======================================================================
2781 //function : ExtrusionSweepObject1D
2783 //=======================================================================
2785 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2786 const SMESH::DirStruct & theStepVector,
2787 CORBA::Long theNbOfSteps)
2788 throw (SALOME::SALOME_Exception)
2790 prepareIdSource( theObject );
2791 SMESH::long_array_var anElementsId = theObject->GetIDs();
2792 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
2793 if ( !myIsPreviewMode ) {
2794 TPythonDump() << this << ".ExtrusionSweepObject1D( "
2795 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2799 //=======================================================================
2800 //function : ExtrusionSweepObject2D
2802 //=======================================================================
2804 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2805 const SMESH::DirStruct & theStepVector,
2806 CORBA::Long theNbOfSteps)
2807 throw (SALOME::SALOME_Exception)
2809 prepareIdSource( theObject );
2810 SMESH::long_array_var anElementsId = theObject->GetIDs();
2811 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
2812 if ( !myIsPreviewMode ) {
2813 TPythonDump() << this << ".ExtrusionSweepObject2D( "
2814 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2818 //=======================================================================
2819 //function : ExtrusionSweepMakeGroups
2821 //=======================================================================
2823 SMESH::ListOfGroups*
2824 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2825 const SMESH::DirStruct& theStepVector,
2826 CORBA::Long theNbOfSteps)
2827 throw (SALOME::SALOME_Exception)
2829 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2831 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
2833 if (!myIsPreviewMode) {
2834 dumpGroupsList(aPythonDump, aGroups);
2835 aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
2836 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2841 //=======================================================================
2842 //function : ExtrusionSweepMakeGroups0D
2844 //=======================================================================
2846 SMESH::ListOfGroups*
2847 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups0D(const SMESH::long_array& theIDsOfElements,
2848 const SMESH::DirStruct& theStepVector,
2849 CORBA::Long theNbOfSteps)
2850 throw (SALOME::SALOME_Exception)
2852 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2854 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true,SMDSAbs_Node);
2856 if (!myIsPreviewMode) {
2857 dumpGroupsList(aPythonDump, aGroups);
2858 aPythonDump << this << ".ExtrusionSweepMakeGroups0D( " << theIDsOfElements
2859 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2864 //=======================================================================
2865 //function : ExtrusionSweepObjectMakeGroups
2867 //=======================================================================
2869 SMESH::ListOfGroups*
2870 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2871 const SMESH::DirStruct& theStepVector,
2872 CORBA::Long theNbOfSteps)
2873 throw (SALOME::SALOME_Exception)
2875 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2877 prepareIdSource( theObject );
2878 SMESH::long_array_var anElementsId = theObject->GetIDs();
2879 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
2881 if (!myIsPreviewMode) {
2882 dumpGroupsList(aPythonDump, aGroups);
2883 aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
2884 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2889 //=======================================================================
2890 //function : ExtrusionSweepObject0DMakeGroups
2892 //=======================================================================
2894 SMESH::ListOfGroups*
2895 SMESH_MeshEditor_i::ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2896 const SMESH::DirStruct& theStepVector,
2897 CORBA::Long theNbOfSteps)
2898 throw (SALOME::SALOME_Exception)
2900 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2902 prepareIdSource( theObject );
2903 SMESH::long_array_var anElementsId = theObject->GetIDs();
2904 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2905 theNbOfSteps, true, SMDSAbs_Node);
2906 if (!myIsPreviewMode) {
2907 dumpGroupsList(aPythonDump, aGroups);
2908 aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject
2909 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2914 //=======================================================================
2915 //function : ExtrusionSweepObject1DMakeGroups
2917 //=======================================================================
2919 SMESH::ListOfGroups*
2920 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2921 const SMESH::DirStruct& theStepVector,
2922 CORBA::Long theNbOfSteps)
2923 throw (SALOME::SALOME_Exception)
2925 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2927 prepareIdSource( theObject );
2928 SMESH::long_array_var anElementsId = theObject->GetIDs();
2929 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2930 theNbOfSteps, true, SMDSAbs_Edge);
2931 if (!myIsPreviewMode) {
2932 dumpGroupsList(aPythonDump, aGroups);
2933 aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
2934 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2939 //=======================================================================
2940 //function : ExtrusionSweepObject2DMakeGroups
2942 //=======================================================================
2944 SMESH::ListOfGroups*
2945 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2946 const SMESH::DirStruct& theStepVector,
2947 CORBA::Long theNbOfSteps)
2948 throw (SALOME::SALOME_Exception)
2950 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2952 prepareIdSource( theObject );
2953 SMESH::long_array_var anElementsId = theObject->GetIDs();
2954 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2955 theNbOfSteps, true, SMDSAbs_Face);
2956 if (!myIsPreviewMode) {
2957 dumpGroupsList(aPythonDump, aGroups);
2958 aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
2959 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2965 //=======================================================================
2966 //function : advancedExtrusion
2968 //=======================================================================
2970 SMESH::ListOfGroups*
2971 SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
2972 const SMESH::DirStruct & theStepVector,
2973 CORBA::Long theNbOfSteps,
2974 CORBA::Long theExtrFlags,
2975 CORBA::Double theSewTolerance,
2976 const bool theMakeGroups)
2977 throw (SALOME::SALOME_Exception)
2982 TIDSortedElemSet elements;
2983 arrayToSet(theIDsOfElements, getMeshDS(), elements);
2985 const SMESH::PointStruct * P = &theStepVector.PS;
2986 gp_Vec stepVec( P->x, P->y, P->z );
2988 ::SMESH_MeshEditor::TTElemOfElemListMap aHystory;
2989 ::SMESH_MeshEditor::PGroupIDs groupIds =
2990 getEditor().ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
2991 theMakeGroups, theExtrFlags, theSewTolerance);
2993 declareMeshModified( /*isReComputeSafe=*/true );
2995 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2997 SMESH_CATCH( SMESH::throwCorbaException );
3001 //=======================================================================
3002 //function : AdvancedExtrusion
3004 //=======================================================================
3006 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
3007 const SMESH::DirStruct & theStepVector,
3008 CORBA::Long theNbOfSteps,
3009 CORBA::Long theExtrFlags,
3010 CORBA::Double theSewTolerance)
3011 throw (SALOME::SALOME_Exception)
3013 if ( !myIsPreviewMode ) {
3014 TPythonDump() << "stepVector = " << theStepVector;
3015 TPythonDump() << this << ".AdvancedExtrusion("
3018 << theNbOfSteps << ","
3019 << theExtrFlags << ", "
3020 << theSewTolerance << " )";
3022 advancedExtrusion( theIDsOfElements,
3030 //=======================================================================
3031 //function : AdvancedExtrusionMakeGroups
3033 //=======================================================================
3034 SMESH::ListOfGroups*
3035 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
3036 const SMESH::DirStruct& theStepVector,
3037 CORBA::Long theNbOfSteps,
3038 CORBA::Long theExtrFlags,
3039 CORBA::Double theSewTolerance)
3040 throw (SALOME::SALOME_Exception)
3042 if (!myIsPreviewMode) {
3043 TPythonDump() << "stepVector = " << theStepVector;
3045 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3047 SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
3054 if (!myIsPreviewMode) {
3055 dumpGroupsList(aPythonDump, aGroups);
3056 aPythonDump << this << ".AdvancedExtrusionMakeGroups("
3059 << theNbOfSteps << ","
3060 << theExtrFlags << ", "
3061 << theSewTolerance << " )";
3067 //================================================================================
3069 * \brief Convert extrusion error to IDL enum
3071 //================================================================================
3073 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
3075 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
3079 RETCASE( EXTR_NO_ELEMENTS );
3080 RETCASE( EXTR_PATH_NOT_EDGE );
3081 RETCASE( EXTR_BAD_PATH_SHAPE );
3082 RETCASE( EXTR_BAD_STARTING_NODE );
3083 RETCASE( EXTR_BAD_ANGLES_NUMBER );
3084 RETCASE( EXTR_CANT_GET_TANGENT );
3086 return SMESH::SMESH_MeshEditor::EXTR_OK;
3090 //=======================================================================
3091 //function : extrusionAlongPath
3093 //=======================================================================
3094 SMESH::ListOfGroups*
3095 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfElements,
3096 SMESH::SMESH_Mesh_ptr thePathMesh,
3097 GEOM::GEOM_Object_ptr thePathShape,
3098 CORBA::Long theNodeStart,
3099 CORBA::Boolean theHasAngles,
3100 const SMESH::double_array & theAngles,
3101 CORBA::Boolean theHasRefPoint,
3102 const SMESH::PointStruct & theRefPoint,
3103 const bool theMakeGroups,
3104 SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
3105 const SMDSAbs_ElementType theElementType)
3106 throw (SALOME::SALOME_Exception)
3109 MESSAGE("extrusionAlongPath");
3112 if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
3113 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3116 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3118 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3119 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3121 if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
3122 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3126 SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
3128 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3132 TIDSortedElemSet elements;
3133 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
3135 list<double> angles;
3136 for (int i = 0; i < theAngles.length(); i++) {
3137 angles.push_back( theAngles[i] );
3140 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
3142 int nbOldGroups = myMesh->NbGroup();
3144 ::SMESH_MeshEditor::Extrusion_Error error =
3145 getEditor().ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
3146 theHasAngles, angles, false,
3147 theHasRefPoint, refPnt, theMakeGroups );
3149 declareMeshModified( /*isReComputeSafe=*/true );
3150 theError = convExtrError( error );
3152 if ( theMakeGroups ) {
3153 list<int> groupIDs = myMesh->GetGroupIds();
3154 list<int>::iterator newBegin = groupIDs.begin();
3155 std::advance( newBegin, nbOldGroups ); // skip old groups
3156 groupIDs.erase( groupIDs.begin(), newBegin );
3157 return getGroups( & groupIDs );
3161 SMESH_CATCH( SMESH::throwCorbaException );
3165 //=======================================================================
3166 //function : extrusionAlongPathX
3168 //=======================================================================
3170 SMESH::ListOfGroups*
3171 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements,
3172 SMESH::SMESH_IDSource_ptr Path,
3173 CORBA::Long NodeStart,
3174 CORBA::Boolean HasAngles,
3175 const SMESH::double_array& Angles,
3176 CORBA::Boolean LinearVariation,
3177 CORBA::Boolean HasRefPoint,
3178 const SMESH::PointStruct& RefPoint,
3180 const SMDSAbs_ElementType ElementType,
3181 SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
3182 throw (SALOME::SALOME_Exception)
3185 SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
3189 list<double> angles;
3190 for (int i = 0; i < Angles.length(); i++) {
3191 angles.push_back( Angles[i] );
3193 gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
3194 int nbOldGroups = myMesh->NbGroup();
3196 if ( Path->_is_nil() ) {
3197 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3201 TIDSortedElemSet elements, copyElements;
3202 arrayToSet(IDsOfElements, getMeshDS(), elements, ElementType);
3204 TIDSortedElemSet* workElements = &elements;
3206 if ( myIsPreviewMode )
3208 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
3209 getPreviewMesh( SMDSAbs_Face )->Copy( elements, copyElements, select, avoid );
3210 workElements = & copyElements;
3214 ::SMESH_MeshEditor::Extrusion_Error error;
3216 if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path ))
3219 SMDS_MeshNode* aNodeStart =
3220 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
3221 if ( !aNodeStart ) {
3222 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3225 error = getEditor().ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
3226 HasAngles, angles, LinearVariation,
3227 HasRefPoint, refPnt, MakeGroups );
3228 declareMeshModified( /*isReComputeSafe=*/true );
3230 else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
3233 SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
3234 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
3235 SMDS_MeshNode* aNodeStart =
3236 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
3237 if ( !aNodeStart ) {
3238 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3241 SMESH_subMesh* aSubMesh =
3242 aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
3243 error = getEditor().ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
3244 HasAngles, angles, LinearVariation,
3245 HasRefPoint, refPnt, MakeGroups );
3246 declareMeshModified( /*isReComputeSafe=*/true );
3248 else if ( SMESH::DownCast<SMESH_Group_i*>( Path ))
3250 // path as group of 1D elements
3256 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3260 Error = convExtrError( error );
3263 list<int> groupIDs = myMesh->GetGroupIds();
3264 list<int>::iterator newBegin = groupIDs.begin();
3265 std::advance( newBegin, nbOldGroups ); // skip old groups
3266 groupIDs.erase( groupIDs.begin(), newBegin );
3267 return getGroups( & groupIDs );
3271 SMESH_CATCH( SMESH::throwCorbaException );
3275 //=======================================================================
3276 //function : ExtrusionAlongPath
3278 //=======================================================================
3280 SMESH::SMESH_MeshEditor::Extrusion_Error
3281 SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements,
3282 SMESH::SMESH_Mesh_ptr thePathMesh,
3283 GEOM::GEOM_Object_ptr thePathShape,
3284 CORBA::Long theNodeStart,
3285 CORBA::Boolean theHasAngles,
3286 const SMESH::double_array & theAngles,
3287 CORBA::Boolean theHasRefPoint,
3288 const SMESH::PointStruct & theRefPoint)
3289 throw (SALOME::SALOME_Exception)
3291 MESSAGE("ExtrusionAlongPath");
3292 if ( !myIsPreviewMode ) {
3293 TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
3294 << theIDsOfElements << ", "
3295 << thePathMesh << ", "
3296 << thePathShape << ", "
3297 << theNodeStart << ", "
3298 << theHasAngles << ", "
3299 << theAngles << ", "
3300 << theHasRefPoint << ", "
3301 << "SMESH.PointStruct( "
3302 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3303 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3304 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3306 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3307 extrusionAlongPath( theIDsOfElements,
3320 //=======================================================================
3321 //function : ExtrusionAlongPathObject
3323 //=======================================================================
3325 SMESH::SMESH_MeshEditor::Extrusion_Error
3326 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject,
3327 SMESH::SMESH_Mesh_ptr thePathMesh,
3328 GEOM::GEOM_Object_ptr thePathShape,
3329 CORBA::Long theNodeStart,
3330 CORBA::Boolean theHasAngles,
3331 const SMESH::double_array & theAngles,
3332 CORBA::Boolean theHasRefPoint,
3333 const SMESH::PointStruct & theRefPoint)
3334 throw (SALOME::SALOME_Exception)
3336 if ( !myIsPreviewMode ) {
3337 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
3338 << theObject << ", "
3339 << thePathMesh << ", "
3340 << thePathShape << ", "
3341 << theNodeStart << ", "
3342 << theHasAngles << ", "
3343 << theAngles << ", "
3344 << theHasRefPoint << ", "
3345 << "SMESH.PointStruct( "
3346 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3347 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3348 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3350 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3351 prepareIdSource( theObject );
3352 SMESH::long_array_var anElementsId = theObject->GetIDs();
3353 extrusionAlongPath( anElementsId,
3366 //=======================================================================
3367 //function : ExtrusionAlongPathObject1D
3369 //=======================================================================
3371 SMESH::SMESH_MeshEditor::Extrusion_Error
3372 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject,
3373 SMESH::SMESH_Mesh_ptr thePathMesh,
3374 GEOM::GEOM_Object_ptr thePathShape,
3375 CORBA::Long theNodeStart,
3376 CORBA::Boolean theHasAngles,
3377 const SMESH::double_array & theAngles,
3378 CORBA::Boolean theHasRefPoint,
3379 const SMESH::PointStruct & theRefPoint)
3380 throw (SALOME::SALOME_Exception)
3382 if ( !myIsPreviewMode ) {
3383 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
3384 << theObject << ", "
3385 << thePathMesh << ", "
3386 << thePathShape << ", "
3387 << theNodeStart << ", "
3388 << theHasAngles << ", "
3389 << theAngles << ", "
3390 << theHasRefPoint << ", "
3391 << "SMESH.PointStruct( "
3392 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3393 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3394 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3396 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3397 prepareIdSource( theObject );
3398 SMESH::long_array_var anElementsId = theObject->GetIDs();
3399 extrusionAlongPath( anElementsId,
3413 //=======================================================================
3414 //function : ExtrusionAlongPathObject2D
3416 //=======================================================================
3418 SMESH::SMESH_MeshEditor::Extrusion_Error
3419 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject,
3420 SMESH::SMESH_Mesh_ptr thePathMesh,
3421 GEOM::GEOM_Object_ptr thePathShape,
3422 CORBA::Long theNodeStart,
3423 CORBA::Boolean theHasAngles,
3424 const SMESH::double_array & theAngles,
3425 CORBA::Boolean theHasRefPoint,
3426 const SMESH::PointStruct & theRefPoint)
3427 throw (SALOME::SALOME_Exception)
3429 if ( !myIsPreviewMode ) {
3430 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
3431 << theObject << ", "
3432 << thePathMesh << ", "
3433 << thePathShape << ", "
3434 << theNodeStart << ", "
3435 << theHasAngles << ", "
3436 << theAngles << ", "
3437 << theHasRefPoint << ", "
3438 << "SMESH.PointStruct( "
3439 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3440 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3441 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3443 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3444 prepareIdSource( theObject );
3445 SMESH::long_array_var anElementsId = theObject->GetIDs();
3446 extrusionAlongPath( anElementsId,
3461 //=======================================================================
3462 //function : ExtrusionAlongPathMakeGroups
3464 //=======================================================================
3466 SMESH::ListOfGroups*
3467 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theIDsOfElements,
3468 SMESH::SMESH_Mesh_ptr thePathMesh,
3469 GEOM::GEOM_Object_ptr thePathShape,
3470 CORBA::Long theNodeStart,
3471 CORBA::Boolean theHasAngles,
3472 const SMESH::double_array& theAngles,
3473 CORBA::Boolean theHasRefPoint,
3474 const SMESH::PointStruct& theRefPoint,
3475 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3476 throw (SALOME::SALOME_Exception)
3478 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3480 SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements,
3490 if (!myIsPreviewMode) {
3491 bool isDumpGroups = aGroups && aGroups->length() > 0;
3493 aPythonDump << "(" << aGroups << ", error)";
3495 aPythonDump <<"error";
3497 aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
3498 << theIDsOfElements << ", "
3499 << thePathMesh << ", "
3500 << thePathShape << ", "
3501 << theNodeStart << ", "
3502 << theHasAngles << ", "
3503 << theAngles << ", "
3504 << theHasRefPoint << ", "
3505 << "SMESH.PointStruct( "
3506 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3507 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3508 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3513 //=======================================================================
3514 //function : ExtrusionAlongPathObjectMakeGroups
3516 //=======================================================================
3518 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3519 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3520 SMESH::SMESH_Mesh_ptr thePathMesh,
3521 GEOM::GEOM_Object_ptr thePathShape,
3522 CORBA::Long theNodeStart,
3523 CORBA::Boolean theHasAngles,
3524 const SMESH::double_array& theAngles,
3525 CORBA::Boolean theHasRefPoint,
3526 const SMESH::PointStruct& theRefPoint,
3527 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3528 throw (SALOME::SALOME_Exception)
3530 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3532 prepareIdSource( theObject );
3533 SMESH::long_array_var anElementsId = theObject->GetIDs();
3534 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3545 if (!myIsPreviewMode) {
3546 bool isDumpGroups = aGroups && aGroups->length() > 0;
3548 aPythonDump << "(" << aGroups << ", error)";
3550 aPythonDump <<"error";
3552 aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
3553 << theObject << ", "
3554 << thePathMesh << ", "
3555 << thePathShape << ", "
3556 << theNodeStart << ", "
3557 << theHasAngles << ", "
3558 << theAngles << ", "
3559 << theHasRefPoint << ", "
3560 << "SMESH.PointStruct( "
3561 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3562 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3563 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3568 //=======================================================================
3569 //function : ExtrusionAlongPathObject1DMakeGroups
3571 //=======================================================================
3573 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3574 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3575 SMESH::SMESH_Mesh_ptr thePathMesh,
3576 GEOM::GEOM_Object_ptr thePathShape,
3577 CORBA::Long theNodeStart,
3578 CORBA::Boolean theHasAngles,
3579 const SMESH::double_array& theAngles,
3580 CORBA::Boolean theHasRefPoint,
3581 const SMESH::PointStruct& theRefPoint,
3582 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3583 throw (SALOME::SALOME_Exception)
3585 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3587 prepareIdSource( theObject );
3588 SMESH::long_array_var anElementsId = theObject->GetIDs();
3589 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3601 if (!myIsPreviewMode) {
3602 bool isDumpGroups = aGroups && aGroups->length() > 0;
3604 aPythonDump << "(" << aGroups << ", error)";
3606 aPythonDump << "error";
3608 aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
3609 << theObject << ", "
3610 << thePathMesh << ", "
3611 << thePathShape << ", "
3612 << theNodeStart << ", "
3613 << theHasAngles << ", "
3614 << theAngles << ", "
3615 << theHasRefPoint << ", "
3616 << "SMESH.PointStruct( "
3617 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3618 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3619 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3624 //=======================================================================
3625 //function : ExtrusionAlongPathObject2DMakeGroups
3627 //=======================================================================
3629 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3630 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3631 SMESH::SMESH_Mesh_ptr thePathMesh,
3632 GEOM::GEOM_Object_ptr thePathShape,
3633 CORBA::Long theNodeStart,
3634 CORBA::Boolean theHasAngles,
3635 const SMESH::double_array& theAngles,
3636 CORBA::Boolean theHasRefPoint,
3637 const SMESH::PointStruct& theRefPoint,
3638 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3639 throw (SALOME::SALOME_Exception)
3641 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3643 prepareIdSource( theObject );
3644 SMESH::long_array_var anElementsId = theObject->GetIDs();
3645 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3657 if (!myIsPreviewMode) {
3658 bool isDumpGroups = aGroups && aGroups->length() > 0;
3660 aPythonDump << "(" << aGroups << ", error)";
3662 aPythonDump << "error";
3664 aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
3665 << theObject << ", "
3666 << thePathMesh << ", "
3667 << thePathShape << ", "
3668 << theNodeStart << ", "
3669 << theHasAngles << ", "
3670 << theAngles << ", "
3671 << theHasRefPoint << ", "
3672 << "SMESH.PointStruct( "
3673 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3674 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3675 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3680 //=======================================================================
3681 //function : ExtrusionAlongPathObjX
3683 //=======================================================================
3685 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3686 ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr Object,
3687 SMESH::SMESH_IDSource_ptr Path,
3688 CORBA::Long NodeStart,
3689 CORBA::Boolean HasAngles,
3690 const SMESH::double_array& Angles,
3691 CORBA::Boolean LinearVariation,
3692 CORBA::Boolean HasRefPoint,
3693 const SMESH::PointStruct& RefPoint,
3694 CORBA::Boolean MakeGroups,
3695 SMESH::ElementType ElemType,
3696 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3697 throw (SALOME::SALOME_Exception)
3699 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3701 prepareIdSource( Object );
3702 SMESH::long_array_var anElementsId = Object->GetIDs();
3703 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
3712 (SMDSAbs_ElementType)ElemType,
3715 if (!myIsPreviewMode) {
3716 bool isDumpGroups = aGroups && aGroups->length() > 0;
3718 aPythonDump << "(" << *aGroups << ", error)";
3720 aPythonDump << "error";
3722 aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
3725 << NodeStart << ", "
3726 << HasAngles << ", "
3727 << TVar( Angles ) << ", "
3728 << LinearVariation << ", "
3729 << HasRefPoint << ", "
3730 << "SMESH.PointStruct( "
3731 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3732 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3733 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3734 << MakeGroups << ", "
3735 << ElemType << " )";
3740 //=======================================================================
3741 //function : ExtrusionAlongPathX
3743 //=======================================================================
3745 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3746 ExtrusionAlongPathX(const SMESH::long_array& IDsOfElements,
3747 SMESH::SMESH_IDSource_ptr Path,
3748 CORBA::Long NodeStart,
3749 CORBA::Boolean HasAngles,
3750 const SMESH::double_array& Angles,
3751 CORBA::Boolean LinearVariation,
3752 CORBA::Boolean HasRefPoint,
3753 const SMESH::PointStruct& RefPoint,
3754 CORBA::Boolean MakeGroups,
3755 SMESH::ElementType ElemType,
3756 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3757 throw (SALOME::SALOME_Exception)
3759 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3761 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
3770 (SMDSAbs_ElementType)ElemType,
3773 if (!myIsPreviewMode) {
3774 bool isDumpGroups = aGroups && aGroups->length() > 0;
3776 aPythonDump << "(" << *aGroups << ", error)";
3778 aPythonDump <<"error";
3780 aPythonDump << " = " << this << ".ExtrusionAlongPathX( "
3781 << IDsOfElements << ", "
3783 << NodeStart << ", "
3784 << HasAngles << ", "
3785 << TVar( Angles ) << ", "
3786 << LinearVariation << ", "
3787 << HasRefPoint << ", "
3788 << "SMESH.PointStruct( "
3789 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3790 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3791 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3792 << MakeGroups << ", "
3793 << ElemType << " )";
3798 //================================================================================
3800 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
3801 * of given angles along path steps
3802 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
3803 * which proceeds the extrusion
3804 * \param PathShape is shape(edge); as the mesh can be complex, the edge
3805 * is used to define the sub-mesh for the path
3807 //================================================================================
3809 SMESH::double_array*
3810 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
3811 GEOM::GEOM_Object_ptr thePathShape,
3812 const SMESH::double_array & theAngles)
3814 SMESH::double_array_var aResult = new SMESH::double_array();
3815 int nbAngles = theAngles.length();
3816 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
3818 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3819 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3820 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3821 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
3822 return aResult._retn();
3823 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
3824 if ( nbSteps == nbAngles )
3826 aResult.inout() = theAngles;
3830 aResult->length( nbSteps );
3831 double rAn2St = double( nbAngles ) / double( nbSteps );
3832 double angPrev = 0, angle;
3833 for ( int iSt = 0; iSt < nbSteps; ++iSt )
3835 double angCur = rAn2St * ( iSt+1 );
3836 double angCurFloor = floor( angCur );
3837 double angPrevFloor = floor( angPrev );
3838 if ( angPrevFloor == angCurFloor )
3839 angle = rAn2St * theAngles[ int( angCurFloor ) ];
3842 int iP = int( angPrevFloor );
3843 double angPrevCeil = ceil(angPrev);
3844 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
3846 int iC = int( angCurFloor );
3847 if ( iC < nbAngles )
3848 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
3850 iP = int( angPrevCeil );
3852 angle += theAngles[ iC ];
3854 aResult[ iSt ] = angle;
3859 // Update Python script
3860 TPythonDump() << "rotAngles = " << theAngles;
3861 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
3862 << thePathMesh << ", "
3863 << thePathShape << ", "
3866 return aResult._retn();
3869 //=======================================================================
3872 //=======================================================================
3874 SMESH::ListOfGroups*
3875 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
3876 const SMESH::AxisStruct & theAxis,
3877 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3878 CORBA::Boolean theCopy,
3880 ::SMESH_Mesh* theTargetMesh)
3881 throw (SALOME::SALOME_Exception)
3886 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3887 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3889 if ( theTargetMesh )
3893 switch ( theMirrorType ) {
3894 case SMESH::SMESH_MeshEditor::POINT:
3895 aTrsf.SetMirror( P );
3897 case SMESH::SMESH_MeshEditor::AXIS:
3898 aTrsf.SetMirror( gp_Ax1( P, V ));
3901 aTrsf.SetMirror( gp_Ax2( P, V ));
3904 TIDSortedElemSet copyElements;
3905 TIDSortedElemSet* workElements = & theElements;
3907 if ( myIsPreviewMode )
3909 TPreviewMesh * tmpMesh = getPreviewMesh();
3910 tmpMesh->Copy( theElements, copyElements);
3911 if ( !theCopy && !theTargetMesh )
3913 TIDSortedElemSet elemsAround, elemsAroundCopy;
3914 getElementsAround( theElements, getMeshDS(), elemsAround );
3915 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3917 workElements = & copyElements;
3918 theMakeGroups = false;
3921 ::SMESH_MeshEditor::PGroupIDs groupIds =
3922 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3924 if ( theCopy && !myIsPreviewMode)
3926 if ( theTargetMesh )
3928 theTargetMesh->GetMeshDS()->Modified();
3932 declareMeshModified( /*isReComputeSafe=*/false );
3935 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3937 SMESH_CATCH( SMESH::throwCorbaException );
3941 //=======================================================================
3944 //=======================================================================
3946 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3947 const SMESH::AxisStruct & theAxis,
3948 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3949 CORBA::Boolean theCopy)
3950 throw (SALOME::SALOME_Exception)
3952 if ( !myIsPreviewMode ) {
3953 TPythonDump() << this << ".Mirror( "
3954 << theIDsOfElements << ", "
3956 << mirrorTypeName(theMirrorType) << ", "
3959 if ( theIDsOfElements.length() > 0 )
3961 TIDSortedElemSet elements;
3962 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3963 mirror(elements, theAxis, theMirrorType, theCopy, false);
3968 //=======================================================================
3969 //function : MirrorObject
3971 //=======================================================================
3973 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3974 const SMESH::AxisStruct & theAxis,
3975 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3976 CORBA::Boolean theCopy)
3977 throw (SALOME::SALOME_Exception)
3979 if ( !myIsPreviewMode ) {
3980 TPythonDump() << this << ".MirrorObject( "
3981 << theObject << ", "
3983 << mirrorTypeName(theMirrorType) << ", "
3986 TIDSortedElemSet elements;
3988 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3990 prepareIdSource( theObject );
3991 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3992 mirror(elements, theAxis, theMirrorType, theCopy, false);
3995 //=======================================================================
3996 //function : MirrorMakeGroups
3998 //=======================================================================
4000 SMESH::ListOfGroups*
4001 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
4002 const SMESH::AxisStruct& theMirror,
4003 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
4004 throw (SALOME::SALOME_Exception)
4006 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4008 SMESH::ListOfGroups * aGroups = 0;
4009 if ( theIDsOfElements.length() > 0 )
4011 TIDSortedElemSet elements;
4012 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4013 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
4015 if (!myIsPreviewMode) {
4016 dumpGroupsList(aPythonDump, aGroups);
4017 aPythonDump << this << ".MirrorMakeGroups( "
4018 << theIDsOfElements << ", "
4019 << theMirror << ", "
4020 << mirrorTypeName(theMirrorType) << " )";
4025 //=======================================================================
4026 //function : MirrorObjectMakeGroups
4028 //=======================================================================
4030 SMESH::ListOfGroups*
4031 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4032 const SMESH::AxisStruct& theMirror,
4033 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
4034 throw (SALOME::SALOME_Exception)
4036 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4038 SMESH::ListOfGroups * aGroups = 0;
4039 TIDSortedElemSet elements;
4040 prepareIdSource( theObject );
4041 if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4042 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
4044 if (!myIsPreviewMode)
4046 dumpGroupsList(aPythonDump,aGroups);
4047 aPythonDump << this << ".MirrorObjectMakeGroups( "
4048 << theObject << ", "
4049 << theMirror << ", "
4050 << mirrorTypeName(theMirrorType) << " )";
4055 //=======================================================================
4056 //function : MirrorMakeMesh
4058 //=======================================================================
4060 SMESH::SMESH_Mesh_ptr
4061 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
4062 const SMESH::AxisStruct& theMirror,
4063 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
4064 CORBA::Boolean theCopyGroups,
4065 const char* theMeshName)
4066 throw (SALOME::SALOME_Exception)
4068 SMESH_Mesh_i* mesh_i;
4069 SMESH::SMESH_Mesh_var mesh;
4070 { // open new scope to dump "MakeMesh" command
4071 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4073 TPythonDump pydump; // to prevent dump at mesh creation
4075 mesh = makeMesh( theMeshName );
4076 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4077 if (mesh_i && theIDsOfElements.length() > 0 )
4079 TIDSortedElemSet elements;
4080 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4081 mirror(elements, theMirror, theMirrorType,
4082 false, theCopyGroups, & mesh_i->GetImpl());
4083 mesh_i->CreateGroupServants();
4086 if (!myIsPreviewMode) {
4087 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
4088 << theIDsOfElements << ", "
4089 << theMirror << ", "
4090 << mirrorTypeName(theMirrorType) << ", "
4091 << theCopyGroups << ", '"
4092 << theMeshName << "' )";
4097 if (!myIsPreviewMode && mesh_i)
4098 mesh_i->GetGroups();
4100 return mesh._retn();
4103 //=======================================================================
4104 //function : MirrorObjectMakeMesh
4106 //=======================================================================
4108 SMESH::SMESH_Mesh_ptr
4109 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4110 const SMESH::AxisStruct& theMirror,
4111 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
4112 CORBA::Boolean theCopyGroups,
4113 const char* theMeshName)
4114 throw (SALOME::SALOME_Exception)
4116 SMESH_Mesh_i* mesh_i;
4117 SMESH::SMESH_Mesh_var mesh;
4118 { // open new scope to dump "MakeMesh" command
4119 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4121 TPythonDump pydump; // to prevent dump at mesh creation
4123 mesh = makeMesh( theMeshName );
4124 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4125 TIDSortedElemSet elements;
4126 prepareIdSource( theObject );
4128 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4130 mirror(elements, theMirror, theMirrorType,
4131 false, theCopyGroups, & mesh_i->GetImpl());
4132 mesh_i->CreateGroupServants();
4134 if (!myIsPreviewMode) {
4135 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
4136 << theObject << ", "
4137 << theMirror << ", "
4138 << mirrorTypeName(theMirrorType) << ", "
4139 << theCopyGroups << ", '"
4140 << theMeshName << "' )";
4145 if (!myIsPreviewMode && mesh_i)
4146 mesh_i->GetGroups();
4148 return mesh._retn();
4151 //=======================================================================
4152 //function : translate
4154 //=======================================================================
4156 SMESH::ListOfGroups*
4157 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
4158 const SMESH::DirStruct & theVector,
4159 CORBA::Boolean theCopy,
4161 ::SMESH_Mesh* theTargetMesh)
4162 throw (SALOME::SALOME_Exception)
4167 if ( theTargetMesh )
4171 const SMESH::PointStruct * P = &theVector.PS;
4172 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
4174 TIDSortedElemSet copyElements;
4175 TIDSortedElemSet* workElements = &theElements;
4177 if ( myIsPreviewMode )
4179 TPreviewMesh * tmpMesh = getPreviewMesh();
4180 tmpMesh->Copy( theElements, copyElements);
4181 if ( !theCopy && !theTargetMesh )
4183 TIDSortedElemSet elemsAround, elemsAroundCopy;
4184 getElementsAround( theElements, getMeshDS(), elemsAround );
4185 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4187 workElements = & copyElements;
4188 theMakeGroups = false;
4191 ::SMESH_MeshEditor::PGroupIDs groupIds =
4192 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4194 if ( theCopy && !myIsPreviewMode )
4196 if ( theTargetMesh )
4198 theTargetMesh->GetMeshDS()->Modified();
4202 declareMeshModified( /*isReComputeSafe=*/false );
4206 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4208 SMESH_CATCH( SMESH::throwCorbaException );
4212 //=======================================================================
4213 //function : Translate
4215 //=======================================================================
4217 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
4218 const SMESH::DirStruct & theVector,
4219 CORBA::Boolean theCopy)
4220 throw (SALOME::SALOME_Exception)
4222 if (!myIsPreviewMode) {
4223 TPythonDump() << this << ".Translate( "
4224 << theIDsOfElements << ", "
4225 << theVector << ", "
4228 if (theIDsOfElements.length()) {
4229 TIDSortedElemSet elements;
4230 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4231 translate(elements, theVector, theCopy, false);
4235 //=======================================================================
4236 //function : TranslateObject
4238 //=======================================================================
4240 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
4241 const SMESH::DirStruct & theVector,
4242 CORBA::Boolean theCopy)
4243 throw (SALOME::SALOME_Exception)
4245 if (!myIsPreviewMode) {
4246 TPythonDump() << this << ".TranslateObject( "
4247 << theObject << ", "
4248 << theVector << ", "
4251 TIDSortedElemSet elements;
4253 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4255 prepareIdSource( theObject );
4256 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4257 translate(elements, theVector, theCopy, false);
4260 //=======================================================================
4261 //function : TranslateMakeGroups
4263 //=======================================================================
4265 SMESH::ListOfGroups*
4266 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
4267 const SMESH::DirStruct& theVector)
4268 throw (SALOME::SALOME_Exception)
4270 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4272 SMESH::ListOfGroups * aGroups = 0;
4273 if (theIDsOfElements.length()) {
4274 TIDSortedElemSet elements;
4275 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4276 aGroups = translate(elements,theVector,true,true);
4278 if (!myIsPreviewMode) {
4279 dumpGroupsList(aPythonDump, aGroups);
4280 aPythonDump << this << ".TranslateMakeGroups( "
4281 << theIDsOfElements << ", "
4282 << theVector << " )";
4287 //=======================================================================
4288 //function : TranslateObjectMakeGroups
4290 //=======================================================================
4292 SMESH::ListOfGroups*
4293 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4294 const SMESH::DirStruct& theVector)
4295 throw (SALOME::SALOME_Exception)
4297 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4299 SMESH::ListOfGroups * aGroups = 0;
4300 TIDSortedElemSet elements;
4301 prepareIdSource( theObject );
4302 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4303 aGroups = translate(elements, theVector, true, true);
4305 if (!myIsPreviewMode) {
4306 dumpGroupsList(aPythonDump, aGroups);
4307 aPythonDump << this << ".TranslateObjectMakeGroups( "
4308 << theObject << ", "
4309 << theVector << " )";
4314 //=======================================================================
4315 //function : TranslateMakeMesh
4317 //=======================================================================
4319 SMESH::SMESH_Mesh_ptr
4320 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
4321 const SMESH::DirStruct& theVector,
4322 CORBA::Boolean theCopyGroups,
4323 const char* theMeshName)
4324 throw (SALOME::SALOME_Exception)
4326 SMESH_Mesh_i* mesh_i;
4327 SMESH::SMESH_Mesh_var mesh;
4329 { // open new scope to dump "MakeMesh" command
4330 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4332 TPythonDump pydump; // to prevent dump at mesh creation
4334 mesh = makeMesh( theMeshName );
4335 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4337 if ( mesh_i && theIDsOfElements.length() )
4339 TIDSortedElemSet elements;
4340 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4341 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
4342 mesh_i->CreateGroupServants();
4345 if ( !myIsPreviewMode ) {
4346 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
4347 << theIDsOfElements << ", "
4348 << theVector << ", "
4349 << theCopyGroups << ", '"
4350 << theMeshName << "' )";
4355 if (!myIsPreviewMode && mesh_i)
4356 mesh_i->GetGroups();
4358 return mesh._retn();
4361 //=======================================================================
4362 //function : TranslateObjectMakeMesh
4364 //=======================================================================
4366 SMESH::SMESH_Mesh_ptr
4367 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4368 const SMESH::DirStruct& theVector,
4369 CORBA::Boolean theCopyGroups,
4370 const char* theMeshName)
4371 throw (SALOME::SALOME_Exception)
4374 SMESH_Mesh_i* mesh_i;
4375 SMESH::SMESH_Mesh_var mesh;
4376 { // open new scope to dump "MakeMesh" command
4377 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4379 TPythonDump pydump; // to prevent dump at mesh creation
4380 mesh = makeMesh( theMeshName );
4381 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4383 TIDSortedElemSet elements;
4384 prepareIdSource( theObject );
4386 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4388 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
4389 mesh_i->CreateGroupServants();
4391 if ( !myIsPreviewMode ) {
4392 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
4393 << theObject << ", "
4394 << theVector << ", "
4395 << theCopyGroups << ", '"
4396 << theMeshName << "' )";
4401 if (!myIsPreviewMode && mesh_i)
4402 mesh_i->GetGroups();
4404 return mesh._retn();
4406 SMESH_CATCH( SMESH::throwCorbaException );
4410 //=======================================================================
4413 //=======================================================================
4415 SMESH::ListOfGroups*
4416 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
4417 const SMESH::AxisStruct & theAxis,
4418 CORBA::Double theAngle,
4419 CORBA::Boolean theCopy,
4421 ::SMESH_Mesh* theTargetMesh)
4422 throw (SALOME::SALOME_Exception)
4427 if ( theTargetMesh )
4430 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
4431 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
4434 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
4436 TIDSortedElemSet copyElements;
4437 TIDSortedElemSet* workElements = &theElements;
4438 if ( myIsPreviewMode ) {
4439 TPreviewMesh * tmpMesh = getPreviewMesh();
4440 tmpMesh->Copy( theElements, copyElements );
4441 if ( !theCopy && !theTargetMesh )
4443 TIDSortedElemSet elemsAround, elemsAroundCopy;
4444 getElementsAround( theElements, getMeshDS(), elemsAround );
4445 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4447 workElements = ©Elements;
4448 theMakeGroups = false;
4451 ::SMESH_MeshEditor::PGroupIDs groupIds =
4452 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4454 if ( theCopy && !myIsPreviewMode)
4456 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
4457 else declareMeshModified( /*isReComputeSafe=*/false );
4460 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4462 SMESH_CATCH( SMESH::throwCorbaException );
4466 //=======================================================================
4469 //=======================================================================
4471 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
4472 const SMESH::AxisStruct & theAxis,
4473 CORBA::Double theAngle,
4474 CORBA::Boolean theCopy)
4475 throw (SALOME::SALOME_Exception)
4477 if (!myIsPreviewMode) {
4478 TPythonDump() << this << ".Rotate( "
4479 << theIDsOfElements << ", "
4481 << TVar( theAngle ) << ", "
4484 if (theIDsOfElements.length() > 0)
4486 TIDSortedElemSet elements;
4487 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4488 rotate(elements,theAxis,theAngle,theCopy,false);
4492 //=======================================================================
4493 //function : RotateObject
4495 //=======================================================================
4497 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
4498 const SMESH::AxisStruct & theAxis,
4499 CORBA::Double theAngle,
4500 CORBA::Boolean theCopy)
4501 throw (SALOME::SALOME_Exception)
4503 if ( !myIsPreviewMode ) {
4504 TPythonDump() << this << ".RotateObject( "
4505 << theObject << ", "
4507 << TVar( theAngle ) << ", "
4510 TIDSortedElemSet elements;
4511 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4512 prepareIdSource( theObject );
4513 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4514 rotate(elements,theAxis,theAngle,theCopy,false);
4517 //=======================================================================
4518 //function : RotateMakeGroups
4520 //=======================================================================
4522 SMESH::ListOfGroups*
4523 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
4524 const SMESH::AxisStruct& theAxis,
4525 CORBA::Double theAngle)
4526 throw (SALOME::SALOME_Exception)
4528 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4530 SMESH::ListOfGroups * aGroups = 0;
4531 if (theIDsOfElements.length() > 0)
4533 TIDSortedElemSet elements;
4534 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4535 aGroups = rotate(elements,theAxis,theAngle,true,true);
4537 if (!myIsPreviewMode) {
4538 dumpGroupsList(aPythonDump, aGroups);
4539 aPythonDump << this << ".RotateMakeGroups( "
4540 << theIDsOfElements << ", "
4542 << TVar( theAngle ) << " )";
4547 //=======================================================================
4548 //function : RotateObjectMakeGroups
4550 //=======================================================================
4552 SMESH::ListOfGroups*
4553 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4554 const SMESH::AxisStruct& theAxis,
4555 CORBA::Double theAngle)
4556 throw (SALOME::SALOME_Exception)
4558 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4560 SMESH::ListOfGroups * aGroups = 0;
4561 TIDSortedElemSet elements;
4562 prepareIdSource( theObject );
4563 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4564 aGroups = rotate(elements, theAxis, theAngle, true, true);
4566 if (!myIsPreviewMode) {
4567 dumpGroupsList(aPythonDump, aGroups);
4568 aPythonDump << this << ".RotateObjectMakeGroups( "
4569 << theObject << ", "
4571 << TVar( theAngle ) << " )";
4576 //=======================================================================
4577 //function : RotateMakeMesh
4579 //=======================================================================
4581 SMESH::SMESH_Mesh_ptr
4582 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
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
4598 mesh = makeMesh( theMeshName );
4599 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4601 if ( mesh_i && theIDsOfElements.length() > 0 )
4603 TIDSortedElemSet elements;
4604 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4605 rotate(elements, theAxis, theAngleInRadians,
4606 false, theCopyGroups, & mesh_i->GetImpl());
4607 mesh_i->CreateGroupServants();
4609 if ( !myIsPreviewMode ) {
4610 pydump << mesh << " = " << this << ".RotateMakeMesh( "
4611 << theIDsOfElements << ", "
4613 << TVar( theAngleInRadians ) << ", "
4614 << theCopyGroups << ", '"
4615 << theMeshName << "' )";
4620 if (!myIsPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
4621 mesh_i->GetGroups();
4623 return mesh._retn();
4625 SMESH_CATCH( SMESH::throwCorbaException );
4629 //=======================================================================
4630 //function : RotateObjectMakeMesh
4632 //=======================================================================
4634 SMESH::SMESH_Mesh_ptr
4635 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4636 const SMESH::AxisStruct& theAxis,
4637 CORBA::Double theAngleInRadians,
4638 CORBA::Boolean theCopyGroups,
4639 const char* theMeshName)
4640 throw (SALOME::SALOME_Exception)
4643 SMESH::SMESH_Mesh_var mesh;
4644 SMESH_Mesh_i* mesh_i;
4646 {// open new scope to dump "MakeMesh" command
4647 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4649 TPythonDump pydump; // to prevent dump at mesh creation
4650 mesh = makeMesh( theMeshName );
4651 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4653 TIDSortedElemSet elements;
4654 prepareIdSource( theObject );
4656 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4658 rotate(elements, theAxis, theAngleInRadians,
4659 false, theCopyGroups, & mesh_i->GetImpl());
4660 mesh_i->CreateGroupServants();
4662 if ( !myIsPreviewMode ) {
4663 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
4664 << theObject << ", "
4666 << TVar( theAngleInRadians ) << ", "
4667 << theCopyGroups << ", '"
4668 << theMeshName << "' )";
4673 if (!myIsPreviewMode && mesh_i)
4674 mesh_i->GetGroups();
4676 return mesh._retn();
4678 SMESH_CATCH( SMESH::throwCorbaException );
4682 //=======================================================================
4685 //=======================================================================
4687 SMESH::ListOfGroups*
4688 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
4689 const SMESH::PointStruct& thePoint,
4690 const SMESH::double_array& theScaleFact,
4691 CORBA::Boolean theCopy,
4693 ::SMESH_Mesh* theTargetMesh)
4694 throw (SALOME::SALOME_Exception)
4698 if ( theScaleFact.length() < 1 )
4699 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
4700 if ( theScaleFact.length() == 2 )
4701 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
4703 if ( theTargetMesh )
4706 TIDSortedElemSet elements;
4707 prepareIdSource( theObject );
4708 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4709 if ( !idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4714 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
4715 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
4717 double tol = std::numeric_limits<double>::max();
4719 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
4720 0, S[1], 0, thePoint.y * (1-S[1]),
4721 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
4723 TIDSortedElemSet copyElements;
4724 TIDSortedElemSet* workElements = &elements;
4725 if ( myIsPreviewMode )
4727 TPreviewMesh * tmpMesh = getPreviewMesh();
4728 tmpMesh->Copy( elements, copyElements);
4729 if ( !theCopy && !theTargetMesh )
4731 TIDSortedElemSet elemsAround, elemsAroundCopy;
4732 getElementsAround( elements, getMeshDS(), elemsAround );
4733 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4735 workElements = & copyElements;
4736 theMakeGroups = false;
4739 ::SMESH_MeshEditor::PGroupIDs groupIds =
4740 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4742 if ( theCopy && !myIsPreviewMode )
4744 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
4745 else declareMeshModified( /*isReComputeSafe=*/false );
4747 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4749 SMESH_CATCH( SMESH::throwCorbaException );
4753 //=======================================================================
4756 //=======================================================================
4758 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
4759 const SMESH::PointStruct& thePoint,
4760 const SMESH::double_array& theScaleFact,
4761 CORBA::Boolean theCopy)
4762 throw (SALOME::SALOME_Exception)
4764 if ( !myIsPreviewMode ) {
4765 TPythonDump() << this << ".Scale( "
4766 << theObject << ", "
4768 << TVar( theScaleFact ) << ", "
4771 scale(theObject, thePoint, theScaleFact, theCopy, false);
4775 //=======================================================================
4776 //function : ScaleMakeGroups
4778 //=======================================================================
4780 SMESH::ListOfGroups*
4781 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4782 const SMESH::PointStruct& thePoint,
4783 const SMESH::double_array& theScaleFact)
4784 throw (SALOME::SALOME_Exception)
4786 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4788 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
4789 if (!myIsPreviewMode) {
4790 dumpGroupsList(aPythonDump, aGroups);
4791 aPythonDump << this << ".Scale("
4794 << TVar( theScaleFact ) << ",True,True)";
4800 //=======================================================================
4801 //function : ScaleMakeMesh
4803 //=======================================================================
4805 SMESH::SMESH_Mesh_ptr
4806 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4807 const SMESH::PointStruct& thePoint,
4808 const SMESH::double_array& theScaleFact,
4809 CORBA::Boolean theCopyGroups,
4810 const char* theMeshName)
4811 throw (SALOME::SALOME_Exception)
4813 SMESH_Mesh_i* mesh_i;
4814 SMESH::SMESH_Mesh_var mesh;
4815 { // open new scope to dump "MakeMesh" command
4816 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4818 TPythonDump pydump; // to prevent dump at mesh creation
4819 mesh = makeMesh( theMeshName );
4820 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4824 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
4825 mesh_i->CreateGroupServants();
4827 if ( !myIsPreviewMode )
4828 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
4829 << theObject << ", "
4831 << TVar( theScaleFact ) << ", "
4832 << theCopyGroups << ", '"
4833 << theMeshName << "' )";
4837 if (!myIsPreviewMode && mesh_i)
4838 mesh_i->GetGroups();
4840 return mesh._retn();
4844 //=======================================================================
4845 //function : FindCoincidentNodes
4847 //=======================================================================
4849 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance,
4850 SMESH::array_of_long_array_out GroupsOfNodes)
4851 throw (SALOME::SALOME_Exception)
4856 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4857 TIDSortedNodeSet nodes; // no input nodes
4858 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4860 GroupsOfNodes = new SMESH::array_of_long_array;
4861 GroupsOfNodes->length( aListOfListOfNodes.size() );
4862 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4863 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
4864 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4865 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4866 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4867 aGroup.length( aListOfNodes.size() );
4868 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4869 aGroup[ j ] = (*lIt)->GetID();
4871 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
4872 << Tolerance << " )";
4874 SMESH_CATCH( SMESH::throwCorbaException );
4877 //=======================================================================
4878 //function : FindCoincidentNodesOnPart
4880 //=======================================================================
4882 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
4883 CORBA::Double Tolerance,
4884 SMESH::array_of_long_array_out GroupsOfNodes)
4885 throw (SALOME::SALOME_Exception)
4890 TIDSortedNodeSet nodes;
4891 prepareIdSource( theObject );
4892 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4894 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4896 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4898 GroupsOfNodes = new SMESH::array_of_long_array;
4899 GroupsOfNodes->length( aListOfListOfNodes.size() );
4900 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4901 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4903 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4904 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4905 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4906 aGroup.length( aListOfNodes.size() );
4907 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4908 aGroup[ j ] = (*lIt)->GetID();
4910 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
4912 << Tolerance << " )";
4914 SMESH_CATCH( SMESH::throwCorbaException );
4917 //================================================================================
4919 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
4920 * ExceptSubMeshOrGroups
4922 //================================================================================
4924 void SMESH_MeshEditor_i::
4925 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
4926 CORBA::Double theTolerance,
4927 SMESH::array_of_long_array_out theGroupsOfNodes,
4928 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups)
4929 throw (SALOME::SALOME_Exception)
4934 TIDSortedNodeSet nodes;
4935 prepareIdSource( theObject );
4936 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4938 for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
4940 TIDSortedNodeSet exceptNodes;
4941 idSourceToNodeSet( theExceptSubMeshOrGroups[i], getMeshDS(), exceptNodes );
4942 TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
4943 for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
4944 nodes.erase( *avoidNode );
4946 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4948 getEditor().FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
4950 theGroupsOfNodes = new SMESH::array_of_long_array;
4951 theGroupsOfNodes->length( aListOfListOfNodes.size() );
4952 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4953 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4955 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4956 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4957 SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
4958 aGroup.length( aListOfNodes.size() );
4959 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4960 aGroup[ j ] = (*lIt)->GetID();
4962 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
4964 << theTolerance << ", "
4965 << theExceptSubMeshOrGroups << " )";
4967 SMESH_CATCH( SMESH::throwCorbaException );
4970 //=======================================================================
4971 //function : MergeNodes
4973 //=======================================================================
4975 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
4976 throw (SALOME::SALOME_Exception)
4981 SMESHDS_Mesh* aMesh = getMeshDS();
4983 TPythonDump aTPythonDump;
4984 aTPythonDump << this << ".MergeNodes([";
4985 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4986 for (int i = 0; i < GroupsOfNodes.length(); i++)
4988 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
4989 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
4990 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
4991 for ( int j = 0; j < aNodeGroup.length(); j++ )
4993 CORBA::Long index = aNodeGroup[ j ];
4994 const SMDS_MeshNode * node = aMesh->FindNode(index);
4996 aListOfNodes.push_back( node );
4998 if ( aListOfNodes.size() < 2 )
4999 aListOfListOfNodes.pop_back();
5001 if ( i > 0 ) aTPythonDump << ", ";
5002 aTPythonDump << aNodeGroup;
5004 getEditor().MergeNodes( aListOfListOfNodes );
5006 aTPythonDump << "])";
5008 declareMeshModified( /*isReComputeSafe=*/false );
5010 SMESH_CATCH( SMESH::throwCorbaException );
5013 //=======================================================================
5014 //function : FindEqualElements
5016 //=======================================================================
5018 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
5019 SMESH::array_of_long_array_out GroupsOfElementsID)
5020 throw (SALOME::SALOME_Exception)
5025 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
5026 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
5028 TIDSortedElemSet elems;
5029 prepareIdSource( theObject );
5030 idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true);
5032 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
5033 getEditor().FindEqualElements( elems, aListOfListOfElementsID );
5035 GroupsOfElementsID = new SMESH::array_of_long_array;
5036 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
5038 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt =
5039 aListOfListOfElementsID.begin();
5040 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j)
5042 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
5043 list<int>& listOfIDs = *arraysIt;
5044 aGroup.length( listOfIDs.size() );
5045 list<int>::iterator idIt = listOfIDs.begin();
5046 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k )
5047 aGroup[ k ] = *idIt;
5050 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
5054 SMESH_CATCH( SMESH::throwCorbaException );
5057 //=======================================================================
5058 //function : MergeElements
5060 //=======================================================================
5062 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
5063 throw (SALOME::SALOME_Exception)
5068 TPythonDump aTPythonDump;
5069 aTPythonDump << this << ".MergeElements( [";
5071 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
5073 for (int i = 0; i < GroupsOfElementsID.length(); i++) {
5074 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
5075 aListOfListOfElementsID.push_back( list< int >() );
5076 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
5077 for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
5078 CORBA::Long id = anElemsIDGroup[ j ];
5079 aListOfElemsID.push_back( id );
5081 if ( aListOfElemsID.size() < 2 )
5082 aListOfListOfElementsID.pop_back();
5083 if ( i > 0 ) aTPythonDump << ", ";
5084 aTPythonDump << anElemsIDGroup;
5087 getEditor().MergeElements(aListOfListOfElementsID);
5089 declareMeshModified( /*isReComputeSafe=*/true );
5091 aTPythonDump << "] )";
5093 SMESH_CATCH( SMESH::throwCorbaException );
5096 //=======================================================================
5097 //function : MergeEqualElements
5099 //=======================================================================
5101 void SMESH_MeshEditor_i::MergeEqualElements()
5102 throw (SALOME::SALOME_Exception)
5107 getEditor().MergeEqualElements();
5109 declareMeshModified( /*isReComputeSafe=*/true );
5111 TPythonDump() << this << ".MergeEqualElements()";
5113 SMESH_CATCH( SMESH::throwCorbaException );
5116 //=============================================================================
5118 * Move the node to a given point
5120 //=============================================================================
5122 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
5126 throw (SALOME::SALOME_Exception)
5129 initData(/*deleteSearchers=*/false);
5131 const SMDS_MeshNode * node = getMeshDS()->FindNode( NodeID );
5135 if ( theNodeSearcher )
5136 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5138 if ( myIsPreviewMode ) // make preview data
5140 // in a preview mesh, make edges linked to a node
5141 TPreviewMesh& tmpMesh = *getPreviewMesh();
5142 TIDSortedElemSet linkedNodes;
5143 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
5144 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
5145 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
5146 for ( ; nIt != linkedNodes.end(); ++nIt )
5148 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
5149 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
5153 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
5154 // fill preview data
5156 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
5157 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
5159 getMeshDS()->MoveNode(node, x, y, z);
5161 if ( !myIsPreviewMode )
5163 // Update Python script
5164 TPythonDump() << "isDone = " << this << ".MoveNode( "
5165 << NodeID << ", " << TVar(x) << ", " << TVar(y) << ", " << TVar(z) << " )";
5166 declareMeshModified( /*isReComputeSafe=*/false );
5169 SMESH_CATCH( SMESH::throwCorbaException );
5174 //================================================================================
5176 * \brief Return ID of node closest to a given point
5178 //================================================================================
5180 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
5183 throw (SALOME::SALOME_Exception)
5186 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5188 if ( !theNodeSearcher ) {
5189 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
5192 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
5193 return node->GetID();
5195 SMESH_CATCH( SMESH::throwCorbaException );
5199 //================================================================================
5201 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
5202 * move the node closest to the point to point's location and return ID of the node
5204 //================================================================================
5206 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
5209 CORBA::Long theNodeID)
5210 throw (SALOME::SALOME_Exception)
5213 // We keep theNodeSearcher until any mesh modification:
5214 // 1) initData() deletes theNodeSearcher at any edition,
5215 // 2) TSearchersDeleter - at any mesh compute event and mesh change
5217 initData(/*deleteSearchers=*/false);
5219 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5221 int nodeID = theNodeID;
5222 const SMDS_MeshNode* node = getMeshDS()->FindNode( nodeID );
5223 if ( !node ) // preview moving node
5225 if ( !theNodeSearcher ) {
5226 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
5229 node = theNodeSearcher->FindClosestTo( p );
5232 nodeID = node->GetID();
5233 if ( myIsPreviewMode ) // make preview data
5235 // in a preview mesh, make edges linked to a node
5236 TPreviewMesh tmpMesh = *getPreviewMesh();
5237 TIDSortedElemSet linkedNodes;
5238 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
5239 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
5240 for ( ; nIt != linkedNodes.end(); ++nIt )
5242 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
5243 tmpMesh.Copy( &edge );
5246 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
5248 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
5249 // fill preview data
5251 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
5253 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
5257 getMeshDS()->MoveNode(node, x, y, z);
5261 if ( !myIsPreviewMode )
5263 TPythonDump() << "nodeID = " << this
5264 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
5265 << ", " << nodeID << " )";
5267 declareMeshModified( /*isReComputeSafe=*/false );
5272 SMESH_CATCH( SMESH::throwCorbaException );
5276 //=======================================================================
5278 * Return elements of given type where the given point is IN or ON.
5280 * 'ALL' type means elements of any type excluding nodes
5282 //=======================================================================
5284 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
5287 SMESH::ElementType type)
5288 throw (SALOME::SALOME_Exception)
5291 SMESH::long_array_var res = new SMESH::long_array;
5292 vector< const SMDS_MeshElement* > foundElems;
5294 theSearchersDeleter.Set( myMesh );
5295 if ( !theElementSearcher ) {
5296 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
5298 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
5299 SMDSAbs_ElementType( type ),
5301 res->length( foundElems.size() );
5302 for ( int i = 0; i < foundElems.size(); ++i )
5303 res[i] = foundElems[i]->GetID();
5307 SMESH_CATCH( SMESH::throwCorbaException );
5311 //=======================================================================
5312 //function : FindAmongElementsByPoint
5313 //purpose : Searching among the given elements, return elements of given type
5314 // where the given point is IN or ON.
5315 // 'ALL' type means elements of any type excluding nodes
5316 //=======================================================================
5319 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
5323 SMESH::ElementType type)
5324 throw (SALOME::SALOME_Exception)
5327 SMESH::long_array_var res = new SMESH::long_array;
5329 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
5330 if ( types->length() == 1 && // a part contains only nodes or 0D elements
5331 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) &&
5332 type != types[0] ) // but search of elements of dim > 0
5335 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
5336 return FindElementsByPoint( x,y,z, type );
5338 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
5340 theSearchersDeleter.Set( myMesh, getPartIOR( elementIDs, type ));
5341 if ( !theElementSearcher )
5343 // create a searcher from elementIDs
5344 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
5345 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
5347 if ( !idSourceToSet( elementIDs, meshDS, elements,
5348 SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
5351 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5352 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
5354 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt );
5357 vector< const SMDS_MeshElement* > foundElems;
5359 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
5360 SMDSAbs_ElementType( type ),
5362 res->length( foundElems.size() );
5363 for ( int i = 0; i < foundElems.size(); ++i )
5364 res[i] = foundElems[i]->GetID();
5368 SMESH_CATCH( SMESH::throwCorbaException );
5372 //=======================================================================
5373 //function : GetPointState
5374 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
5375 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
5376 //=======================================================================
5378 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
5381 throw (SALOME::SALOME_Exception)
5384 theSearchersDeleter.Set( myMesh );
5385 if ( !theElementSearcher ) {
5386 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
5388 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
5390 SMESH_CATCH( SMESH::throwCorbaException );
5394 //=======================================================================
5395 //function : convError
5397 //=======================================================================
5399 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
5401 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
5405 RETCASE( SEW_BORDER1_NOT_FOUND );
5406 RETCASE( SEW_BORDER2_NOT_FOUND );
5407 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
5408 RETCASE( SEW_BAD_SIDE_NODES );
5409 RETCASE( SEW_VOLUMES_TO_SPLIT );
5410 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
5411 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
5412 RETCASE( SEW_BAD_SIDE1_NODES );
5413 RETCASE( SEW_BAD_SIDE2_NODES );
5415 return SMESH::SMESH_MeshEditor::SEW_OK;
5418 //=======================================================================
5419 //function : SewFreeBorders
5421 //=======================================================================
5423 SMESH::SMESH_MeshEditor::Sew_Error
5424 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
5425 CORBA::Long SecondNodeID1,
5426 CORBA::Long LastNodeID1,
5427 CORBA::Long FirstNodeID2,
5428 CORBA::Long SecondNodeID2,
5429 CORBA::Long LastNodeID2,
5430 CORBA::Boolean CreatePolygons,
5431 CORBA::Boolean CreatePolyedrs)
5432 throw (SALOME::SALOME_Exception)
5437 SMESHDS_Mesh* aMesh = getMeshDS();
5439 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
5440 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
5441 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
5442 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
5443 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
5444 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
5446 if (!aBorderFirstNode ||
5447 !aBorderSecondNode||
5449 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5450 if (!aSide2FirstNode ||
5451 !aSide2SecondNode ||
5453 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
5455 TPythonDump() << "error = " << this << ".SewFreeBorders( "
5456 << FirstNodeID1 << ", "
5457 << SecondNodeID1 << ", "
5458 << LastNodeID1 << ", "
5459 << FirstNodeID2 << ", "
5460 << SecondNodeID2 << ", "
5461 << LastNodeID2 << ", "
5462 << CreatePolygons<< ", "
5463 << CreatePolyedrs<< " )";
5465 SMESH::SMESH_MeshEditor::Sew_Error error =
5466 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5477 declareMeshModified( /*isReComputeSafe=*/false );
5480 SMESH_CATCH( SMESH::throwCorbaException );
5481 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5485 //=======================================================================
5486 //function : SewConformFreeBorders
5488 //=======================================================================
5490 SMESH::SMESH_MeshEditor::Sew_Error
5491 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
5492 CORBA::Long SecondNodeID1,
5493 CORBA::Long LastNodeID1,
5494 CORBA::Long FirstNodeID2,
5495 CORBA::Long SecondNodeID2)
5496 throw (SALOME::SALOME_Exception)
5501 SMESHDS_Mesh* aMesh = getMeshDS();
5503 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
5504 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
5505 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
5506 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
5507 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
5508 const SMDS_MeshNode* aSide2ThirdNode = 0;
5510 if (!aBorderFirstNode ||
5511 !aBorderSecondNode||
5513 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5514 if (!aSide2FirstNode ||
5516 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
5518 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
5519 << FirstNodeID1 << ", "
5520 << SecondNodeID1 << ", "
5521 << LastNodeID1 << ", "
5522 << FirstNodeID2 << ", "
5523 << SecondNodeID2 << " )";
5525 SMESH::SMESH_MeshEditor::Sew_Error error =
5526 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5535 declareMeshModified( /*isReComputeSafe=*/false );
5538 SMESH_CATCH( SMESH::throwCorbaException );
5539 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5543 //=======================================================================
5544 //function : SewBorderToSide
5546 //=======================================================================
5548 SMESH::SMESH_MeshEditor::Sew_Error
5549 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
5550 CORBA::Long SecondNodeIDOnFreeBorder,
5551 CORBA::Long LastNodeIDOnFreeBorder,
5552 CORBA::Long FirstNodeIDOnSide,
5553 CORBA::Long LastNodeIDOnSide,
5554 CORBA::Boolean CreatePolygons,
5555 CORBA::Boolean CreatePolyedrs)
5556 throw (SALOME::SALOME_Exception)
5561 SMESHDS_Mesh* aMesh = getMeshDS();
5563 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
5564 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
5565 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
5566 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
5567 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
5568 const SMDS_MeshNode* aSide2ThirdNode = 0;
5570 if (!aBorderFirstNode ||
5571 !aBorderSecondNode||
5573 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5574 if (!aSide2FirstNode ||
5576 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
5578 TPythonDump() << "error = " << this << ".SewBorderToSide( "
5579 << FirstNodeIDOnFreeBorder << ", "
5580 << SecondNodeIDOnFreeBorder << ", "
5581 << LastNodeIDOnFreeBorder << ", "
5582 << FirstNodeIDOnSide << ", "
5583 << LastNodeIDOnSide << ", "
5584 << CreatePolygons << ", "
5585 << CreatePolyedrs << ") ";
5587 SMESH::SMESH_MeshEditor::Sew_Error error =
5588 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5598 declareMeshModified( /*isReComputeSafe=*/false );
5601 SMESH_CATCH( SMESH::throwCorbaException );
5602 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5606 //=======================================================================
5607 //function : SewSideElements
5609 //=======================================================================
5611 SMESH::SMESH_MeshEditor::Sew_Error
5612 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
5613 const SMESH::long_array& IDsOfSide2Elements,
5614 CORBA::Long NodeID1OfSide1ToMerge,
5615 CORBA::Long NodeID1OfSide2ToMerge,
5616 CORBA::Long NodeID2OfSide1ToMerge,
5617 CORBA::Long NodeID2OfSide2ToMerge)
5618 throw (SALOME::SALOME_Exception)
5623 SMESHDS_Mesh* aMesh = getMeshDS();
5625 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
5626 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
5627 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
5628 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
5630 if (!aFirstNode1ToMerge ||
5631 !aFirstNode2ToMerge )
5632 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
5633 if (!aSecondNode1ToMerge||
5634 !aSecondNode2ToMerge)
5635 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
5637 TIDSortedElemSet aSide1Elems, aSide2Elems;
5638 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
5639 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
5641 TPythonDump() << "error = " << this << ".SewSideElements( "
5642 << IDsOfSide1Elements << ", "
5643 << IDsOfSide2Elements << ", "
5644 << NodeID1OfSide1ToMerge << ", "
5645 << NodeID1OfSide2ToMerge << ", "
5646 << NodeID2OfSide1ToMerge << ", "
5647 << NodeID2OfSide2ToMerge << ")";
5649 SMESH::SMESH_MeshEditor::Sew_Error error =
5650 convError( getEditor().SewSideElements (aSide1Elems, aSide2Elems,
5653 aSecondNode1ToMerge,
5654 aSecondNode2ToMerge));
5656 declareMeshModified( /*isReComputeSafe=*/false );
5659 SMESH_CATCH( SMESH::throwCorbaException );
5660 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5663 //================================================================================
5665 * \brief Set new nodes for given element
5666 * \param ide - element id
5667 * \param newIDs - new node ids
5668 * \retval CORBA::Boolean - true if result is OK
5670 //================================================================================
5672 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
5673 const SMESH::long_array& newIDs)
5674 throw (SALOME::SALOME_Exception)
5679 const SMDS_MeshElement* elem = getMeshDS()->FindElement(ide);
5680 if(!elem) return false;
5682 int nbn = newIDs.length();
5684 vector<const SMDS_MeshNode*> aNodes(nbn);
5687 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(newIDs[i]);
5690 aNodes[nbn1] = aNode;
5693 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
5694 << ide << ", " << newIDs << " )";
5696 MESSAGE("ChangeElementNodes");
5697 bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
5699 declareMeshModified( /*isReComputeSafe=*/ !res );
5703 SMESH_CATCH( SMESH::throwCorbaException );
5707 //=======================================================================
5709 * \brief Makes a part of the mesh quadratic or bi-quadratic
5711 //=======================================================================
5713 void SMESH_MeshEditor_i::convertToQuadratic(CORBA::Boolean theForce3d,
5714 CORBA::Boolean theToBiQuad,
5715 SMESH::SMESH_IDSource_ptr theObject)
5716 throw (SALOME::SALOME_Exception)
5719 TIDSortedElemSet elems;
5721 if ( !( elemsOK = CORBA::is_nil( theObject )))
5723 prepareIdSource( theObject );
5724 elemsOK = idSourceToSet( theObject, getMeshDS(), elems,
5725 SMDSAbs_All, /*emptyIfIsMesh=*/true );
5729 if ( !elems.empty() && (*elems.begin())->GetType() == SMDSAbs_Node )
5730 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5732 if ( elems.empty() ) getEditor().ConvertToQuadratic(theForce3d, theToBiQuad);
5733 else getEditor().ConvertToQuadratic(theForce3d, elems, theToBiQuad);
5735 declareMeshModified( /*isReComputeSafe=*/false );
5738 SMESH_CATCH( SMESH::throwCorbaException );
5741 //=======================================================================
5742 //function : ConvertFromQuadratic
5744 //=======================================================================
5746 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
5747 throw (SALOME::SALOME_Exception)
5749 CORBA::Boolean isDone = getEditor().ConvertFromQuadratic();
5750 TPythonDump() << this << ".ConvertFromQuadratic()";
5751 declareMeshModified( /*isReComputeSafe=*/!isDone );
5755 //=======================================================================
5756 //function : ConvertToQuadratic
5758 //=======================================================================
5760 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
5761 throw (SALOME::SALOME_Exception)
5763 convertToQuadratic( theForce3d, false );
5764 TPythonDump() << this << ".ConvertToQuadratic("<<theForce3d<<")";
5767 //================================================================================
5769 * \brief Makes a part of the mesh quadratic
5771 //================================================================================
5773 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
5774 SMESH::SMESH_IDSource_ptr theObject)
5775 throw (SALOME::SALOME_Exception)
5777 convertToQuadratic( theForce3d, false, theObject );
5778 TPythonDump() << this << ".ConvertToQuadraticObject("<<theForce3d<<", "<<theObject<<")";
5781 //================================================================================
5783 * \brief Makes a part of the mesh bi-quadratic
5785 //================================================================================
5787 void SMESH_MeshEditor_i::ConvertToBiQuadratic(CORBA::Boolean theForce3d,
5788 SMESH::SMESH_IDSource_ptr theObject)
5789 throw (SALOME::SALOME_Exception)
5791 convertToQuadratic( theForce3d, true, theObject );
5792 TPythonDump() << this << ".ConvertToBiQuadratic("<<theForce3d<<", "<<theObject<<")";
5795 //================================================================================
5797 * \brief Makes a part of the mesh linear
5799 //================================================================================
5801 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
5802 throw (SALOME::SALOME_Exception)
5808 TIDSortedElemSet elems;
5809 prepareIdSource( theObject );
5810 if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5812 if ( elems.empty() )
5814 ConvertFromQuadratic();
5816 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5818 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5822 getEditor().ConvertFromQuadratic(elems);
5825 declareMeshModified( /*isReComputeSafe=*/false );
5827 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
5829 SMESH_CATCH( SMESH::throwCorbaException );
5832 //=======================================================================
5833 //function : makeMesh
5834 //purpose : create a named imported mesh
5835 //=======================================================================
5837 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
5839 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
5840 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
5841 SALOMEDS::Study_var study = gen->GetCurrentStudy();
5842 SALOMEDS::SObject_wrap meshSO = gen->ObjectToSObject( study, mesh );
5843 gen->SetName( meshSO, theMeshName, "Mesh" );
5844 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
5846 return mesh._retn();
5849 //=======================================================================
5850 //function : dumpGroupsList
5852 //=======================================================================
5854 void SMESH_MeshEditor_i::dumpGroupsList(TPythonDump & theDumpPython,
5855 const SMESH::ListOfGroups * theGroupList)
5857 bool isDumpGroupList = ( theGroupList && theGroupList->length() > 0 );
5858 if ( isDumpGroupList )
5859 theDumpPython << theGroupList << " = ";
5862 //================================================================================
5864 \brief Generates the unique group name.
5865 \param thePrefix name prefix
5868 //================================================================================
5870 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
5872 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5873 set<string> groupNames;
5875 // Get existing group names
5876 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
5877 SMESH::SMESH_GroupBase_var aGroup = groups[i];
5878 if (CORBA::is_nil(aGroup))
5881 CORBA::String_var name = aGroup->GetName();
5882 groupNames.insert( name.in() );
5886 string name = thePrefix;
5889 while (!groupNames.insert(name).second)
5890 name = SMESH_Comment( thePrefix ) << "_" << index++;
5895 //================================================================================
5897 * \brief Prepare SMESH_IDSource for work
5899 //================================================================================
5901 void SMESH_MeshEditor_i::prepareIdSource(SMESH::SMESH_IDSource_ptr theObject)
5903 if ( SMESH::Filter_i* filter = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5905 SMESH::SMESH_Mesh_var mesh = myMesh_i->_this();
5906 filter->SetMesh( mesh );
5910 //================================================================================
5912 * \brief Duplicates given elements, i.e. creates new elements based on the
5913 * same nodes as the given ones.
5914 * \param theElements - container of elements to duplicate.
5915 * \param theGroupName - a name of group to contain the generated elements.
5916 * If a group with such a name already exists, the new elements
5917 * are added to the existng group, else a new group is created.
5918 * If \a theGroupName is empty, new elements are not added
5920 * \return a group where the new elements are added. NULL if theGroupName == "".
5923 //================================================================================
5925 SMESH::SMESH_Group_ptr
5926 SMESH_MeshEditor_i::DoubleElements(SMESH::SMESH_IDSource_ptr theElements,
5927 const char* theGroupName)
5928 throw (SALOME::SALOME_Exception)
5930 SMESH::SMESH_Group_var newGroup;
5937 TIDSortedElemSet elems;
5938 prepareIdSource( theElements );
5939 if ( idSourceToSet( theElements, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true))
5941 getEditor().DoubleElements( elems );
5943 if ( strlen( theGroupName ) && !getEditor().GetLastCreatedElems().IsEmpty() )
5946 SMESH::ElementType type =
5947 SMESH::ElementType( getEditor().GetLastCreatedElems().Value(1)->GetType() );
5948 // find existing group
5949 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5950 for ( size_t i = 0; i < groups->length(); ++i )
5951 if ( groups[i]->GetType() == type )
5953 CORBA::String_var name = groups[i]->GetName();
5954 if ( strcmp( name, theGroupName ) == 0 ) {
5955 newGroup = SMESH::SMESH_Group::_narrow( groups[i] );
5959 // create a new group
5960 if ( newGroup->_is_nil() )
5961 newGroup = myMesh_i->CreateGroup( type, theGroupName );
5963 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* >( newGroup ))
5965 SMESHDS_Group* groupDS = static_cast< SMESHDS_Group* >( group_i->GetGroupDS() );
5966 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
5967 for ( int i = 1; i <= aSeq.Length(); i++ )
5968 groupDS->SMDSGroup().Add( aSeq(i) );
5973 if ( !newGroup->_is_nil() )
5974 pyDump << newGroup << " = ";
5975 pyDump << this << ".DoubleElements( "
5976 << theElements << ", " << "'" << theGroupName <<"')";
5978 SMESH_CATCH( SMESH::throwCorbaException );
5980 return newGroup._retn();
5983 //================================================================================
5985 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5986 \param theNodes - identifiers of nodes to be doubled
5987 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
5988 nodes. If list of element identifiers is empty then nodes are doubled but
5989 they not assigned to elements
5990 \return TRUE if operation has been completed successfully, FALSE otherwise
5991 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
5993 //================================================================================
5995 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
5996 const SMESH::long_array& theModifiedElems )
5997 throw (SALOME::SALOME_Exception)
6002 list< int > aListOfNodes;
6004 for ( i = 0, n = theNodes.length(); i < n; i++ )
6005 aListOfNodes.push_back( theNodes[ i ] );
6007 list< int > aListOfElems;
6008 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
6009 aListOfElems.push_back( theModifiedElems[ i ] );
6011 bool aResult = getEditor().DoubleNodes( aListOfNodes, aListOfElems );
6013 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6015 // Update Python script
6016 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
6020 SMESH_CATCH( SMESH::throwCorbaException );
6024 //================================================================================
6026 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6027 This method provided for convenience works as DoubleNodes() described above.
6028 \param theNodeId - identifier of node to be doubled.
6029 \param theModifiedElems - identifiers of elements to be updated.
6030 \return TRUE if operation has been completed successfully, FALSE otherwise
6031 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
6033 //================================================================================
6035 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
6036 const SMESH::long_array& theModifiedElems )
6037 throw (SALOME::SALOME_Exception)
6040 SMESH::long_array_var aNodes = new SMESH::long_array;
6041 aNodes->length( 1 );
6042 aNodes[ 0 ] = theNodeId;
6044 TPythonDump pyDump; // suppress dump by the next line
6046 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
6048 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
6052 SMESH_CATCH( SMESH::throwCorbaException );
6056 //================================================================================
6058 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6059 This method provided for convenience works as DoubleNodes() described above.
6060 \param theNodes - group of nodes to be doubled.
6061 \param theModifiedElems - group of elements to be updated.
6062 \return TRUE if operation has been completed successfully, FALSE otherwise
6063 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
6065 //================================================================================
6067 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
6068 SMESH::SMESH_GroupBase_ptr theModifiedElems )
6069 throw (SALOME::SALOME_Exception)
6072 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
6075 SMESH::long_array_var aNodes = theNodes->GetListOfID();
6076 SMESH::long_array_var aModifiedElems;
6077 if ( !CORBA::is_nil( theModifiedElems ) )
6078 aModifiedElems = theModifiedElems->GetListOfID();
6081 aModifiedElems = new SMESH::long_array;
6082 aModifiedElems->length( 0 );
6085 TPythonDump pyDump; // suppress dump by the next line
6087 bool done = DoubleNodes( aNodes, aModifiedElems );
6089 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
6093 SMESH_CATCH( SMESH::throwCorbaException );
6097 //================================================================================
6099 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6100 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
6101 * \param theNodes - group of nodes to be doubled.
6102 * \param theModifiedElems - group of elements to be updated.
6103 * \return a new group with newly created nodes
6104 * \sa DoubleNodeGroup()
6106 //================================================================================
6108 SMESH::SMESH_Group_ptr
6109 SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
6110 SMESH::SMESH_GroupBase_ptr theModifiedElems )
6111 throw (SALOME::SALOME_Exception)
6114 SMESH::SMESH_Group_var aNewGroup;
6116 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
6117 return aNewGroup._retn();
6120 SMESH::long_array_var aNodes = theNodes->GetListOfID();
6121 SMESH::long_array_var aModifiedElems;
6122 if ( !CORBA::is_nil( theModifiedElems ) )
6123 aModifiedElems = theModifiedElems->GetListOfID();
6125 aModifiedElems = new SMESH::long_array;
6126 aModifiedElems->length( 0 );
6129 TPythonDump pyDump; // suppress dump by the next line
6131 bool aResult = DoubleNodes( aNodes, aModifiedElems );
6134 // Create group with newly created nodes
6135 SMESH::long_array_var anIds = GetLastCreatedNodes();
6136 if (anIds->length() > 0) {
6137 string anUnindexedName (theNodes->GetName());
6138 string aNewName = generateGroupName(anUnindexedName + "_double");
6139 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6140 aNewGroup->Add(anIds);
6141 pyDump << aNewGroup << " = ";
6145 pyDump << this << ".DoubleNodeGroupNew( " << theNodes << ", "
6146 << theModifiedElems << " )";
6148 return aNewGroup._retn();
6150 SMESH_CATCH( SMESH::throwCorbaException );
6154 //================================================================================
6156 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6157 This method provided for convenience works as DoubleNodes() described above.
6158 \param theNodes - list of groups of nodes to be doubled
6159 \param theModifiedElems - list of groups of elements to be updated.
6160 \return TRUE if operation has been completed successfully, FALSE otherwise
6161 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
6163 //================================================================================
6165 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
6166 const SMESH::ListOfGroups& theModifiedElems )
6167 throw (SALOME::SALOME_Exception)
6172 std::list< int > aNodes;
6174 for ( i = 0, n = theNodes.length(); i < n; i++ )
6176 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
6177 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
6179 SMESH::long_array_var aCurr = aGrp->GetListOfID();
6180 for ( j = 0, m = aCurr->length(); j < m; j++ )
6181 aNodes.push_back( aCurr[ j ] );
6185 std::list< int > anElems;
6186 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
6188 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
6189 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
6191 SMESH::long_array_var aCurr = aGrp->GetListOfID();
6192 for ( j = 0, m = aCurr->length(); j < m; j++ )
6193 anElems.push_back( aCurr[ j ] );
6197 bool aResult = getEditor().DoubleNodes( aNodes, anElems );
6199 declareMeshModified( /*isReComputeSafe=*/false );
6201 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
6205 SMESH_CATCH( SMESH::throwCorbaException );
6209 //================================================================================
6211 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6212 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
6213 * \param theNodes - group of nodes to be doubled.
6214 * \param theModifiedElems - group of elements to be updated.
6215 * \return a new group with newly created nodes
6216 * \sa DoubleNodeGroups()
6218 //================================================================================
6220 SMESH::SMESH_Group_ptr
6221 SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
6222 const SMESH::ListOfGroups& theModifiedElems )
6223 throw (SALOME::SALOME_Exception)
6225 SMESH::SMESH_Group_var aNewGroup;
6227 TPythonDump pyDump; // suppress dump by the next line
6229 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
6233 // Create group with newly created nodes
6234 SMESH::long_array_var anIds = GetLastCreatedNodes();
6235 if (anIds->length() > 0) {
6236 string anUnindexedName (theNodes[0]->GetName());
6237 string aNewName = generateGroupName(anUnindexedName + "_double");
6238 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6239 aNewGroup->Add(anIds);
6240 pyDump << aNewGroup << " = ";
6244 pyDump << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
6245 << theModifiedElems << " )";
6247 return aNewGroup._retn();
6251 //================================================================================
6253 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6254 \param theElems - the list of elements (edges or faces) to be replicated
6255 The nodes for duplication could be found from these elements
6256 \param theNodesNot - list of nodes to NOT replicate
6257 \param theAffectedElems - the list of elements (cells and edges) to which the
6258 replicated nodes should be associated to.
6259 \return TRUE if operation has been completed successfully, FALSE otherwise
6260 \sa DoubleNodeGroup(), DoubleNodeGroups()
6262 //================================================================================
6264 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
6265 const SMESH::long_array& theNodesNot,
6266 const SMESH::long_array& theAffectedElems )
6267 throw (SALOME::SALOME_Exception)
6272 SMESHDS_Mesh* aMeshDS = getMeshDS();
6273 TIDSortedElemSet anElems, aNodes, anAffected;
6274 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
6275 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
6276 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
6278 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6280 // Update Python script
6281 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
6282 << theNodesNot << ", " << theAffectedElems << " )";
6284 declareMeshModified( /*isReComputeSafe=*/false );
6287 SMESH_CATCH( SMESH::throwCorbaException );
6291 //================================================================================
6293 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6294 \param theElems - the list of elements (edges or faces) to be replicated
6295 The nodes for duplication could be found from these elements
6296 \param theNodesNot - list of nodes to NOT replicate
6297 \param theShape - shape to detect affected elements (element which geometric center
6298 located on or inside shape).
6299 The replicated nodes should be associated to affected elements.
6300 \return TRUE if operation has been completed successfully, FALSE otherwise
6301 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
6303 //================================================================================
6305 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
6306 const SMESH::long_array& theNodesNot,
6307 GEOM::GEOM_Object_ptr theShape )
6308 throw (SALOME::SALOME_Exception)
6314 SMESHDS_Mesh* aMeshDS = getMeshDS();
6315 TIDSortedElemSet anElems, aNodes;
6316 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
6317 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
6319 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6320 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6322 // Update Python script
6323 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
6324 << theNodesNot << ", " << theShape << " )";
6326 declareMeshModified( /*isReComputeSafe=*/false );
6329 SMESH_CATCH( SMESH::throwCorbaException );
6333 //================================================================================
6335 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6336 \param theElems - group of of elements (edges or faces) to be replicated
6337 \param theNodesNot - group of nodes not to replicated
6338 \param theAffectedElems - group of elements to which the replicated nodes
6339 should be associated to.
6340 \return TRUE if operation has been completed successfully, FALSE otherwise
6341 \sa DoubleNodes(), DoubleNodeGroups()
6343 //================================================================================
6346 SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
6347 SMESH::SMESH_GroupBase_ptr theNodesNot,
6348 SMESH::SMESH_GroupBase_ptr theAffectedElems)
6349 throw (SALOME::SALOME_Exception)
6352 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6358 SMESHDS_Mesh* aMeshDS = getMeshDS();
6359 TIDSortedElemSet anElems, aNodes, anAffected;
6360 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6361 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6362 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
6364 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6366 // Update Python script
6367 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
6368 << theNodesNot << ", " << theAffectedElems << " )";
6370 declareMeshModified( /*isReComputeSafe=*/false );
6373 SMESH_CATCH( SMESH::throwCorbaException );
6377 //================================================================================
6379 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6380 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
6381 * \param theElems - group of of elements (edges or faces) to be replicated
6382 * \param theNodesNot - group of nodes not to replicated
6383 * \param theAffectedElems - group of elements to which the replicated nodes
6384 * should be associated to.
6385 * \return a new group with newly created elements
6386 * \sa DoubleNodeElemGroup()
6388 //================================================================================
6390 SMESH::SMESH_Group_ptr
6391 SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
6392 SMESH::SMESH_GroupBase_ptr theNodesNot,
6393 SMESH::SMESH_GroupBase_ptr theAffectedElems)
6394 throw (SALOME::SALOME_Exception)
6397 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroup2New( theElems,
6401 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
6402 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
6404 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupNew( "
6406 << theNodesNot << ", "
6407 << theAffectedElems << " )";
6409 return elemGroup._retn();
6412 //================================================================================
6414 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6415 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
6416 * \param theElems - group of of elements (edges or faces) to be replicated
6417 * \param theNodesNot - group of nodes not to replicated
6418 * \param theAffectedElems - group of elements to which the replicated nodes
6419 * should be associated to.
6420 * \return a new group with newly created elements
6421 * \sa DoubleNodeElemGroup()
6423 //================================================================================
6425 SMESH::ListOfGroups*
6426 SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
6427 SMESH::SMESH_GroupBase_ptr theNodesNot,
6428 SMESH::SMESH_GroupBase_ptr theAffectedElems,
6429 CORBA::Boolean theElemGroupNeeded,
6430 CORBA::Boolean theNodeGroupNeeded)
6431 throw (SALOME::SALOME_Exception)
6434 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
6435 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
6436 aTwoGroups->length( 2 );
6438 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6439 return aTwoGroups._retn();
6444 SMESHDS_Mesh* aMeshDS = getMeshDS();
6445 TIDSortedElemSet anElems, aNodes, anAffected;
6446 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6447 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6448 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
6451 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6453 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6459 // Create group with newly created elements
6460 CORBA::String_var elemGroupName = theElems->GetName();
6461 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
6462 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
6464 SMESH::long_array_var anIds = GetLastCreatedElems();
6465 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
6466 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
6467 aNewElemGroup->Add(anIds);
6469 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
6471 SMESH::long_array_var anIds = GetLastCreatedNodes();
6472 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6473 aNewNodeGroup->Add(anIds);
6477 // Update Python script
6480 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
6481 else pyDump << aNewElemGroup << ", ";
6482 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
6483 else pyDump << aNewNodeGroup << " ] = ";
6485 pyDump << this << ".DoubleNodeElemGroup2New( " << theElems << ", "
6486 << theNodesNot << ", "
6487 << theAffectedElems << ", "
6488 << theElemGroupNeeded << ", "
6489 << theNodeGroupNeeded <<" )";
6491 aTwoGroups[0] = aNewElemGroup._retn();
6492 aTwoGroups[1] = aNewNodeGroup._retn();
6493 return aTwoGroups._retn();
6495 SMESH_CATCH( SMESH::throwCorbaException );
6499 //================================================================================
6501 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6502 \param theElems - group of of elements (edges or faces) to be replicated
6503 \param theNodesNot - group of nodes not to replicated
6504 \param theShape - shape to detect affected elements (element which geometric center
6505 located on or inside shape).
6506 The replicated nodes should be associated to affected elements.
6507 \return TRUE if operation has been completed successfully, FALSE otherwise
6508 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
6510 //================================================================================
6513 SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
6514 SMESH::SMESH_GroupBase_ptr theNodesNot,
6515 GEOM::GEOM_Object_ptr theShape )
6516 throw (SALOME::SALOME_Exception)
6519 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6525 SMESHDS_Mesh* aMeshDS = getMeshDS();
6526 TIDSortedElemSet anElems, aNodes, anAffected;
6527 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6528 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6530 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6531 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6534 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6536 // Update Python script
6537 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
6538 << theNodesNot << ", " << theShape << " )";
6541 SMESH_CATCH( SMESH::throwCorbaException );
6545 //================================================================================
6547 * \brief Re-load elements from a list of groups into a TIDSortedElemSet
6548 * \param [in] theGrpList - groups
6549 * \param [in] theMeshDS - mesh
6550 * \param [out] theElemSet - set of elements
6551 * \param [in] theIsNodeGrp - is \a theGrpList includes goups of nodes
6553 //================================================================================
6555 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
6556 SMESHDS_Mesh* theMeshDS,
6557 TIDSortedElemSet& theElemSet,
6558 const bool theIsNodeGrp)
6560 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
6562 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
6563 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
6564 : aGrp->GetType() != SMESH::NODE ) )
6566 SMESH::long_array_var anIDs = aGrp->GetIDs();
6567 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
6572 //================================================================================
6574 \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6575 This method provided for convenience works as DoubleNodes() described above.
6576 \param theElems - list of groups of elements (edges or faces) to be replicated
6577 \param theNodesNot - list of groups of nodes not to replicated
6578 \param theAffectedElems - group of elements to which the replicated nodes
6579 should be associated to.
6580 \return TRUE if operation has been completed successfully, FALSE otherwise
6581 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
6583 //================================================================================
6586 SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
6587 const SMESH::ListOfGroups& theNodesNot,
6588 const SMESH::ListOfGroups& theAffectedElems)
6589 throw (SALOME::SALOME_Exception)
6595 SMESHDS_Mesh* aMeshDS = getMeshDS();
6596 TIDSortedElemSet anElems, aNodes, anAffected;
6597 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6598 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6599 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6601 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6603 // Update Python script
6604 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
6605 << &theNodesNot << ", " << &theAffectedElems << " )";
6607 declareMeshModified( /*isReComputeSafe=*/false );
6610 SMESH_CATCH( SMESH::throwCorbaException );
6614 //================================================================================
6616 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6617 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6618 \param theElems - list of groups of elements (edges or faces) to be replicated
6619 \param theNodesNot - list of groups of nodes not to replicated
6620 \param theAffectedElems - group of elements to which the replicated nodes
6621 should be associated to.
6622 * \return a new group with newly created elements
6623 * \sa DoubleNodeElemGroups()
6625 //================================================================================
6627 SMESH::SMESH_Group_ptr
6628 SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
6629 const SMESH::ListOfGroups& theNodesNot,
6630 const SMESH::ListOfGroups& theAffectedElems)
6631 throw (SALOME::SALOME_Exception)
6634 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroups2New( theElems,
6638 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
6639 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
6641 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupsNew( "
6643 << theNodesNot << ", "
6644 << theAffectedElems << " )";
6646 return elemGroup._retn();
6649 //================================================================================
6651 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6652 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6653 \param theElems - list of groups of elements (edges or faces) to be replicated
6654 \param theNodesNot - list of groups of nodes not to replicated
6655 \param theAffectedElems - group of elements to which the replicated nodes
6656 should be associated to.
6657 * \return a new group with newly created elements
6658 * \sa DoubleNodeElemGroups()
6660 //================================================================================
6662 SMESH::ListOfGroups*
6663 SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems,
6664 const SMESH::ListOfGroups& theNodesNot,
6665 const SMESH::ListOfGroups& theAffectedElems,
6666 CORBA::Boolean theElemGroupNeeded,
6667 CORBA::Boolean theNodeGroupNeeded)
6668 throw (SALOME::SALOME_Exception)
6671 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
6672 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
6673 aTwoGroups->length( 2 );
6678 SMESHDS_Mesh* aMeshDS = getMeshDS();
6679 TIDSortedElemSet anElems, aNodes, anAffected;
6680 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6681 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6682 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6684 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6686 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6691 // Create group with newly created elements
6692 CORBA::String_var elemGroupName = theElems[0]->GetName();
6693 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
6694 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
6696 SMESH::long_array_var anIds = GetLastCreatedElems();
6697 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
6698 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
6699 aNewElemGroup->Add(anIds);
6701 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
6703 SMESH::long_array_var anIds = GetLastCreatedNodes();
6704 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6705 aNewNodeGroup->Add(anIds);
6709 // Update Python script
6712 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
6713 else pyDump << aNewElemGroup << ", ";
6714 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
6715 else pyDump << aNewNodeGroup << " ] = ";
6717 pyDump << this << ".DoubleNodeElemGroups2New( " << &theElems << ", "
6718 << &theNodesNot << ", "
6719 << &theAffectedElems << ", "
6720 << theElemGroupNeeded << ", "
6721 << theNodeGroupNeeded << " )";
6723 aTwoGroups[0] = aNewElemGroup._retn();
6724 aTwoGroups[1] = aNewNodeGroup._retn();
6725 return aTwoGroups._retn();
6727 SMESH_CATCH( SMESH::throwCorbaException );
6731 //================================================================================
6733 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6734 This method provided for convenience works as DoubleNodes() described above.
6735 \param theElems - list of groups of elements (edges or faces) to be replicated
6736 \param theNodesNot - list of groups of nodes not to replicated
6737 \param theShape - shape to detect affected elements (element which geometric center
6738 located on or inside shape).
6739 The replicated nodes should be associated to affected elements.
6740 \return TRUE if operation has been completed successfully, FALSE otherwise
6741 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
6743 //================================================================================
6746 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
6747 const SMESH::ListOfGroups& theNodesNot,
6748 GEOM::GEOM_Object_ptr theShape )
6749 throw (SALOME::SALOME_Exception)
6755 SMESHDS_Mesh* aMeshDS = getMeshDS();
6756 TIDSortedElemSet anElems, aNodes;
6757 listOfGroupToSet(theElems, aMeshDS, anElems,false );
6758 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6760 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6761 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6763 // Update Python script
6764 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
6765 << &theNodesNot << ", " << theShape << " )";
6767 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6770 SMESH_CATCH( SMESH::throwCorbaException );
6774 //================================================================================
6776 \brief Identify the elements that will be affected by node duplication (actual
6777 duplication is not performed.
6778 This method is the first step of DoubleNodeElemGroupsInRegion.
6779 \param theElems - list of groups of elements (edges or faces) to be replicated
6780 \param theNodesNot - list of groups of nodes not to replicated
6781 \param theShape - shape to detect affected elements (element which geometric center
6782 located on or inside shape).
6783 The replicated nodes should be associated to affected elements.
6784 \return groups of affected elements
6785 \sa DoubleNodeElemGroupsInRegion()
6787 //================================================================================
6788 SMESH::ListOfGroups*
6789 SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theElems,
6790 const SMESH::ListOfGroups& theNodesNot,
6791 GEOM::GEOM_Object_ptr theShape )
6792 throw (SALOME::SALOME_Exception)
6795 MESSAGE("AffectedElemGroupsInRegion");
6796 SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
6797 bool isEdgeGroup = false;
6798 bool isFaceGroup = false;
6799 bool isVolumeGroup = false;
6800 SMESH::SMESH_Group_var aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE, "affectedEdges");
6801 SMESH::SMESH_Group_var aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE, "affectedFaces");
6802 SMESH::SMESH_Group_var aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME, "affectedVolumes");
6806 ::SMESH_MeshEditor aMeshEditor(myMesh);
6808 SMESHDS_Mesh* aMeshDS = getMeshDS();
6809 TIDSortedElemSet anElems, aNodes;
6810 listOfGroupToSet(theElems, aMeshDS, anElems, false);
6811 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true);
6813 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape(theShape);
6814 TIDSortedElemSet anAffected;
6815 bool aResult = aMeshEditor.AffectedElemGroupsInRegion(anElems, aNodes, aShape, anAffected);
6818 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6823 int lg = anAffected.size();
6824 MESSAGE("lg="<< lg);
6825 SMESH::long_array_var volumeIds = new SMESH::long_array;
6826 volumeIds->length(lg);
6827 SMESH::long_array_var faceIds = new SMESH::long_array;
6828 faceIds->length(lg);
6829 SMESH::long_array_var edgeIds = new SMESH::long_array;
6830 edgeIds->length(lg);
6835 TIDSortedElemSet::const_iterator eIt = anAffected.begin();
6836 for (; eIt != anAffected.end(); ++eIt)
6838 const SMDS_MeshElement* anElem = *eIt;
6841 int elemId = anElem->GetID();
6842 if (myMesh->GetElementType(elemId, true) == SMDSAbs_Volume)
6843 volumeIds[ivol++] = elemId;
6844 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Face)
6845 faceIds[iface++] = elemId;
6846 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Edge)
6847 edgeIds[iedge++] = elemId;
6849 volumeIds->length(ivol);
6850 faceIds->length(iface);
6851 edgeIds->length(iedge);
6853 aNewVolumeGroup->Add(volumeIds);
6854 aNewFaceGroup->Add(faceIds);
6855 aNewEdgeGroup->Add(edgeIds);
6856 isVolumeGroup = (aNewVolumeGroup->Size() > 0);
6857 isFaceGroup = (aNewFaceGroup->Size() > 0);
6858 isEdgeGroup = (aNewEdgeGroup->Size() > 0);
6862 if (isEdgeGroup) nbGroups++;
6863 if (isFaceGroup) nbGroups++;
6864 if (isVolumeGroup) nbGroups++;
6865 aListOfGroups->length(nbGroups);
6868 if (isEdgeGroup) aListOfGroups[i++] = aNewEdgeGroup._retn();
6869 if (isFaceGroup) aListOfGroups[i++] = aNewFaceGroup._retn();
6870 if (isVolumeGroup) aListOfGroups[i++] = aNewVolumeGroup._retn();
6872 // Update Python script
6875 if (isEdgeGroup) pyDump << aNewEdgeGroup << ", ";
6876 if (isFaceGroup) pyDump << aNewFaceGroup << ", ";
6877 if (isVolumeGroup) pyDump << aNewVolumeGroup << ", ";
6879 pyDump << this << ".AffectedElemGroupsInRegion( "
6880 << &theElems << ", " << &theNodesNot << ", " << theShape << " )";
6882 return aListOfGroups._retn();
6884 SMESH_CATCH( SMESH::throwCorbaException );
6888 //================================================================================
6890 \brief Generated skin mesh (containing 2D cells) from 3D mesh
6891 The created 2D mesh elements based on nodes of free faces of boundary volumes
6892 \return TRUE if operation has been completed successfully, FALSE otherwise
6894 //================================================================================
6896 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
6897 throw (SALOME::SALOME_Exception)
6902 bool aResult = getEditor().Make2DMeshFrom3D();
6904 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
6906 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6909 SMESH_CATCH( SMESH::throwCorbaException );
6913 //================================================================================
6915 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
6916 * The list of groups must contain at least two groups. The groups have to be disjoint:
6917 * no common element into two different groups.
6918 * The nodes of the internal faces at the boundaries of the groups are doubled.
6919 * Optionally, the internal faces are replaced by flat elements.
6920 * Triangles are transformed into prisms, and quadrangles into hexahedrons.
6921 * The flat elements are stored in groups of volumes.
6922 * These groups are named according to the position of the group in the list:
6923 * 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.
6924 * 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.
6925 * All the flat elements are gathered into the group named "joints3D" (or "joints2D" in 2D situation).
6926 * The flat element of the multiple junctions between the simple junction are stored in a group named "jointsMultiples".
6927 * \param theDomains - list of groups of volumes
6928 * \param createJointElems - if TRUE, create the elements
6929 * \param onAllBoundaries - if TRUE, the nodes and elements are also created on
6930 * the boundary between \a theDomains and the rest mesh
6931 * \return TRUE if operation has been completed successfully, FALSE otherwise
6933 //================================================================================
6936 SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
6937 CORBA::Boolean createJointElems,
6938 CORBA::Boolean onAllBoundaries )
6939 throw (SALOME::SALOME_Exception)
6946 SMESHDS_Mesh* aMeshDS = getMeshDS();
6948 // MESSAGE("theDomains.length = "<<theDomains.length());
6949 if ( theDomains.length() <= 1 && !onAllBoundaries )
6950 THROW_SALOME_CORBA_EXCEPTION("At least 2 groups are required.", SALOME::BAD_PARAM);
6952 vector<TIDSortedElemSet> domains;
6953 domains.resize( theDomains.length() );
6955 for ( int i = 0, n = theDomains.length(); i < n; i++ )
6957 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
6958 if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
6960 // if ( aGrp->GetType() != SMESH::VOLUME )
6961 // THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
6962 SMESH::long_array_var anIDs = aGrp->GetIDs();
6963 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
6967 isOK = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems, onAllBoundaries );
6968 // TODO publish the groups of flat elements in study
6970 declareMeshModified( /*isReComputeSafe=*/ !isOK );
6972 // Update Python script
6973 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
6974 << ", " << createJointElems << ", " << onAllBoundaries << " )";
6976 SMESH_CATCH( SMESH::throwCorbaException );
6978 myMesh_i->CreateGroupServants(); // publish created groups if any
6983 //================================================================================
6985 * \brief Double nodes on some external faces and create flat elements.
6986 * Flat elements are mainly used by some types of mechanic calculations.
6988 * Each group of the list must be constituted of faces.
6989 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
6990 * @param theGroupsOfFaces - list of groups of faces
6991 * @return TRUE if operation has been completed successfully, FALSE otherwise
6993 //================================================================================
6996 SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
6997 throw (SALOME::SALOME_Exception)
7002 SMESHDS_Mesh* aMeshDS = getMeshDS();
7004 vector<TIDSortedElemSet> faceGroups;
7007 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
7009 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
7010 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
7012 TIDSortedElemSet faceGroup;
7014 faceGroups.push_back(faceGroup);
7015 SMESH::long_array_var anIDs = aGrp->GetIDs();
7016 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
7020 bool aResult = getEditor().CreateFlatElementsOnFacesGroups( faceGroups );
7021 // TODO publish the groups of flat elements in study
7023 declareMeshModified( /*isReComputeSafe=*/ !aResult );
7025 // Update Python script
7026 TPythonDump() << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
7029 SMESH_CATCH( SMESH::throwCorbaException );
7033 //================================================================================
7035 * \brief Identify all the elements around a geom shape, get the faces delimiting
7038 * Build groups of volume to remove, groups of faces to replace on the skin of the
7039 * object, groups of faces to remove inside the object, (idem edges).
7040 * Build ordered list of nodes at the border of each group of faces to replace
7041 * (to be used to build a geom subshape).
7043 //================================================================================
7045 void SMESH_MeshEditor_i::CreateHoleSkin(CORBA::Double radius,
7046 GEOM::GEOM_Object_ptr theShape,
7047 const char* groupName,
7048 const SMESH::double_array& theNodesCoords,
7049 SMESH::array_of_long_array_out GroupsOfNodes)
7050 throw (SALOME::SALOME_Exception)
7055 std::vector<std::vector<int> > aListOfListOfNodes;
7056 ::SMESH_MeshEditor aMeshEditor( myMesh );
7058 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
7059 if ( !theNodeSearcher )
7060 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
7062 vector<double> nodesCoords;
7063 for (int i = 0; i < theNodesCoords.length(); i++)
7065 nodesCoords.push_back( theNodesCoords[i] );
7068 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
7069 aMeshEditor.CreateHoleSkin(radius, aShape, theNodeSearcher, groupName,
7070 nodesCoords, aListOfListOfNodes);
7072 GroupsOfNodes = new SMESH::array_of_long_array;
7073 GroupsOfNodes->length( aListOfListOfNodes.size() );
7074 std::vector<std::vector<int> >::iterator llIt = aListOfListOfNodes.begin();
7075 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
7077 vector<int>& aListOfNodes = *llIt;
7078 vector<int>::iterator lIt = aListOfNodes.begin();;
7079 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
7080 aGroup.length( aListOfNodes.size() );
7081 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
7082 aGroup[ j ] = (*lIt);
7084 TPythonDump() << "lists_nodes = " << this << ".CreateHoleSkin( "
7087 << ", '" << groupName << "', "
7088 << theNodesCoords << " )";
7090 SMESH_CATCH( SMESH::throwCorbaException );
7093 // issue 20749 ===================================================================
7095 * \brief Creates missing boundary elements
7096 * \param elements - elements whose boundary is to be checked
7097 * \param dimension - defines type of boundary elements to create
7098 * \param groupName - a name of group to store created boundary elements in,
7099 * "" means not to create the group
7100 * \param meshName - a name of new mesh to store created boundary elements in,
7101 * "" means not to create the new mesh
7102 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
7103 * \param toCopyExistingBondary - if true, not only new but also pre-existing
7104 * boundary elements will be copied into the new mesh
7105 * \param group - returns the create group, if any
7106 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
7108 // ================================================================================
7110 SMESH::SMESH_Mesh_ptr
7111 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
7112 SMESH::Bnd_Dimension dim,
7113 const char* groupName,
7114 const char* meshName,
7115 CORBA::Boolean toCopyElements,
7116 CORBA::Boolean toCopyExistingBondary,
7117 SMESH::SMESH_Group_out group)
7118 throw (SALOME::SALOME_Exception)
7123 if ( dim > SMESH::BND_1DFROM2D )
7124 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
7126 SMESHDS_Mesh* aMeshDS = getMeshDS();
7128 SMESH::SMESH_Mesh_var mesh_var;
7129 SMESH::SMESH_Group_var group_var;
7133 TIDSortedElemSet elements;
7134 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
7135 prepareIdSource( idSource );
7136 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
7140 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
7141 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
7143 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
7145 // group of new boundary elements
7146 SMESH_Group* smesh_group = 0;
7147 if ( strlen(groupName) )
7149 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
7150 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
7151 smesh_group = group_i->GetSmeshGroup();
7155 getEditor().MakeBoundaryMesh( elements,
7156 ::SMESH_MeshEditor::Bnd_Dimension(dim),
7160 toCopyExistingBondary);
7163 smesh_mesh->GetMeshDS()->Modified();
7166 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
7168 // result of MakeBoundaryMesh() is a tuple (mesh, group)
7169 if ( mesh_var->_is_nil() )
7170 pyDump << myMesh_i->_this() << ", ";
7172 pyDump << mesh_var << ", ";
7173 if ( group_var->_is_nil() )
7174 pyDump << "_NoneGroup = "; // assignment to None is forbiden
7176 pyDump << group_var << " = ";
7177 pyDump << this << ".MakeBoundaryMesh( "
7179 << "SMESH." << dimName[int(dim)] << ", "
7180 << "'" << groupName << "', "
7181 << "'" << meshName<< "', "
7182 << toCopyElements << ", "
7183 << toCopyExistingBondary << ")";
7185 group = group_var._retn();
7186 return mesh_var._retn();
7188 SMESH_CATCH( SMESH::throwCorbaException );
7189 return SMESH::SMESH_Mesh::_nil();
7192 //================================================================================
7194 * \brief Creates missing boundary elements
7195 * \param dimension - defines type of boundary elements to create
7196 * \param groupName - a name of group to store all boundary elements in,
7197 * "" means not to create the group
7198 * \param meshName - a name of a new mesh, which is a copy of the initial
7199 * mesh + created boundary elements; "" means not to create the new mesh
7200 * \param toCopyAll - if true, the whole initial mesh will be copied into
7201 * the new mesh else only boundary elements will be copied into the new mesh
7202 * \param groups - optional groups of elements to make boundary around
7203 * \param mesh - returns the mesh where elements were added to
7204 * \param group - returns the created group, if any
7205 * \retval long - number of added boundary elements
7207 //================================================================================
7209 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
7210 const char* groupName,
7211 const char* meshName,
7212 CORBA::Boolean toCopyAll,
7213 const SMESH::ListOfIDSources& groups,
7214 SMESH::SMESH_Mesh_out mesh,
7215 SMESH::SMESH_Group_out group)
7216 throw (SALOME::SALOME_Exception)
7221 if ( dim > SMESH::BND_1DFROM2D )
7222 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
7224 // separate groups belonging to this and other mesh
7225 SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
7226 SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
7227 groupsOfThisMesh->length( groups.length() );
7228 groupsOfOtherMesh->length( groups.length() );
7229 int nbGroups = 0, nbGroupsOfOtherMesh = 0;
7230 for ( int i = 0; i < groups.length(); ++i )
7232 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
7233 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
7234 groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
7236 groupsOfThisMesh[ nbGroups++ ] = groups[i];
7237 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
7238 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
7240 groupsOfThisMesh->length( nbGroups );
7241 groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
7246 if ( nbGroupsOfOtherMesh > 0 )
7248 // process groups belonging to another mesh
7249 SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
7250 SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
7251 nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
7252 groupsOfOtherMesh, mesh, group );
7255 SMESH::SMESH_Mesh_var mesh_var;
7256 SMESH::SMESH_Group_var group_var;
7259 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
7260 const bool toCopyMesh = ( strlen( meshName ) > 0 );
7264 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
7266 /*toCopyGroups=*/false,
7267 /*toKeepIDs=*/true);
7269 mesh_var = makeMesh(meshName);
7271 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
7272 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
7275 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
7276 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
7278 // group of boundary elements
7279 SMESH_Group* smesh_group = 0;
7280 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
7281 if ( strlen(groupName) )
7283 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
7284 group_var = mesh_i->CreateGroup( groupType, groupName );
7285 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
7286 smesh_group = group_i->GetSmeshGroup();
7289 TIDSortedElemSet elements;
7291 if ( groups.length() > 0 )
7293 for ( int i = 0; i < nbGroups; ++i )
7296 if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
7298 SMESH::Bnd_Dimension bdim =
7299 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
7300 nbAdded += getEditor().MakeBoundaryMesh( elements,
7301 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
7304 /*toCopyElements=*/false,
7305 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
7306 /*toAddExistingBondary=*/true,
7307 /*aroundElements=*/true);
7313 nbAdded += getEditor().MakeBoundaryMesh( elements,
7314 ::SMESH_MeshEditor::Bnd_Dimension(dim),
7317 /*toCopyElements=*/false,
7318 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
7319 /*toAddExistingBondary=*/true);
7321 tgtMesh->GetMeshDS()->Modified();
7323 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
7325 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
7326 pyDump << "nbAdded, ";
7327 if ( mesh_var->_is_nil() )
7328 pyDump << myMesh_i->_this() << ", ";
7330 pyDump << mesh_var << ", ";
7331 if ( group_var->_is_nil() )
7332 pyDump << "_NoneGroup = "; // assignment to None is forbiden
7334 pyDump << group_var << " = ";
7335 pyDump << this << ".MakeBoundaryElements( "
7336 << "SMESH." << dimName[int(dim)] << ", "
7337 << "'" << groupName << "', "
7338 << "'" << meshName<< "', "
7339 << toCopyAll << ", "
7342 mesh = mesh_var._retn();
7343 group = group_var._retn();
7346 SMESH_CATCH( SMESH::throwCorbaException );