1 // Copyright (C) 2007-2016 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 ( CORBA::ULong i = 0; i < IDs.length(); i++ ) {
289 const SMDS_MeshElement * elem = aMesh->FindNode( IDs[i] );
291 aMap.insert( aMap.end(), elem );
294 for ( CORBA::ULong 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 ( CORBA::ULong 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 ( CORBA::ULong 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 ) == (int) 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 ( CORBA::ULong 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 ( CORBA::ULong 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)
862 list< int > IdList( seq.begin(), seq.end() );
864 int nbNodesBefore = myMesh->NbNodes();
865 getEditor().Remove( IdList, true );
866 int nbNodesAfter = myMesh->NbNodes();
868 declareMeshModified( /*isReComputeSafe=*/ IdList.size() == 0 ); // issue 0020693
869 return nbNodesBefore - nbNodesAfter;
871 SMESH_CATCH( SMESH::throwCorbaException );
875 //=============================================================================
879 //=============================================================================
881 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,CORBA::Double y, CORBA::Double z)
882 throw (SALOME::SALOME_Exception)
887 const SMDS_MeshNode* N = getMeshDS()->AddNode(x, y, z);
889 // Update Python script
890 TPythonDump() << "nodeID = " << this << ".AddNode( "
891 << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )";
893 declareMeshModified( /*isReComputeSafe=*/false );
896 SMESH_CATCH( SMESH::throwCorbaException );
900 //=============================================================================
902 * Create 0D element on the given node.
904 //=============================================================================
906 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode,
907 CORBA::Boolean DuplicateElements)
908 throw (SALOME::SALOME_Exception)
913 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
914 SMDS_ElemIteratorPtr it0D = aNode->GetInverseElementIterator( SMDSAbs_0DElement );
916 SMDS_MeshElement* elem = 0;
917 if ( DuplicateElements || !it0D->more() )
918 elem = getMeshDS()->Add0DElement(aNode);
920 // Update Python script
921 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
923 declareMeshModified( /*isReComputeSafe=*/false );
925 return elem ? elem->GetID() : 0;
927 SMESH_CATCH( SMESH::throwCorbaException );
931 //=============================================================================
933 * Create a ball element on the given node.
935 //=============================================================================
937 CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diameter)
938 throw (SALOME::SALOME_Exception)
943 if ( diameter < std::numeric_limits<double>::min() )
944 THROW_SALOME_CORBA_EXCEPTION("Invalid diameter", SALOME::BAD_PARAM);
946 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
947 SMDS_MeshElement* elem = getMeshDS()->AddBall(aNode, diameter);
949 // Update Python script
950 TPythonDump() << "ballElem = "
951 << this << ".AddBall( " << IDOfNode << ", " << diameter <<" )";
953 declareMeshModified( /*isReComputeSafe=*/false );
954 return elem ? elem->GetID() : 0;
956 SMESH_CATCH( SMESH::throwCorbaException );
960 //=============================================================================
962 * Create an edge, either linear and quadratic (this is determed
963 * by number of given nodes, two or three)
965 //=============================================================================
967 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
968 throw (SALOME::SALOME_Exception)
973 int NbNodes = IDsOfNodes.length();
974 SMDS_MeshElement* elem = 0;
977 CORBA::Long index1 = IDsOfNodes[0];
978 CORBA::Long index2 = IDsOfNodes[1];
979 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(index1),
980 getMeshDS()->FindNode(index2));
982 // Update Python script
983 TPythonDump() << "edge = " << this << ".AddEdge([ "
984 << index1 << ", " << index2 <<" ])";
987 CORBA::Long n1 = IDsOfNodes[0];
988 CORBA::Long n2 = IDsOfNodes[1];
989 CORBA::Long n12 = IDsOfNodes[2];
990 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(n1),
991 getMeshDS()->FindNode(n2),
992 getMeshDS()->FindNode(n12));
993 // Update Python script
994 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
995 <<n1<<", "<<n2<<", "<<n12<<" ])";
998 declareMeshModified( /*isReComputeSafe=*/false );
999 return elem ? elem->GetID() : 0;
1001 SMESH_CATCH( SMESH::throwCorbaException );
1005 //=============================================================================
1009 //=============================================================================
1011 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
1012 throw (SALOME::SALOME_Exception)
1017 int NbNodes = IDsOfNodes.length();
1023 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1024 for (int i = 0; i < NbNodes; i++)
1025 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1027 SMDS_MeshElement* elem = 0;
1029 case 3: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]); break;
1030 case 4: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]); break;
1031 case 6: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1032 nodes[4], nodes[5]); break;
1033 case 7: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1034 nodes[4], nodes[5], nodes[6]); break;
1035 case 8: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1036 nodes[4], nodes[5], nodes[6], nodes[7]); break;
1037 case 9: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1038 nodes[4], nodes[5], nodes[6], nodes[7],
1040 default: elem = getMeshDS()->AddPolygonalFace(nodes);
1043 // Update Python script
1044 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
1046 declareMeshModified( /*isReComputeSafe=*/false );
1048 return elem ? elem->GetID() : 0;
1050 SMESH_CATCH( SMESH::throwCorbaException );
1054 //=============================================================================
1058 //=============================================================================
1060 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
1061 throw (SALOME::SALOME_Exception)
1066 int NbNodes = IDsOfNodes.length();
1067 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1068 for (int i = 0; i < NbNodes; i++)
1069 if ( ! ( nodes[i] = getMeshDS()->FindNode( IDsOfNodes[i] )))
1072 const SMDS_MeshElement* elem = getMeshDS()->AddPolygonalFace(nodes);
1074 // Update Python script
1075 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
1077 declareMeshModified( /*isReComputeSafe=*/false );
1078 return elem ? elem->GetID() : 0;
1080 SMESH_CATCH( SMESH::throwCorbaException );
1084 //=============================================================================
1086 * AddQuadPolygonalFace
1088 //=============================================================================
1090 CORBA::Long SMESH_MeshEditor_i::AddQuadPolygonalFace (const SMESH::long_array & IDsOfNodes)
1091 throw (SALOME::SALOME_Exception)
1096 int NbNodes = IDsOfNodes.length();
1097 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1098 for (int i = 0; i < NbNodes; i++)
1099 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1101 const SMDS_MeshElement* elem = getMeshDS()->AddQuadPolygonalFace(nodes);
1103 // Update Python script
1104 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
1106 declareMeshModified( /*isReComputeSafe=*/false );
1107 return elem ? elem->GetID() : 0;
1109 SMESH_CATCH( SMESH::throwCorbaException );
1113 //=============================================================================
1115 * Create volume, either linear and quadratic (this is determed
1116 * by number of given nodes)
1118 //=============================================================================
1120 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
1121 throw (SALOME::SALOME_Exception)
1126 int NbNodes = IDsOfNodes.length();
1127 vector< const SMDS_MeshNode*> n(NbNodes);
1128 for(int i=0;i<NbNodes;i++)
1129 n[i]= getMeshDS()->FindNode(IDsOfNodes[i]);
1131 SMDS_MeshElement* elem = 0;
1134 case 4 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
1135 case 5 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
1136 case 6 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
1137 case 8 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
1138 case 10:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1139 n[6],n[7],n[8],n[9]);
1141 case 12:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1142 n[6],n[7],n[8],n[9],n[10],n[11]);
1144 case 13:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
1145 n[7],n[8],n[9],n[10],n[11],n[12]);
1147 case 15:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
1148 n[9],n[10],n[11],n[12],n[13],n[14]);
1150 case 20:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1151 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1152 n[15],n[16],n[17],n[18],n[19]);
1154 case 27:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1155 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1156 n[15],n[16],n[17],n[18],n[19],
1157 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
1161 // Update Python script
1162 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
1164 declareMeshModified( /*isReComputeSafe=*/false );
1165 return elem ? elem->GetID() : 0;
1167 SMESH_CATCH( SMESH::throwCorbaException );
1171 //=============================================================================
1173 * AddPolyhedralVolume
1175 //=============================================================================
1176 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
1177 const SMESH::long_array & Quantities)
1178 throw (SALOME::SALOME_Exception)
1183 int NbNodes = IDsOfNodes.length();
1184 std::vector<const SMDS_MeshNode*> n (NbNodes);
1185 for (int i = 0; i < NbNodes; i++)
1187 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDsOfNodes[i]);
1188 if (!aNode) return 0;
1192 int NbFaces = Quantities.length();
1193 std::vector<int> q (NbFaces);
1194 for (int j = 0; j < NbFaces; j++)
1195 q[j] = Quantities[j];
1197 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(n, q);
1199 // Update Python script
1200 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
1201 << IDsOfNodes << ", " << Quantities << " )";
1203 declareMeshModified( /*isReComputeSafe=*/false );
1204 return elem ? elem->GetID() : 0;
1206 SMESH_CATCH( SMESH::throwCorbaException );
1210 //=============================================================================
1212 * AddPolyhedralVolumeByFaces
1214 //=============================================================================
1216 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
1217 throw (SALOME::SALOME_Exception)
1222 int NbFaces = IdsOfFaces.length();
1223 std::vector<const SMDS_MeshNode*> poly_nodes;
1224 std::vector<int> quantities (NbFaces);
1226 for (int i = 0; i < NbFaces; i++) {
1227 const SMDS_MeshElement* aFace = getMeshDS()->FindElement(IdsOfFaces[i]);
1228 quantities[i] = aFace->NbNodes();
1230 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
1231 while (It->more()) {
1232 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
1236 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
1238 // Update Python script
1239 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
1240 << IdsOfFaces << " )";
1242 declareMeshModified( /*isReComputeSafe=*/false );
1243 return elem ? elem->GetID() : 0;
1245 SMESH_CATCH( SMESH::throwCorbaException );
1249 //=============================================================================
1251 // \brief Create 0D elements on all nodes of the given object.
1252 // \param theObject object on whose nodes 0D elements will be created.
1253 // \param theGroupName optional name of a group to add 0D elements created
1254 // and/or found on nodes of \a theObject.
1255 // \param DuplicateElements to add one more 0D element to a node or not.
1256 // \return an object (a new group or a temporary SMESH_IDSource) holding
1257 // ids of new and/or found 0D elements.
1259 //=============================================================================
1261 SMESH::SMESH_IDSource_ptr
1262 SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObject,
1263 const char* theGroupName,
1264 CORBA::Boolean theDuplicateElements)
1265 throw (SALOME::SALOME_Exception)
1270 SMESH::SMESH_IDSource_var result;
1273 TIDSortedElemSet elements, elems0D;
1274 if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
1275 getEditor().Create0DElementsOnAllNodes( elements, elems0D, theDuplicateElements );
1277 SMESH::long_array_var newElems = new SMESH::long_array;
1278 newElems->length( elems0D.size() );
1279 TIDSortedElemSet::iterator eIt = elems0D.begin();
1280 for ( size_t i = 0; i < elems0D.size(); ++i, ++eIt )
1281 newElems[ i ] = (*eIt)->GetID();
1283 SMESH::SMESH_GroupBase_var groupToFill;
1284 if ( theGroupName && strlen( theGroupName ))
1286 // Get existing group named theGroupName
1287 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
1288 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
1289 SMESH::SMESH_GroupBase_var group = groups[i];
1290 if ( !group->_is_nil() ) {
1291 CORBA::String_var name = group->GetName();
1292 if ( strcmp( name.in(), theGroupName ) == 0 && group->GetType() == SMESH::ELEM0D ) {
1293 groupToFill = group;
1298 if ( groupToFill->_is_nil() )
1299 groupToFill = myMesh_i->CreateGroup( SMESH::ELEM0D, theGroupName );
1300 else if ( !SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1301 groupToFill = myMesh_i->ConvertToStandalone( groupToFill );
1304 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1306 group_i->Add( newElems );
1307 result = SMESH::SMESH_IDSource::_narrow( groupToFill );
1308 pyDump << groupToFill;
1312 result = MakeIDSource( newElems, SMESH::ELEM0D );
1313 pyDump << "elem0DIDs";
1316 pyDump << " = " << this << ".Create0DElementsOnAllNodes( "
1317 << theObject << ", '" << theGroupName << "' )";
1319 return result._retn();
1321 SMESH_CATCH( SMESH::throwCorbaException );
1325 //=============================================================================
1327 * \brief Bind a node to a vertex
1328 * \param NodeID - node ID
1329 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1330 * \retval boolean - false if NodeID or VertexID is invalid
1332 //=============================================================================
1334 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
1335 throw (SALOME::SALOME_Exception)
1339 SMESHDS_Mesh * mesh = getMeshDS();
1340 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1342 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1344 if ( mesh->MaxShapeIndex() < VertexID )
1345 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1347 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
1348 if ( shape.ShapeType() != TopAbs_VERTEX )
1349 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1351 mesh->SetNodeOnVertex( node, VertexID );
1353 myMesh->SetIsModified( true );
1355 SMESH_CATCH( SMESH::throwCorbaException );
1358 //=============================================================================
1360 * \brief Store node position on an edge
1361 * \param NodeID - node ID
1362 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
1363 * \param paramOnEdge - parameter on edge where the node is located
1364 * \retval boolean - false if any parameter is invalid
1366 //=============================================================================
1368 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
1369 CORBA::Double paramOnEdge)
1370 throw (SALOME::SALOME_Exception)
1374 SMESHDS_Mesh * mesh = getMeshDS();
1375 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1377 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1379 if ( mesh->MaxShapeIndex() < EdgeID )
1380 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1382 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
1383 if ( shape.ShapeType() != TopAbs_EDGE )
1384 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1387 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
1388 if ( paramOnEdge < f || paramOnEdge > l )
1389 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
1391 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
1393 myMesh->SetIsModified( true );
1395 SMESH_CATCH( SMESH::throwCorbaException );
1398 //=============================================================================
1400 * \brief Store node position on a face
1401 * \param NodeID - node ID
1402 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
1403 * \param u - U parameter on face where the node is located
1404 * \param v - V parameter on face where the node is located
1405 * \retval boolean - false if any parameter is invalid
1407 //=============================================================================
1409 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
1410 CORBA::Double u, CORBA::Double v)
1411 throw (SALOME::SALOME_Exception)
1414 SMESHDS_Mesh * mesh = getMeshDS();
1415 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1417 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1419 if ( mesh->MaxShapeIndex() < FaceID )
1420 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1422 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
1423 if ( shape.ShapeType() != TopAbs_FACE )
1424 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1426 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
1427 bool isOut = ( u < surf.FirstUParameter() ||
1428 u > surf.LastUParameter() ||
1429 v < surf.FirstVParameter() ||
1430 v > surf.LastVParameter() );
1434 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
1435 << " u( " << surf.FirstUParameter()
1436 << "," << surf.LastUParameter()
1437 << ") v( " << surf.FirstVParameter()
1438 << "," << surf.LastVParameter() << ")" );
1440 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
1443 mesh->SetNodeOnFace( node, FaceID, u, v );
1444 myMesh->SetIsModified( true );
1446 SMESH_CATCH( SMESH::throwCorbaException );
1449 //=============================================================================
1451 * \brief Bind a node to a solid
1452 * \param NodeID - node ID
1453 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1454 * \retval boolean - false if NodeID or SolidID is invalid
1456 //=============================================================================
1458 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
1459 throw (SALOME::SALOME_Exception)
1462 SMESHDS_Mesh * mesh = getMeshDS();
1463 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1465 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1467 if ( mesh->MaxShapeIndex() < SolidID )
1468 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1470 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
1471 if ( shape.ShapeType() != TopAbs_SOLID &&
1472 shape.ShapeType() != TopAbs_SHELL)
1473 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1475 mesh->SetNodeInVolume( node, SolidID );
1477 SMESH_CATCH( SMESH::throwCorbaException );
1480 //=============================================================================
1482 * \brief Bind an element to a shape
1483 * \param ElementID - element ID
1484 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
1486 //=============================================================================
1488 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
1489 CORBA::Long ShapeID)
1490 throw (SALOME::SALOME_Exception)
1493 SMESHDS_Mesh * mesh = getMeshDS();
1494 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
1496 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
1498 if ( mesh->MaxShapeIndex() < ShapeID || ShapeID < 1 )
1499 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1501 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1502 if ( shape.ShapeType() != TopAbs_EDGE &&
1503 shape.ShapeType() != TopAbs_FACE &&
1504 shape.ShapeType() != TopAbs_SOLID &&
1505 shape.ShapeType() != TopAbs_SHELL )
1506 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1508 mesh->SetMeshElementOnShape( elem, ShapeID );
1510 myMesh->SetIsModified( true );
1512 SMESH_CATCH( SMESH::throwCorbaException );
1515 //=============================================================================
1519 //=============================================================================
1521 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1522 CORBA::Long NodeID2)
1523 throw (SALOME::SALOME_Exception)
1528 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1529 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1533 // Update Python script
1534 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1535 << NodeID1 << ", " << NodeID2 << " )";
1537 int ret = getEditor().InverseDiag ( n1, n2 );
1539 declareMeshModified( /*isReComputeSafe=*/false );
1542 SMESH_CATCH( SMESH::throwCorbaException );
1546 //=============================================================================
1550 //=============================================================================
1552 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1553 CORBA::Long NodeID2)
1554 throw (SALOME::SALOME_Exception)
1559 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1560 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1564 // Update Python script
1565 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1566 << NodeID1 << ", " << NodeID2 << " )";
1569 bool stat = getEditor().DeleteDiag ( n1, n2 );
1571 declareMeshModified( /*isReComputeSafe=*/!stat );
1575 SMESH_CATCH( SMESH::throwCorbaException );
1579 //=============================================================================
1583 //=============================================================================
1585 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1586 throw (SALOME::SALOME_Exception)
1591 for ( CORBA::ULong i = 0; i < IDsOfElements.length(); i++ )
1593 CORBA::Long index = IDsOfElements[i];
1594 const SMDS_MeshElement * elem = getMeshDS()->FindElement(index);
1596 getEditor().Reorient( elem );
1598 // Update Python script
1599 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1601 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 );
1604 SMESH_CATCH( SMESH::throwCorbaException );
1608 //=============================================================================
1612 //=============================================================================
1614 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1615 throw (SALOME::SALOME_Exception)
1620 TPythonDump aTPythonDump; // suppress dump in Reorient()
1622 prepareIdSource( theObject );
1624 SMESH::long_array_var anElementsId = theObject->GetIDs();
1625 CORBA::Boolean isDone = Reorient(anElementsId);
1627 // Update Python script
1628 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1630 declareMeshModified( /*isReComputeSafe=*/ anElementsId->length() == 0 );
1633 SMESH_CATCH( SMESH::throwCorbaException );
1637 //=======================================================================
1638 //function : Reorient2D
1639 //purpose : Reorient faces contained in \a the2Dgroup.
1640 // the2Dgroup - the mesh or its part to reorient
1641 // theDirection - desired direction of normal of \a theFace
1642 // theFace - ID of face whose orientation is checked.
1643 // It can be < 1 then \a thePoint is used to find a face.
1644 // thePoint - is used to find a face if \a theFace < 1.
1645 // return number of reoriented elements.
1646 //=======================================================================
1648 CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
1649 const SMESH::DirStruct& theDirection,
1650 CORBA::Long theFace,
1651 const SMESH::PointStruct& thePoint)
1652 throw (SALOME::SALOME_Exception)
1655 initData(/*deleteSearchers=*/false);
1657 TIDSortedElemSet elements;
1658 IDSource_Error error;
1659 idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error );
1660 if ( error == IDSource_EMPTY )
1662 if ( error == IDSource_INVALID )
1663 THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
1666 const SMDS_MeshElement* face = 0;
1669 face = getMeshDS()->FindElement( theFace );
1671 THROW_SALOME_CORBA_EXCEPTION("Inexistent face given", SALOME::BAD_PARAM);
1672 if ( face->GetType() != SMDSAbs_Face )
1673 THROW_SALOME_CORBA_EXCEPTION("Wrong element type", SALOME::BAD_PARAM);
1677 // create theElementSearcher if needed
1678 theSearchersDeleter.Set( myMesh, getPartIOR( the2Dgroup, SMESH::FACE ));
1679 if ( !theElementSearcher )
1681 if ( elements.empty() ) // search in the whole mesh
1683 if ( myMesh->NbFaces() == 0 )
1684 THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM);
1686 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
1690 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
1691 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
1693 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt);
1697 gp_Pnt p( thePoint.x, thePoint.y, thePoint.z );
1698 face = theElementSearcher->FindClosestTo( p, SMDSAbs_Face );
1701 THROW_SALOME_CORBA_EXCEPTION("No face found by point", SALOME::INTERNAL_ERROR );
1702 if ( !elements.empty() && !elements.count( face ))
1703 THROW_SALOME_CORBA_EXCEPTION("Found face is not in the group", SALOME::BAD_PARAM );
1706 const SMESH::PointStruct * P = &theDirection.PS;
1707 gp_Vec dirVec( P->x, P->y, P->z );
1708 if ( dirVec.Magnitude() < std::numeric_limits< double >::min() )
1709 THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM);
1711 int nbReori = getEditor().Reorient2D( elements, dirVec, face );
1714 declareMeshModified( /*isReComputeSafe=*/false );
1716 TPythonDump() << this << ".Reorient2D( "
1717 << the2Dgroup << ", "
1718 << theDirection << ", "
1720 << thePoint << " )";
1724 SMESH_CATCH( SMESH::throwCorbaException );
1728 //=======================================================================
1729 //function : Reorient2DBy3D
1730 //purpose : Reorient faces basing on orientation of adjacent volumes.
1731 //=======================================================================
1733 CORBA::Long SMESH_MeshEditor_i::Reorient2DBy3D(const SMESH::ListOfIDSources& faceGroups,
1734 SMESH::SMESH_IDSource_ptr volumeGroup,
1735 CORBA::Boolean outsideNormal)
1736 throw (SALOME::SALOME_Exception)
1741 TIDSortedElemSet volumes;
1742 IDSource_Error volsError;
1743 idSourceToSet( volumeGroup, getMeshDS(), volumes, SMDSAbs_Volume, /*emptyIfMesh=*/1, &volsError);
1746 for ( size_t i = 0; i < faceGroups.length(); ++i )
1748 SMESH::SMESH_IDSource_ptr faceGrp = faceGroups[i].in();
1750 TIDSortedElemSet faces;
1751 IDSource_Error error;
1752 idSourceToSet( faceGrp, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error );
1753 if ( error == IDSource_INVALID && faceGroups.length() == 1 )
1754 THROW_SALOME_CORBA_EXCEPTION("No faces in a given object", SALOME::BAD_PARAM);
1755 if ( error == IDSource_OK && volsError != IDSource_OK )
1756 THROW_SALOME_CORBA_EXCEPTION("No volumes in a given object", SALOME::BAD_PARAM);
1758 nbReori += getEditor().Reorient2DBy3D( faces, volumes, outsideNormal );
1760 if ( error != IDSource_EMPTY && faces.empty() ) // all faces in the mesh treated
1765 declareMeshModified( /*isReComputeSafe=*/false );
1767 TPythonDump() << this << ".Reorient2DBy3D( "
1768 << faceGroups << ", "
1769 << volumeGroup << ", "
1770 << outsideNormal << " )";
1774 SMESH_CATCH( SMESH::throwCorbaException );
1778 //=============================================================================
1780 * \brief Fuse neighbour triangles into quadrangles.
1782 //=============================================================================
1784 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1785 SMESH::NumericalFunctor_ptr Criterion,
1786 CORBA::Double MaxAngle)
1787 throw (SALOME::SALOME_Exception)
1792 SMESHDS_Mesh* aMesh = getMeshDS();
1793 TIDSortedElemSet faces,copyFaces;
1794 SMDS_MeshElement::GeomFilter triaFilter(SMDSGeom_TRIANGLE);
1795 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face, & triaFilter);
1796 TIDSortedElemSet* workElements = & faces;
1798 if ( myIsPreviewMode ) {
1799 SMDSAbs_ElementType select = SMDSAbs_Face;
1800 getPreviewMesh( SMDSAbs_Face )->Copy( faces, copyFaces, select );
1801 workElements = & copyFaces;
1804 SMESH::NumericalFunctor_i* aNumericalFunctor =
1805 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1806 SMESH::Controls::NumericalFunctorPtr aCrit;
1807 if ( !aNumericalFunctor )
1808 aCrit.reset( new SMESH::Controls::MaxElementLength2D() );
1810 aCrit = aNumericalFunctor->GetNumericalFunctor();
1812 if ( !myIsPreviewMode ) {
1813 // Update Python script
1814 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1815 << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1818 bool stat = getEditor().TriToQuad( *workElements, aCrit, MaxAngle );
1820 declareMeshModified( /*isReComputeSafe=*/!stat );
1823 SMESH_CATCH( SMESH::throwCorbaException );
1827 //=============================================================================
1829 * \brief Fuse neighbour triangles into quadrangles.
1831 //=============================================================================
1833 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1834 SMESH::NumericalFunctor_ptr Criterion,
1835 CORBA::Double MaxAngle)
1836 throw (SALOME::SALOME_Exception)
1841 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1843 prepareIdSource( theObject );
1844 SMESH::long_array_var anElementsId = theObject->GetIDs();
1845 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1847 if ( !myIsPreviewMode ) {
1848 SMESH::NumericalFunctor_i* aNumericalFunctor =
1849 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1851 // Update Python script
1852 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1853 << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1858 SMESH_CATCH( SMESH::throwCorbaException );
1862 //=============================================================================
1864 * \brief Split quadrangles into triangles.
1866 //=============================================================================
1868 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1869 SMESH::NumericalFunctor_ptr Criterion)
1870 throw (SALOME::SALOME_Exception)
1875 SMESHDS_Mesh* aMesh = getMeshDS();
1876 TIDSortedElemSet faces;
1877 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1879 SMESH::NumericalFunctor_i* aNumericalFunctor =
1880 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1881 SMESH::Controls::NumericalFunctorPtr aCrit;
1882 if ( !aNumericalFunctor )
1883 aCrit.reset( new SMESH::Controls::AspectRatio() );
1885 aCrit = aNumericalFunctor->GetNumericalFunctor();
1888 // Update Python script
1889 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1891 CORBA::Boolean stat = getEditor().QuadToTri( faces, aCrit );
1893 declareMeshModified( /*isReComputeSafe=*/false );
1896 SMESH_CATCH( SMESH::throwCorbaException );
1900 //=============================================================================
1902 * \brief Split quadrangles into triangles.
1904 //=============================================================================
1906 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1907 SMESH::NumericalFunctor_ptr Criterion)
1908 throw (SALOME::SALOME_Exception)
1913 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1915 prepareIdSource( theObject );
1916 SMESH::long_array_var anElementsId = theObject->GetIDs();
1917 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1919 SMESH::NumericalFunctor_i* aNumericalFunctor =
1920 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1922 // Update Python script
1923 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1925 declareMeshModified( /*isReComputeSafe=*/false );
1928 SMESH_CATCH( SMESH::throwCorbaException );
1932 //================================================================================
1934 * \brief Split each of quadrangles into 4 triangles.
1935 * \param [in] theObject - theQuads Container of quadrangles to split.
1937 //================================================================================
1939 void SMESH_MeshEditor_i::QuadTo4Tri (SMESH::SMESH_IDSource_ptr theObject)
1940 throw (SALOME::SALOME_Exception)
1945 TIDSortedElemSet faces;
1946 if ( !idSourceToSet( theObject, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/true ) &&
1948 THROW_SALOME_CORBA_EXCEPTION("No faces given", SALOME::BAD_PARAM);
1950 getEditor().QuadTo4Tri( faces );
1951 TPythonDump() << this << ".QuadTo4Tri( " << theObject << " )";
1953 SMESH_CATCH( SMESH::throwCorbaException );
1956 //=============================================================================
1958 * \brief Split quadrangles into triangles.
1960 //=============================================================================
1962 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1963 CORBA::Boolean Diag13)
1964 throw (SALOME::SALOME_Exception)
1969 SMESHDS_Mesh* aMesh = getMeshDS();
1970 TIDSortedElemSet faces;
1971 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1973 // Update Python script
1974 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1975 << IDsOfElements << ", " << Diag13 << " )";
1977 CORBA::Boolean stat = getEditor().QuadToTri( faces, Diag13 );
1979 declareMeshModified( /*isReComputeSafe=*/ !stat );
1982 SMESH_CATCH( SMESH::throwCorbaException );
1986 //=============================================================================
1988 * \brief Split quadrangles into triangles.
1990 //=============================================================================
1992 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1993 CORBA::Boolean Diag13)
1994 throw (SALOME::SALOME_Exception)
1999 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
2001 prepareIdSource( theObject );
2002 SMESH::long_array_var anElementsId = theObject->GetIDs();
2003 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
2005 // Update Python script
2006 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
2007 << theObject << ", " << Diag13 << " )";
2009 declareMeshModified( /*isReComputeSafe=*/!isDone );
2012 SMESH_CATCH( SMESH::throwCorbaException );
2017 //=============================================================================
2019 * Find better splitting of the given quadrangle.
2020 * \param IDOfQuad ID of the quadrangle to be splitted.
2021 * \param Criterion A criterion to choose a diagonal for splitting.
2022 * \return 1 if 1-3 diagonal is better, 2 if 2-4
2023 * diagonal is better, 0 if error occurs.
2025 //=============================================================================
2027 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
2028 SMESH::NumericalFunctor_ptr Criterion)
2029 throw (SALOME::SALOME_Exception)
2034 const SMDS_MeshElement* quad = getMeshDS()->FindElement(IDOfQuad);
2035 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
2037 SMESH::NumericalFunctor_i* aNumericalFunctor =
2038 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
2039 SMESH::Controls::NumericalFunctorPtr aCrit;
2040 if (aNumericalFunctor)
2041 aCrit = aNumericalFunctor->GetNumericalFunctor();
2043 aCrit.reset(new SMESH::Controls::AspectRatio());
2045 int id = getEditor().BestSplit(quad, aCrit);
2046 declareMeshModified( /*isReComputeSafe=*/ id < 1 );
2050 SMESH_CATCH( SMESH::throwCorbaException );
2054 //================================================================================
2056 * \brief Split volumic elements into tetrahedrons
2058 //================================================================================
2060 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
2061 CORBA::Short methodFlags)
2062 throw (SALOME::SALOME_Exception)
2067 ::SMESH_MeshEditor::TFacetOfElem elemSet;
2068 const int noneFacet = -1;
2069 SMDS_ElemIteratorPtr volIt = myMesh_i->GetElements( elems, SMESH::VOLUME );
2070 while( volIt->more() )
2071 elemSet.insert( elemSet.end(), make_pair( volIt->next(), noneFacet ));
2073 getEditor().SplitVolumes( elemSet, int( methodFlags ));
2074 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2076 TPythonDump() << this << ".SplitVolumesIntoTetra( "
2077 << elems << ", " << methodFlags << " )";
2079 SMESH_CATCH( SMESH::throwCorbaException );
2082 //================================================================================
2084 * \brief Split hexahedra into triangular prisms
2085 * \param elems - elements to split
2086 * \param facetToSplitNormal - normal used to find a facet of hexahedron
2087 * to split into triangles
2088 * \param methodFlags - flags passing splitting method:
2089 * 1 - split the hexahedron into 2 prisms
2090 * 2 - split the hexahedron into 4 prisms
2092 //================================================================================
2094 void SMESH_MeshEditor_i::SplitHexahedraIntoPrisms( SMESH::SMESH_IDSource_ptr elems,
2095 const SMESH::PointStruct & startHexPoint,
2096 const SMESH::DirStruct& facetToSplitNormal,
2097 CORBA::Short methodFlags,
2098 CORBA::Boolean allDomains)
2099 throw (SALOME::SALOME_Exception)
2103 prepareIdSource( elems );
2105 gp_Ax1 facetNorm( gp_Pnt( startHexPoint.x,
2108 gp_Dir( facetToSplitNormal.PS.x,
2109 facetToSplitNormal.PS.y,
2110 facetToSplitNormal.PS.z ));
2111 TIDSortedElemSet elemSet;
2112 SMESH::long_array_var anElementsId = elems->GetIDs();
2113 SMDS_MeshElement::GeomFilter filter( SMDSGeom_HEXA );
2114 arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume, &filter );
2116 ::SMESH_MeshEditor::TFacetOfElem elemFacets;
2117 while ( !elemSet.empty() )
2119 getEditor().GetHexaFacetsToSplit( elemSet, facetNorm, elemFacets );
2123 ::SMESH_MeshEditor::TFacetOfElem::iterator ef = elemFacets.begin();
2124 for ( ; ef != elemFacets.end(); ++ef )
2125 elemSet.erase( ef->first );
2128 if ( methodFlags == 2 )
2129 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_4_PRISMS );
2131 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_2_PRISMS );
2133 getEditor().SplitVolumes( elemFacets, int( methodFlags ));
2134 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2136 TPythonDump() << this << ".SplitHexahedraIntoPrisms( "
2138 << startHexPoint << ", "
2139 << facetToSplitNormal<< ", "
2140 << methodFlags<< ", "
2141 << allDomains << " )";
2143 SMESH_CATCH( SMESH::throwCorbaException );
2146 //================================================================================
2148 * \brief Split bi-quadratic elements into linear ones without creation of additional nodes:
2149 * - bi-quadratic triangle will be split into 3 linear quadrangles;
2150 * - bi-quadratic quadrangle will be split into 4 linear quadrangles;
2151 * - tri-quadratic hexahedron will be split into 8 linear hexahedra.
2152 * Quadratic elements of lower dimension adjacent to the split bi-quadratic element
2153 * will be split in order to keep the mesh conformal.
2154 * \param elems - elements to split
2156 //================================================================================
2158 void SMESH_MeshEditor_i::SplitBiQuadraticIntoLinear(const SMESH::ListOfIDSources& theElems)
2159 throw (SALOME::SALOME_Exception)
2164 TIDSortedElemSet elemSet;
2165 for ( size_t i = 0; i < theElems.length(); ++i )
2167 SMESH::SMESH_IDSource_ptr elems = theElems[i].in();
2168 SMESH::SMESH_Mesh_var mesh = elems->GetMesh();
2169 if ( mesh->GetId() != myMesh_i->GetId() )
2170 THROW_SALOME_CORBA_EXCEPTION("Wrong mesh of IDSource", SALOME::BAD_PARAM);
2172 idSourceToSet( elems, getMeshDS(), elemSet, SMDSAbs_All );
2174 getEditor().SplitBiQuadraticIntoLinear( elemSet );
2176 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2178 TPythonDump() << this << ".SplitBiQuadraticIntoLinear( "
2179 << theElems << " )";
2181 SMESH_CATCH( SMESH::throwCorbaException );
2184 //=======================================================================
2187 //=======================================================================
2190 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
2191 const SMESH::long_array & IDsOfFixedNodes,
2192 CORBA::Long MaxNbOfIterations,
2193 CORBA::Double MaxAspectRatio,
2194 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2195 throw (SALOME::SALOME_Exception)
2197 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2198 MaxAspectRatio, Method, false );
2202 //=======================================================================
2203 //function : SmoothParametric
2205 //=======================================================================
2208 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
2209 const SMESH::long_array & IDsOfFixedNodes,
2210 CORBA::Long MaxNbOfIterations,
2211 CORBA::Double MaxAspectRatio,
2212 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2213 throw (SALOME::SALOME_Exception)
2215 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2216 MaxAspectRatio, Method, true );
2220 //=======================================================================
2221 //function : SmoothObject
2223 //=======================================================================
2226 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
2227 const SMESH::long_array & IDsOfFixedNodes,
2228 CORBA::Long MaxNbOfIterations,
2229 CORBA::Double MaxAspectRatio,
2230 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2231 throw (SALOME::SALOME_Exception)
2233 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2234 MaxAspectRatio, Method, false);
2238 //=======================================================================
2239 //function : SmoothParametricObject
2241 //=======================================================================
2244 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
2245 const SMESH::long_array & IDsOfFixedNodes,
2246 CORBA::Long MaxNbOfIterations,
2247 CORBA::Double MaxAspectRatio,
2248 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2249 throw (SALOME::SALOME_Exception)
2251 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2252 MaxAspectRatio, Method, true);
2256 //=============================================================================
2260 //=============================================================================
2263 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
2264 const SMESH::long_array & IDsOfFixedNodes,
2265 CORBA::Long MaxNbOfIterations,
2266 CORBA::Double MaxAspectRatio,
2267 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2269 throw (SALOME::SALOME_Exception)
2274 SMESHDS_Mesh* aMesh = getMeshDS();
2276 TIDSortedElemSet elements;
2277 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
2279 set<const SMDS_MeshNode*> fixedNodes;
2280 for ( CORBA::ULong i = 0; i < IDsOfFixedNodes.length(); i++) {
2281 CORBA::Long index = IDsOfFixedNodes[i];
2282 const SMDS_MeshNode * node = aMesh->FindNode(index);
2284 fixedNodes.insert( node );
2286 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
2287 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
2288 method = ::SMESH_MeshEditor::CENTROIDAL;
2290 getEditor().Smooth(elements, fixedNodes, method,
2291 MaxNbOfIterations, MaxAspectRatio, IsParametric );
2293 declareMeshModified( /*isReComputeSafe=*/true ); // does not prevent re-compute
2295 // Update Python script
2296 TPythonDump() << "isDone = " << this << "."
2297 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
2298 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
2299 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2300 << "SMESH.SMESH_MeshEditor."
2301 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2302 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2306 SMESH_CATCH( SMESH::throwCorbaException );
2310 //=============================================================================
2314 //=============================================================================
2317 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
2318 const SMESH::long_array & IDsOfFixedNodes,
2319 CORBA::Long MaxNbOfIterations,
2320 CORBA::Double MaxAspectRatio,
2321 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2323 throw (SALOME::SALOME_Exception)
2328 TPythonDump aTPythonDump; // suppress dump in smooth()
2330 prepareIdSource( theObject );
2331 SMESH::long_array_var anElementsId = theObject->GetIDs();
2332 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
2333 MaxAspectRatio, Method, IsParametric);
2335 // Update Python script
2336 aTPythonDump << "isDone = " << this << "."
2337 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
2338 << theObject << ", " << IDsOfFixedNodes << ", "
2339 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2340 << "SMESH.SMESH_MeshEditor."
2341 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2342 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2346 SMESH_CATCH( SMESH::throwCorbaException );
2350 //=============================================================================
2354 //=============================================================================
2356 void SMESH_MeshEditor_i::RenumberNodes()
2357 throw (SALOME::SALOME_Exception)
2360 // Update Python script
2361 TPythonDump() << this << ".RenumberNodes()";
2363 getMeshDS()->Renumber( true );
2365 SMESH_CATCH( SMESH::throwCorbaException );
2368 //=============================================================================
2372 //=============================================================================
2374 void SMESH_MeshEditor_i::RenumberElements()
2375 throw (SALOME::SALOME_Exception)
2378 // Update Python script
2379 TPythonDump() << this << ".RenumberElements()";
2381 getMeshDS()->Renumber( false );
2383 SMESH_CATCH( SMESH::throwCorbaException );
2386 //=======================================================================
2388 * \brief Return groups by their IDs
2390 //=======================================================================
2392 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
2393 throw (SALOME::SALOME_Exception)
2398 myMesh_i->CreateGroupServants();
2399 return myMesh_i->GetGroups( *groupIDs );
2401 SMESH_CATCH( SMESH::throwCorbaException );
2405 //=======================================================================
2406 //function : RotationSweepObjects
2408 //=======================================================================
2410 SMESH::ListOfGroups*
2411 SMESH_MeshEditor_i::RotationSweepObjects(const SMESH::ListOfIDSources & theNodes,
2412 const SMESH::ListOfIDSources & theEdges,
2413 const SMESH::ListOfIDSources & theFaces,
2414 const SMESH::AxisStruct & theAxis,
2415 CORBA::Double theAngleInRadians,
2416 CORBA::Long theNbOfSteps,
2417 CORBA::Double theTolerance,
2418 const bool theMakeGroups)
2419 throw (SALOME::SALOME_Exception)
2424 TIDSortedElemSet elemsNodes[2];
2425 for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) {
2426 SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE );
2427 while ( nIt->more() ) elemsNodes[1].insert( nIt->next() );
2429 for ( int i = 0, nb = theEdges.length(); i < nb; ++i )
2430 idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge );
2431 for ( int i = 0, nb = theFaces.length(); i < nb; ++i )
2432 idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face );
2434 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2435 bool makeWalls=true;
2436 if ( myIsPreviewMode )
2438 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2439 TPreviewMesh * tmpMesh = getPreviewMesh();
2440 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2441 tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid );
2442 workElements = & copyElements[0];
2443 //makeWalls = false; -- faces are needed for preview
2446 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2448 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
2449 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
2451 ::SMESH_MeshEditor::PGroupIDs groupIds =
2452 getEditor().RotationSweep (workElements, Ax1, theAngleInRadians,
2453 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
2455 SMESH::ListOfGroups * aGroups = theMakeGroups ? getGroups( groupIds.get()) : 0;
2457 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2459 if ( !myIsPreviewMode )
2461 dumpGroupsList( aPythonDump, aGroups );
2462 aPythonDump << this<< ".RotationSweepObjects( "
2467 << TVar( theAngleInRadians ) << ", "
2468 << TVar( theNbOfSteps ) << ", "
2469 << TVar( theTolerance ) << ", "
2470 << theMakeGroups << " )";
2474 getPreviewMesh()->Remove( SMDSAbs_Volume );
2477 return aGroups ? aGroups : new SMESH::ListOfGroups;
2479 SMESH_CATCH( SMESH::throwCorbaException );
2483 namespace MeshEditor_I
2486 * \brief Structure used to pass extrusion parameters to ::SMESH_MeshEditor
2488 struct ExtrusionParams : public ::SMESH_MeshEditor::ExtrusParam
2490 bool myIsExtrusionByNormal;
2492 static int makeFlags( CORBA::Boolean MakeGroups,
2493 CORBA::Boolean LinearVariation = false,
2494 CORBA::Boolean ByAverageNormal = false,
2495 CORBA::Boolean UseInputElemsOnly = false,
2496 CORBA::Long Flags = 0,
2497 CORBA::Boolean MakeBoundary = true )
2499 if ( MakeGroups ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS;
2500 if ( ByAverageNormal ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BY_AVG_NORMAL;
2501 if ( UseInputElemsOnly) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY;
2502 if ( LinearVariation ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_SCALE_LINEAR_VARIATION;
2503 if ( MakeBoundary ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BOUNDARY;
2507 ExtrusionParams(const SMESH::DirStruct & theDir,
2508 CORBA::Long theNbOfSteps,
2509 const SMESH::double_array & theScaleFactors,
2510 CORBA::Boolean theLinearVariation,
2511 const SMESH::double_array & theBasePoint,
2512 CORBA::Boolean theMakeGroups):
2513 ::SMESH_MeshEditor::ExtrusParam ( gp_Vec( theDir.PS.x,
2517 toList( theScaleFactors ),
2518 TBasePoint( theBasePoint ),
2519 makeFlags( theMakeGroups, theLinearVariation )),
2520 myIsExtrusionByNormal( false )
2524 ExtrusionParams(const SMESH::DirStruct & theDir,
2525 CORBA::Long theNbOfSteps,
2526 CORBA::Boolean theMakeGroups,
2527 CORBA::Long theExtrFlags,
2528 CORBA::Double theSewTolerance):
2529 ::SMESH_MeshEditor::ExtrusParam ( gp_Vec( theDir.PS.x,
2533 std::list<double>(),
2535 makeFlags( theMakeGroups, false, false, false,
2536 theExtrFlags, false ),
2538 myIsExtrusionByNormal( false )
2541 // params for extrusion by normal
2542 ExtrusionParams(CORBA::Double theStepSize,
2543 CORBA::Long theNbOfSteps,
2544 CORBA::Short theDim,
2545 CORBA::Boolean theByAverageNormal,
2546 CORBA::Boolean theUseInputElemsOnly,
2547 CORBA::Boolean theMakeGroups ):
2548 ::SMESH_MeshEditor::ExtrusParam ( theStepSize,
2550 makeFlags( theMakeGroups, false,
2551 theByAverageNormal, theUseInputElemsOnly ),
2553 myIsExtrusionByNormal( true )
2559 Flags() &= ~(::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS);
2564 static std::list<double> toList( const SMESH::double_array & theScaleFactors )
2566 std::list<double> scales;
2567 for ( CORBA::ULong i = 0; i < theScaleFactors.length(); ++i )
2568 scales.push_back( theScaleFactors[i] );
2572 // structure used to convert SMESH::double_array to gp_XYZ*
2576 TBasePoint( const SMESH::double_array & theBasePoint )
2579 if ( theBasePoint.length() == 3 )
2581 p.SetCoord( theBasePoint[0], theBasePoint[1], theBasePoint[2] );
2585 operator const gp_XYZ*() const { return pp; }
2590 //=======================================================================
2592 * \brief Generate dim+1 elements by extrusion of elements along vector
2593 * \param [in] edges - edges to extrude: a list including groups, sub-meshes or a mesh
2594 * \param [in] faces - faces to extrude: a list including groups, sub-meshes or a mesh
2595 * \param [in] nodes - nodes to extrude: a list including groups, sub-meshes or a mesh
2596 * \param [in] stepVector - vector giving direction and distance of an extrusion step
2597 * \param [in] nbOfSteps - number of elements to generate from one element
2598 * \param [in] toMakeGroups - if true, new elements will be included into new groups
2599 * corresponding to groups the input elements included in.
2600 * \return ListOfGroups - new groups craeted if \a toMakeGroups is true
2602 //=======================================================================
2604 SMESH::ListOfGroups*
2605 SMESH_MeshEditor_i::ExtrusionSweepObjects(const SMESH::ListOfIDSources & theNodes,
2606 const SMESH::ListOfIDSources & theEdges,
2607 const SMESH::ListOfIDSources & theFaces,
2608 const SMESH::DirStruct & theStepVector,
2609 CORBA::Long theNbOfSteps,
2610 const SMESH::double_array & theScaleFactors,
2611 CORBA::Boolean theLinearVariation,
2612 const SMESH::double_array & theBasePoint,
2613 CORBA::Boolean theToMakeGroups)
2614 throw (SALOME::SALOME_Exception)
2619 ExtrusionParams params( theStepVector, theNbOfSteps, theScaleFactors,
2620 theLinearVariation, theBasePoint, theToMakeGroups );
2622 TIDSortedElemSet elemsNodes[2];
2623 for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) {
2624 SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE );
2625 while ( nIt->more() ) elemsNodes[1].insert( nIt->next() );
2627 for ( int i = 0, nb = theEdges.length(); i < nb; ++i )
2628 idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge );
2629 for ( int i = 0, nb = theFaces.length(); i < nb; ++i )
2630 idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face );
2632 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2633 SMDSAbs_ElementType previewType = SMDSAbs_All; //SMDSAbs_Face;
2634 if ( myIsPreviewMode )
2636 // if ( (*elemsNodes.begin())->GetType() == SMDSAbs_Node )
2637 // previewType = SMDSAbs_Edge;
2639 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2640 TPreviewMesh * tmpMesh = getPreviewMesh( previewType );
2641 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2642 tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid );
2643 workElements = & copyElements[0];
2645 params.SetNoGroups();
2647 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2649 ::SMESH_MeshEditor::TTElemOfElemListMap aHistory;
2650 ::SMESH_MeshEditor::PGroupIDs groupIds =
2651 getEditor().ExtrusionSweep( workElements, params, aHistory );
2653 SMESH::ListOfGroups * aGroups = theToMakeGroups ? getGroups( groupIds.get()) : 0;
2655 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2657 if ( !myIsPreviewMode )
2659 dumpGroupsList( aPythonDump, aGroups );
2660 aPythonDump << this<< ".ExtrusionSweepObjects( "
2664 << theStepVector << ", "
2665 << TVar( theNbOfSteps ) << ", "
2666 << theToMakeGroups << " )";
2670 getPreviewMesh( previewType )->Remove( SMDSAbs_Volume );
2673 return aGroups ? aGroups : new SMESH::ListOfGroups;
2675 SMESH_CATCH( SMESH::throwCorbaException );
2679 //=======================================================================
2680 //function : ExtrusionByNormal
2682 //=======================================================================
2684 SMESH::ListOfGroups*
2685 SMESH_MeshEditor_i::ExtrusionByNormal(const SMESH::ListOfIDSources& objects,
2686 CORBA::Double stepSize,
2687 CORBA::Long nbOfSteps,
2688 CORBA::Boolean byAverageNormal,
2689 CORBA::Boolean useInputElemsOnly,
2690 CORBA::Boolean makeGroups,
2692 throw (SALOME::SALOME_Exception)
2697 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2699 ExtrusionParams params( stepSize, nbOfSteps, dim,
2700 byAverageNormal, useInputElemsOnly, makeGroups );
2702 SMDSAbs_ElementType elemType = ( dim == 1 ? SMDSAbs_Edge : SMDSAbs_Face );
2703 if ( objects.length() > 0 && !SMESH::DownCast<SMESH_Mesh_i*>( objects[0] ))
2705 SMESH::array_of_ElementType_var elemTypes = objects[0]->GetTypes();
2706 if (( elemTypes->length() == 1 ) &&
2707 ( elemTypes[0] == SMESH::EDGE || elemTypes[0] == SMESH::FACE ))
2708 elemType = ( SMDSAbs_ElementType ) elemTypes[0];
2711 TIDSortedElemSet elemsNodes[2];
2712 for ( int i = 0, nb = objects.length(); i < nb; ++i )
2713 idSourceToSet( objects[i], getMeshDS(), elemsNodes[0], elemType );
2715 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2716 SMDSAbs_ElementType previewType = SMDSAbs_Face;
2717 if ( myIsPreviewMode )
2719 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2720 TPreviewMesh * tmpMesh = getPreviewMesh( previewType );
2721 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2722 workElements = & copyElements[0];
2724 params.SetNoGroups();
2727 ::SMESH_MeshEditor::TTElemOfElemListMap aHistory;
2728 ::SMESH_MeshEditor::PGroupIDs groupIds =
2729 getEditor().ExtrusionSweep( workElements, params, aHistory );
2731 SMESH::ListOfGroups * aGroups = makeGroups ? getGroups( groupIds.get()) : 0;
2733 if (!myIsPreviewMode) {
2734 dumpGroupsList(aPythonDump, aGroups);
2735 aPythonDump << this << ".ExtrusionByNormal( " << objects
2736 << ", " << TVar( stepSize )
2737 << ", " << TVar( nbOfSteps )
2738 << ", " << byAverageNormal
2739 << ", " << useInputElemsOnly
2740 << ", " << makeGroups
2746 getPreviewMesh( previewType )->Remove( SMDSAbs_Volume );
2749 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2751 return aGroups ? aGroups : new SMESH::ListOfGroups;
2753 SMESH_CATCH( SMESH::throwCorbaException );
2757 //=======================================================================
2758 //function : AdvancedExtrusion
2760 //=======================================================================
2762 SMESH::ListOfGroups*
2763 SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2764 const SMESH::DirStruct & theStepVector,
2765 CORBA::Long theNbOfSteps,
2766 CORBA::Long theExtrFlags,
2767 CORBA::Double theSewTolerance,
2768 CORBA::Boolean theMakeGroups)
2769 throw (SALOME::SALOME_Exception)
2774 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2776 ExtrusionParams params( theStepVector, theNbOfSteps, theMakeGroups,
2777 theExtrFlags, theSewTolerance );
2779 TIDSortedElemSet elemsNodes[2];
2780 arrayToSet( theIDsOfElements, getMeshDS(), elemsNodes[0] );
2782 ::SMESH_MeshEditor::TTElemOfElemListMap aHistory;
2783 ::SMESH_MeshEditor::PGroupIDs groupIds =
2784 getEditor().ExtrusionSweep( elemsNodes, params, aHistory );
2786 SMESH::ListOfGroups * aGroups = theMakeGroups ? getGroups( groupIds.get()) : 0;
2788 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2790 if ( !myIsPreviewMode ) {
2791 dumpGroupsList(aPythonDump, aGroups);
2792 aPythonDump << this << ".AdvancedExtrusion( "
2793 << theIDsOfElements << ", "
2794 << theStepVector << ", "
2795 << theNbOfSteps << ", "
2796 << theExtrFlags << ", "
2797 << theSewTolerance << ", "
2798 << theMakeGroups << " )";
2802 getPreviewMesh()->Remove( SMDSAbs_Volume );
2805 return aGroups ? aGroups : new SMESH::ListOfGroups;
2807 SMESH_CATCH( SMESH::throwCorbaException );
2811 //================================================================================
2813 * \brief Convert extrusion error to IDL enum
2815 //================================================================================
2819 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
2821 SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( ::SMESH_MeshEditor::Extrusion_Error e )
2825 RETCASE( EXTR_NO_ELEMENTS );
2826 RETCASE( EXTR_PATH_NOT_EDGE );
2827 RETCASE( EXTR_BAD_PATH_SHAPE );
2828 RETCASE( EXTR_BAD_STARTING_NODE );
2829 RETCASE( EXTR_BAD_ANGLES_NUMBER );
2830 RETCASE( EXTR_CANT_GET_TANGENT );
2832 return SMESH::SMESH_MeshEditor::EXTR_OK;
2836 //=======================================================================
2837 //function : extrusionAlongPath
2839 //=======================================================================
2840 SMESH::ListOfGroups*
2841 SMESH_MeshEditor_i::ExtrusionAlongPathObjects(const SMESH::ListOfIDSources & theNodes,
2842 const SMESH::ListOfIDSources & theEdges,
2843 const SMESH::ListOfIDSources & theFaces,
2844 SMESH::SMESH_IDSource_ptr thePathMesh,
2845 GEOM::GEOM_Object_ptr thePathShape,
2846 CORBA::Long theNodeStart,
2847 CORBA::Boolean theHasAngles,
2848 const SMESH::double_array & theAngles,
2849 CORBA::Boolean theLinearVariation,
2850 CORBA::Boolean theHasRefPoint,
2851 const SMESH::PointStruct & theRefPoint,
2853 SMESH::SMESH_MeshEditor::Extrusion_Error& theError)
2854 throw (SALOME::SALOME_Exception)
2859 SMESH::ListOfGroups_var aGroups = new SMESH::ListOfGroups;
2861 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2862 if ( thePathMesh->_is_nil() )
2863 return aGroups._retn();
2866 SMESH_subMesh* aSubMesh = 0;
2867 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2868 if ( thePathShape->_is_nil() )
2870 // thePathMesh should be either a sub-mesh or a mesh with 1D elements only
2871 if ( SMESH_subMesh_i* sm = SMESH::DownCast<SMESH_subMesh_i*>( thePathMesh ))
2873 SMESH::SMESH_Mesh_var mesh = thePathMesh->GetMesh();
2874 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
2875 if ( !aMeshImp ) return aGroups._retn();
2876 aSubMesh = aMeshImp->GetImpl().GetSubMeshContaining( sm->GetId() );
2877 if ( !aSubMesh ) return aGroups._retn();
2879 else if ( !aMeshImp ||
2880 aMeshImp->NbEdges() != aMeshImp->NbElements() )
2882 return aGroups._retn();
2887 if ( !aMeshImp ) return aGroups._retn();
2888 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2889 aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2890 if ( !aSubMesh /*|| !aSubMesh->GetSubMeshDS()*/ )
2891 return aGroups._retn();
2894 SMDS_MeshNode* nodeStart =
2895 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
2897 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2898 return aGroups._retn();
2901 TIDSortedElemSet elemsNodes[2];
2902 for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) {
2903 SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE );
2904 while ( nIt->more() ) elemsNodes[1].insert( nIt->next() );
2906 for ( int i = 0, nb = theEdges.length(); i < nb; ++i )
2907 idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge );
2908 for ( int i = 0, nb = theFaces.length(); i < nb; ++i )
2909 idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face );
2911 list<double> angles;
2912 for ( CORBA::ULong i = 0; i < theAngles.length(); i++ ) {
2913 angles.push_back( theAngles[i] );
2916 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
2918 int nbOldGroups = myMesh->NbGroup();
2920 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2921 if ( myIsPreviewMode )
2923 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2924 TPreviewMesh * tmpMesh = getPreviewMesh();
2925 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2926 tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid );
2927 workElements = & copyElements[0];
2928 theMakeGroups = false;
2931 ::SMESH_MeshEditor::Extrusion_Error error;
2933 error = getEditor().ExtrusionAlongTrack( workElements, &(aMeshImp->GetImpl()), nodeStart,
2934 theHasAngles, angles, theLinearVariation,
2935 theHasRefPoint, refPnt, theMakeGroups );
2937 error = getEditor().ExtrusionAlongTrack( workElements, aSubMesh, nodeStart,
2938 theHasAngles, angles, theLinearVariation,
2939 theHasRefPoint, refPnt, theMakeGroups );
2941 declareMeshModified( /*isReComputeSafe=*/true );
2942 theError = convExtrError( error );
2944 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2945 if ( theMakeGroups ) {
2946 list<int> groupIDs = myMesh->GetGroupIds();
2947 list<int>::iterator newBegin = groupIDs.begin();
2948 std::advance( newBegin, nbOldGroups ); // skip old groups
2949 groupIDs.erase( groupIDs.begin(), newBegin );
2950 aGroups = getGroups( & groupIDs );
2951 if ( ! &aGroups.in() ) aGroups = new SMESH::ListOfGroups;
2954 if ( !myIsPreviewMode ) {
2955 aPythonDump << "(" << aGroups << ", error) = "
2956 << this << ".ExtrusionAlongPathObjects( "
2960 << thePathMesh << ", "
2961 << thePathShape << ", "
2962 << theNodeStart << ", "
2963 << theHasAngles << ", "
2964 << TVar( theAngles ) << ", "
2965 << theLinearVariation << ", "
2966 << theHasRefPoint << ", "
2967 << "SMESH.PointStruct( "
2968 << TVar( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2969 << TVar( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2970 << TVar( theHasRefPoint ? theRefPoint.z : 0 ) << " ), "
2971 << theMakeGroups << " )";
2975 getPreviewMesh()->Remove( SMDSAbs_Volume );
2978 return aGroups._retn();
2980 SMESH_CATCH( SMESH::throwCorbaException );
2984 //================================================================================
2986 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
2987 * of given angles along path steps
2988 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
2989 * which proceeds the extrusion
2990 * \param PathShape is shape(edge); as the mesh can be complex, the edge
2991 * is used to define the sub-mesh for the path
2993 //================================================================================
2995 SMESH::double_array*
2996 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
2997 GEOM::GEOM_Object_ptr thePathShape,
2998 const SMESH::double_array & theAngles)
3000 SMESH::double_array_var aResult = new SMESH::double_array();
3001 int nbAngles = theAngles.length();
3002 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
3004 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3005 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3006 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3007 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
3008 return aResult._retn();
3009 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
3010 if ( nbSteps == nbAngles )
3012 aResult.inout() = theAngles;
3016 aResult->length( nbSteps );
3017 double rAn2St = double( nbAngles ) / double( nbSteps );
3018 double angPrev = 0, angle;
3019 for ( int iSt = 0; iSt < nbSteps; ++iSt )
3021 double angCur = rAn2St * ( iSt+1 );
3022 double angCurFloor = floor( angCur );
3023 double angPrevFloor = floor( angPrev );
3024 if ( angPrevFloor == angCurFloor )
3025 angle = rAn2St * theAngles[ int( angCurFloor ) ];
3028 int iP = int( angPrevFloor );
3029 double angPrevCeil = ceil(angPrev);
3030 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
3032 int iC = int( angCurFloor );
3033 if ( iC < nbAngles )
3034 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
3036 iP = int( angPrevCeil );
3038 angle += theAngles[ iC ];
3040 aResult[ iSt ] = angle;
3045 // Update Python script
3046 TPythonDump() << "rotAngles = " << theAngles;
3047 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
3048 << thePathMesh << ", "
3049 << thePathShape << ", "
3052 return aResult._retn();
3055 //=======================================================================
3058 //=======================================================================
3060 SMESH::ListOfGroups*
3061 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
3062 const SMESH::AxisStruct & theAxis,
3063 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3064 CORBA::Boolean theCopy,
3066 ::SMESH_Mesh* theTargetMesh)
3067 throw (SALOME::SALOME_Exception)
3072 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3073 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3075 if ( theTargetMesh )
3079 switch ( theMirrorType ) {
3080 case SMESH::SMESH_MeshEditor::POINT:
3081 aTrsf.SetMirror( P );
3083 case SMESH::SMESH_MeshEditor::AXIS:
3084 aTrsf.SetMirror( gp_Ax1( P, V ));
3087 aTrsf.SetMirror( gp_Ax2( P, V ));
3090 TIDSortedElemSet copyElements;
3091 TIDSortedElemSet* workElements = & theElements;
3093 if ( myIsPreviewMode )
3095 TPreviewMesh * tmpMesh = getPreviewMesh();
3096 tmpMesh->Copy( theElements, copyElements);
3097 if ( !theCopy && !theTargetMesh )
3099 TIDSortedElemSet elemsAround, elemsAroundCopy;
3100 getElementsAround( theElements, getMeshDS(), elemsAround );
3101 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3103 workElements = & copyElements;
3104 theMakeGroups = false;
3107 ::SMESH_MeshEditor::PGroupIDs groupIds =
3108 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3110 if ( theCopy && !myIsPreviewMode)
3112 if ( theTargetMesh )
3114 theTargetMesh->GetMeshDS()->Modified();
3118 declareMeshModified( /*isReComputeSafe=*/false );
3121 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3123 SMESH_CATCH( SMESH::throwCorbaException );
3127 //=======================================================================
3130 //=======================================================================
3132 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3133 const SMESH::AxisStruct & theAxis,
3134 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3135 CORBA::Boolean theCopy)
3136 throw (SALOME::SALOME_Exception)
3138 if ( !myIsPreviewMode ) {
3139 TPythonDump() << this << ".Mirror( "
3140 << theIDsOfElements << ", "
3142 << mirrorTypeName(theMirrorType) << ", "
3145 if ( theIDsOfElements.length() > 0 )
3147 TIDSortedElemSet elements;
3148 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3149 mirror(elements, theAxis, theMirrorType, theCopy, false);
3154 //=======================================================================
3155 //function : MirrorObject
3157 //=======================================================================
3159 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3160 const SMESH::AxisStruct & theAxis,
3161 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3162 CORBA::Boolean theCopy)
3163 throw (SALOME::SALOME_Exception)
3165 if ( !myIsPreviewMode ) {
3166 TPythonDump() << this << ".MirrorObject( "
3167 << theObject << ", "
3169 << mirrorTypeName(theMirrorType) << ", "
3172 TIDSortedElemSet elements;
3174 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3176 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3177 mirror(elements, theAxis, theMirrorType, theCopy, false);
3180 //=======================================================================
3181 //function : MirrorMakeGroups
3183 //=======================================================================
3185 SMESH::ListOfGroups*
3186 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3187 const SMESH::AxisStruct& theMirror,
3188 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3189 throw (SALOME::SALOME_Exception)
3191 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3193 SMESH::ListOfGroups * aGroups = 0;
3194 if ( theIDsOfElements.length() > 0 )
3196 TIDSortedElemSet elements;
3197 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3198 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3200 if (!myIsPreviewMode) {
3201 dumpGroupsList(aPythonDump, aGroups);
3202 aPythonDump << this << ".MirrorMakeGroups( "
3203 << theIDsOfElements << ", "
3204 << theMirror << ", "
3205 << mirrorTypeName(theMirrorType) << " )";
3210 //=======================================================================
3211 //function : MirrorObjectMakeGroups
3213 //=======================================================================
3215 SMESH::ListOfGroups*
3216 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3217 const SMESH::AxisStruct& theMirror,
3218 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3219 throw (SALOME::SALOME_Exception)
3221 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3223 SMESH::ListOfGroups * aGroups = 0;
3224 TIDSortedElemSet elements;
3225 if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3226 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3228 if (!myIsPreviewMode)
3230 dumpGroupsList(aPythonDump,aGroups);
3231 aPythonDump << this << ".MirrorObjectMakeGroups( "
3232 << theObject << ", "
3233 << theMirror << ", "
3234 << mirrorTypeName(theMirrorType) << " )";
3239 //=======================================================================
3240 //function : MirrorMakeMesh
3242 //=======================================================================
3244 SMESH::SMESH_Mesh_ptr
3245 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
3246 const SMESH::AxisStruct& theMirror,
3247 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3248 CORBA::Boolean theCopyGroups,
3249 const char* theMeshName)
3250 throw (SALOME::SALOME_Exception)
3252 SMESH_Mesh_i* mesh_i;
3253 SMESH::SMESH_Mesh_var mesh;
3254 { // open new scope to dump "MakeMesh" command
3255 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3257 TPythonDump pydump; // to prevent dump at mesh creation
3259 mesh = makeMesh( theMeshName );
3260 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3261 if (mesh_i && theIDsOfElements.length() > 0 )
3263 TIDSortedElemSet elements;
3264 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3265 mirror(elements, theMirror, theMirrorType,
3266 false, theCopyGroups, & mesh_i->GetImpl());
3267 mesh_i->CreateGroupServants();
3270 if (!myIsPreviewMode) {
3271 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
3272 << theIDsOfElements << ", "
3273 << theMirror << ", "
3274 << mirrorTypeName(theMirrorType) << ", "
3275 << theCopyGroups << ", '"
3276 << theMeshName << "' )";
3281 if (!myIsPreviewMode && mesh_i)
3282 mesh_i->GetGroups();
3284 return mesh._retn();
3287 //=======================================================================
3288 //function : MirrorObjectMakeMesh
3290 //=======================================================================
3292 SMESH::SMESH_Mesh_ptr
3293 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3294 const SMESH::AxisStruct& theMirror,
3295 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3296 CORBA::Boolean theCopyGroups,
3297 const char* theMeshName)
3298 throw (SALOME::SALOME_Exception)
3300 SMESH_Mesh_i* mesh_i;
3301 SMESH::SMESH_Mesh_var mesh;
3302 { // open new scope to dump "MakeMesh" command
3303 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3305 TPythonDump pydump; // to prevent dump at mesh creation
3307 mesh = makeMesh( theMeshName );
3308 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3309 TIDSortedElemSet elements;
3311 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3313 mirror(elements, theMirror, theMirrorType,
3314 false, theCopyGroups, & mesh_i->GetImpl());
3315 mesh_i->CreateGroupServants();
3317 if (!myIsPreviewMode) {
3318 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
3319 << theObject << ", "
3320 << theMirror << ", "
3321 << mirrorTypeName(theMirrorType) << ", "
3322 << theCopyGroups << ", '"
3323 << theMeshName << "' )";
3328 if (!myIsPreviewMode && mesh_i)
3329 mesh_i->GetGroups();
3331 return mesh._retn();
3334 //=======================================================================
3335 //function : translate
3337 //=======================================================================
3339 SMESH::ListOfGroups*
3340 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
3341 const SMESH::DirStruct & theVector,
3342 CORBA::Boolean theCopy,
3344 ::SMESH_Mesh* theTargetMesh)
3345 throw (SALOME::SALOME_Exception)
3350 if ( theTargetMesh )
3354 const SMESH::PointStruct * P = &theVector.PS;
3355 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
3357 TIDSortedElemSet copyElements;
3358 TIDSortedElemSet* workElements = &theElements;
3360 if ( myIsPreviewMode )
3362 TPreviewMesh * tmpMesh = getPreviewMesh();
3363 tmpMesh->Copy( theElements, copyElements);
3364 if ( !theCopy && !theTargetMesh )
3366 TIDSortedElemSet elemsAround, elemsAroundCopy;
3367 getElementsAround( theElements, getMeshDS(), elemsAround );
3368 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3370 workElements = & copyElements;
3371 theMakeGroups = false;
3374 ::SMESH_MeshEditor::PGroupIDs groupIds =
3375 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3377 if ( theCopy && !myIsPreviewMode )
3379 if ( theTargetMesh )
3381 theTargetMesh->GetMeshDS()->Modified();
3385 declareMeshModified( /*isReComputeSafe=*/false );
3389 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3391 SMESH_CATCH( SMESH::throwCorbaException );
3395 //=======================================================================
3396 //function : Translate
3398 //=======================================================================
3400 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
3401 const SMESH::DirStruct & theVector,
3402 CORBA::Boolean theCopy)
3403 throw (SALOME::SALOME_Exception)
3405 if (!myIsPreviewMode) {
3406 TPythonDump() << this << ".Translate( "
3407 << theIDsOfElements << ", "
3408 << theVector << ", "
3411 if (theIDsOfElements.length()) {
3412 TIDSortedElemSet elements;
3413 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3414 translate(elements, theVector, theCopy, false);
3418 //=======================================================================
3419 //function : TranslateObject
3421 //=======================================================================
3423 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
3424 const SMESH::DirStruct & theVector,
3425 CORBA::Boolean theCopy)
3426 throw (SALOME::SALOME_Exception)
3428 if (!myIsPreviewMode) {
3429 TPythonDump() << this << ".TranslateObject( "
3430 << theObject << ", "
3431 << theVector << ", "
3434 TIDSortedElemSet elements;
3436 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3438 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3439 translate(elements, theVector, theCopy, false);
3442 //=======================================================================
3443 //function : TranslateMakeGroups
3445 //=======================================================================
3447 SMESH::ListOfGroups*
3448 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
3449 const SMESH::DirStruct& theVector)
3450 throw (SALOME::SALOME_Exception)
3452 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3454 SMESH::ListOfGroups * aGroups = 0;
3455 if (theIDsOfElements.length()) {
3456 TIDSortedElemSet elements;
3457 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3458 aGroups = translate(elements,theVector,true,true);
3460 if (!myIsPreviewMode) {
3461 dumpGroupsList(aPythonDump, aGroups);
3462 aPythonDump << this << ".TranslateMakeGroups( "
3463 << theIDsOfElements << ", "
3464 << theVector << " )";
3469 //=======================================================================
3470 //function : TranslateObjectMakeGroups
3472 //=======================================================================
3474 SMESH::ListOfGroups*
3475 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3476 const SMESH::DirStruct& theVector)
3477 throw (SALOME::SALOME_Exception)
3479 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3481 SMESH::ListOfGroups * aGroups = 0;
3482 TIDSortedElemSet elements;
3483 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3484 aGroups = translate(elements, theVector, true, true);
3486 if (!myIsPreviewMode) {
3487 dumpGroupsList(aPythonDump, aGroups);
3488 aPythonDump << this << ".TranslateObjectMakeGroups( "
3489 << theObject << ", "
3490 << theVector << " )";
3495 //=======================================================================
3496 //function : TranslateMakeMesh
3498 //=======================================================================
3500 SMESH::SMESH_Mesh_ptr
3501 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
3502 const SMESH::DirStruct& theVector,
3503 CORBA::Boolean theCopyGroups,
3504 const char* theMeshName)
3505 throw (SALOME::SALOME_Exception)
3507 SMESH_Mesh_i* mesh_i;
3508 SMESH::SMESH_Mesh_var mesh;
3510 { // open new scope to dump "MakeMesh" command
3511 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3513 TPythonDump pydump; // to prevent dump at mesh creation
3515 mesh = makeMesh( theMeshName );
3516 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3518 if ( mesh_i && theIDsOfElements.length() )
3520 TIDSortedElemSet elements;
3521 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3522 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
3523 mesh_i->CreateGroupServants();
3526 if ( !myIsPreviewMode ) {
3527 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
3528 << theIDsOfElements << ", "
3529 << theVector << ", "
3530 << theCopyGroups << ", '"
3531 << theMeshName << "' )";
3536 if (!myIsPreviewMode && mesh_i)
3537 mesh_i->GetGroups();
3539 return mesh._retn();
3542 //=======================================================================
3543 //function : TranslateObjectMakeMesh
3545 //=======================================================================
3547 SMESH::SMESH_Mesh_ptr
3548 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3549 const SMESH::DirStruct& theVector,
3550 CORBA::Boolean theCopyGroups,
3551 const char* theMeshName)
3552 throw (SALOME::SALOME_Exception)
3555 SMESH_Mesh_i* mesh_i;
3556 SMESH::SMESH_Mesh_var mesh;
3557 { // open new scope to dump "MakeMesh" command
3558 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3560 TPythonDump pydump; // to prevent dump at mesh creation
3561 mesh = makeMesh( theMeshName );
3562 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3564 TIDSortedElemSet elements;
3566 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3568 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
3569 mesh_i->CreateGroupServants();
3571 if ( !myIsPreviewMode ) {
3572 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
3573 << theObject << ", "
3574 << theVector << ", "
3575 << theCopyGroups << ", '"
3576 << theMeshName << "' )";
3581 if (!myIsPreviewMode && mesh_i)
3582 mesh_i->GetGroups();
3584 return mesh._retn();
3586 SMESH_CATCH( SMESH::throwCorbaException );
3590 //=======================================================================
3593 //=======================================================================
3595 SMESH::ListOfGroups*
3596 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
3597 const SMESH::AxisStruct & theAxis,
3598 CORBA::Double theAngle,
3599 CORBA::Boolean theCopy,
3601 ::SMESH_Mesh* theTargetMesh)
3602 throw (SALOME::SALOME_Exception)
3607 if ( theTargetMesh )
3610 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3611 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3614 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
3616 TIDSortedElemSet copyElements;
3617 TIDSortedElemSet* workElements = &theElements;
3618 if ( myIsPreviewMode ) {
3619 TPreviewMesh * tmpMesh = getPreviewMesh();
3620 tmpMesh->Copy( theElements, copyElements );
3621 if ( !theCopy && !theTargetMesh )
3623 TIDSortedElemSet elemsAround, elemsAroundCopy;
3624 getElementsAround( theElements, getMeshDS(), elemsAround );
3625 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3627 workElements = ©Elements;
3628 theMakeGroups = false;
3631 ::SMESH_MeshEditor::PGroupIDs groupIds =
3632 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3634 if ( theCopy && !myIsPreviewMode)
3636 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
3637 else declareMeshModified( /*isReComputeSafe=*/false );
3640 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3642 SMESH_CATCH( SMESH::throwCorbaException );
3646 //=======================================================================
3649 //=======================================================================
3651 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
3652 const SMESH::AxisStruct & theAxis,
3653 CORBA::Double theAngle,
3654 CORBA::Boolean theCopy)
3655 throw (SALOME::SALOME_Exception)
3657 if (!myIsPreviewMode) {
3658 TPythonDump() << this << ".Rotate( "
3659 << theIDsOfElements << ", "
3661 << TVar( theAngle ) << ", "
3664 if (theIDsOfElements.length() > 0)
3666 TIDSortedElemSet elements;
3667 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3668 rotate(elements,theAxis,theAngle,theCopy,false);
3672 //=======================================================================
3673 //function : RotateObject
3675 //=======================================================================
3677 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
3678 const SMESH::AxisStruct & theAxis,
3679 CORBA::Double theAngle,
3680 CORBA::Boolean theCopy)
3681 throw (SALOME::SALOME_Exception)
3683 if ( !myIsPreviewMode ) {
3684 TPythonDump() << this << ".RotateObject( "
3685 << theObject << ", "
3687 << TVar( theAngle ) << ", "
3690 TIDSortedElemSet elements;
3691 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3692 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3693 rotate(elements,theAxis,theAngle,theCopy,false);
3696 //=======================================================================
3697 //function : RotateMakeGroups
3699 //=======================================================================
3701 SMESH::ListOfGroups*
3702 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
3703 const SMESH::AxisStruct& theAxis,
3704 CORBA::Double theAngle)
3705 throw (SALOME::SALOME_Exception)
3707 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3709 SMESH::ListOfGroups * aGroups = 0;
3710 if (theIDsOfElements.length() > 0)
3712 TIDSortedElemSet elements;
3713 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3714 aGroups = rotate(elements,theAxis,theAngle,true,true);
3716 if (!myIsPreviewMode) {
3717 dumpGroupsList(aPythonDump, aGroups);
3718 aPythonDump << this << ".RotateMakeGroups( "
3719 << theIDsOfElements << ", "
3721 << TVar( theAngle ) << " )";
3726 //=======================================================================
3727 //function : RotateObjectMakeGroups
3729 //=======================================================================
3731 SMESH::ListOfGroups*
3732 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3733 const SMESH::AxisStruct& theAxis,
3734 CORBA::Double theAngle)
3735 throw (SALOME::SALOME_Exception)
3737 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3739 SMESH::ListOfGroups * aGroups = 0;
3740 TIDSortedElemSet elements;
3741 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3742 aGroups = rotate(elements, theAxis, theAngle, true, true);
3744 if (!myIsPreviewMode) {
3745 dumpGroupsList(aPythonDump, aGroups);
3746 aPythonDump << this << ".RotateObjectMakeGroups( "
3747 << theObject << ", "
3749 << TVar( theAngle ) << " )";
3754 //=======================================================================
3755 //function : RotateMakeMesh
3757 //=======================================================================
3759 SMESH::SMESH_Mesh_ptr
3760 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
3761 const SMESH::AxisStruct& theAxis,
3762 CORBA::Double theAngleInRadians,
3763 CORBA::Boolean theCopyGroups,
3764 const char* theMeshName)
3765 throw (SALOME::SALOME_Exception)
3768 SMESH::SMESH_Mesh_var mesh;
3769 SMESH_Mesh_i* mesh_i;
3771 { // open new scope to dump "MakeMesh" command
3772 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3774 TPythonDump pydump; // to prevent dump at mesh creation
3776 mesh = makeMesh( theMeshName );
3777 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3779 if ( mesh_i && theIDsOfElements.length() > 0 )
3781 TIDSortedElemSet elements;
3782 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3783 rotate(elements, theAxis, theAngleInRadians,
3784 false, theCopyGroups, & mesh_i->GetImpl());
3785 mesh_i->CreateGroupServants();
3787 if ( !myIsPreviewMode ) {
3788 pydump << mesh << " = " << this << ".RotateMakeMesh( "
3789 << theIDsOfElements << ", "
3791 << TVar( theAngleInRadians ) << ", "
3792 << theCopyGroups << ", '"
3793 << theMeshName << "' )";
3798 if (!myIsPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
3799 mesh_i->GetGroups();
3801 return mesh._retn();
3803 SMESH_CATCH( SMESH::throwCorbaException );
3807 //=======================================================================
3808 //function : RotateObjectMakeMesh
3810 //=======================================================================
3812 SMESH::SMESH_Mesh_ptr
3813 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3814 const SMESH::AxisStruct& theAxis,
3815 CORBA::Double theAngleInRadians,
3816 CORBA::Boolean theCopyGroups,
3817 const char* theMeshName)
3818 throw (SALOME::SALOME_Exception)
3821 SMESH::SMESH_Mesh_var mesh;
3822 SMESH_Mesh_i* mesh_i;
3824 {// open new scope to dump "MakeMesh" command
3825 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3827 TPythonDump pydump; // to prevent dump at mesh creation
3828 mesh = makeMesh( theMeshName );
3829 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3831 TIDSortedElemSet elements;
3833 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3835 rotate(elements, theAxis, theAngleInRadians,
3836 false, theCopyGroups, & mesh_i->GetImpl());
3837 mesh_i->CreateGroupServants();
3839 if ( !myIsPreviewMode ) {
3840 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
3841 << theObject << ", "
3843 << TVar( theAngleInRadians ) << ", "
3844 << theCopyGroups << ", '"
3845 << theMeshName << "' )";
3850 if (!myIsPreviewMode && mesh_i)
3851 mesh_i->GetGroups();
3853 return mesh._retn();
3855 SMESH_CATCH( SMESH::throwCorbaException );
3859 //=======================================================================
3862 //=======================================================================
3864 SMESH::ListOfGroups*
3865 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
3866 const SMESH::PointStruct& thePoint,
3867 const SMESH::double_array& theScaleFact,
3868 CORBA::Boolean theCopy,
3870 ::SMESH_Mesh* theTargetMesh)
3871 throw (SALOME::SALOME_Exception)
3875 if ( theScaleFact.length() < 1 )
3876 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
3877 if ( theScaleFact.length() == 2 )
3878 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
3880 if ( theTargetMesh )
3883 TIDSortedElemSet elements;
3884 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3885 if ( !idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3890 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
3891 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
3895 #if OCC_VERSION_LARGE > 0x06070100
3896 // fight against orthogonalization
3897 // aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
3898 // 0, S[1], 0, thePoint.y * (1-S[1]),
3899 // 0, 0, S[2], thePoint.z * (1-S[2]) );
3900 aTrsf.SetScale( gp::Origin(), 1.0 ); // set form which is used to make group names
3901 gp_XYZ & loc = ( gp_XYZ& ) aTrsf.TranslationPart();
3902 gp_Mat & M = ( gp_Mat& ) aTrsf.HVectorialPart();
3903 loc.SetCoord( thePoint.x * (1-S[0]),
3904 thePoint.y * (1-S[1]),
3905 thePoint.z * (1-S[2]));
3906 M.SetDiagonal( S[0], S[1], S[2] );
3909 double tol = std::numeric_limits<double>::max();
3910 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
3911 0, S[1], 0, thePoint.y * (1-S[1]),
3912 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
3915 TIDSortedElemSet copyElements;
3916 TIDSortedElemSet* workElements = &elements;
3917 if ( myIsPreviewMode )
3919 TPreviewMesh * tmpMesh = getPreviewMesh();
3920 tmpMesh->Copy( elements, copyElements);
3921 if ( !theCopy && !theTargetMesh )
3923 TIDSortedElemSet elemsAround, elemsAroundCopy;
3924 getElementsAround( elements, getMeshDS(), elemsAround );
3925 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3927 workElements = & copyElements;
3928 theMakeGroups = false;
3931 ::SMESH_MeshEditor::PGroupIDs groupIds =
3932 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3934 if ( theCopy && !myIsPreviewMode )
3936 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
3937 else declareMeshModified( /*isReComputeSafe=*/false );
3939 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3941 SMESH_CATCH( SMESH::throwCorbaException );
3945 //=======================================================================
3948 //=======================================================================
3950 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
3951 const SMESH::PointStruct& thePoint,
3952 const SMESH::double_array& theScaleFact,
3953 CORBA::Boolean theCopy)
3954 throw (SALOME::SALOME_Exception)
3956 if ( !myIsPreviewMode ) {
3957 TPythonDump() << this << ".Scale( "
3958 << theObject << ", "
3960 << TVar( theScaleFact ) << ", "
3963 scale(theObject, thePoint, theScaleFact, theCopy, false);
3967 //=======================================================================
3968 //function : ScaleMakeGroups
3970 //=======================================================================
3972 SMESH::ListOfGroups*
3973 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3974 const SMESH::PointStruct& thePoint,
3975 const SMESH::double_array& theScaleFact)
3976 throw (SALOME::SALOME_Exception)
3978 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3980 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
3981 if (!myIsPreviewMode) {
3982 dumpGroupsList(aPythonDump, aGroups);
3983 aPythonDump << this << ".Scale("
3986 << TVar( theScaleFact ) << ",True,True)";
3992 //=======================================================================
3993 //function : ScaleMakeMesh
3995 //=======================================================================
3997 SMESH::SMESH_Mesh_ptr
3998 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3999 const SMESH::PointStruct& thePoint,
4000 const SMESH::double_array& theScaleFact,
4001 CORBA::Boolean theCopyGroups,
4002 const char* theMeshName)
4003 throw (SALOME::SALOME_Exception)
4005 SMESH_Mesh_i* mesh_i;
4006 SMESH::SMESH_Mesh_var mesh;
4007 { // open new scope to dump "MakeMesh" command
4008 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4010 TPythonDump pydump; // to prevent dump at mesh creation
4011 mesh = makeMesh( theMeshName );
4012 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4016 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
4017 mesh_i->CreateGroupServants();
4019 if ( !myIsPreviewMode )
4020 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
4021 << theObject << ", "
4023 << TVar( theScaleFact ) << ", "
4024 << theCopyGroups << ", '"
4025 << theMeshName << "' )";
4029 if (!myIsPreviewMode && mesh_i)
4030 mesh_i->GetGroups();
4032 return mesh._retn();
4036 //=======================================================================
4037 //function : findCoincidentNodes
4039 //=======================================================================
4041 void SMESH_MeshEditor_i::
4042 findCoincidentNodes (TIDSortedNodeSet & Nodes,
4043 CORBA::Double Tolerance,
4044 SMESH::array_of_long_array_out GroupsOfNodes,
4045 CORBA::Boolean SeparateCornersAndMedium)
4047 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4048 getEditor().FindCoincidentNodes( Nodes, Tolerance, aListOfListOfNodes, SeparateCornersAndMedium );
4050 GroupsOfNodes = new SMESH::array_of_long_array;
4051 GroupsOfNodes->length( aListOfListOfNodes.size() );
4052 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4053 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4055 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4056 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4057 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4058 aGroup.length( aListOfNodes.size() );
4059 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4060 aGroup[ j ] = (*lIt)->GetID();
4064 //=======================================================================
4065 //function : FindCoincidentNodes
4067 //=======================================================================
4069 void SMESH_MeshEditor_i::
4070 FindCoincidentNodes (CORBA::Double Tolerance,
4071 SMESH::array_of_long_array_out GroupsOfNodes,
4072 CORBA::Boolean SeparateCornersAndMedium)
4073 throw (SALOME::SALOME_Exception)
4078 TIDSortedNodeSet nodes; // no input nodes
4079 findCoincidentNodes( nodes, Tolerance, GroupsOfNodes, SeparateCornersAndMedium );
4081 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
4082 << Tolerance << ", "
4083 << SeparateCornersAndMedium << " )";
4085 SMESH_CATCH( SMESH::throwCorbaException );
4088 //=======================================================================
4089 //function : FindCoincidentNodesOnPart
4091 //=======================================================================
4093 void SMESH_MeshEditor_i::
4094 FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
4095 CORBA::Double Tolerance,
4096 SMESH::array_of_long_array_out GroupsOfNodes,
4097 CORBA::Boolean SeparateCornersAndMedium)
4098 throw (SALOME::SALOME_Exception)
4103 TIDSortedNodeSet nodes;
4104 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4106 findCoincidentNodes( nodes, Tolerance, GroupsOfNodes, SeparateCornersAndMedium );
4108 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
4110 << Tolerance << ", "
4111 << SeparateCornersAndMedium << " )";
4113 SMESH_CATCH( SMESH::throwCorbaException );
4116 //================================================================================
4118 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
4119 * ExceptSubMeshOrGroups
4121 //================================================================================
4123 void SMESH_MeshEditor_i::
4124 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
4125 CORBA::Double theTolerance,
4126 SMESH::array_of_long_array_out theGroupsOfNodes,
4127 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups,
4128 CORBA::Boolean theSeparateCornersAndMedium)
4129 throw (SALOME::SALOME_Exception)
4134 TIDSortedNodeSet nodes;
4135 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4137 for ( CORBA::ULong i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
4139 SMDS_ElemIteratorPtr nodeIt = myMesh_i->GetElements( theExceptSubMeshOrGroups[i],
4141 while ( nodeIt->more() )
4142 nodes.erase( cast2Node( nodeIt->next() ));
4144 findCoincidentNodes( nodes, theTolerance, theGroupsOfNodes, theSeparateCornersAndMedium );
4146 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
4148 << theTolerance << ", "
4149 << theExceptSubMeshOrGroups << ", "
4150 << theSeparateCornersAndMedium << " )";
4152 SMESH_CATCH( SMESH::throwCorbaException );
4155 //=======================================================================
4156 //function : MergeNodes
4158 //=======================================================================
4160 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes,
4161 const SMESH::ListOfIDSources& NodesToKeep)
4162 throw (SALOME::SALOME_Exception)
4167 SMESHDS_Mesh* aMesh = getMeshDS();
4169 TPythonDump aTPythonDump;
4170 aTPythonDump << this << ".MergeNodes([";
4172 TIDSortedNodeSet setOfNodesToKeep;
4173 for ( CORBA::ULong i = 0; i < NodesToKeep.length(); ++i )
4175 prepareIdSource( NodesToKeep[i] );
4176 SMDS_ElemIteratorPtr nodeIt = myMesh_i->GetElements( NodesToKeep[i], SMESH::NODE );
4177 while ( nodeIt->more() )
4178 setOfNodesToKeep.insert( setOfNodesToKeep.end(), cast2Node( nodeIt->next() ));
4181 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4182 for ( CORBA::ULong i = 0; i < GroupsOfNodes.length(); i++ )
4184 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
4185 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
4186 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
4187 for ( CORBA::ULong j = 0; j < aNodeGroup.length(); j++ )
4189 CORBA::Long index = aNodeGroup[ j ];
4190 if ( const SMDS_MeshNode * node = aMesh->FindNode( index ))
4192 if ( setOfNodesToKeep.count( node ))
4193 aListOfNodes.push_front( node );
4195 aListOfNodes.push_back( node );
4198 if ( aListOfNodes.size() < 2 )
4199 aListOfListOfNodes.pop_back();
4201 if ( i > 0 ) aTPythonDump << ", ";
4202 aTPythonDump << aNodeGroup;
4205 getEditor().MergeNodes( aListOfListOfNodes );
4207 aTPythonDump << "], " << NodesToKeep << ")";
4209 declareMeshModified( /*isReComputeSafe=*/false );
4211 SMESH_CATCH( SMESH::throwCorbaException );
4214 //=======================================================================
4215 //function : FindEqualElements
4217 //=======================================================================
4219 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
4220 SMESH::array_of_long_array_out GroupsOfElementsID)
4221 throw (SALOME::SALOME_Exception)
4226 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
4227 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
4229 TIDSortedElemSet elems;
4230 idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true);
4232 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4233 getEditor().FindEqualElements( elems, aListOfListOfElementsID );
4235 GroupsOfElementsID = new SMESH::array_of_long_array;
4236 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
4238 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt =
4239 aListOfListOfElementsID.begin();
4240 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j)
4242 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
4243 list<int>& listOfIDs = *arraysIt;
4244 aGroup.length( listOfIDs.size() );
4245 list<int>::iterator idIt = listOfIDs.begin();
4246 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k )
4247 aGroup[ k ] = *idIt;
4250 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
4254 SMESH_CATCH( SMESH::throwCorbaException );
4257 //=======================================================================
4258 //function : MergeElements
4260 //=======================================================================
4262 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
4263 throw (SALOME::SALOME_Exception)
4268 TPythonDump aTPythonDump;
4269 aTPythonDump << this << ".MergeElements( [";
4271 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4273 for ( CORBA::ULong i = 0; i < GroupsOfElementsID.length(); i++ ) {
4274 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
4275 aListOfListOfElementsID.push_back( list< int >() );
4276 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
4277 for ( CORBA::ULong j = 0; j < anElemsIDGroup.length(); j++ ) {
4278 CORBA::Long id = anElemsIDGroup[ j ];
4279 aListOfElemsID.push_back( id );
4281 if ( aListOfElemsID.size() < 2 )
4282 aListOfListOfElementsID.pop_back();
4283 if ( i > 0 ) aTPythonDump << ", ";
4284 aTPythonDump << anElemsIDGroup;
4287 getEditor().MergeElements(aListOfListOfElementsID);
4289 declareMeshModified( /*isReComputeSafe=*/true );
4291 aTPythonDump << "] )";
4293 SMESH_CATCH( SMESH::throwCorbaException );
4296 //=======================================================================
4297 //function : MergeEqualElements
4299 //=======================================================================
4301 void SMESH_MeshEditor_i::MergeEqualElements()
4302 throw (SALOME::SALOME_Exception)
4307 getEditor().MergeEqualElements();
4309 declareMeshModified( /*isReComputeSafe=*/true );
4311 TPythonDump() << this << ".MergeEqualElements()";
4313 SMESH_CATCH( SMESH::throwCorbaException );
4316 //=============================================================================
4318 * Move the node to a given point
4320 //=============================================================================
4322 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
4326 throw (SALOME::SALOME_Exception)
4329 initData(/*deleteSearchers=*/false);
4331 const SMDS_MeshNode * node = getMeshDS()->FindNode( NodeID );
4335 if ( theNodeSearcher )
4336 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4338 if ( myIsPreviewMode ) // make preview data
4340 // in a preview mesh, make edges linked to a node
4341 TPreviewMesh& tmpMesh = *getPreviewMesh();
4342 TIDSortedElemSet linkedNodes;
4343 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4344 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4345 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
4346 for ( ; nIt != linkedNodes.end(); ++nIt )
4348 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
4349 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
4353 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
4354 // fill preview data
4356 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4357 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4359 getMeshDS()->MoveNode(node, x, y, z);
4361 if ( !myIsPreviewMode )
4363 // Update Python script
4364 TPythonDump() << "isDone = " << this << ".MoveNode( "
4365 << NodeID << ", " << TVar(x) << ", " << TVar(y) << ", " << TVar(z) << " )";
4366 declareMeshModified( /*isReComputeSafe=*/false );
4369 SMESH_CATCH( SMESH::throwCorbaException );
4374 //================================================================================
4376 * \brief Return ID of node closest to a given point
4378 //================================================================================
4380 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
4383 throw (SALOME::SALOME_Exception)
4386 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4388 if ( !theNodeSearcher ) {
4389 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
4392 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
4393 return node->GetID();
4395 SMESH_CATCH( SMESH::throwCorbaException );
4399 //================================================================================
4401 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
4402 * move the node closest to the point to point's location and return ID of the node
4404 //================================================================================
4406 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
4409 CORBA::Long theNodeID)
4410 throw (SALOME::SALOME_Exception)
4413 // We keep theNodeSearcher until any mesh modification:
4414 // 1) initData() deletes theNodeSearcher at any edition,
4415 // 2) TSearchersDeleter - at any mesh compute event and mesh change
4417 initData(/*deleteSearchers=*/false);
4419 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4421 int nodeID = theNodeID;
4422 const SMDS_MeshNode* node = getMeshDS()->FindNode( nodeID );
4423 if ( !node ) // preview moving node
4425 if ( !theNodeSearcher ) {
4426 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
4429 node = theNodeSearcher->FindClosestTo( p );
4432 nodeID = node->GetID();
4433 if ( myIsPreviewMode ) // make preview data
4435 // in a preview mesh, make edges linked to a node
4436 TPreviewMesh tmpMesh = *getPreviewMesh();
4437 TIDSortedElemSet linkedNodes;
4438 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4439 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4440 for ( ; nIt != linkedNodes.end(); ++nIt )
4442 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
4443 tmpMesh.Copy( &edge );
4446 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
4448 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
4449 // fill preview data
4451 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4453 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4457 getMeshDS()->MoveNode(node, x, y, z);
4461 if ( !myIsPreviewMode )
4463 TPythonDump() << "nodeID = " << this
4464 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
4465 << ", " << nodeID << " )";
4467 declareMeshModified( /*isReComputeSafe=*/false );
4472 SMESH_CATCH( SMESH::throwCorbaException );
4476 //=======================================================================
4478 * Return elements of given type where the given point is IN or ON.
4480 * 'ALL' type means elements of any type excluding nodes
4482 //=======================================================================
4484 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
4487 SMESH::ElementType type)
4488 throw (SALOME::SALOME_Exception)
4491 SMESH::long_array_var res = new SMESH::long_array;
4492 vector< const SMDS_MeshElement* > foundElems;
4494 theSearchersDeleter.Set( myMesh );
4495 if ( !theElementSearcher ) {
4496 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
4498 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4499 SMDSAbs_ElementType( type ),
4501 res->length( foundElems.size() );
4502 for ( size_t i = 0; i < foundElems.size(); ++i )
4503 res[i] = foundElems[i]->GetID();
4507 SMESH_CATCH( SMESH::throwCorbaException );
4511 //=======================================================================
4512 //function : FindAmongElementsByPoint
4513 //purpose : Searching among the given elements, return elements of given type
4514 // where the given point is IN or ON.
4515 // 'ALL' type means elements of any type excluding nodes
4516 //=======================================================================
4519 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
4523 SMESH::ElementType type)
4524 throw (SALOME::SALOME_Exception)
4527 SMESH::long_array_var res = new SMESH::long_array;
4529 if ( type != SMESH::NODE )
4531 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
4532 if ( types->length() == 1 && // a part contains only nodes or 0D elements
4533 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) &&
4534 type != types[0] ) // but search of elements of dim > 0
4537 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
4538 return FindElementsByPoint( x,y,z, type );
4540 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
4542 theSearchersDeleter.Set( myMesh, getPartIOR( elementIDs, type ));
4543 if ( !theElementSearcher )
4545 // create a searcher from elementIDs
4546 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
4547 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
4549 if ( !idSourceToSet( elementIDs, meshDS, elements,
4550 ( type == SMESH::NODE ? SMDSAbs_All : (SMDSAbs_ElementType) type ),
4551 /*emptyIfIsMesh=*/true))
4554 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
4555 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
4557 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt );
4560 vector< const SMDS_MeshElement* > foundElems;
4562 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4563 SMDSAbs_ElementType( type ),
4565 res->length( foundElems.size() );
4566 for ( size_t i = 0; i < foundElems.size(); ++i )
4567 res[i] = foundElems[i]->GetID();
4571 SMESH_CATCH( SMESH::throwCorbaException );
4575 //=======================================================================
4576 //function : GetPointState
4577 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
4578 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
4579 //=======================================================================
4581 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
4584 throw (SALOME::SALOME_Exception)
4587 theSearchersDeleter.Set( myMesh );
4588 if ( !theElementSearcher ) {
4589 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
4591 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
4593 SMESH_CATCH( SMESH::throwCorbaException );
4597 //=======================================================================
4598 //function : convError
4600 //=======================================================================
4602 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
4604 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
4608 RETCASE( SEW_BORDER1_NOT_FOUND );
4609 RETCASE( SEW_BORDER2_NOT_FOUND );
4610 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
4611 RETCASE( SEW_BAD_SIDE_NODES );
4612 RETCASE( SEW_VOLUMES_TO_SPLIT );
4613 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
4614 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
4615 RETCASE( SEW_BAD_SIDE1_NODES );
4616 RETCASE( SEW_BAD_SIDE2_NODES );
4617 RETCASE( SEW_INTERNAL_ERROR );
4619 return SMESH::SMESH_MeshEditor::SEW_OK;
4622 //=======================================================================
4624 * Returns groups of FreeBorder's coincident within the given tolerance.
4625 * If the tolerance <= 0.0 then one tenth of an average size of elements adjacent
4626 * to free borders being compared is used.
4628 //=======================================================================
4630 SMESH::CoincidentFreeBorders*
4631 SMESH_MeshEditor_i::FindCoincidentFreeBorders(CORBA::Double tolerance)
4633 SMESH::CoincidentFreeBorders_var aCFB = new SMESH::CoincidentFreeBorders;
4637 SMESH_MeshAlgos::CoincidentFreeBorders cfb;
4638 SMESH_MeshAlgos::FindCoincidentFreeBorders( *getMeshDS(), tolerance, cfb );
4640 // copy free borders
4641 aCFB->borders.length( cfb._borders.size() );
4642 for ( size_t i = 0; i < cfb._borders.size(); ++i )
4644 SMESH_MeshAlgos::TFreeBorder& nodes = cfb._borders[i];
4645 SMESH::FreeBorder& aBRD = aCFB->borders[i];
4646 aBRD.nodeIDs.length( nodes.size() );
4647 for ( size_t iN = 0; iN < nodes.size(); ++iN )
4648 aBRD.nodeIDs[ iN ] = nodes[ iN ]->GetID();
4651 // copy coincident parts
4652 aCFB->coincidentGroups.length( cfb._coincidentGroups.size() );
4653 for ( size_t i = 0; i < cfb._coincidentGroups.size(); ++i )
4655 SMESH_MeshAlgos::TCoincidentGroup& grp = cfb._coincidentGroups[i];
4656 SMESH::FreeBordersGroup& aGRP = aCFB->coincidentGroups[i];
4657 aGRP.length( grp.size() );
4658 for ( size_t iP = 0; iP < grp.size(); ++iP )
4660 SMESH_MeshAlgos::TFreeBorderPart& part = grp[ iP ];
4661 SMESH::FreeBorderPart& aPART = aGRP[ iP ];
4662 aPART.border = part._border;
4663 aPART.node1 = part._node1;
4664 aPART.node2 = part._node2;
4665 aPART.nodeLast = part._nodeLast;
4668 SMESH_CATCH( SMESH::doNothing );
4670 TPythonDump() << "CoincidentFreeBorders = "
4671 << this << ".FindCoincidentFreeBorders( " << tolerance << " )";
4673 return aCFB._retn();
4676 //=======================================================================
4678 * Sew FreeBorder's of each group
4680 //=======================================================================
4682 CORBA::Short SMESH_MeshEditor_i::
4683 SewCoincidentFreeBorders(const SMESH::CoincidentFreeBorders& freeBorders,
4684 CORBA::Boolean createPolygons,
4685 CORBA::Boolean createPolyhedra)
4686 throw (SALOME::SALOME_Exception)
4688 CORBA::Short nbSewed = 0;
4690 SMESH_MeshAlgos::TFreeBorderVec groups;
4691 SMESH_MeshAlgos::TFreeBorder borderNodes; // triples of nodes for every FreeBorderPart
4693 // check the input and collect nodes
4694 for ( CORBA::ULong i = 0; i < freeBorders.coincidentGroups.length(); ++i )
4696 borderNodes.clear();
4697 const SMESH::FreeBordersGroup& aGRP = freeBorders.coincidentGroups[ i ];
4698 for ( CORBA::ULong iP = 0; iP < aGRP.length(); ++iP )
4700 const SMESH::FreeBorderPart& aPART = aGRP[ iP ];
4701 if ( aPART.border < 0 || aPART.border >= (int) freeBorders.borders.length() )
4702 THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::border index", SALOME::BAD_PARAM);
4704 const SMESH::FreeBorder& aBRD = freeBorders.borders[ aPART.border ];
4706 if ( aPART.node1 < 0 || aPART.node1 > (int) aBRD.nodeIDs.length() )
4707 THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::node1", SALOME::BAD_PARAM);
4708 if ( aPART.node2 < 0 || aPART.node2 > (int) aBRD.nodeIDs.length() )
4709 THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::node2", SALOME::BAD_PARAM);
4710 if ( aPART.nodeLast < 0 || aPART.nodeLast > (int) aBRD.nodeIDs.length() )
4711 THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::nodeLast", SALOME::BAD_PARAM);
4713 // do not keep these nodes for further sewing as nodes can be removed by the sewing
4714 const SMDS_MeshNode* n1 = getMeshDS()->FindNode( aBRD.nodeIDs[ aPART.node1 ]);
4715 const SMDS_MeshNode* n2 = getMeshDS()->FindNode( aBRD.nodeIDs[ aPART.node2 ]);
4716 const SMDS_MeshNode* n3 = getMeshDS()->FindNode( aBRD.nodeIDs[ aPART.nodeLast ]);
4718 THROW_SALOME_CORBA_EXCEPTION("Nonexistent FreeBorderPart::node1", SALOME::BAD_PARAM);
4720 THROW_SALOME_CORBA_EXCEPTION("Nonexistent FreeBorderPart::node2", SALOME::BAD_PARAM);
4722 THROW_SALOME_CORBA_EXCEPTION("Nonexistent FreeBorderPart::nodeLast", SALOME::BAD_PARAM);
4724 borderNodes.push_back( n1 );
4725 borderNodes.push_back( n2 );
4726 borderNodes.push_back( n3 );
4728 groups.push_back( borderNodes );
4731 // SewFreeBorder() can merge nodes, thus nodes stored in 'groups' can become dead;
4732 // to get nodes that replace other nodes during merge we create 0D elements
4733 // on each node and MergeNodes() will replace underlying nodes of 0D elements by
4736 vector< const SMDS_MeshElement* > tmp0Delems;
4737 for ( size_t i = 0; i < groups.size(); ++i )
4739 SMESH_MeshAlgos::TFreeBorder& nodes = groups[i];
4740 for ( size_t iN = 0; iN < nodes.size(); ++iN )
4742 SMDS_ElemIteratorPtr it0D = nodes[iN]->GetInverseElementIterator(SMDSAbs_0DElement);
4744 tmp0Delems.push_back( it0D->next() );
4746 tmp0Delems.push_back( getMeshDS()->Add0DElement( nodes[iN] ));
4750 // cout << endl << "INIT" << endl;
4751 // for ( size_t i = 0; i < tmp0Delems.size(); ++i )
4753 // cout << i << " ";
4754 // if ( i % 3 == 0 ) cout << "^ ";
4755 // tmp0Delems[i]->GetNode(0)->Print( cout );
4760 ::SMESH_MeshEditor::Sew_Error res, ok = ::SMESH_MeshEditor::SEW_OK;
4762 for ( size_t i = 0; i < groups.size(); ++i )
4764 bool isBordToBord = true;
4765 bool groupSewed = false;
4766 SMESH_MeshAlgos::TFreeBorder& nodes = groups[i];
4767 for ( size_t iN = 3; iN+2 < nodes.size(); iN += 3 )
4769 const SMDS_MeshNode* n0 = tmp0Delems[ i0D + 0 ]->GetNode( 0 );
4770 const SMDS_MeshNode* n1 = tmp0Delems[ i0D + 1 ]->GetNode( 0 );
4771 const SMDS_MeshNode* n2 = tmp0Delems[ i0D + 2 ]->GetNode( 0 );
4773 const SMDS_MeshNode* n3 = tmp0Delems[ i0D + 0 + iN ]->GetNode( 0 );
4774 const SMDS_MeshNode* n4 = tmp0Delems[ i0D + 1 + iN ]->GetNode( 0 );
4775 const SMDS_MeshNode* n5 = tmp0Delems[ i0D + 2 + iN ]->GetNode( 0 );
4777 if ( !n0 || !n1 || !n2 || !n3 || !n4 || !n5 )
4780 // TIDSortedElemSet emptySet, avoidSet;
4781 // if ( !SMESH_MeshAlgos::FindFaceInSet( n0, n1, emptySet, avoidSet))
4783 // cout << "WRONG 2nd 1" << endl;
4784 // n0->Print( cout );
4785 // n1->Print( cout );
4787 // if ( !SMESH_MeshAlgos::FindFaceInSet( n3, n4, emptySet, avoidSet))
4789 // cout << "WRONG 2nd 2" << endl;
4790 // n3->Print( cout );
4791 // n4->Print( cout );
4794 if ( !isBordToBord )
4796 n1 = n2; // at border-to-side sewing only last side node (n1) is needed
4797 n2 = 0; // and n2 is not used
4799 // 1st border moves to 2nd
4800 res = getEditor().SewFreeBorder( n3, n4, n5 ,// 1st
4802 /*2ndIsFreeBorder=*/ isBordToBord,
4803 createPolygons, createPolyhedra);
4804 groupSewed = ( res == ok );
4806 isBordToBord = false;
4807 // cout << endl << "SEWED GROUP " << i << " PART " << iN / 3 << endl;
4808 // for ( size_t t = 0; t < tmp0Delems.size(); ++t )
4810 // cout << t << " ";
4811 // if ( t % 3 == 0 ) cout << "^ ";
4812 // tmp0Delems[t]->GetNode(0)->Print( cout );
4815 i0D += nodes.size();
4816 nbSewed += groupSewed;
4819 TPythonDump() << "nbSewed = " << this << ".SewCoincidentFreeBorders( "
4820 << freeBorders << ", "
4821 << createPolygons << ", "
4822 << createPolyhedra << " )";
4824 SMESH_CATCH( SMESH::doNothing );
4826 declareMeshModified( /*isReComputeSafe=*/false );
4828 // remove tmp 0D elements
4830 set< const SMDS_MeshElement* > removed0D;
4831 for ( size_t i = 0; i < tmp0Delems.size(); ++i )
4833 if ( removed0D.insert( tmp0Delems[i] ).second )
4834 getMeshDS()->RemoveFreeElement( tmp0Delems[i], /*sm=*/0, /*fromGroups=*/false );
4836 SMESH_CATCH( SMESH::throwCorbaException );
4841 //=======================================================================
4842 //function : SewFreeBorders
4844 //=======================================================================
4846 SMESH::SMESH_MeshEditor::Sew_Error
4847 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
4848 CORBA::Long SecondNodeID1,
4849 CORBA::Long LastNodeID1,
4850 CORBA::Long FirstNodeID2,
4851 CORBA::Long SecondNodeID2,
4852 CORBA::Long LastNodeID2,
4853 CORBA::Boolean CreatePolygons,
4854 CORBA::Boolean CreatePolyedrs)
4855 throw (SALOME::SALOME_Exception)
4860 SMESHDS_Mesh* aMesh = getMeshDS();
4862 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4863 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4864 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4865 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4866 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4867 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
4869 if (!aBorderFirstNode ||
4870 !aBorderSecondNode||
4872 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4873 if (!aSide2FirstNode ||
4874 !aSide2SecondNode ||
4876 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4878 TPythonDump() << "error = " << this << ".SewFreeBorders( "
4879 << FirstNodeID1 << ", "
4880 << SecondNodeID1 << ", "
4881 << LastNodeID1 << ", "
4882 << FirstNodeID2 << ", "
4883 << SecondNodeID2 << ", "
4884 << LastNodeID2 << ", "
4885 << CreatePolygons<< ", "
4886 << CreatePolyedrs<< " )";
4888 SMESH::SMESH_MeshEditor::Sew_Error error =
4889 convError( getEditor().SewFreeBorder (aBorderFirstNode,
4900 declareMeshModified( /*isReComputeSafe=*/false );
4903 SMESH_CATCH( SMESH::throwCorbaException );
4904 return SMESH::SMESH_MeshEditor::Sew_Error(0);
4908 //=======================================================================
4909 //function : SewConformFreeBorders
4911 //=======================================================================
4913 SMESH::SMESH_MeshEditor::Sew_Error
4914 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
4915 CORBA::Long SecondNodeID1,
4916 CORBA::Long LastNodeID1,
4917 CORBA::Long FirstNodeID2,
4918 CORBA::Long SecondNodeID2)
4919 throw (SALOME::SALOME_Exception)
4924 SMESHDS_Mesh* aMesh = getMeshDS();
4926 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4927 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4928 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4929 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4930 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4931 const SMDS_MeshNode* aSide2ThirdNode = 0;
4933 if (!aBorderFirstNode ||
4934 !aBorderSecondNode||
4936 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4937 if (!aSide2FirstNode ||
4939 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4941 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
4942 << FirstNodeID1 << ", "
4943 << SecondNodeID1 << ", "
4944 << LastNodeID1 << ", "
4945 << FirstNodeID2 << ", "
4946 << SecondNodeID2 << " )";
4948 SMESH::SMESH_MeshEditor::Sew_Error error =
4949 convError( getEditor().SewFreeBorder (aBorderFirstNode,
4958 declareMeshModified( /*isReComputeSafe=*/false );
4961 SMESH_CATCH( SMESH::throwCorbaException );
4962 return SMESH::SMESH_MeshEditor::Sew_Error(0);
4966 //=======================================================================
4967 //function : SewBorderToSide
4969 //=======================================================================
4971 SMESH::SMESH_MeshEditor::Sew_Error
4972 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
4973 CORBA::Long SecondNodeIDOnFreeBorder,
4974 CORBA::Long LastNodeIDOnFreeBorder,
4975 CORBA::Long FirstNodeIDOnSide,
4976 CORBA::Long LastNodeIDOnSide,
4977 CORBA::Boolean CreatePolygons,
4978 CORBA::Boolean CreatePolyedrs)
4979 throw (SALOME::SALOME_Exception)
4984 SMESHDS_Mesh* aMesh = getMeshDS();
4986 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
4987 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
4988 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
4989 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
4990 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
4991 const SMDS_MeshNode* aSide2ThirdNode = 0;
4993 if (!aBorderFirstNode ||
4994 !aBorderSecondNode||
4996 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4997 if (!aSide2FirstNode ||
4999 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
5001 TPythonDump() << "error = " << this << ".SewBorderToSide( "
5002 << FirstNodeIDOnFreeBorder << ", "
5003 << SecondNodeIDOnFreeBorder << ", "
5004 << LastNodeIDOnFreeBorder << ", "
5005 << FirstNodeIDOnSide << ", "
5006 << LastNodeIDOnSide << ", "
5007 << CreatePolygons << ", "
5008 << CreatePolyedrs << ") ";
5010 SMESH::SMESH_MeshEditor::Sew_Error error =
5011 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5021 declareMeshModified( /*isReComputeSafe=*/false );
5024 SMESH_CATCH( SMESH::throwCorbaException );
5025 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5029 //=======================================================================
5030 //function : SewSideElements
5032 //=======================================================================
5034 SMESH::SMESH_MeshEditor::Sew_Error
5035 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
5036 const SMESH::long_array& IDsOfSide2Elements,
5037 CORBA::Long NodeID1OfSide1ToMerge,
5038 CORBA::Long NodeID1OfSide2ToMerge,
5039 CORBA::Long NodeID2OfSide1ToMerge,
5040 CORBA::Long NodeID2OfSide2ToMerge)
5041 throw (SALOME::SALOME_Exception)
5046 SMESHDS_Mesh* aMesh = getMeshDS();
5048 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
5049 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
5050 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
5051 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
5053 if (!aFirstNode1ToMerge ||
5054 !aFirstNode2ToMerge )
5055 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
5056 if (!aSecondNode1ToMerge||
5057 !aSecondNode2ToMerge)
5058 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
5060 TIDSortedElemSet aSide1Elems, aSide2Elems;
5061 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
5062 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
5064 TPythonDump() << "error = " << this << ".SewSideElements( "
5065 << IDsOfSide1Elements << ", "
5066 << IDsOfSide2Elements << ", "
5067 << NodeID1OfSide1ToMerge << ", "
5068 << NodeID1OfSide2ToMerge << ", "
5069 << NodeID2OfSide1ToMerge << ", "
5070 << NodeID2OfSide2ToMerge << ")";
5072 SMESH::SMESH_MeshEditor::Sew_Error error =
5073 convError( getEditor().SewSideElements (aSide1Elems, aSide2Elems,
5076 aSecondNode1ToMerge,
5077 aSecondNode2ToMerge));
5079 declareMeshModified( /*isReComputeSafe=*/false );
5082 SMESH_CATCH( SMESH::throwCorbaException );
5083 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5086 //================================================================================
5088 * \brief Set new nodes for given element
5089 * \param ide - element id
5090 * \param newIDs - new node ids
5091 * \retval CORBA::Boolean - true if result is OK
5093 //================================================================================
5095 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
5096 const SMESH::long_array& newIDs)
5097 throw (SALOME::SALOME_Exception)
5102 const SMDS_MeshElement* elem = getMeshDS()->FindElement(ide);
5103 if(!elem) return false;
5105 int nbn = newIDs.length();
5107 vector<const SMDS_MeshNode*> aNodes(nbn);
5110 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(newIDs[i]);
5113 aNodes[nbn1] = aNode;
5116 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
5117 << ide << ", " << newIDs << " )";
5119 MESSAGE("ChangeElementNodes");
5120 bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
5122 declareMeshModified( /*isReComputeSafe=*/ !res );
5126 SMESH_CATCH( SMESH::throwCorbaException );
5130 //=======================================================================
5132 * \brief Makes a part of the mesh quadratic or bi-quadratic
5134 //=======================================================================
5136 void SMESH_MeshEditor_i::convertToQuadratic(CORBA::Boolean theForce3d,
5137 CORBA::Boolean theToBiQuad,
5138 SMESH::SMESH_IDSource_ptr theObject)
5139 throw (SALOME::SALOME_Exception)
5144 TIDSortedElemSet elems;
5146 if ( !( elemsOK = CORBA::is_nil( theObject )))
5148 elemsOK = idSourceToSet( theObject, getMeshDS(), elems,
5149 SMDSAbs_All, /*emptyIfIsMesh=*/true );
5153 if ( !elems.empty() && (*elems.begin())->GetType() == SMDSAbs_Node )
5154 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5156 if ( elems.empty() ) getEditor().ConvertToQuadratic(theForce3d, theToBiQuad);
5157 else getEditor().ConvertToQuadratic(theForce3d, elems, theToBiQuad);
5159 declareMeshModified( /*isReComputeSafe=*/false );
5162 SMESH_CATCH( SMESH::throwCorbaException );
5165 //=======================================================================
5166 //function : ConvertFromQuadratic
5168 //=======================================================================
5170 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
5171 throw (SALOME::SALOME_Exception)
5176 CORBA::Boolean isDone = getEditor().ConvertFromQuadratic();
5177 TPythonDump() << this << ".ConvertFromQuadratic()";
5178 declareMeshModified( /*isReComputeSafe=*/!isDone );
5181 SMESH_CATCH( SMESH::throwCorbaException );
5185 //=======================================================================
5186 //function : ConvertToQuadratic
5188 //=======================================================================
5190 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
5191 throw (SALOME::SALOME_Exception)
5193 convertToQuadratic( theForce3d, false );
5194 TPythonDump() << this << ".ConvertToQuadratic("<<theForce3d<<")";
5197 //================================================================================
5199 * \brief Makes a part of the mesh quadratic
5201 //================================================================================
5203 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
5204 SMESH::SMESH_IDSource_ptr theObject)
5205 throw (SALOME::SALOME_Exception)
5207 convertToQuadratic( theForce3d, false, theObject );
5208 TPythonDump() << this << ".ConvertToQuadraticObject("<<theForce3d<<", "<<theObject<<")";
5211 //================================================================================
5213 * \brief Makes a part of the mesh bi-quadratic
5215 //================================================================================
5217 void SMESH_MeshEditor_i::ConvertToBiQuadratic(CORBA::Boolean theForce3d,
5218 SMESH::SMESH_IDSource_ptr theObject)
5219 throw (SALOME::SALOME_Exception)
5221 convertToQuadratic( theForce3d, true, theObject );
5222 TPythonDump() << this << ".ConvertToBiQuadratic("<<theForce3d<<", "<<theObject<<")";
5225 //================================================================================
5227 * \brief Makes a part of the mesh linear
5229 //================================================================================
5231 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
5232 throw (SALOME::SALOME_Exception)
5239 TIDSortedElemSet elems;
5240 if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5242 if ( elems.empty() )
5244 ConvertFromQuadratic();
5246 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5248 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5252 getEditor().ConvertFromQuadratic(elems);
5255 declareMeshModified( /*isReComputeSafe=*/false );
5257 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
5259 SMESH_CATCH( SMESH::throwCorbaException );
5262 //=======================================================================
5263 //function : makeMesh
5264 //purpose : create a named imported mesh
5265 //=======================================================================
5267 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
5269 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
5270 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
5271 SALOMEDS::Study_var study = gen->GetCurrentStudy();
5272 SALOMEDS::SObject_wrap meshSO = gen->ObjectToSObject( study, mesh );
5273 gen->SetName( meshSO, theMeshName, "Mesh" );
5274 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
5276 return mesh._retn();
5279 //=======================================================================
5280 //function : dumpGroupsList
5282 //=======================================================================
5284 void SMESH_MeshEditor_i::dumpGroupsList(TPythonDump & theDumpPython,
5285 const SMESH::ListOfGroups * theGroupList)
5287 bool isDumpGroupList = ( theGroupList && theGroupList->length() > 0 );
5288 if ( isDumpGroupList )
5289 theDumpPython << theGroupList << " = ";
5292 //================================================================================
5294 \brief Generates the unique group name.
5295 \param thePrefix name prefix
5298 //================================================================================
5300 std::string SMESH_MeshEditor_i::generateGroupName(const std::string& thePrefix)
5302 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5303 set<std::string> groupNames;
5305 // Get existing group names
5306 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
5307 SMESH::SMESH_GroupBase_var aGroup = groups[i];
5308 if (CORBA::is_nil(aGroup))
5311 CORBA::String_var name = aGroup->GetName();
5312 groupNames.insert( name.in() );
5316 std::string name = thePrefix;
5319 while (!groupNames.insert(name).second)
5320 name = SMESH_Comment( thePrefix ) << "_" << index++;
5325 //================================================================================
5327 * \brief Prepare SMESH_IDSource for work
5329 //================================================================================
5331 void SMESH_MeshEditor_i::prepareIdSource(SMESH::SMESH_IDSource_ptr theObject)
5333 if ( SMESH::Filter_i* filter = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5335 SMESH::SMESH_Mesh_var mesh = myMesh_i->_this();
5336 filter->SetMesh( mesh );
5339 //================================================================================
5341 * \brief Retrieve elements of given type from SMESH_IDSource
5343 //================================================================================
5345 bool SMESH_MeshEditor_i::idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource,
5346 const SMESHDS_Mesh* theMeshDS,
5347 TIDSortedElemSet& theElemSet,
5348 const SMDSAbs_ElementType theType,
5349 const bool emptyIfIsMesh,
5350 IDSource_Error* error)
5353 if ( error ) *error = IDSource_OK;
5355 if ( CORBA::is_nil( theIDSource ))
5357 if ( error ) *error = IDSource_INVALID;
5360 if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
5362 if ( error && getMeshDS()->GetMeshInfo().NbElements( theType ) == 0 )
5363 *error = IDSource_EMPTY;
5366 prepareIdSource( theIDSource );
5367 SMESH::long_array_var anIDs = theIDSource->GetIDs();
5368 if ( anIDs->length() == 0 )
5370 if ( error ) *error = IDSource_EMPTY;
5373 SMESH::array_of_ElementType_var types = theIDSource->GetTypes();
5374 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
5376 if ( theType == SMDSAbs_All || theType == SMDSAbs_Node )
5378 arrayToSet( anIDs, getMeshDS(), theElemSet, SMDSAbs_Node );
5382 if ( error ) *error = IDSource_INVALID;
5388 arrayToSet( anIDs, getMeshDS(), theElemSet, theType);
5389 if ( bool(anIDs->length()) != bool(theElemSet.size()))
5391 if ( error ) *error = IDSource_INVALID;
5398 //================================================================================
5400 * \brief Duplicates given elements, i.e. creates new elements based on the
5401 * same nodes as the given ones.
5402 * \param theElements - container of elements to duplicate.
5403 * \param theGroupName - a name of group to contain the generated elements.
5404 * If a group with such a name already exists, the new elements
5405 * are added to the existng group, else a new group is created.
5406 * If \a theGroupName is empty, new elements are not added
5408 * \return a group where the new elements are added. NULL if theGroupName == "".
5411 //================================================================================
5413 SMESH::SMESH_Group_ptr
5414 SMESH_MeshEditor_i::DoubleElements(SMESH::SMESH_IDSource_ptr theElements,
5415 const char* theGroupName)
5416 throw (SALOME::SALOME_Exception)
5418 SMESH::SMESH_Group_var newGroup;
5425 TIDSortedElemSet elems;
5426 if ( idSourceToSet( theElements, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true))
5428 getEditor().DoubleElements( elems );
5430 if ( strlen( theGroupName ) && !getEditor().GetLastCreatedElems().IsEmpty() )
5433 SMESH::ElementType type =
5434 SMESH::ElementType( getEditor().GetLastCreatedElems().Value(1)->GetType() );
5435 // find existing group
5436 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5437 for ( size_t i = 0; i < groups->length(); ++i )
5438 if ( groups[i]->GetType() == type )
5440 CORBA::String_var name = groups[i]->GetName();
5441 if ( strcmp( name, theGroupName ) == 0 ) {
5442 newGroup = SMESH::SMESH_Group::_narrow( groups[i] );
5446 // create a new group
5447 if ( newGroup->_is_nil() )
5448 newGroup = myMesh_i->CreateGroup( type, theGroupName );
5450 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* >( newGroup ))
5452 SMESHDS_Group* groupDS = static_cast< SMESHDS_Group* >( group_i->GetGroupDS() );
5453 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
5454 for ( int i = 1; i <= aSeq.Length(); i++ )
5455 groupDS->SMDSGroup().Add( aSeq(i) );
5460 if ( !newGroup->_is_nil() )
5461 pyDump << newGroup << " = ";
5462 pyDump << this << ".DoubleElements( "
5463 << theElements << ", " << "'" << theGroupName <<"')";
5465 SMESH_CATCH( SMESH::throwCorbaException );
5467 return newGroup._retn();
5470 //================================================================================
5472 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5473 \param theNodes - identifiers of nodes to be doubled
5474 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
5475 nodes. If list of element identifiers is empty then nodes are doubled but
5476 they not assigned to elements
5477 \return TRUE if operation has been completed successfully, FALSE otherwise
5478 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
5480 //================================================================================
5482 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
5483 const SMESH::long_array& theModifiedElems )
5484 throw (SALOME::SALOME_Exception)
5489 list< int > aListOfNodes;
5491 for ( i = 0, n = theNodes.length(); i < n; i++ )
5492 aListOfNodes.push_back( theNodes[ i ] );
5494 list< int > aListOfElems;
5495 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5496 aListOfElems.push_back( theModifiedElems[ i ] );
5498 bool aResult = getEditor().DoubleNodes( aListOfNodes, aListOfElems );
5500 declareMeshModified( /*isReComputeSafe=*/ !aResult );
5502 // Update Python script
5503 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
5507 SMESH_CATCH( SMESH::throwCorbaException );
5511 //================================================================================
5513 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5514 This method provided for convenience works as DoubleNodes() described above.
5515 \param theNodeId - identifier of node to be doubled.
5516 \param theModifiedElems - identifiers of elements to be updated.
5517 \return TRUE if operation has been completed successfully, FALSE otherwise
5518 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
5520 //================================================================================
5522 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
5523 const SMESH::long_array& theModifiedElems )
5524 throw (SALOME::SALOME_Exception)
5527 SMESH::long_array_var aNodes = new SMESH::long_array;
5528 aNodes->length( 1 );
5529 aNodes[ 0 ] = theNodeId;
5531 TPythonDump pyDump; // suppress dump by the next line
5533 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
5535 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
5539 SMESH_CATCH( SMESH::throwCorbaException );
5543 //================================================================================
5545 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5546 This method provided for convenience works as DoubleNodes() described above.
5547 \param theNodes - group of nodes to be doubled.
5548 \param theModifiedElems - group of elements to be updated.
5549 \return TRUE if operation has been completed successfully, FALSE otherwise
5550 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
5552 //================================================================================
5554 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
5555 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5556 throw (SALOME::SALOME_Exception)
5559 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5562 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5563 SMESH::long_array_var aModifiedElems;
5564 if ( !CORBA::is_nil( theModifiedElems ) )
5565 aModifiedElems = theModifiedElems->GetListOfID();
5568 aModifiedElems = new SMESH::long_array;
5569 aModifiedElems->length( 0 );
5572 TPythonDump pyDump; // suppress dump by the next line
5574 bool done = DoubleNodes( aNodes, aModifiedElems );
5576 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
5580 SMESH_CATCH( SMESH::throwCorbaException );
5584 //================================================================================
5586 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5587 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
5588 * \param theNodes - group of nodes to be doubled.
5589 * \param theModifiedElems - group of elements to be updated.
5590 * \return a new group with newly created nodes
5591 * \sa DoubleNodeGroup()
5593 //================================================================================
5595 SMESH::SMESH_Group_ptr
5596 SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
5597 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5598 throw (SALOME::SALOME_Exception)
5601 SMESH::SMESH_Group_var aNewGroup;
5603 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5604 return aNewGroup._retn();
5607 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5608 SMESH::long_array_var aModifiedElems;
5609 if ( !CORBA::is_nil( theModifiedElems ) )
5610 aModifiedElems = theModifiedElems->GetListOfID();
5612 aModifiedElems = new SMESH::long_array;
5613 aModifiedElems->length( 0 );
5616 TPythonDump pyDump; // suppress dump by the next line
5618 bool aResult = DoubleNodes( aNodes, aModifiedElems );
5621 // Create group with newly created nodes
5622 SMESH::long_array_var anIds = GetLastCreatedNodes();
5623 if (anIds->length() > 0) {
5624 std::string anUnindexedName (theNodes->GetName());
5625 std::string aNewName = generateGroupName(anUnindexedName + "_double");
5626 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5627 aNewGroup->Add(anIds);
5628 pyDump << aNewGroup << " = ";
5632 pyDump << this << ".DoubleNodeGroupNew( " << theNodes << ", "
5633 << theModifiedElems << " )";
5635 return aNewGroup._retn();
5637 SMESH_CATCH( SMESH::throwCorbaException );
5641 //================================================================================
5643 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5644 This method provided for convenience works as DoubleNodes() described above.
5645 \param theNodes - list of groups of nodes to be doubled
5646 \param theModifiedElems - list of groups of elements to be updated.
5647 \return TRUE if operation has been completed successfully, FALSE otherwise
5648 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
5650 //================================================================================
5652 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
5653 const SMESH::ListOfGroups& theModifiedElems )
5654 throw (SALOME::SALOME_Exception)
5659 std::list< int > aNodes;
5661 for ( i = 0, n = theNodes.length(); i < n; i++ )
5663 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
5664 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
5666 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5667 for ( j = 0, m = aCurr->length(); j < m; j++ )
5668 aNodes.push_back( aCurr[ j ] );
5672 std::list< int > anElems;
5673 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5675 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
5676 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
5678 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5679 for ( j = 0, m = aCurr->length(); j < m; j++ )
5680 anElems.push_back( aCurr[ j ] );
5684 bool aResult = getEditor().DoubleNodes( aNodes, anElems );
5686 declareMeshModified( /*isReComputeSafe=*/false );
5688 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
5692 SMESH_CATCH( SMESH::throwCorbaException );
5696 //================================================================================
5698 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5699 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
5700 * \param theNodes - group of nodes to be doubled.
5701 * \param theModifiedElems - group of elements to be updated.
5702 * \return a new group with newly created nodes
5703 * \sa DoubleNodeGroups()
5705 //================================================================================
5707 SMESH::SMESH_Group_ptr
5708 SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
5709 const SMESH::ListOfGroups& theModifiedElems )
5710 throw (SALOME::SALOME_Exception)
5712 SMESH::SMESH_Group_var aNewGroup;
5714 TPythonDump pyDump; // suppress dump by the next line
5716 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
5720 // Create group with newly created nodes
5721 SMESH::long_array_var anIds = GetLastCreatedNodes();
5722 if (anIds->length() > 0) {
5723 std::string anUnindexedName (theNodes[0]->GetName());
5724 std::string aNewName = generateGroupName(anUnindexedName + "_double");
5725 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5726 aNewGroup->Add(anIds);
5727 pyDump << aNewGroup << " = ";
5731 pyDump << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
5732 << theModifiedElems << " )";
5734 return aNewGroup._retn();
5738 //================================================================================
5740 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5741 \param theElems - the list of elements (edges or faces) to be replicated
5742 The nodes for duplication could be found from these elements
5743 \param theNodesNot - list of nodes to NOT replicate
5744 \param theAffectedElems - the list of elements (cells and edges) to which the
5745 replicated nodes should be associated to.
5746 \return TRUE if operation has been completed successfully, FALSE otherwise
5747 \sa DoubleNodeGroup(), DoubleNodeGroups()
5749 //================================================================================
5751 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
5752 const SMESH::long_array& theNodesNot,
5753 const SMESH::long_array& theAffectedElems )
5754 throw (SALOME::SALOME_Exception)
5759 SMESHDS_Mesh* aMeshDS = getMeshDS();
5760 TIDSortedElemSet anElems, aNodes, anAffected;
5761 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5762 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5763 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
5765 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5767 // Update Python script
5768 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
5769 << theNodesNot << ", " << theAffectedElems << " )";
5771 declareMeshModified( /*isReComputeSafe=*/false );
5774 SMESH_CATCH( SMESH::throwCorbaException );
5778 //================================================================================
5780 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5781 \param theElems - the list of elements (edges or faces) to be replicated
5782 The nodes for duplication could be found from these elements
5783 \param theNodesNot - list of nodes to NOT replicate
5784 \param theShape - shape to detect affected elements (element which geometric center
5785 located on or inside shape).
5786 The replicated nodes should be associated to affected elements.
5787 \return TRUE if operation has been completed successfully, FALSE otherwise
5788 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
5790 //================================================================================
5792 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
5793 const SMESH::long_array& theNodesNot,
5794 GEOM::GEOM_Object_ptr theShape )
5795 throw (SALOME::SALOME_Exception)
5801 SMESHDS_Mesh* aMeshDS = getMeshDS();
5802 TIDSortedElemSet anElems, aNodes;
5803 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5804 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5806 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5807 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
5809 // Update Python script
5810 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
5811 << theNodesNot << ", " << theShape << " )";
5813 declareMeshModified( /*isReComputeSafe=*/false );
5816 SMESH_CATCH( SMESH::throwCorbaException );
5820 //================================================================================
5822 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5823 \param theElems - group of of elements (edges or faces) to be replicated
5824 \param theNodesNot - group of nodes not to replicated
5825 \param theAffectedElems - group of elements to which the replicated nodes
5826 should be associated to.
5827 \return TRUE if operation has been completed successfully, FALSE otherwise
5828 \sa DoubleNodes(), DoubleNodeGroups()
5830 //================================================================================
5833 SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
5834 SMESH::SMESH_GroupBase_ptr theNodesNot,
5835 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5836 throw (SALOME::SALOME_Exception)
5839 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5845 SMESHDS_Mesh* aMeshDS = getMeshDS();
5846 TIDSortedElemSet anElems, aNodes, anAffected;
5847 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5848 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5849 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5851 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5853 // Update Python script
5854 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
5855 << theNodesNot << ", " << theAffectedElems << " )";
5857 declareMeshModified( /*isReComputeSafe=*/false );
5860 SMESH_CATCH( SMESH::throwCorbaException );
5864 //================================================================================
5866 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5867 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
5868 * \param theElems - group of of elements (edges or faces) to be replicated
5869 * \param theNodesNot - group of nodes not to replicated
5870 * \param theAffectedElems - group of elements to which the replicated nodes
5871 * should be associated to.
5872 * \return a new group with newly created elements
5873 * \sa DoubleNodeElemGroup()
5875 //================================================================================
5877 SMESH::SMESH_Group_ptr
5878 SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
5879 SMESH::SMESH_GroupBase_ptr theNodesNot,
5880 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5881 throw (SALOME::SALOME_Exception)
5884 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroup2New( theElems,
5888 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
5889 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
5891 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupNew( "
5893 << theNodesNot << ", "
5894 << theAffectedElems << " )";
5896 return elemGroup._retn();
5899 //================================================================================
5901 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5902 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
5903 * \param theElems - group of of elements (edges or faces) to be replicated
5904 * \param theNodesNot - group of nodes not to replicated
5905 * \param theAffectedElems - group of elements to which the replicated nodes
5906 * should be associated to.
5907 * \return a new group with newly created elements
5908 * \sa DoubleNodeElemGroup()
5910 //================================================================================
5912 SMESH::ListOfGroups*
5913 SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
5914 SMESH::SMESH_GroupBase_ptr theNodesNot,
5915 SMESH::SMESH_GroupBase_ptr theAffectedElems,
5916 CORBA::Boolean theElemGroupNeeded,
5917 CORBA::Boolean theNodeGroupNeeded)
5918 throw (SALOME::SALOME_Exception)
5921 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
5922 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
5923 aTwoGroups->length( 2 );
5925 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5926 return aTwoGroups._retn();
5931 SMESHDS_Mesh* aMeshDS = getMeshDS();
5932 TIDSortedElemSet anElems, aNodes, anAffected;
5933 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5934 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5935 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5938 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5940 declareMeshModified( /*isReComputeSafe=*/ !aResult );
5946 // Create group with newly created elements
5947 CORBA::String_var elemGroupName = theElems->GetName();
5948 std::string aNewName = generateGroupName( std::string(elemGroupName.in()) + "_double");
5949 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
5951 SMESH::long_array_var anIds = GetLastCreatedElems();
5952 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5953 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5954 aNewElemGroup->Add(anIds);
5956 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
5958 SMESH::long_array_var anIds = GetLastCreatedNodes();
5959 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5960 aNewNodeGroup->Add(anIds);
5964 // Update Python script
5967 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
5968 else pyDump << aNewElemGroup << ", ";
5969 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
5970 else pyDump << aNewNodeGroup << " ] = ";
5972 pyDump << this << ".DoubleNodeElemGroup2New( " << theElems << ", "
5973 << theNodesNot << ", "
5974 << theAffectedElems << ", "
5975 << theElemGroupNeeded << ", "
5976 << theNodeGroupNeeded <<" )";
5978 aTwoGroups[0] = aNewElemGroup._retn();
5979 aTwoGroups[1] = aNewNodeGroup._retn();
5980 return aTwoGroups._retn();
5982 SMESH_CATCH( SMESH::throwCorbaException );
5986 //================================================================================
5988 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5989 \param theElems - group of of elements (edges or faces) to be replicated
5990 \param theNodesNot - group of nodes not to replicated
5991 \param theShape - shape to detect affected elements (element which geometric center
5992 located on or inside shape).
5993 The replicated nodes should be associated to affected elements.
5994 \return TRUE if operation has been completed successfully, FALSE otherwise
5995 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
5997 //================================================================================
6000 SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
6001 SMESH::SMESH_GroupBase_ptr theNodesNot,
6002 GEOM::GEOM_Object_ptr theShape )
6003 throw (SALOME::SALOME_Exception)
6006 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6012 SMESHDS_Mesh* aMeshDS = getMeshDS();
6013 TIDSortedElemSet anElems, aNodes, anAffected;
6014 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6015 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6017 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6018 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6021 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6023 // Update Python script
6024 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
6025 << theNodesNot << ", " << theShape << " )";
6028 SMESH_CATCH( SMESH::throwCorbaException );
6032 //================================================================================
6034 * \brief Re-load elements from a list of groups into a TIDSortedElemSet
6035 * \param [in] theGrpList - groups
6036 * \param [in] theMeshDS - mesh
6037 * \param [out] theElemSet - set of elements
6038 * \param [in] theIsNodeGrp - is \a theGrpList includes goups of nodes
6040 //================================================================================
6042 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
6043 SMESHDS_Mesh* theMeshDS,
6044 TIDSortedElemSet& theElemSet,
6045 const bool theIsNodeGrp)
6047 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
6049 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
6050 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
6051 : aGrp->GetType() != SMESH::NODE ) )
6053 SMESH::long_array_var anIDs = aGrp->GetIDs();
6054 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
6059 //================================================================================
6061 \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6062 This method provided for convenience works as DoubleNodes() described above.
6063 \param theElems - list of groups of elements (edges or faces) to be replicated
6064 \param theNodesNot - list of groups of nodes not to replicated
6065 \param theAffectedElems - group of elements to which the replicated nodes
6066 should be associated to.
6067 \return TRUE if operation has been completed successfully, FALSE otherwise
6068 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
6070 //================================================================================
6073 SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
6074 const SMESH::ListOfGroups& theNodesNot,
6075 const SMESH::ListOfGroups& theAffectedElems)
6076 throw (SALOME::SALOME_Exception)
6082 SMESHDS_Mesh* aMeshDS = getMeshDS();
6083 TIDSortedElemSet anElems, aNodes, anAffected;
6084 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6085 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6086 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6088 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6090 // Update Python script
6091 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
6092 << &theNodesNot << ", " << &theAffectedElems << " )";
6094 declareMeshModified( /*isReComputeSafe=*/false );
6097 SMESH_CATCH( SMESH::throwCorbaException );
6101 //================================================================================
6103 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6104 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6105 \param theElems - list of groups of elements (edges or faces) to be replicated
6106 \param theNodesNot - list of groups of nodes not to replicated
6107 \param theAffectedElems - group of elements to which the replicated nodes
6108 should be associated to.
6109 * \return a new group with newly created elements
6110 * \sa DoubleNodeElemGroups()
6112 //================================================================================
6114 SMESH::SMESH_Group_ptr
6115 SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
6116 const SMESH::ListOfGroups& theNodesNot,
6117 const SMESH::ListOfGroups& theAffectedElems)
6118 throw (SALOME::SALOME_Exception)
6121 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroups2New( theElems,
6125 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
6126 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
6128 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupsNew( "
6130 << theNodesNot << ", "
6131 << theAffectedElems << " )";
6133 return elemGroup._retn();
6136 //================================================================================
6138 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6139 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6140 \param theElems - list of groups of elements (edges or faces) to be replicated
6141 \param theNodesNot - list of groups of nodes not to replicated
6142 \param theAffectedElems - group of elements to which the replicated nodes
6143 should be associated to.
6144 * \return a new group with newly created elements
6145 * \sa DoubleNodeElemGroups()
6147 //================================================================================
6149 SMESH::ListOfGroups*
6150 SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems,
6151 const SMESH::ListOfGroups& theNodesNot,
6152 const SMESH::ListOfGroups& theAffectedElems,
6153 CORBA::Boolean theElemGroupNeeded,
6154 CORBA::Boolean theNodeGroupNeeded)
6155 throw (SALOME::SALOME_Exception)
6158 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
6159 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
6160 aTwoGroups->length( 2 );
6165 SMESHDS_Mesh* aMeshDS = getMeshDS();
6166 TIDSortedElemSet anElems, aNodes, anAffected;
6167 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6168 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6169 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6171 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6173 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6178 // Create group with newly created elements
6179 CORBA::String_var elemGroupName = theElems[0]->GetName();
6180 std::string aNewName = generateGroupName( std::string(elemGroupName.in()) + "_double");
6181 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
6183 SMESH::long_array_var anIds = GetLastCreatedElems();
6184 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
6185 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
6186 aNewElemGroup->Add(anIds);
6188 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
6190 SMESH::long_array_var anIds = GetLastCreatedNodes();
6191 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6192 aNewNodeGroup->Add(anIds);
6196 // Update Python script
6199 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
6200 else pyDump << aNewElemGroup << ", ";
6201 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
6202 else pyDump << aNewNodeGroup << " ] = ";
6204 pyDump << this << ".DoubleNodeElemGroups2New( " << &theElems << ", "
6205 << &theNodesNot << ", "
6206 << &theAffectedElems << ", "
6207 << theElemGroupNeeded << ", "
6208 << theNodeGroupNeeded << " )";
6210 aTwoGroups[0] = aNewElemGroup._retn();
6211 aTwoGroups[1] = aNewNodeGroup._retn();
6212 return aTwoGroups._retn();
6214 SMESH_CATCH( SMESH::throwCorbaException );
6218 //================================================================================
6220 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6221 This method provided for convenience works as DoubleNodes() described above.
6222 \param theElems - list of groups of elements (edges or faces) to be replicated
6223 \param theNodesNot - list of groups of nodes not to replicated
6224 \param theShape - shape to detect affected elements (element which geometric center
6225 located on or inside shape).
6226 The replicated nodes should be associated to affected elements.
6227 \return TRUE if operation has been completed successfully, FALSE otherwise
6228 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
6230 //================================================================================
6233 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
6234 const SMESH::ListOfGroups& theNodesNot,
6235 GEOM::GEOM_Object_ptr theShape )
6236 throw (SALOME::SALOME_Exception)
6242 SMESHDS_Mesh* aMeshDS = getMeshDS();
6243 TIDSortedElemSet anElems, aNodes;
6244 listOfGroupToSet(theElems, aMeshDS, anElems,false );
6245 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6247 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6248 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6250 // Update Python script
6251 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
6252 << &theNodesNot << ", " << theShape << " )";
6254 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6257 SMESH_CATCH( SMESH::throwCorbaException );
6261 //================================================================================
6263 \brief Identify the elements that will be affected by node duplication (actual
6264 duplication is not performed.
6265 This method is the first step of DoubleNodeElemGroupsInRegion.
6266 \param theElems - list of groups of elements (edges or faces) to be replicated
6267 \param theNodesNot - list of groups of nodes not to replicated
6268 \param theShape - shape to detect affected elements (element which geometric center
6269 located on or inside shape).
6270 The replicated nodes should be associated to affected elements.
6271 \return groups of affected elements
6272 \sa DoubleNodeElemGroupsInRegion()
6274 //================================================================================
6275 SMESH::ListOfGroups*
6276 SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theElems,
6277 const SMESH::ListOfGroups& theNodesNot,
6278 GEOM::GEOM_Object_ptr theShape )
6279 throw (SALOME::SALOME_Exception)
6282 MESSAGE("AffectedElemGroupsInRegion");
6283 SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
6284 bool isEdgeGroup = false;
6285 bool isFaceGroup = false;
6286 bool isVolumeGroup = false;
6287 SMESH::SMESH_Group_var aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE, "affectedEdges");
6288 SMESH::SMESH_Group_var aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE, "affectedFaces");
6289 SMESH::SMESH_Group_var aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME, "affectedVolumes");
6293 ::SMESH_MeshEditor aMeshEditor(myMesh);
6295 SMESHDS_Mesh* aMeshDS = getMeshDS();
6296 TIDSortedElemSet anElems, aNodes;
6297 listOfGroupToSet(theElems, aMeshDS, anElems, false);
6298 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true);
6300 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape(theShape);
6301 TIDSortedElemSet anAffected;
6302 bool aResult = aMeshEditor.AffectedElemGroupsInRegion(anElems, aNodes, aShape, anAffected);
6305 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6310 int lg = anAffected.size();
6311 MESSAGE("lg="<< lg);
6312 SMESH::long_array_var volumeIds = new SMESH::long_array;
6313 volumeIds->length(lg);
6314 SMESH::long_array_var faceIds = new SMESH::long_array;
6315 faceIds->length(lg);
6316 SMESH::long_array_var edgeIds = new SMESH::long_array;
6317 edgeIds->length(lg);
6322 TIDSortedElemSet::const_iterator eIt = anAffected.begin();
6323 for (; eIt != anAffected.end(); ++eIt)
6325 const SMDS_MeshElement* anElem = *eIt;
6328 int elemId = anElem->GetID();
6329 if (myMesh->GetElementType(elemId, true) == SMDSAbs_Volume)
6330 volumeIds[ivol++] = elemId;
6331 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Face)
6332 faceIds[iface++] = elemId;
6333 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Edge)
6334 edgeIds[iedge++] = elemId;
6336 volumeIds->length(ivol);
6337 faceIds->length(iface);
6338 edgeIds->length(iedge);
6340 aNewVolumeGroup->Add(volumeIds);
6341 aNewFaceGroup->Add(faceIds);
6342 aNewEdgeGroup->Add(edgeIds);
6343 isVolumeGroup = (aNewVolumeGroup->Size() > 0);
6344 isFaceGroup = (aNewFaceGroup->Size() > 0);
6345 isEdgeGroup = (aNewEdgeGroup->Size() > 0);
6349 if (isEdgeGroup) nbGroups++;
6350 if (isFaceGroup) nbGroups++;
6351 if (isVolumeGroup) nbGroups++;
6352 aListOfGroups->length(nbGroups);
6355 if (isEdgeGroup) aListOfGroups[i++] = aNewEdgeGroup._retn();
6356 if (isFaceGroup) aListOfGroups[i++] = aNewFaceGroup._retn();
6357 if (isVolumeGroup) aListOfGroups[i++] = aNewVolumeGroup._retn();
6359 // Update Python script
6362 if (isEdgeGroup) pyDump << aNewEdgeGroup << ", ";
6363 if (isFaceGroup) pyDump << aNewFaceGroup << ", ";
6364 if (isVolumeGroup) pyDump << aNewVolumeGroup << ", ";
6366 pyDump << this << ".AffectedElemGroupsInRegion( "
6367 << &theElems << ", " << &theNodesNot << ", " << theShape << " )";
6369 return aListOfGroups._retn();
6371 SMESH_CATCH( SMESH::throwCorbaException );
6375 //================================================================================
6377 \brief Generated skin mesh (containing 2D cells) from 3D mesh
6378 The created 2D mesh elements based on nodes of free faces of boundary volumes
6379 \return TRUE if operation has been completed successfully, FALSE otherwise
6381 //================================================================================
6383 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
6384 throw (SALOME::SALOME_Exception)
6389 bool aResult = getEditor().Make2DMeshFrom3D();
6391 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
6393 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6396 SMESH_CATCH( SMESH::throwCorbaException );
6400 //================================================================================
6402 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
6403 * The list of groups must contain at least two groups. The groups have to be disjoint:
6404 * no common element into two different groups.
6405 * The nodes of the internal faces at the boundaries of the groups are doubled.
6406 * Optionally, the internal faces are replaced by flat elements.
6407 * Triangles are transformed into prisms, and quadrangles into hexahedrons.
6408 * The flat elements are stored in groups of volumes.
6409 * These groups are named according to the position of the group in the list:
6410 * 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.
6411 * 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.
6412 * All the flat elements are gathered into the group named "joints3D" (or "joints2D" in 2D situation).
6413 * The flat element of the multiple junctions between the simple junction are stored in a group named "jointsMultiples".
6414 * \param theDomains - list of groups of volumes
6415 * \param createJointElems - if TRUE, create the elements
6416 * \param onAllBoundaries - if TRUE, the nodes and elements are also created on
6417 * the boundary between \a theDomains and the rest mesh
6418 * \return TRUE if operation has been completed successfully, FALSE otherwise
6420 //================================================================================
6423 SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
6424 CORBA::Boolean createJointElems,
6425 CORBA::Boolean onAllBoundaries )
6426 throw (SALOME::SALOME_Exception)
6433 SMESHDS_Mesh* aMeshDS = getMeshDS();
6435 // MESSAGE("theDomains.length = "<<theDomains.length());
6436 if ( theDomains.length() <= 1 && !onAllBoundaries )
6437 THROW_SALOME_CORBA_EXCEPTION("At least 2 groups are required.", SALOME::BAD_PARAM);
6439 vector<TIDSortedElemSet> domains;
6440 domains.resize( theDomains.length() );
6442 for ( int i = 0, n = theDomains.length(); i < n; i++ )
6444 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
6445 if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
6447 // if ( aGrp->GetType() != SMESH::VOLUME )
6448 // THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
6449 SMESH::long_array_var anIDs = aGrp->GetIDs();
6450 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
6454 isOK = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems, onAllBoundaries );
6455 // TODO publish the groups of flat elements in study
6457 declareMeshModified( /*isReComputeSafe=*/ !isOK );
6459 // Update Python script
6460 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
6461 << ", " << createJointElems << ", " << onAllBoundaries << " )";
6463 SMESH_CATCH( SMESH::throwCorbaException );
6465 myMesh_i->CreateGroupServants(); // publish created groups if any
6470 //================================================================================
6472 * \brief Double nodes on some external faces and create flat elements.
6473 * Flat elements are mainly used by some types of mechanic calculations.
6475 * Each group of the list must be constituted of faces.
6476 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
6477 * @param theGroupsOfFaces - list of groups of faces
6478 * @return TRUE if operation has been completed successfully, FALSE otherwise
6480 //================================================================================
6483 SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
6484 throw (SALOME::SALOME_Exception)
6489 SMESHDS_Mesh* aMeshDS = getMeshDS();
6491 vector<TIDSortedElemSet> faceGroups;
6494 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
6496 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
6497 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
6499 TIDSortedElemSet faceGroup;
6501 faceGroups.push_back(faceGroup);
6502 SMESH::long_array_var anIDs = aGrp->GetIDs();
6503 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
6507 bool aResult = getEditor().CreateFlatElementsOnFacesGroups( faceGroups );
6508 // TODO publish the groups of flat elements in study
6510 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6512 // Update Python script
6513 TPythonDump() << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
6516 SMESH_CATCH( SMESH::throwCorbaException );
6520 //================================================================================
6522 * \brief Identify all the elements around a geom shape, get the faces delimiting
6525 * Build groups of volume to remove, groups of faces to replace on the skin of the
6526 * object, groups of faces to remove inside the object, (idem edges).
6527 * Build ordered list of nodes at the border of each group of faces to replace
6528 * (to be used to build a geom subshape).
6530 //================================================================================
6532 void SMESH_MeshEditor_i::CreateHoleSkin(CORBA::Double radius,
6533 GEOM::GEOM_Object_ptr theShape,
6534 const char* groupName,
6535 const SMESH::double_array& theNodesCoords,
6536 SMESH::array_of_long_array_out GroupsOfNodes)
6537 throw (SALOME::SALOME_Exception)
6542 std::vector<std::vector<int> > aListOfListOfNodes;
6543 ::SMESH_MeshEditor aMeshEditor( myMesh );
6545 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
6546 if ( !theNodeSearcher )
6547 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
6549 vector<double> nodesCoords;
6550 for ( CORBA::ULong i = 0; i < theNodesCoords.length(); i++)
6552 nodesCoords.push_back( theNodesCoords[i] );
6555 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6556 aMeshEditor.CreateHoleSkin(radius, aShape, theNodeSearcher, groupName,
6557 nodesCoords, aListOfListOfNodes);
6559 GroupsOfNodes = new SMESH::array_of_long_array;
6560 GroupsOfNodes->length( aListOfListOfNodes.size() );
6561 std::vector<std::vector<int> >::iterator llIt = aListOfListOfNodes.begin();
6562 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
6564 vector<int>& aListOfNodes = *llIt;
6565 vector<int>::iterator lIt = aListOfNodes.begin();;
6566 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
6567 aGroup.length( aListOfNodes.size() );
6568 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
6569 aGroup[ j ] = (*lIt);
6571 TPythonDump() << "lists_nodes = " << this << ".CreateHoleSkin( "
6574 << ", '" << groupName << "', "
6575 << theNodesCoords << " )";
6577 SMESH_CATCH( SMESH::throwCorbaException );
6580 // issue 20749 ===================================================================
6582 * \brief Creates missing boundary elements
6583 * \param elements - elements whose boundary is to be checked
6584 * \param dimension - defines type of boundary elements to create
6585 * \param groupName - a name of group to store created boundary elements in,
6586 * "" means not to create the group
6587 * \param meshName - a name of new mesh to store created boundary elements in,
6588 * "" means not to create the new mesh
6589 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
6590 * \param toCopyExistingBondary - if true, not only new but also pre-existing
6591 * boundary elements will be copied into the new mesh
6592 * \param group - returns the create group, if any
6593 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
6595 // ================================================================================
6597 SMESH::SMESH_Mesh_ptr
6598 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
6599 SMESH::Bnd_Dimension dim,
6600 const char* groupName,
6601 const char* meshName,
6602 CORBA::Boolean toCopyElements,
6603 CORBA::Boolean toCopyExistingBondary,
6604 SMESH::SMESH_Group_out group)
6605 throw (SALOME::SALOME_Exception)
6610 if ( dim > SMESH::BND_1DFROM2D )
6611 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
6613 SMESHDS_Mesh* aMeshDS = getMeshDS();
6615 SMESH::SMESH_Mesh_var mesh_var;
6616 SMESH::SMESH_Group_var group_var;
6620 TIDSortedElemSet elements;
6621 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
6622 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
6626 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
6627 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
6629 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
6631 // group of new boundary elements
6632 SMESH_Group* smesh_group = 0;
6633 if ( strlen(groupName) )
6635 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
6636 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
6637 smesh_group = group_i->GetSmeshGroup();
6641 getEditor().MakeBoundaryMesh( elements,
6642 ::SMESH_MeshEditor::Bnd_Dimension(dim),
6646 toCopyExistingBondary);
6649 smesh_mesh->GetMeshDS()->Modified();
6652 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
6654 // result of MakeBoundaryMesh() is a tuple (mesh, group)
6655 if ( mesh_var->_is_nil() )
6656 pyDump << myMesh_i->_this() << ", ";
6658 pyDump << mesh_var << ", ";
6659 if ( group_var->_is_nil() )
6660 pyDump << "_NoneGroup = "; // assignment to None is forbiden
6662 pyDump << group_var << " = ";
6663 pyDump << this << ".MakeBoundaryMesh( "
6665 << "SMESH." << dimName[int(dim)] << ", "
6666 << "'" << groupName << "', "
6667 << "'" << meshName<< "', "
6668 << toCopyElements << ", "
6669 << toCopyExistingBondary << ")";
6671 group = group_var._retn();
6672 return mesh_var._retn();
6674 SMESH_CATCH( SMESH::throwCorbaException );
6675 return SMESH::SMESH_Mesh::_nil();
6678 //================================================================================
6680 * \brief Creates missing boundary elements
6681 * \param dimension - defines type of boundary elements to create
6682 * \param groupName - a name of group to store all boundary elements in,
6683 * "" means not to create the group
6684 * \param meshName - a name of a new mesh, which is a copy of the initial
6685 * mesh + created boundary elements; "" means not to create the new mesh
6686 * \param toCopyAll - if true, the whole initial mesh will be copied into
6687 * the new mesh else only boundary elements will be copied into the new mesh
6688 * \param groups - optional groups of elements to make boundary around
6689 * \param mesh - returns the mesh where elements were added to
6690 * \param group - returns the created group, if any
6691 * \retval long - number of added boundary elements
6693 //================================================================================
6695 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
6696 const char* groupName,
6697 const char* meshName,
6698 CORBA::Boolean toCopyAll,
6699 const SMESH::ListOfIDSources& groups,
6700 SMESH::SMESH_Mesh_out mesh,
6701 SMESH::SMESH_Group_out group)
6702 throw (SALOME::SALOME_Exception)
6707 if ( dim > SMESH::BND_1DFROM2D )
6708 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
6710 // separate groups belonging to this and other mesh
6711 SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
6712 SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
6713 groupsOfThisMesh ->length( groups.length() );
6714 groupsOfOtherMesh->length( groups.length() );
6715 int nbGroups = 0, nbGroupsOfOtherMesh = 0;
6716 for ( CORBA::ULong i = 0; i < groups.length(); ++i )
6718 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
6719 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
6720 groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
6722 groupsOfThisMesh[ nbGroups++ ] = groups[i];
6723 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
6724 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
6726 groupsOfThisMesh->length( nbGroups );
6727 groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
6732 if ( nbGroupsOfOtherMesh > 0 )
6734 // process groups belonging to another mesh
6735 SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
6736 SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
6737 nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
6738 groupsOfOtherMesh, mesh, group );
6741 SMESH::SMESH_Mesh_var mesh_var;
6742 SMESH::SMESH_Group_var group_var;
6745 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
6746 const bool toCopyMesh = ( strlen( meshName ) > 0 );
6750 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
6752 /*toCopyGroups=*/false,
6753 /*toKeepIDs=*/true);
6755 mesh_var = makeMesh(meshName);
6757 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
6758 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
6761 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
6762 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
6764 // group of boundary elements
6765 SMESH_Group* smesh_group = 0;
6766 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
6767 if ( strlen(groupName) )
6769 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
6770 group_var = mesh_i->CreateGroup( groupType, groupName );
6771 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
6772 smesh_group = group_i->GetSmeshGroup();
6775 TIDSortedElemSet elements;
6777 if ( groups.length() > 0 )
6779 for ( int i = 0; i < nbGroups; ++i )
6782 if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
6784 SMESH::Bnd_Dimension bdim =
6785 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
6786 nbAdded += getEditor().MakeBoundaryMesh( elements,
6787 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
6790 /*toCopyElements=*/false,
6791 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
6792 /*toAddExistingBondary=*/true,
6793 /*aroundElements=*/true);
6799 nbAdded += getEditor().MakeBoundaryMesh( elements,
6800 ::SMESH_MeshEditor::Bnd_Dimension(dim),
6803 /*toCopyElements=*/false,
6804 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
6805 /*toAddExistingBondary=*/true);
6807 tgtMesh->GetMeshDS()->Modified();
6809 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
6811 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
6812 pyDump << "nbAdded, ";
6813 if ( mesh_var->_is_nil() )
6814 pyDump << myMesh_i->_this() << ", ";
6816 pyDump << mesh_var << ", ";
6817 if ( group_var->_is_nil() )
6818 pyDump << "_NoneGroup = "; // assignment to None is forbiden
6820 pyDump << group_var << " = ";
6821 pyDump << this << ".MakeBoundaryElements( "
6822 << "SMESH." << dimName[int(dim)] << ", "
6823 << "'" << groupName << "', "
6824 << "'" << meshName<< "', "
6825 << toCopyAll << ", "
6828 mesh = mesh_var._retn();
6829 group = group_var._retn();
6832 SMESH_CATCH( SMESH::throwCorbaException );