1 // Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_MeshEditor_i.cxx
23 // Author : Nicolas REJNERI
30 // A macro used in SMESH_TryCatch.hxx,
31 // it re-raises a CORBA SALOME exception thrown by SMESH_MeshEditor_i and caught by SMESH_CATCH
32 #define SMY_OWN_CATCH \
33 catch ( SALOME::SALOME_Exception & e ) { throw e; }
35 #include "SMESH_MeshEditor_i.hxx"
37 #include "SMDS_EdgePosition.hxx"
38 #include "SMDS_ElemIterator.hxx"
39 #include "SMDS_FacePosition.hxx"
40 #include "SMDS_IteratorOnIterators.hxx"
41 #include "SMDS_LinearEdge.hxx"
42 #include "SMDS_Mesh0DElement.hxx"
43 #include "SMDS_MeshFace.hxx"
44 #include "SMDS_MeshVolume.hxx"
45 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
46 #include "SMDS_SetIterator.hxx"
47 #include "SMDS_VolumeTool.hxx"
48 #include "SMESHDS_Group.hxx"
49 #include "SMESHDS_GroupOnGeom.hxx"
50 #include "SMESH_ControlsDef.hxx"
51 #include "SMESH_Filter_i.hxx"
52 #include "SMESH_Gen_i.hxx"
53 #include "SMESH_Group.hxx"
54 #include "SMESH_Group_i.hxx"
55 #include "SMESH_MeshAlgos.hxx"
56 #include "SMESH_MeshPartDS.hxx"
57 #include "SMESH_MesherHelper.hxx"
58 #include "SMESH_PythonDump.hxx"
59 #include "SMESH_subMeshEventListener.hxx"
60 #include "SMESH_subMesh_i.hxx"
62 #include <utilities.h>
63 #include <Utils_ExceptHandlers.hxx>
64 #include <Utils_CorbaException.hxx>
65 #include <SALOMEDS_wrap.hxx>
66 #include <SALOME_GenericObj_i.hh>
67 #include <Basics_OCCTVersion.hxx>
69 #include <BRepAdaptor_Surface.hxx>
70 #include <BRep_Tool.hxx>
71 #include <TopExp_Explorer.hxx>
73 #include <TopoDS_Edge.hxx>
74 #include <TopoDS_Face.hxx>
79 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
83 #include <Standard_Failure.hxx>
86 #include <Standard_ErrorHandler.hxx>
92 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
94 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
97 using SMESH::TPythonDump;
100 namespace MeshEditor_I {
102 //=============================================================================
104 * \brief Mesh to apply modifications for preview purposes
106 //=============================================================================
108 struct TPreviewMesh: public SMESH_Mesh
110 SMDSAbs_ElementType myPreviewType; // type to show
112 TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
113 _isShapeToMesh = (_id =_studyId = 0);
114 _myMeshDS = new SMESHDS_Mesh( _id, true );
115 myPreviewType = previewElements;
117 //!< Copy a set of elements
118 void Copy(const TIDSortedElemSet & theElements,
119 TIDSortedElemSet& theCopyElements,
120 SMDSAbs_ElementType theSelectType = SMDSAbs_All,
121 SMDSAbs_ElementType theAvoidType = SMDSAbs_All)
123 // loop on theIDsOfElements
124 TIDSortedElemSet::const_iterator eIt = theElements.begin();
125 for ( ; eIt != theElements.end(); ++eIt )
127 const SMDS_MeshElement* anElem = *eIt;
128 if ( !anElem ) continue;
129 SMDSAbs_ElementType type = anElem->GetType();
130 if ( type == theAvoidType ||
131 ( theSelectType != SMDSAbs_All && type != theSelectType ))
133 const SMDS_MeshElement* anElemCopy;
134 if ( type == SMDSAbs_Node)
135 anElemCopy = Copy( cast2Node(anElem) );
137 anElemCopy = Copy( anElem );
139 theCopyElements.insert( theCopyElements.end(), anElemCopy );
143 SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
145 // copy element nodes
146 int anElemNbNodes = anElem->NbNodes();
147 vector< int > anElemNodesID( anElemNbNodes ) ;
148 SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
149 for ( int i = 0; itElemNodes->more(); i++)
151 const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
153 anElemNodesID[i] = anElemNode->GetID();
156 // creates a corresponding element on copied nodes
157 ::SMESH_MeshEditor::ElemFeatures elemType;
158 elemType.Init( anElem, /*basicOnly=*/false );
159 elemType.SetID( anElem->GetID() );
160 SMDS_MeshElement* anElemCopy =
161 ::SMESH_MeshEditor(this).AddElement( anElemNodesID, elemType );
165 SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
167 return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(),
168 anElemNode->GetID());
172 GetMeshDS()->ClearMesh();
174 void Remove( SMDSAbs_ElementType type )
176 SMDS_ElemIteratorPtr eIt = GetMeshDS()->elementsIterator( type );
177 while ( eIt->more() )
178 GetMeshDS()->RemoveFreeElement( eIt->next(), /*sm=*/0, /*fromGroups=*/false );
180 };// struct TPreviewMesh
182 static SMESH_NodeSearcher * theNodeSearcher = 0;
183 static SMESH_ElementSearcher * theElementSearcher = 0;
185 //=============================================================================
187 * \brief Deleter of theNodeSearcher at any compute event occured
189 //=============================================================================
191 struct TSearchersDeleter : public SMESH_subMeshEventListener
194 string myMeshPartIOR;
196 TSearchersDeleter(): SMESH_subMeshEventListener( false, // won't be deleted by submesh
197 "SMESH_MeshEditor_i::TSearchersDeleter"),
199 //!< Delete theNodeSearcher
202 if ( theNodeSearcher ) delete theNodeSearcher; theNodeSearcher = 0;
203 if ( theElementSearcher ) delete theElementSearcher; theElementSearcher = 0;
205 typedef map < int, SMESH_subMesh * > TDependsOnMap;
206 //!< The meshod called by submesh: do my main job
207 void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
208 SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
210 if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
212 Unset( sm->GetFather() );
215 //!< set self on all submeshes and delete theNodeSearcher if other mesh is set
216 void Set(SMESH_Mesh* mesh, const string& meshPartIOR = string())
218 if ( myMesh != mesh || myMeshPartIOR != meshPartIOR)
225 myMeshPartIOR = meshPartIOR;
226 SMESH_subMesh* sm = mesh->GetSubMesh( mesh->GetShapeToMesh() );
227 SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true );
228 while ( smIt->more() )
231 sm->SetEventListener( this, 0, sm );
235 //!< delete self from all submeshes
236 void Unset(SMESH_Mesh* mesh)
238 if ( SMESH_subMesh* sm = mesh->GetSubMeshContaining(1) ) {
239 SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true );
240 while ( smIt->more() )
241 smIt->next()->DeleteEventListener( this );
246 } theSearchersDeleter;
248 TCollection_AsciiString mirrorTypeName( SMESH::SMESH_MeshEditor::MirrorType theMirrorType )
250 TCollection_AsciiString typeStr;
251 switch ( theMirrorType ) {
252 case SMESH::SMESH_MeshEditor::POINT:
253 typeStr = "SMESH.SMESH_MeshEditor.POINT";
255 case SMESH::SMESH_MeshEditor::AXIS:
256 typeStr = "SMESH.SMESH_MeshEditor.AXIS";
259 typeStr = "SMESH.SMESH_MeshEditor.PLANE";
263 //================================================================================
265 * \brief function for conversion of long_array to TIDSortedElemSet
266 * \param IDs - array of IDs
267 * \param aMesh - mesh
268 * \param aMap - collection to fill
269 * \param aType - element type
271 //================================================================================
273 void arrayToSet(const SMESH::long_array & IDs,
274 const SMESHDS_Mesh* aMesh,
275 TIDSortedElemSet& aMap,
276 const SMDSAbs_ElementType aType = SMDSAbs_All,
277 SMDS_MeshElement::Filter* aFilter = NULL)
279 SMDS_MeshElement::NonNullFilter filter1;
280 SMDS_MeshElement::TypeFilter filter2( aType );
282 if ( aFilter == NULL )
283 aFilter = ( aType == SMDSAbs_All ) ? (SMDS_MeshElement::Filter*) &filter1 : (SMDS_MeshElement::Filter*) &filter2;
285 SMDS_MeshElement::Filter & filter = *aFilter;
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 );
301 //================================================================================
303 * \brief Retrieve nodes from SMESH_IDSource
305 //================================================================================
307 void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject,
308 const SMESHDS_Mesh* theMeshDS,
309 TIDSortedNodeSet& theNodeSet)
312 if ( CORBA::is_nil( theObject ) )
314 SMESH::array_of_ElementType_var types = theObject->GetTypes();
315 SMESH::long_array_var aElementsId = theObject->GetIDs();
316 if ( types->length() == 1 && types[0] == SMESH::NODE)
318 for(int i = 0; i < aElementsId->length(); i++)
319 if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] ))
320 theNodeSet.insert( theNodeSet.end(), n);
322 else if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
324 SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator();
325 while ( nIt->more( ))
326 if( const SMDS_MeshElement * elem = nIt->next() )
327 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
331 for(int i = 0; i < aElementsId->length(); i++)
332 if( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] ))
333 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
337 //================================================================================
339 * \brief Returns elements connected to the given elements
341 //================================================================================
343 void getElementsAround(const TIDSortedElemSet& theElements,
344 const SMESHDS_Mesh* theMeshDS,
345 TIDSortedElemSet& theElementsAround)
347 if ( theElements.empty() ) return;
349 SMDSAbs_ElementType elemType = (*theElements.begin())->GetType();
350 bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() );
352 theMeshDS->GetMeshInfo().NbElements( elemType ) == theElements.size() )
353 return; // all the elements are in theElements
356 elemType = SMDSAbs_All;
358 vector<bool> isNodeChecked( theMeshDS->NbNodes(), false );
360 TIDSortedElemSet::const_iterator elemIt = theElements.begin();
361 for ( ; elemIt != theElements.end(); ++elemIt )
363 const SMDS_MeshElement* e = *elemIt;
364 int i = e->NbCornerNodes();
367 const SMDS_MeshNode* n = e->GetNode( i );
368 if ( !isNodeChecked[ n->GetID() ])
370 isNodeChecked[ n->GetID() ] = true;
371 SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
372 while ( invIt->more() )
374 const SMDS_MeshElement* elemAround = invIt->next();
375 if ( !theElements.count( elemAround ))
376 theElementsAround.insert( elemAround );
383 //================================================================================
385 * \brief Return a string used to detect change of mesh part on which theElementSearcher
386 * is going to be used
388 //================================================================================
390 string getPartIOR( SMESH::SMESH_IDSource_ptr theMeshPart, SMESH::ElementType type)
392 string partIOR = SMESH_Gen_i::GetORB()->object_to_string( theMeshPart );
393 if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( theMeshPart ))
394 // take into account passible group modification
395 partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() );
396 partIOR += SMESH_Comment( type );
400 } // namespace MeshEditor_I
402 using namespace MeshEditor_I;
404 //=============================================================================
408 //=============================================================================
410 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview):
412 myMesh( &theMesh->GetImpl() ),
414 myIsPreviewMode ( isPreview ),
420 //================================================================================
424 //================================================================================
426 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
428 PortableServer::POA_var poa = SMESH_Gen_i::GetPOA();
429 PortableServer::ObjectId_var anObjectId = poa->servant_to_id(this);
430 poa->deactivate_object(anObjectId.in());
432 //deleteAuxIDSources();
433 delete myPreviewMesh; myPreviewMesh = 0;
434 delete myPreviewEditor; myPreviewEditor = 0;
437 //================================================================================
439 * \brief Returns the mesh
441 //================================================================================
443 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::GetMesh()
445 return myMesh_i->_this();
448 //================================================================================
450 * \brief Clear members
452 //================================================================================
454 void SMESH_MeshEditor_i::initData(bool deleteSearchers)
456 if ( myIsPreviewMode ) {
457 if ( myPreviewMesh ) myPreviewMesh->RemoveAll();
460 if ( deleteSearchers )
461 TSearchersDeleter::Delete();
463 getEditor().GetError().reset();
464 getEditor().ClearLastCreated();
467 //================================================================================
469 * \brief Increment mesh modif time and optionally record that the performed
470 * modification may influence futher mesh re-compute.
471 * \param [in] isReComputeSafe - true if the modification does not influence
472 * futher mesh re-compute
474 //================================================================================
476 void SMESH_MeshEditor_i::declareMeshModified( bool isReComputeSafe )
478 myMesh->GetMeshDS()->Modified();
479 if ( !isReComputeSafe )
480 myMesh->SetIsModified( true );
483 //================================================================================
485 * \brief Return either myEditor or myPreviewEditor depending on myIsPreviewMode.
486 * WARNING: in preview mode call getPreviewMesh() before getEditor()!
488 //================================================================================
490 ::SMESH_MeshEditor& SMESH_MeshEditor_i::getEditor()
492 if ( myIsPreviewMode && !myPreviewEditor ) {
493 if ( !myPreviewMesh ) getPreviewMesh();
494 myPreviewEditor = new ::SMESH_MeshEditor( myPreviewMesh );
496 return myIsPreviewMode ? *myPreviewEditor : myEditor;
499 //================================================================================
501 * \brief Initialize and return myPreviewMesh
502 * \param previewElements - type of elements to show in preview
504 * WARNING: call it once par a method!
506 //================================================================================
508 TPreviewMesh * SMESH_MeshEditor_i::getPreviewMesh(SMDSAbs_ElementType previewElements)
510 if ( !myPreviewMesh || myPreviewMesh->myPreviewType != previewElements )
512 delete myPreviewEditor;
514 delete myPreviewMesh;
515 myPreviewMesh = new TPreviewMesh( previewElements );
517 myPreviewMesh->Clear();
518 return myPreviewMesh;
521 //================================================================================
523 * Return data of mesh edition preview
525 //================================================================================
527 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
528 throw (SALOME::SALOME_Exception)
531 const bool hasBadElems = ( getEditor().GetError() && getEditor().GetError()->HasBadElems() );
533 if ( myIsPreviewMode || hasBadElems ) { // --- MeshPreviewStruct filling ---
535 list<int> aNodesConnectivity;
536 typedef map<int, int> TNodesMap;
539 SMESHDS_Mesh* aMeshDS;
540 std::auto_ptr< SMESH_MeshPartDS > aMeshPartDS;
542 aMeshPartDS.reset( new SMESH_MeshPartDS( getEditor().GetError()->myBadElements ));
543 aMeshDS = aMeshPartDS.get();
546 aMeshDS = getEditor().GetMeshDS();
548 myPreviewData = new SMESH::MeshPreviewStruct();
549 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
552 SMDSAbs_ElementType previewType = SMDSAbs_All;
554 if (TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( getEditor().GetMesh() )) {
555 previewType = aPreviewMesh->myPreviewType;
556 switch ( previewType ) {
557 case SMDSAbs_Edge : break;
558 case SMDSAbs_Face : break;
559 case SMDSAbs_Volume: break;
561 if ( aMeshDS->GetMeshInfo().NbElements() == 0 ) previewType = SMDSAbs_Node;
565 myPreviewData->elementTypes.length( aMeshDS->GetMeshInfo().NbElements( previewType ));
567 SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator(previewType);
569 while ( itMeshElems->more() ) {
570 const SMDS_MeshElement* aMeshElem = itMeshElems->next();
571 SMDS_NodeIteratorPtr itElemNodes =
572 (( aMeshElem->GetEntityType() == SMDSEntity_Quad_Polygon ) ?
573 aMeshElem->interlacedNodesIterator() :
574 aMeshElem->nodeIterator() );
575 while ( itElemNodes->more() ) {
576 const SMDS_MeshNode* aMeshNode = itElemNodes->next();
577 int aNodeID = aMeshNode->GetID();
578 TNodesMap::iterator anIter = nodesMap.find(aNodeID);
579 if ( anIter == nodesMap.end() ) {
580 // filling the nodes coordinates
581 myPreviewData->nodesXYZ[j].x = aMeshNode->X();
582 myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
583 myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
584 anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
587 aNodesConnectivity.push_back(anIter->second);
590 // filling the elements types
591 SMDSAbs_ElementType aType = aMeshElem->GetType();
592 bool isPoly = aMeshElem->IsPoly();
593 myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
594 myPreviewData->elementTypes[i].isPoly = isPoly;
595 myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
598 myPreviewData->nodesXYZ.length( j );
600 // filling the elements connectivities
601 list<int>::iterator aConnIter = aNodesConnectivity.begin();
602 myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
603 for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
604 myPreviewData->elementConnectivities[i] = *aConnIter;
606 return myPreviewData._retn();
608 SMESH_CATCH( SMESH::throwCorbaException );
612 //================================================================================
614 * \brief Returns list of it's IDs of created nodes
615 * \retval SMESH::long_array* - list of node ID
617 //================================================================================
619 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
620 throw (SALOME::SALOME_Exception)
623 SMESH::long_array_var myLastCreatedNodes = new SMESH::long_array();
625 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedNodes();
626 myLastCreatedNodes->length( aSeq.Length() );
627 for (int i = 1; i <= aSeq.Length(); i++)
628 myLastCreatedNodes[i-1] = aSeq.Value(i)->GetID();
630 return myLastCreatedNodes._retn();
631 SMESH_CATCH( SMESH::throwCorbaException );
635 //================================================================================
637 * \brief Returns list of it's IDs of created elements
638 * \retval SMESH::long_array* - list of elements' ID
640 //================================================================================
642 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
643 throw (SALOME::SALOME_Exception)
646 SMESH::long_array_var myLastCreatedElems = new SMESH::long_array();
648 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
649 myLastCreatedElems->length( aSeq.Length() );
650 for ( int i = 1; i <= aSeq.Length(); i++ )
651 myLastCreatedElems[i-1] = aSeq.Value(i)->GetID();
653 return myLastCreatedElems._retn();
654 SMESH_CATCH( SMESH::throwCorbaException );
658 //=======================================================================
659 //function : ClearLastCreated
660 //purpose : Clears sequences of last created elements and nodes
661 //=======================================================================
663 void SMESH_MeshEditor_i::ClearLastCreated() throw (SALOME::SALOME_Exception)
666 getEditor().ClearLastCreated();
667 SMESH_CATCH( SMESH::throwCorbaException );
670 //=======================================================================
672 * Returns description of an error/warning occured during the last operation
673 * WARNING: ComputeError.code >= 100 and no corresponding enum in IDL API
675 //=======================================================================
677 SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError()
678 throw (SALOME::SALOME_Exception)
681 SMESH::ComputeError_var errOut = new SMESH::ComputeError;
682 SMESH_ComputeErrorPtr& errIn = getEditor().GetError();
683 if ( errIn && !errIn->IsOK() )
685 errOut->code = -( errIn->myName < 0 ? errIn->myName + 1: errIn->myName ); // -1 -> 0
686 errOut->comment = errIn->myComment.c_str();
687 errOut->subShapeID = -1;
688 errOut->hasBadMesh = !errIn->myBadElements.empty();
693 errOut->subShapeID = -1;
694 errOut->hasBadMesh = false;
697 return errOut._retn();
698 SMESH_CATCH( SMESH::throwCorbaException );
702 //=======================================================================
703 //function : MakeIDSource
704 //purpose : Wrap a sequence of ids in a SMESH_IDSource.
705 // Call UnRegister() as you fininsh using it!!
706 //=======================================================================
708 struct SMESH_MeshEditor_i::_IDSource : public virtual POA_SMESH::SMESH_IDSource,
709 public virtual SALOME::GenericObj_i
711 SMESH::long_array _ids;
712 SMESH::ElementType _type;
713 SMESH::SMESH_Mesh_ptr _mesh;
714 SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); }
715 SMESH::long_array* GetMeshInfo() { return 0; }
716 SMESH::long_array* GetNbElementsByType()
718 SMESH::long_array_var aRes = new SMESH::long_array();
719 aRes->length(SMESH::NB_ELEMENT_TYPES);
720 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
721 aRes[ i ] = ( i == _type ) ? _ids.length() : 0;
724 SMESH::SMESH_Mesh_ptr GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _mesh ); }
725 bool IsMeshInfoCorrect() { return true; }
726 SMESH::array_of_ElementType* GetTypes()
728 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
729 if ( _ids.length() > 0 ) {
733 return types._retn();
735 SALOMEDS::TMPFile* GetVtkUgStream()
737 SALOMEDS::TMPFile_var SeqFile;
738 return SeqFile._retn();
742 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
743 SMESH::ElementType type)
745 _IDSource* idSrc = new _IDSource;
746 idSrc->_mesh = myMesh_i->_this();
749 if ( type == SMESH::ALL && ids.length() > 0 )
750 idSrc->_type = myMesh_i->GetElementType( ids[0], true );
752 SMESH::SMESH_IDSource_var anIDSourceVar = idSrc->_this();
754 return anIDSourceVar._retn();
757 bool SMESH_MeshEditor_i::IsTemporaryIDSource( SMESH::SMESH_IDSource_ptr& idSource )
759 return SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource );
762 CORBA::Long* SMESH_MeshEditor_i::GetTemporaryIDs( SMESH::SMESH_IDSource_ptr& idSource,
765 if ( _IDSource* tmpIdSource = SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource ))
767 nbIds = (int) tmpIdSource->_ids.length();
768 return & tmpIdSource->_ids[0];
774 // void SMESH_MeshEditor_i::deleteAuxIDSources()
776 // std::list< _IDSource* >::iterator idSrcIt = myAuxIDSources.begin();
777 // for ( ; idSrcIt != myAuxIDSources.end(); ++idSrcIt )
779 // myAuxIDSources.clear();
782 //=============================================================================
786 //=============================================================================
789 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
790 throw (SALOME::SALOME_Exception)
797 for (int i = 0; i < IDsOfElements.length(); i++)
798 IdList.push_back( IDsOfElements[i] );
800 // Update Python script
801 TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
804 bool ret = getEditor().Remove( IdList, false );
806 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 ); // issue 0020693
809 SMESH_CATCH( SMESH::throwCorbaException );
813 //=============================================================================
817 //=============================================================================
819 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
820 throw (SALOME::SALOME_Exception)
826 for (int i = 0; i < IDsOfNodes.length(); i++)
827 IdList.push_back( IDsOfNodes[i] );
829 // Update Python script
830 TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
832 bool ret = getEditor().Remove( IdList, true );
834 declareMeshModified( /*isReComputeSafe=*/ !ret ); // issue 0020693
837 SMESH_CATCH( SMESH::throwCorbaException );
841 //=============================================================================
845 //=============================================================================
847 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
848 throw (SALOME::SALOME_Exception)
853 // Update Python script
854 TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
856 // Create filter to find all orphan nodes
857 SMESH::Controls::Filter::TIdSequence seq;
858 SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
859 SMESH::Controls::Filter::GetElementsId( getMeshDS(), predicate, seq );
861 // remove orphan nodes (if there are any)
863 for ( int i = 0; i < seq.size(); i++ )
864 IdList.push_back( seq[i] );
866 int nbNodesBefore = myMesh->NbNodes();
867 getEditor().Remove( IdList, true );
868 int nbNodesAfter = myMesh->NbNodes();
870 declareMeshModified( /*isReComputeSafe=*/ IdList.size() == 0 ); // issue 0020693
871 return nbNodesBefore - nbNodesAfter;
873 SMESH_CATCH( SMESH::throwCorbaException );
877 //=============================================================================
881 //=============================================================================
883 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,CORBA::Double y, CORBA::Double z)
884 throw (SALOME::SALOME_Exception)
889 const SMDS_MeshNode* N = getMeshDS()->AddNode(x, y, z);
891 // Update Python script
892 TPythonDump() << "nodeID = " << this << ".AddNode( "
893 << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )";
895 declareMeshModified( /*isReComputeSafe=*/false );
898 SMESH_CATCH( SMESH::throwCorbaException );
902 //=============================================================================
904 * Create 0D element on the given node.
906 //=============================================================================
908 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
909 throw (SALOME::SALOME_Exception)
914 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
915 SMDS_MeshElement* elem = getMeshDS()->Add0DElement(aNode);
917 // Update Python script
918 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
920 declareMeshModified( /*isReComputeSafe=*/false );
922 return elem ? elem->GetID() : 0;
924 SMESH_CATCH( SMESH::throwCorbaException );
928 //=============================================================================
930 * Create a ball element on the given node.
932 //=============================================================================
934 CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diameter)
935 throw (SALOME::SALOME_Exception)
940 if ( diameter < std::numeric_limits<double>::min() )
941 THROW_SALOME_CORBA_EXCEPTION("Invalid diameter", SALOME::BAD_PARAM);
943 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
944 SMDS_MeshElement* elem = getMeshDS()->AddBall(aNode, diameter);
946 // Update Python script
947 TPythonDump() << "ballElem = "
948 << this << ".AddBall( " << IDOfNode << ", " << diameter <<" )";
950 declareMeshModified( /*isReComputeSafe=*/false );
951 return elem ? elem->GetID() : 0;
953 SMESH_CATCH( SMESH::throwCorbaException );
957 //=============================================================================
959 * Create an edge, either linear and quadratic (this is determed
960 * by number of given nodes, two or three)
962 //=============================================================================
964 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
965 throw (SALOME::SALOME_Exception)
970 int NbNodes = IDsOfNodes.length();
971 SMDS_MeshElement* elem = 0;
974 CORBA::Long index1 = IDsOfNodes[0];
975 CORBA::Long index2 = IDsOfNodes[1];
976 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(index1),
977 getMeshDS()->FindNode(index2));
979 // Update Python script
980 TPythonDump() << "edge = " << this << ".AddEdge([ "
981 << index1 << ", " << index2 <<" ])";
984 CORBA::Long n1 = IDsOfNodes[0];
985 CORBA::Long n2 = IDsOfNodes[1];
986 CORBA::Long n12 = IDsOfNodes[2];
987 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(n1),
988 getMeshDS()->FindNode(n2),
989 getMeshDS()->FindNode(n12));
990 // Update Python script
991 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
992 <<n1<<", "<<n2<<", "<<n12<<" ])";
995 declareMeshModified( /*isReComputeSafe=*/false );
996 return elem ? elem->GetID() : 0;
998 SMESH_CATCH( SMESH::throwCorbaException );
1002 //=============================================================================
1006 //=============================================================================
1008 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
1009 throw (SALOME::SALOME_Exception)
1014 int NbNodes = IDsOfNodes.length();
1020 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1021 for (int i = 0; i < NbNodes; i++)
1022 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1024 SMDS_MeshElement* elem = 0;
1026 case 3: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]); break;
1027 case 4: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]); break;
1028 case 6: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1029 nodes[4], nodes[5]); break;
1030 case 7: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1031 nodes[4], nodes[5], nodes[6]); break;
1032 case 8: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1033 nodes[4], nodes[5], nodes[6], nodes[7]); break;
1034 case 9: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1035 nodes[4], nodes[5], nodes[6], nodes[7],
1037 default: elem = getMeshDS()->AddPolygonalFace(nodes);
1040 // Update Python script
1041 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
1043 declareMeshModified( /*isReComputeSafe=*/false );
1045 return elem ? elem->GetID() : 0;
1047 SMESH_CATCH( SMESH::throwCorbaException );
1051 //=============================================================================
1055 //=============================================================================
1057 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
1058 throw (SALOME::SALOME_Exception)
1063 int NbNodes = IDsOfNodes.length();
1064 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1065 for (int i = 0; i < NbNodes; i++)
1066 if ( ! ( nodes[i] = getMeshDS()->FindNode( IDsOfNodes[i] )))
1069 const SMDS_MeshElement* elem = getMeshDS()->AddPolygonalFace(nodes);
1071 // Update Python script
1072 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
1074 declareMeshModified( /*isReComputeSafe=*/false );
1075 return elem ? elem->GetID() : 0;
1077 SMESH_CATCH( SMESH::throwCorbaException );
1081 //=============================================================================
1083 * AddQuadPolygonalFace
1085 //=============================================================================
1087 CORBA::Long SMESH_MeshEditor_i::AddQuadPolygonalFace (const SMESH::long_array & IDsOfNodes)
1088 throw (SALOME::SALOME_Exception)
1093 int NbNodes = IDsOfNodes.length();
1094 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1095 for (int i = 0; i < NbNodes; i++)
1096 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1098 const SMDS_MeshElement* elem = getMeshDS()->AddQuadPolygonalFace(nodes);
1100 // Update Python script
1101 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
1103 declareMeshModified( /*isReComputeSafe=*/false );
1104 return elem ? elem->GetID() : 0;
1106 SMESH_CATCH( SMESH::throwCorbaException );
1110 //=============================================================================
1112 * Create volume, either linear and quadratic (this is determed
1113 * by number of given nodes)
1115 //=============================================================================
1117 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
1118 throw (SALOME::SALOME_Exception)
1123 int NbNodes = IDsOfNodes.length();
1124 vector< const SMDS_MeshNode*> n(NbNodes);
1125 for(int i=0;i<NbNodes;i++)
1126 n[i]= getMeshDS()->FindNode(IDsOfNodes[i]);
1128 SMDS_MeshElement* elem = 0;
1131 case 4 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
1132 case 5 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
1133 case 6 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
1134 case 8 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
1135 case 10:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1136 n[6],n[7],n[8],n[9]);
1138 case 12:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1139 n[6],n[7],n[8],n[9],n[10],n[11]);
1141 case 13:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
1142 n[7],n[8],n[9],n[10],n[11],n[12]);
1144 case 15:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
1145 n[9],n[10],n[11],n[12],n[13],n[14]);
1147 case 20:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1148 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1149 n[15],n[16],n[17],n[18],n[19]);
1151 case 27:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1152 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1153 n[15],n[16],n[17],n[18],n[19],
1154 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
1158 // Update Python script
1159 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
1161 declareMeshModified( /*isReComputeSafe=*/false );
1162 return elem ? elem->GetID() : 0;
1164 SMESH_CATCH( SMESH::throwCorbaException );
1168 //=============================================================================
1170 * AddPolyhedralVolume
1172 //=============================================================================
1173 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
1174 const SMESH::long_array & Quantities)
1175 throw (SALOME::SALOME_Exception)
1180 int NbNodes = IDsOfNodes.length();
1181 std::vector<const SMDS_MeshNode*> n (NbNodes);
1182 for (int i = 0; i < NbNodes; i++)
1184 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDsOfNodes[i]);
1185 if (!aNode) return 0;
1189 int NbFaces = Quantities.length();
1190 std::vector<int> q (NbFaces);
1191 for (int j = 0; j < NbFaces; j++)
1192 q[j] = Quantities[j];
1194 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(n, q);
1196 // Update Python script
1197 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
1198 << IDsOfNodes << ", " << Quantities << " )";
1200 declareMeshModified( /*isReComputeSafe=*/false );
1201 return elem ? elem->GetID() : 0;
1203 SMESH_CATCH( SMESH::throwCorbaException );
1207 //=============================================================================
1209 * AddPolyhedralVolumeByFaces
1211 //=============================================================================
1213 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
1214 throw (SALOME::SALOME_Exception)
1219 int NbFaces = IdsOfFaces.length();
1220 std::vector<const SMDS_MeshNode*> poly_nodes;
1221 std::vector<int> quantities (NbFaces);
1223 for (int i = 0; i < NbFaces; i++) {
1224 const SMDS_MeshElement* aFace = getMeshDS()->FindElement(IdsOfFaces[i]);
1225 quantities[i] = aFace->NbNodes();
1227 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
1228 while (It->more()) {
1229 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
1233 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
1235 // Update Python script
1236 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
1237 << IdsOfFaces << " )";
1239 declareMeshModified( /*isReComputeSafe=*/false );
1240 return elem ? elem->GetID() : 0;
1242 SMESH_CATCH( SMESH::throwCorbaException );
1246 //=============================================================================
1248 // \brief Create 0D elements on all nodes of the given object except those
1249 // nodes on which a 0D element already exists.
1250 // \param theObject object on whose nodes 0D elements will be created.
1251 // \param theGroupName optional name of a group to add 0D elements created
1252 // and/or found on nodes of \a theObject.
1253 // \return an object (a new group or a temporary SMESH_IDSource) holding
1254 // ids of new and/or found 0D elements.
1256 //=============================================================================
1258 SMESH::SMESH_IDSource_ptr
1259 SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObject,
1260 const char* theGroupName)
1261 throw (SALOME::SALOME_Exception)
1266 SMESH::SMESH_IDSource_var result;
1269 TIDSortedElemSet elements, elems0D;
1270 if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
1271 getEditor().Create0DElementsOnAllNodes( elements, elems0D );
1273 SMESH::long_array_var newElems = new SMESH::long_array;
1274 newElems->length( elems0D.size() );
1275 TIDSortedElemSet::iterator eIt = elems0D.begin();
1276 for ( size_t i = 0; i < elems0D.size(); ++i, ++eIt )
1277 newElems[ i ] = (*eIt)->GetID();
1279 SMESH::SMESH_GroupBase_var groupToFill;
1280 if ( theGroupName && strlen( theGroupName ))
1282 // Get existing group named theGroupName
1283 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
1284 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
1285 SMESH::SMESH_GroupBase_var group = groups[i];
1286 if ( !group->_is_nil() ) {
1287 CORBA::String_var name = group->GetName();
1288 if ( strcmp( name.in(), theGroupName ) == 0 && group->GetType() == SMESH::ELEM0D ) {
1289 groupToFill = group;
1294 if ( groupToFill->_is_nil() )
1295 groupToFill = myMesh_i->CreateGroup( SMESH::ELEM0D, theGroupName );
1296 else if ( !SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1297 groupToFill = myMesh_i->ConvertToStandalone( groupToFill );
1300 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1302 group_i->Add( newElems );
1303 result = SMESH::SMESH_IDSource::_narrow( groupToFill );
1304 pyDump << groupToFill;
1308 result = MakeIDSource( newElems, SMESH::ELEM0D );
1309 pyDump << "elem0DIDs";
1312 pyDump << " = " << this << ".Create0DElementsOnAllNodes( "
1313 << theObject << ", '" << theGroupName << "' )";
1315 return result._retn();
1317 SMESH_CATCH( SMESH::throwCorbaException );
1321 //=============================================================================
1323 * \brief Bind a node to a vertex
1324 * \param NodeID - node ID
1325 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1326 * \retval boolean - false if NodeID or VertexID is invalid
1328 //=============================================================================
1330 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
1331 throw (SALOME::SALOME_Exception)
1335 SMESHDS_Mesh * mesh = getMeshDS();
1336 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1338 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1340 if ( mesh->MaxShapeIndex() < VertexID )
1341 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1343 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
1344 if ( shape.ShapeType() != TopAbs_VERTEX )
1345 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1347 mesh->SetNodeOnVertex( node, VertexID );
1349 myMesh->SetIsModified( true );
1351 SMESH_CATCH( SMESH::throwCorbaException );
1354 //=============================================================================
1356 * \brief Store node position on an edge
1357 * \param NodeID - node ID
1358 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
1359 * \param paramOnEdge - parameter on edge where the node is located
1360 * \retval boolean - false if any parameter is invalid
1362 //=============================================================================
1364 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
1365 CORBA::Double paramOnEdge)
1366 throw (SALOME::SALOME_Exception)
1370 SMESHDS_Mesh * mesh = getMeshDS();
1371 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1373 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1375 if ( mesh->MaxShapeIndex() < EdgeID )
1376 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1378 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
1379 if ( shape.ShapeType() != TopAbs_EDGE )
1380 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1383 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
1384 if ( paramOnEdge < f || paramOnEdge > l )
1385 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
1387 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
1389 myMesh->SetIsModified( true );
1391 SMESH_CATCH( SMESH::throwCorbaException );
1394 //=============================================================================
1396 * \brief Store node position on a face
1397 * \param NodeID - node ID
1398 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
1399 * \param u - U parameter on face where the node is located
1400 * \param v - V parameter on face where the node is located
1401 * \retval boolean - false if any parameter is invalid
1403 //=============================================================================
1405 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
1406 CORBA::Double u, CORBA::Double v)
1407 throw (SALOME::SALOME_Exception)
1410 SMESHDS_Mesh * mesh = getMeshDS();
1411 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1413 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1415 if ( mesh->MaxShapeIndex() < FaceID )
1416 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1418 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
1419 if ( shape.ShapeType() != TopAbs_FACE )
1420 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1422 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
1423 bool isOut = ( u < surf.FirstUParameter() ||
1424 u > surf.LastUParameter() ||
1425 v < surf.FirstVParameter() ||
1426 v > surf.LastVParameter() );
1430 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
1431 << " u( " << surf.FirstUParameter()
1432 << "," << surf.LastUParameter()
1433 << ") v( " << surf.FirstVParameter()
1434 << "," << surf.LastVParameter() << ")" );
1436 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
1439 mesh->SetNodeOnFace( node, FaceID, u, v );
1440 myMesh->SetIsModified( true );
1442 SMESH_CATCH( SMESH::throwCorbaException );
1445 //=============================================================================
1447 * \brief Bind a node to a solid
1448 * \param NodeID - node ID
1449 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1450 * \retval boolean - false if NodeID or SolidID is invalid
1452 //=============================================================================
1454 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
1455 throw (SALOME::SALOME_Exception)
1458 SMESHDS_Mesh * mesh = getMeshDS();
1459 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1461 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1463 if ( mesh->MaxShapeIndex() < SolidID )
1464 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1466 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
1467 if ( shape.ShapeType() != TopAbs_SOLID &&
1468 shape.ShapeType() != TopAbs_SHELL)
1469 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1471 mesh->SetNodeInVolume( node, SolidID );
1473 SMESH_CATCH( SMESH::throwCorbaException );
1476 //=============================================================================
1478 * \brief Bind an element to a shape
1479 * \param ElementID - element ID
1480 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
1482 //=============================================================================
1484 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
1485 CORBA::Long ShapeID)
1486 throw (SALOME::SALOME_Exception)
1489 SMESHDS_Mesh * mesh = getMeshDS();
1490 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
1492 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
1494 if ( mesh->MaxShapeIndex() < ShapeID || ShapeID < 1 )
1495 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1497 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1498 if ( shape.ShapeType() != TopAbs_EDGE &&
1499 shape.ShapeType() != TopAbs_FACE &&
1500 shape.ShapeType() != TopAbs_SOLID &&
1501 shape.ShapeType() != TopAbs_SHELL )
1502 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1504 mesh->SetMeshElementOnShape( elem, ShapeID );
1506 myMesh->SetIsModified( true );
1508 SMESH_CATCH( SMESH::throwCorbaException );
1511 //=============================================================================
1515 //=============================================================================
1517 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1518 CORBA::Long NodeID2)
1519 throw (SALOME::SALOME_Exception)
1524 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1525 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1529 // Update Python script
1530 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1531 << NodeID1 << ", " << NodeID2 << " )";
1533 int ret = getEditor().InverseDiag ( n1, n2 );
1535 declareMeshModified( /*isReComputeSafe=*/false );
1538 SMESH_CATCH( SMESH::throwCorbaException );
1542 //=============================================================================
1546 //=============================================================================
1548 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1549 CORBA::Long NodeID2)
1550 throw (SALOME::SALOME_Exception)
1555 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1556 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1560 // Update Python script
1561 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1562 << NodeID1 << ", " << NodeID2 << " )";
1565 bool stat = getEditor().DeleteDiag ( n1, n2 );
1567 declareMeshModified( /*isReComputeSafe=*/!stat );
1571 SMESH_CATCH( SMESH::throwCorbaException );
1575 //=============================================================================
1579 //=============================================================================
1581 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1582 throw (SALOME::SALOME_Exception)
1587 for (int i = 0; i < IDsOfElements.length(); i++)
1589 CORBA::Long index = IDsOfElements[i];
1590 const SMDS_MeshElement * elem = getMeshDS()->FindElement(index);
1592 getEditor().Reorient( elem );
1594 // Update Python script
1595 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1597 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 );
1600 SMESH_CATCH( SMESH::throwCorbaException );
1604 //=============================================================================
1608 //=============================================================================
1610 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1611 throw (SALOME::SALOME_Exception)
1616 TPythonDump aTPythonDump; // suppress dump in Reorient()
1618 prepareIdSource( theObject );
1620 SMESH::long_array_var anElementsId = theObject->GetIDs();
1621 CORBA::Boolean isDone = Reorient(anElementsId);
1623 // Update Python script
1624 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1626 declareMeshModified( /*isReComputeSafe=*/ anElementsId->length() == 0 );
1629 SMESH_CATCH( SMESH::throwCorbaException );
1633 //=======================================================================
1634 //function : Reorient2D
1635 //purpose : Reorient faces contained in \a the2Dgroup.
1636 // the2Dgroup - the mesh or its part to reorient
1637 // theDirection - desired direction of normal of \a theFace
1638 // theFace - ID of face whose orientation is checked.
1639 // It can be < 1 then \a thePoint is used to find a face.
1640 // thePoint - is used to find a face if \a theFace < 1.
1641 // return number of reoriented elements.
1642 //=======================================================================
1644 CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
1645 const SMESH::DirStruct& theDirection,
1646 CORBA::Long theFace,
1647 const SMESH::PointStruct& thePoint)
1648 throw (SALOME::SALOME_Exception)
1651 initData(/*deleteSearchers=*/false);
1653 TIDSortedElemSet elements;
1654 IDSource_Error error;
1655 idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error );
1656 if ( error == IDSource_EMPTY )
1658 if ( error == IDSource_INVALID )
1659 THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
1662 const SMDS_MeshElement* face = 0;
1665 face = getMeshDS()->FindElement( theFace );
1667 THROW_SALOME_CORBA_EXCEPTION("Inexistent face given", SALOME::BAD_PARAM);
1668 if ( face->GetType() != SMDSAbs_Face )
1669 THROW_SALOME_CORBA_EXCEPTION("Wrong element type", SALOME::BAD_PARAM);
1673 // create theElementSearcher if needed
1674 theSearchersDeleter.Set( myMesh, getPartIOR( the2Dgroup, SMESH::FACE ));
1675 if ( !theElementSearcher )
1677 if ( elements.empty() ) // search in the whole mesh
1679 if ( myMesh->NbFaces() == 0 )
1680 THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM);
1682 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
1686 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
1687 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
1689 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt);
1693 gp_Pnt p( thePoint.x, thePoint.y, thePoint.z );
1694 face = theElementSearcher->FindClosestTo( p, SMDSAbs_Face );
1697 THROW_SALOME_CORBA_EXCEPTION("No face found by point", SALOME::INTERNAL_ERROR );
1698 if ( !elements.empty() && !elements.count( face ))
1699 THROW_SALOME_CORBA_EXCEPTION("Found face is not in the group", SALOME::BAD_PARAM );
1702 const SMESH::PointStruct * P = &theDirection.PS;
1703 gp_Vec dirVec( P->x, P->y, P->z );
1704 if ( dirVec.Magnitude() < std::numeric_limits< double >::min() )
1705 THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM);
1707 int nbReori = getEditor().Reorient2D( elements, dirVec, face );
1710 declareMeshModified( /*isReComputeSafe=*/false );
1712 TPythonDump() << this << ".Reorient2D( "
1713 << the2Dgroup << ", "
1714 << theDirection << ", "
1716 << thePoint << " )";
1720 SMESH_CATCH( SMESH::throwCorbaException );
1724 //=======================================================================
1725 //function : Reorient2DBy3D
1726 //purpose : Reorient faces basing on orientation of adjacent volumes.
1727 //=======================================================================
1729 CORBA::Long SMESH_MeshEditor_i::Reorient2DBy3D(const SMESH::ListOfIDSources& faceGroups,
1730 SMESH::SMESH_IDSource_ptr volumeGroup,
1731 CORBA::Boolean outsideNormal)
1732 throw (SALOME::SALOME_Exception)
1737 TIDSortedElemSet volumes;
1738 IDSource_Error volsError;
1739 idSourceToSet( volumeGroup, getMeshDS(), volumes, SMDSAbs_Volume, /*emptyIfMesh=*/1, &volsError);
1742 for ( size_t i = 0; i < faceGroups.length(); ++i )
1744 SMESH::SMESH_IDSource_ptr faceGrp = faceGroups[i].in();
1746 TIDSortedElemSet faces;
1747 IDSource_Error error;
1748 idSourceToSet( faceGrp, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error );
1749 if ( error == IDSource_INVALID && faceGroups.length() == 1 )
1750 THROW_SALOME_CORBA_EXCEPTION("No faces in a given object", SALOME::BAD_PARAM);
1751 if ( error == IDSource_OK && volsError != IDSource_OK )
1752 THROW_SALOME_CORBA_EXCEPTION("No volumes in a given object", SALOME::BAD_PARAM);
1754 nbReori += getEditor().Reorient2DBy3D( faces, volumes, outsideNormal );
1756 if ( error != IDSource_EMPTY && faces.empty() ) // all faces in the mesh treated
1761 declareMeshModified( /*isReComputeSafe=*/false );
1763 TPythonDump() << this << ".Reorient2DBy3D( "
1764 << faceGroups << ", "
1765 << volumeGroup << ", "
1766 << outsideNormal << " )";
1770 SMESH_CATCH( SMESH::throwCorbaException );
1774 //=============================================================================
1776 * \brief Fuse neighbour triangles into quadrangles.
1778 //=============================================================================
1780 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1781 SMESH::NumericalFunctor_ptr Criterion,
1782 CORBA::Double MaxAngle)
1783 throw (SALOME::SALOME_Exception)
1788 SMESHDS_Mesh* aMesh = getMeshDS();
1789 TIDSortedElemSet faces,copyFaces;
1790 SMDS_MeshElement::GeomFilter triaFilter(SMDSGeom_TRIANGLE);
1791 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face, & triaFilter);
1792 TIDSortedElemSet* workElements = & faces;
1794 if ( myIsPreviewMode ) {
1795 SMDSAbs_ElementType select = SMDSAbs_Face;
1796 getPreviewMesh( SMDSAbs_Face )->Copy( faces, copyFaces, select );
1797 workElements = & copyFaces;
1800 SMESH::NumericalFunctor_i* aNumericalFunctor =
1801 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1802 SMESH::Controls::NumericalFunctorPtr aCrit;
1803 if ( !aNumericalFunctor )
1804 aCrit.reset( new SMESH::Controls::MaxElementLength2D() );
1806 aCrit = aNumericalFunctor->GetNumericalFunctor();
1808 if ( !myIsPreviewMode ) {
1809 // Update Python script
1810 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1811 << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1814 bool stat = getEditor().TriToQuad( *workElements, aCrit, MaxAngle );
1816 declareMeshModified( /*isReComputeSafe=*/!stat );
1819 SMESH_CATCH( SMESH::throwCorbaException );
1823 //=============================================================================
1825 * \brief Fuse neighbour triangles into quadrangles.
1827 //=============================================================================
1829 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1830 SMESH::NumericalFunctor_ptr Criterion,
1831 CORBA::Double MaxAngle)
1832 throw (SALOME::SALOME_Exception)
1837 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1839 prepareIdSource( theObject );
1840 SMESH::long_array_var anElementsId = theObject->GetIDs();
1841 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1843 if ( !myIsPreviewMode ) {
1844 SMESH::NumericalFunctor_i* aNumericalFunctor =
1845 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1847 // Update Python script
1848 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1849 << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1854 SMESH_CATCH( SMESH::throwCorbaException );
1858 //=============================================================================
1860 * \brief Split quadrangles into triangles.
1862 //=============================================================================
1864 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1865 SMESH::NumericalFunctor_ptr Criterion)
1866 throw (SALOME::SALOME_Exception)
1871 SMESHDS_Mesh* aMesh = getMeshDS();
1872 TIDSortedElemSet faces;
1873 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1875 SMESH::NumericalFunctor_i* aNumericalFunctor =
1876 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1877 SMESH::Controls::NumericalFunctorPtr aCrit;
1878 if ( !aNumericalFunctor )
1879 aCrit.reset( new SMESH::Controls::AspectRatio() );
1881 aCrit = aNumericalFunctor->GetNumericalFunctor();
1884 // Update Python script
1885 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1887 CORBA::Boolean stat = getEditor().QuadToTri( faces, aCrit );
1889 declareMeshModified( /*isReComputeSafe=*/false );
1892 SMESH_CATCH( SMESH::throwCorbaException );
1896 //=============================================================================
1898 * \brief Split quadrangles into triangles.
1900 //=============================================================================
1902 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1903 SMESH::NumericalFunctor_ptr Criterion)
1904 throw (SALOME::SALOME_Exception)
1909 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1911 prepareIdSource( theObject );
1912 SMESH::long_array_var anElementsId = theObject->GetIDs();
1913 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1915 SMESH::NumericalFunctor_i* aNumericalFunctor =
1916 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1918 // Update Python script
1919 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1921 declareMeshModified( /*isReComputeSafe=*/false );
1924 SMESH_CATCH( SMESH::throwCorbaException );
1928 //================================================================================
1930 * \brief Split each of quadrangles into 4 triangles.
1931 * \param [in] theObject - theQuads Container of quadrangles to split.
1933 //================================================================================
1935 void SMESH_MeshEditor_i::QuadTo4Tri (SMESH::SMESH_IDSource_ptr theObject)
1936 throw (SALOME::SALOME_Exception)
1941 TIDSortedElemSet faces;
1942 if ( !idSourceToSet( theObject, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/true ) &&
1944 THROW_SALOME_CORBA_EXCEPTION("No faces given", SALOME::BAD_PARAM);
1946 getEditor().QuadTo4Tri( faces );
1947 TPythonDump() << this << ".QuadTo4Tri( " << theObject << " )";
1949 SMESH_CATCH( SMESH::throwCorbaException );
1952 //=============================================================================
1954 * \brief Split quadrangles into triangles.
1956 //=============================================================================
1958 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1959 CORBA::Boolean Diag13)
1960 throw (SALOME::SALOME_Exception)
1965 SMESHDS_Mesh* aMesh = getMeshDS();
1966 TIDSortedElemSet faces;
1967 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1969 // Update Python script
1970 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1971 << IDsOfElements << ", " << Diag13 << " )";
1973 CORBA::Boolean stat = getEditor().QuadToTri( faces, Diag13 );
1975 declareMeshModified( /*isReComputeSafe=*/ !stat );
1978 SMESH_CATCH( SMESH::throwCorbaException );
1982 //=============================================================================
1984 * \brief Split quadrangles into triangles.
1986 //=============================================================================
1988 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1989 CORBA::Boolean Diag13)
1990 throw (SALOME::SALOME_Exception)
1995 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
1997 prepareIdSource( theObject );
1998 SMESH::long_array_var anElementsId = theObject->GetIDs();
1999 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
2001 // Update Python script
2002 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
2003 << theObject << ", " << Diag13 << " )";
2005 declareMeshModified( /*isReComputeSafe=*/!isDone );
2008 SMESH_CATCH( SMESH::throwCorbaException );
2013 //=============================================================================
2015 * Find better splitting of the given quadrangle.
2016 * \param IDOfQuad ID of the quadrangle to be splitted.
2017 * \param Criterion A criterion to choose a diagonal for splitting.
2018 * \return 1 if 1-3 diagonal is better, 2 if 2-4
2019 * diagonal is better, 0 if error occurs.
2021 //=============================================================================
2023 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
2024 SMESH::NumericalFunctor_ptr Criterion)
2025 throw (SALOME::SALOME_Exception)
2030 const SMDS_MeshElement* quad = getMeshDS()->FindElement(IDOfQuad);
2031 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
2033 SMESH::NumericalFunctor_i* aNumericalFunctor =
2034 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
2035 SMESH::Controls::NumericalFunctorPtr aCrit;
2036 if (aNumericalFunctor)
2037 aCrit = aNumericalFunctor->GetNumericalFunctor();
2039 aCrit.reset(new SMESH::Controls::AspectRatio());
2041 int id = getEditor().BestSplit(quad, aCrit);
2042 declareMeshModified( /*isReComputeSafe=*/ id < 1 );
2046 SMESH_CATCH( SMESH::throwCorbaException );
2050 //================================================================================
2052 * \brief Split volumic elements into tetrahedrons
2054 //================================================================================
2056 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
2057 CORBA::Short methodFlags)
2058 throw (SALOME::SALOME_Exception)
2063 ::SMESH_MeshEditor::TFacetOfElem elemSet;
2064 const int noneFacet = -1;
2065 SMDS_ElemIteratorPtr volIt = myMesh_i->GetElements( elems, SMESH::VOLUME );
2066 while( volIt->more() )
2067 elemSet.insert( elemSet.end(), make_pair( volIt->next(), noneFacet ));
2069 getEditor().SplitVolumes( elemSet, int( methodFlags ));
2070 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2072 TPythonDump() << this << ".SplitVolumesIntoTetra( "
2073 << elems << ", " << methodFlags << " )";
2075 SMESH_CATCH( SMESH::throwCorbaException );
2078 //================================================================================
2080 * \brief Split hexahedra into triangular prisms
2081 * \param elems - elements to split
2082 * \param facetToSplitNormal - normal used to find a facet of hexahedron
2083 * to split into triangles
2084 * \param methodFlags - flags passing splitting method:
2085 * 1 - split the hexahedron into 2 prisms
2086 * 2 - split the hexahedron into 4 prisms
2088 //================================================================================
2090 void SMESH_MeshEditor_i::SplitHexahedraIntoPrisms( SMESH::SMESH_IDSource_ptr elems,
2091 const SMESH::PointStruct & startHexPoint,
2092 const SMESH::DirStruct& facetToSplitNormal,
2093 CORBA::Short methodFlags,
2094 CORBA::Boolean allDomains)
2095 throw (SALOME::SALOME_Exception)
2099 prepareIdSource( elems );
2101 gp_Ax1 facetNorm( gp_Pnt( startHexPoint.x,
2104 gp_Dir( facetToSplitNormal.PS.x,
2105 facetToSplitNormal.PS.y,
2106 facetToSplitNormal.PS.z ));
2107 TIDSortedElemSet elemSet;
2108 SMESH::long_array_var anElementsId = elems->GetIDs();
2109 SMDS_MeshElement::GeomFilter filter( SMDSGeom_HEXA );
2110 arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume, &filter );
2112 ::SMESH_MeshEditor::TFacetOfElem elemFacets;
2113 while ( !elemSet.empty() )
2115 getEditor().GetHexaFacetsToSplit( elemSet, facetNorm, elemFacets );
2119 ::SMESH_MeshEditor::TFacetOfElem::iterator ef = elemFacets.begin();
2120 for ( ; ef != elemFacets.end(); ++ef )
2121 elemSet.erase( ef->first );
2124 if ( methodFlags == 2 )
2125 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_4_PRISMS );
2127 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_2_PRISMS );
2129 getEditor().SplitVolumes( elemFacets, int( methodFlags ));
2130 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2132 TPythonDump() << this << ".SplitHexahedraIntoPrisms( "
2134 << startHexPoint << ", "
2135 << facetToSplitNormal<< ", "
2136 << methodFlags<< ", "
2137 << allDomains << " )";
2139 SMESH_CATCH( SMESH::throwCorbaException );
2142 //================================================================================
2144 * \brief Split bi-quadratic elements into linear ones without creation of additional nodes:
2145 * - bi-quadratic triangle will be split into 3 linear quadrangles;
2146 * - bi-quadratic quadrangle will be split into 4 linear quadrangles;
2147 * - tri-quadratic hexahedron will be split into 8 linear hexahedra.
2148 * Quadratic elements of lower dimension adjacent to the split bi-quadratic element
2149 * will be split in order to keep the mesh conformal.
2150 * \param elems - elements to split
2152 //================================================================================
2154 void SMESH_MeshEditor_i::SplitBiQuadraticIntoLinear(const SMESH::ListOfIDSources& theElems)
2155 throw (SALOME::SALOME_Exception)
2160 TIDSortedElemSet elemSet;
2161 for ( size_t i = 0; i < theElems.length(); ++i )
2163 SMESH::SMESH_IDSource_ptr elems = theElems[i].in();
2164 SMESH::SMESH_Mesh_var mesh = elems->GetMesh();
2165 if ( mesh->GetId() != myMesh_i->GetId() )
2166 THROW_SALOME_CORBA_EXCEPTION("Wrong mesh of IDSource", SALOME::BAD_PARAM);
2168 idSourceToSet( elems, getMeshDS(), elemSet, SMDSAbs_All );
2170 getEditor().SplitBiQuadraticIntoLinear( elemSet );
2172 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2174 TPythonDump() << this << ".SplitBiQuadraticIntoLinear( "
2175 << theElems << " )";
2177 SMESH_CATCH( SMESH::throwCorbaException );
2180 //=======================================================================
2183 //=======================================================================
2186 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
2187 const SMESH::long_array & IDsOfFixedNodes,
2188 CORBA::Long MaxNbOfIterations,
2189 CORBA::Double MaxAspectRatio,
2190 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2191 throw (SALOME::SALOME_Exception)
2193 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2194 MaxAspectRatio, Method, false );
2198 //=======================================================================
2199 //function : SmoothParametric
2201 //=======================================================================
2204 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
2205 const SMESH::long_array & IDsOfFixedNodes,
2206 CORBA::Long MaxNbOfIterations,
2207 CORBA::Double MaxAspectRatio,
2208 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2209 throw (SALOME::SALOME_Exception)
2211 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2212 MaxAspectRatio, Method, true );
2216 //=======================================================================
2217 //function : SmoothObject
2219 //=======================================================================
2222 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
2223 const SMESH::long_array & IDsOfFixedNodes,
2224 CORBA::Long MaxNbOfIterations,
2225 CORBA::Double MaxAspectRatio,
2226 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2227 throw (SALOME::SALOME_Exception)
2229 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2230 MaxAspectRatio, Method, false);
2234 //=======================================================================
2235 //function : SmoothParametricObject
2237 //=======================================================================
2240 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
2241 const SMESH::long_array & IDsOfFixedNodes,
2242 CORBA::Long MaxNbOfIterations,
2243 CORBA::Double MaxAspectRatio,
2244 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2245 throw (SALOME::SALOME_Exception)
2247 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2248 MaxAspectRatio, Method, true);
2252 //=============================================================================
2256 //=============================================================================
2259 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
2260 const SMESH::long_array & IDsOfFixedNodes,
2261 CORBA::Long MaxNbOfIterations,
2262 CORBA::Double MaxAspectRatio,
2263 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2265 throw (SALOME::SALOME_Exception)
2270 SMESHDS_Mesh* aMesh = getMeshDS();
2272 TIDSortedElemSet elements;
2273 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
2275 set<const SMDS_MeshNode*> fixedNodes;
2276 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
2277 CORBA::Long index = IDsOfFixedNodes[i];
2278 const SMDS_MeshNode * node = aMesh->FindNode(index);
2280 fixedNodes.insert( node );
2282 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
2283 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
2284 method = ::SMESH_MeshEditor::CENTROIDAL;
2286 getEditor().Smooth(elements, fixedNodes, method,
2287 MaxNbOfIterations, MaxAspectRatio, IsParametric );
2289 declareMeshModified( /*isReComputeSafe=*/true ); // does not prevent re-compute
2291 // Update Python script
2292 TPythonDump() << "isDone = " << this << "."
2293 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
2294 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
2295 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2296 << "SMESH.SMESH_MeshEditor."
2297 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2298 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2302 SMESH_CATCH( SMESH::throwCorbaException );
2306 //=============================================================================
2310 //=============================================================================
2313 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
2314 const SMESH::long_array & IDsOfFixedNodes,
2315 CORBA::Long MaxNbOfIterations,
2316 CORBA::Double MaxAspectRatio,
2317 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2319 throw (SALOME::SALOME_Exception)
2324 TPythonDump aTPythonDump; // suppress dump in smooth()
2326 prepareIdSource( theObject );
2327 SMESH::long_array_var anElementsId = theObject->GetIDs();
2328 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
2329 MaxAspectRatio, Method, IsParametric);
2331 // Update Python script
2332 aTPythonDump << "isDone = " << this << "."
2333 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
2334 << theObject << ", " << IDsOfFixedNodes << ", "
2335 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2336 << "SMESH.SMESH_MeshEditor."
2337 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2338 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2342 SMESH_CATCH( SMESH::throwCorbaException );
2346 //=============================================================================
2350 //=============================================================================
2352 void SMESH_MeshEditor_i::RenumberNodes()
2353 throw (SALOME::SALOME_Exception)
2356 // Update Python script
2357 TPythonDump() << this << ".RenumberNodes()";
2359 getMeshDS()->Renumber( true );
2361 SMESH_CATCH( SMESH::throwCorbaException );
2364 //=============================================================================
2368 //=============================================================================
2370 void SMESH_MeshEditor_i::RenumberElements()
2371 throw (SALOME::SALOME_Exception)
2374 // Update Python script
2375 TPythonDump() << this << ".RenumberElements()";
2377 getMeshDS()->Renumber( false );
2379 SMESH_CATCH( SMESH::throwCorbaException );
2382 //=======================================================================
2384 * \brief Return groups by their IDs
2386 //=======================================================================
2388 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
2389 throw (SALOME::SALOME_Exception)
2394 myMesh_i->CreateGroupServants();
2395 return myMesh_i->GetGroups( *groupIDs );
2397 SMESH_CATCH( SMESH::throwCorbaException );
2401 //=======================================================================
2402 //function : RotationSweepObjects
2404 //=======================================================================
2406 SMESH::ListOfGroups*
2407 SMESH_MeshEditor_i::RotationSweepObjects(const SMESH::ListOfIDSources & theNodes,
2408 const SMESH::ListOfIDSources & theEdges,
2409 const SMESH::ListOfIDSources & theFaces,
2410 const SMESH::AxisStruct & theAxis,
2411 CORBA::Double theAngleInRadians,
2412 CORBA::Long theNbOfSteps,
2413 CORBA::Double theTolerance,
2414 const bool theMakeGroups)
2415 throw (SALOME::SALOME_Exception)
2420 TIDSortedElemSet elemsNodes[2];
2421 for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) {
2422 SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE );
2423 while ( nIt->more() ) elemsNodes[1].insert( nIt->next() );
2425 for ( int i = 0, nb = theEdges.length(); i < nb; ++i )
2426 idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge );
2427 for ( int i = 0, nb = theFaces.length(); i < nb; ++i )
2428 idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face );
2430 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2431 bool makeWalls=true;
2432 if ( myIsPreviewMode )
2434 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2435 TPreviewMesh * tmpMesh = getPreviewMesh();
2436 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2437 tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid );
2438 workElements = & copyElements[0];
2439 //makeWalls = false; -- faces are needed for preview
2442 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2444 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
2445 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
2447 ::SMESH_MeshEditor::PGroupIDs groupIds =
2448 getEditor().RotationSweep (workElements, Ax1, theAngleInRadians,
2449 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
2451 SMESH::ListOfGroups * aGroups = theMakeGroups ? getGroups( groupIds.get()) : 0;
2453 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2455 if ( !myIsPreviewMode )
2457 dumpGroupsList( aPythonDump, aGroups );
2458 aPythonDump << this<< ".RotationSweepObjects( "
2463 << TVar( theAngleInRadians ) << ", "
2464 << TVar( theNbOfSteps ) << ", "
2465 << TVar( theTolerance ) << ", "
2466 << theMakeGroups << " )";
2470 getPreviewMesh()->Remove( SMDSAbs_Volume );
2473 return aGroups ? aGroups : new SMESH::ListOfGroups;
2475 SMESH_CATCH( SMESH::throwCorbaException );
2479 namespace MeshEditor_I
2482 * \brief Structure used to pass extrusion parameters to ::SMESH_MeshEditor
2484 struct ExtrusionParams : public ::SMESH_MeshEditor::ExtrusParam
2486 bool myIsExtrusionByNormal;
2488 static int makeFlags( CORBA::Boolean MakeGroups,
2489 CORBA::Boolean ByAverageNormal = false,
2490 CORBA::Boolean UseInputElemsOnly = false,
2491 CORBA::Long Flags = 0,
2492 CORBA::Boolean MakeBoundary = true )
2494 if ( MakeGroups ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS;
2495 if ( ByAverageNormal ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BY_AVG_NORMAL;
2496 if ( UseInputElemsOnly) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY;
2497 if ( MakeBoundary ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BOUNDARY;
2501 ExtrusionParams(const SMESH::DirStruct & theDir,
2502 CORBA::Long theNbOfSteps,
2503 CORBA::Boolean theMakeGroups):
2504 ::SMESH_MeshEditor::ExtrusParam ( gp_Vec( theDir.PS.x,
2508 makeFlags( theMakeGroups )),
2509 myIsExtrusionByNormal( false )
2513 ExtrusionParams(const SMESH::DirStruct & theDir,
2514 CORBA::Long theNbOfSteps,
2515 CORBA::Boolean theMakeGroups,
2516 CORBA::Long theExtrFlags,
2517 CORBA::Double theSewTolerance):
2518 ::SMESH_MeshEditor::ExtrusParam ( gp_Vec( theDir.PS.x,
2522 makeFlags( theMakeGroups, false, false,
2523 theExtrFlags, false ),
2525 myIsExtrusionByNormal( false )
2528 // params for extrusion by normal
2529 ExtrusionParams(CORBA::Double theStepSize,
2530 CORBA::Long theNbOfSteps,
2531 CORBA::Short theDim,
2532 CORBA::Boolean theByAverageNormal,
2533 CORBA::Boolean theUseInputElemsOnly,
2534 CORBA::Boolean theMakeGroups ):
2535 ::SMESH_MeshEditor::ExtrusParam ( theStepSize,
2537 makeFlags( theMakeGroups,
2538 theByAverageNormal, theUseInputElemsOnly ),
2540 myIsExtrusionByNormal( true )
2546 Flags() &= ~(::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS);
2551 //=======================================================================
2553 * \brief Generate dim+1 elements by extrusion of elements along vector
2554 * \param [in] edges - edges to extrude: a list including groups, sub-meshes or a mesh
2555 * \param [in] faces - faces to extrude: a list including groups, sub-meshes or a mesh
2556 * \param [in] nodes - nodes to extrude: a list including groups, sub-meshes or a mesh
2557 * \param [in] stepVector - vector giving direction and distance of an extrusion step
2558 * \param [in] nbOfSteps - number of elements to generate from one element
2559 * \param [in] toMakeGroups - if true, new elements will be included into new groups
2560 * corresponding to groups the input elements included in.
2561 * \return ListOfGroups - new groups craeted if \a toMakeGroups is true
2563 //=======================================================================
2565 SMESH::ListOfGroups*
2566 SMESH_MeshEditor_i::ExtrusionSweepObjects(const SMESH::ListOfIDSources & theNodes,
2567 const SMESH::ListOfIDSources & theEdges,
2568 const SMESH::ListOfIDSources & theFaces,
2569 const SMESH::DirStruct & theStepVector,
2570 CORBA::Long theNbOfSteps,
2571 CORBA::Boolean theToMakeGroups)
2572 throw (SALOME::SALOME_Exception)
2577 ExtrusionParams params( theStepVector, theNbOfSteps, theToMakeGroups );
2579 TIDSortedElemSet elemsNodes[2];
2580 for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) {
2581 SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE );
2582 while ( nIt->more() ) elemsNodes[1].insert( nIt->next() );
2584 for ( int i = 0, nb = theEdges.length(); i < nb; ++i )
2585 idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge );
2586 for ( int i = 0, nb = theFaces.length(); i < nb; ++i )
2587 idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face );
2589 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2590 SMDSAbs_ElementType previewType = SMDSAbs_All; //SMDSAbs_Face;
2591 if ( myIsPreviewMode )
2593 // if ( (*elemsNodes.begin())->GetType() == SMDSAbs_Node )
2594 // previewType = SMDSAbs_Edge;
2596 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2597 TPreviewMesh * tmpMesh = getPreviewMesh( previewType );
2598 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2599 tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid );
2600 workElements = & copyElements[0];
2602 params.SetNoGroups();
2604 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2606 ::SMESH_MeshEditor::TTElemOfElemListMap aHistory;
2607 ::SMESH_MeshEditor::PGroupIDs groupIds =
2608 getEditor().ExtrusionSweep( workElements, params, aHistory );
2610 SMESH::ListOfGroups * aGroups = theToMakeGroups ? getGroups( groupIds.get()) : 0;
2612 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2614 if ( !myIsPreviewMode )
2616 dumpGroupsList( aPythonDump, aGroups );
2617 aPythonDump << this<< ".ExtrusionSweepObjects( "
2621 << theStepVector << ", "
2622 << TVar( theNbOfSteps ) << ", "
2623 << theToMakeGroups << " )";
2627 getPreviewMesh( previewType )->Remove( SMDSAbs_Volume );
2630 return aGroups ? aGroups : new SMESH::ListOfGroups;
2632 SMESH_CATCH( SMESH::throwCorbaException );
2636 //=======================================================================
2637 //function : ExtrusionByNormal
2639 //=======================================================================
2641 SMESH::ListOfGroups*
2642 SMESH_MeshEditor_i::ExtrusionByNormal(const SMESH::ListOfIDSources& objects,
2643 CORBA::Double stepSize,
2644 CORBA::Long nbOfSteps,
2645 CORBA::Boolean byAverageNormal,
2646 CORBA::Boolean useInputElemsOnly,
2647 CORBA::Boolean makeGroups,
2649 throw (SALOME::SALOME_Exception)
2654 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2656 ExtrusionParams params( stepSize, nbOfSteps, dim,
2657 byAverageNormal, useInputElemsOnly, makeGroups );
2659 SMDSAbs_ElementType elemType = ( dim == 1 ? SMDSAbs_Edge : SMDSAbs_Face );
2660 if ( objects.length() > 0 && !SMESH::DownCast<SMESH_Mesh_i*>( objects[0] ))
2662 SMESH::array_of_ElementType_var elemTypes = objects[0]->GetTypes();
2663 if (( elemTypes->length() == 1 ) &&
2664 ( elemTypes[0] == SMESH::EDGE || elemTypes[0] == SMESH::FACE ))
2665 elemType = ( SMDSAbs_ElementType ) elemTypes[0];
2668 TIDSortedElemSet elemsNodes[2];
2669 for ( int i = 0, nb = objects.length(); i < nb; ++i )
2670 idSourceToSet( objects[i], getMeshDS(), elemsNodes[0], elemType );
2672 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2673 SMDSAbs_ElementType previewType = SMDSAbs_Face;
2674 if ( myIsPreviewMode )
2676 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2677 TPreviewMesh * tmpMesh = getPreviewMesh( previewType );
2678 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2679 workElements = & copyElements[0];
2681 params.SetNoGroups();
2684 ::SMESH_MeshEditor::TTElemOfElemListMap aHistory;
2685 ::SMESH_MeshEditor::PGroupIDs groupIds =
2686 getEditor().ExtrusionSweep( workElements, params, aHistory );
2688 SMESH::ListOfGroups * aGroups = makeGroups ? getGroups( groupIds.get()) : 0;
2690 if (!myIsPreviewMode) {
2691 dumpGroupsList(aPythonDump, aGroups);
2692 aPythonDump << this << ".ExtrusionByNormal( " << objects
2693 << ", " << TVar( stepSize )
2694 << ", " << TVar( nbOfSteps )
2695 << ", " << byAverageNormal
2696 << ", " << useInputElemsOnly
2697 << ", " << makeGroups
2703 getPreviewMesh( previewType )->Remove( SMDSAbs_Volume );
2706 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2708 return aGroups ? aGroups : new SMESH::ListOfGroups;
2710 SMESH_CATCH( SMESH::throwCorbaException );
2714 //=======================================================================
2715 //function : AdvancedExtrusion
2717 //=======================================================================
2719 SMESH::ListOfGroups*
2720 SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2721 const SMESH::DirStruct & theStepVector,
2722 CORBA::Long theNbOfSteps,
2723 CORBA::Long theExtrFlags,
2724 CORBA::Double theSewTolerance,
2725 CORBA::Boolean theMakeGroups)
2726 throw (SALOME::SALOME_Exception)
2731 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2733 ExtrusionParams params( theStepVector, theNbOfSteps, theMakeGroups,
2734 theExtrFlags, theSewTolerance );
2736 TIDSortedElemSet elemsNodes[2];
2737 arrayToSet( theIDsOfElements, getMeshDS(), elemsNodes[0] );
2739 ::SMESH_MeshEditor::TTElemOfElemListMap aHistory;
2740 ::SMESH_MeshEditor::PGroupIDs groupIds =
2741 getEditor().ExtrusionSweep( elemsNodes, params, aHistory );
2743 SMESH::ListOfGroups * aGroups = theMakeGroups ? getGroups( groupIds.get()) : 0;
2745 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2747 if ( !myIsPreviewMode ) {
2748 dumpGroupsList(aPythonDump, aGroups);
2749 aPythonDump << this << ".AdvancedExtrusion( "
2750 << theIDsOfElements << ", "
2751 << theStepVector << ", "
2752 << theNbOfSteps << ", "
2753 << theExtrFlags << ", "
2754 << theSewTolerance << ", "
2755 << theMakeGroups << " )";
2759 getPreviewMesh()->Remove( SMDSAbs_Volume );
2762 return aGroups ? aGroups : new SMESH::ListOfGroups;
2764 SMESH_CATCH( SMESH::throwCorbaException );
2768 //================================================================================
2770 * \brief Convert extrusion error to IDL enum
2772 //================================================================================
2776 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
2778 SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( ::SMESH_MeshEditor::Extrusion_Error e )
2782 RETCASE( EXTR_NO_ELEMENTS );
2783 RETCASE( EXTR_PATH_NOT_EDGE );
2784 RETCASE( EXTR_BAD_PATH_SHAPE );
2785 RETCASE( EXTR_BAD_STARTING_NODE );
2786 RETCASE( EXTR_BAD_ANGLES_NUMBER );
2787 RETCASE( EXTR_CANT_GET_TANGENT );
2789 return SMESH::SMESH_MeshEditor::EXTR_OK;
2793 //=======================================================================
2794 //function : extrusionAlongPath
2796 //=======================================================================
2797 SMESH::ListOfGroups*
2798 SMESH_MeshEditor_i::ExtrusionAlongPathObjects(const SMESH::ListOfIDSources & theNodes,
2799 const SMESH::ListOfIDSources & theEdges,
2800 const SMESH::ListOfIDSources & theFaces,
2801 SMESH::SMESH_IDSource_ptr thePathMesh,
2802 GEOM::GEOM_Object_ptr thePathShape,
2803 CORBA::Long theNodeStart,
2804 CORBA::Boolean theHasAngles,
2805 const SMESH::double_array & theAngles,
2806 CORBA::Boolean theLinearVariation,
2807 CORBA::Boolean theHasRefPoint,
2808 const SMESH::PointStruct & theRefPoint,
2810 SMESH::SMESH_MeshEditor::Extrusion_Error& theError)
2811 throw (SALOME::SALOME_Exception)
2816 SMESH::ListOfGroups_var aGroups = new SMESH::ListOfGroups;
2818 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2819 if ( thePathMesh->_is_nil() )
2820 return aGroups._retn();
2823 SMESH_subMesh* aSubMesh = 0;
2824 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2825 if ( thePathShape->_is_nil() )
2827 // thePathMesh should be either a sub-mesh or a mesh with 1D elements only
2828 if ( SMESH_subMesh_i* sm = SMESH::DownCast<SMESH_subMesh_i*>( thePathMesh ))
2830 SMESH::SMESH_Mesh_var mesh = thePathMesh->GetMesh();
2831 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
2832 if ( !aMeshImp ) return aGroups._retn();
2833 aSubMesh = aMeshImp->GetImpl().GetSubMeshContaining( sm->GetId() );
2834 if ( !aSubMesh ) return aGroups._retn();
2836 else if ( !aMeshImp ||
2837 aMeshImp->NbEdges() != aMeshImp->NbElements() )
2839 return aGroups._retn();
2844 if ( !aMeshImp ) return aGroups._retn();
2845 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2846 aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2847 if ( !aSubMesh || !aSubMesh->GetSubMeshDS() )
2848 return aGroups._retn();
2851 SMDS_MeshNode* nodeStart =
2852 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
2854 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2855 return aGroups._retn();
2858 TIDSortedElemSet elemsNodes[2];
2859 for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) {
2860 SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE );
2861 while ( nIt->more() ) elemsNodes[1].insert( nIt->next() );
2863 for ( int i = 0, nb = theEdges.length(); i < nb; ++i )
2864 idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge );
2865 for ( int i = 0, nb = theFaces.length(); i < nb; ++i )
2866 idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face );
2868 list<double> angles;
2869 for (int i = 0; i < theAngles.length(); i++) {
2870 angles.push_back( theAngles[i] );
2873 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
2875 int nbOldGroups = myMesh->NbGroup();
2877 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2878 if ( myIsPreviewMode )
2880 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2881 TPreviewMesh * tmpMesh = getPreviewMesh();
2882 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2883 tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid );
2884 workElements = & copyElements[0];
2885 theMakeGroups = false;
2888 ::SMESH_MeshEditor::Extrusion_Error error;
2890 error = getEditor().ExtrusionAlongTrack( workElements, &(aMeshImp->GetImpl()), nodeStart,
2891 theHasAngles, angles, theLinearVariation,
2892 theHasRefPoint, refPnt, theMakeGroups );
2894 error = getEditor().ExtrusionAlongTrack( workElements, aSubMesh, nodeStart,
2895 theHasAngles, angles, theLinearVariation,
2896 theHasRefPoint, refPnt, theMakeGroups );
2898 declareMeshModified( /*isReComputeSafe=*/true );
2899 theError = convExtrError( error );
2901 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2902 if ( theMakeGroups ) {
2903 list<int> groupIDs = myMesh->GetGroupIds();
2904 list<int>::iterator newBegin = groupIDs.begin();
2905 std::advance( newBegin, nbOldGroups ); // skip old groups
2906 groupIDs.erase( groupIDs.begin(), newBegin );
2907 aGroups = getGroups( & groupIDs );
2908 if ( ! &aGroups.in() ) aGroups = new SMESH::ListOfGroups;
2911 if ( !myIsPreviewMode ) {
2912 aPythonDump << "(" << aGroups << ", error) = "
2913 << this << ".ExtrusionAlongPathObjects( "
2917 << thePathMesh << ", "
2918 << thePathShape << ", "
2919 << theNodeStart << ", "
2920 << theHasAngles << ", "
2921 << theAngles << ", "
2922 << theLinearVariation << ", "
2923 << theHasRefPoint << ", "
2924 << "SMESH.PointStruct( "
2925 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2926 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2927 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ), "
2928 << theMakeGroups << " )";
2932 getPreviewMesh()->Remove( SMDSAbs_Volume );
2935 return aGroups._retn();
2937 SMESH_CATCH( SMESH::throwCorbaException );
2941 //================================================================================
2943 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
2944 * of given angles along path steps
2945 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
2946 * which proceeds the extrusion
2947 * \param PathShape is shape(edge); as the mesh can be complex, the edge
2948 * is used to define the sub-mesh for the path
2950 //================================================================================
2952 SMESH::double_array*
2953 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
2954 GEOM::GEOM_Object_ptr thePathShape,
2955 const SMESH::double_array & theAngles)
2957 SMESH::double_array_var aResult = new SMESH::double_array();
2958 int nbAngles = theAngles.length();
2959 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
2961 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2962 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2963 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2964 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
2965 return aResult._retn();
2966 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
2967 if ( nbSteps == nbAngles )
2969 aResult.inout() = theAngles;
2973 aResult->length( nbSteps );
2974 double rAn2St = double( nbAngles ) / double( nbSteps );
2975 double angPrev = 0, angle;
2976 for ( int iSt = 0; iSt < nbSteps; ++iSt )
2978 double angCur = rAn2St * ( iSt+1 );
2979 double angCurFloor = floor( angCur );
2980 double angPrevFloor = floor( angPrev );
2981 if ( angPrevFloor == angCurFloor )
2982 angle = rAn2St * theAngles[ int( angCurFloor ) ];
2985 int iP = int( angPrevFloor );
2986 double angPrevCeil = ceil(angPrev);
2987 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
2989 int iC = int( angCurFloor );
2990 if ( iC < nbAngles )
2991 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
2993 iP = int( angPrevCeil );
2995 angle += theAngles[ iC ];
2997 aResult[ iSt ] = angle;
3002 // Update Python script
3003 TPythonDump() << "rotAngles = " << theAngles;
3004 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
3005 << thePathMesh << ", "
3006 << thePathShape << ", "
3009 return aResult._retn();
3012 //=======================================================================
3015 //=======================================================================
3017 SMESH::ListOfGroups*
3018 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
3019 const SMESH::AxisStruct & theAxis,
3020 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3021 CORBA::Boolean theCopy,
3023 ::SMESH_Mesh* theTargetMesh)
3024 throw (SALOME::SALOME_Exception)
3029 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3030 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3032 if ( theTargetMesh )
3036 switch ( theMirrorType ) {
3037 case SMESH::SMESH_MeshEditor::POINT:
3038 aTrsf.SetMirror( P );
3040 case SMESH::SMESH_MeshEditor::AXIS:
3041 aTrsf.SetMirror( gp_Ax1( P, V ));
3044 aTrsf.SetMirror( gp_Ax2( P, V ));
3047 TIDSortedElemSet copyElements;
3048 TIDSortedElemSet* workElements = & theElements;
3050 if ( myIsPreviewMode )
3052 TPreviewMesh * tmpMesh = getPreviewMesh();
3053 tmpMesh->Copy( theElements, copyElements);
3054 if ( !theCopy && !theTargetMesh )
3056 TIDSortedElemSet elemsAround, elemsAroundCopy;
3057 getElementsAround( theElements, getMeshDS(), elemsAround );
3058 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3060 workElements = & copyElements;
3061 theMakeGroups = false;
3064 ::SMESH_MeshEditor::PGroupIDs groupIds =
3065 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3067 if ( theCopy && !myIsPreviewMode)
3069 if ( theTargetMesh )
3071 theTargetMesh->GetMeshDS()->Modified();
3075 declareMeshModified( /*isReComputeSafe=*/false );
3078 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3080 SMESH_CATCH( SMESH::throwCorbaException );
3084 //=======================================================================
3087 //=======================================================================
3089 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3090 const SMESH::AxisStruct & theAxis,
3091 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3092 CORBA::Boolean theCopy)
3093 throw (SALOME::SALOME_Exception)
3095 if ( !myIsPreviewMode ) {
3096 TPythonDump() << this << ".Mirror( "
3097 << theIDsOfElements << ", "
3099 << mirrorTypeName(theMirrorType) << ", "
3102 if ( theIDsOfElements.length() > 0 )
3104 TIDSortedElemSet elements;
3105 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3106 mirror(elements, theAxis, theMirrorType, theCopy, false);
3111 //=======================================================================
3112 //function : MirrorObject
3114 //=======================================================================
3116 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3117 const SMESH::AxisStruct & theAxis,
3118 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3119 CORBA::Boolean theCopy)
3120 throw (SALOME::SALOME_Exception)
3122 if ( !myIsPreviewMode ) {
3123 TPythonDump() << this << ".MirrorObject( "
3124 << theObject << ", "
3126 << mirrorTypeName(theMirrorType) << ", "
3129 TIDSortedElemSet elements;
3131 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3133 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3134 mirror(elements, theAxis, theMirrorType, theCopy, false);
3137 //=======================================================================
3138 //function : MirrorMakeGroups
3140 //=======================================================================
3142 SMESH::ListOfGroups*
3143 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3144 const SMESH::AxisStruct& theMirror,
3145 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3146 throw (SALOME::SALOME_Exception)
3148 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3150 SMESH::ListOfGroups * aGroups = 0;
3151 if ( theIDsOfElements.length() > 0 )
3153 TIDSortedElemSet elements;
3154 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3155 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3157 if (!myIsPreviewMode) {
3158 dumpGroupsList(aPythonDump, aGroups);
3159 aPythonDump << this << ".MirrorMakeGroups( "
3160 << theIDsOfElements << ", "
3161 << theMirror << ", "
3162 << mirrorTypeName(theMirrorType) << " )";
3167 //=======================================================================
3168 //function : MirrorObjectMakeGroups
3170 //=======================================================================
3172 SMESH::ListOfGroups*
3173 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3174 const SMESH::AxisStruct& theMirror,
3175 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3176 throw (SALOME::SALOME_Exception)
3178 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3180 SMESH::ListOfGroups * aGroups = 0;
3181 TIDSortedElemSet elements;
3182 if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3183 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3185 if (!myIsPreviewMode)
3187 dumpGroupsList(aPythonDump,aGroups);
3188 aPythonDump << this << ".MirrorObjectMakeGroups( "
3189 << theObject << ", "
3190 << theMirror << ", "
3191 << mirrorTypeName(theMirrorType) << " )";
3196 //=======================================================================
3197 //function : MirrorMakeMesh
3199 //=======================================================================
3201 SMESH::SMESH_Mesh_ptr
3202 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
3203 const SMESH::AxisStruct& theMirror,
3204 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3205 CORBA::Boolean theCopyGroups,
3206 const char* theMeshName)
3207 throw (SALOME::SALOME_Exception)
3209 SMESH_Mesh_i* mesh_i;
3210 SMESH::SMESH_Mesh_var mesh;
3211 { // open new scope to dump "MakeMesh" command
3212 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3214 TPythonDump pydump; // to prevent dump at mesh creation
3216 mesh = makeMesh( theMeshName );
3217 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3218 if (mesh_i && theIDsOfElements.length() > 0 )
3220 TIDSortedElemSet elements;
3221 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3222 mirror(elements, theMirror, theMirrorType,
3223 false, theCopyGroups, & mesh_i->GetImpl());
3224 mesh_i->CreateGroupServants();
3227 if (!myIsPreviewMode) {
3228 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
3229 << theIDsOfElements << ", "
3230 << theMirror << ", "
3231 << mirrorTypeName(theMirrorType) << ", "
3232 << theCopyGroups << ", '"
3233 << theMeshName << "' )";
3238 if (!myIsPreviewMode && mesh_i)
3239 mesh_i->GetGroups();
3241 return mesh._retn();
3244 //=======================================================================
3245 //function : MirrorObjectMakeMesh
3247 //=======================================================================
3249 SMESH::SMESH_Mesh_ptr
3250 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3251 const SMESH::AxisStruct& theMirror,
3252 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3253 CORBA::Boolean theCopyGroups,
3254 const char* theMeshName)
3255 throw (SALOME::SALOME_Exception)
3257 SMESH_Mesh_i* mesh_i;
3258 SMESH::SMESH_Mesh_var mesh;
3259 { // open new scope to dump "MakeMesh" command
3260 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3262 TPythonDump pydump; // to prevent dump at mesh creation
3264 mesh = makeMesh( theMeshName );
3265 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3266 TIDSortedElemSet elements;
3268 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3270 mirror(elements, theMirror, theMirrorType,
3271 false, theCopyGroups, & mesh_i->GetImpl());
3272 mesh_i->CreateGroupServants();
3274 if (!myIsPreviewMode) {
3275 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
3276 << theObject << ", "
3277 << theMirror << ", "
3278 << mirrorTypeName(theMirrorType) << ", "
3279 << theCopyGroups << ", '"
3280 << theMeshName << "' )";
3285 if (!myIsPreviewMode && mesh_i)
3286 mesh_i->GetGroups();
3288 return mesh._retn();
3291 //=======================================================================
3292 //function : translate
3294 //=======================================================================
3296 SMESH::ListOfGroups*
3297 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
3298 const SMESH::DirStruct & theVector,
3299 CORBA::Boolean theCopy,
3301 ::SMESH_Mesh* theTargetMesh)
3302 throw (SALOME::SALOME_Exception)
3307 if ( theTargetMesh )
3311 const SMESH::PointStruct * P = &theVector.PS;
3312 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
3314 TIDSortedElemSet copyElements;
3315 TIDSortedElemSet* workElements = &theElements;
3317 if ( myIsPreviewMode )
3319 TPreviewMesh * tmpMesh = getPreviewMesh();
3320 tmpMesh->Copy( theElements, copyElements);
3321 if ( !theCopy && !theTargetMesh )
3323 TIDSortedElemSet elemsAround, elemsAroundCopy;
3324 getElementsAround( theElements, getMeshDS(), elemsAround );
3325 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3327 workElements = & copyElements;
3328 theMakeGroups = false;
3331 ::SMESH_MeshEditor::PGroupIDs groupIds =
3332 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3334 if ( theCopy && !myIsPreviewMode )
3336 if ( theTargetMesh )
3338 theTargetMesh->GetMeshDS()->Modified();
3342 declareMeshModified( /*isReComputeSafe=*/false );
3346 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3348 SMESH_CATCH( SMESH::throwCorbaException );
3352 //=======================================================================
3353 //function : Translate
3355 //=======================================================================
3357 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
3358 const SMESH::DirStruct & theVector,
3359 CORBA::Boolean theCopy)
3360 throw (SALOME::SALOME_Exception)
3362 if (!myIsPreviewMode) {
3363 TPythonDump() << this << ".Translate( "
3364 << theIDsOfElements << ", "
3365 << theVector << ", "
3368 if (theIDsOfElements.length()) {
3369 TIDSortedElemSet elements;
3370 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3371 translate(elements, theVector, theCopy, false);
3375 //=======================================================================
3376 //function : TranslateObject
3378 //=======================================================================
3380 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
3381 const SMESH::DirStruct & theVector,
3382 CORBA::Boolean theCopy)
3383 throw (SALOME::SALOME_Exception)
3385 if (!myIsPreviewMode) {
3386 TPythonDump() << this << ".TranslateObject( "
3387 << theObject << ", "
3388 << theVector << ", "
3391 TIDSortedElemSet elements;
3393 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3395 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3396 translate(elements, theVector, theCopy, false);
3399 //=======================================================================
3400 //function : TranslateMakeGroups
3402 //=======================================================================
3404 SMESH::ListOfGroups*
3405 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
3406 const SMESH::DirStruct& theVector)
3407 throw (SALOME::SALOME_Exception)
3409 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3411 SMESH::ListOfGroups * aGroups = 0;
3412 if (theIDsOfElements.length()) {
3413 TIDSortedElemSet elements;
3414 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3415 aGroups = translate(elements,theVector,true,true);
3417 if (!myIsPreviewMode) {
3418 dumpGroupsList(aPythonDump, aGroups);
3419 aPythonDump << this << ".TranslateMakeGroups( "
3420 << theIDsOfElements << ", "
3421 << theVector << " )";
3426 //=======================================================================
3427 //function : TranslateObjectMakeGroups
3429 //=======================================================================
3431 SMESH::ListOfGroups*
3432 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3433 const SMESH::DirStruct& theVector)
3434 throw (SALOME::SALOME_Exception)
3436 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3438 SMESH::ListOfGroups * aGroups = 0;
3439 TIDSortedElemSet elements;
3440 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3441 aGroups = translate(elements, theVector, true, true);
3443 if (!myIsPreviewMode) {
3444 dumpGroupsList(aPythonDump, aGroups);
3445 aPythonDump << this << ".TranslateObjectMakeGroups( "
3446 << theObject << ", "
3447 << theVector << " )";
3452 //=======================================================================
3453 //function : TranslateMakeMesh
3455 //=======================================================================
3457 SMESH::SMESH_Mesh_ptr
3458 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
3459 const SMESH::DirStruct& theVector,
3460 CORBA::Boolean theCopyGroups,
3461 const char* theMeshName)
3462 throw (SALOME::SALOME_Exception)
3464 SMESH_Mesh_i* mesh_i;
3465 SMESH::SMESH_Mesh_var mesh;
3467 { // open new scope to dump "MakeMesh" command
3468 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3470 TPythonDump pydump; // to prevent dump at mesh creation
3472 mesh = makeMesh( theMeshName );
3473 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3475 if ( mesh_i && theIDsOfElements.length() )
3477 TIDSortedElemSet elements;
3478 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3479 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
3480 mesh_i->CreateGroupServants();
3483 if ( !myIsPreviewMode ) {
3484 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
3485 << theIDsOfElements << ", "
3486 << theVector << ", "
3487 << theCopyGroups << ", '"
3488 << theMeshName << "' )";
3493 if (!myIsPreviewMode && mesh_i)
3494 mesh_i->GetGroups();
3496 return mesh._retn();
3499 //=======================================================================
3500 //function : TranslateObjectMakeMesh
3502 //=======================================================================
3504 SMESH::SMESH_Mesh_ptr
3505 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3506 const SMESH::DirStruct& theVector,
3507 CORBA::Boolean theCopyGroups,
3508 const char* theMeshName)
3509 throw (SALOME::SALOME_Exception)
3512 SMESH_Mesh_i* mesh_i;
3513 SMESH::SMESH_Mesh_var mesh;
3514 { // open new scope to dump "MakeMesh" command
3515 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3517 TPythonDump pydump; // to prevent dump at mesh creation
3518 mesh = makeMesh( theMeshName );
3519 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3521 TIDSortedElemSet elements;
3523 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3525 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
3526 mesh_i->CreateGroupServants();
3528 if ( !myIsPreviewMode ) {
3529 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
3530 << theObject << ", "
3531 << theVector << ", "
3532 << theCopyGroups << ", '"
3533 << theMeshName << "' )";
3538 if (!myIsPreviewMode && mesh_i)
3539 mesh_i->GetGroups();
3541 return mesh._retn();
3543 SMESH_CATCH( SMESH::throwCorbaException );
3547 //=======================================================================
3550 //=======================================================================
3552 SMESH::ListOfGroups*
3553 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
3554 const SMESH::AxisStruct & theAxis,
3555 CORBA::Double theAngle,
3556 CORBA::Boolean theCopy,
3558 ::SMESH_Mesh* theTargetMesh)
3559 throw (SALOME::SALOME_Exception)
3564 if ( theTargetMesh )
3567 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3568 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3571 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
3573 TIDSortedElemSet copyElements;
3574 TIDSortedElemSet* workElements = &theElements;
3575 if ( myIsPreviewMode ) {
3576 TPreviewMesh * tmpMesh = getPreviewMesh();
3577 tmpMesh->Copy( theElements, copyElements );
3578 if ( !theCopy && !theTargetMesh )
3580 TIDSortedElemSet elemsAround, elemsAroundCopy;
3581 getElementsAround( theElements, getMeshDS(), elemsAround );
3582 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3584 workElements = ©Elements;
3585 theMakeGroups = false;
3588 ::SMESH_MeshEditor::PGroupIDs groupIds =
3589 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3591 if ( theCopy && !myIsPreviewMode)
3593 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
3594 else declareMeshModified( /*isReComputeSafe=*/false );
3597 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3599 SMESH_CATCH( SMESH::throwCorbaException );
3603 //=======================================================================
3606 //=======================================================================
3608 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
3609 const SMESH::AxisStruct & theAxis,
3610 CORBA::Double theAngle,
3611 CORBA::Boolean theCopy)
3612 throw (SALOME::SALOME_Exception)
3614 if (!myIsPreviewMode) {
3615 TPythonDump() << this << ".Rotate( "
3616 << theIDsOfElements << ", "
3618 << TVar( theAngle ) << ", "
3621 if (theIDsOfElements.length() > 0)
3623 TIDSortedElemSet elements;
3624 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3625 rotate(elements,theAxis,theAngle,theCopy,false);
3629 //=======================================================================
3630 //function : RotateObject
3632 //=======================================================================
3634 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
3635 const SMESH::AxisStruct & theAxis,
3636 CORBA::Double theAngle,
3637 CORBA::Boolean theCopy)
3638 throw (SALOME::SALOME_Exception)
3640 if ( !myIsPreviewMode ) {
3641 TPythonDump() << this << ".RotateObject( "
3642 << theObject << ", "
3644 << TVar( theAngle ) << ", "
3647 TIDSortedElemSet elements;
3648 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3649 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3650 rotate(elements,theAxis,theAngle,theCopy,false);
3653 //=======================================================================
3654 //function : RotateMakeGroups
3656 //=======================================================================
3658 SMESH::ListOfGroups*
3659 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
3660 const SMESH::AxisStruct& theAxis,
3661 CORBA::Double theAngle)
3662 throw (SALOME::SALOME_Exception)
3664 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3666 SMESH::ListOfGroups * aGroups = 0;
3667 if (theIDsOfElements.length() > 0)
3669 TIDSortedElemSet elements;
3670 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3671 aGroups = rotate(elements,theAxis,theAngle,true,true);
3673 if (!myIsPreviewMode) {
3674 dumpGroupsList(aPythonDump, aGroups);
3675 aPythonDump << this << ".RotateMakeGroups( "
3676 << theIDsOfElements << ", "
3678 << TVar( theAngle ) << " )";
3683 //=======================================================================
3684 //function : RotateObjectMakeGroups
3686 //=======================================================================
3688 SMESH::ListOfGroups*
3689 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3690 const SMESH::AxisStruct& theAxis,
3691 CORBA::Double theAngle)
3692 throw (SALOME::SALOME_Exception)
3694 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3696 SMESH::ListOfGroups * aGroups = 0;
3697 TIDSortedElemSet elements;
3698 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3699 aGroups = rotate(elements, theAxis, theAngle, true, true);
3701 if (!myIsPreviewMode) {
3702 dumpGroupsList(aPythonDump, aGroups);
3703 aPythonDump << this << ".RotateObjectMakeGroups( "
3704 << theObject << ", "
3706 << TVar( theAngle ) << " )";
3711 //=======================================================================
3712 //function : RotateMakeMesh
3714 //=======================================================================
3716 SMESH::SMESH_Mesh_ptr
3717 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
3718 const SMESH::AxisStruct& theAxis,
3719 CORBA::Double theAngleInRadians,
3720 CORBA::Boolean theCopyGroups,
3721 const char* theMeshName)
3722 throw (SALOME::SALOME_Exception)
3725 SMESH::SMESH_Mesh_var mesh;
3726 SMESH_Mesh_i* mesh_i;
3728 { // open new scope to dump "MakeMesh" command
3729 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3731 TPythonDump pydump; // to prevent dump at mesh creation
3733 mesh = makeMesh( theMeshName );
3734 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3736 if ( mesh_i && theIDsOfElements.length() > 0 )
3738 TIDSortedElemSet elements;
3739 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3740 rotate(elements, theAxis, theAngleInRadians,
3741 false, theCopyGroups, & mesh_i->GetImpl());
3742 mesh_i->CreateGroupServants();
3744 if ( !myIsPreviewMode ) {
3745 pydump << mesh << " = " << this << ".RotateMakeMesh( "
3746 << theIDsOfElements << ", "
3748 << TVar( theAngleInRadians ) << ", "
3749 << theCopyGroups << ", '"
3750 << theMeshName << "' )";
3755 if (!myIsPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
3756 mesh_i->GetGroups();
3758 return mesh._retn();
3760 SMESH_CATCH( SMESH::throwCorbaException );
3764 //=======================================================================
3765 //function : RotateObjectMakeMesh
3767 //=======================================================================
3769 SMESH::SMESH_Mesh_ptr
3770 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3771 const SMESH::AxisStruct& theAxis,
3772 CORBA::Double theAngleInRadians,
3773 CORBA::Boolean theCopyGroups,
3774 const char* theMeshName)
3775 throw (SALOME::SALOME_Exception)
3778 SMESH::SMESH_Mesh_var mesh;
3779 SMESH_Mesh_i* mesh_i;
3781 {// open new scope to dump "MakeMesh" command
3782 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3784 TPythonDump pydump; // to prevent dump at mesh creation
3785 mesh = makeMesh( theMeshName );
3786 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3788 TIDSortedElemSet elements;
3790 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3792 rotate(elements, theAxis, theAngleInRadians,
3793 false, theCopyGroups, & mesh_i->GetImpl());
3794 mesh_i->CreateGroupServants();
3796 if ( !myIsPreviewMode ) {
3797 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
3798 << theObject << ", "
3800 << TVar( theAngleInRadians ) << ", "
3801 << theCopyGroups << ", '"
3802 << theMeshName << "' )";
3807 if (!myIsPreviewMode && mesh_i)
3808 mesh_i->GetGroups();
3810 return mesh._retn();
3812 SMESH_CATCH( SMESH::throwCorbaException );
3816 //=======================================================================
3819 //=======================================================================
3821 SMESH::ListOfGroups*
3822 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
3823 const SMESH::PointStruct& thePoint,
3824 const SMESH::double_array& theScaleFact,
3825 CORBA::Boolean theCopy,
3827 ::SMESH_Mesh* theTargetMesh)
3828 throw (SALOME::SALOME_Exception)
3832 if ( theScaleFact.length() < 1 )
3833 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
3834 if ( theScaleFact.length() == 2 )
3835 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
3837 if ( theTargetMesh )
3840 TIDSortedElemSet elements;
3841 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3842 if ( !idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3847 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
3848 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
3852 #if OCC_VERSION_LARGE > 0x06070100
3853 // fight against orthogonalization
3854 // aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
3855 // 0, S[1], 0, thePoint.y * (1-S[1]),
3856 // 0, 0, S[2], thePoint.z * (1-S[2]) );
3857 aTrsf.SetScale( gp::Origin(), 1.0 ); // set form which is used to make group names
3858 gp_XYZ & loc = ( gp_XYZ& ) aTrsf.TranslationPart();
3859 gp_Mat & M = ( gp_Mat& ) aTrsf.HVectorialPart();
3860 loc.SetCoord( thePoint.x * (1-S[0]),
3861 thePoint.y * (1-S[1]),
3862 thePoint.z * (1-S[2]));
3863 M.SetDiagonal( S[0], S[1], S[2] );
3866 double tol = std::numeric_limits<double>::max();
3867 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
3868 0, S[1], 0, thePoint.y * (1-S[1]),
3869 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
3872 TIDSortedElemSet copyElements;
3873 TIDSortedElemSet* workElements = &elements;
3874 if ( myIsPreviewMode )
3876 TPreviewMesh * tmpMesh = getPreviewMesh();
3877 tmpMesh->Copy( elements, copyElements);
3878 if ( !theCopy && !theTargetMesh )
3880 TIDSortedElemSet elemsAround, elemsAroundCopy;
3881 getElementsAround( elements, getMeshDS(), elemsAround );
3882 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3884 workElements = & copyElements;
3885 theMakeGroups = false;
3888 ::SMESH_MeshEditor::PGroupIDs groupIds =
3889 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3891 if ( theCopy && !myIsPreviewMode )
3893 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
3894 else declareMeshModified( /*isReComputeSafe=*/false );
3896 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3898 SMESH_CATCH( SMESH::throwCorbaException );
3902 //=======================================================================
3905 //=======================================================================
3907 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
3908 const SMESH::PointStruct& thePoint,
3909 const SMESH::double_array& theScaleFact,
3910 CORBA::Boolean theCopy)
3911 throw (SALOME::SALOME_Exception)
3913 if ( !myIsPreviewMode ) {
3914 TPythonDump() << this << ".Scale( "
3915 << theObject << ", "
3917 << TVar( theScaleFact ) << ", "
3920 scale(theObject, thePoint, theScaleFact, theCopy, false);
3924 //=======================================================================
3925 //function : ScaleMakeGroups
3927 //=======================================================================
3929 SMESH::ListOfGroups*
3930 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3931 const SMESH::PointStruct& thePoint,
3932 const SMESH::double_array& theScaleFact)
3933 throw (SALOME::SALOME_Exception)
3935 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3937 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
3938 if (!myIsPreviewMode) {
3939 dumpGroupsList(aPythonDump, aGroups);
3940 aPythonDump << this << ".Scale("
3943 << TVar( theScaleFact ) << ",True,True)";
3949 //=======================================================================
3950 //function : ScaleMakeMesh
3952 //=======================================================================
3954 SMESH::SMESH_Mesh_ptr
3955 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3956 const SMESH::PointStruct& thePoint,
3957 const SMESH::double_array& theScaleFact,
3958 CORBA::Boolean theCopyGroups,
3959 const char* theMeshName)
3960 throw (SALOME::SALOME_Exception)
3962 SMESH_Mesh_i* mesh_i;
3963 SMESH::SMESH_Mesh_var mesh;
3964 { // open new scope to dump "MakeMesh" command
3965 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3967 TPythonDump pydump; // to prevent dump at mesh creation
3968 mesh = makeMesh( theMeshName );
3969 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3973 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
3974 mesh_i->CreateGroupServants();
3976 if ( !myIsPreviewMode )
3977 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
3978 << theObject << ", "
3980 << TVar( theScaleFact ) << ", "
3981 << theCopyGroups << ", '"
3982 << theMeshName << "' )";
3986 if (!myIsPreviewMode && mesh_i)
3987 mesh_i->GetGroups();
3989 return mesh._retn();
3993 //=======================================================================
3994 //function : findCoincidentNodes
3996 //=======================================================================
3998 void SMESH_MeshEditor_i::
3999 findCoincidentNodes (TIDSortedNodeSet & Nodes,
4000 CORBA::Double Tolerance,
4001 SMESH::array_of_long_array_out GroupsOfNodes,
4002 CORBA::Boolean SeparateCornersAndMedium)
4004 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4005 getEditor().FindCoincidentNodes( Nodes, Tolerance, aListOfListOfNodes, SeparateCornersAndMedium );
4007 GroupsOfNodes = new SMESH::array_of_long_array;
4008 GroupsOfNodes->length( aListOfListOfNodes.size() );
4009 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4010 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4012 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4013 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4014 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4015 aGroup.length( aListOfNodes.size() );
4016 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4017 aGroup[ j ] = (*lIt)->GetID();
4021 //=======================================================================
4022 //function : FindCoincidentNodes
4024 //=======================================================================
4026 void SMESH_MeshEditor_i::
4027 FindCoincidentNodes (CORBA::Double Tolerance,
4028 SMESH::array_of_long_array_out GroupsOfNodes,
4029 CORBA::Boolean SeparateCornersAndMedium)
4030 throw (SALOME::SALOME_Exception)
4035 TIDSortedNodeSet nodes; // no input nodes
4036 findCoincidentNodes( nodes, Tolerance, GroupsOfNodes, SeparateCornersAndMedium );
4038 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
4039 << Tolerance << ", "
4040 << SeparateCornersAndMedium << " )";
4042 SMESH_CATCH( SMESH::throwCorbaException );
4045 //=======================================================================
4046 //function : FindCoincidentNodesOnPart
4048 //=======================================================================
4050 void SMESH_MeshEditor_i::
4051 FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
4052 CORBA::Double Tolerance,
4053 SMESH::array_of_long_array_out GroupsOfNodes,
4054 CORBA::Boolean SeparateCornersAndMedium)
4055 throw (SALOME::SALOME_Exception)
4060 TIDSortedNodeSet nodes;
4061 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4063 findCoincidentNodes( nodes, Tolerance, GroupsOfNodes, SeparateCornersAndMedium );
4065 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
4067 << Tolerance << ", "
4068 << SeparateCornersAndMedium << " )";
4070 SMESH_CATCH( SMESH::throwCorbaException );
4073 //================================================================================
4075 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
4076 * ExceptSubMeshOrGroups
4078 //================================================================================
4080 void SMESH_MeshEditor_i::
4081 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
4082 CORBA::Double theTolerance,
4083 SMESH::array_of_long_array_out theGroupsOfNodes,
4084 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups,
4085 CORBA::Boolean theSeparateCornersAndMedium)
4086 throw (SALOME::SALOME_Exception)
4091 TIDSortedNodeSet nodes;
4092 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4094 for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
4096 SMDS_ElemIteratorPtr nodeIt = myMesh_i->GetElements( theExceptSubMeshOrGroups[i],
4098 while ( nodeIt->more() )
4099 nodes.erase( cast2Node( nodeIt->next() ));
4101 findCoincidentNodes( nodes, theTolerance, theGroupsOfNodes, theSeparateCornersAndMedium );
4103 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
4105 << theTolerance << ", "
4106 << theExceptSubMeshOrGroups << ", "
4107 << theSeparateCornersAndMedium << " )";
4109 SMESH_CATCH( SMESH::throwCorbaException );
4112 //=======================================================================
4113 //function : MergeNodes
4115 //=======================================================================
4117 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes,
4118 const SMESH::ListOfIDSources& NodesToKeep)
4119 throw (SALOME::SALOME_Exception)
4124 SMESHDS_Mesh* aMesh = getMeshDS();
4126 TPythonDump aTPythonDump;
4127 aTPythonDump << this << ".MergeNodes([";
4129 TIDSortedNodeSet setOfNodesToKeep;
4130 for ( int i = 0; i < NodesToKeep.length(); ++i )
4132 prepareIdSource( NodesToKeep[i] );
4133 SMDS_ElemIteratorPtr nodeIt = myMesh_i->GetElements( NodesToKeep[i], SMESH::NODE );
4134 while ( nodeIt->more() )
4135 setOfNodesToKeep.insert( setOfNodesToKeep.end(), cast2Node( nodeIt->next() ));
4138 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4139 for (int i = 0; i < GroupsOfNodes.length(); i++)
4141 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
4142 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
4143 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
4144 for ( int j = 0; j < aNodeGroup.length(); j++ )
4146 CORBA::Long index = aNodeGroup[ j ];
4147 if ( const SMDS_MeshNode * node = aMesh->FindNode( index ))
4149 if ( setOfNodesToKeep.count( node ))
4150 aListOfNodes.push_front( node );
4152 aListOfNodes.push_back( node );
4155 if ( aListOfNodes.size() < 2 )
4156 aListOfListOfNodes.pop_back();
4158 if ( i > 0 ) aTPythonDump << ", ";
4159 aTPythonDump << aNodeGroup;
4162 getEditor().MergeNodes( aListOfListOfNodes );
4164 aTPythonDump << "], " << NodesToKeep << ")";
4166 declareMeshModified( /*isReComputeSafe=*/false );
4168 SMESH_CATCH( SMESH::throwCorbaException );
4171 //=======================================================================
4172 //function : FindEqualElements
4174 //=======================================================================
4176 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
4177 SMESH::array_of_long_array_out GroupsOfElementsID)
4178 throw (SALOME::SALOME_Exception)
4183 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
4184 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
4186 TIDSortedElemSet elems;
4187 idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true);
4189 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4190 getEditor().FindEqualElements( elems, aListOfListOfElementsID );
4192 GroupsOfElementsID = new SMESH::array_of_long_array;
4193 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
4195 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt =
4196 aListOfListOfElementsID.begin();
4197 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j)
4199 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
4200 list<int>& listOfIDs = *arraysIt;
4201 aGroup.length( listOfIDs.size() );
4202 list<int>::iterator idIt = listOfIDs.begin();
4203 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k )
4204 aGroup[ k ] = *idIt;
4207 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
4211 SMESH_CATCH( SMESH::throwCorbaException );
4214 //=======================================================================
4215 //function : MergeElements
4217 //=======================================================================
4219 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
4220 throw (SALOME::SALOME_Exception)
4225 TPythonDump aTPythonDump;
4226 aTPythonDump << this << ".MergeElements( [";
4228 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4230 for (int i = 0; i < GroupsOfElementsID.length(); i++) {
4231 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
4232 aListOfListOfElementsID.push_back( list< int >() );
4233 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
4234 for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
4235 CORBA::Long id = anElemsIDGroup[ j ];
4236 aListOfElemsID.push_back( id );
4238 if ( aListOfElemsID.size() < 2 )
4239 aListOfListOfElementsID.pop_back();
4240 if ( i > 0 ) aTPythonDump << ", ";
4241 aTPythonDump << anElemsIDGroup;
4244 getEditor().MergeElements(aListOfListOfElementsID);
4246 declareMeshModified( /*isReComputeSafe=*/true );
4248 aTPythonDump << "] )";
4250 SMESH_CATCH( SMESH::throwCorbaException );
4253 //=======================================================================
4254 //function : MergeEqualElements
4256 //=======================================================================
4258 void SMESH_MeshEditor_i::MergeEqualElements()
4259 throw (SALOME::SALOME_Exception)
4264 getEditor().MergeEqualElements();
4266 declareMeshModified( /*isReComputeSafe=*/true );
4268 TPythonDump() << this << ".MergeEqualElements()";
4270 SMESH_CATCH( SMESH::throwCorbaException );
4273 //=============================================================================
4275 * Move the node to a given point
4277 //=============================================================================
4279 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
4283 throw (SALOME::SALOME_Exception)
4286 initData(/*deleteSearchers=*/false);
4288 const SMDS_MeshNode * node = getMeshDS()->FindNode( NodeID );
4292 if ( theNodeSearcher )
4293 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4295 if ( myIsPreviewMode ) // make preview data
4297 // in a preview mesh, make edges linked to a node
4298 TPreviewMesh& tmpMesh = *getPreviewMesh();
4299 TIDSortedElemSet linkedNodes;
4300 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4301 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4302 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
4303 for ( ; nIt != linkedNodes.end(); ++nIt )
4305 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
4306 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
4310 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
4311 // fill preview data
4313 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4314 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4316 getMeshDS()->MoveNode(node, x, y, z);
4318 if ( !myIsPreviewMode )
4320 // Update Python script
4321 TPythonDump() << "isDone = " << this << ".MoveNode( "
4322 << NodeID << ", " << TVar(x) << ", " << TVar(y) << ", " << TVar(z) << " )";
4323 declareMeshModified( /*isReComputeSafe=*/false );
4326 SMESH_CATCH( SMESH::throwCorbaException );
4331 //================================================================================
4333 * \brief Return ID of node closest to a given point
4335 //================================================================================
4337 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
4340 throw (SALOME::SALOME_Exception)
4343 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4345 if ( !theNodeSearcher ) {
4346 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
4349 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
4350 return node->GetID();
4352 SMESH_CATCH( SMESH::throwCorbaException );
4356 //================================================================================
4358 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
4359 * move the node closest to the point to point's location and return ID of the node
4361 //================================================================================
4363 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
4366 CORBA::Long theNodeID)
4367 throw (SALOME::SALOME_Exception)
4370 // We keep theNodeSearcher until any mesh modification:
4371 // 1) initData() deletes theNodeSearcher at any edition,
4372 // 2) TSearchersDeleter - at any mesh compute event and mesh change
4374 initData(/*deleteSearchers=*/false);
4376 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4378 int nodeID = theNodeID;
4379 const SMDS_MeshNode* node = getMeshDS()->FindNode( nodeID );
4380 if ( !node ) // preview moving node
4382 if ( !theNodeSearcher ) {
4383 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
4386 node = theNodeSearcher->FindClosestTo( p );
4389 nodeID = node->GetID();
4390 if ( myIsPreviewMode ) // make preview data
4392 // in a preview mesh, make edges linked to a node
4393 TPreviewMesh tmpMesh = *getPreviewMesh();
4394 TIDSortedElemSet linkedNodes;
4395 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4396 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4397 for ( ; nIt != linkedNodes.end(); ++nIt )
4399 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
4400 tmpMesh.Copy( &edge );
4403 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
4405 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
4406 // fill preview data
4408 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4410 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4414 getMeshDS()->MoveNode(node, x, y, z);
4418 if ( !myIsPreviewMode )
4420 TPythonDump() << "nodeID = " << this
4421 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
4422 << ", " << nodeID << " )";
4424 declareMeshModified( /*isReComputeSafe=*/false );
4429 SMESH_CATCH( SMESH::throwCorbaException );
4433 //=======================================================================
4435 * Return elements of given type where the given point is IN or ON.
4437 * 'ALL' type means elements of any type excluding nodes
4439 //=======================================================================
4441 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
4444 SMESH::ElementType type)
4445 throw (SALOME::SALOME_Exception)
4448 SMESH::long_array_var res = new SMESH::long_array;
4449 vector< const SMDS_MeshElement* > foundElems;
4451 theSearchersDeleter.Set( myMesh );
4452 if ( !theElementSearcher ) {
4453 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
4455 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4456 SMDSAbs_ElementType( type ),
4458 res->length( foundElems.size() );
4459 for ( int i = 0; i < foundElems.size(); ++i )
4460 res[i] = foundElems[i]->GetID();
4464 SMESH_CATCH( SMESH::throwCorbaException );
4468 //=======================================================================
4469 //function : FindAmongElementsByPoint
4470 //purpose : Searching among the given elements, return elements of given type
4471 // where the given point is IN or ON.
4472 // 'ALL' type means elements of any type excluding nodes
4473 //=======================================================================
4476 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
4480 SMESH::ElementType type)
4481 throw (SALOME::SALOME_Exception)
4484 SMESH::long_array_var res = new SMESH::long_array;
4486 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
4487 if ( types->length() == 1 && // a part contains only nodes or 0D elements
4488 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) &&
4489 type != types[0] ) // but search of elements of dim > 0
4492 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
4493 return FindElementsByPoint( x,y,z, type );
4495 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
4497 theSearchersDeleter.Set( myMesh, getPartIOR( elementIDs, type ));
4498 if ( !theElementSearcher )
4500 // create a searcher from elementIDs
4501 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
4502 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
4504 if ( !idSourceToSet( elementIDs, meshDS, elements,
4505 SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
4508 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
4509 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
4511 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt );
4514 vector< const SMDS_MeshElement* > foundElems;
4516 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4517 SMDSAbs_ElementType( type ),
4519 res->length( foundElems.size() );
4520 for ( int i = 0; i < foundElems.size(); ++i )
4521 res[i] = foundElems[i]->GetID();
4525 SMESH_CATCH( SMESH::throwCorbaException );
4529 //=======================================================================
4530 //function : GetPointState
4531 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
4532 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
4533 //=======================================================================
4535 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
4538 throw (SALOME::SALOME_Exception)
4541 theSearchersDeleter.Set( myMesh );
4542 if ( !theElementSearcher ) {
4543 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
4545 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
4547 SMESH_CATCH( SMESH::throwCorbaException );
4551 //=======================================================================
4552 //function : convError
4554 //=======================================================================
4556 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
4558 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
4562 RETCASE( SEW_BORDER1_NOT_FOUND );
4563 RETCASE( SEW_BORDER2_NOT_FOUND );
4564 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
4565 RETCASE( SEW_BAD_SIDE_NODES );
4566 RETCASE( SEW_VOLUMES_TO_SPLIT );
4567 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
4568 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
4569 RETCASE( SEW_BAD_SIDE1_NODES );
4570 RETCASE( SEW_BAD_SIDE2_NODES );
4572 return SMESH::SMESH_MeshEditor::SEW_OK;
4575 //=======================================================================
4577 * Returns groups of FreeBorder's coincident within the given tolerance.
4578 * If the tolerance <= 0.0 then one tenth of an average size of elements adjacent
4579 * to free borders being compared is used.
4581 //=======================================================================
4583 SMESH::CoincidentFreeBorders*
4584 SMESH_MeshEditor_i::FindCoincidentFreeBorders(CORBA::Double tolerance)
4586 SMESH::CoincidentFreeBorders_var aCFB = new SMESH::CoincidentFreeBorders;
4590 SMESH_MeshAlgos::CoincidentFreeBorders cfb;
4591 SMESH_MeshAlgos::FindCoincidentFreeBorders( *getMeshDS(), tolerance, cfb );
4593 // copy free borders
4594 aCFB->borders.length( cfb._borders.size() );
4595 for ( size_t i = 0; i < cfb._borders.size(); ++i )
4597 SMESH_MeshAlgos::TFreeBorder& nodes = cfb._borders[i];
4598 SMESH::FreeBorder& aBRD = aCFB->borders[i];
4599 aBRD.nodeIDs.length( nodes.size() );
4600 for ( size_t iN = 0; iN < nodes.size(); ++iN )
4601 aBRD.nodeIDs[ iN ] = nodes[ iN ]->GetID();
4604 // copy coincident parts
4605 aCFB->coincidentGroups.length( cfb._coincidentGroups.size() );
4606 for ( size_t i = 0; i < cfb._coincidentGroups.size(); ++i )
4608 SMESH_MeshAlgos::TCoincidentGroup& grp = cfb._coincidentGroups[i];
4609 SMESH::FreeBordersGroup& aGRP = aCFB->coincidentGroups[i];
4610 aGRP.length( grp.size() );
4611 for ( size_t iP = 0; iP < grp.size(); ++iP )
4613 SMESH_MeshAlgos::TFreeBorderPart& part = grp[ iP ];
4614 SMESH::FreeBorderPart& aPART = aGRP[ iP ];
4615 aPART.border = part._border;
4616 aPART.node1 = part._node1;
4617 aPART.node2 = part._node2;
4618 aPART.nodeLast = part._nodeLast;
4621 SMESH_CATCH( SMESH::doNothing );
4623 TPythonDump() << "CoincidentFreeBorders = "
4624 << this << ".FindCoincidentFreeBorders( " << tolerance << " )";
4626 return aCFB._retn();
4629 //=======================================================================
4631 * Sew FreeBorder's of each group
4633 //=======================================================================
4635 CORBA::Short SMESH_MeshEditor_i::
4636 SewCoincidentFreeBorders(const SMESH::CoincidentFreeBorders& freeBorders,
4637 CORBA::Boolean createPolygons,
4638 CORBA::Boolean createPolyhedra)
4639 throw (SALOME::SALOME_Exception)
4641 CORBA::Short nbSewed = 0;
4643 SMESH_MeshAlgos::TFreeBorderVec groups;
4644 SMESH_MeshAlgos::TFreeBorder borderNodes; // triples on nodes for every FreeBorderPart
4647 for ( CORBA::ULong i = 0; i < freeBorders.coincidentGroups.length(); ++i )
4649 const SMESH::FreeBordersGroup& aGRP = freeBorders.coincidentGroups[ i ];
4650 for ( CORBA::ULong iP = 0; iP < aGRP.length(); ++iP )
4652 const SMESH::FreeBorderPart& aPART = aGRP[ iP ];
4653 if ( aPART.border < 0 || aPART.border >= freeBorders.borders.length() )
4654 THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::border index", SALOME::BAD_PARAM);
4656 const SMESH::FreeBorder& aBRD = freeBorders.borders[ aPART.border ];
4658 if ( aPART.node1 < 0 || aPART.node1 > aBRD.nodeIDs.length() )
4659 THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::node1", SALOME::BAD_PARAM);
4660 if ( aPART.node2 < 0 || aPART.node2 > aBRD.nodeIDs.length() )
4661 THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::node2", SALOME::BAD_PARAM);
4662 if ( aPART.nodeLast < 0 || aPART.nodeLast > aBRD.nodeIDs.length() )
4663 THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::nodeLast", SALOME::BAD_PARAM);
4665 // do not keep these nodes for further sewing as nodes can be removed by the sewing
4666 const SMDS_MeshNode* n1 = getMeshDS()->FindNode( aBRD.nodeIDs[ aPART.node1 ]);
4667 const SMDS_MeshNode* n2 = getMeshDS()->FindNode( aBRD.nodeIDs[ aPART.node2 ]);
4668 const SMDS_MeshNode* n3 = getMeshDS()->FindNode( aBRD.nodeIDs[ aPART.nodeLast ]);
4670 THROW_SALOME_CORBA_EXCEPTION("Nonexistent FreeBorderPart::node1", SALOME::BAD_PARAM);
4672 THROW_SALOME_CORBA_EXCEPTION("Nonexistent FreeBorderPart::node2", SALOME::BAD_PARAM);
4674 THROW_SALOME_CORBA_EXCEPTION("Nonexistent FreeBorderPart::nodeLast", SALOME::BAD_PARAM);
4678 //TIDSortedElemSet dummy;
4680 ::SMESH_MeshEditor::Sew_Error res, ok = ::SMESH_MeshEditor::SEW_OK;
4681 for ( CORBA::ULong i = 0; i < freeBorders.coincidentGroups.length(); ++i )
4683 const SMESH::FreeBordersGroup& aGRP = freeBorders.coincidentGroups[ i ];
4684 if ( aGRP.length() < 2 )
4687 //int n1bord2, n2bord2;
4689 bool groupSewed = false;
4690 for ( CORBA::ULong iP = 1; iP < aGRP.length(); ++iP )
4692 const SMESH::FreeBorderPart& aPART_0 = aGRP[ 0 ];
4693 const SMESH::FreeBorder& aBRD_0 = freeBorders.borders[ aPART_0.border ];
4695 const SMDS_MeshNode* n0 = getMeshDS()->FindNode( aBRD_0.nodeIDs[ aPART_0.node1 ]);
4696 const SMDS_MeshNode* n1 = getMeshDS()->FindNode( aBRD_0.nodeIDs[ aPART_0.node2 ]);
4697 const SMDS_MeshNode* n2 = getMeshDS()->FindNode( aBRD_0.nodeIDs[ aPART_0.nodeLast ]);
4699 const SMESH::FreeBorderPart& aPART = aGRP[ iP ];
4700 const SMESH::FreeBorder& aBRD = freeBorders.borders[ aPART.border ];
4702 const SMDS_MeshNode* n3 = getMeshDS()->FindNode( aBRD.nodeIDs[ aPART.node1 ]);
4703 const SMDS_MeshNode* n4 = getMeshDS()->FindNode( aBRD.nodeIDs[ aPART.node2 ]);
4704 const SMDS_MeshNode* n5 = getMeshDS()->FindNode( aBRD.nodeIDs[ aPART.nodeLast ]);
4706 if ( !n0 || !n1 || !n2 || !n3 || !n4 || !n5 )
4711 // n1bord2 = aBRD.nodeIDs[ aPART.node1 ];
4712 // n2bord2 = aBRD.nodeIDs[ aPART.node2 ];
4714 // else if ( !SMESH_MeshAlgos::FindFaceInSet( n0, n1, dummy, dummy ))
4716 // // a face including n0 and n1 was split;
4717 // // find a new face starting at n0 in order to get a new n1
4718 // const SMDS_MeshNode* n1test = getMeshDS()->FindNode( n1bord2 );
4719 // const SMDS_MeshNode* n2test = getMeshDS()->FindNode( n2bord2 );
4720 // if ( n1test && SMESH_MeshAlgos::FindFaceInSet( n0, n1test, dummy, dummy ))
4722 // else if ( n2test && SMESH_MeshAlgos::FindFaceInSet( n0, n2test, dummy, dummy ))
4724 // // else continue; ??????
4729 n1 = n2; // at border-to-side sewing only last side node (n1) is needed
4730 n2 = 0; // and n2 is not used
4733 // 1st border moves to 2nd
4734 res = getEditor().SewFreeBorder( n3, n4, n5 ,// 1st
4736 /*2ndIsFreeBorder=*/ iP == 1,
4737 createPolygons, createPolyhedra);
4738 groupSewed = ( res == ok );
4740 nbSewed += groupSewed;
4743 TPythonDump() << "nbSewed = " << this << ".SewCoincidentFreeBorders( "
4744 << freeBorders << ", "
4745 << createPolygons << ", "
4746 << createPolyhedra << " )";
4751 //=======================================================================
4752 //function : SewFreeBorders
4754 //=======================================================================
4756 SMESH::SMESH_MeshEditor::Sew_Error
4757 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
4758 CORBA::Long SecondNodeID1,
4759 CORBA::Long LastNodeID1,
4760 CORBA::Long FirstNodeID2,
4761 CORBA::Long SecondNodeID2,
4762 CORBA::Long LastNodeID2,
4763 CORBA::Boolean CreatePolygons,
4764 CORBA::Boolean CreatePolyedrs)
4765 throw (SALOME::SALOME_Exception)
4770 SMESHDS_Mesh* aMesh = getMeshDS();
4772 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4773 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4774 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4775 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4776 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4777 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
4779 if (!aBorderFirstNode ||
4780 !aBorderSecondNode||
4782 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4783 if (!aSide2FirstNode ||
4784 !aSide2SecondNode ||
4786 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4788 TPythonDump() << "error = " << this << ".SewFreeBorders( "
4789 << FirstNodeID1 << ", "
4790 << SecondNodeID1 << ", "
4791 << LastNodeID1 << ", "
4792 << FirstNodeID2 << ", "
4793 << SecondNodeID2 << ", "
4794 << LastNodeID2 << ", "
4795 << CreatePolygons<< ", "
4796 << CreatePolyedrs<< " )";
4798 SMESH::SMESH_MeshEditor::Sew_Error error =
4799 convError( getEditor().SewFreeBorder (aBorderFirstNode,
4810 declareMeshModified( /*isReComputeSafe=*/false );
4813 SMESH_CATCH( SMESH::throwCorbaException );
4814 return SMESH::SMESH_MeshEditor::Sew_Error(0);
4818 //=======================================================================
4819 //function : SewConformFreeBorders
4821 //=======================================================================
4823 SMESH::SMESH_MeshEditor::Sew_Error
4824 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
4825 CORBA::Long SecondNodeID1,
4826 CORBA::Long LastNodeID1,
4827 CORBA::Long FirstNodeID2,
4828 CORBA::Long SecondNodeID2)
4829 throw (SALOME::SALOME_Exception)
4834 SMESHDS_Mesh* aMesh = getMeshDS();
4836 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4837 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4838 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4839 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4840 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4841 const SMDS_MeshNode* aSide2ThirdNode = 0;
4843 if (!aBorderFirstNode ||
4844 !aBorderSecondNode||
4846 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4847 if (!aSide2FirstNode ||
4849 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4851 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
4852 << FirstNodeID1 << ", "
4853 << SecondNodeID1 << ", "
4854 << LastNodeID1 << ", "
4855 << FirstNodeID2 << ", "
4856 << SecondNodeID2 << " )";
4858 SMESH::SMESH_MeshEditor::Sew_Error error =
4859 convError( getEditor().SewFreeBorder (aBorderFirstNode,
4868 declareMeshModified( /*isReComputeSafe=*/false );
4871 SMESH_CATCH( SMESH::throwCorbaException );
4872 return SMESH::SMESH_MeshEditor::Sew_Error(0);
4876 //=======================================================================
4877 //function : SewBorderToSide
4879 //=======================================================================
4881 SMESH::SMESH_MeshEditor::Sew_Error
4882 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
4883 CORBA::Long SecondNodeIDOnFreeBorder,
4884 CORBA::Long LastNodeIDOnFreeBorder,
4885 CORBA::Long FirstNodeIDOnSide,
4886 CORBA::Long LastNodeIDOnSide,
4887 CORBA::Boolean CreatePolygons,
4888 CORBA::Boolean CreatePolyedrs)
4889 throw (SALOME::SALOME_Exception)
4894 SMESHDS_Mesh* aMesh = getMeshDS();
4896 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
4897 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
4898 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
4899 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
4900 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
4901 const SMDS_MeshNode* aSide2ThirdNode = 0;
4903 if (!aBorderFirstNode ||
4904 !aBorderSecondNode||
4906 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4907 if (!aSide2FirstNode ||
4909 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
4911 TPythonDump() << "error = " << this << ".SewBorderToSide( "
4912 << FirstNodeIDOnFreeBorder << ", "
4913 << SecondNodeIDOnFreeBorder << ", "
4914 << LastNodeIDOnFreeBorder << ", "
4915 << FirstNodeIDOnSide << ", "
4916 << LastNodeIDOnSide << ", "
4917 << CreatePolygons << ", "
4918 << CreatePolyedrs << ") ";
4920 SMESH::SMESH_MeshEditor::Sew_Error error =
4921 convError( getEditor().SewFreeBorder (aBorderFirstNode,
4931 declareMeshModified( /*isReComputeSafe=*/false );
4934 SMESH_CATCH( SMESH::throwCorbaException );
4935 return SMESH::SMESH_MeshEditor::Sew_Error(0);
4939 //=======================================================================
4940 //function : SewSideElements
4942 //=======================================================================
4944 SMESH::SMESH_MeshEditor::Sew_Error
4945 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
4946 const SMESH::long_array& IDsOfSide2Elements,
4947 CORBA::Long NodeID1OfSide1ToMerge,
4948 CORBA::Long NodeID1OfSide2ToMerge,
4949 CORBA::Long NodeID2OfSide1ToMerge,
4950 CORBA::Long NodeID2OfSide2ToMerge)
4951 throw (SALOME::SALOME_Exception)
4956 SMESHDS_Mesh* aMesh = getMeshDS();
4958 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
4959 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
4960 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
4961 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
4963 if (!aFirstNode1ToMerge ||
4964 !aFirstNode2ToMerge )
4965 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
4966 if (!aSecondNode1ToMerge||
4967 !aSecondNode2ToMerge)
4968 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
4970 TIDSortedElemSet aSide1Elems, aSide2Elems;
4971 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
4972 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
4974 TPythonDump() << "error = " << this << ".SewSideElements( "
4975 << IDsOfSide1Elements << ", "
4976 << IDsOfSide2Elements << ", "
4977 << NodeID1OfSide1ToMerge << ", "
4978 << NodeID1OfSide2ToMerge << ", "
4979 << NodeID2OfSide1ToMerge << ", "
4980 << NodeID2OfSide2ToMerge << ")";
4982 SMESH::SMESH_MeshEditor::Sew_Error error =
4983 convError( getEditor().SewSideElements (aSide1Elems, aSide2Elems,
4986 aSecondNode1ToMerge,
4987 aSecondNode2ToMerge));
4989 declareMeshModified( /*isReComputeSafe=*/false );
4992 SMESH_CATCH( SMESH::throwCorbaException );
4993 return SMESH::SMESH_MeshEditor::Sew_Error(0);
4996 //================================================================================
4998 * \brief Set new nodes for given element
4999 * \param ide - element id
5000 * \param newIDs - new node ids
5001 * \retval CORBA::Boolean - true if result is OK
5003 //================================================================================
5005 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
5006 const SMESH::long_array& newIDs)
5007 throw (SALOME::SALOME_Exception)
5012 const SMDS_MeshElement* elem = getMeshDS()->FindElement(ide);
5013 if(!elem) return false;
5015 int nbn = newIDs.length();
5017 vector<const SMDS_MeshNode*> aNodes(nbn);
5020 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(newIDs[i]);
5023 aNodes[nbn1] = aNode;
5026 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
5027 << ide << ", " << newIDs << " )";
5029 MESSAGE("ChangeElementNodes");
5030 bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
5032 declareMeshModified( /*isReComputeSafe=*/ !res );
5036 SMESH_CATCH( SMESH::throwCorbaException );
5040 //=======================================================================
5042 * \brief Makes a part of the mesh quadratic or bi-quadratic
5044 //=======================================================================
5046 void SMESH_MeshEditor_i::convertToQuadratic(CORBA::Boolean theForce3d,
5047 CORBA::Boolean theToBiQuad,
5048 SMESH::SMESH_IDSource_ptr theObject)
5049 throw (SALOME::SALOME_Exception)
5054 TIDSortedElemSet elems;
5056 if ( !( elemsOK = CORBA::is_nil( theObject )))
5058 elemsOK = idSourceToSet( theObject, getMeshDS(), elems,
5059 SMDSAbs_All, /*emptyIfIsMesh=*/true );
5063 if ( !elems.empty() && (*elems.begin())->GetType() == SMDSAbs_Node )
5064 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5066 if ( elems.empty() ) getEditor().ConvertToQuadratic(theForce3d, theToBiQuad);
5067 else getEditor().ConvertToQuadratic(theForce3d, elems, theToBiQuad);
5069 declareMeshModified( /*isReComputeSafe=*/false );
5072 SMESH_CATCH( SMESH::throwCorbaException );
5075 //=======================================================================
5076 //function : ConvertFromQuadratic
5078 //=======================================================================
5080 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
5081 throw (SALOME::SALOME_Exception)
5086 CORBA::Boolean isDone = getEditor().ConvertFromQuadratic();
5087 TPythonDump() << this << ".ConvertFromQuadratic()";
5088 declareMeshModified( /*isReComputeSafe=*/!isDone );
5091 SMESH_CATCH( SMESH::throwCorbaException );
5095 //=======================================================================
5096 //function : ConvertToQuadratic
5098 //=======================================================================
5100 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
5101 throw (SALOME::SALOME_Exception)
5103 convertToQuadratic( theForce3d, false );
5104 TPythonDump() << this << ".ConvertToQuadratic("<<theForce3d<<")";
5107 //================================================================================
5109 * \brief Makes a part of the mesh quadratic
5111 //================================================================================
5113 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
5114 SMESH::SMESH_IDSource_ptr theObject)
5115 throw (SALOME::SALOME_Exception)
5117 convertToQuadratic( theForce3d, false, theObject );
5118 TPythonDump() << this << ".ConvertToQuadraticObject("<<theForce3d<<", "<<theObject<<")";
5121 //================================================================================
5123 * \brief Makes a part of the mesh bi-quadratic
5125 //================================================================================
5127 void SMESH_MeshEditor_i::ConvertToBiQuadratic(CORBA::Boolean theForce3d,
5128 SMESH::SMESH_IDSource_ptr theObject)
5129 throw (SALOME::SALOME_Exception)
5131 convertToQuadratic( theForce3d, true, theObject );
5132 TPythonDump() << this << ".ConvertToBiQuadratic("<<theForce3d<<", "<<theObject<<")";
5135 //================================================================================
5137 * \brief Makes a part of the mesh linear
5139 //================================================================================
5141 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
5142 throw (SALOME::SALOME_Exception)
5149 TIDSortedElemSet elems;
5150 if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5152 if ( elems.empty() )
5154 ConvertFromQuadratic();
5156 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5158 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5162 getEditor().ConvertFromQuadratic(elems);
5165 declareMeshModified( /*isReComputeSafe=*/false );
5167 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
5169 SMESH_CATCH( SMESH::throwCorbaException );
5172 //=======================================================================
5173 //function : makeMesh
5174 //purpose : create a named imported mesh
5175 //=======================================================================
5177 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
5179 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
5180 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
5181 SALOMEDS::Study_var study = gen->GetCurrentStudy();
5182 SALOMEDS::SObject_wrap meshSO = gen->ObjectToSObject( study, mesh );
5183 gen->SetName( meshSO, theMeshName, "Mesh" );
5184 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
5186 return mesh._retn();
5189 //=======================================================================
5190 //function : dumpGroupsList
5192 //=======================================================================
5194 void SMESH_MeshEditor_i::dumpGroupsList(TPythonDump & theDumpPython,
5195 const SMESH::ListOfGroups * theGroupList)
5197 bool isDumpGroupList = ( theGroupList && theGroupList->length() > 0 );
5198 if ( isDumpGroupList )
5199 theDumpPython << theGroupList << " = ";
5202 //================================================================================
5204 \brief Generates the unique group name.
5205 \param thePrefix name prefix
5208 //================================================================================
5210 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
5212 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5213 set<string> groupNames;
5215 // Get existing group names
5216 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
5217 SMESH::SMESH_GroupBase_var aGroup = groups[i];
5218 if (CORBA::is_nil(aGroup))
5221 CORBA::String_var name = aGroup->GetName();
5222 groupNames.insert( name.in() );
5226 string name = thePrefix;
5229 while (!groupNames.insert(name).second)
5230 name = SMESH_Comment( thePrefix ) << "_" << index++;
5235 //================================================================================
5237 * \brief Prepare SMESH_IDSource for work
5239 //================================================================================
5241 void SMESH_MeshEditor_i::prepareIdSource(SMESH::SMESH_IDSource_ptr theObject)
5243 if ( SMESH::Filter_i* filter = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5245 SMESH::SMESH_Mesh_var mesh = myMesh_i->_this();
5246 filter->SetMesh( mesh );
5249 //================================================================================
5251 * \brief Retrieve elements of given type from SMESH_IDSource
5253 //================================================================================
5255 bool SMESH_MeshEditor_i::idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource,
5256 const SMESHDS_Mesh* theMeshDS,
5257 TIDSortedElemSet& theElemSet,
5258 const SMDSAbs_ElementType theType,
5259 const bool emptyIfIsMesh,
5260 IDSource_Error* error)
5263 if ( error ) *error = IDSource_OK;
5265 if ( CORBA::is_nil( theIDSource ) )
5267 if ( error ) *error = IDSource_INVALID;
5270 if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
5272 if ( error && getMeshDS()->GetMeshInfo().NbElements( theType ) == 0 )
5273 *error = IDSource_EMPTY;
5276 prepareIdSource( theIDSource );
5277 SMESH::long_array_var anIDs = theIDSource->GetIDs();
5278 if ( anIDs->length() == 0 )
5280 if ( error ) *error = IDSource_EMPTY;
5283 SMESH::array_of_ElementType_var types = theIDSource->GetTypes();
5284 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
5286 if ( theType == SMDSAbs_All || theType == SMDSAbs_Node )
5288 arrayToSet( anIDs, getMeshDS(), theElemSet, SMDSAbs_Node );
5292 if ( error ) *error = IDSource_INVALID;
5298 arrayToSet( anIDs, getMeshDS(), theElemSet, theType);
5299 if ( bool(anIDs->length()) != bool(theElemSet.size()))
5301 if ( error ) *error = IDSource_INVALID;
5308 //================================================================================
5310 * \brief Duplicates given elements, i.e. creates new elements based on the
5311 * same nodes as the given ones.
5312 * \param theElements - container of elements to duplicate.
5313 * \param theGroupName - a name of group to contain the generated elements.
5314 * If a group with such a name already exists, the new elements
5315 * are added to the existng group, else a new group is created.
5316 * If \a theGroupName is empty, new elements are not added
5318 * \return a group where the new elements are added. NULL if theGroupName == "".
5321 //================================================================================
5323 SMESH::SMESH_Group_ptr
5324 SMESH_MeshEditor_i::DoubleElements(SMESH::SMESH_IDSource_ptr theElements,
5325 const char* theGroupName)
5326 throw (SALOME::SALOME_Exception)
5328 SMESH::SMESH_Group_var newGroup;
5335 TIDSortedElemSet elems;
5336 if ( idSourceToSet( theElements, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true))
5338 getEditor().DoubleElements( elems );
5340 if ( strlen( theGroupName ) && !getEditor().GetLastCreatedElems().IsEmpty() )
5343 SMESH::ElementType type =
5344 SMESH::ElementType( getEditor().GetLastCreatedElems().Value(1)->GetType() );
5345 // find existing group
5346 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5347 for ( size_t i = 0; i < groups->length(); ++i )
5348 if ( groups[i]->GetType() == type )
5350 CORBA::String_var name = groups[i]->GetName();
5351 if ( strcmp( name, theGroupName ) == 0 ) {
5352 newGroup = SMESH::SMESH_Group::_narrow( groups[i] );
5356 // create a new group
5357 if ( newGroup->_is_nil() )
5358 newGroup = myMesh_i->CreateGroup( type, theGroupName );
5360 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* >( newGroup ))
5362 SMESHDS_Group* groupDS = static_cast< SMESHDS_Group* >( group_i->GetGroupDS() );
5363 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
5364 for ( int i = 1; i <= aSeq.Length(); i++ )
5365 groupDS->SMDSGroup().Add( aSeq(i) );
5370 if ( !newGroup->_is_nil() )
5371 pyDump << newGroup << " = ";
5372 pyDump << this << ".DoubleElements( "
5373 << theElements << ", " << "'" << theGroupName <<"')";
5375 SMESH_CATCH( SMESH::throwCorbaException );
5377 return newGroup._retn();
5380 //================================================================================
5382 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5383 \param theNodes - identifiers of nodes to be doubled
5384 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
5385 nodes. If list of element identifiers is empty then nodes are doubled but
5386 they not assigned to elements
5387 \return TRUE if operation has been completed successfully, FALSE otherwise
5388 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
5390 //================================================================================
5392 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
5393 const SMESH::long_array& theModifiedElems )
5394 throw (SALOME::SALOME_Exception)
5399 list< int > aListOfNodes;
5401 for ( i = 0, n = theNodes.length(); i < n; i++ )
5402 aListOfNodes.push_back( theNodes[ i ] );
5404 list< int > aListOfElems;
5405 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5406 aListOfElems.push_back( theModifiedElems[ i ] );
5408 bool aResult = getEditor().DoubleNodes( aListOfNodes, aListOfElems );
5410 declareMeshModified( /*isReComputeSafe=*/ !aResult );
5412 // Update Python script
5413 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
5417 SMESH_CATCH( SMESH::throwCorbaException );
5421 //================================================================================
5423 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5424 This method provided for convenience works as DoubleNodes() described above.
5425 \param theNodeId - identifier of node to be doubled.
5426 \param theModifiedElems - identifiers of elements to be updated.
5427 \return TRUE if operation has been completed successfully, FALSE otherwise
5428 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
5430 //================================================================================
5432 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
5433 const SMESH::long_array& theModifiedElems )
5434 throw (SALOME::SALOME_Exception)
5437 SMESH::long_array_var aNodes = new SMESH::long_array;
5438 aNodes->length( 1 );
5439 aNodes[ 0 ] = theNodeId;
5441 TPythonDump pyDump; // suppress dump by the next line
5443 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
5445 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
5449 SMESH_CATCH( SMESH::throwCorbaException );
5453 //================================================================================
5455 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5456 This method provided for convenience works as DoubleNodes() described above.
5457 \param theNodes - group of nodes to be doubled.
5458 \param theModifiedElems - group of elements to be updated.
5459 \return TRUE if operation has been completed successfully, FALSE otherwise
5460 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
5462 //================================================================================
5464 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
5465 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5466 throw (SALOME::SALOME_Exception)
5469 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5472 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5473 SMESH::long_array_var aModifiedElems;
5474 if ( !CORBA::is_nil( theModifiedElems ) )
5475 aModifiedElems = theModifiedElems->GetListOfID();
5478 aModifiedElems = new SMESH::long_array;
5479 aModifiedElems->length( 0 );
5482 TPythonDump pyDump; // suppress dump by the next line
5484 bool done = DoubleNodes( aNodes, aModifiedElems );
5486 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
5490 SMESH_CATCH( SMESH::throwCorbaException );
5494 //================================================================================
5496 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5497 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
5498 * \param theNodes - group of nodes to be doubled.
5499 * \param theModifiedElems - group of elements to be updated.
5500 * \return a new group with newly created nodes
5501 * \sa DoubleNodeGroup()
5503 //================================================================================
5505 SMESH::SMESH_Group_ptr
5506 SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
5507 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5508 throw (SALOME::SALOME_Exception)
5511 SMESH::SMESH_Group_var aNewGroup;
5513 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5514 return aNewGroup._retn();
5517 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5518 SMESH::long_array_var aModifiedElems;
5519 if ( !CORBA::is_nil( theModifiedElems ) )
5520 aModifiedElems = theModifiedElems->GetListOfID();
5522 aModifiedElems = new SMESH::long_array;
5523 aModifiedElems->length( 0 );
5526 TPythonDump pyDump; // suppress dump by the next line
5528 bool aResult = DoubleNodes( aNodes, aModifiedElems );
5531 // Create group with newly created nodes
5532 SMESH::long_array_var anIds = GetLastCreatedNodes();
5533 if (anIds->length() > 0) {
5534 string anUnindexedName (theNodes->GetName());
5535 string aNewName = generateGroupName(anUnindexedName + "_double");
5536 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5537 aNewGroup->Add(anIds);
5538 pyDump << aNewGroup << " = ";
5542 pyDump << this << ".DoubleNodeGroupNew( " << theNodes << ", "
5543 << theModifiedElems << " )";
5545 return aNewGroup._retn();
5547 SMESH_CATCH( SMESH::throwCorbaException );
5551 //================================================================================
5553 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5554 This method provided for convenience works as DoubleNodes() described above.
5555 \param theNodes - list of groups of nodes to be doubled
5556 \param theModifiedElems - list of groups of elements to be updated.
5557 \return TRUE if operation has been completed successfully, FALSE otherwise
5558 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
5560 //================================================================================
5562 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
5563 const SMESH::ListOfGroups& theModifiedElems )
5564 throw (SALOME::SALOME_Exception)
5569 std::list< int > aNodes;
5571 for ( i = 0, n = theNodes.length(); i < n; i++ )
5573 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
5574 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
5576 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5577 for ( j = 0, m = aCurr->length(); j < m; j++ )
5578 aNodes.push_back( aCurr[ j ] );
5582 std::list< int > anElems;
5583 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5585 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
5586 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
5588 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5589 for ( j = 0, m = aCurr->length(); j < m; j++ )
5590 anElems.push_back( aCurr[ j ] );
5594 bool aResult = getEditor().DoubleNodes( aNodes, anElems );
5596 declareMeshModified( /*isReComputeSafe=*/false );
5598 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
5602 SMESH_CATCH( SMESH::throwCorbaException );
5606 //================================================================================
5608 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5609 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
5610 * \param theNodes - group of nodes to be doubled.
5611 * \param theModifiedElems - group of elements to be updated.
5612 * \return a new group with newly created nodes
5613 * \sa DoubleNodeGroups()
5615 //================================================================================
5617 SMESH::SMESH_Group_ptr
5618 SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
5619 const SMESH::ListOfGroups& theModifiedElems )
5620 throw (SALOME::SALOME_Exception)
5622 SMESH::SMESH_Group_var aNewGroup;
5624 TPythonDump pyDump; // suppress dump by the next line
5626 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
5630 // Create group with newly created nodes
5631 SMESH::long_array_var anIds = GetLastCreatedNodes();
5632 if (anIds->length() > 0) {
5633 string anUnindexedName (theNodes[0]->GetName());
5634 string aNewName = generateGroupName(anUnindexedName + "_double");
5635 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5636 aNewGroup->Add(anIds);
5637 pyDump << aNewGroup << " = ";
5641 pyDump << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
5642 << theModifiedElems << " )";
5644 return aNewGroup._retn();
5648 //================================================================================
5650 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5651 \param theElems - the list of elements (edges or faces) to be replicated
5652 The nodes for duplication could be found from these elements
5653 \param theNodesNot - list of nodes to NOT replicate
5654 \param theAffectedElems - the list of elements (cells and edges) to which the
5655 replicated nodes should be associated to.
5656 \return TRUE if operation has been completed successfully, FALSE otherwise
5657 \sa DoubleNodeGroup(), DoubleNodeGroups()
5659 //================================================================================
5661 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
5662 const SMESH::long_array& theNodesNot,
5663 const SMESH::long_array& theAffectedElems )
5664 throw (SALOME::SALOME_Exception)
5669 SMESHDS_Mesh* aMeshDS = getMeshDS();
5670 TIDSortedElemSet anElems, aNodes, anAffected;
5671 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5672 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5673 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
5675 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5677 // Update Python script
5678 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
5679 << theNodesNot << ", " << theAffectedElems << " )";
5681 declareMeshModified( /*isReComputeSafe=*/false );
5684 SMESH_CATCH( SMESH::throwCorbaException );
5688 //================================================================================
5690 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5691 \param theElems - the list of elements (edges or faces) to be replicated
5692 The nodes for duplication could be found from these elements
5693 \param theNodesNot - list of nodes to NOT replicate
5694 \param theShape - shape to detect affected elements (element which geometric center
5695 located on or inside shape).
5696 The replicated nodes should be associated to affected elements.
5697 \return TRUE if operation has been completed successfully, FALSE otherwise
5698 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
5700 //================================================================================
5702 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
5703 const SMESH::long_array& theNodesNot,
5704 GEOM::GEOM_Object_ptr theShape )
5705 throw (SALOME::SALOME_Exception)
5711 SMESHDS_Mesh* aMeshDS = getMeshDS();
5712 TIDSortedElemSet anElems, aNodes;
5713 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5714 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5716 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5717 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
5719 // Update Python script
5720 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
5721 << theNodesNot << ", " << theShape << " )";
5723 declareMeshModified( /*isReComputeSafe=*/false );
5726 SMESH_CATCH( SMESH::throwCorbaException );
5730 //================================================================================
5732 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5733 \param theElems - group of of elements (edges or faces) to be replicated
5734 \param theNodesNot - group of nodes not to replicated
5735 \param theAffectedElems - group of elements to which the replicated nodes
5736 should be associated to.
5737 \return TRUE if operation has been completed successfully, FALSE otherwise
5738 \sa DoubleNodes(), DoubleNodeGroups()
5740 //================================================================================
5743 SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
5744 SMESH::SMESH_GroupBase_ptr theNodesNot,
5745 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5746 throw (SALOME::SALOME_Exception)
5749 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5755 SMESHDS_Mesh* aMeshDS = getMeshDS();
5756 TIDSortedElemSet anElems, aNodes, anAffected;
5757 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5758 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5759 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5761 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5763 // Update Python script
5764 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
5765 << theNodesNot << ", " << theAffectedElems << " )";
5767 declareMeshModified( /*isReComputeSafe=*/false );
5770 SMESH_CATCH( SMESH::throwCorbaException );
5774 //================================================================================
5776 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5777 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
5778 * \param theElems - group of of elements (edges or faces) to be replicated
5779 * \param theNodesNot - group of nodes not to replicated
5780 * \param theAffectedElems - group of elements to which the replicated nodes
5781 * should be associated to.
5782 * \return a new group with newly created elements
5783 * \sa DoubleNodeElemGroup()
5785 //================================================================================
5787 SMESH::SMESH_Group_ptr
5788 SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
5789 SMESH::SMESH_GroupBase_ptr theNodesNot,
5790 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5791 throw (SALOME::SALOME_Exception)
5794 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroup2New( theElems,
5798 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
5799 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
5801 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupNew( "
5803 << theNodesNot << ", "
5804 << theAffectedElems << " )";
5806 return elemGroup._retn();
5809 //================================================================================
5811 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5812 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
5813 * \param theElems - group of of elements (edges or faces) to be replicated
5814 * \param theNodesNot - group of nodes not to replicated
5815 * \param theAffectedElems - group of elements to which the replicated nodes
5816 * should be associated to.
5817 * \return a new group with newly created elements
5818 * \sa DoubleNodeElemGroup()
5820 //================================================================================
5822 SMESH::ListOfGroups*
5823 SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
5824 SMESH::SMESH_GroupBase_ptr theNodesNot,
5825 SMESH::SMESH_GroupBase_ptr theAffectedElems,
5826 CORBA::Boolean theElemGroupNeeded,
5827 CORBA::Boolean theNodeGroupNeeded)
5828 throw (SALOME::SALOME_Exception)
5831 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
5832 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
5833 aTwoGroups->length( 2 );
5835 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5836 return aTwoGroups._retn();
5841 SMESHDS_Mesh* aMeshDS = getMeshDS();
5842 TIDSortedElemSet anElems, aNodes, anAffected;
5843 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5844 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5845 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5848 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5850 declareMeshModified( /*isReComputeSafe=*/ !aResult );
5856 // Create group with newly created elements
5857 CORBA::String_var elemGroupName = theElems->GetName();
5858 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
5859 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
5861 SMESH::long_array_var anIds = GetLastCreatedElems();
5862 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5863 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5864 aNewElemGroup->Add(anIds);
5866 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
5868 SMESH::long_array_var anIds = GetLastCreatedNodes();
5869 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5870 aNewNodeGroup->Add(anIds);
5874 // Update Python script
5877 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
5878 else pyDump << aNewElemGroup << ", ";
5879 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
5880 else pyDump << aNewNodeGroup << " ] = ";
5882 pyDump << this << ".DoubleNodeElemGroup2New( " << theElems << ", "
5883 << theNodesNot << ", "
5884 << theAffectedElems << ", "
5885 << theElemGroupNeeded << ", "
5886 << theNodeGroupNeeded <<" )";
5888 aTwoGroups[0] = aNewElemGroup._retn();
5889 aTwoGroups[1] = aNewNodeGroup._retn();
5890 return aTwoGroups._retn();
5892 SMESH_CATCH( SMESH::throwCorbaException );
5896 //================================================================================
5898 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5899 \param theElems - group of of elements (edges or faces) to be replicated
5900 \param theNodesNot - group of nodes not to replicated
5901 \param theShape - shape to detect affected elements (element which geometric center
5902 located on or inside shape).
5903 The replicated nodes should be associated to affected elements.
5904 \return TRUE if operation has been completed successfully, FALSE otherwise
5905 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
5907 //================================================================================
5910 SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
5911 SMESH::SMESH_GroupBase_ptr theNodesNot,
5912 GEOM::GEOM_Object_ptr theShape )
5913 throw (SALOME::SALOME_Exception)
5916 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5922 SMESHDS_Mesh* aMeshDS = getMeshDS();
5923 TIDSortedElemSet anElems, aNodes, anAffected;
5924 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5925 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5927 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5928 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
5931 declareMeshModified( /*isReComputeSafe=*/ !aResult );
5933 // Update Python script
5934 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
5935 << theNodesNot << ", " << theShape << " )";
5938 SMESH_CATCH( SMESH::throwCorbaException );
5942 //================================================================================
5944 * \brief Re-load elements from a list of groups into a TIDSortedElemSet
5945 * \param [in] theGrpList - groups
5946 * \param [in] theMeshDS - mesh
5947 * \param [out] theElemSet - set of elements
5948 * \param [in] theIsNodeGrp - is \a theGrpList includes goups of nodes
5950 //================================================================================
5952 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
5953 SMESHDS_Mesh* theMeshDS,
5954 TIDSortedElemSet& theElemSet,
5955 const bool theIsNodeGrp)
5957 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
5959 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
5960 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
5961 : aGrp->GetType() != SMESH::NODE ) )
5963 SMESH::long_array_var anIDs = aGrp->GetIDs();
5964 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
5969 //================================================================================
5971 \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5972 This method provided for convenience works as DoubleNodes() described above.
5973 \param theElems - list of groups of elements (edges or faces) to be replicated
5974 \param theNodesNot - list of groups of nodes not to replicated
5975 \param theAffectedElems - group of elements to which the replicated nodes
5976 should be associated to.
5977 \return TRUE if operation has been completed successfully, FALSE otherwise
5978 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
5980 //================================================================================
5983 SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
5984 const SMESH::ListOfGroups& theNodesNot,
5985 const SMESH::ListOfGroups& theAffectedElems)
5986 throw (SALOME::SALOME_Exception)
5992 SMESHDS_Mesh* aMeshDS = getMeshDS();
5993 TIDSortedElemSet anElems, aNodes, anAffected;
5994 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5995 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5996 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5998 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6000 // Update Python script
6001 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
6002 << &theNodesNot << ", " << &theAffectedElems << " )";
6004 declareMeshModified( /*isReComputeSafe=*/false );
6007 SMESH_CATCH( SMESH::throwCorbaException );
6011 //================================================================================
6013 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6014 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6015 \param theElems - list of groups of elements (edges or faces) to be replicated
6016 \param theNodesNot - list of groups of nodes not to replicated
6017 \param theAffectedElems - group of elements to which the replicated nodes
6018 should be associated to.
6019 * \return a new group with newly created elements
6020 * \sa DoubleNodeElemGroups()
6022 //================================================================================
6024 SMESH::SMESH_Group_ptr
6025 SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
6026 const SMESH::ListOfGroups& theNodesNot,
6027 const SMESH::ListOfGroups& theAffectedElems)
6028 throw (SALOME::SALOME_Exception)
6031 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroups2New( theElems,
6035 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
6036 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
6038 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupsNew( "
6040 << theNodesNot << ", "
6041 << theAffectedElems << " )";
6043 return elemGroup._retn();
6046 //================================================================================
6048 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6049 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6050 \param theElems - list of groups of elements (edges or faces) to be replicated
6051 \param theNodesNot - list of groups of nodes not to replicated
6052 \param theAffectedElems - group of elements to which the replicated nodes
6053 should be associated to.
6054 * \return a new group with newly created elements
6055 * \sa DoubleNodeElemGroups()
6057 //================================================================================
6059 SMESH::ListOfGroups*
6060 SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems,
6061 const SMESH::ListOfGroups& theNodesNot,
6062 const SMESH::ListOfGroups& theAffectedElems,
6063 CORBA::Boolean theElemGroupNeeded,
6064 CORBA::Boolean theNodeGroupNeeded)
6065 throw (SALOME::SALOME_Exception)
6068 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
6069 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
6070 aTwoGroups->length( 2 );
6075 SMESHDS_Mesh* aMeshDS = getMeshDS();
6076 TIDSortedElemSet anElems, aNodes, anAffected;
6077 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6078 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6079 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6081 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6083 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6088 // Create group with newly created elements
6089 CORBA::String_var elemGroupName = theElems[0]->GetName();
6090 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
6091 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
6093 SMESH::long_array_var anIds = GetLastCreatedElems();
6094 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
6095 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
6096 aNewElemGroup->Add(anIds);
6098 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
6100 SMESH::long_array_var anIds = GetLastCreatedNodes();
6101 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6102 aNewNodeGroup->Add(anIds);
6106 // Update Python script
6109 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
6110 else pyDump << aNewElemGroup << ", ";
6111 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
6112 else pyDump << aNewNodeGroup << " ] = ";
6114 pyDump << this << ".DoubleNodeElemGroups2New( " << &theElems << ", "
6115 << &theNodesNot << ", "
6116 << &theAffectedElems << ", "
6117 << theElemGroupNeeded << ", "
6118 << theNodeGroupNeeded << " )";
6120 aTwoGroups[0] = aNewElemGroup._retn();
6121 aTwoGroups[1] = aNewNodeGroup._retn();
6122 return aTwoGroups._retn();
6124 SMESH_CATCH( SMESH::throwCorbaException );
6128 //================================================================================
6130 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6131 This method provided for convenience works as DoubleNodes() described above.
6132 \param theElems - list of groups of elements (edges or faces) to be replicated
6133 \param theNodesNot - list of groups of nodes not to replicated
6134 \param theShape - shape to detect affected elements (element which geometric center
6135 located on or inside shape).
6136 The replicated nodes should be associated to affected elements.
6137 \return TRUE if operation has been completed successfully, FALSE otherwise
6138 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
6140 //================================================================================
6143 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
6144 const SMESH::ListOfGroups& theNodesNot,
6145 GEOM::GEOM_Object_ptr theShape )
6146 throw (SALOME::SALOME_Exception)
6152 SMESHDS_Mesh* aMeshDS = getMeshDS();
6153 TIDSortedElemSet anElems, aNodes;
6154 listOfGroupToSet(theElems, aMeshDS, anElems,false );
6155 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6157 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6158 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6160 // Update Python script
6161 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
6162 << &theNodesNot << ", " << theShape << " )";
6164 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6167 SMESH_CATCH( SMESH::throwCorbaException );
6171 //================================================================================
6173 \brief Identify the elements that will be affected by node duplication (actual
6174 duplication is not performed.
6175 This method is the first step of DoubleNodeElemGroupsInRegion.
6176 \param theElems - list of groups of elements (edges or faces) to be replicated
6177 \param theNodesNot - list of groups of nodes not to replicated
6178 \param theShape - shape to detect affected elements (element which geometric center
6179 located on or inside shape).
6180 The replicated nodes should be associated to affected elements.
6181 \return groups of affected elements
6182 \sa DoubleNodeElemGroupsInRegion()
6184 //================================================================================
6185 SMESH::ListOfGroups*
6186 SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theElems,
6187 const SMESH::ListOfGroups& theNodesNot,
6188 GEOM::GEOM_Object_ptr theShape )
6189 throw (SALOME::SALOME_Exception)
6192 MESSAGE("AffectedElemGroupsInRegion");
6193 SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
6194 bool isEdgeGroup = false;
6195 bool isFaceGroup = false;
6196 bool isVolumeGroup = false;
6197 SMESH::SMESH_Group_var aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE, "affectedEdges");
6198 SMESH::SMESH_Group_var aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE, "affectedFaces");
6199 SMESH::SMESH_Group_var aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME, "affectedVolumes");
6203 ::SMESH_MeshEditor aMeshEditor(myMesh);
6205 SMESHDS_Mesh* aMeshDS = getMeshDS();
6206 TIDSortedElemSet anElems, aNodes;
6207 listOfGroupToSet(theElems, aMeshDS, anElems, false);
6208 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true);
6210 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape(theShape);
6211 TIDSortedElemSet anAffected;
6212 bool aResult = aMeshEditor.AffectedElemGroupsInRegion(anElems, aNodes, aShape, anAffected);
6215 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6220 int lg = anAffected.size();
6221 MESSAGE("lg="<< lg);
6222 SMESH::long_array_var volumeIds = new SMESH::long_array;
6223 volumeIds->length(lg);
6224 SMESH::long_array_var faceIds = new SMESH::long_array;
6225 faceIds->length(lg);
6226 SMESH::long_array_var edgeIds = new SMESH::long_array;
6227 edgeIds->length(lg);
6232 TIDSortedElemSet::const_iterator eIt = anAffected.begin();
6233 for (; eIt != anAffected.end(); ++eIt)
6235 const SMDS_MeshElement* anElem = *eIt;
6238 int elemId = anElem->GetID();
6239 if (myMesh->GetElementType(elemId, true) == SMDSAbs_Volume)
6240 volumeIds[ivol++] = elemId;
6241 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Face)
6242 faceIds[iface++] = elemId;
6243 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Edge)
6244 edgeIds[iedge++] = elemId;
6246 volumeIds->length(ivol);
6247 faceIds->length(iface);
6248 edgeIds->length(iedge);
6250 aNewVolumeGroup->Add(volumeIds);
6251 aNewFaceGroup->Add(faceIds);
6252 aNewEdgeGroup->Add(edgeIds);
6253 isVolumeGroup = (aNewVolumeGroup->Size() > 0);
6254 isFaceGroup = (aNewFaceGroup->Size() > 0);
6255 isEdgeGroup = (aNewEdgeGroup->Size() > 0);
6259 if (isEdgeGroup) nbGroups++;
6260 if (isFaceGroup) nbGroups++;
6261 if (isVolumeGroup) nbGroups++;
6262 aListOfGroups->length(nbGroups);
6265 if (isEdgeGroup) aListOfGroups[i++] = aNewEdgeGroup._retn();
6266 if (isFaceGroup) aListOfGroups[i++] = aNewFaceGroup._retn();
6267 if (isVolumeGroup) aListOfGroups[i++] = aNewVolumeGroup._retn();
6269 // Update Python script
6272 if (isEdgeGroup) pyDump << aNewEdgeGroup << ", ";
6273 if (isFaceGroup) pyDump << aNewFaceGroup << ", ";
6274 if (isVolumeGroup) pyDump << aNewVolumeGroup << ", ";
6276 pyDump << this << ".AffectedElemGroupsInRegion( "
6277 << &theElems << ", " << &theNodesNot << ", " << theShape << " )";
6279 return aListOfGroups._retn();
6281 SMESH_CATCH( SMESH::throwCorbaException );
6285 //================================================================================
6287 \brief Generated skin mesh (containing 2D cells) from 3D mesh
6288 The created 2D mesh elements based on nodes of free faces of boundary volumes
6289 \return TRUE if operation has been completed successfully, FALSE otherwise
6291 //================================================================================
6293 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
6294 throw (SALOME::SALOME_Exception)
6299 bool aResult = getEditor().Make2DMeshFrom3D();
6301 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
6303 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6306 SMESH_CATCH( SMESH::throwCorbaException );
6310 //================================================================================
6312 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
6313 * The list of groups must contain at least two groups. The groups have to be disjoint:
6314 * no common element into two different groups.
6315 * The nodes of the internal faces at the boundaries of the groups are doubled.
6316 * Optionally, the internal faces are replaced by flat elements.
6317 * Triangles are transformed into prisms, and quadrangles into hexahedrons.
6318 * The flat elements are stored in groups of volumes.
6319 * These groups are named according to the position of the group in the list:
6320 * 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.
6321 * 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.
6322 * All the flat elements are gathered into the group named "joints3D" (or "joints2D" in 2D situation).
6323 * The flat element of the multiple junctions between the simple junction are stored in a group named "jointsMultiples".
6324 * \param theDomains - list of groups of volumes
6325 * \param createJointElems - if TRUE, create the elements
6326 * \param onAllBoundaries - if TRUE, the nodes and elements are also created on
6327 * the boundary between \a theDomains and the rest mesh
6328 * \return TRUE if operation has been completed successfully, FALSE otherwise
6330 //================================================================================
6333 SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
6334 CORBA::Boolean createJointElems,
6335 CORBA::Boolean onAllBoundaries )
6336 throw (SALOME::SALOME_Exception)
6343 SMESHDS_Mesh* aMeshDS = getMeshDS();
6345 // MESSAGE("theDomains.length = "<<theDomains.length());
6346 if ( theDomains.length() <= 1 && !onAllBoundaries )
6347 THROW_SALOME_CORBA_EXCEPTION("At least 2 groups are required.", SALOME::BAD_PARAM);
6349 vector<TIDSortedElemSet> domains;
6350 domains.resize( theDomains.length() );
6352 for ( int i = 0, n = theDomains.length(); i < n; i++ )
6354 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
6355 if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
6357 // if ( aGrp->GetType() != SMESH::VOLUME )
6358 // THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
6359 SMESH::long_array_var anIDs = aGrp->GetIDs();
6360 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
6364 isOK = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems, onAllBoundaries );
6365 // TODO publish the groups of flat elements in study
6367 declareMeshModified( /*isReComputeSafe=*/ !isOK );
6369 // Update Python script
6370 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
6371 << ", " << createJointElems << ", " << onAllBoundaries << " )";
6373 SMESH_CATCH( SMESH::throwCorbaException );
6375 myMesh_i->CreateGroupServants(); // publish created groups if any
6380 //================================================================================
6382 * \brief Double nodes on some external faces and create flat elements.
6383 * Flat elements are mainly used by some types of mechanic calculations.
6385 * Each group of the list must be constituted of faces.
6386 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
6387 * @param theGroupsOfFaces - list of groups of faces
6388 * @return TRUE if operation has been completed successfully, FALSE otherwise
6390 //================================================================================
6393 SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
6394 throw (SALOME::SALOME_Exception)
6399 SMESHDS_Mesh* aMeshDS = getMeshDS();
6401 vector<TIDSortedElemSet> faceGroups;
6404 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
6406 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
6407 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
6409 TIDSortedElemSet faceGroup;
6411 faceGroups.push_back(faceGroup);
6412 SMESH::long_array_var anIDs = aGrp->GetIDs();
6413 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
6417 bool aResult = getEditor().CreateFlatElementsOnFacesGroups( faceGroups );
6418 // TODO publish the groups of flat elements in study
6420 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6422 // Update Python script
6423 TPythonDump() << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
6426 SMESH_CATCH( SMESH::throwCorbaException );
6430 //================================================================================
6432 * \brief Identify all the elements around a geom shape, get the faces delimiting
6435 * Build groups of volume to remove, groups of faces to replace on the skin of the
6436 * object, groups of faces to remove inside the object, (idem edges).
6437 * Build ordered list of nodes at the border of each group of faces to replace
6438 * (to be used to build a geom subshape).
6440 //================================================================================
6442 void SMESH_MeshEditor_i::CreateHoleSkin(CORBA::Double radius,
6443 GEOM::GEOM_Object_ptr theShape,
6444 const char* groupName,
6445 const SMESH::double_array& theNodesCoords,
6446 SMESH::array_of_long_array_out GroupsOfNodes)
6447 throw (SALOME::SALOME_Exception)
6452 std::vector<std::vector<int> > aListOfListOfNodes;
6453 ::SMESH_MeshEditor aMeshEditor( myMesh );
6455 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
6456 if ( !theNodeSearcher )
6457 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
6459 vector<double> nodesCoords;
6460 for (int i = 0; i < theNodesCoords.length(); i++)
6462 nodesCoords.push_back( theNodesCoords[i] );
6465 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6466 aMeshEditor.CreateHoleSkin(radius, aShape, theNodeSearcher, groupName,
6467 nodesCoords, aListOfListOfNodes);
6469 GroupsOfNodes = new SMESH::array_of_long_array;
6470 GroupsOfNodes->length( aListOfListOfNodes.size() );
6471 std::vector<std::vector<int> >::iterator llIt = aListOfListOfNodes.begin();
6472 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
6474 vector<int>& aListOfNodes = *llIt;
6475 vector<int>::iterator lIt = aListOfNodes.begin();;
6476 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
6477 aGroup.length( aListOfNodes.size() );
6478 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
6479 aGroup[ j ] = (*lIt);
6481 TPythonDump() << "lists_nodes = " << this << ".CreateHoleSkin( "
6484 << ", '" << groupName << "', "
6485 << theNodesCoords << " )";
6487 SMESH_CATCH( SMESH::throwCorbaException );
6490 // issue 20749 ===================================================================
6492 * \brief Creates missing boundary elements
6493 * \param elements - elements whose boundary is to be checked
6494 * \param dimension - defines type of boundary elements to create
6495 * \param groupName - a name of group to store created boundary elements in,
6496 * "" means not to create the group
6497 * \param meshName - a name of new mesh to store created boundary elements in,
6498 * "" means not to create the new mesh
6499 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
6500 * \param toCopyExistingBondary - if true, not only new but also pre-existing
6501 * boundary elements will be copied into the new mesh
6502 * \param group - returns the create group, if any
6503 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
6505 // ================================================================================
6507 SMESH::SMESH_Mesh_ptr
6508 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
6509 SMESH::Bnd_Dimension dim,
6510 const char* groupName,
6511 const char* meshName,
6512 CORBA::Boolean toCopyElements,
6513 CORBA::Boolean toCopyExistingBondary,
6514 SMESH::SMESH_Group_out group)
6515 throw (SALOME::SALOME_Exception)
6520 if ( dim > SMESH::BND_1DFROM2D )
6521 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
6523 SMESHDS_Mesh* aMeshDS = getMeshDS();
6525 SMESH::SMESH_Mesh_var mesh_var;
6526 SMESH::SMESH_Group_var group_var;
6530 TIDSortedElemSet elements;
6531 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
6532 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
6536 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
6537 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
6539 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
6541 // group of new boundary elements
6542 SMESH_Group* smesh_group = 0;
6543 if ( strlen(groupName) )
6545 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
6546 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
6547 smesh_group = group_i->GetSmeshGroup();
6551 getEditor().MakeBoundaryMesh( elements,
6552 ::SMESH_MeshEditor::Bnd_Dimension(dim),
6556 toCopyExistingBondary);
6559 smesh_mesh->GetMeshDS()->Modified();
6562 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
6564 // result of MakeBoundaryMesh() is a tuple (mesh, group)
6565 if ( mesh_var->_is_nil() )
6566 pyDump << myMesh_i->_this() << ", ";
6568 pyDump << mesh_var << ", ";
6569 if ( group_var->_is_nil() )
6570 pyDump << "_NoneGroup = "; // assignment to None is forbiden
6572 pyDump << group_var << " = ";
6573 pyDump << this << ".MakeBoundaryMesh( "
6575 << "SMESH." << dimName[int(dim)] << ", "
6576 << "'" << groupName << "', "
6577 << "'" << meshName<< "', "
6578 << toCopyElements << ", "
6579 << toCopyExistingBondary << ")";
6581 group = group_var._retn();
6582 return mesh_var._retn();
6584 SMESH_CATCH( SMESH::throwCorbaException );
6585 return SMESH::SMESH_Mesh::_nil();
6588 //================================================================================
6590 * \brief Creates missing boundary elements
6591 * \param dimension - defines type of boundary elements to create
6592 * \param groupName - a name of group to store all boundary elements in,
6593 * "" means not to create the group
6594 * \param meshName - a name of a new mesh, which is a copy of the initial
6595 * mesh + created boundary elements; "" means not to create the new mesh
6596 * \param toCopyAll - if true, the whole initial mesh will be copied into
6597 * the new mesh else only boundary elements will be copied into the new mesh
6598 * \param groups - optional groups of elements to make boundary around
6599 * \param mesh - returns the mesh where elements were added to
6600 * \param group - returns the created group, if any
6601 * \retval long - number of added boundary elements
6603 //================================================================================
6605 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
6606 const char* groupName,
6607 const char* meshName,
6608 CORBA::Boolean toCopyAll,
6609 const SMESH::ListOfIDSources& groups,
6610 SMESH::SMESH_Mesh_out mesh,
6611 SMESH::SMESH_Group_out group)
6612 throw (SALOME::SALOME_Exception)
6617 if ( dim > SMESH::BND_1DFROM2D )
6618 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
6620 // separate groups belonging to this and other mesh
6621 SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
6622 SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
6623 groupsOfThisMesh ->length( groups.length() );
6624 groupsOfOtherMesh->length( groups.length() );
6625 int nbGroups = 0, nbGroupsOfOtherMesh = 0;
6626 for ( int i = 0; i < groups.length(); ++i )
6628 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
6629 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
6630 groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
6632 groupsOfThisMesh[ nbGroups++ ] = groups[i];
6633 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
6634 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
6636 groupsOfThisMesh->length( nbGroups );
6637 groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
6642 if ( nbGroupsOfOtherMesh > 0 )
6644 // process groups belonging to another mesh
6645 SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
6646 SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
6647 nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
6648 groupsOfOtherMesh, mesh, group );
6651 SMESH::SMESH_Mesh_var mesh_var;
6652 SMESH::SMESH_Group_var group_var;
6655 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
6656 const bool toCopyMesh = ( strlen( meshName ) > 0 );
6660 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
6662 /*toCopyGroups=*/false,
6663 /*toKeepIDs=*/true);
6665 mesh_var = makeMesh(meshName);
6667 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
6668 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
6671 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
6672 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
6674 // group of boundary elements
6675 SMESH_Group* smesh_group = 0;
6676 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
6677 if ( strlen(groupName) )
6679 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
6680 group_var = mesh_i->CreateGroup( groupType, groupName );
6681 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
6682 smesh_group = group_i->GetSmeshGroup();
6685 TIDSortedElemSet elements;
6687 if ( groups.length() > 0 )
6689 for ( int i = 0; i < nbGroups; ++i )
6692 if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
6694 SMESH::Bnd_Dimension bdim =
6695 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
6696 nbAdded += getEditor().MakeBoundaryMesh( elements,
6697 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
6700 /*toCopyElements=*/false,
6701 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
6702 /*toAddExistingBondary=*/true,
6703 /*aroundElements=*/true);
6709 nbAdded += getEditor().MakeBoundaryMesh( elements,
6710 ::SMESH_MeshEditor::Bnd_Dimension(dim),
6713 /*toCopyElements=*/false,
6714 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
6715 /*toAddExistingBondary=*/true);
6717 tgtMesh->GetMeshDS()->Modified();
6719 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
6721 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
6722 pyDump << "nbAdded, ";
6723 if ( mesh_var->_is_nil() )
6724 pyDump << myMesh_i->_this() << ", ";
6726 pyDump << mesh_var << ", ";
6727 if ( group_var->_is_nil() )
6728 pyDump << "_NoneGroup = "; // assignment to None is forbiden
6730 pyDump << group_var << " = ";
6731 pyDump << this << ".MakeBoundaryElements( "
6732 << "SMESH." << dimName[int(dim)] << ", "
6733 << "'" << groupName << "', "
6734 << "'" << meshName<< "', "
6735 << toCopyAll << ", "
6738 mesh = mesh_var._retn();
6739 group = group_var._retn();
6742 SMESH_CATCH( SMESH::throwCorbaException );