1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_MeshEditor_i.cxx
23 // Author : Nicolas REJNERI
30 // A macro used in SMESH_TryCatch.hxx,
31 // it re-raises a CORBA SALOME exception thrown by SMESH_MeshEditor_i and caught by SMESH_CATCH
32 #define SMY_OWN_CATCH \
33 catch ( SALOME::SALOME_Exception & e ) { throw e; }
35 #include "SMESH_MeshEditor_i.hxx"
37 #include "SMDS_EdgePosition.hxx"
38 #include "SMDS_ElemIterator.hxx"
39 #include "SMDS_FacePosition.hxx"
40 #include "SMDS_IteratorOnIterators.hxx"
41 #include "SMDS_LinearEdge.hxx"
42 #include "SMDS_Mesh0DElement.hxx"
43 #include "SMDS_MeshFace.hxx"
44 #include "SMDS_MeshVolume.hxx"
45 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
46 #include "SMDS_SetIterator.hxx"
47 #include "SMDS_VolumeTool.hxx"
48 #include "SMESHDS_Group.hxx"
49 #include "SMESHDS_GroupOnGeom.hxx"
50 #include "SMESH_ControlsDef.hxx"
51 #include "SMESH_Filter_i.hxx"
52 #include "SMESH_Gen_i.hxx"
53 #include "SMESH_Group.hxx"
54 #include "SMESH_Group_i.hxx"
55 #include "SMESH_MeshAlgos.hxx"
56 #include "SMESH_MeshPartDS.hxx"
57 #include "SMESH_MesherHelper.hxx"
58 #include "SMESH_PythonDump.hxx"
59 #include "SMESH_subMeshEventListener.hxx"
60 #include "SMESH_subMesh_i.hxx"
62 #include <utilities.h>
63 #include <Utils_ExceptHandlers.hxx>
64 #include <Utils_CorbaException.hxx>
65 #include <SALOMEDS_wrap.hxx>
66 #include <SALOME_GenericObj_i.hh>
68 #include <BRepAdaptor_Surface.hxx>
69 #include <BRep_Tool.hxx>
70 #include <TopExp_Explorer.hxx>
72 #include <TopoDS_Edge.hxx>
73 #include <TopoDS_Face.hxx>
78 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
82 #include <Standard_Failure.hxx>
85 #include <Standard_ErrorHandler.hxx>
91 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
93 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
96 using SMESH::TPythonDump;
99 namespace MeshEditor_I {
101 //=============================================================================
103 * \brief Mesh to apply modifications for preview purposes
105 //=============================================================================
107 struct TPreviewMesh: public SMESH_Mesh
109 SMDSAbs_ElementType myPreviewType; // type to show
111 TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
112 _isShapeToMesh = (_id =_studyId = 0);
113 _myMeshDS = new SMESHDS_Mesh( _id, true );
114 myPreviewType = previewElements;
117 virtual ~TPreviewMesh() { delete _myMeshDS; _myMeshDS = 0; }
118 //!< Copy a set of elements
119 void Copy(const TIDSortedElemSet & theElements,
120 TIDSortedElemSet& theCopyElements,
121 SMDSAbs_ElementType theSelectType = SMDSAbs_All,
122 SMDSAbs_ElementType theAvoidType = SMDSAbs_All)
124 // loop on theIDsOfElements
125 TIDSortedElemSet::const_iterator eIt = theElements.begin();
126 for ( ; eIt != theElements.end(); ++eIt )
128 const SMDS_MeshElement* anElem = *eIt;
129 if ( !anElem ) continue;
130 SMDSAbs_ElementType type = anElem->GetType();
131 if ( type == theAvoidType ||
132 ( theSelectType != SMDSAbs_All && type != theSelectType ))
134 const SMDS_MeshElement* anElemCopy;
135 if ( type == SMDSAbs_Node)
136 anElemCopy = Copy( cast2Node(anElem) );
138 anElemCopy = Copy( anElem );
140 theCopyElements.insert( theCopyElements.end(), anElemCopy );
144 SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
146 // copy element nodes
147 int anElemNbNodes = anElem->NbNodes();
148 vector< int > anElemNodesID( anElemNbNodes ) ;
149 SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
150 for ( int i = 0; itElemNodes->more(); i++)
152 const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
154 anElemNodesID[i] = anElemNode->GetID();
157 // creates a corresponding element on copied nodes
158 SMDS_MeshElement* anElemCopy = 0;
159 if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
161 const SMDS_VtkVolume* ph =
162 dynamic_cast<const SMDS_VtkVolume*> (anElem);
164 anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
165 (anElemNodesID, ph->GetQuantities(),anElem->GetID());
168 anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
175 SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
177 return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(),
178 anElemNode->GetID());
182 GetMeshDS()->ClearMesh();
184 };// struct TPreviewMesh
186 static SMESH_NodeSearcher * theNodeSearcher = 0;
187 static SMESH_ElementSearcher * theElementSearcher = 0;
189 //=============================================================================
191 * \brief Deleter of theNodeSearcher at any compute event occured
193 //=============================================================================
195 struct TSearchersDeleter : public SMESH_subMeshEventListener
198 string myMeshPartIOR;
200 TSearchersDeleter(): SMESH_subMeshEventListener( false, // won't be deleted by submesh
201 "SMESH_MeshEditor_i::TSearchersDeleter"),
203 //!< Delete theNodeSearcher
206 if ( theNodeSearcher ) delete theNodeSearcher; theNodeSearcher = 0;
207 if ( theElementSearcher ) delete theElementSearcher; theElementSearcher = 0;
209 typedef map < int, SMESH_subMesh * > TDependsOnMap;
210 //!< The meshod called by submesh: do my main job
211 void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
212 SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
214 if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
216 Unset( sm->GetFather() );
219 //!< set self on all submeshes and delete theNodeSearcher if other mesh is set
220 void Set(SMESH_Mesh* mesh, const string& meshPartIOR = string())
222 if ( myMesh != mesh || myMeshPartIOR != meshPartIOR)
229 myMeshPartIOR = meshPartIOR;
230 if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
231 const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
232 TDependsOnMap::const_iterator sm;
233 for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
234 sm->second->SetEventListener( this, 0, sm->second );
238 //!< delete self from all submeshes
239 void Unset(SMESH_Mesh* mesh)
241 if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
242 const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
243 TDependsOnMap::const_iterator sm;
244 for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
245 sm->second->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 )
282 SMDS_MeshElement::NonNullFilter filter1;
283 SMDS_MeshElement::TypeFilter filter2( aType );
284 SMDS_MeshElement::Filter & filter =
285 ( aType == SMDSAbs_All ) ? (SMDS_MeshElement::Filter&) filter1 : filter2;
287 if ( aType == SMDSAbs_Node )
288 for (int i=0; i<IDs.length(); i++) {
289 const SMDS_MeshElement * elem = aMesh->FindNode( IDs[i] );
291 aMap.insert( aMap.end(), elem );
294 for (int i=0; i<IDs.length(); i++) {
295 const SMDS_MeshElement * elem = aMesh->FindElement( IDs[i] );
297 aMap.insert( aMap.end(), elem );
300 //================================================================================
302 * \brief Retrieve elements of given type from SMESH_IDSource
304 //================================================================================
306 bool idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource,
307 const SMESHDS_Mesh* theMeshDS,
308 TIDSortedElemSet& theElemSet,
309 const SMDSAbs_ElementType theType,
310 const bool emptyIfIsMesh=false)
313 if ( CORBA::is_nil( theIDSource ) )
315 if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
318 SMESH::long_array_var anIDs = theIDSource->GetIDs();
319 if ( anIDs->length() == 0 )
321 SMESH::array_of_ElementType_var types = theIDSource->GetTypes();
322 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
324 if ( theType == SMDSAbs_All || theType == SMDSAbs_Node )
325 arrayToSet( anIDs, theMeshDS, theElemSet, SMDSAbs_Node );
331 arrayToSet( anIDs, theMeshDS, theElemSet, theType);
332 return bool(anIDs->length()) == bool(theElemSet.size());
336 //================================================================================
338 * \brief Retrieve nodes from SMESH_IDSource
340 //================================================================================
342 void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject,
343 const SMESHDS_Mesh* theMeshDS,
344 TIDSortedNodeSet& theNodeSet)
347 if ( CORBA::is_nil( theObject ) )
349 SMESH::array_of_ElementType_var types = theObject->GetTypes();
350 SMESH::long_array_var aElementsId = theObject->GetIDs();
351 if ( types->length() == 1 && types[0] == SMESH::NODE)
353 for(int i = 0; i < aElementsId->length(); i++)
354 if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] ))
355 theNodeSet.insert( theNodeSet.end(), n);
357 else if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
359 SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator();
360 while ( nIt->more( ))
361 if( const SMDS_MeshElement * elem = nIt->next() )
362 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
366 for(int i = 0; i < aElementsId->length(); i++)
367 if( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] ))
368 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
372 //================================================================================
374 * \brief Returns elements connected to the given elements
376 //================================================================================
378 void getElementsAround(const TIDSortedElemSet& theElements,
379 const SMESHDS_Mesh* theMeshDS,
380 TIDSortedElemSet& theElementsAround)
382 if ( theElements.empty() ) return;
384 SMDSAbs_ElementType elemType = (*theElements.begin())->GetType();
385 bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() );
387 theMeshDS->GetMeshInfo().NbElements( elemType ) == theElements.size() )
388 return; // all the elements are in theElements
391 elemType = SMDSAbs_All;
393 TIDSortedElemSet visitedNodes;
394 TIDSortedElemSet::const_iterator elemIt = theElements.begin();
395 for ( ; elemIt != theElements.end(); ++elemIt )
397 const SMDS_MeshElement* e = *elemIt;
398 int i = e->NbCornerNodes();
401 const SMDS_MeshNode* n = e->GetNode( i );
402 if ( visitedNodes.insert( n ).second )
404 SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
405 while ( invIt->more() )
407 const SMDS_MeshElement* elemAround = invIt->next();
408 if ( !theElements.count( elemAround ))
409 theElementsAround.insert( elemAround );
416 //================================================================================
418 * \brief Return a string used to detect change of mesh part on which theElementSearcher
419 * is going to be used
421 //================================================================================
423 string getPartIOR( SMESH::SMESH_IDSource_ptr theMeshPart, SMESH::ElementType type)
425 string partIOR = SMESH_Gen_i::GetORB()->object_to_string( theMeshPart );
426 if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( theMeshPart ))
427 // take into account passible group modification
428 partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() );
429 partIOR += SMESH_Comment( type );
433 } // namespace MeshEditor_I
435 using namespace MeshEditor_I;
437 //=============================================================================
441 //=============================================================================
443 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview):
445 myMesh( &theMesh->GetImpl() ),
447 myIsPreviewMode ( isPreview ),
453 //================================================================================
457 //================================================================================
459 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
461 //deleteAuxIDSources();
462 delete myPreviewMesh; myPreviewMesh = 0;
463 delete myPreviewEditor; myPreviewEditor = 0;
466 //================================================================================
468 * \brief Clear members
470 //================================================================================
472 void SMESH_MeshEditor_i::initData(bool deleteSearchers)
474 if ( myIsPreviewMode ) {
475 if ( myPreviewMesh ) myPreviewMesh->RemoveAll();
478 if ( deleteSearchers )
479 TSearchersDeleter::Delete();
481 getEditor().GetError().reset();
482 getEditor().CrearLastCreated();
485 //================================================================================
487 * \brief Increment mesh modif time and optionally record that the performed
488 * modification may influence futher mesh re-compute.
489 * \param [in] isReComputeSafe - true if the modification does not infulence
490 * futher mesh re-compute
492 //================================================================================
494 void SMESH_MeshEditor_i::declareMeshModified( bool isReComputeSafe )
496 myMesh->GetMeshDS()->Modified();
497 if ( !isReComputeSafe )
498 myMesh->SetIsModified( true );
501 //================================================================================
503 * \brief Return either myEditor or myPreviewEditor depending on myIsPreviewMode.
504 * WARNING: in preview mode call getPreviewMesh() before getEditor()!
506 //================================================================================
508 ::SMESH_MeshEditor& SMESH_MeshEditor_i::getEditor()
510 if ( myIsPreviewMode && !myPreviewEditor ) {
511 if ( !myPreviewMesh ) getPreviewMesh();
512 myPreviewEditor = new ::SMESH_MeshEditor( myPreviewMesh );
514 return myIsPreviewMode ? *myPreviewEditor : myEditor;
517 //================================================================================
519 * \brief Initialize and return myPreviewMesh
520 * \param previewElements - type of elements to show in preview
522 * WARNING: call it once par a method!
524 //================================================================================
526 TPreviewMesh * SMESH_MeshEditor_i::getPreviewMesh(SMDSAbs_ElementType previewElements)
528 if ( !myPreviewMesh || myPreviewMesh->myPreviewType != previewElements )
530 delete myPreviewEditor;
532 delete myPreviewMesh;
533 myPreviewMesh = new TPreviewMesh( previewElements );
535 myPreviewMesh->Clear();
536 return myPreviewMesh;
539 //================================================================================
541 * Return data of mesh edition preview
543 //================================================================================
545 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
546 throw (SALOME::SALOME_Exception)
549 const bool hasBadElems = ( getEditor().GetError() && getEditor().GetError()->HasBadElems() );
551 if ( myIsPreviewMode || hasBadElems ) { // --- MeshPreviewStruct filling ---
553 list<int> aNodesConnectivity;
554 typedef map<int, int> TNodesMap;
557 SMESHDS_Mesh* aMeshDS;
558 std::auto_ptr< SMESH_MeshPartDS > aMeshPartDS;
560 aMeshPartDS.reset( new SMESH_MeshPartDS( getEditor().GetError()->myBadElements ));
561 aMeshDS = aMeshPartDS.get();
564 aMeshDS = getEditor().GetMeshDS();
566 myPreviewData = new SMESH::MeshPreviewStruct();
567 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
570 SMDSAbs_ElementType previewType = SMDSAbs_All;
572 if (TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( getEditor().GetMesh() )) {
573 previewType = aPreviewMesh->myPreviewType;
574 switch ( previewType ) {
575 case SMDSAbs_Edge : break;
576 case SMDSAbs_Face : break;
577 case SMDSAbs_Volume: break;
579 if ( aMeshDS->GetMeshInfo().NbElements() == 0 ) previewType = SMDSAbs_Node;
583 myPreviewData->elementTypes.length( aMeshDS->GetMeshInfo().NbElements( previewType ));
585 SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator(previewType);
587 while ( itMeshElems->more() ) {
588 const SMDS_MeshElement* aMeshElem = itMeshElems->next();
589 SMDS_NodeIteratorPtr itElemNodes = aMeshElem->nodeIterator();
590 while ( itElemNodes->more() ) {
591 const SMDS_MeshNode* aMeshNode = itElemNodes->next();
592 int aNodeID = aMeshNode->GetID();
593 TNodesMap::iterator anIter = nodesMap.find(aNodeID);
594 if ( anIter == nodesMap.end() ) {
595 // filling the nodes coordinates
596 myPreviewData->nodesXYZ[j].x = aMeshNode->X();
597 myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
598 myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
599 anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
602 aNodesConnectivity.push_back(anIter->second);
605 // filling the elements types
606 SMDSAbs_ElementType aType = aMeshElem->GetType();
607 bool isPoly = aMeshElem->IsPoly();
608 myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
609 myPreviewData->elementTypes[i].isPoly = isPoly;
610 myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
613 myPreviewData->nodesXYZ.length( j );
615 // filling the elements connectivities
616 list<int>::iterator aConnIter = aNodesConnectivity.begin();
617 myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
618 for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
619 myPreviewData->elementConnectivities[i] = *aConnIter;
621 return myPreviewData._retn();
623 SMESH_CATCH( SMESH::throwCorbaException );
627 //================================================================================
629 * \brief Returns list of it's IDs of created nodes
630 * \retval SMESH::long_array* - list of node ID
632 //================================================================================
634 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
635 throw (SALOME::SALOME_Exception)
638 SMESH::long_array_var myLastCreatedNodes = new SMESH::long_array();
640 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedNodes();
641 myLastCreatedNodes->length( aSeq.Length() );
642 for (int i = 1; i <= aSeq.Length(); i++)
643 myLastCreatedNodes[i-1] = aSeq.Value(i)->GetID();
645 return myLastCreatedNodes._retn();
646 SMESH_CATCH( SMESH::throwCorbaException );
650 //================================================================================
652 * \brief Returns list of it's IDs of created elements
653 * \retval SMESH::long_array* - list of elements' ID
655 //================================================================================
657 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
658 throw (SALOME::SALOME_Exception)
661 SMESH::long_array_var myLastCreatedElems = new SMESH::long_array();
663 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
664 myLastCreatedElems->length( aSeq.Length() );
665 for ( int i = 1; i <= aSeq.Length(); i++ )
666 myLastCreatedElems[i-1] = aSeq.Value(i)->GetID();
668 return myLastCreatedElems._retn();
669 SMESH_CATCH( SMESH::throwCorbaException );
673 //=======================================================================
674 //function : ClearLastCreated
675 //purpose : Clears sequences of last created elements and nodes
676 //=======================================================================
678 void SMESH_MeshEditor_i::ClearLastCreated() throw (SALOME::SALOME_Exception)
681 getEditor().CrearLastCreated();
682 SMESH_CATCH( SMESH::throwCorbaException );
685 //=======================================================================
687 * Returns description of an error/warning occured during the last operation
688 * WARNING: ComputeError.code >= 100 and no corresponding enum in IDL API
690 //=======================================================================
692 SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError()
693 throw (SALOME::SALOME_Exception)
696 SMESH::ComputeError_var errOut = new SMESH::ComputeError;
697 SMESH_ComputeErrorPtr& errIn = getEditor().GetError();
698 if ( errIn && !errIn->IsOK() )
700 errOut->code = -( errIn->myName < 0 ? errIn->myName + 1: errIn->myName ); // -1 -> 0
701 errOut->comment = errIn->myComment.c_str();
702 errOut->subShapeID = -1;
703 errOut->hasBadMesh = !errIn->myBadElements.empty();
708 errOut->subShapeID = -1;
709 errOut->hasBadMesh = false;
712 return errOut._retn();
713 SMESH_CATCH( SMESH::throwCorbaException );
717 //=======================================================================
718 //function : MakeIDSource
719 //purpose : Wrap a sequence of ids in a SMESH_IDSource.
720 // Call UnRegister() as you fininsh using it!!
721 //=======================================================================
723 struct SMESH_MeshEditor_i::_IDSource : public virtual POA_SMESH::SMESH_IDSource,
724 public virtual SALOME::GenericObj_i
726 SMESH::long_array _ids;
727 SMESH::ElementType _type;
728 SMESH::SMESH_Mesh_ptr _mesh;
729 SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); }
730 SMESH::long_array* GetMeshInfo() { return 0; }
731 SMESH::long_array* GetNbElementsByType()
733 SMESH::long_array_var aRes = new SMESH::long_array();
734 aRes->length(SMESH::NB_ELEMENT_TYPES);
735 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
736 aRes[ i ] = ( i == _type ) ? _ids.length() : 0;
739 SMESH::SMESH_Mesh_ptr GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _mesh ); }
740 bool IsMeshInfoCorrect() { return true; }
741 SMESH::array_of_ElementType* GetTypes()
743 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
744 if ( _ids.length() > 0 ) {
748 return types._retn();
752 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
753 SMESH::ElementType type)
755 // if ( myAuxIDSources.size() > 10 ) {
756 // delete myAuxIDSources.front();
757 // myAuxIDSources.pop_front();
760 _IDSource* idSrc = new _IDSource;
761 idSrc->_mesh = myMesh_i->_this();
764 //myAuxIDSources.push_back( idSrc );
766 SMESH::SMESH_IDSource_var anIDSourceVar = idSrc->_this();
768 return anIDSourceVar._retn();
771 bool SMESH_MeshEditor_i::IsTemporaryIDSource( SMESH::SMESH_IDSource_ptr& idSource )
773 return SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource );
776 CORBA::Long* SMESH_MeshEditor_i::GetTemporaryIDs( SMESH::SMESH_IDSource_ptr& idSource,
779 if ( _IDSource* tmpIdSource = SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource ))
781 nbIds = (int) tmpIdSource->_ids.length();
782 return & tmpIdSource->_ids[0];
788 // void SMESH_MeshEditor_i::deleteAuxIDSources()
790 // std::list< _IDSource* >::iterator idSrcIt = myAuxIDSources.begin();
791 // for ( ; idSrcIt != myAuxIDSources.end(); ++idSrcIt )
793 // myAuxIDSources.clear();
796 //=============================================================================
800 //=============================================================================
803 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
804 throw (SALOME::SALOME_Exception)
811 for (int i = 0; i < IDsOfElements.length(); i++)
812 IdList.push_back( IDsOfElements[i] );
814 // Update Python script
815 TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
818 bool ret = getEditor().Remove( IdList, false );
820 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 ); // issue 0020693
823 SMESH_CATCH( SMESH::throwCorbaException );
827 //=============================================================================
831 //=============================================================================
833 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
834 throw (SALOME::SALOME_Exception)
840 for (int i = 0; i < IDsOfNodes.length(); i++)
841 IdList.push_back( IDsOfNodes[i] );
843 // Update Python script
844 TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
846 bool ret = getEditor().Remove( IdList, true );
848 declareMeshModified( /*isReComputeSafe=*/ !ret ); // issue 0020693
851 SMESH_CATCH( SMESH::throwCorbaException );
855 //=============================================================================
859 //=============================================================================
861 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
862 throw (SALOME::SALOME_Exception)
867 // Update Python script
868 TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
870 // Create filter to find all orphan nodes
871 SMESH::Controls::Filter::TIdSequence seq;
872 SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
873 SMESH::Controls::Filter::GetElementsId( getMeshDS(), predicate, seq );
875 // remove orphan nodes (if there are any)
877 for ( int i = 0; i < seq.size(); i++ )
878 IdList.push_back( seq[i] );
880 int nbNodesBefore = myMesh->NbNodes();
881 getEditor().Remove( IdList, true );
882 int nbNodesAfter = myMesh->NbNodes();
884 declareMeshModified( /*isReComputeSafe=*/ IdList.size() == 0 ); // issue 0020693
885 return nbNodesBefore - nbNodesAfter;
887 SMESH_CATCH( SMESH::throwCorbaException );
891 //=============================================================================
895 //=============================================================================
897 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,CORBA::Double y, CORBA::Double z)
898 throw (SALOME::SALOME_Exception)
903 const SMDS_MeshNode* N = getMeshDS()->AddNode(x, y, z);
905 // Update Python script
906 TPythonDump() << "nodeID = " << this << ".AddNode( "
907 << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )";
909 declareMeshModified( /*isReComputeSafe=*/false );
912 SMESH_CATCH( SMESH::throwCorbaException );
916 //=============================================================================
918 * Create 0D element on the given node.
920 //=============================================================================
922 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
923 throw (SALOME::SALOME_Exception)
928 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
929 SMDS_MeshElement* elem = getMeshDS()->Add0DElement(aNode);
931 // Update Python script
932 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
934 declareMeshModified( /*isReComputeSafe=*/false );
936 return elem ? elem->GetID() : 0;
938 SMESH_CATCH( SMESH::throwCorbaException );
942 //=============================================================================
944 * Create a ball element on the given node.
946 //=============================================================================
948 CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diameter)
949 throw (SALOME::SALOME_Exception)
954 if ( diameter < std::numeric_limits<double>::min() )
955 THROW_SALOME_CORBA_EXCEPTION("Invalid diameter", SALOME::BAD_PARAM);
957 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
958 SMDS_MeshElement* elem = getMeshDS()->AddBall(aNode, diameter);
960 // Update Python script
961 TPythonDump() << "ballElem = "
962 << this << ".AddBall( " << IDOfNode << ", " << diameter <<" )";
964 declareMeshModified( /*isReComputeSafe=*/false );
965 return elem ? elem->GetID() : 0;
967 SMESH_CATCH( SMESH::throwCorbaException );
971 //=============================================================================
973 * Create an edge, either linear and quadratic (this is determed
974 * by number of given nodes, two or three)
976 //=============================================================================
978 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
979 throw (SALOME::SALOME_Exception)
984 int NbNodes = IDsOfNodes.length();
985 SMDS_MeshElement* elem = 0;
988 CORBA::Long index1 = IDsOfNodes[0];
989 CORBA::Long index2 = IDsOfNodes[1];
990 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(index1),
991 getMeshDS()->FindNode(index2));
993 // Update Python script
994 TPythonDump() << "edge = " << this << ".AddEdge([ "
995 << index1 << ", " << index2 <<" ])";
998 CORBA::Long n1 = IDsOfNodes[0];
999 CORBA::Long n2 = IDsOfNodes[1];
1000 CORBA::Long n12 = IDsOfNodes[2];
1001 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(n1),
1002 getMeshDS()->FindNode(n2),
1003 getMeshDS()->FindNode(n12));
1004 // Update Python script
1005 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
1006 <<n1<<", "<<n2<<", "<<n12<<" ])";
1009 declareMeshModified( /*isReComputeSafe=*/false );
1010 return elem ? elem->GetID() : 0;
1012 SMESH_CATCH( SMESH::throwCorbaException );
1016 //=============================================================================
1020 //=============================================================================
1022 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
1023 throw (SALOME::SALOME_Exception)
1028 int NbNodes = IDsOfNodes.length();
1034 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1035 for (int i = 0; i < NbNodes; i++)
1036 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1038 SMDS_MeshElement* elem = 0;
1040 case 3: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]); break;
1041 case 4: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]); break;
1042 case 6: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1043 nodes[4], nodes[5]); break;
1044 case 7: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1045 nodes[4], nodes[5], nodes[6]); break;
1046 case 8: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1047 nodes[4], nodes[5], nodes[6], nodes[7]); break;
1048 case 9: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1049 nodes[4], nodes[5], nodes[6], nodes[7],
1051 default: elem = getMeshDS()->AddPolygonalFace(nodes);
1054 // Update Python script
1055 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
1057 declareMeshModified( /*isReComputeSafe=*/false );
1059 return elem ? elem->GetID() : 0;
1061 SMESH_CATCH( SMESH::throwCorbaException );
1065 //=============================================================================
1069 //=============================================================================
1070 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
1071 throw (SALOME::SALOME_Exception)
1076 int NbNodes = IDsOfNodes.length();
1077 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1078 for (int i = 0; i < NbNodes; i++)
1079 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1081 const SMDS_MeshElement* elem = getMeshDS()->AddPolygonalFace(nodes);
1083 // Update Python script
1084 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
1086 declareMeshModified( /*isReComputeSafe=*/false );
1087 return elem ? elem->GetID() : 0;
1089 SMESH_CATCH( SMESH::throwCorbaException );
1093 //=============================================================================
1095 * Create volume, either linear and quadratic (this is determed
1096 * by number of given nodes)
1098 //=============================================================================
1100 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
1101 throw (SALOME::SALOME_Exception)
1106 int NbNodes = IDsOfNodes.length();
1107 vector< const SMDS_MeshNode*> n(NbNodes);
1108 for(int i=0;i<NbNodes;i++)
1109 n[i]= getMeshDS()->FindNode(IDsOfNodes[i]);
1111 SMDS_MeshElement* elem = 0;
1114 case 4 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
1115 case 5 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
1116 case 6 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
1117 case 8 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
1118 case 10:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1119 n[6],n[7],n[8],n[9]);
1121 case 12:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1122 n[6],n[7],n[8],n[9],n[10],n[11]);
1124 case 13:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
1125 n[7],n[8],n[9],n[10],n[11],n[12]);
1127 case 15:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
1128 n[9],n[10],n[11],n[12],n[13],n[14]);
1130 case 20:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1131 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1132 n[15],n[16],n[17],n[18],n[19]);
1134 case 27:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1135 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1136 n[15],n[16],n[17],n[18],n[19],
1137 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
1141 // Update Python script
1142 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
1144 declareMeshModified( /*isReComputeSafe=*/false );
1145 return elem ? elem->GetID() : 0;
1147 SMESH_CATCH( SMESH::throwCorbaException );
1151 //=============================================================================
1153 * AddPolyhedralVolume
1155 //=============================================================================
1156 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
1157 const SMESH::long_array & Quantities)
1158 throw (SALOME::SALOME_Exception)
1163 int NbNodes = IDsOfNodes.length();
1164 std::vector<const SMDS_MeshNode*> n (NbNodes);
1165 for (int i = 0; i < NbNodes; i++)
1167 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDsOfNodes[i]);
1168 if (!aNode) return 0;
1172 int NbFaces = Quantities.length();
1173 std::vector<int> q (NbFaces);
1174 for (int j = 0; j < NbFaces; j++)
1175 q[j] = Quantities[j];
1177 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(n, q);
1179 // Update Python script
1180 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
1181 << IDsOfNodes << ", " << Quantities << " )";
1183 declareMeshModified( /*isReComputeSafe=*/false );
1184 return elem ? elem->GetID() : 0;
1186 SMESH_CATCH( SMESH::throwCorbaException );
1190 //=============================================================================
1192 * AddPolyhedralVolumeByFaces
1194 //=============================================================================
1196 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
1197 throw (SALOME::SALOME_Exception)
1202 int NbFaces = IdsOfFaces.length();
1203 std::vector<const SMDS_MeshNode*> poly_nodes;
1204 std::vector<int> quantities (NbFaces);
1206 for (int i = 0; i < NbFaces; i++) {
1207 const SMDS_MeshElement* aFace = getMeshDS()->FindElement(IdsOfFaces[i]);
1208 quantities[i] = aFace->NbNodes();
1210 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
1211 while (It->more()) {
1212 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
1216 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
1218 // Update Python script
1219 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
1220 << IdsOfFaces << " )";
1222 declareMeshModified( /*isReComputeSafe=*/false );
1223 return elem ? elem->GetID() : 0;
1225 SMESH_CATCH( SMESH::throwCorbaException );
1229 //=============================================================================
1231 // \brief Create 0D elements on all nodes of the given object except those
1232 // nodes on which a 0D element already exists.
1233 // \param theObject object on whose nodes 0D elements will be created.
1234 // \param theGroupName optional name of a group to add 0D elements created
1235 // and/or found on nodes of \a theObject.
1236 // \return an object (a new group or a temporary SMESH_IDSource) holding
1237 // ids of new and/or found 0D elements.
1239 //=============================================================================
1241 SMESH::SMESH_IDSource_ptr
1242 SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObject,
1243 const char* theGroupName)
1244 throw (SALOME::SALOME_Exception)
1249 SMESH::SMESH_IDSource_var result;
1252 TIDSortedElemSet elements, elems0D;
1253 prepareIdSource( theObject );
1254 if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
1255 getEditor().Create0DElementsOnAllNodes( elements, elems0D );
1257 SMESH::long_array_var newElems = new SMESH::long_array;
1258 newElems->length( elems0D.size() );
1259 TIDSortedElemSet::iterator eIt = elems0D.begin();
1260 for ( size_t i = 0; i < elems0D.size(); ++i, ++eIt )
1261 newElems[ i ] = (*eIt)->GetID();
1263 SMESH::SMESH_GroupBase_var groupToFill;
1264 if ( theGroupName && strlen( theGroupName ))
1266 // Get existing group named theGroupName
1267 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
1268 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
1269 SMESH::SMESH_GroupBase_var group = groups[i];
1270 if ( !group->_is_nil() ) {
1271 CORBA::String_var name = group->GetName();
1272 if ( strcmp( name.in(), theGroupName ) == 0 && group->GetType() == SMESH::ELEM0D ) {
1273 groupToFill = group;
1278 if ( groupToFill->_is_nil() )
1279 groupToFill = myMesh_i->CreateGroup( SMESH::ELEM0D, theGroupName );
1280 else if ( !SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1281 groupToFill = myMesh_i->ConvertToStandalone( groupToFill );
1284 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1286 group_i->Add( newElems );
1287 result = SMESH::SMESH_IDSource::_narrow( groupToFill );
1288 pyDump << groupToFill;
1292 result = MakeIDSource( newElems, SMESH::ELEM0D );
1293 pyDump << "elem0DIDs";
1296 pyDump << " = " << this << ".Create0DElementsOnAllNodes( "
1297 << theObject << ", '" << theGroupName << "' )";
1299 return result._retn();
1301 SMESH_CATCH( SMESH::throwCorbaException );
1305 //=============================================================================
1307 * \brief Bind a node to a vertex
1308 * \param NodeID - node ID
1309 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1310 * \retval boolean - false if NodeID or VertexID is invalid
1312 //=============================================================================
1314 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
1315 throw (SALOME::SALOME_Exception)
1319 SMESHDS_Mesh * mesh = getMeshDS();
1320 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1322 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1324 if ( mesh->MaxShapeIndex() < VertexID )
1325 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1327 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
1328 if ( shape.ShapeType() != TopAbs_VERTEX )
1329 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1331 mesh->SetNodeOnVertex( node, VertexID );
1333 myMesh->SetIsModified( true );
1335 SMESH_CATCH( SMESH::throwCorbaException );
1338 //=============================================================================
1340 * \brief Store node position on an edge
1341 * \param NodeID - node ID
1342 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
1343 * \param paramOnEdge - parameter on edge where the node is located
1344 * \retval boolean - false if any parameter is invalid
1346 //=============================================================================
1348 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
1349 CORBA::Double paramOnEdge)
1350 throw (SALOME::SALOME_Exception)
1354 SMESHDS_Mesh * mesh = getMeshDS();
1355 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1357 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1359 if ( mesh->MaxShapeIndex() < EdgeID )
1360 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1362 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
1363 if ( shape.ShapeType() != TopAbs_EDGE )
1364 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1367 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
1368 if ( paramOnEdge < f || paramOnEdge > l )
1369 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
1371 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
1373 myMesh->SetIsModified( true );
1375 SMESH_CATCH( SMESH::throwCorbaException );
1378 //=============================================================================
1380 * \brief Store node position on a face
1381 * \param NodeID - node ID
1382 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
1383 * \param u - U parameter on face where the node is located
1384 * \param v - V parameter on face where the node is located
1385 * \retval boolean - false if any parameter is invalid
1387 //=============================================================================
1389 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
1390 CORBA::Double u, CORBA::Double v)
1391 throw (SALOME::SALOME_Exception)
1394 SMESHDS_Mesh * mesh = getMeshDS();
1395 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1397 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1399 if ( mesh->MaxShapeIndex() < FaceID )
1400 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1402 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
1403 if ( shape.ShapeType() != TopAbs_FACE )
1404 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1406 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
1407 bool isOut = ( u < surf.FirstUParameter() ||
1408 u > surf.LastUParameter() ||
1409 v < surf.FirstVParameter() ||
1410 v > surf.LastVParameter() );
1414 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
1415 << " u( " << surf.FirstUParameter()
1416 << "," << surf.LastUParameter()
1417 << ") v( " << surf.FirstVParameter()
1418 << "," << surf.LastVParameter() << ")" );
1420 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
1423 mesh->SetNodeOnFace( node, FaceID, u, v );
1424 myMesh->SetIsModified( true );
1426 SMESH_CATCH( SMESH::throwCorbaException );
1429 //=============================================================================
1431 * \brief Bind a node to a solid
1432 * \param NodeID - node ID
1433 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1434 * \retval boolean - false if NodeID or SolidID is invalid
1436 //=============================================================================
1438 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
1439 throw (SALOME::SALOME_Exception)
1442 SMESHDS_Mesh * mesh = getMeshDS();
1443 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1445 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1447 if ( mesh->MaxShapeIndex() < SolidID )
1448 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1450 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
1451 if ( shape.ShapeType() != TopAbs_SOLID &&
1452 shape.ShapeType() != TopAbs_SHELL)
1453 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1455 mesh->SetNodeInVolume( node, SolidID );
1457 SMESH_CATCH( SMESH::throwCorbaException );
1460 //=============================================================================
1462 * \brief Bind an element to a shape
1463 * \param ElementID - element ID
1464 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
1466 //=============================================================================
1468 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
1469 CORBA::Long ShapeID)
1470 throw (SALOME::SALOME_Exception)
1473 SMESHDS_Mesh * mesh = getMeshDS();
1474 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
1476 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
1478 if ( mesh->MaxShapeIndex() < ShapeID || ShapeID < 1 )
1479 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1481 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1482 if ( shape.ShapeType() != TopAbs_EDGE &&
1483 shape.ShapeType() != TopAbs_FACE &&
1484 shape.ShapeType() != TopAbs_SOLID &&
1485 shape.ShapeType() != TopAbs_SHELL )
1486 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1488 mesh->SetMeshElementOnShape( elem, ShapeID );
1490 myMesh->SetIsModified( true );
1492 SMESH_CATCH( SMESH::throwCorbaException );
1495 //=============================================================================
1499 //=============================================================================
1501 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1502 CORBA::Long NodeID2)
1503 throw (SALOME::SALOME_Exception)
1508 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1509 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1513 // Update Python script
1514 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1515 << NodeID1 << ", " << NodeID2 << " )";
1517 int ret = getEditor().InverseDiag ( n1, n2 );
1519 declareMeshModified( /*isReComputeSafe=*/false );
1522 SMESH_CATCH( SMESH::throwCorbaException );
1526 //=============================================================================
1530 //=============================================================================
1532 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1533 CORBA::Long NodeID2)
1534 throw (SALOME::SALOME_Exception)
1539 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1540 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1544 // Update Python script
1545 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1546 << NodeID1 << ", " << NodeID2 << " )";
1549 bool stat = getEditor().DeleteDiag ( n1, n2 );
1551 declareMeshModified( /*isReComputeSafe=*/!stat );
1555 SMESH_CATCH( SMESH::throwCorbaException );
1559 //=============================================================================
1563 //=============================================================================
1565 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1566 throw (SALOME::SALOME_Exception)
1571 for (int i = 0; i < IDsOfElements.length(); i++)
1573 CORBA::Long index = IDsOfElements[i];
1574 const SMDS_MeshElement * elem = getMeshDS()->FindElement(index);
1576 getEditor().Reorient( elem );
1578 // Update Python script
1579 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1581 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 );
1584 SMESH_CATCH( SMESH::throwCorbaException );
1588 //=============================================================================
1592 //=============================================================================
1594 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1595 throw (SALOME::SALOME_Exception)
1600 TPythonDump aTPythonDump; // suppress dump in Reorient()
1602 prepareIdSource( theObject );
1604 SMESH::long_array_var anElementsId = theObject->GetIDs();
1605 CORBA::Boolean isDone = Reorient(anElementsId);
1607 // Update Python script
1608 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1610 declareMeshModified( /*isReComputeSafe=*/ anElementsId->length() == 0 );
1613 SMESH_CATCH( SMESH::throwCorbaException );
1617 //=======================================================================
1618 //function : Reorient2D
1619 //purpose : Reorient faces contained in \a the2Dgroup.
1620 // the2Dgroup - the mesh or its part to reorient
1621 // theDirection - desired direction of normal of \a theFace
1622 // theFace - ID of face whose orientation is checked.
1623 // It can be < 1 then \a thePoint is used to find a face.
1624 // thePoint - is used to find a face if \a theFace < 1.
1625 // return number of reoriented elements.
1626 //=======================================================================
1628 CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
1629 const SMESH::DirStruct& theDirection,
1630 CORBA::Long theFace,
1631 const SMESH::PointStruct& thePoint)
1632 throw (SALOME::SALOME_Exception)
1635 initData(/*deleteSearchers=*/false);
1637 TIDSortedElemSet elements;
1638 prepareIdSource( the2Dgroup );
1639 if ( !idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1))
1640 THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
1643 const SMDS_MeshElement* face = 0;
1646 face = getMeshDS()->FindElement( theFace );
1648 THROW_SALOME_CORBA_EXCEPTION("Inexistent face given", SALOME::BAD_PARAM);
1649 if ( face->GetType() != SMDSAbs_Face )
1650 THROW_SALOME_CORBA_EXCEPTION("Wrong element type", SALOME::BAD_PARAM);
1654 // create theElementSearcher if needed
1655 theSearchersDeleter.Set( myMesh, getPartIOR( the2Dgroup, SMESH::FACE ));
1656 if ( !theElementSearcher )
1658 if ( elements.empty() ) // search in the whole mesh
1660 if ( myMesh->NbFaces() == 0 )
1661 THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM);
1663 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
1667 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
1668 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
1670 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt);
1674 gp_Pnt p( thePoint.x, thePoint.y, thePoint.z );
1675 face = theElementSearcher->FindClosestTo( p, SMDSAbs_Face );
1678 THROW_SALOME_CORBA_EXCEPTION("No face found by point", SALOME::INTERNAL_ERROR );
1679 if ( !elements.empty() && !elements.count( face ))
1680 THROW_SALOME_CORBA_EXCEPTION("Found face is not in the group", SALOME::BAD_PARAM );
1683 const SMESH::PointStruct * P = &theDirection.PS;
1684 gp_Vec dirVec( P->x, P->y, P->z );
1685 if ( dirVec.Magnitude() < std::numeric_limits< double >::min() )
1686 THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM);
1688 int nbReori = getEditor().Reorient2D( elements, dirVec, face );
1691 declareMeshModified( /*isReComputeSafe=*/false );
1693 TPythonDump() << this << ".Reorient2D( "
1694 << the2Dgroup << ", "
1695 << theDirection << ", "
1697 << thePoint << " )";
1701 SMESH_CATCH( SMESH::throwCorbaException );
1705 //=============================================================================
1707 * \brief Fuse neighbour triangles into quadrangles.
1709 //=============================================================================
1711 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1712 SMESH::NumericalFunctor_ptr Criterion,
1713 CORBA::Double MaxAngle)
1714 throw (SALOME::SALOME_Exception)
1719 SMESHDS_Mesh* aMesh = getMeshDS();
1720 TIDSortedElemSet faces;
1721 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1723 SMESH::NumericalFunctor_i* aNumericalFunctor =
1724 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1725 SMESH::Controls::NumericalFunctorPtr aCrit;
1726 if ( !aNumericalFunctor )
1727 aCrit.reset( new SMESH::Controls::MaxElementLength2D() );
1729 aCrit = aNumericalFunctor->GetNumericalFunctor();
1731 // Update Python script
1732 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1733 << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1736 bool stat = getEditor().TriToQuad( faces, aCrit, MaxAngle );
1738 declareMeshModified( /*isReComputeSafe=*/!stat );
1741 SMESH_CATCH( SMESH::throwCorbaException );
1745 //=============================================================================
1747 * \brief Fuse neighbour triangles into quadrangles.
1749 //=============================================================================
1751 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1752 SMESH::NumericalFunctor_ptr Criterion,
1753 CORBA::Double MaxAngle)
1754 throw (SALOME::SALOME_Exception)
1759 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1761 prepareIdSource( theObject );
1762 SMESH::long_array_var anElementsId = theObject->GetIDs();
1763 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1765 SMESH::NumericalFunctor_i* aNumericalFunctor =
1766 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1768 // Update Python script
1769 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1770 << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1774 SMESH_CATCH( SMESH::throwCorbaException );
1778 //=============================================================================
1780 * \brief Split quadrangles into triangles.
1782 //=============================================================================
1784 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1785 SMESH::NumericalFunctor_ptr Criterion)
1786 throw (SALOME::SALOME_Exception)
1791 SMESHDS_Mesh* aMesh = getMeshDS();
1792 TIDSortedElemSet faces;
1793 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1795 SMESH::NumericalFunctor_i* aNumericalFunctor =
1796 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1797 SMESH::Controls::NumericalFunctorPtr aCrit;
1798 if ( !aNumericalFunctor )
1799 aCrit.reset( new SMESH::Controls::AspectRatio() );
1801 aCrit = aNumericalFunctor->GetNumericalFunctor();
1804 // Update Python script
1805 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1807 CORBA::Boolean stat = getEditor().QuadToTri( faces, aCrit );
1809 declareMeshModified( /*isReComputeSafe=*/false );
1812 SMESH_CATCH( SMESH::throwCorbaException );
1816 //=============================================================================
1818 * \brief Split quadrangles into triangles.
1820 //=============================================================================
1822 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1823 SMESH::NumericalFunctor_ptr Criterion)
1824 throw (SALOME::SALOME_Exception)
1829 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1831 prepareIdSource( theObject );
1832 SMESH::long_array_var anElementsId = theObject->GetIDs();
1833 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1835 SMESH::NumericalFunctor_i* aNumericalFunctor =
1836 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1838 // Update Python script
1839 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1841 declareMeshModified( /*isReComputeSafe=*/false );
1844 SMESH_CATCH( SMESH::throwCorbaException );
1848 //================================================================================
1850 * \brief Split each of quadrangles into 4 triangles.
1851 * \param [in] theObject - theQuads Container of quadrangles to split.
1853 //================================================================================
1855 void SMESH_MeshEditor_i::QuadTo4Tri (SMESH::SMESH_IDSource_ptr theObject)
1856 throw (SALOME::SALOME_Exception)
1861 TIDSortedElemSet faces;
1862 prepareIdSource( theObject );
1863 if ( !idSourceToSet( theObject, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/true ) &&
1865 THROW_SALOME_CORBA_EXCEPTION("No faces given", SALOME::BAD_PARAM);
1867 getEditor().QuadTo4Tri( faces );
1868 TPythonDump() << this << ".QuadTo4Tri( " << theObject << " )";
1870 SMESH_CATCH( SMESH::throwCorbaException );
1873 //=============================================================================
1875 * \brief Split quadrangles into triangles.
1877 //=============================================================================
1879 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1880 CORBA::Boolean Diag13)
1881 throw (SALOME::SALOME_Exception)
1886 SMESHDS_Mesh* aMesh = getMeshDS();
1887 TIDSortedElemSet faces;
1888 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1890 // Update Python script
1891 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1892 << IDsOfElements << ", " << Diag13 << " )";
1894 CORBA::Boolean stat = getEditor().QuadToTri( faces, Diag13 );
1896 declareMeshModified( /*isReComputeSafe=*/ !stat );
1899 SMESH_CATCH( SMESH::throwCorbaException );
1903 //=============================================================================
1905 * \brief Split quadrangles into triangles.
1907 //=============================================================================
1909 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1910 CORBA::Boolean Diag13)
1911 throw (SALOME::SALOME_Exception)
1916 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
1918 prepareIdSource( theObject );
1919 SMESH::long_array_var anElementsId = theObject->GetIDs();
1920 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
1922 // Update Python script
1923 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
1924 << theObject << ", " << Diag13 << " )";
1926 declareMeshModified( /*isReComputeSafe=*/!isDone );
1929 SMESH_CATCH( SMESH::throwCorbaException );
1934 //=============================================================================
1936 * Find better splitting of the given quadrangle.
1937 * \param IDOfQuad ID of the quadrangle to be splitted.
1938 * \param Criterion A criterion to choose a diagonal for splitting.
1939 * \return 1 if 1-3 diagonal is better, 2 if 2-4
1940 * diagonal is better, 0 if error occurs.
1942 //=============================================================================
1944 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
1945 SMESH::NumericalFunctor_ptr Criterion)
1946 throw (SALOME::SALOME_Exception)
1951 const SMDS_MeshElement* quad = getMeshDS()->FindElement(IDOfQuad);
1952 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
1954 SMESH::NumericalFunctor_i* aNumericalFunctor =
1955 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
1956 SMESH::Controls::NumericalFunctorPtr aCrit;
1957 if (aNumericalFunctor)
1958 aCrit = aNumericalFunctor->GetNumericalFunctor();
1960 aCrit.reset(new SMESH::Controls::AspectRatio());
1962 int id = getEditor().BestSplit(quad, aCrit);
1963 declareMeshModified( /*isReComputeSafe=*/ id < 1 );
1966 SMESH_CATCH( SMESH::throwCorbaException );
1970 //================================================================================
1972 * \brief Split volumic elements into tetrahedrons
1974 //================================================================================
1976 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
1977 CORBA::Short methodFlags)
1978 throw (SALOME::SALOME_Exception)
1983 prepareIdSource( elems );
1984 SMESH::long_array_var anElementsId = elems->GetIDs();
1985 TIDSortedElemSet elemSet;
1986 arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume );
1988 getEditor().SplitVolumesIntoTetra( elemSet, int( methodFlags ));
1989 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
1991 TPythonDump() << this << ".SplitVolumesIntoTetra( "
1992 << elems << ", " << methodFlags << " )";
1994 SMESH_CATCH( SMESH::throwCorbaException );
1997 //=======================================================================
2000 //=======================================================================
2003 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
2004 const SMESH::long_array & IDsOfFixedNodes,
2005 CORBA::Long MaxNbOfIterations,
2006 CORBA::Double MaxAspectRatio,
2007 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2008 throw (SALOME::SALOME_Exception)
2010 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2011 MaxAspectRatio, Method, false );
2015 //=======================================================================
2016 //function : SmoothParametric
2018 //=======================================================================
2021 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
2022 const SMESH::long_array & IDsOfFixedNodes,
2023 CORBA::Long MaxNbOfIterations,
2024 CORBA::Double MaxAspectRatio,
2025 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2026 throw (SALOME::SALOME_Exception)
2028 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2029 MaxAspectRatio, Method, true );
2033 //=======================================================================
2034 //function : SmoothObject
2036 //=======================================================================
2039 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
2040 const SMESH::long_array & IDsOfFixedNodes,
2041 CORBA::Long MaxNbOfIterations,
2042 CORBA::Double MaxAspectRatio,
2043 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2044 throw (SALOME::SALOME_Exception)
2046 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2047 MaxAspectRatio, Method, false);
2051 //=======================================================================
2052 //function : SmoothParametricObject
2054 //=======================================================================
2057 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
2058 const SMESH::long_array & IDsOfFixedNodes,
2059 CORBA::Long MaxNbOfIterations,
2060 CORBA::Double MaxAspectRatio,
2061 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2062 throw (SALOME::SALOME_Exception)
2064 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2065 MaxAspectRatio, Method, true);
2069 //=============================================================================
2073 //=============================================================================
2076 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
2077 const SMESH::long_array & IDsOfFixedNodes,
2078 CORBA::Long MaxNbOfIterations,
2079 CORBA::Double MaxAspectRatio,
2080 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2082 throw (SALOME::SALOME_Exception)
2087 SMESHDS_Mesh* aMesh = getMeshDS();
2089 TIDSortedElemSet elements;
2090 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
2092 set<const SMDS_MeshNode*> fixedNodes;
2093 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
2094 CORBA::Long index = IDsOfFixedNodes[i];
2095 const SMDS_MeshNode * node = aMesh->FindNode(index);
2097 fixedNodes.insert( node );
2099 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
2100 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
2101 method = ::SMESH_MeshEditor::CENTROIDAL;
2103 getEditor().Smooth(elements, fixedNodes, method,
2104 MaxNbOfIterations, MaxAspectRatio, IsParametric );
2106 declareMeshModified( /*isReComputeSafe=*/true ); // does not prevent re-compute
2108 // Update Python script
2109 TPythonDump() << "isDone = " << this << "."
2110 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
2111 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
2112 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2113 << "SMESH.SMESH_MeshEditor."
2114 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2115 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2119 SMESH_CATCH( SMESH::throwCorbaException );
2123 //=============================================================================
2127 //=============================================================================
2130 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
2131 const SMESH::long_array & IDsOfFixedNodes,
2132 CORBA::Long MaxNbOfIterations,
2133 CORBA::Double MaxAspectRatio,
2134 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2136 throw (SALOME::SALOME_Exception)
2141 TPythonDump aTPythonDump; // suppress dump in smooth()
2143 prepareIdSource( theObject );
2144 SMESH::long_array_var anElementsId = theObject->GetIDs();
2145 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
2146 MaxAspectRatio, Method, IsParametric);
2148 // Update Python script
2149 aTPythonDump << "isDone = " << this << "."
2150 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
2151 << theObject << ", " << IDsOfFixedNodes << ", "
2152 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2153 << "SMESH.SMESH_MeshEditor."
2154 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2155 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2159 SMESH_CATCH( SMESH::throwCorbaException );
2163 //=============================================================================
2167 //=============================================================================
2169 void SMESH_MeshEditor_i::RenumberNodes()
2170 throw (SALOME::SALOME_Exception)
2173 // Update Python script
2174 TPythonDump() << this << ".RenumberNodes()";
2176 getMeshDS()->Renumber( true );
2178 SMESH_CATCH( SMESH::throwCorbaException );
2181 //=============================================================================
2185 //=============================================================================
2187 void SMESH_MeshEditor_i::RenumberElements()
2188 throw (SALOME::SALOME_Exception)
2191 // Update Python script
2192 TPythonDump() << this << ".RenumberElements()";
2194 getMeshDS()->Renumber( false );
2196 SMESH_CATCH( SMESH::throwCorbaException );
2199 //=======================================================================
2201 * \brief Return groups by their IDs
2203 //=======================================================================
2205 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
2206 throw (SALOME::SALOME_Exception)
2211 myMesh_i->CreateGroupServants();
2212 return myMesh_i->GetGroups( *groupIDs );
2214 SMESH_CATCH( SMESH::throwCorbaException );
2218 //=======================================================================
2219 //function : rotationSweep
2221 //=======================================================================
2223 SMESH::ListOfGroups*
2224 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
2225 const SMESH::AxisStruct & theAxis,
2226 CORBA::Double theAngleInRadians,
2227 CORBA::Long theNbOfSteps,
2228 CORBA::Double theTolerance,
2229 const bool theMakeGroups,
2230 const SMDSAbs_ElementType theElementType)
2231 throw (SALOME::SALOME_Exception)
2236 TIDSortedElemSet inElements, copyElements;
2237 arrayToSet(theIDsOfElements, getMeshDS(), inElements, theElementType);
2239 TIDSortedElemSet* workElements = & inElements;
2240 bool makeWalls=true;
2241 if ( myIsPreviewMode )
2243 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2244 getPreviewMesh( SMDSAbs_Face )->Copy( inElements, copyElements, select, avoid );
2245 workElements = & copyElements;
2246 //makeWalls = false;
2249 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
2250 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
2252 ::SMESH_MeshEditor::PGroupIDs groupIds =
2253 getEditor().RotationSweep (*workElements, Ax1, theAngleInRadians,
2254 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
2256 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2258 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2260 SMESH_CATCH( SMESH::throwCorbaException );
2264 //=======================================================================
2265 //function : RotationSweep
2267 //=======================================================================
2269 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
2270 const SMESH::AxisStruct & theAxis,
2271 CORBA::Double theAngleInRadians,
2272 CORBA::Long theNbOfSteps,
2273 CORBA::Double theTolerance)
2274 throw (SALOME::SALOME_Exception)
2276 if ( !myIsPreviewMode ) {
2277 TPythonDump() << this << ".RotationSweep( "
2278 << theIDsOfElements << ", "
2280 << TVar( theAngleInRadians ) << ", "
2281 << TVar( theNbOfSteps ) << ", "
2282 << TVar( theTolerance ) << " )";
2284 rotationSweep(theIDsOfElements,
2292 //=======================================================================
2293 //function : RotationSweepMakeGroups
2295 //=======================================================================
2297 SMESH::ListOfGroups*
2298 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2299 const SMESH::AxisStruct& theAxis,
2300 CORBA::Double theAngleInRadians,
2301 CORBA::Long theNbOfSteps,
2302 CORBA::Double theTolerance)
2303 throw (SALOME::SALOME_Exception)
2305 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2307 SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
2313 if (!myIsPreviewMode) {
2314 dumpGroupsList(aPythonDump, aGroups);
2315 aPythonDump << this << ".RotationSweepMakeGroups( "
2316 << theIDsOfElements << ", "
2318 << TVar( theAngleInRadians ) << ", "
2319 << TVar( theNbOfSteps ) << ", "
2320 << TVar( theTolerance ) << " )";
2325 //=======================================================================
2326 //function : RotationSweepObject
2328 //=======================================================================
2330 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2331 const SMESH::AxisStruct & theAxis,
2332 CORBA::Double theAngleInRadians,
2333 CORBA::Long theNbOfSteps,
2334 CORBA::Double theTolerance)
2335 throw (SALOME::SALOME_Exception)
2337 if ( !myIsPreviewMode ) {
2338 TPythonDump() << this << ".RotationSweepObject( "
2339 << theObject << ", "
2341 << theAngleInRadians << ", "
2342 << theNbOfSteps << ", "
2343 << theTolerance << " )";
2345 prepareIdSource( theObject );
2346 SMESH::long_array_var anElementsId = theObject->GetIDs();
2347 rotationSweep(anElementsId,
2355 //=======================================================================
2356 //function : RotationSweepObject1D
2358 //=======================================================================
2360 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2361 const SMESH::AxisStruct & theAxis,
2362 CORBA::Double theAngleInRadians,
2363 CORBA::Long theNbOfSteps,
2364 CORBA::Double theTolerance)
2365 throw (SALOME::SALOME_Exception)
2367 if ( !myIsPreviewMode ) {
2368 TPythonDump() << this << ".RotationSweepObject1D( "
2369 << theObject << ", "
2371 << TVar( theAngleInRadians ) << ", "
2372 << TVar( theNbOfSteps ) << ", "
2373 << TVar( theTolerance ) << " )";
2375 prepareIdSource( theObject );
2376 SMESH::long_array_var anElementsId = theObject->GetIDs();
2377 rotationSweep(anElementsId,
2386 //=======================================================================
2387 //function : RotationSweepObject2D
2389 //=======================================================================
2391 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2392 const SMESH::AxisStruct & theAxis,
2393 CORBA::Double theAngleInRadians,
2394 CORBA::Long theNbOfSteps,
2395 CORBA::Double theTolerance)
2396 throw (SALOME::SALOME_Exception)
2398 if ( !myIsPreviewMode ) {
2399 TPythonDump() << this << ".RotationSweepObject2D( "
2400 << theObject << ", "
2402 << TVar( theAngleInRadians ) << ", "
2403 << TVar( theNbOfSteps ) << ", "
2404 << TVar( theTolerance ) << " )";
2406 prepareIdSource( theObject );
2407 SMESH::long_array_var anElementsId = theObject->GetIDs();
2408 rotationSweep(anElementsId,
2417 //=======================================================================
2418 //function : RotationSweepObjectMakeGroups
2420 //=======================================================================
2422 SMESH::ListOfGroups*
2423 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2424 const SMESH::AxisStruct& theAxis,
2425 CORBA::Double theAngleInRadians,
2426 CORBA::Long theNbOfSteps,
2427 CORBA::Double theTolerance)
2428 throw (SALOME::SALOME_Exception)
2430 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2432 prepareIdSource( theObject );
2433 SMESH::long_array_var anElementsId = theObject->GetIDs();
2434 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2440 if (!myIsPreviewMode) {
2441 dumpGroupsList(aPythonDump, aGroups);
2442 aPythonDump << this << ".RotationSweepObjectMakeGroups( "
2443 << theObject << ", "
2445 << theAngleInRadians << ", "
2446 << theNbOfSteps << ", "
2447 << theTolerance << " )";
2452 //=======================================================================
2453 //function : RotationSweepObject1DMakeGroups
2455 //=======================================================================
2457 SMESH::ListOfGroups*
2458 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2459 const SMESH::AxisStruct& theAxis,
2460 CORBA::Double theAngleInRadians,
2461 CORBA::Long theNbOfSteps,
2462 CORBA::Double theTolerance)
2463 throw (SALOME::SALOME_Exception)
2465 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2467 prepareIdSource( theObject );
2468 SMESH::long_array_var anElementsId = theObject->GetIDs();
2469 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2476 if (!myIsPreviewMode) {
2477 dumpGroupsList(aPythonDump, aGroups);
2478 aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
2479 << theObject << ", "
2481 << TVar( theAngleInRadians ) << ", "
2482 << TVar( theNbOfSteps ) << ", "
2483 << TVar( theTolerance ) << " )";
2488 //=======================================================================
2489 //function : RotationSweepObject2DMakeGroups
2491 //=======================================================================
2493 SMESH::ListOfGroups*
2494 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2495 const SMESH::AxisStruct& theAxis,
2496 CORBA::Double theAngleInRadians,
2497 CORBA::Long theNbOfSteps,
2498 CORBA::Double theTolerance)
2499 throw (SALOME::SALOME_Exception)
2501 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2503 prepareIdSource( theObject );
2504 SMESH::long_array_var anElementsId = theObject->GetIDs();
2505 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2512 if (!myIsPreviewMode) {
2513 dumpGroupsList(aPythonDump, aGroups);
2514 aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
2515 << theObject << ", "
2517 << TVar( theAngleInRadians ) << ", "
2518 << TVar( theNbOfSteps ) << ", "
2519 << TVar( theTolerance ) << " )";
2525 //=======================================================================
2526 //function : extrusionSweep
2528 //=======================================================================
2530 SMESH::ListOfGroups*
2531 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
2532 const SMESH::DirStruct & theStepVector,
2533 CORBA::Long theNbOfSteps,
2535 const SMDSAbs_ElementType theElementType)
2536 throw (SALOME::SALOME_Exception)
2541 TIDSortedElemSet elements, copyElements;
2542 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
2544 const SMESH::PointStruct * P = &theStepVector.PS;
2545 gp_Vec stepVec( P->x, P->y, P->z );
2547 TIDSortedElemSet* workElements = & elements;
2549 SMDSAbs_ElementType aType = SMDSAbs_Face;
2550 if (theElementType == SMDSAbs_Node)
2552 aType = SMDSAbs_Edge;
2554 if ( myIsPreviewMode ) {
2555 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2556 getPreviewMesh( aType )->Copy( elements, copyElements, select, avoid );
2557 workElements = & copyElements;
2558 theMakeGroups = false;
2561 ::SMESH_MeshEditor::TTElemOfElemListMap aHystory;
2562 ::SMESH_MeshEditor::PGroupIDs groupIds =
2563 getEditor().ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
2565 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2567 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2569 SMESH_CATCH( SMESH::throwCorbaException );
2573 //=======================================================================
2574 //function : ExtrusionSweep
2576 //=======================================================================
2578 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
2579 const SMESH::DirStruct & theStepVector,
2580 CORBA::Long theNbOfSteps)
2581 throw (SALOME::SALOME_Exception)
2583 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
2584 if (!myIsPreviewMode) {
2585 TPythonDump() << this << ".ExtrusionSweep( "
2586 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps) << " )";
2590 //=======================================================================
2591 //function : ExtrusionSweep0D
2593 //=======================================================================
2595 void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElements,
2596 const SMESH::DirStruct & theStepVector,
2597 CORBA::Long theNbOfSteps)
2598 throw (SALOME::SALOME_Exception)
2600 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2601 if (!myIsPreviewMode) {
2602 TPythonDump() << this << ".ExtrusionSweep0D( "
2603 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps)<< " )";
2607 //=======================================================================
2608 //function : ExtrusionSweepObject
2610 //=======================================================================
2612 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2613 const SMESH::DirStruct & theStepVector,
2614 CORBA::Long theNbOfSteps)
2615 throw (SALOME::SALOME_Exception)
2617 prepareIdSource( theObject );
2618 SMESH::long_array_var anElementsId = theObject->GetIDs();
2619 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
2620 if (!myIsPreviewMode) {
2621 TPythonDump() << this << ".ExtrusionSweepObject( "
2622 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
2626 //=======================================================================
2627 //function : ExtrusionSweepObject0D
2629 //=======================================================================
2631 void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObject,
2632 const SMESH::DirStruct & theStepVector,
2633 CORBA::Long theNbOfSteps)
2634 throw (SALOME::SALOME_Exception)
2636 prepareIdSource( theObject );
2637 SMESH::long_array_var anElementsId = theObject->GetIDs();
2638 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2639 if ( !myIsPreviewMode ) {
2640 TPythonDump() << this << ".ExtrusionSweepObject0D( "
2641 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2645 //=======================================================================
2646 //function : ExtrusionSweepObject1D
2648 //=======================================================================
2650 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2651 const SMESH::DirStruct & theStepVector,
2652 CORBA::Long theNbOfSteps)
2653 throw (SALOME::SALOME_Exception)
2655 prepareIdSource( theObject );
2656 SMESH::long_array_var anElementsId = theObject->GetIDs();
2657 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
2658 if ( !myIsPreviewMode ) {
2659 TPythonDump() << this << ".ExtrusionSweepObject1D( "
2660 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2664 //=======================================================================
2665 //function : ExtrusionSweepObject2D
2667 //=======================================================================
2669 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2670 const SMESH::DirStruct & theStepVector,
2671 CORBA::Long theNbOfSteps)
2672 throw (SALOME::SALOME_Exception)
2674 prepareIdSource( theObject );
2675 SMESH::long_array_var anElementsId = theObject->GetIDs();
2676 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
2677 if ( !myIsPreviewMode ) {
2678 TPythonDump() << this << ".ExtrusionSweepObject2D( "
2679 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2683 //=======================================================================
2684 //function : ExtrusionSweepMakeGroups
2686 //=======================================================================
2688 SMESH::ListOfGroups*
2689 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2690 const SMESH::DirStruct& theStepVector,
2691 CORBA::Long theNbOfSteps)
2692 throw (SALOME::SALOME_Exception)
2694 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2696 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
2698 if (!myIsPreviewMode) {
2699 dumpGroupsList(aPythonDump, aGroups);
2700 aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
2701 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2706 //=======================================================================
2707 //function : ExtrusionSweepMakeGroups0D
2709 //=======================================================================
2711 SMESH::ListOfGroups*
2712 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups0D(const SMESH::long_array& theIDsOfElements,
2713 const SMESH::DirStruct& theStepVector,
2714 CORBA::Long theNbOfSteps)
2715 throw (SALOME::SALOME_Exception)
2717 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2719 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true,SMDSAbs_Node);
2721 if (!myIsPreviewMode) {
2722 dumpGroupsList(aPythonDump, aGroups);
2723 aPythonDump << this << ".ExtrusionSweepMakeGroups0D( " << theIDsOfElements
2724 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2729 //=======================================================================
2730 //function : ExtrusionSweepObjectMakeGroups
2732 //=======================================================================
2734 SMESH::ListOfGroups*
2735 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2736 const SMESH::DirStruct& theStepVector,
2737 CORBA::Long theNbOfSteps)
2738 throw (SALOME::SALOME_Exception)
2740 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2742 prepareIdSource( theObject );
2743 SMESH::long_array_var anElementsId = theObject->GetIDs();
2744 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
2746 if (!myIsPreviewMode) {
2747 dumpGroupsList(aPythonDump, aGroups);
2748 aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
2749 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2754 //=======================================================================
2755 //function : ExtrusionSweepObject0DMakeGroups
2757 //=======================================================================
2759 SMESH::ListOfGroups*
2760 SMESH_MeshEditor_i::ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2761 const SMESH::DirStruct& theStepVector,
2762 CORBA::Long theNbOfSteps)
2763 throw (SALOME::SALOME_Exception)
2765 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2767 prepareIdSource( theObject );
2768 SMESH::long_array_var anElementsId = theObject->GetIDs();
2769 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2770 theNbOfSteps, true, SMDSAbs_Node);
2771 if (!myIsPreviewMode) {
2772 dumpGroupsList(aPythonDump, aGroups);
2773 aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject
2774 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2779 //=======================================================================
2780 //function : ExtrusionSweepObject1DMakeGroups
2782 //=======================================================================
2784 SMESH::ListOfGroups*
2785 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2786 const SMESH::DirStruct& theStepVector,
2787 CORBA::Long theNbOfSteps)
2788 throw (SALOME::SALOME_Exception)
2790 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2792 prepareIdSource( theObject );
2793 SMESH::long_array_var anElementsId = theObject->GetIDs();
2794 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2795 theNbOfSteps, true, SMDSAbs_Edge);
2796 if (!myIsPreviewMode) {
2797 dumpGroupsList(aPythonDump, aGroups);
2798 aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
2799 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2804 //=======================================================================
2805 //function : ExtrusionSweepObject2DMakeGroups
2807 //=======================================================================
2809 SMESH::ListOfGroups*
2810 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2811 const SMESH::DirStruct& theStepVector,
2812 CORBA::Long theNbOfSteps)
2813 throw (SALOME::SALOME_Exception)
2815 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2817 prepareIdSource( theObject );
2818 SMESH::long_array_var anElementsId = theObject->GetIDs();
2819 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2820 theNbOfSteps, true, SMDSAbs_Face);
2821 if (!myIsPreviewMode) {
2822 dumpGroupsList(aPythonDump, aGroups);
2823 aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
2824 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2830 //=======================================================================
2831 //function : advancedExtrusion
2833 //=======================================================================
2835 SMESH::ListOfGroups*
2836 SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
2837 const SMESH::DirStruct & theStepVector,
2838 CORBA::Long theNbOfSteps,
2839 CORBA::Long theExtrFlags,
2840 CORBA::Double theSewTolerance,
2841 const bool theMakeGroups)
2842 throw (SALOME::SALOME_Exception)
2847 TIDSortedElemSet elements;
2848 arrayToSet(theIDsOfElements, getMeshDS(), elements);
2850 const SMESH::PointStruct * P = &theStepVector.PS;
2851 gp_Vec stepVec( P->x, P->y, P->z );
2853 ::SMESH_MeshEditor::TTElemOfElemListMap aHystory;
2854 ::SMESH_MeshEditor::PGroupIDs groupIds =
2855 getEditor().ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
2856 theMakeGroups, theExtrFlags, theSewTolerance);
2858 declareMeshModified( /*isReComputeSafe=*/true );
2860 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2862 SMESH_CATCH( SMESH::throwCorbaException );
2866 //=======================================================================
2867 //function : AdvancedExtrusion
2869 //=======================================================================
2871 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2872 const SMESH::DirStruct & theStepVector,
2873 CORBA::Long theNbOfSteps,
2874 CORBA::Long theExtrFlags,
2875 CORBA::Double theSewTolerance)
2876 throw (SALOME::SALOME_Exception)
2878 if ( !myIsPreviewMode ) {
2879 TPythonDump() << "stepVector = " << theStepVector;
2880 TPythonDump() << this << ".AdvancedExtrusion("
2883 << theNbOfSteps << ","
2884 << theExtrFlags << ", "
2885 << theSewTolerance << " )";
2887 advancedExtrusion( theIDsOfElements,
2895 //=======================================================================
2896 //function : AdvancedExtrusionMakeGroups
2898 //=======================================================================
2899 SMESH::ListOfGroups*
2900 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
2901 const SMESH::DirStruct& theStepVector,
2902 CORBA::Long theNbOfSteps,
2903 CORBA::Long theExtrFlags,
2904 CORBA::Double theSewTolerance)
2905 throw (SALOME::SALOME_Exception)
2907 if (!myIsPreviewMode) {
2908 TPythonDump() << "stepVector = " << theStepVector;
2910 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2912 SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
2919 if (!myIsPreviewMode) {
2920 dumpGroupsList(aPythonDump, aGroups);
2921 aPythonDump << this << ".AdvancedExtrusionMakeGroups("
2924 << theNbOfSteps << ","
2925 << theExtrFlags << ", "
2926 << theSewTolerance << " )";
2932 //================================================================================
2934 * \brief Convert extrusion error to IDL enum
2936 //================================================================================
2938 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
2940 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
2944 RETCASE( EXTR_NO_ELEMENTS );
2945 RETCASE( EXTR_PATH_NOT_EDGE );
2946 RETCASE( EXTR_BAD_PATH_SHAPE );
2947 RETCASE( EXTR_BAD_STARTING_NODE );
2948 RETCASE( EXTR_BAD_ANGLES_NUMBER );
2949 RETCASE( EXTR_CANT_GET_TANGENT );
2951 return SMESH::SMESH_MeshEditor::EXTR_OK;
2955 //=======================================================================
2956 //function : extrusionAlongPath
2958 //=======================================================================
2959 SMESH::ListOfGroups*
2960 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2961 SMESH::SMESH_Mesh_ptr thePathMesh,
2962 GEOM::GEOM_Object_ptr thePathShape,
2963 CORBA::Long theNodeStart,
2964 CORBA::Boolean theHasAngles,
2965 const SMESH::double_array & theAngles,
2966 CORBA::Boolean theHasRefPoint,
2967 const SMESH::PointStruct & theRefPoint,
2968 const bool theMakeGroups,
2969 SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
2970 const SMDSAbs_ElementType theElementType)
2971 throw (SALOME::SALOME_Exception)
2974 MESSAGE("extrusionAlongPath");
2977 if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
2978 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2981 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2983 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2984 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2986 if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
2987 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2991 SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
2993 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2997 TIDSortedElemSet elements;
2998 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
3000 list<double> angles;
3001 for (int i = 0; i < theAngles.length(); i++) {
3002 angles.push_back( theAngles[i] );
3005 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
3007 int nbOldGroups = myMesh->NbGroup();
3009 ::SMESH_MeshEditor::Extrusion_Error error =
3010 getEditor().ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
3011 theHasAngles, angles, false,
3012 theHasRefPoint, refPnt, theMakeGroups );
3014 declareMeshModified( /*isReComputeSafe=*/true );
3015 theError = convExtrError( error );
3017 if ( theMakeGroups ) {
3018 list<int> groupIDs = myMesh->GetGroupIds();
3019 list<int>::iterator newBegin = groupIDs.begin();
3020 std::advance( newBegin, nbOldGroups ); // skip old groups
3021 groupIDs.erase( groupIDs.begin(), newBegin );
3022 return getGroups( & groupIDs );
3026 SMESH_CATCH( SMESH::throwCorbaException );
3030 //=======================================================================
3031 //function : extrusionAlongPathX
3033 //=======================================================================
3035 SMESH::ListOfGroups*
3036 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements,
3037 SMESH::SMESH_IDSource_ptr Path,
3038 CORBA::Long NodeStart,
3039 CORBA::Boolean HasAngles,
3040 const SMESH::double_array& Angles,
3041 CORBA::Boolean LinearVariation,
3042 CORBA::Boolean HasRefPoint,
3043 const SMESH::PointStruct& RefPoint,
3045 const SMDSAbs_ElementType ElementType,
3046 SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
3047 throw (SALOME::SALOME_Exception)
3050 SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
3054 list<double> angles;
3055 for (int i = 0; i < Angles.length(); i++) {
3056 angles.push_back( Angles[i] );
3058 gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
3059 int nbOldGroups = myMesh->NbGroup();
3061 if ( Path->_is_nil() ) {
3062 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3066 TIDSortedElemSet elements, copyElements;
3067 arrayToSet(IDsOfElements, getMeshDS(), elements, ElementType);
3069 TIDSortedElemSet* workElements = &elements;
3071 if ( myIsPreviewMode )
3073 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
3074 getPreviewMesh( SMDSAbs_Face )->Copy( elements, copyElements, select, avoid );
3075 workElements = & copyElements;
3079 ::SMESH_MeshEditor::Extrusion_Error error;
3081 if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path ))
3084 SMDS_MeshNode* aNodeStart =
3085 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
3086 if ( !aNodeStart ) {
3087 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3090 error = getEditor().ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
3091 HasAngles, angles, LinearVariation,
3092 HasRefPoint, refPnt, MakeGroups );
3093 declareMeshModified( /*isReComputeSafe=*/true );
3095 else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
3098 SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
3099 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
3100 SMDS_MeshNode* aNodeStart =
3101 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
3102 if ( !aNodeStart ) {
3103 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3106 SMESH_subMesh* aSubMesh =
3107 aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
3108 error = getEditor().ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
3109 HasAngles, angles, LinearVariation,
3110 HasRefPoint, refPnt, MakeGroups );
3111 declareMeshModified( /*isReComputeSafe=*/true );
3113 else if ( SMESH::DownCast<SMESH_Group_i*>( Path ))
3115 // path as group of 1D elements
3121 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3125 Error = convExtrError( error );
3128 list<int> groupIDs = myMesh->GetGroupIds();
3129 list<int>::iterator newBegin = groupIDs.begin();
3130 std::advance( newBegin, nbOldGroups ); // skip old groups
3131 groupIDs.erase( groupIDs.begin(), newBegin );
3132 return getGroups( & groupIDs );
3136 SMESH_CATCH( SMESH::throwCorbaException );
3140 //=======================================================================
3141 //function : ExtrusionAlongPath
3143 //=======================================================================
3145 SMESH::SMESH_MeshEditor::Extrusion_Error
3146 SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements,
3147 SMESH::SMESH_Mesh_ptr thePathMesh,
3148 GEOM::GEOM_Object_ptr thePathShape,
3149 CORBA::Long theNodeStart,
3150 CORBA::Boolean theHasAngles,
3151 const SMESH::double_array & theAngles,
3152 CORBA::Boolean theHasRefPoint,
3153 const SMESH::PointStruct & theRefPoint)
3154 throw (SALOME::SALOME_Exception)
3156 MESSAGE("ExtrusionAlongPath");
3157 if ( !myIsPreviewMode ) {
3158 TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
3159 << theIDsOfElements << ", "
3160 << thePathMesh << ", "
3161 << thePathShape << ", "
3162 << theNodeStart << ", "
3163 << theHasAngles << ", "
3164 << theAngles << ", "
3165 << theHasRefPoint << ", "
3166 << "SMESH.PointStruct( "
3167 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3168 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3169 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3171 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3172 extrusionAlongPath( theIDsOfElements,
3185 //=======================================================================
3186 //function : ExtrusionAlongPathObject
3188 //=======================================================================
3190 SMESH::SMESH_MeshEditor::Extrusion_Error
3191 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject,
3192 SMESH::SMESH_Mesh_ptr thePathMesh,
3193 GEOM::GEOM_Object_ptr thePathShape,
3194 CORBA::Long theNodeStart,
3195 CORBA::Boolean theHasAngles,
3196 const SMESH::double_array & theAngles,
3197 CORBA::Boolean theHasRefPoint,
3198 const SMESH::PointStruct & theRefPoint)
3199 throw (SALOME::SALOME_Exception)
3201 if ( !myIsPreviewMode ) {
3202 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
3203 << theObject << ", "
3204 << thePathMesh << ", "
3205 << thePathShape << ", "
3206 << theNodeStart << ", "
3207 << theHasAngles << ", "
3208 << theAngles << ", "
3209 << theHasRefPoint << ", "
3210 << "SMESH.PointStruct( "
3211 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3212 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3213 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3215 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3216 prepareIdSource( theObject );
3217 SMESH::long_array_var anElementsId = theObject->GetIDs();
3218 extrusionAlongPath( anElementsId,
3231 //=======================================================================
3232 //function : ExtrusionAlongPathObject1D
3234 //=======================================================================
3236 SMESH::SMESH_MeshEditor::Extrusion_Error
3237 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject,
3238 SMESH::SMESH_Mesh_ptr thePathMesh,
3239 GEOM::GEOM_Object_ptr thePathShape,
3240 CORBA::Long theNodeStart,
3241 CORBA::Boolean theHasAngles,
3242 const SMESH::double_array & theAngles,
3243 CORBA::Boolean theHasRefPoint,
3244 const SMESH::PointStruct & theRefPoint)
3245 throw (SALOME::SALOME_Exception)
3247 if ( !myIsPreviewMode ) {
3248 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
3249 << theObject << ", "
3250 << thePathMesh << ", "
3251 << thePathShape << ", "
3252 << theNodeStart << ", "
3253 << theHasAngles << ", "
3254 << theAngles << ", "
3255 << theHasRefPoint << ", "
3256 << "SMESH.PointStruct( "
3257 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3258 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3259 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3261 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3262 prepareIdSource( theObject );
3263 SMESH::long_array_var anElementsId = theObject->GetIDs();
3264 extrusionAlongPath( anElementsId,
3278 //=======================================================================
3279 //function : ExtrusionAlongPathObject2D
3281 //=======================================================================
3283 SMESH::SMESH_MeshEditor::Extrusion_Error
3284 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject,
3285 SMESH::SMESH_Mesh_ptr thePathMesh,
3286 GEOM::GEOM_Object_ptr thePathShape,
3287 CORBA::Long theNodeStart,
3288 CORBA::Boolean theHasAngles,
3289 const SMESH::double_array & theAngles,
3290 CORBA::Boolean theHasRefPoint,
3291 const SMESH::PointStruct & theRefPoint)
3292 throw (SALOME::SALOME_Exception)
3294 if ( !myIsPreviewMode ) {
3295 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
3296 << theObject << ", "
3297 << thePathMesh << ", "
3298 << thePathShape << ", "
3299 << theNodeStart << ", "
3300 << theHasAngles << ", "
3301 << theAngles << ", "
3302 << theHasRefPoint << ", "
3303 << "SMESH.PointStruct( "
3304 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3305 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3306 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3308 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3309 prepareIdSource( theObject );
3310 SMESH::long_array_var anElementsId = theObject->GetIDs();
3311 extrusionAlongPath( anElementsId,
3326 //=======================================================================
3327 //function : ExtrusionAlongPathMakeGroups
3329 //=======================================================================
3331 SMESH::ListOfGroups*
3332 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theIDsOfElements,
3333 SMESH::SMESH_Mesh_ptr thePathMesh,
3334 GEOM::GEOM_Object_ptr thePathShape,
3335 CORBA::Long theNodeStart,
3336 CORBA::Boolean theHasAngles,
3337 const SMESH::double_array& theAngles,
3338 CORBA::Boolean theHasRefPoint,
3339 const SMESH::PointStruct& theRefPoint,
3340 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3341 throw (SALOME::SALOME_Exception)
3343 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3345 SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements,
3355 if (!myIsPreviewMode) {
3356 bool isDumpGroups = aGroups && aGroups->length() > 0;
3358 aPythonDump << "(" << aGroups << ", error)";
3360 aPythonDump <<"error";
3362 aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
3363 << theIDsOfElements << ", "
3364 << thePathMesh << ", "
3365 << thePathShape << ", "
3366 << theNodeStart << ", "
3367 << theHasAngles << ", "
3368 << theAngles << ", "
3369 << theHasRefPoint << ", "
3370 << "SMESH.PointStruct( "
3371 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3372 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3373 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3378 //=======================================================================
3379 //function : ExtrusionAlongPathObjectMakeGroups
3381 //=======================================================================
3383 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3384 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3385 SMESH::SMESH_Mesh_ptr thePathMesh,
3386 GEOM::GEOM_Object_ptr thePathShape,
3387 CORBA::Long theNodeStart,
3388 CORBA::Boolean theHasAngles,
3389 const SMESH::double_array& theAngles,
3390 CORBA::Boolean theHasRefPoint,
3391 const SMESH::PointStruct& theRefPoint,
3392 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3393 throw (SALOME::SALOME_Exception)
3395 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3397 prepareIdSource( theObject );
3398 SMESH::long_array_var anElementsId = theObject->GetIDs();
3399 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3410 if (!myIsPreviewMode) {
3411 bool isDumpGroups = aGroups && aGroups->length() > 0;
3413 aPythonDump << "(" << aGroups << ", error)";
3415 aPythonDump <<"error";
3417 aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
3418 << theObject << ", "
3419 << thePathMesh << ", "
3420 << thePathShape << ", "
3421 << theNodeStart << ", "
3422 << theHasAngles << ", "
3423 << theAngles << ", "
3424 << theHasRefPoint << ", "
3425 << "SMESH.PointStruct( "
3426 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3427 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3428 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3433 //=======================================================================
3434 //function : ExtrusionAlongPathObject1DMakeGroups
3436 //=======================================================================
3438 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3439 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3440 SMESH::SMESH_Mesh_ptr thePathMesh,
3441 GEOM::GEOM_Object_ptr thePathShape,
3442 CORBA::Long theNodeStart,
3443 CORBA::Boolean theHasAngles,
3444 const SMESH::double_array& theAngles,
3445 CORBA::Boolean theHasRefPoint,
3446 const SMESH::PointStruct& theRefPoint,
3447 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3448 throw (SALOME::SALOME_Exception)
3450 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3452 prepareIdSource( theObject );
3453 SMESH::long_array_var anElementsId = theObject->GetIDs();
3454 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3466 if (!myIsPreviewMode) {
3467 bool isDumpGroups = aGroups && aGroups->length() > 0;
3469 aPythonDump << "(" << aGroups << ", error)";
3471 aPythonDump << "error";
3473 aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
3474 << theObject << ", "
3475 << thePathMesh << ", "
3476 << thePathShape << ", "
3477 << theNodeStart << ", "
3478 << theHasAngles << ", "
3479 << theAngles << ", "
3480 << theHasRefPoint << ", "
3481 << "SMESH.PointStruct( "
3482 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3483 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3484 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3489 //=======================================================================
3490 //function : ExtrusionAlongPathObject2DMakeGroups
3492 //=======================================================================
3494 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3495 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3496 SMESH::SMESH_Mesh_ptr thePathMesh,
3497 GEOM::GEOM_Object_ptr thePathShape,
3498 CORBA::Long theNodeStart,
3499 CORBA::Boolean theHasAngles,
3500 const SMESH::double_array& theAngles,
3501 CORBA::Boolean theHasRefPoint,
3502 const SMESH::PointStruct& theRefPoint,
3503 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3504 throw (SALOME::SALOME_Exception)
3506 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3508 prepareIdSource( theObject );
3509 SMESH::long_array_var anElementsId = theObject->GetIDs();
3510 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3522 if (!myIsPreviewMode) {
3523 bool isDumpGroups = aGroups && aGroups->length() > 0;
3525 aPythonDump << "(" << aGroups << ", error)";
3527 aPythonDump << "error";
3529 aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
3530 << theObject << ", "
3531 << thePathMesh << ", "
3532 << thePathShape << ", "
3533 << theNodeStart << ", "
3534 << theHasAngles << ", "
3535 << theAngles << ", "
3536 << theHasRefPoint << ", "
3537 << "SMESH.PointStruct( "
3538 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3539 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3540 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3545 //=======================================================================
3546 //function : ExtrusionAlongPathObjX
3548 //=======================================================================
3550 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3551 ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr Object,
3552 SMESH::SMESH_IDSource_ptr Path,
3553 CORBA::Long NodeStart,
3554 CORBA::Boolean HasAngles,
3555 const SMESH::double_array& Angles,
3556 CORBA::Boolean LinearVariation,
3557 CORBA::Boolean HasRefPoint,
3558 const SMESH::PointStruct& RefPoint,
3559 CORBA::Boolean MakeGroups,
3560 SMESH::ElementType ElemType,
3561 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3562 throw (SALOME::SALOME_Exception)
3564 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3566 prepareIdSource( Object );
3567 SMESH::long_array_var anElementsId = Object->GetIDs();
3568 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
3577 (SMDSAbs_ElementType)ElemType,
3580 if (!myIsPreviewMode) {
3581 bool isDumpGroups = aGroups && aGroups->length() > 0;
3583 aPythonDump << "(" << *aGroups << ", error)";
3585 aPythonDump << "error";
3587 aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
3590 << NodeStart << ", "
3591 << HasAngles << ", "
3592 << TVar( Angles ) << ", "
3593 << LinearVariation << ", "
3594 << HasRefPoint << ", "
3595 << "SMESH.PointStruct( "
3596 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3597 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3598 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3599 << MakeGroups << ", "
3600 << ElemType << " )";
3605 //=======================================================================
3606 //function : ExtrusionAlongPathX
3608 //=======================================================================
3610 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3611 ExtrusionAlongPathX(const SMESH::long_array& IDsOfElements,
3612 SMESH::SMESH_IDSource_ptr Path,
3613 CORBA::Long NodeStart,
3614 CORBA::Boolean HasAngles,
3615 const SMESH::double_array& Angles,
3616 CORBA::Boolean LinearVariation,
3617 CORBA::Boolean HasRefPoint,
3618 const SMESH::PointStruct& RefPoint,
3619 CORBA::Boolean MakeGroups,
3620 SMESH::ElementType ElemType,
3621 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3622 throw (SALOME::SALOME_Exception)
3624 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3626 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
3635 (SMDSAbs_ElementType)ElemType,
3638 if (!myIsPreviewMode) {
3639 bool isDumpGroups = aGroups && aGroups->length() > 0;
3641 aPythonDump << "(" << *aGroups << ", error)";
3643 aPythonDump <<"error";
3645 aPythonDump << " = " << this << ".ExtrusionAlongPathX( "
3646 << IDsOfElements << ", "
3648 << NodeStart << ", "
3649 << HasAngles << ", "
3650 << TVar( Angles ) << ", "
3651 << LinearVariation << ", "
3652 << HasRefPoint << ", "
3653 << "SMESH.PointStruct( "
3654 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3655 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3656 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3657 << MakeGroups << ", "
3658 << ElemType << " )";
3663 //================================================================================
3665 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
3666 * of given angles along path steps
3667 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
3668 * which proceeds the extrusion
3669 * \param PathShape is shape(edge); as the mesh can be complex, the edge
3670 * is used to define the sub-mesh for the path
3672 //================================================================================
3674 SMESH::double_array*
3675 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
3676 GEOM::GEOM_Object_ptr thePathShape,
3677 const SMESH::double_array & theAngles)
3679 SMESH::double_array_var aResult = new SMESH::double_array();
3680 int nbAngles = theAngles.length();
3681 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
3683 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3684 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3685 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3686 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
3687 return aResult._retn();
3688 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
3689 if ( nbSteps == nbAngles )
3691 aResult.inout() = theAngles;
3695 aResult->length( nbSteps );
3696 double rAn2St = double( nbAngles ) / double( nbSteps );
3697 double angPrev = 0, angle;
3698 for ( int iSt = 0; iSt < nbSteps; ++iSt )
3700 double angCur = rAn2St * ( iSt+1 );
3701 double angCurFloor = floor( angCur );
3702 double angPrevFloor = floor( angPrev );
3703 if ( angPrevFloor == angCurFloor )
3704 angle = rAn2St * theAngles[ int( angCurFloor ) ];
3707 int iP = int( angPrevFloor );
3708 double angPrevCeil = ceil(angPrev);
3709 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
3711 int iC = int( angCurFloor );
3712 if ( iC < nbAngles )
3713 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
3715 iP = int( angPrevCeil );
3717 angle += theAngles[ iC ];
3719 aResult[ iSt ] = angle;
3724 // Update Python script
3725 TPythonDump() << "rotAngles = " << theAngles;
3726 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
3727 << thePathMesh << ", "
3728 << thePathShape << ", "
3731 return aResult._retn();
3734 //=======================================================================
3737 //=======================================================================
3739 SMESH::ListOfGroups*
3740 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
3741 const SMESH::AxisStruct & theAxis,
3742 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3743 CORBA::Boolean theCopy,
3745 ::SMESH_Mesh* theTargetMesh)
3746 throw (SALOME::SALOME_Exception)
3751 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3752 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3754 if ( theTargetMesh )
3758 switch ( theMirrorType ) {
3759 case SMESH::SMESH_MeshEditor::POINT:
3760 aTrsf.SetMirror( P );
3762 case SMESH::SMESH_MeshEditor::AXIS:
3763 aTrsf.SetMirror( gp_Ax1( P, V ));
3766 aTrsf.SetMirror( gp_Ax2( P, V ));
3769 TIDSortedElemSet copyElements;
3770 TIDSortedElemSet* workElements = & theElements;
3772 if ( myIsPreviewMode )
3774 TPreviewMesh * tmpMesh = getPreviewMesh();
3775 tmpMesh->Copy( theElements, copyElements);
3776 if ( !theCopy && !theTargetMesh )
3778 TIDSortedElemSet elemsAround, elemsAroundCopy;
3779 getElementsAround( theElements, getMeshDS(), elemsAround );
3780 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3782 workElements = & copyElements;
3783 theMakeGroups = false;
3786 ::SMESH_MeshEditor::PGroupIDs groupIds =
3787 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3789 if ( theCopy && !myIsPreviewMode)
3791 if ( theTargetMesh )
3793 theTargetMesh->GetMeshDS()->Modified();
3797 declareMeshModified( /*isReComputeSafe=*/false );
3800 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3802 SMESH_CATCH( SMESH::throwCorbaException );
3806 //=======================================================================
3809 //=======================================================================
3811 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3812 const SMESH::AxisStruct & theAxis,
3813 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3814 CORBA::Boolean theCopy)
3815 throw (SALOME::SALOME_Exception)
3817 if ( !myIsPreviewMode ) {
3818 TPythonDump() << this << ".Mirror( "
3819 << theIDsOfElements << ", "
3821 << mirrorTypeName(theMirrorType) << ", "
3824 if ( theIDsOfElements.length() > 0 )
3826 TIDSortedElemSet elements;
3827 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3828 mirror(elements, theAxis, theMirrorType, theCopy, false);
3833 //=======================================================================
3834 //function : MirrorObject
3836 //=======================================================================
3838 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3839 const SMESH::AxisStruct & theAxis,
3840 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3841 CORBA::Boolean theCopy)
3842 throw (SALOME::SALOME_Exception)
3844 if ( !myIsPreviewMode ) {
3845 TPythonDump() << this << ".MirrorObject( "
3846 << theObject << ", "
3848 << mirrorTypeName(theMirrorType) << ", "
3851 TIDSortedElemSet elements;
3853 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3855 prepareIdSource( theObject );
3856 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3857 mirror(elements, theAxis, theMirrorType, theCopy, false);
3860 //=======================================================================
3861 //function : MirrorMakeGroups
3863 //=======================================================================
3865 SMESH::ListOfGroups*
3866 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3867 const SMESH::AxisStruct& theMirror,
3868 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3869 throw (SALOME::SALOME_Exception)
3871 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3873 SMESH::ListOfGroups * aGroups = 0;
3874 if ( theIDsOfElements.length() > 0 )
3876 TIDSortedElemSet elements;
3877 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3878 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3880 if (!myIsPreviewMode) {
3881 dumpGroupsList(aPythonDump, aGroups);
3882 aPythonDump << this << ".MirrorMakeGroups( "
3883 << theIDsOfElements << ", "
3884 << theMirror << ", "
3885 << mirrorTypeName(theMirrorType) << " )";
3890 //=======================================================================
3891 //function : MirrorObjectMakeGroups
3893 //=======================================================================
3895 SMESH::ListOfGroups*
3896 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3897 const SMESH::AxisStruct& theMirror,
3898 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3899 throw (SALOME::SALOME_Exception)
3901 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3903 SMESH::ListOfGroups * aGroups = 0;
3904 TIDSortedElemSet elements;
3905 prepareIdSource( theObject );
3906 if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3907 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3909 if (!myIsPreviewMode)
3911 dumpGroupsList(aPythonDump,aGroups);
3912 aPythonDump << this << ".MirrorObjectMakeGroups( "
3913 << theObject << ", "
3914 << theMirror << ", "
3915 << mirrorTypeName(theMirrorType) << " )";
3920 //=======================================================================
3921 //function : MirrorMakeMesh
3923 //=======================================================================
3925 SMESH::SMESH_Mesh_ptr
3926 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
3927 const SMESH::AxisStruct& theMirror,
3928 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3929 CORBA::Boolean theCopyGroups,
3930 const char* theMeshName)
3931 throw (SALOME::SALOME_Exception)
3933 SMESH_Mesh_i* mesh_i;
3934 SMESH::SMESH_Mesh_var mesh;
3935 { // open new scope to dump "MakeMesh" command
3936 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3938 TPythonDump pydump; // to prevent dump at mesh creation
3940 mesh = makeMesh( theMeshName );
3941 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3942 if (mesh_i && theIDsOfElements.length() > 0 )
3944 TIDSortedElemSet elements;
3945 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3946 mirror(elements, theMirror, theMirrorType,
3947 false, theCopyGroups, & mesh_i->GetImpl());
3948 mesh_i->CreateGroupServants();
3951 if (!myIsPreviewMode) {
3952 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
3953 << theIDsOfElements << ", "
3954 << theMirror << ", "
3955 << mirrorTypeName(theMirrorType) << ", "
3956 << theCopyGroups << ", '"
3957 << theMeshName << "' )";
3962 if (!myIsPreviewMode && mesh_i)
3963 mesh_i->GetGroups();
3965 return mesh._retn();
3968 //=======================================================================
3969 //function : MirrorObjectMakeMesh
3971 //=======================================================================
3973 SMESH::SMESH_Mesh_ptr
3974 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3975 const SMESH::AxisStruct& theMirror,
3976 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3977 CORBA::Boolean theCopyGroups,
3978 const char* theMeshName)
3979 throw (SALOME::SALOME_Exception)
3981 SMESH_Mesh_i* mesh_i;
3982 SMESH::SMESH_Mesh_var mesh;
3983 { // open new scope to dump "MakeMesh" command
3984 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3986 TPythonDump pydump; // to prevent dump at mesh creation
3988 mesh = makeMesh( theMeshName );
3989 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3990 TIDSortedElemSet elements;
3991 prepareIdSource( theObject );
3993 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3995 mirror(elements, theMirror, theMirrorType,
3996 false, theCopyGroups, & mesh_i->GetImpl());
3997 mesh_i->CreateGroupServants();
3999 if (!myIsPreviewMode) {
4000 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
4001 << theObject << ", "
4002 << theMirror << ", "
4003 << mirrorTypeName(theMirrorType) << ", "
4004 << theCopyGroups << ", '"
4005 << theMeshName << "' )";
4010 if (!myIsPreviewMode && mesh_i)
4011 mesh_i->GetGroups();
4013 return mesh._retn();
4016 //=======================================================================
4017 //function : translate
4019 //=======================================================================
4021 SMESH::ListOfGroups*
4022 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
4023 const SMESH::DirStruct & theVector,
4024 CORBA::Boolean theCopy,
4026 ::SMESH_Mesh* theTargetMesh)
4027 throw (SALOME::SALOME_Exception)
4032 if ( theTargetMesh )
4036 const SMESH::PointStruct * P = &theVector.PS;
4037 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
4039 TIDSortedElemSet copyElements;
4040 TIDSortedElemSet* workElements = &theElements;
4042 if ( myIsPreviewMode )
4044 TPreviewMesh * tmpMesh = getPreviewMesh();
4045 tmpMesh->Copy( theElements, copyElements);
4046 if ( !theCopy && !theTargetMesh )
4048 TIDSortedElemSet elemsAround, elemsAroundCopy;
4049 getElementsAround( theElements, getMeshDS(), elemsAround );
4050 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4052 workElements = & copyElements;
4053 theMakeGroups = false;
4056 ::SMESH_MeshEditor::PGroupIDs groupIds =
4057 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4059 if ( theCopy && !myIsPreviewMode )
4061 if ( theTargetMesh )
4063 theTargetMesh->GetMeshDS()->Modified();
4067 declareMeshModified( /*isReComputeSafe=*/false );
4071 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4073 SMESH_CATCH( SMESH::throwCorbaException );
4077 //=======================================================================
4078 //function : Translate
4080 //=======================================================================
4082 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
4083 const SMESH::DirStruct & theVector,
4084 CORBA::Boolean theCopy)
4085 throw (SALOME::SALOME_Exception)
4087 if (!myIsPreviewMode) {
4088 TPythonDump() << this << ".Translate( "
4089 << theIDsOfElements << ", "
4090 << theVector << ", "
4093 if (theIDsOfElements.length()) {
4094 TIDSortedElemSet elements;
4095 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4096 translate(elements, theVector, theCopy, false);
4100 //=======================================================================
4101 //function : TranslateObject
4103 //=======================================================================
4105 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
4106 const SMESH::DirStruct & theVector,
4107 CORBA::Boolean theCopy)
4108 throw (SALOME::SALOME_Exception)
4110 if (!myIsPreviewMode) {
4111 TPythonDump() << this << ".TranslateObject( "
4112 << theObject << ", "
4113 << theVector << ", "
4116 TIDSortedElemSet elements;
4118 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4120 prepareIdSource( theObject );
4121 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4122 translate(elements, theVector, theCopy, false);
4125 //=======================================================================
4126 //function : TranslateMakeGroups
4128 //=======================================================================
4130 SMESH::ListOfGroups*
4131 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
4132 const SMESH::DirStruct& theVector)
4133 throw (SALOME::SALOME_Exception)
4135 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4137 SMESH::ListOfGroups * aGroups = 0;
4138 if (theIDsOfElements.length()) {
4139 TIDSortedElemSet elements;
4140 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4141 aGroups = translate(elements,theVector,true,true);
4143 if (!myIsPreviewMode) {
4144 dumpGroupsList(aPythonDump, aGroups);
4145 aPythonDump << this << ".TranslateMakeGroups( "
4146 << theIDsOfElements << ", "
4147 << theVector << " )";
4152 //=======================================================================
4153 //function : TranslateObjectMakeGroups
4155 //=======================================================================
4157 SMESH::ListOfGroups*
4158 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4159 const SMESH::DirStruct& theVector)
4160 throw (SALOME::SALOME_Exception)
4162 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4164 SMESH::ListOfGroups * aGroups = 0;
4165 TIDSortedElemSet elements;
4166 prepareIdSource( theObject );
4167 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4168 aGroups = translate(elements, theVector, true, true);
4170 if (!myIsPreviewMode) {
4171 dumpGroupsList(aPythonDump, aGroups);
4172 aPythonDump << this << ".TranslateObjectMakeGroups( "
4173 << theObject << ", "
4174 << theVector << " )";
4179 //=======================================================================
4180 //function : TranslateMakeMesh
4182 //=======================================================================
4184 SMESH::SMESH_Mesh_ptr
4185 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
4186 const SMESH::DirStruct& theVector,
4187 CORBA::Boolean theCopyGroups,
4188 const char* theMeshName)
4189 throw (SALOME::SALOME_Exception)
4191 SMESH_Mesh_i* mesh_i;
4192 SMESH::SMESH_Mesh_var mesh;
4194 { // open new scope to dump "MakeMesh" command
4195 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4197 TPythonDump pydump; // to prevent dump at mesh creation
4199 mesh = makeMesh( theMeshName );
4200 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4202 if ( mesh_i && theIDsOfElements.length() )
4204 TIDSortedElemSet elements;
4205 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4206 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
4207 mesh_i->CreateGroupServants();
4210 if ( !myIsPreviewMode ) {
4211 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
4212 << theIDsOfElements << ", "
4213 << theVector << ", "
4214 << theCopyGroups << ", '"
4215 << theMeshName << "' )";
4220 if (!myIsPreviewMode && mesh_i)
4221 mesh_i->GetGroups();
4223 return mesh._retn();
4226 //=======================================================================
4227 //function : TranslateObjectMakeMesh
4229 //=======================================================================
4231 SMESH::SMESH_Mesh_ptr
4232 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4233 const SMESH::DirStruct& theVector,
4234 CORBA::Boolean theCopyGroups,
4235 const char* theMeshName)
4236 throw (SALOME::SALOME_Exception)
4239 SMESH_Mesh_i* mesh_i;
4240 SMESH::SMESH_Mesh_var mesh;
4241 { // open new scope to dump "MakeMesh" command
4242 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4244 TPythonDump pydump; // to prevent dump at mesh creation
4245 mesh = makeMesh( theMeshName );
4246 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4248 TIDSortedElemSet elements;
4249 prepareIdSource( theObject );
4251 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4253 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
4254 mesh_i->CreateGroupServants();
4256 if ( !myIsPreviewMode ) {
4257 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
4258 << theObject << ", "
4259 << theVector << ", "
4260 << theCopyGroups << ", '"
4261 << theMeshName << "' )";
4266 if (!myIsPreviewMode && mesh_i)
4267 mesh_i->GetGroups();
4269 return mesh._retn();
4271 SMESH_CATCH( SMESH::throwCorbaException );
4275 //=======================================================================
4278 //=======================================================================
4280 SMESH::ListOfGroups*
4281 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
4282 const SMESH::AxisStruct & theAxis,
4283 CORBA::Double theAngle,
4284 CORBA::Boolean theCopy,
4286 ::SMESH_Mesh* theTargetMesh)
4287 throw (SALOME::SALOME_Exception)
4292 if ( theTargetMesh )
4295 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
4296 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
4299 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
4301 TIDSortedElemSet copyElements;
4302 TIDSortedElemSet* workElements = &theElements;
4303 if ( myIsPreviewMode ) {
4304 TPreviewMesh * tmpMesh = getPreviewMesh();
4305 tmpMesh->Copy( theElements, copyElements );
4306 if ( !theCopy && !theTargetMesh )
4308 TIDSortedElemSet elemsAround, elemsAroundCopy;
4309 getElementsAround( theElements, getMeshDS(), elemsAround );
4310 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4312 workElements = ©Elements;
4313 theMakeGroups = false;
4316 ::SMESH_MeshEditor::PGroupIDs groupIds =
4317 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4319 if ( theCopy && !myIsPreviewMode)
4321 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
4322 else declareMeshModified( /*isReComputeSafe=*/false );
4325 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4327 SMESH_CATCH( SMESH::throwCorbaException );
4331 //=======================================================================
4334 //=======================================================================
4336 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
4337 const SMESH::AxisStruct & theAxis,
4338 CORBA::Double theAngle,
4339 CORBA::Boolean theCopy)
4340 throw (SALOME::SALOME_Exception)
4342 if (!myIsPreviewMode) {
4343 TPythonDump() << this << ".Rotate( "
4344 << theIDsOfElements << ", "
4346 << TVar( theAngle ) << ", "
4349 if (theIDsOfElements.length() > 0)
4351 TIDSortedElemSet elements;
4352 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4353 rotate(elements,theAxis,theAngle,theCopy,false);
4357 //=======================================================================
4358 //function : RotateObject
4360 //=======================================================================
4362 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
4363 const SMESH::AxisStruct & theAxis,
4364 CORBA::Double theAngle,
4365 CORBA::Boolean theCopy)
4366 throw (SALOME::SALOME_Exception)
4368 if ( !myIsPreviewMode ) {
4369 TPythonDump() << this << ".RotateObject( "
4370 << theObject << ", "
4372 << TVar( theAngle ) << ", "
4375 TIDSortedElemSet elements;
4376 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4377 prepareIdSource( theObject );
4378 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4379 rotate(elements,theAxis,theAngle,theCopy,false);
4382 //=======================================================================
4383 //function : RotateMakeGroups
4385 //=======================================================================
4387 SMESH::ListOfGroups*
4388 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
4389 const SMESH::AxisStruct& theAxis,
4390 CORBA::Double theAngle)
4391 throw (SALOME::SALOME_Exception)
4393 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4395 SMESH::ListOfGroups * aGroups = 0;
4396 if (theIDsOfElements.length() > 0)
4398 TIDSortedElemSet elements;
4399 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4400 aGroups = rotate(elements,theAxis,theAngle,true,true);
4402 if (!myIsPreviewMode) {
4403 dumpGroupsList(aPythonDump, aGroups);
4404 aPythonDump << this << ".RotateMakeGroups( "
4405 << theIDsOfElements << ", "
4407 << TVar( theAngle ) << " )";
4412 //=======================================================================
4413 //function : RotateObjectMakeGroups
4415 //=======================================================================
4417 SMESH::ListOfGroups*
4418 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4419 const SMESH::AxisStruct& theAxis,
4420 CORBA::Double theAngle)
4421 throw (SALOME::SALOME_Exception)
4423 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4425 SMESH::ListOfGroups * aGroups = 0;
4426 TIDSortedElemSet elements;
4427 prepareIdSource( theObject );
4428 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4429 aGroups = rotate(elements, theAxis, theAngle, true, true);
4431 if (!myIsPreviewMode) {
4432 dumpGroupsList(aPythonDump, aGroups);
4433 aPythonDump << this << ".RotateObjectMakeGroups( "
4434 << theObject << ", "
4436 << TVar( theAngle ) << " )";
4441 //=======================================================================
4442 //function : RotateMakeMesh
4444 //=======================================================================
4446 SMESH::SMESH_Mesh_ptr
4447 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
4448 const SMESH::AxisStruct& theAxis,
4449 CORBA::Double theAngleInRadians,
4450 CORBA::Boolean theCopyGroups,
4451 const char* theMeshName)
4452 throw (SALOME::SALOME_Exception)
4455 SMESH::SMESH_Mesh_var mesh;
4456 SMESH_Mesh_i* mesh_i;
4458 { // open new scope to dump "MakeMesh" command
4459 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4461 TPythonDump pydump; // to prevent dump at mesh creation
4463 mesh = makeMesh( theMeshName );
4464 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4466 if ( mesh_i && theIDsOfElements.length() > 0 )
4468 TIDSortedElemSet elements;
4469 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4470 rotate(elements, theAxis, theAngleInRadians,
4471 false, theCopyGroups, & mesh_i->GetImpl());
4472 mesh_i->CreateGroupServants();
4474 if ( !myIsPreviewMode ) {
4475 pydump << mesh << " = " << this << ".RotateMakeMesh( "
4476 << theIDsOfElements << ", "
4478 << TVar( theAngleInRadians ) << ", "
4479 << theCopyGroups << ", '"
4480 << theMeshName << "' )";
4485 if (!myIsPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
4486 mesh_i->GetGroups();
4488 return mesh._retn();
4490 SMESH_CATCH( SMESH::throwCorbaException );
4494 //=======================================================================
4495 //function : RotateObjectMakeMesh
4497 //=======================================================================
4499 SMESH::SMESH_Mesh_ptr
4500 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4501 const SMESH::AxisStruct& theAxis,
4502 CORBA::Double theAngleInRadians,
4503 CORBA::Boolean theCopyGroups,
4504 const char* theMeshName)
4505 throw (SALOME::SALOME_Exception)
4508 SMESH::SMESH_Mesh_var mesh;
4509 SMESH_Mesh_i* mesh_i;
4511 {// open new scope to dump "MakeMesh" command
4512 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4514 TPythonDump pydump; // to prevent dump at mesh creation
4515 mesh = makeMesh( theMeshName );
4516 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4518 TIDSortedElemSet elements;
4519 prepareIdSource( theObject );
4521 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4523 rotate(elements, theAxis, theAngleInRadians,
4524 false, theCopyGroups, & mesh_i->GetImpl());
4525 mesh_i->CreateGroupServants();
4527 if ( !myIsPreviewMode ) {
4528 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
4529 << theObject << ", "
4531 << TVar( theAngleInRadians ) << ", "
4532 << theCopyGroups << ", '"
4533 << theMeshName << "' )";
4538 if (!myIsPreviewMode && mesh_i)
4539 mesh_i->GetGroups();
4541 return mesh._retn();
4543 SMESH_CATCH( SMESH::throwCorbaException );
4547 //=======================================================================
4550 //=======================================================================
4552 SMESH::ListOfGroups*
4553 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
4554 const SMESH::PointStruct& thePoint,
4555 const SMESH::double_array& theScaleFact,
4556 CORBA::Boolean theCopy,
4558 ::SMESH_Mesh* theTargetMesh)
4559 throw (SALOME::SALOME_Exception)
4563 if ( theScaleFact.length() < 1 )
4564 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
4565 if ( theScaleFact.length() == 2 )
4566 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
4568 if ( theTargetMesh )
4571 TIDSortedElemSet elements;
4572 prepareIdSource( theObject );
4573 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4574 if ( !idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4579 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
4580 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
4582 double tol = std::numeric_limits<double>::max();
4584 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
4585 0, S[1], 0, thePoint.y * (1-S[1]),
4586 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
4588 TIDSortedElemSet copyElements;
4589 TIDSortedElemSet* workElements = &elements;
4590 if ( myIsPreviewMode )
4592 TPreviewMesh * tmpMesh = getPreviewMesh();
4593 tmpMesh->Copy( elements, copyElements);
4594 if ( !theCopy && !theTargetMesh )
4596 TIDSortedElemSet elemsAround, elemsAroundCopy;
4597 getElementsAround( elements, getMeshDS(), elemsAround );
4598 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4600 workElements = & copyElements;
4601 theMakeGroups = false;
4604 ::SMESH_MeshEditor::PGroupIDs groupIds =
4605 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4607 if ( theCopy && !myIsPreviewMode )
4609 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
4610 else declareMeshModified( /*isReComputeSafe=*/false );
4612 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4614 SMESH_CATCH( SMESH::throwCorbaException );
4618 //=======================================================================
4621 //=======================================================================
4623 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
4624 const SMESH::PointStruct& thePoint,
4625 const SMESH::double_array& theScaleFact,
4626 CORBA::Boolean theCopy)
4627 throw (SALOME::SALOME_Exception)
4629 if ( !myIsPreviewMode ) {
4630 TPythonDump() << this << ".Scale( "
4631 << theObject << ", "
4633 << TVar( theScaleFact ) << ", "
4636 scale(theObject, thePoint, theScaleFact, theCopy, false);
4640 //=======================================================================
4641 //function : ScaleMakeGroups
4643 //=======================================================================
4645 SMESH::ListOfGroups*
4646 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4647 const SMESH::PointStruct& thePoint,
4648 const SMESH::double_array& theScaleFact)
4649 throw (SALOME::SALOME_Exception)
4651 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4653 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
4654 if (!myIsPreviewMode) {
4655 dumpGroupsList(aPythonDump, aGroups);
4656 aPythonDump << this << ".Scale("
4659 << TVar( theScaleFact ) << ",True,True)";
4665 //=======================================================================
4666 //function : ScaleMakeMesh
4668 //=======================================================================
4670 SMESH::SMESH_Mesh_ptr
4671 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4672 const SMESH::PointStruct& thePoint,
4673 const SMESH::double_array& theScaleFact,
4674 CORBA::Boolean theCopyGroups,
4675 const char* theMeshName)
4676 throw (SALOME::SALOME_Exception)
4678 SMESH_Mesh_i* mesh_i;
4679 SMESH::SMESH_Mesh_var mesh;
4680 { // open new scope to dump "MakeMesh" command
4681 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4683 TPythonDump pydump; // to prevent dump at mesh creation
4684 mesh = makeMesh( theMeshName );
4685 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4689 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
4690 mesh_i->CreateGroupServants();
4692 if ( !myIsPreviewMode )
4693 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
4694 << theObject << ", "
4696 << TVar( theScaleFact ) << ", "
4697 << theCopyGroups << ", '"
4698 << theMeshName << "' )";
4702 if (!myIsPreviewMode && mesh_i)
4703 mesh_i->GetGroups();
4705 return mesh._retn();
4709 //=======================================================================
4710 //function : FindCoincidentNodes
4712 //=======================================================================
4714 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance,
4715 SMESH::array_of_long_array_out GroupsOfNodes)
4716 throw (SALOME::SALOME_Exception)
4721 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4722 TIDSortedNodeSet nodes; // no input nodes
4723 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4725 GroupsOfNodes = new SMESH::array_of_long_array;
4726 GroupsOfNodes->length( aListOfListOfNodes.size() );
4727 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4728 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
4729 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4730 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4731 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4732 aGroup.length( aListOfNodes.size() );
4733 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4734 aGroup[ j ] = (*lIt)->GetID();
4736 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
4737 << Tolerance << " )";
4739 SMESH_CATCH( SMESH::throwCorbaException );
4742 //=======================================================================
4743 //function : FindCoincidentNodesOnPart
4745 //=======================================================================
4747 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
4748 CORBA::Double Tolerance,
4749 SMESH::array_of_long_array_out GroupsOfNodes)
4750 throw (SALOME::SALOME_Exception)
4755 TIDSortedNodeSet nodes;
4756 prepareIdSource( theObject );
4757 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4759 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4761 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4763 GroupsOfNodes = new SMESH::array_of_long_array;
4764 GroupsOfNodes->length( aListOfListOfNodes.size() );
4765 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4766 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4768 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4769 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4770 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4771 aGroup.length( aListOfNodes.size() );
4772 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4773 aGroup[ j ] = (*lIt)->GetID();
4775 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
4777 << Tolerance << " )";
4779 SMESH_CATCH( SMESH::throwCorbaException );
4782 //================================================================================
4784 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
4785 * ExceptSubMeshOrGroups
4787 //================================================================================
4789 void SMESH_MeshEditor_i::
4790 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
4791 CORBA::Double theTolerance,
4792 SMESH::array_of_long_array_out theGroupsOfNodes,
4793 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups)
4794 throw (SALOME::SALOME_Exception)
4799 TIDSortedNodeSet nodes;
4800 prepareIdSource( theObject );
4801 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4803 for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
4805 TIDSortedNodeSet exceptNodes;
4806 idSourceToNodeSet( theExceptSubMeshOrGroups[i], getMeshDS(), exceptNodes );
4807 TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
4808 for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
4809 nodes.erase( *avoidNode );
4811 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4813 getEditor().FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
4815 theGroupsOfNodes = new SMESH::array_of_long_array;
4816 theGroupsOfNodes->length( aListOfListOfNodes.size() );
4817 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4818 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4820 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4821 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4822 SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
4823 aGroup.length( aListOfNodes.size() );
4824 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4825 aGroup[ j ] = (*lIt)->GetID();
4827 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
4829 << theTolerance << ", "
4830 << theExceptSubMeshOrGroups << " )";
4832 SMESH_CATCH( SMESH::throwCorbaException );
4835 //=======================================================================
4836 //function : MergeNodes
4838 //=======================================================================
4840 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
4841 throw (SALOME::SALOME_Exception)
4846 SMESHDS_Mesh* aMesh = getMeshDS();
4848 TPythonDump aTPythonDump;
4849 aTPythonDump << this << ".MergeNodes([";
4850 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4851 for (int i = 0; i < GroupsOfNodes.length(); i++)
4853 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
4854 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
4855 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
4856 for ( int j = 0; j < aNodeGroup.length(); j++ )
4858 CORBA::Long index = aNodeGroup[ j ];
4859 const SMDS_MeshNode * node = aMesh->FindNode(index);
4861 aListOfNodes.push_back( node );
4863 if ( aListOfNodes.size() < 2 )
4864 aListOfListOfNodes.pop_back();
4866 if ( i > 0 ) aTPythonDump << ", ";
4867 aTPythonDump << aNodeGroup;
4869 getEditor().MergeNodes( aListOfListOfNodes );
4871 aTPythonDump << "])";
4873 declareMeshModified( /*isReComputeSafe=*/false );
4875 SMESH_CATCH( SMESH::throwCorbaException );
4878 //=======================================================================
4879 //function : FindEqualElements
4881 //=======================================================================
4883 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
4884 SMESH::array_of_long_array_out GroupsOfElementsID)
4885 throw (SALOME::SALOME_Exception)
4890 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
4891 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
4893 TIDSortedElemSet elems;
4894 prepareIdSource( theObject );
4895 idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true);
4897 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4898 getEditor().FindEqualElements( elems, aListOfListOfElementsID );
4900 GroupsOfElementsID = new SMESH::array_of_long_array;
4901 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
4903 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt =
4904 aListOfListOfElementsID.begin();
4905 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j)
4907 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
4908 list<int>& listOfIDs = *arraysIt;
4909 aGroup.length( listOfIDs.size() );
4910 list<int>::iterator idIt = listOfIDs.begin();
4911 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k )
4912 aGroup[ k ] = *idIt;
4915 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
4919 SMESH_CATCH( SMESH::throwCorbaException );
4922 //=======================================================================
4923 //function : MergeElements
4925 //=======================================================================
4927 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
4928 throw (SALOME::SALOME_Exception)
4933 TPythonDump aTPythonDump;
4934 aTPythonDump << this << ".MergeElements( [";
4936 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4938 for (int i = 0; i < GroupsOfElementsID.length(); i++) {
4939 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
4940 aListOfListOfElementsID.push_back( list< int >() );
4941 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
4942 for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
4943 CORBA::Long id = anElemsIDGroup[ j ];
4944 aListOfElemsID.push_back( id );
4946 if ( aListOfElemsID.size() < 2 )
4947 aListOfListOfElementsID.pop_back();
4948 if ( i > 0 ) aTPythonDump << ", ";
4949 aTPythonDump << anElemsIDGroup;
4952 getEditor().MergeElements(aListOfListOfElementsID);
4954 declareMeshModified( /*isReComputeSafe=*/true );
4956 aTPythonDump << "] )";
4958 SMESH_CATCH( SMESH::throwCorbaException );
4961 //=======================================================================
4962 //function : MergeEqualElements
4964 //=======================================================================
4966 void SMESH_MeshEditor_i::MergeEqualElements()
4967 throw (SALOME::SALOME_Exception)
4972 getEditor().MergeEqualElements();
4974 declareMeshModified( /*isReComputeSafe=*/true );
4976 TPythonDump() << this << ".MergeEqualElements()";
4978 SMESH_CATCH( SMESH::throwCorbaException );
4981 //=============================================================================
4983 * Move the node to a given point
4985 //=============================================================================
4987 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
4991 throw (SALOME::SALOME_Exception)
4994 initData(/*deleteSearchers=*/false);
4996 const SMDS_MeshNode * node = getMeshDS()->FindNode( NodeID );
5000 if ( theNodeSearcher )
5001 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5003 if ( myIsPreviewMode ) // make preview data
5005 // in a preview mesh, make edges linked to a node
5006 TPreviewMesh& tmpMesh = *getPreviewMesh();
5007 TIDSortedElemSet linkedNodes;
5008 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
5009 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
5010 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
5011 for ( ; nIt != linkedNodes.end(); ++nIt )
5013 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
5014 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
5018 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
5019 // fill preview data
5021 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
5022 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
5024 getMeshDS()->MoveNode(node, x, y, z);
5026 if ( !myIsPreviewMode )
5028 // Update Python script
5029 TPythonDump() << "isDone = " << this << ".MoveNode( "
5030 << NodeID << ", " << TVar(x) << ", " << TVar(y) << ", " << TVar(z) << " )";
5031 declareMeshModified( /*isReComputeSafe=*/false );
5034 SMESH_CATCH( SMESH::throwCorbaException );
5039 //================================================================================
5041 * \brief Return ID of node closest to a given point
5043 //================================================================================
5045 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
5048 throw (SALOME::SALOME_Exception)
5051 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5053 if ( !theNodeSearcher ) {
5054 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
5057 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
5058 return node->GetID();
5060 SMESH_CATCH( SMESH::throwCorbaException );
5064 //================================================================================
5066 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
5067 * move the node closest to the point to point's location and return ID of the node
5069 //================================================================================
5071 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
5074 CORBA::Long theNodeID)
5075 throw (SALOME::SALOME_Exception)
5078 // We keep theNodeSearcher until any mesh modification:
5079 // 1) initData() deletes theNodeSearcher at any edition,
5080 // 2) TSearchersDeleter - at any mesh compute event and mesh change
5082 initData(/*deleteSearchers=*/false);
5084 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5086 int nodeID = theNodeID;
5087 const SMDS_MeshNode* node = getMeshDS()->FindNode( nodeID );
5088 if ( !node ) // preview moving node
5090 if ( !theNodeSearcher ) {
5091 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
5094 node = theNodeSearcher->FindClosestTo( p );
5097 nodeID = node->GetID();
5098 if ( myIsPreviewMode ) // make preview data
5100 // in a preview mesh, make edges linked to a node
5101 TPreviewMesh tmpMesh = *getPreviewMesh();
5102 TIDSortedElemSet linkedNodes;
5103 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
5104 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
5105 for ( ; nIt != linkedNodes.end(); ++nIt )
5107 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
5108 tmpMesh.Copy( &edge );
5111 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
5113 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
5114 // fill preview data
5116 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
5118 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
5122 getMeshDS()->MoveNode(node, x, y, z);
5126 if ( !myIsPreviewMode )
5128 TPythonDump() << "nodeID = " << this
5129 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
5130 << ", " << nodeID << " )";
5132 declareMeshModified( /*isReComputeSafe=*/false );
5137 SMESH_CATCH( SMESH::throwCorbaException );
5141 //=======================================================================
5143 * Return elements of given type where the given point is IN or ON.
5145 * 'ALL' type means elements of any type excluding nodes
5147 //=======================================================================
5149 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
5152 SMESH::ElementType type)
5153 throw (SALOME::SALOME_Exception)
5156 SMESH::long_array_var res = new SMESH::long_array;
5157 vector< const SMDS_MeshElement* > foundElems;
5159 theSearchersDeleter.Set( myMesh );
5160 if ( !theElementSearcher ) {
5161 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
5163 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
5164 SMDSAbs_ElementType( type ),
5166 res->length( foundElems.size() );
5167 for ( int i = 0; i < foundElems.size(); ++i )
5168 res[i] = foundElems[i]->GetID();
5170 if ( !myIsPreviewMode ) // call from tui
5171 TPythonDump() << "res = " << this << ".FindElementsByPoint( "
5179 SMESH_CATCH( SMESH::throwCorbaException );
5183 //=======================================================================
5184 //function : FindAmongElementsByPoint
5185 //purpose : Searching among the given elements, return elements of given type
5186 // where the given point is IN or ON.
5187 // 'ALL' type means elements of any type excluding nodes
5188 //=======================================================================
5191 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
5195 SMESH::ElementType type)
5196 throw (SALOME::SALOME_Exception)
5199 SMESH::long_array_var res = new SMESH::long_array;
5201 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
5202 if ( types->length() == 1 && // a part contains only nodes or 0D elements
5203 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) &&
5204 type != types[0] ) // but search of elements of dim > 0
5207 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
5208 return FindElementsByPoint( x,y,z, type );
5210 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
5212 theSearchersDeleter.Set( myMesh, getPartIOR( elementIDs, type ));
5213 if ( !theElementSearcher )
5215 // create a searcher from elementIDs
5216 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
5217 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
5219 if ( !idSourceToSet( elementIDs, meshDS, elements,
5220 SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
5223 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5224 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
5226 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt );
5229 vector< const SMDS_MeshElement* > foundElems;
5231 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
5232 SMDSAbs_ElementType( type ),
5234 res->length( foundElems.size() );
5235 for ( int i = 0; i < foundElems.size(); ++i )
5236 res[i] = foundElems[i]->GetID();
5238 if ( !myIsPreviewMode ) // call from tui
5239 TPythonDump() << "res = " << this << ".FindAmongElementsByPoint( "
5240 << elementIDs << ", "
5248 SMESH_CATCH( SMESH::throwCorbaException );
5252 //=======================================================================
5253 //function : GetPointState
5254 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
5255 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
5256 //=======================================================================
5258 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
5261 throw (SALOME::SALOME_Exception)
5264 theSearchersDeleter.Set( myMesh );
5265 if ( !theElementSearcher ) {
5266 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
5268 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
5270 SMESH_CATCH( SMESH::throwCorbaException );
5274 //=======================================================================
5275 //function : convError
5277 //=======================================================================
5279 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
5281 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
5285 RETCASE( SEW_BORDER1_NOT_FOUND );
5286 RETCASE( SEW_BORDER2_NOT_FOUND );
5287 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
5288 RETCASE( SEW_BAD_SIDE_NODES );
5289 RETCASE( SEW_VOLUMES_TO_SPLIT );
5290 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
5291 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
5292 RETCASE( SEW_BAD_SIDE1_NODES );
5293 RETCASE( SEW_BAD_SIDE2_NODES );
5295 return SMESH::SMESH_MeshEditor::SEW_OK;
5298 //=======================================================================
5299 //function : SewFreeBorders
5301 //=======================================================================
5303 SMESH::SMESH_MeshEditor::Sew_Error
5304 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
5305 CORBA::Long SecondNodeID1,
5306 CORBA::Long LastNodeID1,
5307 CORBA::Long FirstNodeID2,
5308 CORBA::Long SecondNodeID2,
5309 CORBA::Long LastNodeID2,
5310 CORBA::Boolean CreatePolygons,
5311 CORBA::Boolean CreatePolyedrs)
5312 throw (SALOME::SALOME_Exception)
5317 SMESHDS_Mesh* aMesh = getMeshDS();
5319 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
5320 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
5321 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
5322 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
5323 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
5324 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
5326 if (!aBorderFirstNode ||
5327 !aBorderSecondNode||
5329 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5330 if (!aSide2FirstNode ||
5331 !aSide2SecondNode ||
5333 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
5335 TPythonDump() << "error = " << this << ".SewFreeBorders( "
5336 << FirstNodeID1 << ", "
5337 << SecondNodeID1 << ", "
5338 << LastNodeID1 << ", "
5339 << FirstNodeID2 << ", "
5340 << SecondNodeID2 << ", "
5341 << LastNodeID2 << ", "
5342 << CreatePolygons<< ", "
5343 << CreatePolyedrs<< " )";
5345 SMESH::SMESH_MeshEditor::Sew_Error error =
5346 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5357 declareMeshModified( /*isReComputeSafe=*/false );
5360 SMESH_CATCH( SMESH::throwCorbaException );
5361 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5365 //=======================================================================
5366 //function : SewConformFreeBorders
5368 //=======================================================================
5370 SMESH::SMESH_MeshEditor::Sew_Error
5371 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
5372 CORBA::Long SecondNodeID1,
5373 CORBA::Long LastNodeID1,
5374 CORBA::Long FirstNodeID2,
5375 CORBA::Long SecondNodeID2)
5376 throw (SALOME::SALOME_Exception)
5381 SMESHDS_Mesh* aMesh = getMeshDS();
5383 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
5384 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
5385 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
5386 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
5387 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
5388 const SMDS_MeshNode* aSide2ThirdNode = 0;
5390 if (!aBorderFirstNode ||
5391 !aBorderSecondNode||
5393 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5394 if (!aSide2FirstNode ||
5396 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
5398 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
5399 << FirstNodeID1 << ", "
5400 << SecondNodeID1 << ", "
5401 << LastNodeID1 << ", "
5402 << FirstNodeID2 << ", "
5403 << SecondNodeID2 << " )";
5405 SMESH::SMESH_MeshEditor::Sew_Error error =
5406 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5415 declareMeshModified( /*isReComputeSafe=*/false );
5418 SMESH_CATCH( SMESH::throwCorbaException );
5419 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5423 //=======================================================================
5424 //function : SewBorderToSide
5426 //=======================================================================
5428 SMESH::SMESH_MeshEditor::Sew_Error
5429 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
5430 CORBA::Long SecondNodeIDOnFreeBorder,
5431 CORBA::Long LastNodeIDOnFreeBorder,
5432 CORBA::Long FirstNodeIDOnSide,
5433 CORBA::Long LastNodeIDOnSide,
5434 CORBA::Boolean CreatePolygons,
5435 CORBA::Boolean CreatePolyedrs)
5436 throw (SALOME::SALOME_Exception)
5441 SMESHDS_Mesh* aMesh = getMeshDS();
5443 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
5444 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
5445 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
5446 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
5447 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
5448 const SMDS_MeshNode* aSide2ThirdNode = 0;
5450 if (!aBorderFirstNode ||
5451 !aBorderSecondNode||
5453 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5454 if (!aSide2FirstNode ||
5456 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
5458 TPythonDump() << "error = " << this << ".SewBorderToSide( "
5459 << FirstNodeIDOnFreeBorder << ", "
5460 << SecondNodeIDOnFreeBorder << ", "
5461 << LastNodeIDOnFreeBorder << ", "
5462 << FirstNodeIDOnSide << ", "
5463 << LastNodeIDOnSide << ", "
5464 << CreatePolygons << ", "
5465 << CreatePolyedrs << ") ";
5467 SMESH::SMESH_MeshEditor::Sew_Error error =
5468 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5478 declareMeshModified( /*isReComputeSafe=*/false );
5481 SMESH_CATCH( SMESH::throwCorbaException );
5482 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5486 //=======================================================================
5487 //function : SewSideElements
5489 //=======================================================================
5491 SMESH::SMESH_MeshEditor::Sew_Error
5492 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
5493 const SMESH::long_array& IDsOfSide2Elements,
5494 CORBA::Long NodeID1OfSide1ToMerge,
5495 CORBA::Long NodeID1OfSide2ToMerge,
5496 CORBA::Long NodeID2OfSide1ToMerge,
5497 CORBA::Long NodeID2OfSide2ToMerge)
5498 throw (SALOME::SALOME_Exception)
5503 SMESHDS_Mesh* aMesh = getMeshDS();
5505 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
5506 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
5507 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
5508 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
5510 if (!aFirstNode1ToMerge ||
5511 !aFirstNode2ToMerge )
5512 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
5513 if (!aSecondNode1ToMerge||
5514 !aSecondNode2ToMerge)
5515 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
5517 TIDSortedElemSet aSide1Elems, aSide2Elems;
5518 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
5519 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
5521 TPythonDump() << "error = " << this << ".SewSideElements( "
5522 << IDsOfSide1Elements << ", "
5523 << IDsOfSide2Elements << ", "
5524 << NodeID1OfSide1ToMerge << ", "
5525 << NodeID1OfSide2ToMerge << ", "
5526 << NodeID2OfSide1ToMerge << ", "
5527 << NodeID2OfSide2ToMerge << ")";
5529 SMESH::SMESH_MeshEditor::Sew_Error error =
5530 convError( getEditor().SewSideElements (aSide1Elems, aSide2Elems,
5533 aSecondNode1ToMerge,
5534 aSecondNode2ToMerge));
5536 declareMeshModified( /*isReComputeSafe=*/false );
5539 SMESH_CATCH( SMESH::throwCorbaException );
5540 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5543 //================================================================================
5545 * \brief Set new nodes for given element
5546 * \param ide - element id
5547 * \param newIDs - new node ids
5548 * \retval CORBA::Boolean - true if result is OK
5550 //================================================================================
5552 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
5553 const SMESH::long_array& newIDs)
5554 throw (SALOME::SALOME_Exception)
5559 const SMDS_MeshElement* elem = getMeshDS()->FindElement(ide);
5560 if(!elem) return false;
5562 int nbn = newIDs.length();
5564 vector<const SMDS_MeshNode*> aNodes(nbn);
5567 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(newIDs[i]);
5570 aNodes[nbn1] = aNode;
5573 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
5574 << ide << ", " << newIDs << " )";
5576 MESSAGE("ChangeElementNodes");
5577 bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
5579 declareMeshModified( /*isReComputeSafe=*/ !res );
5583 SMESH_CATCH( SMESH::throwCorbaException );
5587 //=======================================================================
5589 * \brief Makes a part of the mesh quadratic or bi-quadratic
5591 //=======================================================================
5593 void SMESH_MeshEditor_i::convertToQuadratic(CORBA::Boolean theForce3d,
5594 CORBA::Boolean theToBiQuad,
5595 SMESH::SMESH_IDSource_ptr theObject)
5596 throw (SALOME::SALOME_Exception)
5599 TIDSortedElemSet elems;
5601 if ( !( elemsOK = CORBA::is_nil( theObject )))
5603 prepareIdSource( theObject );
5604 elemsOK = idSourceToSet( theObject, getMeshDS(), elems,
5605 SMDSAbs_All, /*emptyIfIsMesh=*/true );
5609 if ( !elems.empty() && (*elems.begin())->GetType() == SMDSAbs_Node )
5610 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5612 if ( elems.empty() ) getEditor().ConvertToQuadratic(theForce3d, theToBiQuad);
5613 else getEditor().ConvertToQuadratic(theForce3d, elems, theToBiQuad);
5615 declareMeshModified( /*isReComputeSafe=*/false );
5618 SMESH_CATCH( SMESH::throwCorbaException );
5621 //=======================================================================
5622 //function : ConvertFromQuadratic
5624 //=======================================================================
5626 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
5627 throw (SALOME::SALOME_Exception)
5629 CORBA::Boolean isDone = getEditor().ConvertFromQuadratic();
5630 TPythonDump() << this << ".ConvertFromQuadratic()";
5631 declareMeshModified( /*isReComputeSafe=*/!isDone );
5635 //=======================================================================
5636 //function : ConvertToQuadratic
5638 //=======================================================================
5640 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
5641 throw (SALOME::SALOME_Exception)
5643 convertToQuadratic( theForce3d, false );
5644 TPythonDump() << this << ".ConvertToQuadratic("<<theForce3d<<")";
5647 //================================================================================
5649 * \brief Makes a part of the mesh quadratic
5651 //================================================================================
5653 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
5654 SMESH::SMESH_IDSource_ptr theObject)
5655 throw (SALOME::SALOME_Exception)
5657 convertToQuadratic( theForce3d, false, theObject );
5658 TPythonDump() << this << ".ConvertToQuadraticObject("<<theForce3d<<", "<<theObject<<")";
5661 //================================================================================
5663 * \brief Makes a part of the mesh bi-quadratic
5665 //================================================================================
5667 void SMESH_MeshEditor_i::ConvertToBiQuadratic(CORBA::Boolean theForce3d,
5668 SMESH::SMESH_IDSource_ptr theObject)
5669 throw (SALOME::SALOME_Exception)
5671 convertToQuadratic( theForce3d, true, theObject );
5672 TPythonDump() << this << ".ConvertToBiQuadratic("<<theForce3d<<", "<<theObject<<")";
5675 //================================================================================
5677 * \brief Makes a part of the mesh linear
5679 //================================================================================
5681 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
5682 throw (SALOME::SALOME_Exception)
5688 TIDSortedElemSet elems;
5689 prepareIdSource( theObject );
5690 if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5692 if ( elems.empty() )
5694 ConvertFromQuadratic();
5696 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5698 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5702 getEditor().ConvertFromQuadratic(elems);
5705 declareMeshModified( /*isReComputeSafe=*/false );
5707 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
5709 SMESH_CATCH( SMESH::throwCorbaException );
5712 //=======================================================================
5713 //function : makeMesh
5714 //purpose : create a named imported mesh
5715 //=======================================================================
5717 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
5719 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
5720 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
5721 SALOMEDS::Study_var study = gen->GetCurrentStudy();
5722 SALOMEDS::SObject_wrap meshSO = gen->ObjectToSObject( study, mesh );
5723 gen->SetName( meshSO, theMeshName, "Mesh" );
5724 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
5726 return mesh._retn();
5729 //=======================================================================
5730 //function : dumpGroupsList
5732 //=======================================================================
5734 void SMESH_MeshEditor_i::dumpGroupsList(TPythonDump & theDumpPython,
5735 const SMESH::ListOfGroups * theGroupList)
5737 bool isDumpGroupList = ( theGroupList && theGroupList->length() > 0 );
5738 if ( isDumpGroupList )
5739 theDumpPython << theGroupList << " = ";
5742 //================================================================================
5744 \brief Generates the unique group name.
5745 \param thePrefix name prefix
5748 //================================================================================
5750 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
5752 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5753 set<string> groupNames;
5755 // Get existing group names
5756 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
5757 SMESH::SMESH_GroupBase_var aGroup = groups[i];
5758 if (CORBA::is_nil(aGroup))
5761 CORBA::String_var name = aGroup->GetName();
5762 groupNames.insert( name.in() );
5766 string name = thePrefix;
5769 while (!groupNames.insert(name).second)
5770 name = SMESH_Comment( thePrefix ) << "_" << index++;
5775 //================================================================================
5777 * \brief Prepare SMESH_IDSource for work
5779 //================================================================================
5781 void SMESH_MeshEditor_i::prepareIdSource(SMESH::SMESH_IDSource_ptr theObject)
5783 if ( SMESH::Filter_i* filter = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5785 SMESH::SMESH_Mesh_var mesh = myMesh_i->_this();
5786 filter->SetMesh( mesh );
5790 //================================================================================
5792 * \brief Duplicates given elements, i.e. creates new elements based on the
5793 * same nodes as the given ones.
5794 * \param theElements - container of elements to duplicate.
5795 * \param theGroupName - a name of group to contain the generated elements.
5796 * If a group with such a name already exists, the new elements
5797 * are added to the existng group, else a new group is created.
5798 * If \a theGroupName is empty, new elements are not added
5800 * \return a group where the new elements are added. NULL if theGroupName == "".
5803 //================================================================================
5805 SMESH::SMESH_Group_ptr
5806 SMESH_MeshEditor_i::DoubleElements(SMESH::SMESH_IDSource_ptr theElements,
5807 const char* theGroupName)
5808 throw (SALOME::SALOME_Exception)
5810 SMESH::SMESH_Group_var newGroup;
5817 TIDSortedElemSet elems;
5818 prepareIdSource( theElements );
5819 if ( idSourceToSet( theElements, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true))
5821 getEditor().DoubleElements( elems );
5823 if ( strlen( theGroupName ) && !getEditor().GetLastCreatedElems().IsEmpty() )
5826 SMESH::ElementType type =
5827 SMESH::ElementType( getEditor().GetLastCreatedElems().Value(1)->GetType() );
5828 // find existing group
5829 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5830 for ( size_t i = 0; i < groups->length(); ++i )
5831 if ( groups[i]->GetType() == type )
5833 CORBA::String_var name = groups[i]->GetName();
5834 if ( strcmp( name, theGroupName ) == 0 ) {
5835 newGroup = SMESH::SMESH_Group::_narrow( groups[i] );
5839 // create a new group
5840 if ( newGroup->_is_nil() )
5841 newGroup = myMesh_i->CreateGroup( type, theGroupName );
5843 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* >( newGroup ))
5845 SMESHDS_Group* groupDS = static_cast< SMESHDS_Group* >( group_i->GetGroupDS() );
5846 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
5847 for ( int i = 1; i <= aSeq.Length(); i++ )
5848 groupDS->SMDSGroup().Add( aSeq(i) );
5853 if ( !newGroup->_is_nil() )
5854 pyDump << newGroup << " = ";
5855 pyDump << this << ".DoubleElements( "
5856 << theElements << ", " << "'" << theGroupName <<"')";
5858 SMESH_CATCH( SMESH::throwCorbaException );
5860 return newGroup._retn();
5863 //================================================================================
5865 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5866 \param theNodes - identifiers of nodes to be doubled
5867 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
5868 nodes. If list of element identifiers is empty then nodes are doubled but
5869 they not assigned to elements
5870 \return TRUE if operation has been completed successfully, FALSE otherwise
5871 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
5873 //================================================================================
5875 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
5876 const SMESH::long_array& theModifiedElems )
5877 throw (SALOME::SALOME_Exception)
5882 list< int > aListOfNodes;
5884 for ( i = 0, n = theNodes.length(); i < n; i++ )
5885 aListOfNodes.push_back( theNodes[ i ] );
5887 list< int > aListOfElems;
5888 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5889 aListOfElems.push_back( theModifiedElems[ i ] );
5891 bool aResult = getEditor().DoubleNodes( aListOfNodes, aListOfElems );
5893 declareMeshModified( /*isReComputeSafe=*/ !aResult );
5895 // Update Python script
5896 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
5900 SMESH_CATCH( SMESH::throwCorbaException );
5904 //================================================================================
5906 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5907 This method provided for convenience works as DoubleNodes() described above.
5908 \param theNodeId - identifier of node to be doubled.
5909 \param theModifiedElems - identifiers of elements to be updated.
5910 \return TRUE if operation has been completed successfully, FALSE otherwise
5911 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
5913 //================================================================================
5915 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
5916 const SMESH::long_array& theModifiedElems )
5917 throw (SALOME::SALOME_Exception)
5920 SMESH::long_array_var aNodes = new SMESH::long_array;
5921 aNodes->length( 1 );
5922 aNodes[ 0 ] = theNodeId;
5924 TPythonDump pyDump; // suppress dump by the next line
5926 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
5928 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
5932 SMESH_CATCH( SMESH::throwCorbaException );
5936 //================================================================================
5938 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5939 This method provided for convenience works as DoubleNodes() described above.
5940 \param theNodes - group of nodes to be doubled.
5941 \param theModifiedElems - group of elements to be updated.
5942 \return TRUE if operation has been completed successfully, FALSE otherwise
5943 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
5945 //================================================================================
5947 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
5948 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5949 throw (SALOME::SALOME_Exception)
5952 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5955 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5956 SMESH::long_array_var aModifiedElems;
5957 if ( !CORBA::is_nil( theModifiedElems ) )
5958 aModifiedElems = theModifiedElems->GetListOfID();
5961 aModifiedElems = new SMESH::long_array;
5962 aModifiedElems->length( 0 );
5965 TPythonDump pyDump; // suppress dump by the next line
5967 bool done = DoubleNodes( aNodes, aModifiedElems );
5969 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
5973 SMESH_CATCH( SMESH::throwCorbaException );
5977 //================================================================================
5979 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5980 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
5981 * \param theNodes - group of nodes to be doubled.
5982 * \param theModifiedElems - group of elements to be updated.
5983 * \return a new group with newly created nodes
5984 * \sa DoubleNodeGroup()
5986 //================================================================================
5988 SMESH::SMESH_Group_ptr
5989 SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
5990 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5991 throw (SALOME::SALOME_Exception)
5994 SMESH::SMESH_Group_var aNewGroup;
5996 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5997 return aNewGroup._retn();
6000 SMESH::long_array_var aNodes = theNodes->GetListOfID();
6001 SMESH::long_array_var aModifiedElems;
6002 if ( !CORBA::is_nil( theModifiedElems ) )
6003 aModifiedElems = theModifiedElems->GetListOfID();
6005 aModifiedElems = new SMESH::long_array;
6006 aModifiedElems->length( 0 );
6009 TPythonDump pyDump; // suppress dump by the next line
6011 bool aResult = DoubleNodes( aNodes, aModifiedElems );
6014 // Create group with newly created nodes
6015 SMESH::long_array_var anIds = GetLastCreatedNodes();
6016 if (anIds->length() > 0) {
6017 string anUnindexedName (theNodes->GetName());
6018 string aNewName = generateGroupName(anUnindexedName + "_double");
6019 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6020 aNewGroup->Add(anIds);
6021 pyDump << aNewGroup << " = ";
6025 pyDump << this << ".DoubleNodeGroupNew( " << theNodes << ", "
6026 << theModifiedElems << " )";
6028 return aNewGroup._retn();
6030 SMESH_CATCH( SMESH::throwCorbaException );
6034 //================================================================================
6036 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6037 This method provided for convenience works as DoubleNodes() described above.
6038 \param theNodes - list of groups of nodes to be doubled
6039 \param theModifiedElems - list of groups of elements to be updated.
6040 \return TRUE if operation has been completed successfully, FALSE otherwise
6041 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
6043 //================================================================================
6045 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
6046 const SMESH::ListOfGroups& theModifiedElems )
6047 throw (SALOME::SALOME_Exception)
6052 std::list< int > aNodes;
6054 for ( i = 0, n = theNodes.length(); i < n; i++ )
6056 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
6057 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
6059 SMESH::long_array_var aCurr = aGrp->GetListOfID();
6060 for ( j = 0, m = aCurr->length(); j < m; j++ )
6061 aNodes.push_back( aCurr[ j ] );
6065 std::list< int > anElems;
6066 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
6068 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
6069 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
6071 SMESH::long_array_var aCurr = aGrp->GetListOfID();
6072 for ( j = 0, m = aCurr->length(); j < m; j++ )
6073 anElems.push_back( aCurr[ j ] );
6077 bool aResult = getEditor().DoubleNodes( aNodes, anElems );
6079 declareMeshModified( /*isReComputeSafe=*/false );
6081 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
6085 SMESH_CATCH( SMESH::throwCorbaException );
6089 //================================================================================
6091 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6092 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
6093 * \param theNodes - group of nodes to be doubled.
6094 * \param theModifiedElems - group of elements to be updated.
6095 * \return a new group with newly created nodes
6096 * \sa DoubleNodeGroups()
6098 //================================================================================
6100 SMESH::SMESH_Group_ptr
6101 SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
6102 const SMESH::ListOfGroups& theModifiedElems )
6103 throw (SALOME::SALOME_Exception)
6105 SMESH::SMESH_Group_var aNewGroup;
6107 TPythonDump pyDump; // suppress dump by the next line
6109 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
6113 // Create group with newly created nodes
6114 SMESH::long_array_var anIds = GetLastCreatedNodes();
6115 if (anIds->length() > 0) {
6116 string anUnindexedName (theNodes[0]->GetName());
6117 string aNewName = generateGroupName(anUnindexedName + "_double");
6118 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6119 aNewGroup->Add(anIds);
6120 pyDump << aNewGroup << " = ";
6124 pyDump << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
6125 << theModifiedElems << " )";
6127 return aNewGroup._retn();
6131 //================================================================================
6133 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6134 \param theElems - the list of elements (edges or faces) to be replicated
6135 The nodes for duplication could be found from these elements
6136 \param theNodesNot - list of nodes to NOT replicate
6137 \param theAffectedElems - the list of elements (cells and edges) to which the
6138 replicated nodes should be associated to.
6139 \return TRUE if operation has been completed successfully, FALSE otherwise
6140 \sa DoubleNodeGroup(), DoubleNodeGroups()
6142 //================================================================================
6144 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
6145 const SMESH::long_array& theNodesNot,
6146 const SMESH::long_array& theAffectedElems )
6147 throw (SALOME::SALOME_Exception)
6152 SMESHDS_Mesh* aMeshDS = getMeshDS();
6153 TIDSortedElemSet anElems, aNodes, anAffected;
6154 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
6155 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
6156 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
6158 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6160 // Update Python script
6161 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
6162 << theNodesNot << ", " << theAffectedElems << " )";
6164 declareMeshModified( /*isReComputeSafe=*/false );
6167 SMESH_CATCH( SMESH::throwCorbaException );
6171 //================================================================================
6173 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6174 \param theElems - the list of elements (edges or faces) to be replicated
6175 The nodes for duplication could be found from these elements
6176 \param theNodesNot - list of nodes to NOT replicate
6177 \param theShape - shape to detect affected elements (element which geometric center
6178 located on or inside shape).
6179 The replicated nodes should be associated to affected elements.
6180 \return TRUE if operation has been completed successfully, FALSE otherwise
6181 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
6183 //================================================================================
6185 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
6186 const SMESH::long_array& theNodesNot,
6187 GEOM::GEOM_Object_ptr theShape )
6188 throw (SALOME::SALOME_Exception)
6194 SMESHDS_Mesh* aMeshDS = getMeshDS();
6195 TIDSortedElemSet anElems, aNodes;
6196 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
6197 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
6199 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6200 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6202 // Update Python script
6203 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
6204 << theNodesNot << ", " << theShape << " )";
6206 declareMeshModified( /*isReComputeSafe=*/false );
6209 SMESH_CATCH( SMESH::throwCorbaException );
6213 //================================================================================
6215 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6216 \param theElems - group of of elements (edges or faces) to be replicated
6217 \param theNodesNot - group of nodes not to replicated
6218 \param theAffectedElems - group of elements to which the replicated nodes
6219 should be associated to.
6220 \return TRUE if operation has been completed successfully, FALSE otherwise
6221 \sa DoubleNodes(), DoubleNodeGroups()
6223 //================================================================================
6226 SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
6227 SMESH::SMESH_GroupBase_ptr theNodesNot,
6228 SMESH::SMESH_GroupBase_ptr theAffectedElems)
6229 throw (SALOME::SALOME_Exception)
6232 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6238 SMESHDS_Mesh* aMeshDS = getMeshDS();
6239 TIDSortedElemSet anElems, aNodes, anAffected;
6240 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6241 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6242 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
6244 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6246 // Update Python script
6247 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
6248 << theNodesNot << ", " << theAffectedElems << " )";
6250 declareMeshModified( /*isReComputeSafe=*/false );
6253 SMESH_CATCH( SMESH::throwCorbaException );
6257 //================================================================================
6259 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6260 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
6261 * \param theElems - group of of elements (edges or faces) to be replicated
6262 * \param theNodesNot - group of nodes not to replicated
6263 * \param theAffectedElems - group of elements to which the replicated nodes
6264 * should be associated to.
6265 * \return a new group with newly created elements
6266 * \sa DoubleNodeElemGroup()
6268 //================================================================================
6270 SMESH::SMESH_Group_ptr
6271 SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
6272 SMESH::SMESH_GroupBase_ptr theNodesNot,
6273 SMESH::SMESH_GroupBase_ptr theAffectedElems)
6274 throw (SALOME::SALOME_Exception)
6277 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroup2New( theElems,
6281 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
6282 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
6284 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupNew( "
6286 << theNodesNot << ", "
6287 << theAffectedElems << " )";
6289 return elemGroup._retn();
6292 //================================================================================
6294 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6295 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
6296 * \param theElems - group of of elements (edges or faces) to be replicated
6297 * \param theNodesNot - group of nodes not to replicated
6298 * \param theAffectedElems - group of elements to which the replicated nodes
6299 * should be associated to.
6300 * \return a new group with newly created elements
6301 * \sa DoubleNodeElemGroup()
6303 //================================================================================
6305 SMESH::ListOfGroups*
6306 SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
6307 SMESH::SMESH_GroupBase_ptr theNodesNot,
6308 SMESH::SMESH_GroupBase_ptr theAffectedElems,
6309 CORBA::Boolean theElemGroupNeeded,
6310 CORBA::Boolean theNodeGroupNeeded)
6311 throw (SALOME::SALOME_Exception)
6314 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
6315 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
6316 aTwoGroups->length( 2 );
6318 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6319 return aTwoGroups._retn();
6324 SMESHDS_Mesh* aMeshDS = getMeshDS();
6325 TIDSortedElemSet anElems, aNodes, anAffected;
6326 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6327 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6328 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
6331 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6333 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6339 // Create group with newly created elements
6340 CORBA::String_var elemGroupName = theElems->GetName();
6341 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
6342 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
6344 SMESH::long_array_var anIds = GetLastCreatedElems();
6345 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
6346 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
6347 aNewElemGroup->Add(anIds);
6349 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
6351 SMESH::long_array_var anIds = GetLastCreatedNodes();
6352 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6353 aNewNodeGroup->Add(anIds);
6357 // Update Python script
6360 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
6361 else pyDump << aNewElemGroup << ", ";
6362 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
6363 else pyDump << aNewNodeGroup << " ] = ";
6365 pyDump << this << ".DoubleNodeElemGroup2New( " << theElems << ", "
6366 << theNodesNot << ", "
6367 << theAffectedElems << ", "
6368 << theElemGroupNeeded << ", "
6369 << theNodeGroupNeeded <<" )";
6371 aTwoGroups[0] = aNewElemGroup._retn();
6372 aTwoGroups[1] = aNewNodeGroup._retn();
6373 return aTwoGroups._retn();
6375 SMESH_CATCH( SMESH::throwCorbaException );
6379 //================================================================================
6381 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6382 \param theElems - group of of elements (edges or faces) to be replicated
6383 \param theNodesNot - group of nodes not to replicated
6384 \param theShape - shape to detect affected elements (element which geometric center
6385 located on or inside shape).
6386 The replicated nodes should be associated to affected elements.
6387 \return TRUE if operation has been completed successfully, FALSE otherwise
6388 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
6390 //================================================================================
6393 SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
6394 SMESH::SMESH_GroupBase_ptr theNodesNot,
6395 GEOM::GEOM_Object_ptr theShape )
6396 throw (SALOME::SALOME_Exception)
6399 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6405 SMESHDS_Mesh* aMeshDS = getMeshDS();
6406 TIDSortedElemSet anElems, aNodes, anAffected;
6407 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6408 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6410 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6411 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6414 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6416 // Update Python script
6417 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
6418 << theNodesNot << ", " << theShape << " )";
6421 SMESH_CATCH( SMESH::throwCorbaException );
6425 //================================================================================
6427 * \brief Re-load elements from a list of groups into a TIDSortedElemSet
6428 * \param [in] theGrpList - groups
6429 * \param [in] theMeshDS - mesh
6430 * \param [out] theElemSet - set of elements
6431 * \param [in] theIsNodeGrp - is \a theGrpList includes goups of nodes
6433 //================================================================================
6435 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
6436 SMESHDS_Mesh* theMeshDS,
6437 TIDSortedElemSet& theElemSet,
6438 const bool theIsNodeGrp)
6440 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
6442 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
6443 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
6444 : aGrp->GetType() != SMESH::NODE ) )
6446 SMESH::long_array_var anIDs = aGrp->GetIDs();
6447 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
6452 //================================================================================
6454 \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6455 This method provided for convenience works as DoubleNodes() described above.
6456 \param theElems - list of groups of elements (edges or faces) to be replicated
6457 \param theNodesNot - list of groups of nodes not to replicated
6458 \param theAffectedElems - group of elements to which the replicated nodes
6459 should be associated to.
6460 \return TRUE if operation has been completed successfully, FALSE otherwise
6461 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
6463 //================================================================================
6466 SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
6467 const SMESH::ListOfGroups& theNodesNot,
6468 const SMESH::ListOfGroups& theAffectedElems)
6469 throw (SALOME::SALOME_Exception)
6475 SMESHDS_Mesh* aMeshDS = getMeshDS();
6476 TIDSortedElemSet anElems, aNodes, anAffected;
6477 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6478 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6479 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6481 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6483 // Update Python script
6484 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
6485 << &theNodesNot << ", " << &theAffectedElems << " )";
6487 declareMeshModified( /*isReComputeSafe=*/false );
6490 SMESH_CATCH( SMESH::throwCorbaException );
6494 //================================================================================
6496 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6497 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6498 \param theElems - list of groups of elements (edges or faces) to be replicated
6499 \param theNodesNot - list of groups of nodes not to replicated
6500 \param theAffectedElems - group of elements to which the replicated nodes
6501 should be associated to.
6502 * \return a new group with newly created elements
6503 * \sa DoubleNodeElemGroups()
6505 //================================================================================
6507 SMESH::SMESH_Group_ptr
6508 SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
6509 const SMESH::ListOfGroups& theNodesNot,
6510 const SMESH::ListOfGroups& theAffectedElems)
6511 throw (SALOME::SALOME_Exception)
6514 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroups2New( theElems,
6518 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
6519 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
6521 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupsNew( "
6523 << theNodesNot << ", "
6524 << theAffectedElems << " )";
6526 return elemGroup._retn();
6529 //================================================================================
6531 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6532 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6533 \param theElems - list of groups of elements (edges or faces) to be replicated
6534 \param theNodesNot - list of groups of nodes not to replicated
6535 \param theAffectedElems - group of elements to which the replicated nodes
6536 should be associated to.
6537 * \return a new group with newly created elements
6538 * \sa DoubleNodeElemGroups()
6540 //================================================================================
6542 SMESH::ListOfGroups*
6543 SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems,
6544 const SMESH::ListOfGroups& theNodesNot,
6545 const SMESH::ListOfGroups& theAffectedElems,
6546 CORBA::Boolean theElemGroupNeeded,
6547 CORBA::Boolean theNodeGroupNeeded)
6548 throw (SALOME::SALOME_Exception)
6551 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
6552 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
6553 aTwoGroups->length( 2 );
6558 SMESHDS_Mesh* aMeshDS = getMeshDS();
6559 TIDSortedElemSet anElems, aNodes, anAffected;
6560 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6561 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6562 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6564 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6566 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6571 // Create group with newly created elements
6572 CORBA::String_var elemGroupName = theElems[0]->GetName();
6573 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
6574 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
6576 SMESH::long_array_var anIds = GetLastCreatedElems();
6577 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
6578 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
6579 aNewElemGroup->Add(anIds);
6581 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
6583 SMESH::long_array_var anIds = GetLastCreatedNodes();
6584 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6585 aNewNodeGroup->Add(anIds);
6589 // Update Python script
6592 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
6593 else pyDump << aNewElemGroup << ", ";
6594 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
6595 else pyDump << aNewNodeGroup << " ] = ";
6597 pyDump << this << ".DoubleNodeElemGroups2New( " << &theElems << ", "
6598 << &theNodesNot << ", "
6599 << &theAffectedElems << ", "
6600 << theElemGroupNeeded << ", "
6601 << theNodeGroupNeeded << " )";
6603 aTwoGroups[0] = aNewElemGroup._retn();
6604 aTwoGroups[1] = aNewNodeGroup._retn();
6605 return aTwoGroups._retn();
6607 SMESH_CATCH( SMESH::throwCorbaException );
6611 //================================================================================
6613 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6614 This method provided for convenience works as DoubleNodes() described above.
6615 \param theElems - list of groups of elements (edges or faces) to be replicated
6616 \param theNodesNot - list of groups of nodes not to replicated
6617 \param theShape - shape to detect affected elements (element which geometric center
6618 located on or inside shape).
6619 The replicated nodes should be associated to affected elements.
6620 \return TRUE if operation has been completed successfully, FALSE otherwise
6621 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
6623 //================================================================================
6626 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
6627 const SMESH::ListOfGroups& theNodesNot,
6628 GEOM::GEOM_Object_ptr theShape )
6629 throw (SALOME::SALOME_Exception)
6635 SMESHDS_Mesh* aMeshDS = getMeshDS();
6636 TIDSortedElemSet anElems, aNodes;
6637 listOfGroupToSet(theElems, aMeshDS, anElems,false );
6638 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6640 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6641 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6643 // Update Python script
6644 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
6645 << &theNodesNot << ", " << theShape << " )";
6647 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6650 SMESH_CATCH( SMESH::throwCorbaException );
6654 //================================================================================
6656 \brief Identify the elements that will be affected by node duplication (actual
6657 duplication is not performed.
6658 This method is the first step of DoubleNodeElemGroupsInRegion.
6659 \param theElems - list of groups of elements (edges or faces) to be replicated
6660 \param theNodesNot - list of groups of nodes not to replicated
6661 \param theShape - shape to detect affected elements (element which geometric center
6662 located on or inside shape).
6663 The replicated nodes should be associated to affected elements.
6664 \return groups of affected elements
6665 \sa DoubleNodeElemGroupsInRegion()
6667 //================================================================================
6668 SMESH::ListOfGroups*
6669 SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theElems,
6670 const SMESH::ListOfGroups& theNodesNot,
6671 GEOM::GEOM_Object_ptr theShape )
6672 throw (SALOME::SALOME_Exception)
6675 MESSAGE("AffectedElemGroupsInRegion");
6676 SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
6677 bool isEdgeGroup = false;
6678 bool isFaceGroup = false;
6679 bool isVolumeGroup = false;
6680 SMESH::SMESH_Group_var aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE, "affectedEdges");
6681 SMESH::SMESH_Group_var aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE, "affectedFaces");
6682 SMESH::SMESH_Group_var aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME, "affectedVolumes");
6686 ::SMESH_MeshEditor aMeshEditor(myMesh);
6688 SMESHDS_Mesh* aMeshDS = getMeshDS();
6689 TIDSortedElemSet anElems, aNodes;
6690 listOfGroupToSet(theElems, aMeshDS, anElems, false);
6691 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true);
6693 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape(theShape);
6694 TIDSortedElemSet anAffected;
6695 bool aResult = aMeshEditor.AffectedElemGroupsInRegion(anElems, aNodes, aShape, anAffected);
6698 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6703 int lg = anAffected.size();
6704 MESSAGE("lg="<< lg);
6705 SMESH::long_array_var volumeIds = new SMESH::long_array;
6706 volumeIds->length(lg);
6707 SMESH::long_array_var faceIds = new SMESH::long_array;
6708 faceIds->length(lg);
6709 SMESH::long_array_var edgeIds = new SMESH::long_array;
6710 edgeIds->length(lg);
6715 TIDSortedElemSet::const_iterator eIt = anAffected.begin();
6716 for (; eIt != anAffected.end(); ++eIt)
6718 const SMDS_MeshElement* anElem = *eIt;
6721 int elemId = anElem->GetID();
6722 if (myMesh->GetElementType(elemId, true) == SMDSAbs_Volume)
6723 volumeIds[ivol++] = elemId;
6724 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Face)
6725 faceIds[iface++] = elemId;
6726 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Edge)
6727 edgeIds[iedge++] = elemId;
6729 volumeIds->length(ivol);
6730 faceIds->length(iface);
6731 edgeIds->length(iedge);
6733 aNewVolumeGroup->Add(volumeIds);
6734 aNewFaceGroup->Add(faceIds);
6735 aNewEdgeGroup->Add(edgeIds);
6736 isVolumeGroup = (aNewVolumeGroup->Size() > 0);
6737 isFaceGroup = (aNewFaceGroup->Size() > 0);
6738 isEdgeGroup = (aNewEdgeGroup->Size() > 0);
6742 if (isEdgeGroup) nbGroups++;
6743 if (isFaceGroup) nbGroups++;
6744 if (isVolumeGroup) nbGroups++;
6745 aListOfGroups->length(nbGroups);
6748 if (isEdgeGroup) aListOfGroups[i++] = aNewEdgeGroup._retn();
6749 if (isFaceGroup) aListOfGroups[i++] = aNewFaceGroup._retn();
6750 if (isVolumeGroup) aListOfGroups[i++] = aNewVolumeGroup._retn();
6752 // Update Python script
6755 if (isEdgeGroup) pyDump << aNewEdgeGroup << ", ";
6756 if (isFaceGroup) pyDump << aNewFaceGroup << ", ";
6757 if (isVolumeGroup) pyDump << aNewVolumeGroup << ", ";
6759 pyDump << this << ".AffectedElemGroupsInRegion( "
6760 << &theElems << ", " << &theNodesNot << ", " << theShape << " )";
6762 return aListOfGroups._retn();
6764 SMESH_CATCH( SMESH::throwCorbaException );
6768 //================================================================================
6770 \brief Generated skin mesh (containing 2D cells) from 3D mesh
6771 The created 2D mesh elements based on nodes of free faces of boundary volumes
6772 \return TRUE if operation has been completed successfully, FALSE otherwise
6774 //================================================================================
6776 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
6777 throw (SALOME::SALOME_Exception)
6782 bool aResult = getEditor().Make2DMeshFrom3D();
6784 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
6786 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6789 SMESH_CATCH( SMESH::throwCorbaException );
6793 //================================================================================
6795 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
6796 * The list of groups must contain at least two groups. The groups have to be disjoint:
6797 * no common element into two different groups.
6798 * The nodes of the internal faces at the boundaries of the groups are doubled.
6799 * Optionally, the internal faces are replaced by flat elements.
6800 * Triangles are transformed into prisms, and quadrangles into hexahedrons.
6801 * The flat elements are stored in groups of volumes.
6802 * These groups are named according to the position of the group in the list:
6803 * 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.
6804 * 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.
6805 * All the flat elements are gathered into the group named "joints3D" (or "joints2D" in 2D situation).
6806 * The flat element of the multiple junctions between the simple junction are stored in a group named "jointsMultiples".
6807 * @param theDomains - list of groups of volumes
6808 * @param createJointElems - if TRUE, create the elements
6809 * @return TRUE if operation has been completed successfully, FALSE otherwise
6811 //================================================================================
6814 SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
6815 CORBA::Boolean createJointElems )
6816 throw (SALOME::SALOME_Exception)
6818 bool aResult = false;
6823 SMESHDS_Mesh* aMeshDS = getMeshDS();
6825 // MESSAGE("theDomains.length = "<<theDomains.length());
6826 if ( theDomains.length() <= 1 )
6827 THROW_SALOME_CORBA_EXCEPTION("At least 2 groups are required.", SALOME::BAD_PARAM);
6828 vector<TIDSortedElemSet> domains;
6831 for ( int i = 0, n = theDomains.length(); i < n; i++ )
6833 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
6834 if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
6836 // if ( aGrp->GetType() != SMESH::VOLUME )
6837 // THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
6838 TIDSortedElemSet domain;
6840 domains.push_back(domain);
6841 SMESH::long_array_var anIDs = aGrp->GetIDs();
6842 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
6846 aResult = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems );
6847 // TODO publish the groups of flat elements in study
6849 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6851 // Update Python script
6852 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
6853 << ", " << createJointElems << " )";
6855 SMESH_CATCH( SMESH::throwCorbaException );
6860 //================================================================================
6862 * \brief Double nodes on some external faces and create flat elements.
6863 * Flat elements are mainly used by some types of mechanic calculations.
6865 * Each group of the list must be constituted of faces.
6866 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
6867 * @param theGroupsOfFaces - list of groups of faces
6868 * @return TRUE if operation has been completed successfully, FALSE otherwise
6870 //================================================================================
6873 SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
6874 throw (SALOME::SALOME_Exception)
6879 SMESHDS_Mesh* aMeshDS = getMeshDS();
6881 vector<TIDSortedElemSet> faceGroups;
6884 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
6886 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
6887 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
6889 TIDSortedElemSet faceGroup;
6891 faceGroups.push_back(faceGroup);
6892 SMESH::long_array_var anIDs = aGrp->GetIDs();
6893 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
6897 bool aResult = getEditor().CreateFlatElementsOnFacesGroups( faceGroups );
6898 // TODO publish the groups of flat elements in study
6900 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6902 // Update Python script
6903 TPythonDump() << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
6906 SMESH_CATCH( SMESH::throwCorbaException );
6910 //================================================================================
6912 * \brief Identify all the elements around a geom shape, get the faces delimiting
6915 * Build groups of volume to remove, groups of faces to replace on the skin of the
6916 * object, groups of faces to remove inside the object, (idem edges).
6917 * Build ordered list of nodes at the border of each group of faces to replace
6918 * (to be used to build a geom subshape).
6920 //================================================================================
6922 void SMESH_MeshEditor_i::CreateHoleSkin(CORBA::Double radius,
6923 GEOM::GEOM_Object_ptr theShape,
6924 const char* groupName,
6925 const SMESH::double_array& theNodesCoords,
6926 SMESH::array_of_long_array_out GroupsOfNodes)
6927 throw (SALOME::SALOME_Exception)
6932 std::vector<std::vector<int> > aListOfListOfNodes;
6933 ::SMESH_MeshEditor aMeshEditor( myMesh );
6935 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
6936 if ( !theNodeSearcher )
6937 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
6939 vector<double> nodesCoords;
6940 for (int i = 0; i < theNodesCoords.length(); i++)
6942 nodesCoords.push_back( theNodesCoords[i] );
6945 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6946 aMeshEditor.CreateHoleSkin(radius, aShape, theNodeSearcher, groupName,
6947 nodesCoords, aListOfListOfNodes);
6949 GroupsOfNodes = new SMESH::array_of_long_array;
6950 GroupsOfNodes->length( aListOfListOfNodes.size() );
6951 std::vector<std::vector<int> >::iterator llIt = aListOfListOfNodes.begin();
6952 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
6954 vector<int>& aListOfNodes = *llIt;
6955 vector<int>::iterator lIt = aListOfNodes.begin();;
6956 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
6957 aGroup.length( aListOfNodes.size() );
6958 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
6959 aGroup[ j ] = (*lIt);
6961 TPythonDump() << "lists_nodes = " << this << ".CreateHoleSkin( "
6964 << ", '" << groupName << "', "
6965 << theNodesCoords << " )";
6967 SMESH_CATCH( SMESH::throwCorbaException );
6970 // issue 20749 ===================================================================
6972 * \brief Creates missing boundary elements
6973 * \param elements - elements whose boundary is to be checked
6974 * \param dimension - defines type of boundary elements to create
6975 * \param groupName - a name of group to store created boundary elements in,
6976 * "" means not to create the group
6977 * \param meshName - a name of new mesh to store created boundary elements in,
6978 * "" means not to create the new mesh
6979 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
6980 * \param toCopyExistingBondary - if true, not only new but also pre-existing
6981 * boundary elements will be copied into the new mesh
6982 * \param group - returns the create group, if any
6983 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
6985 // ================================================================================
6987 SMESH::SMESH_Mesh_ptr
6988 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
6989 SMESH::Bnd_Dimension dim,
6990 const char* groupName,
6991 const char* meshName,
6992 CORBA::Boolean toCopyElements,
6993 CORBA::Boolean toCopyExistingBondary,
6994 SMESH::SMESH_Group_out group)
6995 throw (SALOME::SALOME_Exception)
7000 if ( dim > SMESH::BND_1DFROM2D )
7001 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
7003 SMESHDS_Mesh* aMeshDS = getMeshDS();
7005 SMESH::SMESH_Mesh_var mesh_var;
7006 SMESH::SMESH_Group_var group_var;
7010 TIDSortedElemSet elements;
7011 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
7012 prepareIdSource( idSource );
7013 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
7017 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
7018 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
7020 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
7022 // group of new boundary elements
7023 SMESH_Group* smesh_group = 0;
7024 if ( strlen(groupName) )
7026 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
7027 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
7028 smesh_group = group_i->GetSmeshGroup();
7032 getEditor().MakeBoundaryMesh( elements,
7033 ::SMESH_MeshEditor::Bnd_Dimension(dim),
7037 toCopyExistingBondary);
7040 smesh_mesh->GetMeshDS()->Modified();
7043 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
7045 // result of MakeBoundaryMesh() is a tuple (mesh, group)
7046 if ( mesh_var->_is_nil() )
7047 pyDump << myMesh_i->_this() << ", ";
7049 pyDump << mesh_var << ", ";
7050 if ( group_var->_is_nil() )
7051 pyDump << "_NoneGroup = "; // assignment to None is forbiden
7053 pyDump << group_var << " = ";
7054 pyDump << this << ".MakeBoundaryMesh( "
7056 << "SMESH." << dimName[int(dim)] << ", "
7057 << "'" << groupName << "', "
7058 << "'" << meshName<< "', "
7059 << toCopyElements << ", "
7060 << toCopyExistingBondary << ")";
7062 group = group_var._retn();
7063 return mesh_var._retn();
7065 SMESH_CATCH( SMESH::throwCorbaException );
7066 return SMESH::SMESH_Mesh::_nil();
7069 //================================================================================
7071 * \brief Creates missing boundary elements
7072 * \param dimension - defines type of boundary elements to create
7073 * \param groupName - a name of group to store all boundary elements in,
7074 * "" means not to create the group
7075 * \param meshName - a name of a new mesh, which is a copy of the initial
7076 * mesh + created boundary elements; "" means not to create the new mesh
7077 * \param toCopyAll - if true, the whole initial mesh will be copied into
7078 * the new mesh else only boundary elements will be copied into the new mesh
7079 * \param groups - optional groups of elements to make boundary around
7080 * \param mesh - returns the mesh where elements were added to
7081 * \param group - returns the created group, if any
7082 * \retval long - number of added boundary elements
7084 //================================================================================
7086 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
7087 const char* groupName,
7088 const char* meshName,
7089 CORBA::Boolean toCopyAll,
7090 const SMESH::ListOfIDSources& groups,
7091 SMESH::SMESH_Mesh_out mesh,
7092 SMESH::SMESH_Group_out group)
7093 throw (SALOME::SALOME_Exception)
7098 if ( dim > SMESH::BND_1DFROM2D )
7099 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
7101 // separate groups belonging to this and other mesh
7102 SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
7103 SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
7104 groupsOfThisMesh->length( groups.length() );
7105 groupsOfOtherMesh->length( groups.length() );
7106 int nbGroups = 0, nbGroupsOfOtherMesh = 0;
7107 for ( int i = 0; i < groups.length(); ++i )
7109 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
7110 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
7111 groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
7113 groupsOfThisMesh[ nbGroups++ ] = groups[i];
7114 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
7115 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
7117 groupsOfThisMesh->length( nbGroups );
7118 groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
7123 if ( nbGroupsOfOtherMesh > 0 )
7125 // process groups belonging to another mesh
7126 SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
7127 SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
7128 nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
7129 groupsOfOtherMesh, mesh, group );
7132 SMESH::SMESH_Mesh_var mesh_var;
7133 SMESH::SMESH_Group_var group_var;
7136 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
7137 const bool toCopyMesh = ( strlen( meshName ) > 0 );
7141 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
7143 /*toCopyGroups=*/false,
7144 /*toKeepIDs=*/true);
7146 mesh_var = makeMesh(meshName);
7148 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
7149 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
7152 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
7153 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
7155 // group of boundary elements
7156 SMESH_Group* smesh_group = 0;
7157 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
7158 if ( strlen(groupName) )
7160 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
7161 group_var = mesh_i->CreateGroup( groupType, groupName );
7162 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
7163 smesh_group = group_i->GetSmeshGroup();
7166 TIDSortedElemSet elements;
7168 if ( groups.length() > 0 )
7170 for ( int i = 0; i < nbGroups; ++i )
7173 if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
7175 SMESH::Bnd_Dimension bdim =
7176 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
7177 nbAdded += getEditor().MakeBoundaryMesh( elements,
7178 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
7181 /*toCopyElements=*/false,
7182 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
7183 /*toAddExistingBondary=*/true,
7184 /*aroundElements=*/true);
7190 nbAdded += getEditor().MakeBoundaryMesh( elements,
7191 ::SMESH_MeshEditor::Bnd_Dimension(dim),
7194 /*toCopyElements=*/false,
7195 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
7196 /*toAddExistingBondary=*/true);
7198 tgtMesh->GetMeshDS()->Modified();
7200 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
7202 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
7203 pyDump << "nbAdded, ";
7204 if ( mesh_var->_is_nil() )
7205 pyDump << myMesh_i->_this() << ", ";
7207 pyDump << mesh_var << ", ";
7208 if ( group_var->_is_nil() )
7209 pyDump << "_NoneGroup = "; // assignment to None is forbiden
7211 pyDump << group_var << " = ";
7212 pyDump << this << ".MakeBoundaryElements( "
7213 << "SMESH." << dimName[int(dim)] << ", "
7214 << "'" << groupName << "', "
7215 << "'" << meshName<< "', "
7216 << toCopyAll << ", "
7219 mesh = mesh_var._retn();
7220 group = group_var._retn();
7223 SMESH_CATCH( SMESH::throwCorbaException );