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 occurred
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 further mesh re-compute.
471 * \param [in] isReComputeSafe - true if the modification does not influence
472 * further 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 per 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 occurred 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 if ( aGroups->length() > 0 ) aPythonDump << "(" << aGroups << ", error) = ";
2956 else aPythonDump << "(_noGroups, error) = ";
2957 aPythonDump << this << ".ExtrusionAlongPathObjects( "
2961 << thePathMesh << ", "
2962 << thePathShape << ", "
2963 << theNodeStart << ", "
2964 << theHasAngles << ", "
2965 << TVar( theAngles ) << ", "
2966 << theLinearVariation << ", "
2967 << theHasRefPoint << ", "
2968 << "SMESH.PointStruct( "
2969 << TVar( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2970 << TVar( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2971 << TVar( theHasRefPoint ? theRefPoint.z : 0 ) << " ), "
2972 << theMakeGroups << " )";
2976 getPreviewMesh()->Remove( SMDSAbs_Volume );
2979 return aGroups._retn();
2981 SMESH_CATCH( SMESH::throwCorbaException );
2985 //================================================================================
2987 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
2988 * of given angles along path steps
2989 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
2990 * which proceeds the extrusion
2991 * \param PathShape is shape(edge); as the mesh can be complex, the edge
2992 * is used to define the sub-mesh for the path
2994 //================================================================================
2996 SMESH::double_array*
2997 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
2998 GEOM::GEOM_Object_ptr thePathShape,
2999 const SMESH::double_array & theAngles)
3001 SMESH::double_array_var aResult = new SMESH::double_array();
3002 int nbAngles = theAngles.length();
3003 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
3005 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3006 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3007 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3008 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
3009 return aResult._retn();
3010 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
3011 if ( nbSteps == nbAngles )
3013 aResult.inout() = theAngles;
3017 aResult->length( nbSteps );
3018 double rAn2St = double( nbAngles ) / double( nbSteps );
3019 double angPrev = 0, angle;
3020 for ( int iSt = 0; iSt < nbSteps; ++iSt )
3022 double angCur = rAn2St * ( iSt+1 );
3023 double angCurFloor = floor( angCur );
3024 double angPrevFloor = floor( angPrev );
3025 if ( angPrevFloor == angCurFloor )
3026 angle = rAn2St * theAngles[ int( angCurFloor ) ];
3029 int iP = int( angPrevFloor );
3030 double angPrevCeil = ceil(angPrev);
3031 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
3033 int iC = int( angCurFloor );
3034 if ( iC < nbAngles )
3035 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
3037 iP = int( angPrevCeil );
3039 angle += theAngles[ iC ];
3041 aResult[ iSt ] = angle;
3046 // Update Python script
3047 TPythonDump() << "rotAngles = " << theAngles;
3048 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
3049 << thePathMesh << ", "
3050 << thePathShape << ", "
3053 return aResult._retn();
3056 //=======================================================================
3059 //=======================================================================
3061 SMESH::ListOfGroups*
3062 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
3063 const SMESH::AxisStruct & theAxis,
3064 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3065 CORBA::Boolean theCopy,
3067 ::SMESH_Mesh* theTargetMesh)
3068 throw (SALOME::SALOME_Exception)
3073 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3074 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3076 if ( theTargetMesh )
3080 switch ( theMirrorType ) {
3081 case SMESH::SMESH_MeshEditor::POINT:
3082 aTrsf.SetMirror( P );
3084 case SMESH::SMESH_MeshEditor::AXIS:
3085 aTrsf.SetMirror( gp_Ax1( P, V ));
3088 aTrsf.SetMirror( gp_Ax2( P, V ));
3091 TIDSortedElemSet copyElements;
3092 TIDSortedElemSet* workElements = & theElements;
3094 if ( myIsPreviewMode )
3096 TPreviewMesh * tmpMesh = getPreviewMesh();
3097 tmpMesh->Copy( theElements, copyElements);
3098 if ( !theCopy && !theTargetMesh )
3100 TIDSortedElemSet elemsAround, elemsAroundCopy;
3101 getElementsAround( theElements, getMeshDS(), elemsAround );
3102 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3104 workElements = & copyElements;
3105 theMakeGroups = false;
3108 ::SMESH_MeshEditor::PGroupIDs groupIds =
3109 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3111 if ( !myIsPreviewMode )
3113 if ( theTargetMesh )
3114 theTargetMesh->GetMeshDS()->Modified();
3116 declareMeshModified( /*isReComputeSafe=*/false );
3119 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3121 SMESH_CATCH( SMESH::throwCorbaException );
3125 //=======================================================================
3128 //=======================================================================
3130 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3131 const SMESH::AxisStruct & theAxis,
3132 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3133 CORBA::Boolean theCopy)
3134 throw (SALOME::SALOME_Exception)
3136 if ( !myIsPreviewMode ) {
3137 TPythonDump() << this << ".Mirror( "
3138 << theIDsOfElements << ", "
3140 << mirrorTypeName(theMirrorType) << ", "
3143 if ( theIDsOfElements.length() > 0 )
3145 TIDSortedElemSet elements;
3146 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3147 mirror(elements, theAxis, theMirrorType, theCopy, false);
3152 //=======================================================================
3153 //function : MirrorObject
3155 //=======================================================================
3157 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3158 const SMESH::AxisStruct & theAxis,
3159 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3160 CORBA::Boolean theCopy)
3161 throw (SALOME::SALOME_Exception)
3163 if ( !myIsPreviewMode ) {
3164 TPythonDump() << this << ".MirrorObject( "
3165 << theObject << ", "
3167 << mirrorTypeName(theMirrorType) << ", "
3170 TIDSortedElemSet elements;
3172 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3174 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3175 mirror(elements, theAxis, theMirrorType, theCopy, false);
3178 //=======================================================================
3179 //function : MirrorMakeGroups
3181 //=======================================================================
3183 SMESH::ListOfGroups*
3184 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3185 const SMESH::AxisStruct& theMirror,
3186 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3187 throw (SALOME::SALOME_Exception)
3189 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3191 SMESH::ListOfGroups * aGroups = 0;
3192 if ( theIDsOfElements.length() > 0 )
3194 TIDSortedElemSet elements;
3195 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3196 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3198 if (!myIsPreviewMode) {
3199 dumpGroupsList(aPythonDump, aGroups);
3200 aPythonDump << this << ".MirrorMakeGroups( "
3201 << theIDsOfElements << ", "
3202 << theMirror << ", "
3203 << mirrorTypeName(theMirrorType) << " )";
3208 //=======================================================================
3209 //function : MirrorObjectMakeGroups
3211 //=======================================================================
3213 SMESH::ListOfGroups*
3214 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3215 const SMESH::AxisStruct& theMirror,
3216 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3217 throw (SALOME::SALOME_Exception)
3219 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3221 SMESH::ListOfGroups * aGroups = 0;
3222 TIDSortedElemSet elements;
3223 if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3224 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3226 if (!myIsPreviewMode)
3228 dumpGroupsList(aPythonDump,aGroups);
3229 aPythonDump << this << ".MirrorObjectMakeGroups( "
3230 << theObject << ", "
3231 << theMirror << ", "
3232 << mirrorTypeName(theMirrorType) << " )";
3237 //=======================================================================
3238 //function : MirrorMakeMesh
3240 //=======================================================================
3242 SMESH::SMESH_Mesh_ptr
3243 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
3244 const SMESH::AxisStruct& theMirror,
3245 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3246 CORBA::Boolean theCopyGroups,
3247 const char* theMeshName)
3248 throw (SALOME::SALOME_Exception)
3250 SMESH_Mesh_i* mesh_i;
3251 SMESH::SMESH_Mesh_var mesh;
3252 { // open new scope to dump "MakeMesh" command
3253 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3255 TPythonDump pydump; // to prevent dump at mesh creation
3257 mesh = makeMesh( theMeshName );
3258 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3259 if (mesh_i && theIDsOfElements.length() > 0 )
3261 TIDSortedElemSet elements;
3262 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3263 mirror(elements, theMirror, theMirrorType,
3264 false, theCopyGroups, & mesh_i->GetImpl());
3265 mesh_i->CreateGroupServants();
3268 if (!myIsPreviewMode) {
3269 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
3270 << theIDsOfElements << ", "
3271 << theMirror << ", "
3272 << mirrorTypeName(theMirrorType) << ", "
3273 << theCopyGroups << ", '"
3274 << theMeshName << "' )";
3279 if (!myIsPreviewMode && mesh_i)
3280 mesh_i->GetGroups();
3282 return mesh._retn();
3285 //=======================================================================
3286 //function : MirrorObjectMakeMesh
3288 //=======================================================================
3290 SMESH::SMESH_Mesh_ptr
3291 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3292 const SMESH::AxisStruct& theMirror,
3293 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3294 CORBA::Boolean theCopyGroups,
3295 const char* theMeshName)
3296 throw (SALOME::SALOME_Exception)
3298 SMESH_Mesh_i* mesh_i;
3299 SMESH::SMESH_Mesh_var mesh;
3300 { // open new scope to dump "MakeMesh" command
3301 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3303 TPythonDump pydump; // to prevent dump at mesh creation
3305 mesh = makeMesh( theMeshName );
3306 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3307 TIDSortedElemSet elements;
3309 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3311 mirror(elements, theMirror, theMirrorType,
3312 false, theCopyGroups, & mesh_i->GetImpl());
3313 mesh_i->CreateGroupServants();
3315 if (!myIsPreviewMode) {
3316 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
3317 << theObject << ", "
3318 << theMirror << ", "
3319 << mirrorTypeName(theMirrorType) << ", "
3320 << theCopyGroups << ", '"
3321 << theMeshName << "' )";
3326 if (!myIsPreviewMode && mesh_i)
3327 mesh_i->GetGroups();
3329 return mesh._retn();
3332 //=======================================================================
3333 //function : translate
3335 //=======================================================================
3337 SMESH::ListOfGroups*
3338 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
3339 const SMESH::DirStruct & theVector,
3340 CORBA::Boolean theCopy,
3342 ::SMESH_Mesh* theTargetMesh)
3343 throw (SALOME::SALOME_Exception)
3348 if ( theTargetMesh )
3352 const SMESH::PointStruct * P = &theVector.PS;
3353 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
3355 TIDSortedElemSet copyElements;
3356 TIDSortedElemSet* workElements = &theElements;
3358 if ( myIsPreviewMode )
3360 TPreviewMesh * tmpMesh = getPreviewMesh();
3361 tmpMesh->Copy( theElements, copyElements);
3362 if ( !theCopy && !theTargetMesh )
3364 TIDSortedElemSet elemsAround, elemsAroundCopy;
3365 getElementsAround( theElements, getMeshDS(), elemsAround );
3366 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3368 workElements = & copyElements;
3369 theMakeGroups = false;
3372 ::SMESH_MeshEditor::PGroupIDs groupIds =
3373 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3375 if ( !myIsPreviewMode )
3377 if ( theTargetMesh )
3378 theTargetMesh->GetMeshDS()->Modified();
3380 declareMeshModified( /*isReComputeSafe=*/false );
3383 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3385 SMESH_CATCH( SMESH::throwCorbaException );
3389 //=======================================================================
3390 //function : Translate
3392 //=======================================================================
3394 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
3395 const SMESH::DirStruct & theVector,
3396 CORBA::Boolean theCopy)
3397 throw (SALOME::SALOME_Exception)
3399 if (!myIsPreviewMode) {
3400 TPythonDump() << this << ".Translate( "
3401 << theIDsOfElements << ", "
3402 << theVector << ", "
3405 if (theIDsOfElements.length()) {
3406 TIDSortedElemSet elements;
3407 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3408 translate(elements, theVector, theCopy, false);
3412 //=======================================================================
3413 //function : TranslateObject
3415 //=======================================================================
3417 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
3418 const SMESH::DirStruct & theVector,
3419 CORBA::Boolean theCopy)
3420 throw (SALOME::SALOME_Exception)
3422 if (!myIsPreviewMode) {
3423 TPythonDump() << this << ".TranslateObject( "
3424 << theObject << ", "
3425 << theVector << ", "
3428 TIDSortedElemSet elements;
3430 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3432 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3433 translate(elements, theVector, theCopy, false);
3436 //=======================================================================
3437 //function : TranslateMakeGroups
3439 //=======================================================================
3441 SMESH::ListOfGroups*
3442 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
3443 const SMESH::DirStruct& theVector)
3444 throw (SALOME::SALOME_Exception)
3446 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3448 SMESH::ListOfGroups * aGroups = 0;
3449 if (theIDsOfElements.length()) {
3450 TIDSortedElemSet elements;
3451 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3452 aGroups = translate(elements,theVector,true,true);
3454 if (!myIsPreviewMode) {
3455 dumpGroupsList(aPythonDump, aGroups);
3456 aPythonDump << this << ".TranslateMakeGroups( "
3457 << theIDsOfElements << ", "
3458 << theVector << " )";
3463 //=======================================================================
3464 //function : TranslateObjectMakeGroups
3466 //=======================================================================
3468 SMESH::ListOfGroups*
3469 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3470 const SMESH::DirStruct& theVector)
3471 throw (SALOME::SALOME_Exception)
3473 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3475 SMESH::ListOfGroups * aGroups = 0;
3476 TIDSortedElemSet elements;
3477 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3478 aGroups = translate(elements, theVector, true, true);
3480 if (!myIsPreviewMode) {
3481 dumpGroupsList(aPythonDump, aGroups);
3482 aPythonDump << this << ".TranslateObjectMakeGroups( "
3483 << theObject << ", "
3484 << theVector << " )";
3489 //=======================================================================
3490 //function : TranslateMakeMesh
3492 //=======================================================================
3494 SMESH::SMESH_Mesh_ptr
3495 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
3496 const SMESH::DirStruct& theVector,
3497 CORBA::Boolean theCopyGroups,
3498 const char* theMeshName)
3499 throw (SALOME::SALOME_Exception)
3501 SMESH_Mesh_i* mesh_i;
3502 SMESH::SMESH_Mesh_var mesh;
3504 { // open new scope to dump "MakeMesh" command
3505 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3507 TPythonDump pydump; // to prevent dump at mesh creation
3509 mesh = makeMesh( theMeshName );
3510 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3512 if ( mesh_i && theIDsOfElements.length() )
3514 TIDSortedElemSet elements;
3515 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3516 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
3517 mesh_i->CreateGroupServants();
3520 if ( !myIsPreviewMode ) {
3521 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
3522 << theIDsOfElements << ", "
3523 << theVector << ", "
3524 << theCopyGroups << ", '"
3525 << theMeshName << "' )";
3530 if (!myIsPreviewMode && mesh_i)
3531 mesh_i->GetGroups();
3533 return mesh._retn();
3536 //=======================================================================
3537 //function : TranslateObjectMakeMesh
3539 //=======================================================================
3541 SMESH::SMESH_Mesh_ptr
3542 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3543 const SMESH::DirStruct& theVector,
3544 CORBA::Boolean theCopyGroups,
3545 const char* theMeshName)
3546 throw (SALOME::SALOME_Exception)
3549 SMESH_Mesh_i* mesh_i;
3550 SMESH::SMESH_Mesh_var mesh;
3551 { // open new scope to dump "MakeMesh" command
3552 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3554 TPythonDump pydump; // to prevent dump at mesh creation
3555 mesh = makeMesh( theMeshName );
3556 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3558 TIDSortedElemSet elements;
3560 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3562 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
3563 mesh_i->CreateGroupServants();
3565 if ( !myIsPreviewMode ) {
3566 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
3567 << theObject << ", "
3568 << theVector << ", "
3569 << theCopyGroups << ", '"
3570 << theMeshName << "' )";
3575 if (!myIsPreviewMode && mesh_i)
3576 mesh_i->GetGroups();
3578 return mesh._retn();
3580 SMESH_CATCH( SMESH::throwCorbaException );
3584 //=======================================================================
3587 //=======================================================================
3589 SMESH::ListOfGroups*
3590 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
3591 const SMESH::AxisStruct & theAxis,
3592 CORBA::Double theAngle,
3593 CORBA::Boolean theCopy,
3595 ::SMESH_Mesh* theTargetMesh)
3596 throw (SALOME::SALOME_Exception)
3601 if ( theTargetMesh )
3604 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3605 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3608 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
3610 TIDSortedElemSet copyElements;
3611 TIDSortedElemSet* workElements = &theElements;
3612 if ( myIsPreviewMode ) {
3613 TPreviewMesh * tmpMesh = getPreviewMesh();
3614 tmpMesh->Copy( theElements, copyElements );
3615 if ( !theCopy && !theTargetMesh )
3617 TIDSortedElemSet elemsAround, elemsAroundCopy;
3618 getElementsAround( theElements, getMeshDS(), elemsAround );
3619 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3621 workElements = ©Elements;
3622 theMakeGroups = false;
3625 ::SMESH_MeshEditor::PGroupIDs groupIds =
3626 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3628 if ( !myIsPreviewMode)
3630 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
3631 else declareMeshModified( /*isReComputeSafe=*/false );
3634 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3636 SMESH_CATCH( SMESH::throwCorbaException );
3640 //=======================================================================
3643 //=======================================================================
3645 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
3646 const SMESH::AxisStruct & theAxis,
3647 CORBA::Double theAngle,
3648 CORBA::Boolean theCopy)
3649 throw (SALOME::SALOME_Exception)
3651 if (!myIsPreviewMode) {
3652 TPythonDump() << this << ".Rotate( "
3653 << theIDsOfElements << ", "
3655 << TVar( theAngle ) << ", "
3658 if (theIDsOfElements.length() > 0)
3660 TIDSortedElemSet elements;
3661 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3662 rotate(elements,theAxis,theAngle,theCopy,false);
3666 //=======================================================================
3667 //function : RotateObject
3669 //=======================================================================
3671 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
3672 const SMESH::AxisStruct & theAxis,
3673 CORBA::Double theAngle,
3674 CORBA::Boolean theCopy)
3675 throw (SALOME::SALOME_Exception)
3677 if ( !myIsPreviewMode ) {
3678 TPythonDump() << this << ".RotateObject( "
3679 << theObject << ", "
3681 << TVar( theAngle ) << ", "
3684 TIDSortedElemSet elements;
3685 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3686 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3687 rotate(elements,theAxis,theAngle,theCopy,false);
3690 //=======================================================================
3691 //function : RotateMakeGroups
3693 //=======================================================================
3695 SMESH::ListOfGroups*
3696 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
3697 const SMESH::AxisStruct& theAxis,
3698 CORBA::Double theAngle)
3699 throw (SALOME::SALOME_Exception)
3701 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3703 SMESH::ListOfGroups * aGroups = 0;
3704 if (theIDsOfElements.length() > 0)
3706 TIDSortedElemSet elements;
3707 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3708 aGroups = rotate(elements,theAxis,theAngle,true,true);
3710 if (!myIsPreviewMode) {
3711 dumpGroupsList(aPythonDump, aGroups);
3712 aPythonDump << this << ".RotateMakeGroups( "
3713 << theIDsOfElements << ", "
3715 << TVar( theAngle ) << " )";
3720 //=======================================================================
3721 //function : RotateObjectMakeGroups
3723 //=======================================================================
3725 SMESH::ListOfGroups*
3726 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3727 const SMESH::AxisStruct& theAxis,
3728 CORBA::Double theAngle)
3729 throw (SALOME::SALOME_Exception)
3731 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3733 SMESH::ListOfGroups * aGroups = 0;
3734 TIDSortedElemSet elements;
3735 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3736 aGroups = rotate(elements, theAxis, theAngle, true, true);
3738 if (!myIsPreviewMode) {
3739 dumpGroupsList(aPythonDump, aGroups);
3740 aPythonDump << this << ".RotateObjectMakeGroups( "
3741 << theObject << ", "
3743 << TVar( theAngle ) << " )";
3748 //=======================================================================
3749 //function : RotateMakeMesh
3751 //=======================================================================
3753 SMESH::SMESH_Mesh_ptr
3754 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
3755 const SMESH::AxisStruct& theAxis,
3756 CORBA::Double theAngleInRadians,
3757 CORBA::Boolean theCopyGroups,
3758 const char* theMeshName)
3759 throw (SALOME::SALOME_Exception)
3762 SMESH::SMESH_Mesh_var mesh;
3763 SMESH_Mesh_i* mesh_i;
3765 { // open new scope to dump "MakeMesh" command
3766 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3768 TPythonDump pydump; // to prevent dump at mesh creation
3770 mesh = makeMesh( theMeshName );
3771 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3773 if ( mesh_i && theIDsOfElements.length() > 0 )
3775 TIDSortedElemSet elements;
3776 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3777 rotate(elements, theAxis, theAngleInRadians,
3778 false, theCopyGroups, & mesh_i->GetImpl());
3779 mesh_i->CreateGroupServants();
3781 if ( !myIsPreviewMode ) {
3782 pydump << mesh << " = " << this << ".RotateMakeMesh( "
3783 << theIDsOfElements << ", "
3785 << TVar( theAngleInRadians ) << ", "
3786 << theCopyGroups << ", '"
3787 << theMeshName << "' )";
3792 if (!myIsPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
3793 mesh_i->GetGroups();
3795 return mesh._retn();
3797 SMESH_CATCH( SMESH::throwCorbaException );
3801 //=======================================================================
3802 //function : RotateObjectMakeMesh
3804 //=======================================================================
3806 SMESH::SMESH_Mesh_ptr
3807 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3808 const SMESH::AxisStruct& theAxis,
3809 CORBA::Double theAngleInRadians,
3810 CORBA::Boolean theCopyGroups,
3811 const char* theMeshName)
3812 throw (SALOME::SALOME_Exception)
3815 SMESH::SMESH_Mesh_var mesh;
3816 SMESH_Mesh_i* mesh_i;
3818 {// open new scope to dump "MakeMesh" command
3819 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3821 TPythonDump pydump; // to prevent dump at mesh creation
3822 mesh = makeMesh( theMeshName );
3823 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3825 TIDSortedElemSet elements;
3827 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3829 rotate(elements, theAxis, theAngleInRadians,
3830 false, theCopyGroups, & mesh_i->GetImpl());
3831 mesh_i->CreateGroupServants();
3833 if ( !myIsPreviewMode ) {
3834 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
3835 << theObject << ", "
3837 << TVar( theAngleInRadians ) << ", "
3838 << theCopyGroups << ", '"
3839 << theMeshName << "' )";
3844 if (!myIsPreviewMode && mesh_i)
3845 mesh_i->GetGroups();
3847 return mesh._retn();
3849 SMESH_CATCH( SMESH::throwCorbaException );
3853 //=======================================================================
3856 //=======================================================================
3858 SMESH::ListOfGroups*
3859 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
3860 const SMESH::PointStruct& thePoint,
3861 const SMESH::double_array& theScaleFact,
3862 CORBA::Boolean theCopy,
3864 ::SMESH_Mesh* theTargetMesh)
3865 throw (SALOME::SALOME_Exception)
3869 if ( theScaleFact.length() < 1 )
3870 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
3871 if ( theScaleFact.length() == 2 )
3872 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
3874 if ( theTargetMesh )
3877 TIDSortedElemSet elements;
3878 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3879 if ( !idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3884 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
3885 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
3889 #if OCC_VERSION_LARGE > 0x06070100
3890 // fight against orthogonalization
3891 // aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
3892 // 0, S[1], 0, thePoint.y * (1-S[1]),
3893 // 0, 0, S[2], thePoint.z * (1-S[2]) );
3894 aTrsf.SetScale( gp::Origin(), 1.0 ); // set form which is used to make group names
3895 gp_XYZ & loc = ( gp_XYZ& ) aTrsf.TranslationPart();
3896 gp_Mat & M = ( gp_Mat& ) aTrsf.HVectorialPart();
3897 loc.SetCoord( thePoint.x * (1-S[0]),
3898 thePoint.y * (1-S[1]),
3899 thePoint.z * (1-S[2]));
3900 M.SetDiagonal( S[0], S[1], S[2] );
3903 double tol = std::numeric_limits<double>::max();
3904 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
3905 0, S[1], 0, thePoint.y * (1-S[1]),
3906 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
3909 TIDSortedElemSet copyElements;
3910 TIDSortedElemSet* workElements = &elements;
3911 if ( myIsPreviewMode )
3913 TPreviewMesh * tmpMesh = getPreviewMesh();
3914 tmpMesh->Copy( elements, copyElements);
3915 if ( !theCopy && !theTargetMesh )
3917 TIDSortedElemSet elemsAround, elemsAroundCopy;
3918 getElementsAround( elements, getMeshDS(), elemsAround );
3919 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3921 workElements = & copyElements;
3922 theMakeGroups = false;
3925 ::SMESH_MeshEditor::PGroupIDs groupIds =
3926 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3928 if ( !myIsPreviewMode )
3930 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
3931 else declareMeshModified( /*isReComputeSafe=*/false );
3933 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3935 SMESH_CATCH( SMESH::throwCorbaException );
3939 //=======================================================================
3942 //=======================================================================
3944 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
3945 const SMESH::PointStruct& thePoint,
3946 const SMESH::double_array& theScaleFact,
3947 CORBA::Boolean theCopy)
3948 throw (SALOME::SALOME_Exception)
3950 if ( !myIsPreviewMode ) {
3951 TPythonDump() << this << ".Scale( "
3952 << theObject << ", "
3954 << TVar( theScaleFact ) << ", "
3957 scale(theObject, thePoint, theScaleFact, theCopy, false);
3961 //=======================================================================
3962 //function : ScaleMakeGroups
3964 //=======================================================================
3966 SMESH::ListOfGroups*
3967 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3968 const SMESH::PointStruct& thePoint,
3969 const SMESH::double_array& theScaleFact)
3970 throw (SALOME::SALOME_Exception)
3972 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3974 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
3975 if (!myIsPreviewMode) {
3976 dumpGroupsList(aPythonDump, aGroups);
3977 aPythonDump << this << ".Scale("
3980 << TVar( theScaleFact ) << ",True,True)";
3986 //=======================================================================
3987 //function : ScaleMakeMesh
3989 //=======================================================================
3991 SMESH::SMESH_Mesh_ptr
3992 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3993 const SMESH::PointStruct& thePoint,
3994 const SMESH::double_array& theScaleFact,
3995 CORBA::Boolean theCopyGroups,
3996 const char* theMeshName)
3997 throw (SALOME::SALOME_Exception)
3999 SMESH_Mesh_i* mesh_i;
4000 SMESH::SMESH_Mesh_var mesh;
4001 { // open new scope to dump "MakeMesh" command
4002 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4004 TPythonDump pydump; // to prevent dump at mesh creation
4005 mesh = makeMesh( theMeshName );
4006 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4010 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
4011 mesh_i->CreateGroupServants();
4013 if ( !myIsPreviewMode )
4014 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
4015 << theObject << ", "
4017 << TVar( theScaleFact ) << ", "
4018 << theCopyGroups << ", '"
4019 << theMeshName << "' )";
4023 if (!myIsPreviewMode && mesh_i)
4024 mesh_i->GetGroups();
4026 return mesh._retn();
4030 //=======================================================================
4031 //function : findCoincidentNodes
4033 //=======================================================================
4035 void SMESH_MeshEditor_i::
4036 findCoincidentNodes (TIDSortedNodeSet & Nodes,
4037 CORBA::Double Tolerance,
4038 SMESH::array_of_long_array_out GroupsOfNodes,
4039 CORBA::Boolean SeparateCornersAndMedium)
4041 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4042 getEditor().FindCoincidentNodes( Nodes, Tolerance, aListOfListOfNodes, SeparateCornersAndMedium );
4044 GroupsOfNodes = new SMESH::array_of_long_array;
4045 GroupsOfNodes->length( aListOfListOfNodes.size() );
4046 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4047 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4049 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4050 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4051 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4052 aGroup.length( aListOfNodes.size() );
4053 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4054 aGroup[ j ] = (*lIt)->GetID();
4058 //=======================================================================
4059 //function : FindCoincidentNodes
4061 //=======================================================================
4063 void SMESH_MeshEditor_i::
4064 FindCoincidentNodes (CORBA::Double Tolerance,
4065 SMESH::array_of_long_array_out GroupsOfNodes,
4066 CORBA::Boolean SeparateCornersAndMedium)
4067 throw (SALOME::SALOME_Exception)
4072 TIDSortedNodeSet nodes; // no input nodes
4073 findCoincidentNodes( nodes, Tolerance, GroupsOfNodes, SeparateCornersAndMedium );
4075 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
4076 << Tolerance << ", "
4077 << SeparateCornersAndMedium << " )";
4079 SMESH_CATCH( SMESH::throwCorbaException );
4082 //=======================================================================
4083 //function : FindCoincidentNodesOnPart
4085 //=======================================================================
4087 void SMESH_MeshEditor_i::
4088 FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
4089 CORBA::Double Tolerance,
4090 SMESH::array_of_long_array_out GroupsOfNodes,
4091 CORBA::Boolean SeparateCornersAndMedium)
4092 throw (SALOME::SALOME_Exception)
4097 TIDSortedNodeSet nodes;
4098 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4100 findCoincidentNodes( nodes, Tolerance, GroupsOfNodes, SeparateCornersAndMedium );
4102 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
4104 << Tolerance << ", "
4105 << SeparateCornersAndMedium << " )";
4107 SMESH_CATCH( SMESH::throwCorbaException );
4110 //================================================================================
4112 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
4113 * ExceptSubMeshOrGroups
4115 //================================================================================
4117 void SMESH_MeshEditor_i::
4118 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
4119 CORBA::Double theTolerance,
4120 SMESH::array_of_long_array_out theGroupsOfNodes,
4121 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups,
4122 CORBA::Boolean theSeparateCornersAndMedium)
4123 throw (SALOME::SALOME_Exception)
4128 TIDSortedNodeSet nodes;
4129 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4131 for ( CORBA::ULong i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
4133 SMDS_ElemIteratorPtr nodeIt = myMesh_i->GetElements( theExceptSubMeshOrGroups[i],
4135 while ( nodeIt->more() )
4136 nodes.erase( cast2Node( nodeIt->next() ));
4138 findCoincidentNodes( nodes, theTolerance, theGroupsOfNodes, theSeparateCornersAndMedium );
4140 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
4142 << theTolerance << ", "
4143 << theExceptSubMeshOrGroups << ", "
4144 << theSeparateCornersAndMedium << " )";
4146 SMESH_CATCH( SMESH::throwCorbaException );
4149 //=======================================================================
4150 //function : MergeNodes
4152 //=======================================================================
4154 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes,
4155 const SMESH::ListOfIDSources& NodesToKeep,
4156 CORBA::Boolean AvoidMakingHoles)
4157 throw (SALOME::SALOME_Exception)
4162 SMESHDS_Mesh* aMesh = getMeshDS();
4164 TPythonDump aTPythonDump;
4165 aTPythonDump << this << ".MergeNodes([";
4167 TIDSortedNodeSet setOfNodesToKeep;
4168 for ( CORBA::ULong i = 0; i < NodesToKeep.length(); ++i )
4170 prepareIdSource( NodesToKeep[i] );
4171 SMDS_ElemIteratorPtr nodeIt = myMesh_i->GetElements( NodesToKeep[i], SMESH::NODE );
4172 while ( nodeIt->more() )
4173 setOfNodesToKeep.insert( setOfNodesToKeep.end(), cast2Node( nodeIt->next() ));
4176 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4177 for ( CORBA::ULong i = 0; i < GroupsOfNodes.length(); i++ )
4179 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
4180 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
4181 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
4182 for ( CORBA::ULong j = 0; j < aNodeGroup.length(); j++ )
4184 CORBA::Long index = aNodeGroup[ j ];
4185 if ( const SMDS_MeshNode * node = aMesh->FindNode( index ))
4187 if ( setOfNodesToKeep.count( node ))
4188 aListOfNodes.push_front( node );
4190 aListOfNodes.push_back( node );
4193 if ( aListOfNodes.size() < 2 )
4194 aListOfListOfNodes.pop_back();
4196 if ( i > 0 ) aTPythonDump << ", ";
4197 aTPythonDump << aNodeGroup;
4200 getEditor().MergeNodes( aListOfListOfNodes, AvoidMakingHoles );
4202 aTPythonDump << "], " << NodesToKeep << ", " << AvoidMakingHoles << ")";
4204 declareMeshModified( /*isReComputeSafe=*/false );
4206 SMESH_CATCH( SMESH::throwCorbaException );
4209 //=======================================================================
4210 //function : FindEqualElements
4212 //=======================================================================
4214 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
4215 SMESH::array_of_long_array_out GroupsOfElementsID)
4216 throw (SALOME::SALOME_Exception)
4221 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
4222 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
4224 TIDSortedElemSet elems;
4225 idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true);
4227 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4228 getEditor().FindEqualElements( elems, aListOfListOfElementsID );
4230 GroupsOfElementsID = new SMESH::array_of_long_array;
4231 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
4233 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt =
4234 aListOfListOfElementsID.begin();
4235 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j)
4237 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
4238 list<int>& listOfIDs = *arraysIt;
4239 aGroup.length( listOfIDs.size() );
4240 list<int>::iterator idIt = listOfIDs.begin();
4241 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k )
4242 aGroup[ k ] = *idIt;
4245 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
4249 SMESH_CATCH( SMESH::throwCorbaException );
4252 //=======================================================================
4253 //function : MergeElements
4255 //=======================================================================
4257 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
4258 throw (SALOME::SALOME_Exception)
4263 TPythonDump aTPythonDump;
4264 aTPythonDump << this << ".MergeElements( [";
4266 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4268 for ( CORBA::ULong i = 0; i < GroupsOfElementsID.length(); i++ ) {
4269 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
4270 aListOfListOfElementsID.push_back( list< int >() );
4271 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
4272 for ( CORBA::ULong j = 0; j < anElemsIDGroup.length(); j++ ) {
4273 CORBA::Long id = anElemsIDGroup[ j ];
4274 aListOfElemsID.push_back( id );
4276 if ( aListOfElemsID.size() < 2 )
4277 aListOfListOfElementsID.pop_back();
4278 if ( i > 0 ) aTPythonDump << ", ";
4279 aTPythonDump << anElemsIDGroup;
4282 getEditor().MergeElements(aListOfListOfElementsID);
4284 declareMeshModified( /*isReComputeSafe=*/true );
4286 aTPythonDump << "] )";
4288 SMESH_CATCH( SMESH::throwCorbaException );
4291 //=======================================================================
4292 //function : MergeEqualElements
4294 //=======================================================================
4296 void SMESH_MeshEditor_i::MergeEqualElements()
4297 throw (SALOME::SALOME_Exception)
4302 getEditor().MergeEqualElements();
4304 declareMeshModified( /*isReComputeSafe=*/true );
4306 TPythonDump() << this << ".MergeEqualElements()";
4308 SMESH_CATCH( SMESH::throwCorbaException );
4311 //=============================================================================
4313 * Move the node to a given point
4315 //=============================================================================
4317 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
4321 throw (SALOME::SALOME_Exception)
4324 initData(/*deleteSearchers=*/false);
4326 const SMDS_MeshNode * node = getMeshDS()->FindNode( NodeID );
4330 if ( theNodeSearcher )
4331 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4333 if ( myIsPreviewMode ) // make preview data
4335 // in a preview mesh, make edges linked to a node
4336 TPreviewMesh& tmpMesh = *getPreviewMesh();
4337 TIDSortedElemSet linkedNodes;
4338 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4339 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4340 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
4341 for ( ; nIt != linkedNodes.end(); ++nIt )
4343 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
4344 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
4348 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
4349 // fill preview data
4351 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4352 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4354 getMeshDS()->MoveNode(node, x, y, z);
4356 if ( !myIsPreviewMode )
4358 // Update Python script
4359 TPythonDump() << "isDone = " << this << ".MoveNode( "
4360 << NodeID << ", " << TVar(x) << ", " << TVar(y) << ", " << TVar(z) << " )";
4361 declareMeshModified( /*isReComputeSafe=*/false );
4364 SMESH_CATCH( SMESH::throwCorbaException );
4369 //================================================================================
4371 * \brief Return ID of node closest to a given point
4373 //================================================================================
4375 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
4378 throw (SALOME::SALOME_Exception)
4381 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4383 if ( !theNodeSearcher ) {
4384 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
4387 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
4388 return node->GetID();
4390 SMESH_CATCH( SMESH::throwCorbaException );
4394 //================================================================================
4396 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
4397 * move the node closest to the point to point's location and return ID of the node
4399 //================================================================================
4401 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
4404 CORBA::Long theNodeID)
4405 throw (SALOME::SALOME_Exception)
4408 // We keep theNodeSearcher until any mesh modification:
4409 // 1) initData() deletes theNodeSearcher at any edition,
4410 // 2) TSearchersDeleter - at any mesh compute event and mesh change
4412 initData(/*deleteSearchers=*/false);
4414 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4416 int nodeID = theNodeID;
4417 const SMDS_MeshNode* node = getMeshDS()->FindNode( nodeID );
4418 if ( !node ) // preview moving node
4420 if ( !theNodeSearcher ) {
4421 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
4424 node = theNodeSearcher->FindClosestTo( p );
4427 nodeID = node->GetID();
4428 if ( myIsPreviewMode ) // make preview data
4430 // in a preview mesh, make edges linked to a node
4431 TPreviewMesh tmpMesh = *getPreviewMesh();
4432 TIDSortedElemSet linkedNodes;
4433 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4434 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4435 for ( ; nIt != linkedNodes.end(); ++nIt )
4437 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
4438 tmpMesh.Copy( &edge );
4441 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
4443 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
4444 // fill preview data
4446 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4448 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4452 getMeshDS()->MoveNode(node, x, y, z);
4456 if ( !myIsPreviewMode )
4458 TPythonDump() << "nodeID = " << this
4459 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
4460 << ", " << nodeID << " )";
4462 declareMeshModified( /*isReComputeSafe=*/false );
4467 SMESH_CATCH( SMESH::throwCorbaException );
4471 //=======================================================================
4473 * Return elements of given type where the given point is IN or ON.
4475 * 'ALL' type means elements of any type excluding nodes
4477 //=======================================================================
4479 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
4482 SMESH::ElementType type)
4483 throw (SALOME::SALOME_Exception)
4486 SMESH::long_array_var res = new SMESH::long_array;
4487 vector< const SMDS_MeshElement* > foundElems;
4489 theSearchersDeleter.Set( myMesh );
4490 if ( !theElementSearcher ) {
4491 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
4493 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4494 SMDSAbs_ElementType( type ),
4496 res->length( foundElems.size() );
4497 for ( size_t i = 0; i < foundElems.size(); ++i )
4498 res[i] = foundElems[i]->GetID();
4502 SMESH_CATCH( SMESH::throwCorbaException );
4506 //=======================================================================
4507 //function : FindAmongElementsByPoint
4508 //purpose : Searching among the given elements, return elements of given type
4509 // where the given point is IN or ON.
4510 // 'ALL' type means elements of any type excluding nodes
4511 //=======================================================================
4514 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
4518 SMESH::ElementType type)
4519 throw (SALOME::SALOME_Exception)
4522 SMESH::long_array_var res = new SMESH::long_array;
4524 if ( type != SMESH::NODE )
4526 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
4527 if ( types->length() == 1 && // a part contains only nodes or 0D elements
4528 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) &&
4529 type != types[0] ) // but search of elements of dim > 0
4532 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
4533 return FindElementsByPoint( x,y,z, type );
4535 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
4537 theSearchersDeleter.Set( myMesh, getPartIOR( elementIDs, type ));
4538 if ( !theElementSearcher )
4540 // create a searcher from elementIDs
4541 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
4542 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
4544 if ( !idSourceToSet( elementIDs, meshDS, elements,
4545 ( type == SMESH::NODE ? SMDSAbs_All : (SMDSAbs_ElementType) type ),
4546 /*emptyIfIsMesh=*/true))
4549 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
4550 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
4552 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt );
4555 vector< const SMDS_MeshElement* > foundElems;
4557 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4558 SMDSAbs_ElementType( type ),
4560 res->length( foundElems.size() );
4561 for ( size_t i = 0; i < foundElems.size(); ++i )
4562 res[i] = foundElems[i]->GetID();
4566 SMESH_CATCH( SMESH::throwCorbaException );
4570 //=======================================================================
4571 //function : GetPointState
4572 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
4573 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
4574 //=======================================================================
4576 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
4579 throw (SALOME::SALOME_Exception)
4582 theSearchersDeleter.Set( myMesh );
4583 if ( !theElementSearcher ) {
4584 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
4586 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
4588 SMESH_CATCH( SMESH::throwCorbaException );
4592 //=======================================================================
4593 //function : convError
4595 //=======================================================================
4597 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
4599 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
4603 RETCASE( SEW_BORDER1_NOT_FOUND );
4604 RETCASE( SEW_BORDER2_NOT_FOUND );
4605 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
4606 RETCASE( SEW_BAD_SIDE_NODES );
4607 RETCASE( SEW_VOLUMES_TO_SPLIT );
4608 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
4609 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
4610 RETCASE( SEW_BAD_SIDE1_NODES );
4611 RETCASE( SEW_BAD_SIDE2_NODES );
4612 RETCASE( SEW_INTERNAL_ERROR );
4614 return SMESH::SMESH_MeshEditor::SEW_OK;
4617 //=======================================================================
4619 * Returns groups of FreeBorder's coincident within the given tolerance.
4620 * If the tolerance <= 0.0 then one tenth of an average size of elements adjacent
4621 * to free borders being compared is used.
4623 //=======================================================================
4625 SMESH::CoincidentFreeBorders*
4626 SMESH_MeshEditor_i::FindCoincidentFreeBorders(CORBA::Double tolerance)
4628 SMESH::CoincidentFreeBorders_var aCFB = new SMESH::CoincidentFreeBorders;
4632 SMESH_MeshAlgos::CoincidentFreeBorders cfb;
4633 SMESH_MeshAlgos::FindCoincidentFreeBorders( *getMeshDS(), tolerance, cfb );
4635 // copy free borders
4636 aCFB->borders.length( cfb._borders.size() );
4637 for ( size_t i = 0; i < cfb._borders.size(); ++i )
4639 SMESH_MeshAlgos::TFreeBorder& nodes = cfb._borders[i];
4640 SMESH::FreeBorder& aBRD = aCFB->borders[i];
4641 aBRD.nodeIDs.length( nodes.size() );
4642 for ( size_t iN = 0; iN < nodes.size(); ++iN )
4643 aBRD.nodeIDs[ iN ] = nodes[ iN ]->GetID();
4646 // copy coincident parts
4647 aCFB->coincidentGroups.length( cfb._coincidentGroups.size() );
4648 for ( size_t i = 0; i < cfb._coincidentGroups.size(); ++i )
4650 SMESH_MeshAlgos::TCoincidentGroup& grp = cfb._coincidentGroups[i];
4651 SMESH::FreeBordersGroup& aGRP = aCFB->coincidentGroups[i];
4652 aGRP.length( grp.size() );
4653 for ( size_t iP = 0; iP < grp.size(); ++iP )
4655 SMESH_MeshAlgos::TFreeBorderPart& part = grp[ iP ];
4656 SMESH::FreeBorderPart& aPART = aGRP[ iP ];
4657 aPART.border = part._border;
4658 aPART.node1 = part._node1;
4659 aPART.node2 = part._node2;
4660 aPART.nodeLast = part._nodeLast;
4663 SMESH_CATCH( SMESH::doNothing );
4665 TPythonDump() << "CoincidentFreeBorders = "
4666 << this << ".FindCoincidentFreeBorders( " << tolerance << " )";
4668 return aCFB._retn();
4671 //=======================================================================
4673 * Sew FreeBorder's of each group
4675 //=======================================================================
4677 CORBA::Short SMESH_MeshEditor_i::
4678 SewCoincidentFreeBorders(const SMESH::CoincidentFreeBorders& freeBorders,
4679 CORBA::Boolean createPolygons,
4680 CORBA::Boolean createPolyhedra)
4681 throw (SALOME::SALOME_Exception)
4683 CORBA::Short nbSewed = 0;
4685 SMESH_MeshAlgos::TFreeBorderVec groups;
4686 SMESH_MeshAlgos::TFreeBorder borderNodes; // triples of nodes for every FreeBorderPart
4688 // check the input and collect nodes
4689 for ( CORBA::ULong i = 0; i < freeBorders.coincidentGroups.length(); ++i )
4691 borderNodes.clear();
4692 const SMESH::FreeBordersGroup& aGRP = freeBorders.coincidentGroups[ i ];
4693 for ( CORBA::ULong iP = 0; iP < aGRP.length(); ++iP )
4695 const SMESH::FreeBorderPart& aPART = aGRP[ iP ];
4696 if ( aPART.border < 0 || aPART.border >= (int) freeBorders.borders.length() )
4697 THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::border index", SALOME::BAD_PARAM);
4699 const SMESH::FreeBorder& aBRD = freeBorders.borders[ aPART.border ];
4701 if ( aPART.node1 < 0 || aPART.node1 > (int) aBRD.nodeIDs.length() )
4702 THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::node1", SALOME::BAD_PARAM);
4703 if ( aPART.node2 < 0 || aPART.node2 > (int) aBRD.nodeIDs.length() )
4704 THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::node2", SALOME::BAD_PARAM);
4705 if ( aPART.nodeLast < 0 || aPART.nodeLast > (int) aBRD.nodeIDs.length() )
4706 THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::nodeLast", SALOME::BAD_PARAM);
4708 // do not keep these nodes for further sewing as nodes can be removed by the sewing
4709 const SMDS_MeshNode* n1 = getMeshDS()->FindNode( aBRD.nodeIDs[ aPART.node1 ]);
4710 const SMDS_MeshNode* n2 = getMeshDS()->FindNode( aBRD.nodeIDs[ aPART.node2 ]);
4711 const SMDS_MeshNode* n3 = getMeshDS()->FindNode( aBRD.nodeIDs[ aPART.nodeLast ]);
4713 THROW_SALOME_CORBA_EXCEPTION("Nonexistent FreeBorderPart::node1", SALOME::BAD_PARAM);
4715 THROW_SALOME_CORBA_EXCEPTION("Nonexistent FreeBorderPart::node2", SALOME::BAD_PARAM);
4717 THROW_SALOME_CORBA_EXCEPTION("Nonexistent FreeBorderPart::nodeLast", SALOME::BAD_PARAM);
4719 borderNodes.push_back( n1 );
4720 borderNodes.push_back( n2 );
4721 borderNodes.push_back( n3 );
4723 groups.push_back( borderNodes );
4726 // SewFreeBorder() can merge nodes, thus nodes stored in 'groups' can become dead;
4727 // to get nodes that replace other nodes during merge we create 0D elements
4728 // on each node and MergeNodes() will replace underlying nodes of 0D elements by
4731 vector< const SMDS_MeshElement* > tmp0Delems;
4732 for ( size_t i = 0; i < groups.size(); ++i )
4734 SMESH_MeshAlgos::TFreeBorder& nodes = groups[i];
4735 for ( size_t iN = 0; iN < nodes.size(); ++iN )
4737 SMDS_ElemIteratorPtr it0D = nodes[iN]->GetInverseElementIterator(SMDSAbs_0DElement);
4739 tmp0Delems.push_back( it0D->next() );
4741 tmp0Delems.push_back( getMeshDS()->Add0DElement( nodes[iN] ));
4745 // cout << endl << "INIT" << endl;
4746 // for ( size_t i = 0; i < tmp0Delems.size(); ++i )
4748 // cout << i << " ";
4749 // if ( i % 3 == 0 ) cout << "^ ";
4750 // tmp0Delems[i]->GetNode(0)->Print( cout );
4755 ::SMESH_MeshEditor::Sew_Error res, ok = ::SMESH_MeshEditor::SEW_OK;
4757 for ( size_t i = 0; i < groups.size(); ++i )
4759 bool isBordToBord = true;
4760 bool groupSewed = false;
4761 SMESH_MeshAlgos::TFreeBorder& nodes = groups[i];
4762 for ( size_t iN = 3; iN+2 < nodes.size(); iN += 3 )
4764 const SMDS_MeshNode* n0 = tmp0Delems[ i0D + 0 ]->GetNode( 0 );
4765 const SMDS_MeshNode* n1 = tmp0Delems[ i0D + 1 ]->GetNode( 0 );
4766 const SMDS_MeshNode* n2 = tmp0Delems[ i0D + 2 ]->GetNode( 0 );
4768 const SMDS_MeshNode* n3 = tmp0Delems[ i0D + 0 + iN ]->GetNode( 0 );
4769 const SMDS_MeshNode* n4 = tmp0Delems[ i0D + 1 + iN ]->GetNode( 0 );
4770 const SMDS_MeshNode* n5 = tmp0Delems[ i0D + 2 + iN ]->GetNode( 0 );
4772 if ( !n0 || !n1 || !n2 || !n3 || !n4 || !n5 )
4775 // TIDSortedElemSet emptySet, avoidSet;
4776 // if ( !SMESH_MeshAlgos::FindFaceInSet( n0, n1, emptySet, avoidSet))
4778 // cout << "WRONG 2nd 1" << endl;
4779 // n0->Print( cout );
4780 // n1->Print( cout );
4782 // if ( !SMESH_MeshAlgos::FindFaceInSet( n3, n4, emptySet, avoidSet))
4784 // cout << "WRONG 2nd 2" << endl;
4785 // n3->Print( cout );
4786 // n4->Print( cout );
4789 if ( !isBordToBord )
4791 n1 = n2; // at border-to-side sewing only last side node (n1) is needed
4792 n2 = 0; // and n2 is not used
4794 // 1st border moves to 2nd
4795 res = getEditor().SewFreeBorder( n3, n4, n5 ,// 1st
4797 /*2ndIsFreeBorder=*/ isBordToBord,
4798 createPolygons, createPolyhedra);
4799 groupSewed = ( res == ok );
4801 isBordToBord = false;
4802 // cout << endl << "SEWED GROUP " << i << " PART " << iN / 3 << endl;
4803 // for ( size_t t = 0; t < tmp0Delems.size(); ++t )
4805 // cout << t << " ";
4806 // if ( t % 3 == 0 ) cout << "^ ";
4807 // tmp0Delems[t]->GetNode(0)->Print( cout );
4810 i0D += nodes.size();
4811 nbSewed += groupSewed;
4814 TPythonDump() << "nbSewed = " << this << ".SewCoincidentFreeBorders( "
4815 << freeBorders << ", "
4816 << createPolygons << ", "
4817 << createPolyhedra << " )";
4819 SMESH_CATCH( SMESH::doNothing );
4821 declareMeshModified( /*isReComputeSafe=*/false );
4823 // remove tmp 0D elements
4825 set< const SMDS_MeshElement* > removed0D;
4826 for ( size_t i = 0; i < tmp0Delems.size(); ++i )
4828 if ( removed0D.insert( tmp0Delems[i] ).second )
4829 getMeshDS()->RemoveFreeElement( tmp0Delems[i], /*sm=*/0, /*fromGroups=*/false );
4831 SMESH_CATCH( SMESH::throwCorbaException );
4836 //=======================================================================
4837 //function : SewFreeBorders
4839 //=======================================================================
4841 SMESH::SMESH_MeshEditor::Sew_Error
4842 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
4843 CORBA::Long SecondNodeID1,
4844 CORBA::Long LastNodeID1,
4845 CORBA::Long FirstNodeID2,
4846 CORBA::Long SecondNodeID2,
4847 CORBA::Long LastNodeID2,
4848 CORBA::Boolean CreatePolygons,
4849 CORBA::Boolean CreatePolyedrs)
4850 throw (SALOME::SALOME_Exception)
4855 SMESHDS_Mesh* aMesh = getMeshDS();
4857 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4858 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4859 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4860 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4861 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4862 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
4864 if (!aBorderFirstNode ||
4865 !aBorderSecondNode||
4867 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4868 if (!aSide2FirstNode ||
4869 !aSide2SecondNode ||
4871 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4873 TPythonDump() << "error = " << this << ".SewFreeBorders( "
4874 << FirstNodeID1 << ", "
4875 << SecondNodeID1 << ", "
4876 << LastNodeID1 << ", "
4877 << FirstNodeID2 << ", "
4878 << SecondNodeID2 << ", "
4879 << LastNodeID2 << ", "
4880 << CreatePolygons<< ", "
4881 << CreatePolyedrs<< " )";
4883 SMESH::SMESH_MeshEditor::Sew_Error error =
4884 convError( getEditor().SewFreeBorder (aBorderFirstNode,
4895 declareMeshModified( /*isReComputeSafe=*/false );
4898 SMESH_CATCH( SMESH::throwCorbaException );
4899 return SMESH::SMESH_MeshEditor::Sew_Error(0);
4903 //=======================================================================
4904 //function : SewConformFreeBorders
4906 //=======================================================================
4908 SMESH::SMESH_MeshEditor::Sew_Error
4909 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
4910 CORBA::Long SecondNodeID1,
4911 CORBA::Long LastNodeID1,
4912 CORBA::Long FirstNodeID2,
4913 CORBA::Long SecondNodeID2)
4914 throw (SALOME::SALOME_Exception)
4919 SMESHDS_Mesh* aMesh = getMeshDS();
4921 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4922 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4923 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4924 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4925 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4926 const SMDS_MeshNode* aSide2ThirdNode = 0;
4928 if (!aBorderFirstNode ||
4929 !aBorderSecondNode||
4931 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4932 if (!aSide2FirstNode ||
4934 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4936 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
4937 << FirstNodeID1 << ", "
4938 << SecondNodeID1 << ", "
4939 << LastNodeID1 << ", "
4940 << FirstNodeID2 << ", "
4941 << SecondNodeID2 << " )";
4943 SMESH::SMESH_MeshEditor::Sew_Error error =
4944 convError( getEditor().SewFreeBorder (aBorderFirstNode,
4953 declareMeshModified( /*isReComputeSafe=*/false );
4956 SMESH_CATCH( SMESH::throwCorbaException );
4957 return SMESH::SMESH_MeshEditor::Sew_Error(0);
4961 //=======================================================================
4962 //function : SewBorderToSide
4964 //=======================================================================
4966 SMESH::SMESH_MeshEditor::Sew_Error
4967 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
4968 CORBA::Long SecondNodeIDOnFreeBorder,
4969 CORBA::Long LastNodeIDOnFreeBorder,
4970 CORBA::Long FirstNodeIDOnSide,
4971 CORBA::Long LastNodeIDOnSide,
4972 CORBA::Boolean CreatePolygons,
4973 CORBA::Boolean CreatePolyedrs)
4974 throw (SALOME::SALOME_Exception)
4979 SMESHDS_Mesh* aMesh = getMeshDS();
4981 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
4982 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
4983 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
4984 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
4985 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
4986 const SMDS_MeshNode* aSide2ThirdNode = 0;
4988 if (!aBorderFirstNode ||
4989 !aBorderSecondNode||
4991 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4992 if (!aSide2FirstNode ||
4994 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
4996 TPythonDump() << "error = " << this << ".SewBorderToSide( "
4997 << FirstNodeIDOnFreeBorder << ", "
4998 << SecondNodeIDOnFreeBorder << ", "
4999 << LastNodeIDOnFreeBorder << ", "
5000 << FirstNodeIDOnSide << ", "
5001 << LastNodeIDOnSide << ", "
5002 << CreatePolygons << ", "
5003 << CreatePolyedrs << ") ";
5005 SMESH::SMESH_MeshEditor::Sew_Error error =
5006 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5016 declareMeshModified( /*isReComputeSafe=*/false );
5019 SMESH_CATCH( SMESH::throwCorbaException );
5020 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5024 //=======================================================================
5025 //function : SewSideElements
5027 //=======================================================================
5029 SMESH::SMESH_MeshEditor::Sew_Error
5030 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
5031 const SMESH::long_array& IDsOfSide2Elements,
5032 CORBA::Long NodeID1OfSide1ToMerge,
5033 CORBA::Long NodeID1OfSide2ToMerge,
5034 CORBA::Long NodeID2OfSide1ToMerge,
5035 CORBA::Long NodeID2OfSide2ToMerge)
5036 throw (SALOME::SALOME_Exception)
5041 SMESHDS_Mesh* aMesh = getMeshDS();
5043 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
5044 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
5045 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
5046 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
5048 if (!aFirstNode1ToMerge ||
5049 !aFirstNode2ToMerge )
5050 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
5051 if (!aSecondNode1ToMerge||
5052 !aSecondNode2ToMerge)
5053 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
5055 TIDSortedElemSet aSide1Elems, aSide2Elems;
5056 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
5057 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
5059 TPythonDump() << "error = " << this << ".SewSideElements( "
5060 << IDsOfSide1Elements << ", "
5061 << IDsOfSide2Elements << ", "
5062 << NodeID1OfSide1ToMerge << ", "
5063 << NodeID1OfSide2ToMerge << ", "
5064 << NodeID2OfSide1ToMerge << ", "
5065 << NodeID2OfSide2ToMerge << ")";
5067 SMESH::SMESH_MeshEditor::Sew_Error error =
5068 convError( getEditor().SewSideElements (aSide1Elems, aSide2Elems,
5071 aSecondNode1ToMerge,
5072 aSecondNode2ToMerge));
5074 declareMeshModified( /*isReComputeSafe=*/false );
5077 SMESH_CATCH( SMESH::throwCorbaException );
5078 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5081 //================================================================================
5083 * \brief Set new nodes for given element
5084 * \param ide - element id
5085 * \param newIDs - new node ids
5086 * \retval CORBA::Boolean - true if result is OK
5088 //================================================================================
5090 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
5091 const SMESH::long_array& newIDs)
5092 throw (SALOME::SALOME_Exception)
5097 const SMDS_MeshElement* elem = getMeshDS()->FindElement(ide);
5098 if(!elem) return false;
5100 int nbn = newIDs.length();
5102 vector<const SMDS_MeshNode*> aNodes(nbn);
5105 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(newIDs[i]);
5108 aNodes[nbn1] = aNode;
5111 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
5112 << ide << ", " << newIDs << " )";
5114 bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
5116 declareMeshModified( /*isReComputeSafe=*/ !res );
5120 SMESH_CATCH( SMESH::throwCorbaException );
5124 //=======================================================================
5126 * \brief Makes a part of the mesh quadratic or bi-quadratic
5128 //=======================================================================
5130 void SMESH_MeshEditor_i::convertToQuadratic(CORBA::Boolean theForce3d,
5131 CORBA::Boolean theToBiQuad,
5132 SMESH::SMESH_IDSource_ptr theObject)
5133 throw (SALOME::SALOME_Exception)
5138 TIDSortedElemSet elems;
5140 if ( !( elemsOK = CORBA::is_nil( theObject )))
5142 elemsOK = idSourceToSet( theObject, getMeshDS(), elems,
5143 SMDSAbs_All, /*emptyIfIsMesh=*/true );
5147 if ( !elems.empty() && (*elems.begin())->GetType() == SMDSAbs_Node )
5148 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5150 if ( elems.empty() ) getEditor().ConvertToQuadratic(theForce3d, theToBiQuad);
5151 else getEditor().ConvertToQuadratic(theForce3d, elems, theToBiQuad);
5153 declareMeshModified( /*isReComputeSafe=*/false );
5156 SMESH_CATCH( SMESH::throwCorbaException );
5159 //=======================================================================
5160 //function : ConvertFromQuadratic
5162 //=======================================================================
5164 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
5165 throw (SALOME::SALOME_Exception)
5170 CORBA::Boolean isDone = getEditor().ConvertFromQuadratic();
5171 TPythonDump() << this << ".ConvertFromQuadratic()";
5172 declareMeshModified( /*isReComputeSafe=*/!isDone );
5175 SMESH_CATCH( SMESH::throwCorbaException );
5179 //=======================================================================
5180 //function : ConvertToQuadratic
5182 //=======================================================================
5184 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
5185 throw (SALOME::SALOME_Exception)
5187 convertToQuadratic( theForce3d, false );
5188 TPythonDump() << this << ".ConvertToQuadratic("<<theForce3d<<")";
5191 //================================================================================
5193 * \brief Makes a part of the mesh quadratic
5195 //================================================================================
5197 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
5198 SMESH::SMESH_IDSource_ptr theObject)
5199 throw (SALOME::SALOME_Exception)
5201 convertToQuadratic( theForce3d, false, theObject );
5202 TPythonDump() << this << ".ConvertToQuadraticObject("<<theForce3d<<", "<<theObject<<")";
5205 //================================================================================
5207 * \brief Makes a part of the mesh bi-quadratic
5209 //================================================================================
5211 void SMESH_MeshEditor_i::ConvertToBiQuadratic(CORBA::Boolean theForce3d,
5212 SMESH::SMESH_IDSource_ptr theObject)
5213 throw (SALOME::SALOME_Exception)
5215 convertToQuadratic( theForce3d, true, theObject );
5216 TPythonDump() << this << ".ConvertToBiQuadratic("<<theForce3d<<", "<<theObject<<")";
5219 //================================================================================
5221 * \brief Makes a part of the mesh linear
5223 //================================================================================
5225 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
5226 throw (SALOME::SALOME_Exception)
5233 TIDSortedElemSet elems;
5234 if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5236 if ( elems.empty() )
5238 ConvertFromQuadratic();
5240 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5242 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5246 getEditor().ConvertFromQuadratic(elems);
5249 declareMeshModified( /*isReComputeSafe=*/false );
5251 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
5253 SMESH_CATCH( SMESH::throwCorbaException );
5256 //=======================================================================
5257 //function : makeMesh
5258 //purpose : create a named imported mesh
5259 //=======================================================================
5261 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
5263 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
5264 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
5265 SALOMEDS::Study_var study = gen->GetCurrentStudy();
5266 SALOMEDS::SObject_wrap meshSO = gen->ObjectToSObject( study, mesh );
5267 gen->SetName( meshSO, theMeshName, "Mesh" );
5268 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
5270 return mesh._retn();
5273 //=======================================================================
5274 //function : dumpGroupsList
5276 //=======================================================================
5278 void SMESH_MeshEditor_i::dumpGroupsList(TPythonDump & theDumpPython,
5279 const SMESH::ListOfGroups * theGroupList)
5281 bool isDumpGroupList = ( theGroupList && theGroupList->length() > 0 );
5282 if ( isDumpGroupList )
5283 theDumpPython << theGroupList << " = ";
5286 //================================================================================
5288 \brief Generates the unique group name.
5289 \param thePrefix name prefix
5292 //================================================================================
5294 std::string SMESH_MeshEditor_i::generateGroupName(const std::string& thePrefix)
5296 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5297 set<std::string> groupNames;
5299 // Get existing group names
5300 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
5301 SMESH::SMESH_GroupBase_var aGroup = groups[i];
5302 if (CORBA::is_nil(aGroup))
5305 CORBA::String_var name = aGroup->GetName();
5306 groupNames.insert( name.in() );
5310 std::string name = thePrefix;
5313 while (!groupNames.insert(name).second)
5314 name = SMESH_Comment( thePrefix ) << "_" << index++;
5319 //================================================================================
5321 * \brief Prepare SMESH_IDSource for work
5323 //================================================================================
5325 void SMESH_MeshEditor_i::prepareIdSource(SMESH::SMESH_IDSource_ptr theObject)
5327 if ( SMESH::Filter_i* filter = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5329 SMESH::SMESH_Mesh_var mesh = myMesh_i->_this();
5330 filter->SetMesh( mesh );
5333 //================================================================================
5335 * \brief Retrieve elements of given type from SMESH_IDSource
5337 //================================================================================
5339 bool SMESH_MeshEditor_i::idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource,
5340 const SMESHDS_Mesh* theMeshDS,
5341 TIDSortedElemSet& theElemSet,
5342 const SMDSAbs_ElementType theType,
5343 const bool emptyIfIsMesh,
5344 IDSource_Error* error)
5347 if ( error ) *error = IDSource_OK;
5349 if ( CORBA::is_nil( theIDSource ))
5351 if ( error ) *error = IDSource_INVALID;
5354 if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
5356 if ( error && getMeshDS()->GetMeshInfo().NbElements( theType ) == 0 )
5357 *error = IDSource_EMPTY;
5360 prepareIdSource( theIDSource );
5361 SMESH::long_array_var anIDs = theIDSource->GetIDs();
5362 if ( anIDs->length() == 0 )
5364 if ( error ) *error = IDSource_EMPTY;
5367 SMESH::array_of_ElementType_var types = theIDSource->GetTypes();
5368 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
5370 if ( theType == SMDSAbs_All || theType == SMDSAbs_Node )
5372 arrayToSet( anIDs, getMeshDS(), theElemSet, SMDSAbs_Node );
5376 if ( error ) *error = IDSource_INVALID;
5382 arrayToSet( anIDs, getMeshDS(), theElemSet, theType);
5383 if ( bool(anIDs->length()) != bool(theElemSet.size()))
5385 if ( error ) *error = IDSource_INVALID;
5392 //================================================================================
5394 * \brief Duplicates given elements, i.e. creates new elements based on the
5395 * same nodes as the given ones.
5396 * \param theElements - container of elements to duplicate.
5397 * \param theGroupName - a name of group to contain the generated elements.
5398 * If a group with such a name already exists, the new elements
5399 * are added to the existng group, else a new group is created.
5400 * If \a theGroupName is empty, new elements are not added
5402 * \return a group where the new elements are added. NULL if theGroupName == "".
5405 //================================================================================
5407 SMESH::SMESH_Group_ptr
5408 SMESH_MeshEditor_i::DoubleElements(SMESH::SMESH_IDSource_ptr theElements,
5409 const char* theGroupName)
5410 throw (SALOME::SALOME_Exception)
5412 SMESH::SMESH_Group_var newGroup;
5419 TIDSortedElemSet elems;
5420 if ( idSourceToSet( theElements, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true))
5422 getEditor().DoubleElements( elems );
5424 if ( strlen( theGroupName ) && !getEditor().GetLastCreatedElems().IsEmpty() )
5427 SMESH::ElementType type =
5428 SMESH::ElementType( getEditor().GetLastCreatedElems().Value(1)->GetType() );
5429 // find existing group
5430 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5431 for ( size_t i = 0; i < groups->length(); ++i )
5432 if ( groups[i]->GetType() == type )
5434 CORBA::String_var name = groups[i]->GetName();
5435 if ( strcmp( name, theGroupName ) == 0 ) {
5436 newGroup = SMESH::SMESH_Group::_narrow( groups[i] );
5440 // create a new group
5441 if ( newGroup->_is_nil() )
5442 newGroup = myMesh_i->CreateGroup( type, theGroupName );
5444 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* >( newGroup ))
5446 SMESHDS_Group* groupDS = static_cast< SMESHDS_Group* >( group_i->GetGroupDS() );
5447 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
5448 for ( int i = 1; i <= aSeq.Length(); i++ )
5449 groupDS->SMDSGroup().Add( aSeq(i) );
5454 if ( !newGroup->_is_nil() )
5455 pyDump << newGroup << " = ";
5456 pyDump << this << ".DoubleElements( "
5457 << theElements << ", " << "'" << theGroupName <<"')";
5459 SMESH_CATCH( SMESH::throwCorbaException );
5461 return newGroup._retn();
5464 //================================================================================
5466 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5467 \param theNodes - identifiers of nodes to be doubled
5468 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
5469 nodes. If list of element identifiers is empty then nodes are doubled but
5470 they not assigned to elements
5471 \return TRUE if operation has been completed successfully, FALSE otherwise
5472 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
5474 //================================================================================
5476 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
5477 const SMESH::long_array& theModifiedElems )
5478 throw (SALOME::SALOME_Exception)
5483 list< int > aListOfNodes;
5485 for ( i = 0, n = theNodes.length(); i < n; i++ )
5486 aListOfNodes.push_back( theNodes[ i ] );
5488 list< int > aListOfElems;
5489 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5490 aListOfElems.push_back( theModifiedElems[ i ] );
5492 bool aResult = getEditor().DoubleNodes( aListOfNodes, aListOfElems );
5494 declareMeshModified( /*isReComputeSafe=*/ !aResult );
5496 // Update Python script
5497 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
5501 SMESH_CATCH( SMESH::throwCorbaException );
5505 //================================================================================
5507 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5508 This method provided for convenience works as DoubleNodes() described above.
5509 \param theNodeId - identifier of node to be doubled.
5510 \param theModifiedElems - identifiers of elements to be updated.
5511 \return TRUE if operation has been completed successfully, FALSE otherwise
5512 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
5514 //================================================================================
5516 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
5517 const SMESH::long_array& theModifiedElems )
5518 throw (SALOME::SALOME_Exception)
5521 SMESH::long_array_var aNodes = new SMESH::long_array;
5522 aNodes->length( 1 );
5523 aNodes[ 0 ] = theNodeId;
5525 TPythonDump pyDump; // suppress dump by the next line
5527 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
5529 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
5533 SMESH_CATCH( SMESH::throwCorbaException );
5537 //================================================================================
5539 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5540 This method provided for convenience works as DoubleNodes() described above.
5541 \param theNodes - group of nodes to be doubled.
5542 \param theModifiedElems - group of elements to be updated.
5543 \return TRUE if operation has been completed successfully, FALSE otherwise
5544 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
5546 //================================================================================
5548 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
5549 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5550 throw (SALOME::SALOME_Exception)
5553 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5556 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5557 SMESH::long_array_var aModifiedElems;
5558 if ( !CORBA::is_nil( theModifiedElems ) )
5559 aModifiedElems = theModifiedElems->GetListOfID();
5562 aModifiedElems = new SMESH::long_array;
5563 aModifiedElems->length( 0 );
5566 TPythonDump pyDump; // suppress dump by the next line
5568 bool done = DoubleNodes( aNodes, aModifiedElems );
5570 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
5574 SMESH_CATCH( SMESH::throwCorbaException );
5578 //================================================================================
5580 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5581 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
5582 * \param theNodes - group of nodes to be doubled.
5583 * \param theModifiedElems - group of elements to be updated.
5584 * \return a new group with newly created nodes
5585 * \sa DoubleNodeGroup()
5587 //================================================================================
5589 SMESH::SMESH_Group_ptr
5590 SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
5591 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5592 throw (SALOME::SALOME_Exception)
5595 SMESH::SMESH_Group_var aNewGroup;
5597 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5598 return aNewGroup._retn();
5601 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5602 SMESH::long_array_var aModifiedElems;
5603 if ( !CORBA::is_nil( theModifiedElems ) )
5604 aModifiedElems = theModifiedElems->GetListOfID();
5606 aModifiedElems = new SMESH::long_array;
5607 aModifiedElems->length( 0 );
5610 TPythonDump pyDump; // suppress dump by the next line
5612 bool aResult = DoubleNodes( aNodes, aModifiedElems );
5615 // Create group with newly created nodes
5616 SMESH::long_array_var anIds = GetLastCreatedNodes();
5617 if (anIds->length() > 0) {
5618 std::string anUnindexedName (theNodes->GetName());
5619 std::string aNewName = generateGroupName(anUnindexedName + "_double");
5620 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5621 aNewGroup->Add(anIds);
5622 pyDump << aNewGroup << " = ";
5626 pyDump << this << ".DoubleNodeGroupNew( " << theNodes << ", "
5627 << theModifiedElems << " )";
5629 return aNewGroup._retn();
5631 SMESH_CATCH( SMESH::throwCorbaException );
5635 //================================================================================
5637 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5638 This method provided for convenience works as DoubleNodes() described above.
5639 \param theNodes - list of groups of nodes to be doubled
5640 \param theModifiedElems - list of groups of elements to be updated.
5641 \return TRUE if operation has been completed successfully, FALSE otherwise
5642 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
5644 //================================================================================
5646 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
5647 const SMESH::ListOfGroups& theModifiedElems )
5648 throw (SALOME::SALOME_Exception)
5653 std::list< int > aNodes;
5655 for ( i = 0, n = theNodes.length(); i < n; i++ )
5657 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
5658 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
5660 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5661 for ( j = 0, m = aCurr->length(); j < m; j++ )
5662 aNodes.push_back( aCurr[ j ] );
5666 std::list< int > anElems;
5667 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5669 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
5670 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
5672 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5673 for ( j = 0, m = aCurr->length(); j < m; j++ )
5674 anElems.push_back( aCurr[ j ] );
5678 bool aResult = getEditor().DoubleNodes( aNodes, anElems );
5680 declareMeshModified( /*isReComputeSafe=*/false );
5682 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
5686 SMESH_CATCH( SMESH::throwCorbaException );
5690 //================================================================================
5692 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5693 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
5694 * \param theNodes - group of nodes to be doubled.
5695 * \param theModifiedElems - group of elements to be updated.
5696 * \return a new group with newly created nodes
5697 * \sa DoubleNodeGroups()
5699 //================================================================================
5701 SMESH::SMESH_Group_ptr
5702 SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
5703 const SMESH::ListOfGroups& theModifiedElems )
5704 throw (SALOME::SALOME_Exception)
5706 SMESH::SMESH_Group_var aNewGroup;
5708 TPythonDump pyDump; // suppress dump by the next line
5710 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
5714 // Create group with newly created nodes
5715 SMESH::long_array_var anIds = GetLastCreatedNodes();
5716 if (anIds->length() > 0) {
5717 std::string anUnindexedName (theNodes[0]->GetName());
5718 std::string aNewName = generateGroupName(anUnindexedName + "_double");
5719 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5720 aNewGroup->Add(anIds);
5721 pyDump << aNewGroup << " = ";
5725 pyDump << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
5726 << theModifiedElems << " )";
5728 return aNewGroup._retn();
5732 //================================================================================
5734 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5735 \param theElems - the list of elements (edges or faces) to be replicated
5736 The nodes for duplication could be found from these elements
5737 \param theNodesNot - list of nodes to NOT replicate
5738 \param theAffectedElems - the list of elements (cells and edges) to which the
5739 replicated nodes should be associated to.
5740 \return TRUE if operation has been completed successfully, FALSE otherwise
5741 \sa DoubleNodeGroup(), DoubleNodeGroups()
5743 //================================================================================
5745 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
5746 const SMESH::long_array& theNodesNot,
5747 const SMESH::long_array& theAffectedElems )
5748 throw (SALOME::SALOME_Exception)
5753 SMESHDS_Mesh* aMeshDS = getMeshDS();
5754 TIDSortedElemSet anElems, aNodes, anAffected;
5755 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5756 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5757 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
5759 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5761 // Update Python script
5762 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
5763 << theNodesNot << ", " << theAffectedElems << " )";
5765 declareMeshModified( /*isReComputeSafe=*/false );
5768 SMESH_CATCH( SMESH::throwCorbaException );
5772 //================================================================================
5774 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5775 \param theElems - the list of elements (edges or faces) to be replicated
5776 The nodes for duplication could be found from these elements
5777 \param theNodesNot - list of nodes to NOT replicate
5778 \param theShape - shape to detect affected elements (element which geometric center
5779 located on or inside shape).
5780 The replicated nodes should be associated to affected elements.
5781 \return TRUE if operation has been completed successfully, FALSE otherwise
5782 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
5784 //================================================================================
5786 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
5787 const SMESH::long_array& theNodesNot,
5788 GEOM::GEOM_Object_ptr theShape )
5789 throw (SALOME::SALOME_Exception)
5795 SMESHDS_Mesh* aMeshDS = getMeshDS();
5796 TIDSortedElemSet anElems, aNodes;
5797 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5798 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5800 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5801 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
5803 // Update Python script
5804 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
5805 << theNodesNot << ", " << theShape << " )";
5807 declareMeshModified( /*isReComputeSafe=*/false );
5810 SMESH_CATCH( SMESH::throwCorbaException );
5814 //================================================================================
5816 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5817 \param theElems - group of of elements (edges or faces) to be replicated
5818 \param theNodesNot - group of nodes not to replicated
5819 \param theAffectedElems - group of elements to which the replicated nodes
5820 should be associated to.
5821 \return TRUE if operation has been completed successfully, FALSE otherwise
5822 \sa DoubleNodes(), DoubleNodeGroups()
5824 //================================================================================
5827 SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
5828 SMESH::SMESH_GroupBase_ptr theNodesNot,
5829 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5830 throw (SALOME::SALOME_Exception)
5833 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5839 SMESHDS_Mesh* aMeshDS = getMeshDS();
5840 TIDSortedElemSet anElems, aNodes, anAffected;
5841 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5842 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5843 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5845 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5847 // Update Python script
5848 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
5849 << theNodesNot << ", " << theAffectedElems << " )";
5851 declareMeshModified( /*isReComputeSafe=*/false );
5854 SMESH_CATCH( SMESH::throwCorbaException );
5858 //================================================================================
5860 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5861 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
5862 * \param theElems - group of of elements (edges or faces) to be replicated
5863 * \param theNodesNot - group of nodes not to replicated
5864 * \param theAffectedElems - group of elements to which the replicated nodes
5865 * should be associated to.
5866 * \return a new group with newly created elements
5867 * \sa DoubleNodeElemGroup()
5869 //================================================================================
5871 SMESH::SMESH_Group_ptr
5872 SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
5873 SMESH::SMESH_GroupBase_ptr theNodesNot,
5874 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5875 throw (SALOME::SALOME_Exception)
5878 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroup2New( theElems,
5882 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
5883 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
5885 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupNew( "
5887 << theNodesNot << ", "
5888 << theAffectedElems << " )";
5890 return elemGroup._retn();
5893 //================================================================================
5895 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5896 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
5897 * \param theElems - group of of elements (edges or faces) to be replicated
5898 * \param theNodesNot - group of nodes not to replicated
5899 * \param theAffectedElems - group of elements to which the replicated nodes
5900 * should be associated to.
5901 * \return a new group with newly created elements
5902 * \sa DoubleNodeElemGroup()
5904 //================================================================================
5906 SMESH::ListOfGroups*
5907 SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
5908 SMESH::SMESH_GroupBase_ptr theNodesNot,
5909 SMESH::SMESH_GroupBase_ptr theAffectedElems,
5910 CORBA::Boolean theElemGroupNeeded,
5911 CORBA::Boolean theNodeGroupNeeded)
5912 throw (SALOME::SALOME_Exception)
5915 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
5916 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
5917 aTwoGroups->length( 2 );
5919 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5920 return aTwoGroups._retn();
5925 SMESHDS_Mesh* aMeshDS = getMeshDS();
5926 TIDSortedElemSet anElems, aNodes, anAffected;
5927 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5928 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5929 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5932 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5934 declareMeshModified( /*isReComputeSafe=*/ !aResult );
5940 // Create group with newly created elements
5941 CORBA::String_var elemGroupName = theElems->GetName();
5942 std::string aNewName = generateGroupName( std::string(elemGroupName.in()) + "_double");
5943 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
5945 SMESH::long_array_var anIds = GetLastCreatedElems();
5946 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5947 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5948 aNewElemGroup->Add(anIds);
5950 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
5952 SMESH::long_array_var anIds = GetLastCreatedNodes();
5953 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5954 aNewNodeGroup->Add(anIds);
5958 // Update Python script
5961 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
5962 else pyDump << aNewElemGroup << ", ";
5963 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
5964 else pyDump << aNewNodeGroup << " ] = ";
5966 pyDump << this << ".DoubleNodeElemGroup2New( " << theElems << ", "
5967 << theNodesNot << ", "
5968 << theAffectedElems << ", "
5969 << theElemGroupNeeded << ", "
5970 << theNodeGroupNeeded <<" )";
5972 aTwoGroups[0] = aNewElemGroup._retn();
5973 aTwoGroups[1] = aNewNodeGroup._retn();
5974 return aTwoGroups._retn();
5976 SMESH_CATCH( SMESH::throwCorbaException );
5980 //================================================================================
5982 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5983 \param theElems - group of of elements (edges or faces) to be replicated
5984 \param theNodesNot - group of nodes not to replicated
5985 \param theShape - shape to detect affected elements (element which geometric center
5986 located on or inside shape).
5987 The replicated nodes should be associated to affected elements.
5988 \return TRUE if operation has been completed successfully, FALSE otherwise
5989 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
5991 //================================================================================
5994 SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
5995 SMESH::SMESH_GroupBase_ptr theNodesNot,
5996 GEOM::GEOM_Object_ptr theShape )
5997 throw (SALOME::SALOME_Exception)
6000 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6006 SMESHDS_Mesh* aMeshDS = getMeshDS();
6007 TIDSortedElemSet anElems, aNodes, anAffected;
6008 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6009 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6011 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6012 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6015 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6017 // Update Python script
6018 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
6019 << theNodesNot << ", " << theShape << " )";
6022 SMESH_CATCH( SMESH::throwCorbaException );
6026 //================================================================================
6028 * \brief Re-load elements from a list of groups into a TIDSortedElemSet
6029 * \param [in] theGrpList - groups
6030 * \param [in] theMeshDS - mesh
6031 * \param [out] theElemSet - set of elements
6032 * \param [in] theIsNodeGrp - is \a theGrpList includes goups of nodes
6034 //================================================================================
6036 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
6037 SMESHDS_Mesh* theMeshDS,
6038 TIDSortedElemSet& theElemSet,
6039 const bool theIsNodeGrp)
6041 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
6043 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
6044 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
6045 : aGrp->GetType() != SMESH::NODE ) )
6047 SMESH::long_array_var anIDs = aGrp->GetIDs();
6048 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
6053 //================================================================================
6055 \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6056 This method provided for convenience works as DoubleNodes() described above.
6057 \param theElems - list of groups of elements (edges or faces) to be replicated
6058 \param theNodesNot - list of groups of nodes not to replicated
6059 \param theAffectedElems - group of elements to which the replicated nodes
6060 should be associated to.
6061 \return TRUE if operation has been completed successfully, FALSE otherwise
6062 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
6064 //================================================================================
6067 SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
6068 const SMESH::ListOfGroups& theNodesNot,
6069 const SMESH::ListOfGroups& theAffectedElems)
6070 throw (SALOME::SALOME_Exception)
6076 SMESHDS_Mesh* aMeshDS = getMeshDS();
6077 TIDSortedElemSet anElems, aNodes, anAffected;
6078 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6079 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6080 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6082 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6084 // Update Python script
6085 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
6086 << &theNodesNot << ", " << &theAffectedElems << " )";
6088 declareMeshModified( /*isReComputeSafe=*/false );
6091 SMESH_CATCH( SMESH::throwCorbaException );
6095 //================================================================================
6097 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6098 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6099 \param theElems - list of groups of elements (edges or faces) to be replicated
6100 \param theNodesNot - list of groups of nodes not to replicated
6101 \param theAffectedElems - group of elements to which the replicated nodes
6102 should be associated to.
6103 * \return a new group with newly created elements
6104 * \sa DoubleNodeElemGroups()
6106 //================================================================================
6108 SMESH::SMESH_Group_ptr
6109 SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
6110 const SMESH::ListOfGroups& theNodesNot,
6111 const SMESH::ListOfGroups& theAffectedElems)
6112 throw (SALOME::SALOME_Exception)
6115 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroups2New( theElems,
6119 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
6120 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
6122 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupsNew( "
6124 << theNodesNot << ", "
6125 << theAffectedElems << " )";
6127 return elemGroup._retn();
6130 //================================================================================
6132 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6133 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6134 \param theElems - list of groups of elements (edges or faces) to be replicated
6135 \param theNodesNot - list of groups of nodes not to replicated
6136 \param theAffectedElems - group of elements to which the replicated nodes
6137 should be associated to.
6138 * \return a new group with newly created elements
6139 * \sa DoubleNodeElemGroups()
6141 //================================================================================
6143 SMESH::ListOfGroups*
6144 SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems,
6145 const SMESH::ListOfGroups& theNodesNot,
6146 const SMESH::ListOfGroups& theAffectedElems,
6147 CORBA::Boolean theElemGroupNeeded,
6148 CORBA::Boolean theNodeGroupNeeded)
6149 throw (SALOME::SALOME_Exception)
6152 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
6153 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
6154 aTwoGroups->length( 2 );
6159 SMESHDS_Mesh* aMeshDS = getMeshDS();
6160 TIDSortedElemSet anElems, aNodes, anAffected;
6161 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6162 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6163 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6165 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6167 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6172 // Create group with newly created elements
6173 CORBA::String_var elemGroupName = theElems[0]->GetName();
6174 std::string aNewName = generateGroupName( std::string(elemGroupName.in()) + "_double");
6175 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
6177 SMESH::long_array_var anIds = GetLastCreatedElems();
6178 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
6179 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
6180 aNewElemGroup->Add(anIds);
6182 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
6184 SMESH::long_array_var anIds = GetLastCreatedNodes();
6185 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6186 aNewNodeGroup->Add(anIds);
6190 // Update Python script
6193 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
6194 else pyDump << aNewElemGroup << ", ";
6195 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
6196 else pyDump << aNewNodeGroup << " ] = ";
6198 pyDump << this << ".DoubleNodeElemGroups2New( " << &theElems << ", "
6199 << &theNodesNot << ", "
6200 << &theAffectedElems << ", "
6201 << theElemGroupNeeded << ", "
6202 << theNodeGroupNeeded << " )";
6204 aTwoGroups[0] = aNewElemGroup._retn();
6205 aTwoGroups[1] = aNewNodeGroup._retn();
6206 return aTwoGroups._retn();
6208 SMESH_CATCH( SMESH::throwCorbaException );
6212 //================================================================================
6214 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6215 This method provided for convenience works as DoubleNodes() described above.
6216 \param theElems - list of groups of elements (edges or faces) to be replicated
6217 \param theNodesNot - list of groups of nodes not to replicated
6218 \param theShape - shape to detect affected elements (element which geometric center
6219 located on or inside shape).
6220 The replicated nodes should be associated to affected elements.
6221 \return TRUE if operation has been completed successfully, FALSE otherwise
6222 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
6224 //================================================================================
6227 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
6228 const SMESH::ListOfGroups& theNodesNot,
6229 GEOM::GEOM_Object_ptr theShape )
6230 throw (SALOME::SALOME_Exception)
6236 SMESHDS_Mesh* aMeshDS = getMeshDS();
6237 TIDSortedElemSet anElems, aNodes;
6238 listOfGroupToSet(theElems, aMeshDS, anElems,false );
6239 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6241 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6242 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6244 // Update Python script
6245 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
6246 << &theNodesNot << ", " << theShape << " )";
6248 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6251 SMESH_CATCH( SMESH::throwCorbaException );
6255 //================================================================================
6257 \brief Identify the elements that will be affected by node duplication (actual
6258 duplication is not performed.
6259 This method is the first step of DoubleNodeElemGroupsInRegion.
6260 \param theElems - list of groups of elements (edges or faces) to be replicated
6261 \param theNodesNot - list of groups of nodes not to replicated
6262 \param theShape - shape to detect affected elements (element which geometric center
6263 located on or inside shape).
6264 The replicated nodes should be associated to affected elements.
6265 \return groups of affected elements
6266 \sa DoubleNodeElemGroupsInRegion()
6268 //================================================================================
6269 SMESH::ListOfGroups*
6270 SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theElems,
6271 const SMESH::ListOfGroups& theNodesNot,
6272 GEOM::GEOM_Object_ptr theShape )
6273 throw (SALOME::SALOME_Exception)
6276 SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
6277 bool isEdgeGroup = false;
6278 bool isFaceGroup = false;
6279 bool isVolumeGroup = false;
6280 SMESH::SMESH_Group_var aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE, "affectedEdges");
6281 SMESH::SMESH_Group_var aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE, "affectedFaces");
6282 SMESH::SMESH_Group_var aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME, "affectedVolumes");
6286 ::SMESH_MeshEditor aMeshEditor(myMesh);
6288 SMESHDS_Mesh* aMeshDS = getMeshDS();
6289 TIDSortedElemSet anElems, aNodes;
6290 listOfGroupToSet(theElems, aMeshDS, anElems, false);
6291 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true);
6293 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape(theShape);
6294 TIDSortedElemSet anAffected;
6295 bool aResult = aMeshEditor.AffectedElemGroupsInRegion(anElems, aNodes, aShape, anAffected);
6298 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6303 int lg = anAffected.size();
6304 SMESH::long_array_var volumeIds = new SMESH::long_array;
6305 volumeIds->length(lg);
6306 SMESH::long_array_var faceIds = new SMESH::long_array;
6307 faceIds->length(lg);
6308 SMESH::long_array_var edgeIds = new SMESH::long_array;
6309 edgeIds->length(lg);
6314 TIDSortedElemSet::const_iterator eIt = anAffected.begin();
6315 for (; eIt != anAffected.end(); ++eIt)
6317 const SMDS_MeshElement* anElem = *eIt;
6320 int elemId = anElem->GetID();
6321 if (myMesh->GetElementType(elemId, true) == SMDSAbs_Volume)
6322 volumeIds[ivol++] = elemId;
6323 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Face)
6324 faceIds[iface++] = elemId;
6325 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Edge)
6326 edgeIds[iedge++] = elemId;
6328 volumeIds->length(ivol);
6329 faceIds->length(iface);
6330 edgeIds->length(iedge);
6332 aNewVolumeGroup->Add(volumeIds);
6333 aNewFaceGroup->Add(faceIds);
6334 aNewEdgeGroup->Add(edgeIds);
6335 isVolumeGroup = (aNewVolumeGroup->Size() > 0);
6336 isFaceGroup = (aNewFaceGroup->Size() > 0);
6337 isEdgeGroup = (aNewEdgeGroup->Size() > 0);
6341 if (isEdgeGroup) nbGroups++;
6342 if (isFaceGroup) nbGroups++;
6343 if (isVolumeGroup) nbGroups++;
6344 aListOfGroups->length(nbGroups);
6347 if (isEdgeGroup) aListOfGroups[i++] = aNewEdgeGroup._retn();
6348 if (isFaceGroup) aListOfGroups[i++] = aNewFaceGroup._retn();
6349 if (isVolumeGroup) aListOfGroups[i++] = aNewVolumeGroup._retn();
6351 // Update Python script
6354 if (isEdgeGroup) pyDump << aNewEdgeGroup << ", ";
6355 if (isFaceGroup) pyDump << aNewFaceGroup << ", ";
6356 if (isVolumeGroup) pyDump << aNewVolumeGroup << ", ";
6358 pyDump << this << ".AffectedElemGroupsInRegion( "
6359 << &theElems << ", " << &theNodesNot << ", " << theShape << " )";
6361 return aListOfGroups._retn();
6363 SMESH_CATCH( SMESH::throwCorbaException );
6367 //================================================================================
6369 \brief Generated skin mesh (containing 2D cells) from 3D mesh
6370 The created 2D mesh elements based on nodes of free faces of boundary volumes
6371 \return TRUE if operation has been completed successfully, FALSE otherwise
6373 //================================================================================
6375 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
6376 throw (SALOME::SALOME_Exception)
6381 bool aResult = getEditor().Make2DMeshFrom3D();
6383 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
6385 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6388 SMESH_CATCH( SMESH::throwCorbaException );
6392 //================================================================================
6394 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
6395 * The list of groups must contain at least two groups. The groups have to be disjoint:
6396 * no common element into two different groups.
6397 * The nodes of the internal faces at the boundaries of the groups are doubled.
6398 * Optionally, the internal faces are replaced by flat elements.
6399 * Triangles are transformed into prisms, and quadrangles into hexahedrons.
6400 * The flat elements are stored in groups of volumes.
6401 * These groups are named according to the position of the group in the list:
6402 * 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.
6403 * 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.
6404 * All the flat elements are gathered into the group named "joints3D" (or "joints2D" in 2D situation).
6405 * The flat element of the multiple junctions between the simple junction are stored in a group named "jointsMultiples".
6406 * \param theDomains - list of groups of volumes
6407 * \param createJointElems - if TRUE, create the elements
6408 * \param onAllBoundaries - if TRUE, the nodes and elements are also created on
6409 * the boundary between \a theDomains and the rest mesh
6410 * \return TRUE if operation has been completed successfully, FALSE otherwise
6412 //================================================================================
6415 SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
6416 CORBA::Boolean createJointElems,
6417 CORBA::Boolean onAllBoundaries )
6418 throw (SALOME::SALOME_Exception)
6425 SMESHDS_Mesh* aMeshDS = getMeshDS();
6427 // MESSAGE("theDomains.length = "<<theDomains.length());
6428 if ( theDomains.length() <= 1 && !onAllBoundaries )
6429 THROW_SALOME_CORBA_EXCEPTION("At least 2 groups are required.", SALOME::BAD_PARAM);
6431 vector<TIDSortedElemSet> domains;
6432 domains.resize( theDomains.length() );
6434 for ( int i = 0, n = theDomains.length(); i < n; i++ )
6436 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
6437 if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
6439 // if ( aGrp->GetType() != SMESH::VOLUME )
6440 // THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
6441 SMESH::long_array_var anIDs = aGrp->GetIDs();
6442 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
6446 isOK = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems, onAllBoundaries );
6447 // TODO publish the groups of flat elements in study
6449 declareMeshModified( /*isReComputeSafe=*/ !isOK );
6451 // Update Python script
6452 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
6453 << ", " << createJointElems << ", " << onAllBoundaries << " )";
6455 SMESH_CATCH( SMESH::throwCorbaException );
6457 myMesh_i->CreateGroupServants(); // publish created groups if any
6462 //================================================================================
6464 * \brief Double nodes on some external faces and create flat elements.
6465 * Flat elements are mainly used by some types of mechanic calculations.
6467 * Each group of the list must be constituted of faces.
6468 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
6469 * @param theGroupsOfFaces - list of groups of faces
6470 * @return TRUE if operation has been completed successfully, FALSE otherwise
6472 //================================================================================
6475 SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
6476 throw (SALOME::SALOME_Exception)
6481 SMESHDS_Mesh* aMeshDS = getMeshDS();
6483 vector<TIDSortedElemSet> faceGroups;
6486 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
6488 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
6489 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
6491 TIDSortedElemSet faceGroup;
6493 faceGroups.push_back(faceGroup);
6494 SMESH::long_array_var anIDs = aGrp->GetIDs();
6495 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
6499 bool aResult = getEditor().CreateFlatElementsOnFacesGroups( faceGroups );
6500 // TODO publish the groups of flat elements in study
6502 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6504 // Update Python script
6505 TPythonDump() << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
6508 SMESH_CATCH( SMESH::throwCorbaException );
6512 //================================================================================
6514 * \brief Identify all the elements around a geom shape, get the faces delimiting
6517 * Build groups of volume to remove, groups of faces to replace on the skin of the
6518 * object, groups of faces to remove inside the object, (idem edges).
6519 * Build ordered list of nodes at the border of each group of faces to replace
6520 * (to be used to build a geom subshape).
6522 //================================================================================
6524 void SMESH_MeshEditor_i::CreateHoleSkin(CORBA::Double radius,
6525 GEOM::GEOM_Object_ptr theShape,
6526 const char* groupName,
6527 const SMESH::double_array& theNodesCoords,
6528 SMESH::array_of_long_array_out GroupsOfNodes)
6529 throw (SALOME::SALOME_Exception)
6534 std::vector<std::vector<int> > aListOfListOfNodes;
6535 ::SMESH_MeshEditor aMeshEditor( myMesh );
6537 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
6538 if ( !theNodeSearcher )
6539 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
6541 vector<double> nodesCoords;
6542 for ( CORBA::ULong i = 0; i < theNodesCoords.length(); i++)
6544 nodesCoords.push_back( theNodesCoords[i] );
6547 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6548 aMeshEditor.CreateHoleSkin(radius, aShape, theNodeSearcher, groupName,
6549 nodesCoords, aListOfListOfNodes);
6551 GroupsOfNodes = new SMESH::array_of_long_array;
6552 GroupsOfNodes->length( aListOfListOfNodes.size() );
6553 std::vector<std::vector<int> >::iterator llIt = aListOfListOfNodes.begin();
6554 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
6556 vector<int>& aListOfNodes = *llIt;
6557 vector<int>::iterator lIt = aListOfNodes.begin();;
6558 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
6559 aGroup.length( aListOfNodes.size() );
6560 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
6561 aGroup[ j ] = (*lIt);
6563 TPythonDump() << "lists_nodes = " << this << ".CreateHoleSkin( "
6566 << ", '" << groupName << "', "
6567 << theNodesCoords << " )";
6569 SMESH_CATCH( SMESH::throwCorbaException );
6572 // issue 20749 ===================================================================
6574 * \brief Creates missing boundary elements
6575 * \param elements - elements whose boundary is to be checked
6576 * \param dimension - defines type of boundary elements to create
6577 * \param groupName - a name of group to store created boundary elements in,
6578 * "" means not to create the group
6579 * \param meshName - a name of new mesh to store created boundary elements in,
6580 * "" means not to create the new mesh
6581 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
6582 * \param toCopyExistingBondary - if true, not only new but also pre-existing
6583 * boundary elements will be copied into the new mesh
6584 * \param group - returns the create group, if any
6585 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
6587 // ================================================================================
6589 SMESH::SMESH_Mesh_ptr
6590 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
6591 SMESH::Bnd_Dimension dim,
6592 const char* groupName,
6593 const char* meshName,
6594 CORBA::Boolean toCopyElements,
6595 CORBA::Boolean toCopyExistingBondary,
6596 SMESH::SMESH_Group_out group)
6597 throw (SALOME::SALOME_Exception)
6602 if ( dim > SMESH::BND_1DFROM2D )
6603 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
6605 SMESHDS_Mesh* aMeshDS = getMeshDS();
6607 SMESH::SMESH_Mesh_var mesh_var;
6608 SMESH::SMESH_Group_var group_var;
6612 TIDSortedElemSet elements;
6613 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
6614 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
6618 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
6619 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
6621 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
6623 // group of new boundary elements
6624 SMESH_Group* smesh_group = 0;
6625 if ( strlen(groupName) )
6627 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
6628 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
6629 smesh_group = group_i->GetSmeshGroup();
6633 getEditor().MakeBoundaryMesh( elements,
6634 ::SMESH_MeshEditor::Bnd_Dimension(dim),
6638 toCopyExistingBondary);
6641 smesh_mesh->GetMeshDS()->Modified();
6644 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
6646 // result of MakeBoundaryMesh() is a tuple (mesh, group)
6647 if ( mesh_var->_is_nil() )
6648 pyDump << myMesh_i->_this() << ", ";
6650 pyDump << mesh_var << ", ";
6651 if ( group_var->_is_nil() )
6652 pyDump << "_NoneGroup = "; // assignment to None is forbidden
6654 pyDump << group_var << " = ";
6655 pyDump << this << ".MakeBoundaryMesh( "
6657 << "SMESH." << dimName[int(dim)] << ", "
6658 << "'" << groupName << "', "
6659 << "'" << meshName<< "', "
6660 << toCopyElements << ", "
6661 << toCopyExistingBondary << ")";
6663 group = group_var._retn();
6664 return mesh_var._retn();
6666 SMESH_CATCH( SMESH::throwCorbaException );
6667 return SMESH::SMESH_Mesh::_nil();
6670 //================================================================================
6672 * \brief Creates missing boundary elements
6673 * \param dimension - defines type of boundary elements to create
6674 * \param groupName - a name of group to store all boundary elements in,
6675 * "" means not to create the group
6676 * \param meshName - a name of a new mesh, which is a copy of the initial
6677 * mesh + created boundary elements; "" means not to create the new mesh
6678 * \param toCopyAll - if true, the whole initial mesh will be copied into
6679 * the new mesh else only boundary elements will be copied into the new mesh
6680 * \param groups - optional groups of elements to make boundary around
6681 * \param mesh - returns the mesh where elements were added to
6682 * \param group - returns the created group, if any
6683 * \retval long - number of added boundary elements
6685 //================================================================================
6687 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
6688 const char* groupName,
6689 const char* meshName,
6690 CORBA::Boolean toCopyAll,
6691 const SMESH::ListOfIDSources& groups,
6692 SMESH::SMESH_Mesh_out mesh,
6693 SMESH::SMESH_Group_out group)
6694 throw (SALOME::SALOME_Exception)
6699 if ( dim > SMESH::BND_1DFROM2D )
6700 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
6702 // separate groups belonging to this and other mesh
6703 SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
6704 SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
6705 groupsOfThisMesh ->length( groups.length() );
6706 groupsOfOtherMesh->length( groups.length() );
6707 int nbGroups = 0, nbGroupsOfOtherMesh = 0;
6708 for ( CORBA::ULong i = 0; i < groups.length(); ++i )
6710 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
6711 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
6712 groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
6714 groupsOfThisMesh[ nbGroups++ ] = groups[i];
6715 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
6716 THROW_SALOME_CORBA_EXCEPTION("expected a group but received a mesh", SALOME::BAD_PARAM);
6718 groupsOfThisMesh->length( nbGroups );
6719 groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
6724 if ( nbGroupsOfOtherMesh > 0 )
6726 // process groups belonging to another mesh
6727 SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
6728 SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
6729 nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
6730 groupsOfOtherMesh, mesh, group );
6733 SMESH::SMESH_Mesh_var mesh_var;
6734 SMESH::SMESH_Group_var group_var;
6737 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
6738 const bool toCopyMesh = ( strlen( meshName ) > 0 );
6742 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
6744 /*toCopyGroups=*/false,
6745 /*toKeepIDs=*/true);
6747 mesh_var = makeMesh(meshName);
6749 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
6750 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
6753 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
6754 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
6756 // group of boundary elements
6757 SMESH_Group* smesh_group = 0;
6758 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
6759 if ( strlen(groupName) )
6761 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
6762 group_var = mesh_i->CreateGroup( groupType, groupName );
6763 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
6764 smesh_group = group_i->GetSmeshGroup();
6767 TIDSortedElemSet elements;
6769 if ( groups.length() > 0 )
6771 for ( int i = 0; i < nbGroups; ++i )
6774 if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
6776 SMESH::Bnd_Dimension bdim =
6777 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
6778 nbAdded += getEditor().MakeBoundaryMesh( elements,
6779 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
6782 /*toCopyElements=*/false,
6783 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
6784 /*toAddExistingBondary=*/true,
6785 /*aroundElements=*/true);
6791 nbAdded += getEditor().MakeBoundaryMesh( elements,
6792 ::SMESH_MeshEditor::Bnd_Dimension(dim),
6795 /*toCopyElements=*/false,
6796 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
6797 /*toAddExistingBondary=*/true);
6799 tgtMesh->GetMeshDS()->Modified();
6801 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
6803 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
6804 pyDump << "nbAdded, ";
6805 if ( mesh_var->_is_nil() )
6806 pyDump << myMesh_i->_this() << ", ";
6808 pyDump << mesh_var << ", ";
6809 if ( group_var->_is_nil() )
6810 pyDump << "_NoneGroup = "; // assignment to None is forbidden
6812 pyDump << group_var << " = ";
6813 pyDump << this << ".MakeBoundaryElements( "
6814 << "SMESH." << dimName[int(dim)] << ", "
6815 << "'" << groupName << "', "
6816 << "'" << meshName<< "', "
6817 << toCopyAll << ", "
6820 mesh = mesh_var._retn();
6821 group = group_var._retn();
6824 SMESH_CATCH( SMESH::throwCorbaException );