1 // Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_MeshEditor_i.cxx
23 // Author : Nicolas REJNERI
30 // A macro used in SMESH_TryCatch.hxx,
31 // it re-raises a CORBA SALOME exception thrown by SMESH_MeshEditor_i and caught by SMESH_CATCH
32 #define SMY_OWN_CATCH \
33 catch ( SALOME::SALOME_Exception & e ) { throw e; }
35 #include "SMESH_MeshEditor_i.hxx"
37 #include "SMDS_EdgePosition.hxx"
38 #include "SMDS_ElemIterator.hxx"
39 #include "SMDS_FacePosition.hxx"
40 #include "SMDS_IteratorOnIterators.hxx"
41 #include "SMDS_LinearEdge.hxx"
42 #include "SMDS_Mesh0DElement.hxx"
43 #include "SMDS_MeshFace.hxx"
44 #include "SMDS_MeshVolume.hxx"
45 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
46 #include "SMDS_SetIterator.hxx"
47 #include "SMDS_VolumeTool.hxx"
48 #include "SMESHDS_Group.hxx"
49 #include "SMESHDS_GroupOnGeom.hxx"
50 #include "SMESH_ControlsDef.hxx"
51 #include "SMESH_Filter_i.hxx"
52 #include "SMESH_Gen_i.hxx"
53 #include "SMESH_Group.hxx"
54 #include "SMESH_Group_i.hxx"
55 #include "SMESH_MeshAlgos.hxx"
56 #include "SMESH_MeshPartDS.hxx"
57 #include "SMESH_MesherHelper.hxx"
58 #include "SMESH_PythonDump.hxx"
59 #include "SMESH_subMeshEventListener.hxx"
60 #include "SMESH_subMesh_i.hxx"
62 #include <utilities.h>
63 #include <Utils_ExceptHandlers.hxx>
64 #include <Utils_CorbaException.hxx>
65 #include <SALOMEDS_wrap.hxx>
66 #include <SALOME_GenericObj_i.hh>
67 #include <Basics_OCCTVersion.hxx>
69 #include <BRepAdaptor_Surface.hxx>
70 #include <BRep_Tool.hxx>
71 #include <TopExp_Explorer.hxx>
73 #include <TopoDS_Edge.hxx>
74 #include <TopoDS_Face.hxx>
79 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
83 #include <Standard_Failure.hxx>
86 #include <Standard_ErrorHandler.hxx>
92 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
94 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
97 using SMESH::TPythonDump;
100 namespace MeshEditor_I {
102 //=============================================================================
104 * \brief Mesh to apply modifications for preview purposes
106 //=============================================================================
108 struct TPreviewMesh: public SMESH_Mesh
110 SMDSAbs_ElementType myPreviewType; // type to show
112 TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
113 _isShapeToMesh = (_id =_studyId = 0);
114 _myMeshDS = new SMESHDS_Mesh( _id, true );
115 myPreviewType = previewElements;
117 //!< Copy a set of elements
118 void Copy(const TIDSortedElemSet & theElements,
119 TIDSortedElemSet& theCopyElements,
120 SMDSAbs_ElementType theSelectType = SMDSAbs_All,
121 SMDSAbs_ElementType theAvoidType = SMDSAbs_All)
123 // loop on theIDsOfElements
124 TIDSortedElemSet::const_iterator eIt = theElements.begin();
125 for ( ; eIt != theElements.end(); ++eIt )
127 const SMDS_MeshElement* anElem = *eIt;
128 if ( !anElem ) continue;
129 SMDSAbs_ElementType type = anElem->GetType();
130 if ( type == theAvoidType ||
131 ( theSelectType != SMDSAbs_All && type != theSelectType ))
133 const SMDS_MeshElement* anElemCopy;
134 if ( type == SMDSAbs_Node)
135 anElemCopy = Copy( cast2Node(anElem) );
137 anElemCopy = Copy( anElem );
139 theCopyElements.insert( theCopyElements.end(), anElemCopy );
143 SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
145 // copy element nodes
146 int anElemNbNodes = anElem->NbNodes();
147 vector< int > anElemNodesID( anElemNbNodes ) ;
148 SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
149 for ( int i = 0; itElemNodes->more(); i++)
151 const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
153 anElemNodesID[i] = anElemNode->GetID();
156 // creates a corresponding element on copied nodes
157 ::SMESH_MeshEditor::ElemFeatures elemType;
158 elemType.Init( anElem, /*basicOnly=*/false );
159 elemType.SetID( anElem->GetID() );
160 SMDS_MeshElement* anElemCopy =
161 ::SMESH_MeshEditor(this).AddElement( anElemNodesID, elemType );
165 SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
167 return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(),
168 anElemNode->GetID());
172 GetMeshDS()->ClearMesh();
174 void Remove( SMDSAbs_ElementType type )
176 SMDS_ElemIteratorPtr eIt = GetMeshDS()->elementsIterator( type );
177 while ( eIt->more() )
178 GetMeshDS()->RemoveFreeElement( eIt->next(), /*sm=*/0, /*fromGroups=*/false );
180 };// struct TPreviewMesh
182 static SMESH_NodeSearcher * theNodeSearcher = 0;
183 static SMESH_ElementSearcher * theElementSearcher = 0;
185 //=============================================================================
187 * \brief Deleter of theNodeSearcher at any compute event occured
189 //=============================================================================
191 struct TSearchersDeleter : public SMESH_subMeshEventListener
194 string myMeshPartIOR;
196 TSearchersDeleter(): SMESH_subMeshEventListener( false, // won't be deleted by submesh
197 "SMESH_MeshEditor_i::TSearchersDeleter"),
199 //!< Delete theNodeSearcher
202 if ( theNodeSearcher ) delete theNodeSearcher; theNodeSearcher = 0;
203 if ( theElementSearcher ) delete theElementSearcher; theElementSearcher = 0;
205 typedef map < int, SMESH_subMesh * > TDependsOnMap;
206 //!< The meshod called by submesh: do my main job
207 void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
208 SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
210 if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
212 Unset( sm->GetFather() );
215 //!< set self on all submeshes and delete theNodeSearcher if other mesh is set
216 void Set(SMESH_Mesh* mesh, const string& meshPartIOR = string())
218 if ( myMesh != mesh || myMeshPartIOR != meshPartIOR)
225 myMeshPartIOR = meshPartIOR;
226 SMESH_subMesh* sm = mesh->GetSubMesh( mesh->GetShapeToMesh() );
227 SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true );
228 while ( smIt->more() )
231 sm->SetEventListener( this, 0, sm );
235 //!< delete self from all submeshes
236 void Unset(SMESH_Mesh* mesh)
238 if ( SMESH_subMesh* sm = mesh->GetSubMeshContaining(1) ) {
239 SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true );
240 while ( smIt->more() )
241 smIt->next()->DeleteEventListener( this );
246 } theSearchersDeleter;
248 TCollection_AsciiString mirrorTypeName( SMESH::SMESH_MeshEditor::MirrorType theMirrorType )
250 TCollection_AsciiString typeStr;
251 switch ( theMirrorType ) {
252 case SMESH::SMESH_MeshEditor::POINT:
253 typeStr = "SMESH.SMESH_MeshEditor.POINT";
255 case SMESH::SMESH_MeshEditor::AXIS:
256 typeStr = "SMESH.SMESH_MeshEditor.AXIS";
259 typeStr = "SMESH.SMESH_MeshEditor.PLANE";
263 //================================================================================
265 * \brief function for conversion of long_array to TIDSortedElemSet
266 * \param IDs - array of IDs
267 * \param aMesh - mesh
268 * \param aMap - collection to fill
269 * \param aType - element type
271 //================================================================================
273 void arrayToSet(const SMESH::long_array & IDs,
274 const SMESHDS_Mesh* aMesh,
275 TIDSortedElemSet& aMap,
276 const SMDSAbs_ElementType aType = SMDSAbs_All,
277 SMDS_MeshElement::Filter* aFilter = NULL)
279 SMDS_MeshElement::NonNullFilter filter1;
280 SMDS_MeshElement::TypeFilter filter2( aType );
282 if ( aFilter == NULL )
283 aFilter = ( aType == SMDSAbs_All ) ? (SMDS_MeshElement::Filter*) &filter1 : (SMDS_MeshElement::Filter*) &filter2;
285 SMDS_MeshElement::Filter & filter = *aFilter;
287 if ( aType == SMDSAbs_Node )
288 for ( CORBA::ULong i = 0; i < IDs.length(); i++ ) {
289 const SMDS_MeshElement * elem = aMesh->FindNode( IDs[i] );
291 aMap.insert( aMap.end(), elem );
294 for ( CORBA::ULong i = 0; i<IDs.length(); i++) {
295 const SMDS_MeshElement * elem = aMesh->FindElement( IDs[i] );
297 aMap.insert( aMap.end(), elem );
301 //================================================================================
303 * \brief Retrieve nodes from SMESH_IDSource
305 //================================================================================
307 void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject,
308 const SMESHDS_Mesh* theMeshDS,
309 TIDSortedNodeSet& theNodeSet)
312 if ( CORBA::is_nil( theObject ) )
314 SMESH::array_of_ElementType_var types = theObject->GetTypes();
315 SMESH::long_array_var aElementsId = theObject->GetIDs();
316 if ( types->length() == 1 && types[0] == SMESH::NODE)
318 for ( CORBA::ULong i = 0; i < aElementsId->length(); i++ )
319 if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] ))
320 theNodeSet.insert( theNodeSet.end(), n);
322 else if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
324 SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator();
325 while ( nIt->more( ))
326 if ( const SMDS_MeshElement * elem = nIt->next() )
327 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
331 for ( CORBA::ULong i = 0; i < aElementsId->length(); i++ )
332 if ( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] ))
333 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
337 //================================================================================
339 * \brief Returns elements connected to the given elements
341 //================================================================================
343 void getElementsAround(const TIDSortedElemSet& theElements,
344 const SMESHDS_Mesh* theMeshDS,
345 TIDSortedElemSet& theElementsAround)
347 if ( theElements.empty() ) return;
349 SMDSAbs_ElementType elemType = (*theElements.begin())->GetType();
350 bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() );
352 theMeshDS->GetMeshInfo().NbElements( elemType ) == (int) theElements.size() )
353 return; // all the elements are in theElements
356 elemType = SMDSAbs_All;
358 vector<bool> isNodeChecked( theMeshDS->NbNodes(), false );
360 TIDSortedElemSet::const_iterator elemIt = theElements.begin();
361 for ( ; elemIt != theElements.end(); ++elemIt )
363 const SMDS_MeshElement* e = *elemIt;
364 int i = e->NbCornerNodes();
367 const SMDS_MeshNode* n = e->GetNode( i );
368 if ( !isNodeChecked[ n->GetID() ])
370 isNodeChecked[ n->GetID() ] = true;
371 SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
372 while ( invIt->more() )
374 const SMDS_MeshElement* elemAround = invIt->next();
375 if ( !theElements.count( elemAround ))
376 theElementsAround.insert( elemAround );
383 //================================================================================
385 * \brief Return a string used to detect change of mesh part on which theElementSearcher
386 * is going to be used
388 //================================================================================
390 string getPartIOR( SMESH::SMESH_IDSource_ptr theMeshPart, SMESH::ElementType type)
392 string partIOR = SMESH_Gen_i::GetORB()->object_to_string( theMeshPart );
393 if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( theMeshPart ))
394 // take into account passible group modification
395 partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() );
396 partIOR += SMESH_Comment( type );
400 } // namespace MeshEditor_I
402 using namespace MeshEditor_I;
404 //=============================================================================
408 //=============================================================================
410 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview):
412 myMesh( &theMesh->GetImpl() ),
414 myIsPreviewMode ( isPreview ),
420 //================================================================================
424 //================================================================================
426 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
428 PortableServer::POA_var poa = SMESH_Gen_i::GetPOA();
429 PortableServer::ObjectId_var anObjectId = poa->servant_to_id(this);
430 poa->deactivate_object(anObjectId.in());
432 //deleteAuxIDSources();
433 delete myPreviewMesh; myPreviewMesh = 0;
434 delete myPreviewEditor; myPreviewEditor = 0;
437 //================================================================================
439 * \brief Returns the mesh
441 //================================================================================
443 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::GetMesh()
445 return myMesh_i->_this();
448 //================================================================================
450 * \brief Clear members
452 //================================================================================
454 void SMESH_MeshEditor_i::initData(bool deleteSearchers)
456 if ( myIsPreviewMode ) {
457 if ( myPreviewMesh ) myPreviewMesh->RemoveAll();
460 if ( deleteSearchers )
461 TSearchersDeleter::Delete();
463 getEditor().GetError().reset();
464 getEditor().ClearLastCreated();
467 //================================================================================
469 * \brief Increment mesh modif time and optionally record that the performed
470 * modification may influence futher mesh re-compute.
471 * \param [in] isReComputeSafe - true if the modification does not influence
472 * futher mesh re-compute
474 //================================================================================
476 void SMESH_MeshEditor_i::declareMeshModified( bool isReComputeSafe )
478 myMesh->GetMeshDS()->Modified();
479 if ( !isReComputeSafe )
480 myMesh->SetIsModified( true );
483 //================================================================================
485 * \brief Return either myEditor or myPreviewEditor depending on myIsPreviewMode.
486 * WARNING: in preview mode call getPreviewMesh() before getEditor()!
488 //================================================================================
490 ::SMESH_MeshEditor& SMESH_MeshEditor_i::getEditor()
492 if ( myIsPreviewMode && !myPreviewEditor ) {
493 if ( !myPreviewMesh ) getPreviewMesh();
494 myPreviewEditor = new ::SMESH_MeshEditor( myPreviewMesh );
496 return myIsPreviewMode ? *myPreviewEditor : myEditor;
499 //================================================================================
501 * \brief Initialize and return myPreviewMesh
502 * \param previewElements - type of elements to show in preview
504 * WARNING: call it once par a method!
506 //================================================================================
508 TPreviewMesh * SMESH_MeshEditor_i::getPreviewMesh(SMDSAbs_ElementType previewElements)
510 if ( !myPreviewMesh || myPreviewMesh->myPreviewType != previewElements )
512 delete myPreviewEditor;
514 delete myPreviewMesh;
515 myPreviewMesh = new TPreviewMesh( previewElements );
517 myPreviewMesh->Clear();
518 return myPreviewMesh;
521 //================================================================================
523 * Return data of mesh edition preview
525 //================================================================================
527 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
528 throw (SALOME::SALOME_Exception)
531 const bool hasBadElems = ( getEditor().GetError() && getEditor().GetError()->HasBadElems() );
533 if ( myIsPreviewMode || hasBadElems ) { // --- MeshPreviewStruct filling ---
535 list<int> aNodesConnectivity;
536 typedef map<int, int> TNodesMap;
539 SMESHDS_Mesh* aMeshDS;
540 std::auto_ptr< SMESH_MeshPartDS > aMeshPartDS;
542 aMeshPartDS.reset( new SMESH_MeshPartDS( getEditor().GetError()->myBadElements ));
543 aMeshDS = aMeshPartDS.get();
546 aMeshDS = getEditor().GetMeshDS();
548 myPreviewData = new SMESH::MeshPreviewStruct();
549 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
552 SMDSAbs_ElementType previewType = SMDSAbs_All;
554 if (TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( getEditor().GetMesh() )) {
555 previewType = aPreviewMesh->myPreviewType;
556 switch ( previewType ) {
557 case SMDSAbs_Edge : break;
558 case SMDSAbs_Face : break;
559 case SMDSAbs_Volume: break;
561 if ( aMeshDS->GetMeshInfo().NbElements() == 0 ) previewType = SMDSAbs_Node;
565 myPreviewData->elementTypes.length( aMeshDS->GetMeshInfo().NbElements( previewType ));
567 SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator(previewType);
569 while ( itMeshElems->more() ) {
570 const SMDS_MeshElement* aMeshElem = itMeshElems->next();
571 SMDS_NodeIteratorPtr itElemNodes =
572 (( aMeshElem->GetEntityType() == SMDSEntity_Quad_Polygon ) ?
573 aMeshElem->interlacedNodesIterator() :
574 aMeshElem->nodeIterator() );
575 while ( itElemNodes->more() ) {
576 const SMDS_MeshNode* aMeshNode = itElemNodes->next();
577 int aNodeID = aMeshNode->GetID();
578 TNodesMap::iterator anIter = nodesMap.find(aNodeID);
579 if ( anIter == nodesMap.end() ) {
580 // filling the nodes coordinates
581 myPreviewData->nodesXYZ[j].x = aMeshNode->X();
582 myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
583 myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
584 anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
587 aNodesConnectivity.push_back(anIter->second);
590 // filling the elements types
591 SMDSAbs_ElementType aType = aMeshElem->GetType();
592 bool isPoly = aMeshElem->IsPoly();
593 myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
594 myPreviewData->elementTypes[i].isPoly = isPoly;
595 myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
598 myPreviewData->nodesXYZ.length( j );
600 // filling the elements connectivities
601 list<int>::iterator aConnIter = aNodesConnectivity.begin();
602 myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
603 for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
604 myPreviewData->elementConnectivities[i] = *aConnIter;
606 return myPreviewData._retn();
608 SMESH_CATCH( SMESH::throwCorbaException );
612 //================================================================================
614 * \brief Returns list of it's IDs of created nodes
615 * \retval SMESH::long_array* - list of node ID
617 //================================================================================
619 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
620 throw (SALOME::SALOME_Exception)
623 SMESH::long_array_var myLastCreatedNodes = new SMESH::long_array();
625 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedNodes();
626 myLastCreatedNodes->length( aSeq.Length() );
627 for (int i = 1; i <= aSeq.Length(); i++)
628 myLastCreatedNodes[i-1] = aSeq.Value(i)->GetID();
630 return myLastCreatedNodes._retn();
631 SMESH_CATCH( SMESH::throwCorbaException );
635 //================================================================================
637 * \brief Returns list of it's IDs of created elements
638 * \retval SMESH::long_array* - list of elements' ID
640 //================================================================================
642 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
643 throw (SALOME::SALOME_Exception)
646 SMESH::long_array_var myLastCreatedElems = new SMESH::long_array();
648 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
649 myLastCreatedElems->length( aSeq.Length() );
650 for ( int i = 1; i <= aSeq.Length(); i++ )
651 myLastCreatedElems[i-1] = aSeq.Value(i)->GetID();
653 return myLastCreatedElems._retn();
654 SMESH_CATCH( SMESH::throwCorbaException );
658 //=======================================================================
659 //function : ClearLastCreated
660 //purpose : Clears sequences of last created elements and nodes
661 //=======================================================================
663 void SMESH_MeshEditor_i::ClearLastCreated() throw (SALOME::SALOME_Exception)
666 getEditor().ClearLastCreated();
667 SMESH_CATCH( SMESH::throwCorbaException );
670 //=======================================================================
672 * Returns description of an error/warning occured during the last operation
673 * WARNING: ComputeError.code >= 100 and no corresponding enum in IDL API
675 //=======================================================================
677 SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError()
678 throw (SALOME::SALOME_Exception)
681 SMESH::ComputeError_var errOut = new SMESH::ComputeError;
682 SMESH_ComputeErrorPtr& errIn = getEditor().GetError();
683 if ( errIn && !errIn->IsOK() )
685 errOut->code = -( errIn->myName < 0 ? errIn->myName + 1: errIn->myName ); // -1 -> 0
686 errOut->comment = errIn->myComment.c_str();
687 errOut->subShapeID = -1;
688 errOut->hasBadMesh = !errIn->myBadElements.empty();
693 errOut->subShapeID = -1;
694 errOut->hasBadMesh = false;
697 return errOut._retn();
698 SMESH_CATCH( SMESH::throwCorbaException );
702 //=======================================================================
703 //function : MakeIDSource
704 //purpose : Wrap a sequence of ids in a SMESH_IDSource.
705 // Call UnRegister() as you fininsh using it!!
706 //=======================================================================
708 struct SMESH_MeshEditor_i::_IDSource : public virtual POA_SMESH::SMESH_IDSource,
709 public virtual SALOME::GenericObj_i
711 SMESH::long_array _ids;
712 SMESH::ElementType _type;
713 SMESH::SMESH_Mesh_ptr _mesh;
714 SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); }
715 SMESH::long_array* GetMeshInfo() { return 0; }
716 SMESH::long_array* GetNbElementsByType()
718 SMESH::long_array_var aRes = new SMESH::long_array();
719 aRes->length(SMESH::NB_ELEMENT_TYPES);
720 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
721 aRes[ i ] = ( i == _type ) ? _ids.length() : 0;
724 SMESH::SMESH_Mesh_ptr GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _mesh ); }
725 bool IsMeshInfoCorrect() { return true; }
726 SMESH::array_of_ElementType* GetTypes()
728 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
729 if ( _ids.length() > 0 ) {
733 return types._retn();
735 SALOMEDS::TMPFile* GetVtkUgStream()
737 SALOMEDS::TMPFile_var SeqFile;
738 return SeqFile._retn();
742 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
743 SMESH::ElementType type)
745 _IDSource* idSrc = new _IDSource;
746 idSrc->_mesh = myMesh_i->_this();
749 if ( type == SMESH::ALL && ids.length() > 0 )
750 idSrc->_type = myMesh_i->GetElementType( ids[0], true );
752 SMESH::SMESH_IDSource_var anIDSourceVar = idSrc->_this();
754 return anIDSourceVar._retn();
757 bool SMESH_MeshEditor_i::IsTemporaryIDSource( SMESH::SMESH_IDSource_ptr& idSource )
759 return SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource );
762 CORBA::Long* SMESH_MeshEditor_i::GetTemporaryIDs( SMESH::SMESH_IDSource_ptr& idSource,
765 if ( _IDSource* tmpIdSource = SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource ))
767 nbIds = (int) tmpIdSource->_ids.length();
768 return & tmpIdSource->_ids[0];
774 // void SMESH_MeshEditor_i::deleteAuxIDSources()
776 // std::list< _IDSource* >::iterator idSrcIt = myAuxIDSources.begin();
777 // for ( ; idSrcIt != myAuxIDSources.end(); ++idSrcIt )
779 // myAuxIDSources.clear();
782 //=============================================================================
786 //=============================================================================
789 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
790 throw (SALOME::SALOME_Exception)
797 for ( CORBA::ULong i = 0; i < IDsOfElements.length(); i++ )
798 IdList.push_back( IDsOfElements[i] );
800 // Update Python script
801 TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
804 bool ret = getEditor().Remove( IdList, false );
806 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 ); // issue 0020693
809 SMESH_CATCH( SMESH::throwCorbaException );
813 //=============================================================================
817 //=============================================================================
819 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
820 throw (SALOME::SALOME_Exception)
826 for ( CORBA::ULong i = 0; i < IDsOfNodes.length(); i++)
827 IdList.push_back( IDsOfNodes[i] );
829 // Update Python script
830 TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
832 bool ret = getEditor().Remove( IdList, true );
834 declareMeshModified( /*isReComputeSafe=*/ !ret ); // issue 0020693
837 SMESH_CATCH( SMESH::throwCorbaException );
841 //=============================================================================
845 //=============================================================================
847 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
848 throw (SALOME::SALOME_Exception)
853 // Update Python script
854 TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
856 // Create filter to find all orphan nodes
857 SMESH::Controls::Filter::TIdSequence seq;
858 SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
859 SMESH::Controls::Filter::GetElementsId( getMeshDS(), predicate, seq );
861 // remove orphan nodes (if there are any)
862 list< int > IdList( seq.begin(), seq.end() );
864 int nbNodesBefore = myMesh->NbNodes();
865 getEditor().Remove( IdList, true );
866 int nbNodesAfter = myMesh->NbNodes();
868 declareMeshModified( /*isReComputeSafe=*/ IdList.size() == 0 ); // issue 0020693
869 return nbNodesBefore - nbNodesAfter;
871 SMESH_CATCH( SMESH::throwCorbaException );
875 //=============================================================================
879 //=============================================================================
881 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,CORBA::Double y, CORBA::Double z)
882 throw (SALOME::SALOME_Exception)
887 const SMDS_MeshNode* N = getMeshDS()->AddNode(x, y, z);
889 // Update Python script
890 TPythonDump() << "nodeID = " << this << ".AddNode( "
891 << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )";
893 declareMeshModified( /*isReComputeSafe=*/false );
896 SMESH_CATCH( SMESH::throwCorbaException );
900 //=============================================================================
902 * Create 0D element on the given node.
904 //=============================================================================
906 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
907 throw (SALOME::SALOME_Exception)
912 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
913 SMDS_MeshElement* elem = getMeshDS()->Add0DElement(aNode);
915 // Update Python script
916 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
918 declareMeshModified( /*isReComputeSafe=*/false );
920 return elem ? elem->GetID() : 0;
922 SMESH_CATCH( SMESH::throwCorbaException );
926 //=============================================================================
928 * Create a ball element on the given node.
930 //=============================================================================
932 CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diameter)
933 throw (SALOME::SALOME_Exception)
938 if ( diameter < std::numeric_limits<double>::min() )
939 THROW_SALOME_CORBA_EXCEPTION("Invalid diameter", SALOME::BAD_PARAM);
941 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
942 SMDS_MeshElement* elem = getMeshDS()->AddBall(aNode, diameter);
944 // Update Python script
945 TPythonDump() << "ballElem = "
946 << this << ".AddBall( " << IDOfNode << ", " << diameter <<" )";
948 declareMeshModified( /*isReComputeSafe=*/false );
949 return elem ? elem->GetID() : 0;
951 SMESH_CATCH( SMESH::throwCorbaException );
955 //=============================================================================
957 * Create an edge, either linear and quadratic (this is determed
958 * by number of given nodes, two or three)
960 //=============================================================================
962 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
963 throw (SALOME::SALOME_Exception)
968 int NbNodes = IDsOfNodes.length();
969 SMDS_MeshElement* elem = 0;
972 CORBA::Long index1 = IDsOfNodes[0];
973 CORBA::Long index2 = IDsOfNodes[1];
974 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(index1),
975 getMeshDS()->FindNode(index2));
977 // Update Python script
978 TPythonDump() << "edge = " << this << ".AddEdge([ "
979 << index1 << ", " << index2 <<" ])";
982 CORBA::Long n1 = IDsOfNodes[0];
983 CORBA::Long n2 = IDsOfNodes[1];
984 CORBA::Long n12 = IDsOfNodes[2];
985 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(n1),
986 getMeshDS()->FindNode(n2),
987 getMeshDS()->FindNode(n12));
988 // Update Python script
989 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
990 <<n1<<", "<<n2<<", "<<n12<<" ])";
993 declareMeshModified( /*isReComputeSafe=*/false );
994 return elem ? elem->GetID() : 0;
996 SMESH_CATCH( SMESH::throwCorbaException );
1000 //=============================================================================
1004 //=============================================================================
1006 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
1007 throw (SALOME::SALOME_Exception)
1012 int NbNodes = IDsOfNodes.length();
1018 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1019 for (int i = 0; i < NbNodes; i++)
1020 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1022 SMDS_MeshElement* elem = 0;
1024 case 3: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]); break;
1025 case 4: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]); break;
1026 case 6: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1027 nodes[4], nodes[5]); break;
1028 case 7: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1029 nodes[4], nodes[5], nodes[6]); break;
1030 case 8: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1031 nodes[4], nodes[5], nodes[6], nodes[7]); break;
1032 case 9: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1033 nodes[4], nodes[5], nodes[6], nodes[7],
1035 default: elem = getMeshDS()->AddPolygonalFace(nodes);
1038 // Update Python script
1039 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
1041 declareMeshModified( /*isReComputeSafe=*/false );
1043 return elem ? elem->GetID() : 0;
1045 SMESH_CATCH( SMESH::throwCorbaException );
1049 //=============================================================================
1053 //=============================================================================
1055 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
1056 throw (SALOME::SALOME_Exception)
1061 int NbNodes = IDsOfNodes.length();
1062 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1063 for (int i = 0; i < NbNodes; i++)
1064 if ( ! ( nodes[i] = getMeshDS()->FindNode( IDsOfNodes[i] )))
1067 const SMDS_MeshElement* elem = getMeshDS()->AddPolygonalFace(nodes);
1069 // Update Python script
1070 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
1072 declareMeshModified( /*isReComputeSafe=*/false );
1073 return elem ? elem->GetID() : 0;
1075 SMESH_CATCH( SMESH::throwCorbaException );
1079 //=============================================================================
1081 * AddQuadPolygonalFace
1083 //=============================================================================
1085 CORBA::Long SMESH_MeshEditor_i::AddQuadPolygonalFace (const SMESH::long_array & IDsOfNodes)
1086 throw (SALOME::SALOME_Exception)
1091 int NbNodes = IDsOfNodes.length();
1092 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1093 for (int i = 0; i < NbNodes; i++)
1094 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1096 const SMDS_MeshElement* elem = getMeshDS()->AddQuadPolygonalFace(nodes);
1098 // Update Python script
1099 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
1101 declareMeshModified( /*isReComputeSafe=*/false );
1102 return elem ? elem->GetID() : 0;
1104 SMESH_CATCH( SMESH::throwCorbaException );
1108 //=============================================================================
1110 * Create volume, either linear and quadratic (this is determed
1111 * by number of given nodes)
1113 //=============================================================================
1115 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
1116 throw (SALOME::SALOME_Exception)
1121 int NbNodes = IDsOfNodes.length();
1122 vector< const SMDS_MeshNode*> n(NbNodes);
1123 for(int i=0;i<NbNodes;i++)
1124 n[i]= getMeshDS()->FindNode(IDsOfNodes[i]);
1126 SMDS_MeshElement* elem = 0;
1129 case 4 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
1130 case 5 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
1131 case 6 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
1132 case 8 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
1133 case 10:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1134 n[6],n[7],n[8],n[9]);
1136 case 12:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1137 n[6],n[7],n[8],n[9],n[10],n[11]);
1139 case 13:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
1140 n[7],n[8],n[9],n[10],n[11],n[12]);
1142 case 15:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
1143 n[9],n[10],n[11],n[12],n[13],n[14]);
1145 case 20:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1146 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1147 n[15],n[16],n[17],n[18],n[19]);
1149 case 27:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1150 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1151 n[15],n[16],n[17],n[18],n[19],
1152 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
1156 // Update Python script
1157 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
1159 declareMeshModified( /*isReComputeSafe=*/false );
1160 return elem ? elem->GetID() : 0;
1162 SMESH_CATCH( SMESH::throwCorbaException );
1166 //=============================================================================
1168 * AddPolyhedralVolume
1170 //=============================================================================
1171 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
1172 const SMESH::long_array & Quantities)
1173 throw (SALOME::SALOME_Exception)
1178 int NbNodes = IDsOfNodes.length();
1179 std::vector<const SMDS_MeshNode*> n (NbNodes);
1180 for (int i = 0; i < NbNodes; i++)
1182 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDsOfNodes[i]);
1183 if (!aNode) return 0;
1187 int NbFaces = Quantities.length();
1188 std::vector<int> q (NbFaces);
1189 for (int j = 0; j < NbFaces; j++)
1190 q[j] = Quantities[j];
1192 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(n, q);
1194 // Update Python script
1195 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
1196 << IDsOfNodes << ", " << Quantities << " )";
1198 declareMeshModified( /*isReComputeSafe=*/false );
1199 return elem ? elem->GetID() : 0;
1201 SMESH_CATCH( SMESH::throwCorbaException );
1205 //=============================================================================
1207 * AddPolyhedralVolumeByFaces
1209 //=============================================================================
1211 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
1212 throw (SALOME::SALOME_Exception)
1217 int NbFaces = IdsOfFaces.length();
1218 std::vector<const SMDS_MeshNode*> poly_nodes;
1219 std::vector<int> quantities (NbFaces);
1221 for (int i = 0; i < NbFaces; i++) {
1222 const SMDS_MeshElement* aFace = getMeshDS()->FindElement(IdsOfFaces[i]);
1223 quantities[i] = aFace->NbNodes();
1225 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
1226 while (It->more()) {
1227 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
1231 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
1233 // Update Python script
1234 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
1235 << IdsOfFaces << " )";
1237 declareMeshModified( /*isReComputeSafe=*/false );
1238 return elem ? elem->GetID() : 0;
1240 SMESH_CATCH( SMESH::throwCorbaException );
1244 //=============================================================================
1246 // \brief Create 0D elements on all nodes of the given object except those
1247 // nodes on which a 0D element already exists.
1248 // \param theObject object on whose nodes 0D elements will be created.
1249 // \param theGroupName optional name of a group to add 0D elements created
1250 // and/or found on nodes of \a theObject.
1251 // \return an object (a new group or a temporary SMESH_IDSource) holding
1252 // ids of new and/or found 0D elements.
1254 //=============================================================================
1256 SMESH::SMESH_IDSource_ptr
1257 SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObject,
1258 const char* theGroupName)
1259 throw (SALOME::SALOME_Exception)
1264 SMESH::SMESH_IDSource_var result;
1267 TIDSortedElemSet elements, elems0D;
1268 if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
1269 getEditor().Create0DElementsOnAllNodes( elements, elems0D );
1271 SMESH::long_array_var newElems = new SMESH::long_array;
1272 newElems->length( elems0D.size() );
1273 TIDSortedElemSet::iterator eIt = elems0D.begin();
1274 for ( size_t i = 0; i < elems0D.size(); ++i, ++eIt )
1275 newElems[ i ] = (*eIt)->GetID();
1277 SMESH::SMESH_GroupBase_var groupToFill;
1278 if ( theGroupName && strlen( theGroupName ))
1280 // Get existing group named theGroupName
1281 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
1282 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
1283 SMESH::SMESH_GroupBase_var group = groups[i];
1284 if ( !group->_is_nil() ) {
1285 CORBA::String_var name = group->GetName();
1286 if ( strcmp( name.in(), theGroupName ) == 0 && group->GetType() == SMESH::ELEM0D ) {
1287 groupToFill = group;
1292 if ( groupToFill->_is_nil() )
1293 groupToFill = myMesh_i->CreateGroup( SMESH::ELEM0D, theGroupName );
1294 else if ( !SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1295 groupToFill = myMesh_i->ConvertToStandalone( groupToFill );
1298 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1300 group_i->Add( newElems );
1301 result = SMESH::SMESH_IDSource::_narrow( groupToFill );
1302 pyDump << groupToFill;
1306 result = MakeIDSource( newElems, SMESH::ELEM0D );
1307 pyDump << "elem0DIDs";
1310 pyDump << " = " << this << ".Create0DElementsOnAllNodes( "
1311 << theObject << ", '" << theGroupName << "' )";
1313 return result._retn();
1315 SMESH_CATCH( SMESH::throwCorbaException );
1319 //=============================================================================
1321 * \brief Bind a node to a vertex
1322 * \param NodeID - node ID
1323 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1324 * \retval boolean - false if NodeID or VertexID is invalid
1326 //=============================================================================
1328 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
1329 throw (SALOME::SALOME_Exception)
1333 SMESHDS_Mesh * mesh = getMeshDS();
1334 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1336 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1338 if ( mesh->MaxShapeIndex() < VertexID )
1339 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1341 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
1342 if ( shape.ShapeType() != TopAbs_VERTEX )
1343 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1345 mesh->SetNodeOnVertex( node, VertexID );
1347 myMesh->SetIsModified( true );
1349 SMESH_CATCH( SMESH::throwCorbaException );
1352 //=============================================================================
1354 * \brief Store node position on an edge
1355 * \param NodeID - node ID
1356 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
1357 * \param paramOnEdge - parameter on edge where the node is located
1358 * \retval boolean - false if any parameter is invalid
1360 //=============================================================================
1362 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
1363 CORBA::Double paramOnEdge)
1364 throw (SALOME::SALOME_Exception)
1368 SMESHDS_Mesh * mesh = getMeshDS();
1369 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1371 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1373 if ( mesh->MaxShapeIndex() < EdgeID )
1374 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1376 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
1377 if ( shape.ShapeType() != TopAbs_EDGE )
1378 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1381 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
1382 if ( paramOnEdge < f || paramOnEdge > l )
1383 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
1385 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
1387 myMesh->SetIsModified( true );
1389 SMESH_CATCH( SMESH::throwCorbaException );
1392 //=============================================================================
1394 * \brief Store node position on a face
1395 * \param NodeID - node ID
1396 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
1397 * \param u - U parameter on face where the node is located
1398 * \param v - V parameter on face where the node is located
1399 * \retval boolean - false if any parameter is invalid
1401 //=============================================================================
1403 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
1404 CORBA::Double u, CORBA::Double v)
1405 throw (SALOME::SALOME_Exception)
1408 SMESHDS_Mesh * mesh = getMeshDS();
1409 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1411 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1413 if ( mesh->MaxShapeIndex() < FaceID )
1414 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1416 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
1417 if ( shape.ShapeType() != TopAbs_FACE )
1418 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1420 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
1421 bool isOut = ( u < surf.FirstUParameter() ||
1422 u > surf.LastUParameter() ||
1423 v < surf.FirstVParameter() ||
1424 v > surf.LastVParameter() );
1428 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
1429 << " u( " << surf.FirstUParameter()
1430 << "," << surf.LastUParameter()
1431 << ") v( " << surf.FirstVParameter()
1432 << "," << surf.LastVParameter() << ")" );
1434 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
1437 mesh->SetNodeOnFace( node, FaceID, u, v );
1438 myMesh->SetIsModified( true );
1440 SMESH_CATCH( SMESH::throwCorbaException );
1443 //=============================================================================
1445 * \brief Bind a node to a solid
1446 * \param NodeID - node ID
1447 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1448 * \retval boolean - false if NodeID or SolidID is invalid
1450 //=============================================================================
1452 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
1453 throw (SALOME::SALOME_Exception)
1456 SMESHDS_Mesh * mesh = getMeshDS();
1457 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1459 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1461 if ( mesh->MaxShapeIndex() < SolidID )
1462 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1464 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
1465 if ( shape.ShapeType() != TopAbs_SOLID &&
1466 shape.ShapeType() != TopAbs_SHELL)
1467 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1469 mesh->SetNodeInVolume( node, SolidID );
1471 SMESH_CATCH( SMESH::throwCorbaException );
1474 //=============================================================================
1476 * \brief Bind an element to a shape
1477 * \param ElementID - element ID
1478 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
1480 //=============================================================================
1482 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
1483 CORBA::Long ShapeID)
1484 throw (SALOME::SALOME_Exception)
1487 SMESHDS_Mesh * mesh = getMeshDS();
1488 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
1490 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
1492 if ( mesh->MaxShapeIndex() < ShapeID || ShapeID < 1 )
1493 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1495 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1496 if ( shape.ShapeType() != TopAbs_EDGE &&
1497 shape.ShapeType() != TopAbs_FACE &&
1498 shape.ShapeType() != TopAbs_SOLID &&
1499 shape.ShapeType() != TopAbs_SHELL )
1500 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1502 mesh->SetMeshElementOnShape( elem, ShapeID );
1504 myMesh->SetIsModified( true );
1506 SMESH_CATCH( SMESH::throwCorbaException );
1509 //=============================================================================
1513 //=============================================================================
1515 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1516 CORBA::Long NodeID2)
1517 throw (SALOME::SALOME_Exception)
1522 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1523 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1527 // Update Python script
1528 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1529 << NodeID1 << ", " << NodeID2 << " )";
1531 int ret = getEditor().InverseDiag ( n1, n2 );
1533 declareMeshModified( /*isReComputeSafe=*/false );
1536 SMESH_CATCH( SMESH::throwCorbaException );
1540 //=============================================================================
1544 //=============================================================================
1546 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1547 CORBA::Long NodeID2)
1548 throw (SALOME::SALOME_Exception)
1553 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1554 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1558 // Update Python script
1559 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1560 << NodeID1 << ", " << NodeID2 << " )";
1563 bool stat = getEditor().DeleteDiag ( n1, n2 );
1565 declareMeshModified( /*isReComputeSafe=*/!stat );
1569 SMESH_CATCH( SMESH::throwCorbaException );
1573 //=============================================================================
1577 //=============================================================================
1579 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1580 throw (SALOME::SALOME_Exception)
1585 for ( CORBA::ULong i = 0; i < IDsOfElements.length(); i++ )
1587 CORBA::Long index = IDsOfElements[i];
1588 const SMDS_MeshElement * elem = getMeshDS()->FindElement(index);
1590 getEditor().Reorient( elem );
1592 // Update Python script
1593 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1595 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 );
1598 SMESH_CATCH( SMESH::throwCorbaException );
1602 //=============================================================================
1606 //=============================================================================
1608 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1609 throw (SALOME::SALOME_Exception)
1614 TPythonDump aTPythonDump; // suppress dump in Reorient()
1616 prepareIdSource( theObject );
1618 SMESH::long_array_var anElementsId = theObject->GetIDs();
1619 CORBA::Boolean isDone = Reorient(anElementsId);
1621 // Update Python script
1622 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1624 declareMeshModified( /*isReComputeSafe=*/ anElementsId->length() == 0 );
1627 SMESH_CATCH( SMESH::throwCorbaException );
1631 //=======================================================================
1632 //function : Reorient2D
1633 //purpose : Reorient faces contained in \a the2Dgroup.
1634 // the2Dgroup - the mesh or its part to reorient
1635 // theDirection - desired direction of normal of \a theFace
1636 // theFace - ID of face whose orientation is checked.
1637 // It can be < 1 then \a thePoint is used to find a face.
1638 // thePoint - is used to find a face if \a theFace < 1.
1639 // return number of reoriented elements.
1640 //=======================================================================
1642 CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
1643 const SMESH::DirStruct& theDirection,
1644 CORBA::Long theFace,
1645 const SMESH::PointStruct& thePoint)
1646 throw (SALOME::SALOME_Exception)
1649 initData(/*deleteSearchers=*/false);
1651 TIDSortedElemSet elements;
1652 IDSource_Error error;
1653 idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error );
1654 if ( error == IDSource_EMPTY )
1656 if ( error == IDSource_INVALID )
1657 THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
1660 const SMDS_MeshElement* face = 0;
1663 face = getMeshDS()->FindElement( theFace );
1665 THROW_SALOME_CORBA_EXCEPTION("Inexistent face given", SALOME::BAD_PARAM);
1666 if ( face->GetType() != SMDSAbs_Face )
1667 THROW_SALOME_CORBA_EXCEPTION("Wrong element type", SALOME::BAD_PARAM);
1671 // create theElementSearcher if needed
1672 theSearchersDeleter.Set( myMesh, getPartIOR( the2Dgroup, SMESH::FACE ));
1673 if ( !theElementSearcher )
1675 if ( elements.empty() ) // search in the whole mesh
1677 if ( myMesh->NbFaces() == 0 )
1678 THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM);
1680 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
1684 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
1685 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
1687 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt);
1691 gp_Pnt p( thePoint.x, thePoint.y, thePoint.z );
1692 face = theElementSearcher->FindClosestTo( p, SMDSAbs_Face );
1695 THROW_SALOME_CORBA_EXCEPTION("No face found by point", SALOME::INTERNAL_ERROR );
1696 if ( !elements.empty() && !elements.count( face ))
1697 THROW_SALOME_CORBA_EXCEPTION("Found face is not in the group", SALOME::BAD_PARAM );
1700 const SMESH::PointStruct * P = &theDirection.PS;
1701 gp_Vec dirVec( P->x, P->y, P->z );
1702 if ( dirVec.Magnitude() < std::numeric_limits< double >::min() )
1703 THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM);
1705 int nbReori = getEditor().Reorient2D( elements, dirVec, face );
1708 declareMeshModified( /*isReComputeSafe=*/false );
1710 TPythonDump() << this << ".Reorient2D( "
1711 << the2Dgroup << ", "
1712 << theDirection << ", "
1714 << thePoint << " )";
1718 SMESH_CATCH( SMESH::throwCorbaException );
1722 //=======================================================================
1723 //function : Reorient2DBy3D
1724 //purpose : Reorient faces basing on orientation of adjacent volumes.
1725 //=======================================================================
1727 CORBA::Long SMESH_MeshEditor_i::Reorient2DBy3D(const SMESH::ListOfIDSources& faceGroups,
1728 SMESH::SMESH_IDSource_ptr volumeGroup,
1729 CORBA::Boolean outsideNormal)
1730 throw (SALOME::SALOME_Exception)
1735 TIDSortedElemSet volumes;
1736 IDSource_Error volsError;
1737 idSourceToSet( volumeGroup, getMeshDS(), volumes, SMDSAbs_Volume, /*emptyIfMesh=*/1, &volsError);
1740 for ( size_t i = 0; i < faceGroups.length(); ++i )
1742 SMESH::SMESH_IDSource_ptr faceGrp = faceGroups[i].in();
1744 TIDSortedElemSet faces;
1745 IDSource_Error error;
1746 idSourceToSet( faceGrp, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error );
1747 if ( error == IDSource_INVALID && faceGroups.length() == 1 )
1748 THROW_SALOME_CORBA_EXCEPTION("No faces in a given object", SALOME::BAD_PARAM);
1749 if ( error == IDSource_OK && volsError != IDSource_OK )
1750 THROW_SALOME_CORBA_EXCEPTION("No volumes in a given object", SALOME::BAD_PARAM);
1752 nbReori += getEditor().Reorient2DBy3D( faces, volumes, outsideNormal );
1754 if ( error != IDSource_EMPTY && faces.empty() ) // all faces in the mesh treated
1759 declareMeshModified( /*isReComputeSafe=*/false );
1761 TPythonDump() << this << ".Reorient2DBy3D( "
1762 << faceGroups << ", "
1763 << volumeGroup << ", "
1764 << outsideNormal << " )";
1768 SMESH_CATCH( SMESH::throwCorbaException );
1772 //=============================================================================
1774 * \brief Fuse neighbour triangles into quadrangles.
1776 //=============================================================================
1778 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1779 SMESH::NumericalFunctor_ptr Criterion,
1780 CORBA::Double MaxAngle)
1781 throw (SALOME::SALOME_Exception)
1786 SMESHDS_Mesh* aMesh = getMeshDS();
1787 TIDSortedElemSet faces,copyFaces;
1788 SMDS_MeshElement::GeomFilter triaFilter(SMDSGeom_TRIANGLE);
1789 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face, & triaFilter);
1790 TIDSortedElemSet* workElements = & faces;
1792 if ( myIsPreviewMode ) {
1793 SMDSAbs_ElementType select = SMDSAbs_Face;
1794 getPreviewMesh( SMDSAbs_Face )->Copy( faces, copyFaces, select );
1795 workElements = & copyFaces;
1798 SMESH::NumericalFunctor_i* aNumericalFunctor =
1799 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1800 SMESH::Controls::NumericalFunctorPtr aCrit;
1801 if ( !aNumericalFunctor )
1802 aCrit.reset( new SMESH::Controls::MaxElementLength2D() );
1804 aCrit = aNumericalFunctor->GetNumericalFunctor();
1806 if ( !myIsPreviewMode ) {
1807 // Update Python script
1808 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1809 << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1812 bool stat = getEditor().TriToQuad( *workElements, aCrit, MaxAngle );
1814 declareMeshModified( /*isReComputeSafe=*/!stat );
1817 SMESH_CATCH( SMESH::throwCorbaException );
1821 //=============================================================================
1823 * \brief Fuse neighbour triangles into quadrangles.
1825 //=============================================================================
1827 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1828 SMESH::NumericalFunctor_ptr Criterion,
1829 CORBA::Double MaxAngle)
1830 throw (SALOME::SALOME_Exception)
1835 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1837 prepareIdSource( theObject );
1838 SMESH::long_array_var anElementsId = theObject->GetIDs();
1839 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1841 if ( !myIsPreviewMode ) {
1842 SMESH::NumericalFunctor_i* aNumericalFunctor =
1843 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1845 // Update Python script
1846 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1847 << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1852 SMESH_CATCH( SMESH::throwCorbaException );
1856 //=============================================================================
1858 * \brief Split quadrangles into triangles.
1860 //=============================================================================
1862 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1863 SMESH::NumericalFunctor_ptr Criterion)
1864 throw (SALOME::SALOME_Exception)
1869 SMESHDS_Mesh* aMesh = getMeshDS();
1870 TIDSortedElemSet faces;
1871 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1873 SMESH::NumericalFunctor_i* aNumericalFunctor =
1874 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1875 SMESH::Controls::NumericalFunctorPtr aCrit;
1876 if ( !aNumericalFunctor )
1877 aCrit.reset( new SMESH::Controls::AspectRatio() );
1879 aCrit = aNumericalFunctor->GetNumericalFunctor();
1882 // Update Python script
1883 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1885 CORBA::Boolean stat = getEditor().QuadToTri( faces, aCrit );
1887 declareMeshModified( /*isReComputeSafe=*/false );
1890 SMESH_CATCH( SMESH::throwCorbaException );
1894 //=============================================================================
1896 * \brief Split quadrangles into triangles.
1898 //=============================================================================
1900 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1901 SMESH::NumericalFunctor_ptr Criterion)
1902 throw (SALOME::SALOME_Exception)
1907 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1909 prepareIdSource( theObject );
1910 SMESH::long_array_var anElementsId = theObject->GetIDs();
1911 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1913 SMESH::NumericalFunctor_i* aNumericalFunctor =
1914 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1916 // Update Python script
1917 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1919 declareMeshModified( /*isReComputeSafe=*/false );
1922 SMESH_CATCH( SMESH::throwCorbaException );
1926 //================================================================================
1928 * \brief Split each of quadrangles into 4 triangles.
1929 * \param [in] theObject - theQuads Container of quadrangles to split.
1931 //================================================================================
1933 void SMESH_MeshEditor_i::QuadTo4Tri (SMESH::SMESH_IDSource_ptr theObject)
1934 throw (SALOME::SALOME_Exception)
1939 TIDSortedElemSet faces;
1940 if ( !idSourceToSet( theObject, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/true ) &&
1942 THROW_SALOME_CORBA_EXCEPTION("No faces given", SALOME::BAD_PARAM);
1944 getEditor().QuadTo4Tri( faces );
1945 TPythonDump() << this << ".QuadTo4Tri( " << theObject << " )";
1947 SMESH_CATCH( SMESH::throwCorbaException );
1950 //=============================================================================
1952 * \brief Split quadrangles into triangles.
1954 //=============================================================================
1956 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1957 CORBA::Boolean Diag13)
1958 throw (SALOME::SALOME_Exception)
1963 SMESHDS_Mesh* aMesh = getMeshDS();
1964 TIDSortedElemSet faces;
1965 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1967 // Update Python script
1968 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1969 << IDsOfElements << ", " << Diag13 << " )";
1971 CORBA::Boolean stat = getEditor().QuadToTri( faces, Diag13 );
1973 declareMeshModified( /*isReComputeSafe=*/ !stat );
1976 SMESH_CATCH( SMESH::throwCorbaException );
1980 //=============================================================================
1982 * \brief Split quadrangles into triangles.
1984 //=============================================================================
1986 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1987 CORBA::Boolean Diag13)
1988 throw (SALOME::SALOME_Exception)
1993 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
1995 prepareIdSource( theObject );
1996 SMESH::long_array_var anElementsId = theObject->GetIDs();
1997 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
1999 // Update Python script
2000 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
2001 << theObject << ", " << Diag13 << " )";
2003 declareMeshModified( /*isReComputeSafe=*/!isDone );
2006 SMESH_CATCH( SMESH::throwCorbaException );
2011 //=============================================================================
2013 * Find better splitting of the given quadrangle.
2014 * \param IDOfQuad ID of the quadrangle to be splitted.
2015 * \param Criterion A criterion to choose a diagonal for splitting.
2016 * \return 1 if 1-3 diagonal is better, 2 if 2-4
2017 * diagonal is better, 0 if error occurs.
2019 //=============================================================================
2021 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
2022 SMESH::NumericalFunctor_ptr Criterion)
2023 throw (SALOME::SALOME_Exception)
2028 const SMDS_MeshElement* quad = getMeshDS()->FindElement(IDOfQuad);
2029 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
2031 SMESH::NumericalFunctor_i* aNumericalFunctor =
2032 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
2033 SMESH::Controls::NumericalFunctorPtr aCrit;
2034 if (aNumericalFunctor)
2035 aCrit = aNumericalFunctor->GetNumericalFunctor();
2037 aCrit.reset(new SMESH::Controls::AspectRatio());
2039 int id = getEditor().BestSplit(quad, aCrit);
2040 declareMeshModified( /*isReComputeSafe=*/ id < 1 );
2044 SMESH_CATCH( SMESH::throwCorbaException );
2048 //================================================================================
2050 * \brief Split volumic elements into tetrahedrons
2052 //================================================================================
2054 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
2055 CORBA::Short methodFlags)
2056 throw (SALOME::SALOME_Exception)
2061 ::SMESH_MeshEditor::TFacetOfElem elemSet;
2062 const int noneFacet = -1;
2063 SMDS_ElemIteratorPtr volIt = myMesh_i->GetElements( elems, SMESH::VOLUME );
2064 while( volIt->more() )
2065 elemSet.insert( elemSet.end(), make_pair( volIt->next(), noneFacet ));
2067 getEditor().SplitVolumes( elemSet, int( methodFlags ));
2068 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2070 TPythonDump() << this << ".SplitVolumesIntoTetra( "
2071 << elems << ", " << methodFlags << " )";
2073 SMESH_CATCH( SMESH::throwCorbaException );
2076 //================================================================================
2078 * \brief Split hexahedra into triangular prisms
2079 * \param elems - elements to split
2080 * \param facetToSplitNormal - normal used to find a facet of hexahedron
2081 * to split into triangles
2082 * \param methodFlags - flags passing splitting method:
2083 * 1 - split the hexahedron into 2 prisms
2084 * 2 - split the hexahedron into 4 prisms
2086 //================================================================================
2088 void SMESH_MeshEditor_i::SplitHexahedraIntoPrisms( SMESH::SMESH_IDSource_ptr elems,
2089 const SMESH::PointStruct & startHexPoint,
2090 const SMESH::DirStruct& facetToSplitNormal,
2091 CORBA::Short methodFlags,
2092 CORBA::Boolean allDomains)
2093 throw (SALOME::SALOME_Exception)
2097 prepareIdSource( elems );
2099 gp_Ax1 facetNorm( gp_Pnt( startHexPoint.x,
2102 gp_Dir( facetToSplitNormal.PS.x,
2103 facetToSplitNormal.PS.y,
2104 facetToSplitNormal.PS.z ));
2105 TIDSortedElemSet elemSet;
2106 SMESH::long_array_var anElementsId = elems->GetIDs();
2107 SMDS_MeshElement::GeomFilter filter( SMDSGeom_HEXA );
2108 arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume, &filter );
2110 ::SMESH_MeshEditor::TFacetOfElem elemFacets;
2111 while ( !elemSet.empty() )
2113 getEditor().GetHexaFacetsToSplit( elemSet, facetNorm, elemFacets );
2117 ::SMESH_MeshEditor::TFacetOfElem::iterator ef = elemFacets.begin();
2118 for ( ; ef != elemFacets.end(); ++ef )
2119 elemSet.erase( ef->first );
2122 if ( methodFlags == 2 )
2123 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_4_PRISMS );
2125 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_2_PRISMS );
2127 getEditor().SplitVolumes( elemFacets, int( methodFlags ));
2128 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2130 TPythonDump() << this << ".SplitHexahedraIntoPrisms( "
2132 << startHexPoint << ", "
2133 << facetToSplitNormal<< ", "
2134 << methodFlags<< ", "
2135 << allDomains << " )";
2137 SMESH_CATCH( SMESH::throwCorbaException );
2140 //================================================================================
2142 * \brief Split bi-quadratic elements into linear ones without creation of additional nodes:
2143 * - bi-quadratic triangle will be split into 3 linear quadrangles;
2144 * - bi-quadratic quadrangle will be split into 4 linear quadrangles;
2145 * - tri-quadratic hexahedron will be split into 8 linear hexahedra.
2146 * Quadratic elements of lower dimension adjacent to the split bi-quadratic element
2147 * will be split in order to keep the mesh conformal.
2148 * \param elems - elements to split
2150 //================================================================================
2152 void SMESH_MeshEditor_i::SplitBiQuadraticIntoLinear(const SMESH::ListOfIDSources& theElems)
2153 throw (SALOME::SALOME_Exception)
2158 TIDSortedElemSet elemSet;
2159 for ( size_t i = 0; i < theElems.length(); ++i )
2161 SMESH::SMESH_IDSource_ptr elems = theElems[i].in();
2162 SMESH::SMESH_Mesh_var mesh = elems->GetMesh();
2163 if ( mesh->GetId() != myMesh_i->GetId() )
2164 THROW_SALOME_CORBA_EXCEPTION("Wrong mesh of IDSource", SALOME::BAD_PARAM);
2166 idSourceToSet( elems, getMeshDS(), elemSet, SMDSAbs_All );
2168 getEditor().SplitBiQuadraticIntoLinear( elemSet );
2170 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2172 TPythonDump() << this << ".SplitBiQuadraticIntoLinear( "
2173 << theElems << " )";
2175 SMESH_CATCH( SMESH::throwCorbaException );
2178 //=======================================================================
2181 //=======================================================================
2184 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
2185 const SMESH::long_array & IDsOfFixedNodes,
2186 CORBA::Long MaxNbOfIterations,
2187 CORBA::Double MaxAspectRatio,
2188 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2189 throw (SALOME::SALOME_Exception)
2191 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2192 MaxAspectRatio, Method, false );
2196 //=======================================================================
2197 //function : SmoothParametric
2199 //=======================================================================
2202 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
2203 const SMESH::long_array & IDsOfFixedNodes,
2204 CORBA::Long MaxNbOfIterations,
2205 CORBA::Double MaxAspectRatio,
2206 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2207 throw (SALOME::SALOME_Exception)
2209 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2210 MaxAspectRatio, Method, true );
2214 //=======================================================================
2215 //function : SmoothObject
2217 //=======================================================================
2220 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
2221 const SMESH::long_array & IDsOfFixedNodes,
2222 CORBA::Long MaxNbOfIterations,
2223 CORBA::Double MaxAspectRatio,
2224 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2225 throw (SALOME::SALOME_Exception)
2227 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2228 MaxAspectRatio, Method, false);
2232 //=======================================================================
2233 //function : SmoothParametricObject
2235 //=======================================================================
2238 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
2239 const SMESH::long_array & IDsOfFixedNodes,
2240 CORBA::Long MaxNbOfIterations,
2241 CORBA::Double MaxAspectRatio,
2242 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2243 throw (SALOME::SALOME_Exception)
2245 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2246 MaxAspectRatio, Method, true);
2250 //=============================================================================
2254 //=============================================================================
2257 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
2258 const SMESH::long_array & IDsOfFixedNodes,
2259 CORBA::Long MaxNbOfIterations,
2260 CORBA::Double MaxAspectRatio,
2261 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2263 throw (SALOME::SALOME_Exception)
2268 SMESHDS_Mesh* aMesh = getMeshDS();
2270 TIDSortedElemSet elements;
2271 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
2273 set<const SMDS_MeshNode*> fixedNodes;
2274 for ( CORBA::ULong i = 0; i < IDsOfFixedNodes.length(); i++) {
2275 CORBA::Long index = IDsOfFixedNodes[i];
2276 const SMDS_MeshNode * node = aMesh->FindNode(index);
2278 fixedNodes.insert( node );
2280 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
2281 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
2282 method = ::SMESH_MeshEditor::CENTROIDAL;
2284 getEditor().Smooth(elements, fixedNodes, method,
2285 MaxNbOfIterations, MaxAspectRatio, IsParametric );
2287 declareMeshModified( /*isReComputeSafe=*/true ); // does not prevent re-compute
2289 // Update Python script
2290 TPythonDump() << "isDone = " << this << "."
2291 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
2292 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
2293 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2294 << "SMESH.SMESH_MeshEditor."
2295 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2296 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2300 SMESH_CATCH( SMESH::throwCorbaException );
2304 //=============================================================================
2308 //=============================================================================
2311 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
2312 const SMESH::long_array & IDsOfFixedNodes,
2313 CORBA::Long MaxNbOfIterations,
2314 CORBA::Double MaxAspectRatio,
2315 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2317 throw (SALOME::SALOME_Exception)
2322 TPythonDump aTPythonDump; // suppress dump in smooth()
2324 prepareIdSource( theObject );
2325 SMESH::long_array_var anElementsId = theObject->GetIDs();
2326 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
2327 MaxAspectRatio, Method, IsParametric);
2329 // Update Python script
2330 aTPythonDump << "isDone = " << this << "."
2331 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
2332 << theObject << ", " << IDsOfFixedNodes << ", "
2333 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2334 << "SMESH.SMESH_MeshEditor."
2335 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2336 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2340 SMESH_CATCH( SMESH::throwCorbaException );
2344 //=============================================================================
2348 //=============================================================================
2350 void SMESH_MeshEditor_i::RenumberNodes()
2351 throw (SALOME::SALOME_Exception)
2354 // Update Python script
2355 TPythonDump() << this << ".RenumberNodes()";
2357 getMeshDS()->Renumber( true );
2359 SMESH_CATCH( SMESH::throwCorbaException );
2362 //=============================================================================
2366 //=============================================================================
2368 void SMESH_MeshEditor_i::RenumberElements()
2369 throw (SALOME::SALOME_Exception)
2372 // Update Python script
2373 TPythonDump() << this << ".RenumberElements()";
2375 getMeshDS()->Renumber( false );
2377 SMESH_CATCH( SMESH::throwCorbaException );
2380 //=======================================================================
2382 * \brief Return groups by their IDs
2384 //=======================================================================
2386 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
2387 throw (SALOME::SALOME_Exception)
2392 myMesh_i->CreateGroupServants();
2393 return myMesh_i->GetGroups( *groupIDs );
2395 SMESH_CATCH( SMESH::throwCorbaException );
2399 //=======================================================================
2400 //function : RotationSweepObjects
2402 //=======================================================================
2404 SMESH::ListOfGroups*
2405 SMESH_MeshEditor_i::RotationSweepObjects(const SMESH::ListOfIDSources & theNodes,
2406 const SMESH::ListOfIDSources & theEdges,
2407 const SMESH::ListOfIDSources & theFaces,
2408 const SMESH::AxisStruct & theAxis,
2409 CORBA::Double theAngleInRadians,
2410 CORBA::Long theNbOfSteps,
2411 CORBA::Double theTolerance,
2412 const bool theMakeGroups)
2413 throw (SALOME::SALOME_Exception)
2418 TIDSortedElemSet elemsNodes[2];
2419 for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) {
2420 SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE );
2421 while ( nIt->more() ) elemsNodes[1].insert( nIt->next() );
2423 for ( int i = 0, nb = theEdges.length(); i < nb; ++i )
2424 idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge );
2425 for ( int i = 0, nb = theFaces.length(); i < nb; ++i )
2426 idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face );
2428 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2429 bool makeWalls=true;
2430 if ( myIsPreviewMode )
2432 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2433 TPreviewMesh * tmpMesh = getPreviewMesh();
2434 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2435 tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid );
2436 workElements = & copyElements[0];
2437 //makeWalls = false; -- faces are needed for preview
2440 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2442 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
2443 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
2445 ::SMESH_MeshEditor::PGroupIDs groupIds =
2446 getEditor().RotationSweep (workElements, Ax1, theAngleInRadians,
2447 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
2449 SMESH::ListOfGroups * aGroups = theMakeGroups ? getGroups( groupIds.get()) : 0;
2451 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2453 if ( !myIsPreviewMode )
2455 dumpGroupsList( aPythonDump, aGroups );
2456 aPythonDump << this<< ".RotationSweepObjects( "
2461 << TVar( theAngleInRadians ) << ", "
2462 << TVar( theNbOfSteps ) << ", "
2463 << TVar( theTolerance ) << ", "
2464 << theMakeGroups << " )";
2468 getPreviewMesh()->Remove( SMDSAbs_Volume );
2471 return aGroups ? aGroups : new SMESH::ListOfGroups;
2473 SMESH_CATCH( SMESH::throwCorbaException );
2477 namespace MeshEditor_I
2480 * \brief Structure used to pass extrusion parameters to ::SMESH_MeshEditor
2482 struct ExtrusionParams : public ::SMESH_MeshEditor::ExtrusParam
2484 bool myIsExtrusionByNormal;
2486 static int makeFlags( CORBA::Boolean MakeGroups,
2487 CORBA::Boolean ByAverageNormal = false,
2488 CORBA::Boolean UseInputElemsOnly = false,
2489 CORBA::Long Flags = 0,
2490 CORBA::Boolean MakeBoundary = true )
2492 if ( MakeGroups ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS;
2493 if ( ByAverageNormal ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BY_AVG_NORMAL;
2494 if ( UseInputElemsOnly) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY;
2495 if ( MakeBoundary ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BOUNDARY;
2499 ExtrusionParams(const SMESH::DirStruct & theDir,
2500 CORBA::Long theNbOfSteps,
2501 CORBA::Boolean theMakeGroups):
2502 ::SMESH_MeshEditor::ExtrusParam ( gp_Vec( theDir.PS.x,
2506 makeFlags( theMakeGroups )),
2507 myIsExtrusionByNormal( false )
2511 ExtrusionParams(const SMESH::DirStruct & theDir,
2512 CORBA::Long theNbOfSteps,
2513 CORBA::Boolean theMakeGroups,
2514 CORBA::Long theExtrFlags,
2515 CORBA::Double theSewTolerance):
2516 ::SMESH_MeshEditor::ExtrusParam ( gp_Vec( theDir.PS.x,
2520 makeFlags( theMakeGroups, false, false,
2521 theExtrFlags, false ),
2523 myIsExtrusionByNormal( false )
2526 // params for extrusion by normal
2527 ExtrusionParams(CORBA::Double theStepSize,
2528 CORBA::Long theNbOfSteps,
2529 CORBA::Short theDim,
2530 CORBA::Boolean theByAverageNormal,
2531 CORBA::Boolean theUseInputElemsOnly,
2532 CORBA::Boolean theMakeGroups ):
2533 ::SMESH_MeshEditor::ExtrusParam ( theStepSize,
2535 makeFlags( theMakeGroups,
2536 theByAverageNormal, theUseInputElemsOnly ),
2538 myIsExtrusionByNormal( true )
2544 Flags() &= ~(::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS);
2549 //=======================================================================
2551 * \brief Generate dim+1 elements by extrusion of elements along vector
2552 * \param [in] edges - edges to extrude: a list including groups, sub-meshes or a mesh
2553 * \param [in] faces - faces to extrude: a list including groups, sub-meshes or a mesh
2554 * \param [in] nodes - nodes to extrude: a list including groups, sub-meshes or a mesh
2555 * \param [in] stepVector - vector giving direction and distance of an extrusion step
2556 * \param [in] nbOfSteps - number of elements to generate from one element
2557 * \param [in] toMakeGroups - if true, new elements will be included into new groups
2558 * corresponding to groups the input elements included in.
2559 * \return ListOfGroups - new groups craeted if \a toMakeGroups is true
2561 //=======================================================================
2563 SMESH::ListOfGroups*
2564 SMESH_MeshEditor_i::ExtrusionSweepObjects(const SMESH::ListOfIDSources & theNodes,
2565 const SMESH::ListOfIDSources & theEdges,
2566 const SMESH::ListOfIDSources & theFaces,
2567 const SMESH::DirStruct & theStepVector,
2568 CORBA::Long theNbOfSteps,
2569 CORBA::Boolean theToMakeGroups)
2570 throw (SALOME::SALOME_Exception)
2575 ExtrusionParams params( theStepVector, theNbOfSteps, theToMakeGroups );
2577 TIDSortedElemSet elemsNodes[2];
2578 for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) {
2579 SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE );
2580 while ( nIt->more() ) elemsNodes[1].insert( nIt->next() );
2582 for ( int i = 0, nb = theEdges.length(); i < nb; ++i )
2583 idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge );
2584 for ( int i = 0, nb = theFaces.length(); i < nb; ++i )
2585 idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face );
2587 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2588 SMDSAbs_ElementType previewType = SMDSAbs_All; //SMDSAbs_Face;
2589 if ( myIsPreviewMode )
2591 // if ( (*elemsNodes.begin())->GetType() == SMDSAbs_Node )
2592 // previewType = SMDSAbs_Edge;
2594 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2595 TPreviewMesh * tmpMesh = getPreviewMesh( previewType );
2596 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2597 tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid );
2598 workElements = & copyElements[0];
2600 params.SetNoGroups();
2602 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2604 ::SMESH_MeshEditor::TTElemOfElemListMap aHistory;
2605 ::SMESH_MeshEditor::PGroupIDs groupIds =
2606 getEditor().ExtrusionSweep( workElements, params, aHistory );
2608 SMESH::ListOfGroups * aGroups = theToMakeGroups ? getGroups( groupIds.get()) : 0;
2610 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2612 if ( !myIsPreviewMode )
2614 dumpGroupsList( aPythonDump, aGroups );
2615 aPythonDump << this<< ".ExtrusionSweepObjects( "
2619 << theStepVector << ", "
2620 << TVar( theNbOfSteps ) << ", "
2621 << theToMakeGroups << " )";
2625 getPreviewMesh( previewType )->Remove( SMDSAbs_Volume );
2628 return aGroups ? aGroups : new SMESH::ListOfGroups;
2630 SMESH_CATCH( SMESH::throwCorbaException );
2634 //=======================================================================
2635 //function : ExtrusionByNormal
2637 //=======================================================================
2639 SMESH::ListOfGroups*
2640 SMESH_MeshEditor_i::ExtrusionByNormal(const SMESH::ListOfIDSources& objects,
2641 CORBA::Double stepSize,
2642 CORBA::Long nbOfSteps,
2643 CORBA::Boolean byAverageNormal,
2644 CORBA::Boolean useInputElemsOnly,
2645 CORBA::Boolean makeGroups,
2647 throw (SALOME::SALOME_Exception)
2652 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2654 ExtrusionParams params( stepSize, nbOfSteps, dim,
2655 byAverageNormal, useInputElemsOnly, makeGroups );
2657 SMDSAbs_ElementType elemType = ( dim == 1 ? SMDSAbs_Edge : SMDSAbs_Face );
2658 if ( objects.length() > 0 && !SMESH::DownCast<SMESH_Mesh_i*>( objects[0] ))
2660 SMESH::array_of_ElementType_var elemTypes = objects[0]->GetTypes();
2661 if (( elemTypes->length() == 1 ) &&
2662 ( elemTypes[0] == SMESH::EDGE || elemTypes[0] == SMESH::FACE ))
2663 elemType = ( SMDSAbs_ElementType ) elemTypes[0];
2666 TIDSortedElemSet elemsNodes[2];
2667 for ( int i = 0, nb = objects.length(); i < nb; ++i )
2668 idSourceToSet( objects[i], getMeshDS(), elemsNodes[0], elemType );
2670 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2671 SMDSAbs_ElementType previewType = SMDSAbs_Face;
2672 if ( myIsPreviewMode )
2674 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2675 TPreviewMesh * tmpMesh = getPreviewMesh( previewType );
2676 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2677 workElements = & copyElements[0];
2679 params.SetNoGroups();
2682 ::SMESH_MeshEditor::TTElemOfElemListMap aHistory;
2683 ::SMESH_MeshEditor::PGroupIDs groupIds =
2684 getEditor().ExtrusionSweep( workElements, params, aHistory );
2686 SMESH::ListOfGroups * aGroups = makeGroups ? getGroups( groupIds.get()) : 0;
2688 if (!myIsPreviewMode) {
2689 dumpGroupsList(aPythonDump, aGroups);
2690 aPythonDump << this << ".ExtrusionByNormal( " << objects
2691 << ", " << TVar( stepSize )
2692 << ", " << TVar( nbOfSteps )
2693 << ", " << byAverageNormal
2694 << ", " << useInputElemsOnly
2695 << ", " << makeGroups
2701 getPreviewMesh( previewType )->Remove( SMDSAbs_Volume );
2704 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2706 return aGroups ? aGroups : new SMESH::ListOfGroups;
2708 SMESH_CATCH( SMESH::throwCorbaException );
2712 //=======================================================================
2713 //function : AdvancedExtrusion
2715 //=======================================================================
2717 SMESH::ListOfGroups*
2718 SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2719 const SMESH::DirStruct & theStepVector,
2720 CORBA::Long theNbOfSteps,
2721 CORBA::Long theExtrFlags,
2722 CORBA::Double theSewTolerance,
2723 CORBA::Boolean theMakeGroups)
2724 throw (SALOME::SALOME_Exception)
2729 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2731 ExtrusionParams params( theStepVector, theNbOfSteps, theMakeGroups,
2732 theExtrFlags, theSewTolerance );
2734 TIDSortedElemSet elemsNodes[2];
2735 arrayToSet( theIDsOfElements, getMeshDS(), elemsNodes[0] );
2737 ::SMESH_MeshEditor::TTElemOfElemListMap aHistory;
2738 ::SMESH_MeshEditor::PGroupIDs groupIds =
2739 getEditor().ExtrusionSweep( elemsNodes, params, aHistory );
2741 SMESH::ListOfGroups * aGroups = theMakeGroups ? getGroups( groupIds.get()) : 0;
2743 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2745 if ( !myIsPreviewMode ) {
2746 dumpGroupsList(aPythonDump, aGroups);
2747 aPythonDump << this << ".AdvancedExtrusion( "
2748 << theIDsOfElements << ", "
2749 << theStepVector << ", "
2750 << theNbOfSteps << ", "
2751 << theExtrFlags << ", "
2752 << theSewTolerance << ", "
2753 << theMakeGroups << " )";
2757 getPreviewMesh()->Remove( SMDSAbs_Volume );
2760 return aGroups ? aGroups : new SMESH::ListOfGroups;
2762 SMESH_CATCH( SMESH::throwCorbaException );
2766 //================================================================================
2768 * \brief Convert extrusion error to IDL enum
2770 //================================================================================
2774 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
2776 SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( ::SMESH_MeshEditor::Extrusion_Error e )
2780 RETCASE( EXTR_NO_ELEMENTS );
2781 RETCASE( EXTR_PATH_NOT_EDGE );
2782 RETCASE( EXTR_BAD_PATH_SHAPE );
2783 RETCASE( EXTR_BAD_STARTING_NODE );
2784 RETCASE( EXTR_BAD_ANGLES_NUMBER );
2785 RETCASE( EXTR_CANT_GET_TANGENT );
2787 return SMESH::SMESH_MeshEditor::EXTR_OK;
2791 //=======================================================================
2792 //function : extrusionAlongPath
2794 //=======================================================================
2795 SMESH::ListOfGroups*
2796 SMESH_MeshEditor_i::ExtrusionAlongPathObjects(const SMESH::ListOfIDSources & theNodes,
2797 const SMESH::ListOfIDSources & theEdges,
2798 const SMESH::ListOfIDSources & theFaces,
2799 SMESH::SMESH_IDSource_ptr thePathMesh,
2800 GEOM::GEOM_Object_ptr thePathShape,
2801 CORBA::Long theNodeStart,
2802 CORBA::Boolean theHasAngles,
2803 const SMESH::double_array & theAngles,
2804 CORBA::Boolean theLinearVariation,
2805 CORBA::Boolean theHasRefPoint,
2806 const SMESH::PointStruct & theRefPoint,
2808 SMESH::SMESH_MeshEditor::Extrusion_Error& theError)
2809 throw (SALOME::SALOME_Exception)
2814 SMESH::ListOfGroups_var aGroups = new SMESH::ListOfGroups;
2816 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2817 if ( thePathMesh->_is_nil() )
2818 return aGroups._retn();
2821 SMESH_subMesh* aSubMesh = 0;
2822 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2823 if ( thePathShape->_is_nil() )
2825 // thePathMesh should be either a sub-mesh or a mesh with 1D elements only
2826 if ( SMESH_subMesh_i* sm = SMESH::DownCast<SMESH_subMesh_i*>( thePathMesh ))
2828 SMESH::SMESH_Mesh_var mesh = thePathMesh->GetMesh();
2829 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
2830 if ( !aMeshImp ) return aGroups._retn();
2831 aSubMesh = aMeshImp->GetImpl().GetSubMeshContaining( sm->GetId() );
2832 if ( !aSubMesh ) return aGroups._retn();
2834 else if ( !aMeshImp ||
2835 aMeshImp->NbEdges() != aMeshImp->NbElements() )
2837 return aGroups._retn();
2842 if ( !aMeshImp ) return aGroups._retn();
2843 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2844 aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2845 if ( !aSubMesh /*|| !aSubMesh->GetSubMeshDS()*/ )
2846 return aGroups._retn();
2849 SMDS_MeshNode* nodeStart =
2850 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
2852 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2853 return aGroups._retn();
2856 TIDSortedElemSet elemsNodes[2];
2857 for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) {
2858 SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE );
2859 while ( nIt->more() ) elemsNodes[1].insert( nIt->next() );
2861 for ( int i = 0, nb = theEdges.length(); i < nb; ++i )
2862 idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge );
2863 for ( int i = 0, nb = theFaces.length(); i < nb; ++i )
2864 idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face );
2866 list<double> angles;
2867 for ( CORBA::ULong i = 0; i < theAngles.length(); i++ ) {
2868 angles.push_back( theAngles[i] );
2871 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
2873 int nbOldGroups = myMesh->NbGroup();
2875 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2876 if ( myIsPreviewMode )
2878 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2879 TPreviewMesh * tmpMesh = getPreviewMesh();
2880 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2881 tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid );
2882 workElements = & copyElements[0];
2883 theMakeGroups = false;
2886 ::SMESH_MeshEditor::Extrusion_Error error;
2888 error = getEditor().ExtrusionAlongTrack( workElements, &(aMeshImp->GetImpl()), nodeStart,
2889 theHasAngles, angles, theLinearVariation,
2890 theHasRefPoint, refPnt, theMakeGroups );
2892 error = getEditor().ExtrusionAlongTrack( workElements, aSubMesh, nodeStart,
2893 theHasAngles, angles, theLinearVariation,
2894 theHasRefPoint, refPnt, theMakeGroups );
2896 declareMeshModified( /*isReComputeSafe=*/true );
2897 theError = convExtrError( error );
2899 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2900 if ( theMakeGroups ) {
2901 list<int> groupIDs = myMesh->GetGroupIds();
2902 list<int>::iterator newBegin = groupIDs.begin();
2903 std::advance( newBegin, nbOldGroups ); // skip old groups
2904 groupIDs.erase( groupIDs.begin(), newBegin );
2905 aGroups = getGroups( & groupIDs );
2906 if ( ! &aGroups.in() ) aGroups = new SMESH::ListOfGroups;
2909 if ( !myIsPreviewMode ) {
2910 aPythonDump << "(" << aGroups << ", error) = "
2911 << this << ".ExtrusionAlongPathObjects( "
2915 << thePathMesh << ", "
2916 << thePathShape << ", "
2917 << theNodeStart << ", "
2918 << theHasAngles << ", "
2919 << theAngles << ", "
2920 << theLinearVariation << ", "
2921 << theHasRefPoint << ", "
2922 << "SMESH.PointStruct( "
2923 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2924 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2925 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ), "
2926 << theMakeGroups << " )";
2930 getPreviewMesh()->Remove( SMDSAbs_Volume );
2933 return aGroups._retn();
2935 SMESH_CATCH( SMESH::throwCorbaException );
2939 //================================================================================
2941 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
2942 * of given angles along path steps
2943 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
2944 * which proceeds the extrusion
2945 * \param PathShape is shape(edge); as the mesh can be complex, the edge
2946 * is used to define the sub-mesh for the path
2948 //================================================================================
2950 SMESH::double_array*
2951 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
2952 GEOM::GEOM_Object_ptr thePathShape,
2953 const SMESH::double_array & theAngles)
2955 SMESH::double_array_var aResult = new SMESH::double_array();
2956 int nbAngles = theAngles.length();
2957 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
2959 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2960 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2961 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2962 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
2963 return aResult._retn();
2964 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
2965 if ( nbSteps == nbAngles )
2967 aResult.inout() = theAngles;
2971 aResult->length( nbSteps );
2972 double rAn2St = double( nbAngles ) / double( nbSteps );
2973 double angPrev = 0, angle;
2974 for ( int iSt = 0; iSt < nbSteps; ++iSt )
2976 double angCur = rAn2St * ( iSt+1 );
2977 double angCurFloor = floor( angCur );
2978 double angPrevFloor = floor( angPrev );
2979 if ( angPrevFloor == angCurFloor )
2980 angle = rAn2St * theAngles[ int( angCurFloor ) ];
2983 int iP = int( angPrevFloor );
2984 double angPrevCeil = ceil(angPrev);
2985 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
2987 int iC = int( angCurFloor );
2988 if ( iC < nbAngles )
2989 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
2991 iP = int( angPrevCeil );
2993 angle += theAngles[ iC ];
2995 aResult[ iSt ] = angle;
3000 // Update Python script
3001 TPythonDump() << "rotAngles = " << theAngles;
3002 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
3003 << thePathMesh << ", "
3004 << thePathShape << ", "
3007 return aResult._retn();
3010 //=======================================================================
3013 //=======================================================================
3015 SMESH::ListOfGroups*
3016 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
3017 const SMESH::AxisStruct & theAxis,
3018 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3019 CORBA::Boolean theCopy,
3021 ::SMESH_Mesh* theTargetMesh)
3022 throw (SALOME::SALOME_Exception)
3027 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3028 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3030 if ( theTargetMesh )
3034 switch ( theMirrorType ) {
3035 case SMESH::SMESH_MeshEditor::POINT:
3036 aTrsf.SetMirror( P );
3038 case SMESH::SMESH_MeshEditor::AXIS:
3039 aTrsf.SetMirror( gp_Ax1( P, V ));
3042 aTrsf.SetMirror( gp_Ax2( P, V ));
3045 TIDSortedElemSet copyElements;
3046 TIDSortedElemSet* workElements = & theElements;
3048 if ( myIsPreviewMode )
3050 TPreviewMesh * tmpMesh = getPreviewMesh();
3051 tmpMesh->Copy( theElements, copyElements);
3052 if ( !theCopy && !theTargetMesh )
3054 TIDSortedElemSet elemsAround, elemsAroundCopy;
3055 getElementsAround( theElements, getMeshDS(), elemsAround );
3056 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3058 workElements = & copyElements;
3059 theMakeGroups = false;
3062 ::SMESH_MeshEditor::PGroupIDs groupIds =
3063 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3065 if ( theCopy && !myIsPreviewMode)
3067 if ( theTargetMesh )
3069 theTargetMesh->GetMeshDS()->Modified();
3073 declareMeshModified( /*isReComputeSafe=*/false );
3076 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3078 SMESH_CATCH( SMESH::throwCorbaException );
3082 //=======================================================================
3085 //=======================================================================
3087 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3088 const SMESH::AxisStruct & theAxis,
3089 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3090 CORBA::Boolean theCopy)
3091 throw (SALOME::SALOME_Exception)
3093 if ( !myIsPreviewMode ) {
3094 TPythonDump() << this << ".Mirror( "
3095 << theIDsOfElements << ", "
3097 << mirrorTypeName(theMirrorType) << ", "
3100 if ( theIDsOfElements.length() > 0 )
3102 TIDSortedElemSet elements;
3103 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3104 mirror(elements, theAxis, theMirrorType, theCopy, false);
3109 //=======================================================================
3110 //function : MirrorObject
3112 //=======================================================================
3114 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3115 const SMESH::AxisStruct & theAxis,
3116 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3117 CORBA::Boolean theCopy)
3118 throw (SALOME::SALOME_Exception)
3120 if ( !myIsPreviewMode ) {
3121 TPythonDump() << this << ".MirrorObject( "
3122 << theObject << ", "
3124 << mirrorTypeName(theMirrorType) << ", "
3127 TIDSortedElemSet elements;
3129 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3131 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3132 mirror(elements, theAxis, theMirrorType, theCopy, false);
3135 //=======================================================================
3136 //function : MirrorMakeGroups
3138 //=======================================================================
3140 SMESH::ListOfGroups*
3141 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3142 const SMESH::AxisStruct& theMirror,
3143 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3144 throw (SALOME::SALOME_Exception)
3146 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3148 SMESH::ListOfGroups * aGroups = 0;
3149 if ( theIDsOfElements.length() > 0 )
3151 TIDSortedElemSet elements;
3152 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3153 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3155 if (!myIsPreviewMode) {
3156 dumpGroupsList(aPythonDump, aGroups);
3157 aPythonDump << this << ".MirrorMakeGroups( "
3158 << theIDsOfElements << ", "
3159 << theMirror << ", "
3160 << mirrorTypeName(theMirrorType) << " )";
3165 //=======================================================================
3166 //function : MirrorObjectMakeGroups
3168 //=======================================================================
3170 SMESH::ListOfGroups*
3171 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3172 const SMESH::AxisStruct& theMirror,
3173 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3174 throw (SALOME::SALOME_Exception)
3176 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3178 SMESH::ListOfGroups * aGroups = 0;
3179 TIDSortedElemSet elements;
3180 if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3181 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3183 if (!myIsPreviewMode)
3185 dumpGroupsList(aPythonDump,aGroups);
3186 aPythonDump << this << ".MirrorObjectMakeGroups( "
3187 << theObject << ", "
3188 << theMirror << ", "
3189 << mirrorTypeName(theMirrorType) << " )";
3194 //=======================================================================
3195 //function : MirrorMakeMesh
3197 //=======================================================================
3199 SMESH::SMESH_Mesh_ptr
3200 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
3201 const SMESH::AxisStruct& theMirror,
3202 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3203 CORBA::Boolean theCopyGroups,
3204 const char* theMeshName)
3205 throw (SALOME::SALOME_Exception)
3207 SMESH_Mesh_i* mesh_i;
3208 SMESH::SMESH_Mesh_var mesh;
3209 { // open new scope to dump "MakeMesh" command
3210 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3212 TPythonDump pydump; // to prevent dump at mesh creation
3214 mesh = makeMesh( theMeshName );
3215 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3216 if (mesh_i && theIDsOfElements.length() > 0 )
3218 TIDSortedElemSet elements;
3219 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3220 mirror(elements, theMirror, theMirrorType,
3221 false, theCopyGroups, & mesh_i->GetImpl());
3222 mesh_i->CreateGroupServants();
3225 if (!myIsPreviewMode) {
3226 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
3227 << theIDsOfElements << ", "
3228 << theMirror << ", "
3229 << mirrorTypeName(theMirrorType) << ", "
3230 << theCopyGroups << ", '"
3231 << theMeshName << "' )";
3236 if (!myIsPreviewMode && mesh_i)
3237 mesh_i->GetGroups();
3239 return mesh._retn();
3242 //=======================================================================
3243 //function : MirrorObjectMakeMesh
3245 //=======================================================================
3247 SMESH::SMESH_Mesh_ptr
3248 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3249 const SMESH::AxisStruct& theMirror,
3250 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3251 CORBA::Boolean theCopyGroups,
3252 const char* theMeshName)
3253 throw (SALOME::SALOME_Exception)
3255 SMESH_Mesh_i* mesh_i;
3256 SMESH::SMESH_Mesh_var mesh;
3257 { // open new scope to dump "MakeMesh" command
3258 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3260 TPythonDump pydump; // to prevent dump at mesh creation
3262 mesh = makeMesh( theMeshName );
3263 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3264 TIDSortedElemSet elements;
3266 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3268 mirror(elements, theMirror, theMirrorType,
3269 false, theCopyGroups, & mesh_i->GetImpl());
3270 mesh_i->CreateGroupServants();
3272 if (!myIsPreviewMode) {
3273 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
3274 << theObject << ", "
3275 << theMirror << ", "
3276 << mirrorTypeName(theMirrorType) << ", "
3277 << theCopyGroups << ", '"
3278 << theMeshName << "' )";
3283 if (!myIsPreviewMode && mesh_i)
3284 mesh_i->GetGroups();
3286 return mesh._retn();
3289 //=======================================================================
3290 //function : translate
3292 //=======================================================================
3294 SMESH::ListOfGroups*
3295 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
3296 const SMESH::DirStruct & theVector,
3297 CORBA::Boolean theCopy,
3299 ::SMESH_Mesh* theTargetMesh)
3300 throw (SALOME::SALOME_Exception)
3305 if ( theTargetMesh )
3309 const SMESH::PointStruct * P = &theVector.PS;
3310 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
3312 TIDSortedElemSet copyElements;
3313 TIDSortedElemSet* workElements = &theElements;
3315 if ( myIsPreviewMode )
3317 TPreviewMesh * tmpMesh = getPreviewMesh();
3318 tmpMesh->Copy( theElements, copyElements);
3319 if ( !theCopy && !theTargetMesh )
3321 TIDSortedElemSet elemsAround, elemsAroundCopy;
3322 getElementsAround( theElements, getMeshDS(), elemsAround );
3323 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3325 workElements = & copyElements;
3326 theMakeGroups = false;
3329 ::SMESH_MeshEditor::PGroupIDs groupIds =
3330 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3332 if ( theCopy && !myIsPreviewMode )
3334 if ( theTargetMesh )
3336 theTargetMesh->GetMeshDS()->Modified();
3340 declareMeshModified( /*isReComputeSafe=*/false );
3344 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3346 SMESH_CATCH( SMESH::throwCorbaException );
3350 //=======================================================================
3351 //function : Translate
3353 //=======================================================================
3355 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
3356 const SMESH::DirStruct & theVector,
3357 CORBA::Boolean theCopy)
3358 throw (SALOME::SALOME_Exception)
3360 if (!myIsPreviewMode) {
3361 TPythonDump() << this << ".Translate( "
3362 << theIDsOfElements << ", "
3363 << theVector << ", "
3366 if (theIDsOfElements.length()) {
3367 TIDSortedElemSet elements;
3368 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3369 translate(elements, theVector, theCopy, false);
3373 //=======================================================================
3374 //function : TranslateObject
3376 //=======================================================================
3378 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
3379 const SMESH::DirStruct & theVector,
3380 CORBA::Boolean theCopy)
3381 throw (SALOME::SALOME_Exception)
3383 if (!myIsPreviewMode) {
3384 TPythonDump() << this << ".TranslateObject( "
3385 << theObject << ", "
3386 << theVector << ", "
3389 TIDSortedElemSet elements;
3391 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3393 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3394 translate(elements, theVector, theCopy, false);
3397 //=======================================================================
3398 //function : TranslateMakeGroups
3400 //=======================================================================
3402 SMESH::ListOfGroups*
3403 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
3404 const SMESH::DirStruct& theVector)
3405 throw (SALOME::SALOME_Exception)
3407 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3409 SMESH::ListOfGroups * aGroups = 0;
3410 if (theIDsOfElements.length()) {
3411 TIDSortedElemSet elements;
3412 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3413 aGroups = translate(elements,theVector,true,true);
3415 if (!myIsPreviewMode) {
3416 dumpGroupsList(aPythonDump, aGroups);
3417 aPythonDump << this << ".TranslateMakeGroups( "
3418 << theIDsOfElements << ", "
3419 << theVector << " )";
3424 //=======================================================================
3425 //function : TranslateObjectMakeGroups
3427 //=======================================================================
3429 SMESH::ListOfGroups*
3430 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3431 const SMESH::DirStruct& theVector)
3432 throw (SALOME::SALOME_Exception)
3434 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3436 SMESH::ListOfGroups * aGroups = 0;
3437 TIDSortedElemSet elements;
3438 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3439 aGroups = translate(elements, theVector, true, true);
3441 if (!myIsPreviewMode) {
3442 dumpGroupsList(aPythonDump, aGroups);
3443 aPythonDump << this << ".TranslateObjectMakeGroups( "
3444 << theObject << ", "
3445 << theVector << " )";
3450 //=======================================================================
3451 //function : TranslateMakeMesh
3453 //=======================================================================
3455 SMESH::SMESH_Mesh_ptr
3456 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
3457 const SMESH::DirStruct& theVector,
3458 CORBA::Boolean theCopyGroups,
3459 const char* theMeshName)
3460 throw (SALOME::SALOME_Exception)
3462 SMESH_Mesh_i* mesh_i;
3463 SMESH::SMESH_Mesh_var mesh;
3465 { // open new scope to dump "MakeMesh" command
3466 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3468 TPythonDump pydump; // to prevent dump at mesh creation
3470 mesh = makeMesh( theMeshName );
3471 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3473 if ( mesh_i && theIDsOfElements.length() )
3475 TIDSortedElemSet elements;
3476 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3477 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
3478 mesh_i->CreateGroupServants();
3481 if ( !myIsPreviewMode ) {
3482 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
3483 << theIDsOfElements << ", "
3484 << theVector << ", "
3485 << theCopyGroups << ", '"
3486 << theMeshName << "' )";
3491 if (!myIsPreviewMode && mesh_i)
3492 mesh_i->GetGroups();
3494 return mesh._retn();
3497 //=======================================================================
3498 //function : TranslateObjectMakeMesh
3500 //=======================================================================
3502 SMESH::SMESH_Mesh_ptr
3503 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3504 const SMESH::DirStruct& theVector,
3505 CORBA::Boolean theCopyGroups,
3506 const char* theMeshName)
3507 throw (SALOME::SALOME_Exception)
3510 SMESH_Mesh_i* mesh_i;
3511 SMESH::SMESH_Mesh_var mesh;
3512 { // open new scope to dump "MakeMesh" command
3513 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3515 TPythonDump pydump; // to prevent dump at mesh creation
3516 mesh = makeMesh( theMeshName );
3517 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3519 TIDSortedElemSet elements;
3521 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3523 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
3524 mesh_i->CreateGroupServants();
3526 if ( !myIsPreviewMode ) {
3527 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
3528 << theObject << ", "
3529 << theVector << ", "
3530 << theCopyGroups << ", '"
3531 << theMeshName << "' )";
3536 if (!myIsPreviewMode && mesh_i)
3537 mesh_i->GetGroups();
3539 return mesh._retn();
3541 SMESH_CATCH( SMESH::throwCorbaException );
3545 //=======================================================================
3548 //=======================================================================
3550 SMESH::ListOfGroups*
3551 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
3552 const SMESH::AxisStruct & theAxis,
3553 CORBA::Double theAngle,
3554 CORBA::Boolean theCopy,
3556 ::SMESH_Mesh* theTargetMesh)
3557 throw (SALOME::SALOME_Exception)
3562 if ( theTargetMesh )
3565 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3566 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3569 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
3571 TIDSortedElemSet copyElements;
3572 TIDSortedElemSet* workElements = &theElements;
3573 if ( myIsPreviewMode ) {
3574 TPreviewMesh * tmpMesh = getPreviewMesh();
3575 tmpMesh->Copy( theElements, copyElements );
3576 if ( !theCopy && !theTargetMesh )
3578 TIDSortedElemSet elemsAround, elemsAroundCopy;
3579 getElementsAround( theElements, getMeshDS(), elemsAround );
3580 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3582 workElements = ©Elements;
3583 theMakeGroups = false;
3586 ::SMESH_MeshEditor::PGroupIDs groupIds =
3587 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3589 if ( theCopy && !myIsPreviewMode)
3591 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
3592 else declareMeshModified( /*isReComputeSafe=*/false );
3595 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3597 SMESH_CATCH( SMESH::throwCorbaException );
3601 //=======================================================================
3604 //=======================================================================
3606 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
3607 const SMESH::AxisStruct & theAxis,
3608 CORBA::Double theAngle,
3609 CORBA::Boolean theCopy)
3610 throw (SALOME::SALOME_Exception)
3612 if (!myIsPreviewMode) {
3613 TPythonDump() << this << ".Rotate( "
3614 << theIDsOfElements << ", "
3616 << TVar( theAngle ) << ", "
3619 if (theIDsOfElements.length() > 0)
3621 TIDSortedElemSet elements;
3622 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3623 rotate(elements,theAxis,theAngle,theCopy,false);
3627 //=======================================================================
3628 //function : RotateObject
3630 //=======================================================================
3632 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
3633 const SMESH::AxisStruct & theAxis,
3634 CORBA::Double theAngle,
3635 CORBA::Boolean theCopy)
3636 throw (SALOME::SALOME_Exception)
3638 if ( !myIsPreviewMode ) {
3639 TPythonDump() << this << ".RotateObject( "
3640 << theObject << ", "
3642 << TVar( theAngle ) << ", "
3645 TIDSortedElemSet elements;
3646 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3647 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3648 rotate(elements,theAxis,theAngle,theCopy,false);
3651 //=======================================================================
3652 //function : RotateMakeGroups
3654 //=======================================================================
3656 SMESH::ListOfGroups*
3657 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
3658 const SMESH::AxisStruct& theAxis,
3659 CORBA::Double theAngle)
3660 throw (SALOME::SALOME_Exception)
3662 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3664 SMESH::ListOfGroups * aGroups = 0;
3665 if (theIDsOfElements.length() > 0)
3667 TIDSortedElemSet elements;
3668 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3669 aGroups = rotate(elements,theAxis,theAngle,true,true);
3671 if (!myIsPreviewMode) {
3672 dumpGroupsList(aPythonDump, aGroups);
3673 aPythonDump << this << ".RotateMakeGroups( "
3674 << theIDsOfElements << ", "
3676 << TVar( theAngle ) << " )";
3681 //=======================================================================
3682 //function : RotateObjectMakeGroups
3684 //=======================================================================
3686 SMESH::ListOfGroups*
3687 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3688 const SMESH::AxisStruct& theAxis,
3689 CORBA::Double theAngle)
3690 throw (SALOME::SALOME_Exception)
3692 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3694 SMESH::ListOfGroups * aGroups = 0;
3695 TIDSortedElemSet elements;
3696 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3697 aGroups = rotate(elements, theAxis, theAngle, true, true);
3699 if (!myIsPreviewMode) {
3700 dumpGroupsList(aPythonDump, aGroups);
3701 aPythonDump << this << ".RotateObjectMakeGroups( "
3702 << theObject << ", "
3704 << TVar( theAngle ) << " )";
3709 //=======================================================================
3710 //function : RotateMakeMesh
3712 //=======================================================================
3714 SMESH::SMESH_Mesh_ptr
3715 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
3716 const SMESH::AxisStruct& theAxis,
3717 CORBA::Double theAngleInRadians,
3718 CORBA::Boolean theCopyGroups,
3719 const char* theMeshName)
3720 throw (SALOME::SALOME_Exception)
3723 SMESH::SMESH_Mesh_var mesh;
3724 SMESH_Mesh_i* mesh_i;
3726 { // open new scope to dump "MakeMesh" command
3727 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3729 TPythonDump pydump; // to prevent dump at mesh creation
3731 mesh = makeMesh( theMeshName );
3732 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3734 if ( mesh_i && theIDsOfElements.length() > 0 )
3736 TIDSortedElemSet elements;
3737 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3738 rotate(elements, theAxis, theAngleInRadians,
3739 false, theCopyGroups, & mesh_i->GetImpl());
3740 mesh_i->CreateGroupServants();
3742 if ( !myIsPreviewMode ) {
3743 pydump << mesh << " = " << this << ".RotateMakeMesh( "
3744 << theIDsOfElements << ", "
3746 << TVar( theAngleInRadians ) << ", "
3747 << theCopyGroups << ", '"
3748 << theMeshName << "' )";
3753 if (!myIsPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
3754 mesh_i->GetGroups();
3756 return mesh._retn();
3758 SMESH_CATCH( SMESH::throwCorbaException );
3762 //=======================================================================
3763 //function : RotateObjectMakeMesh
3765 //=======================================================================
3767 SMESH::SMESH_Mesh_ptr
3768 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3769 const SMESH::AxisStruct& theAxis,
3770 CORBA::Double theAngleInRadians,
3771 CORBA::Boolean theCopyGroups,
3772 const char* theMeshName)
3773 throw (SALOME::SALOME_Exception)
3776 SMESH::SMESH_Mesh_var mesh;
3777 SMESH_Mesh_i* mesh_i;
3779 {// open new scope to dump "MakeMesh" command
3780 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3782 TPythonDump pydump; // to prevent dump at mesh creation
3783 mesh = makeMesh( theMeshName );
3784 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3786 TIDSortedElemSet elements;
3788 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3790 rotate(elements, theAxis, theAngleInRadians,
3791 false, theCopyGroups, & mesh_i->GetImpl());
3792 mesh_i->CreateGroupServants();
3794 if ( !myIsPreviewMode ) {
3795 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
3796 << theObject << ", "
3798 << TVar( theAngleInRadians ) << ", "
3799 << theCopyGroups << ", '"
3800 << theMeshName << "' )";
3805 if (!myIsPreviewMode && mesh_i)
3806 mesh_i->GetGroups();
3808 return mesh._retn();
3810 SMESH_CATCH( SMESH::throwCorbaException );
3814 //=======================================================================
3817 //=======================================================================
3819 SMESH::ListOfGroups*
3820 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
3821 const SMESH::PointStruct& thePoint,
3822 const SMESH::double_array& theScaleFact,
3823 CORBA::Boolean theCopy,
3825 ::SMESH_Mesh* theTargetMesh)
3826 throw (SALOME::SALOME_Exception)
3830 if ( theScaleFact.length() < 1 )
3831 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
3832 if ( theScaleFact.length() == 2 )
3833 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
3835 if ( theTargetMesh )
3838 TIDSortedElemSet elements;
3839 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3840 if ( !idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3845 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
3846 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
3850 #if OCC_VERSION_LARGE > 0x06070100
3851 // fight against orthogonalization
3852 // aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
3853 // 0, S[1], 0, thePoint.y * (1-S[1]),
3854 // 0, 0, S[2], thePoint.z * (1-S[2]) );
3855 aTrsf.SetScale( gp::Origin(), 1.0 ); // set form which is used to make group names
3856 gp_XYZ & loc = ( gp_XYZ& ) aTrsf.TranslationPart();
3857 gp_Mat & M = ( gp_Mat& ) aTrsf.HVectorialPart();
3858 loc.SetCoord( thePoint.x * (1-S[0]),
3859 thePoint.y * (1-S[1]),
3860 thePoint.z * (1-S[2]));
3861 M.SetDiagonal( S[0], S[1], S[2] );
3864 double tol = std::numeric_limits<double>::max();
3865 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
3866 0, S[1], 0, thePoint.y * (1-S[1]),
3867 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
3870 TIDSortedElemSet copyElements;
3871 TIDSortedElemSet* workElements = &elements;
3872 if ( myIsPreviewMode )
3874 TPreviewMesh * tmpMesh = getPreviewMesh();
3875 tmpMesh->Copy( elements, copyElements);
3876 if ( !theCopy && !theTargetMesh )
3878 TIDSortedElemSet elemsAround, elemsAroundCopy;
3879 getElementsAround( elements, getMeshDS(), elemsAround );
3880 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3882 workElements = & copyElements;
3883 theMakeGroups = false;
3886 ::SMESH_MeshEditor::PGroupIDs groupIds =
3887 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3889 if ( theCopy && !myIsPreviewMode )
3891 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
3892 else declareMeshModified( /*isReComputeSafe=*/false );
3894 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3896 SMESH_CATCH( SMESH::throwCorbaException );
3900 //=======================================================================
3903 //=======================================================================
3905 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
3906 const SMESH::PointStruct& thePoint,
3907 const SMESH::double_array& theScaleFact,
3908 CORBA::Boolean theCopy)
3909 throw (SALOME::SALOME_Exception)
3911 if ( !myIsPreviewMode ) {
3912 TPythonDump() << this << ".Scale( "
3913 << theObject << ", "
3915 << TVar( theScaleFact ) << ", "
3918 scale(theObject, thePoint, theScaleFact, theCopy, false);
3922 //=======================================================================
3923 //function : ScaleMakeGroups
3925 //=======================================================================
3927 SMESH::ListOfGroups*
3928 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3929 const SMESH::PointStruct& thePoint,
3930 const SMESH::double_array& theScaleFact)
3931 throw (SALOME::SALOME_Exception)
3933 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3935 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
3936 if (!myIsPreviewMode) {
3937 dumpGroupsList(aPythonDump, aGroups);
3938 aPythonDump << this << ".Scale("
3941 << TVar( theScaleFact ) << ",True,True)";
3947 //=======================================================================
3948 //function : ScaleMakeMesh
3950 //=======================================================================
3952 SMESH::SMESH_Mesh_ptr
3953 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3954 const SMESH::PointStruct& thePoint,
3955 const SMESH::double_array& theScaleFact,
3956 CORBA::Boolean theCopyGroups,
3957 const char* theMeshName)
3958 throw (SALOME::SALOME_Exception)
3960 SMESH_Mesh_i* mesh_i;
3961 SMESH::SMESH_Mesh_var mesh;
3962 { // open new scope to dump "MakeMesh" command
3963 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3965 TPythonDump pydump; // to prevent dump at mesh creation
3966 mesh = makeMesh( theMeshName );
3967 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3971 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
3972 mesh_i->CreateGroupServants();
3974 if ( !myIsPreviewMode )
3975 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
3976 << theObject << ", "
3978 << TVar( theScaleFact ) << ", "
3979 << theCopyGroups << ", '"
3980 << theMeshName << "' )";
3984 if (!myIsPreviewMode && mesh_i)
3985 mesh_i->GetGroups();
3987 return mesh._retn();
3991 //=======================================================================
3992 //function : findCoincidentNodes
3994 //=======================================================================
3996 void SMESH_MeshEditor_i::
3997 findCoincidentNodes (TIDSortedNodeSet & Nodes,
3998 CORBA::Double Tolerance,
3999 SMESH::array_of_long_array_out GroupsOfNodes,
4000 CORBA::Boolean SeparateCornersAndMedium)
4002 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4003 getEditor().FindCoincidentNodes( Nodes, Tolerance, aListOfListOfNodes, SeparateCornersAndMedium );
4005 GroupsOfNodes = new SMESH::array_of_long_array;
4006 GroupsOfNodes->length( aListOfListOfNodes.size() );
4007 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4008 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4010 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4011 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4012 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4013 aGroup.length( aListOfNodes.size() );
4014 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4015 aGroup[ j ] = (*lIt)->GetID();
4019 //=======================================================================
4020 //function : FindCoincidentNodes
4022 //=======================================================================
4024 void SMESH_MeshEditor_i::
4025 FindCoincidentNodes (CORBA::Double Tolerance,
4026 SMESH::array_of_long_array_out GroupsOfNodes,
4027 CORBA::Boolean SeparateCornersAndMedium)
4028 throw (SALOME::SALOME_Exception)
4033 TIDSortedNodeSet nodes; // no input nodes
4034 findCoincidentNodes( nodes, Tolerance, GroupsOfNodes, SeparateCornersAndMedium );
4036 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
4037 << Tolerance << ", "
4038 << SeparateCornersAndMedium << " )";
4040 SMESH_CATCH( SMESH::throwCorbaException );
4043 //=======================================================================
4044 //function : FindCoincidentNodesOnPart
4046 //=======================================================================
4048 void SMESH_MeshEditor_i::
4049 FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
4050 CORBA::Double Tolerance,
4051 SMESH::array_of_long_array_out GroupsOfNodes,
4052 CORBA::Boolean SeparateCornersAndMedium)
4053 throw (SALOME::SALOME_Exception)
4058 TIDSortedNodeSet nodes;
4059 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4061 findCoincidentNodes( nodes, Tolerance, GroupsOfNodes, SeparateCornersAndMedium );
4063 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
4065 << Tolerance << ", "
4066 << SeparateCornersAndMedium << " )";
4068 SMESH_CATCH( SMESH::throwCorbaException );
4071 //================================================================================
4073 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
4074 * ExceptSubMeshOrGroups
4076 //================================================================================
4078 void SMESH_MeshEditor_i::
4079 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
4080 CORBA::Double theTolerance,
4081 SMESH::array_of_long_array_out theGroupsOfNodes,
4082 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups,
4083 CORBA::Boolean theSeparateCornersAndMedium)
4084 throw (SALOME::SALOME_Exception)
4089 TIDSortedNodeSet nodes;
4090 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4092 for ( CORBA::ULong i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
4094 SMDS_ElemIteratorPtr nodeIt = myMesh_i->GetElements( theExceptSubMeshOrGroups[i],
4096 while ( nodeIt->more() )
4097 nodes.erase( cast2Node( nodeIt->next() ));
4099 findCoincidentNodes( nodes, theTolerance, theGroupsOfNodes, theSeparateCornersAndMedium );
4101 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
4103 << theTolerance << ", "
4104 << theExceptSubMeshOrGroups << ", "
4105 << theSeparateCornersAndMedium << " )";
4107 SMESH_CATCH( SMESH::throwCorbaException );
4110 //=======================================================================
4111 //function : MergeNodes
4113 //=======================================================================
4115 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes,
4116 const SMESH::ListOfIDSources& NodesToKeep)
4117 throw (SALOME::SALOME_Exception)
4122 SMESHDS_Mesh* aMesh = getMeshDS();
4124 TPythonDump aTPythonDump;
4125 aTPythonDump << this << ".MergeNodes([";
4127 TIDSortedNodeSet setOfNodesToKeep;
4128 for ( CORBA::ULong i = 0; i < NodesToKeep.length(); ++i )
4130 prepareIdSource( NodesToKeep[i] );
4131 SMDS_ElemIteratorPtr nodeIt = myMesh_i->GetElements( NodesToKeep[i], SMESH::NODE );
4132 while ( nodeIt->more() )
4133 setOfNodesToKeep.insert( setOfNodesToKeep.end(), cast2Node( nodeIt->next() ));
4136 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4137 for ( CORBA::ULong i = 0; i < GroupsOfNodes.length(); i++ )
4139 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
4140 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
4141 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
4142 for ( CORBA::ULong j = 0; j < aNodeGroup.length(); j++ )
4144 CORBA::Long index = aNodeGroup[ j ];
4145 if ( const SMDS_MeshNode * node = aMesh->FindNode( index ))
4147 if ( setOfNodesToKeep.count( node ))
4148 aListOfNodes.push_front( node );
4150 aListOfNodes.push_back( node );
4153 if ( aListOfNodes.size() < 2 )
4154 aListOfListOfNodes.pop_back();
4156 if ( i > 0 ) aTPythonDump << ", ";
4157 aTPythonDump << aNodeGroup;
4160 getEditor().MergeNodes( aListOfListOfNodes );
4162 aTPythonDump << "], " << NodesToKeep << ")";
4164 declareMeshModified( /*isReComputeSafe=*/false );
4166 SMESH_CATCH( SMESH::throwCorbaException );
4169 //=======================================================================
4170 //function : FindEqualElements
4172 //=======================================================================
4174 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
4175 SMESH::array_of_long_array_out GroupsOfElementsID)
4176 throw (SALOME::SALOME_Exception)
4181 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
4182 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
4184 TIDSortedElemSet elems;
4185 idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true);
4187 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4188 getEditor().FindEqualElements( elems, aListOfListOfElementsID );
4190 GroupsOfElementsID = new SMESH::array_of_long_array;
4191 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
4193 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt =
4194 aListOfListOfElementsID.begin();
4195 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j)
4197 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
4198 list<int>& listOfIDs = *arraysIt;
4199 aGroup.length( listOfIDs.size() );
4200 list<int>::iterator idIt = listOfIDs.begin();
4201 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k )
4202 aGroup[ k ] = *idIt;
4205 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
4209 SMESH_CATCH( SMESH::throwCorbaException );
4212 //=======================================================================
4213 //function : MergeElements
4215 //=======================================================================
4217 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
4218 throw (SALOME::SALOME_Exception)
4223 TPythonDump aTPythonDump;
4224 aTPythonDump << this << ".MergeElements( [";
4226 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4228 for ( CORBA::ULong i = 0; i < GroupsOfElementsID.length(); i++ ) {
4229 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
4230 aListOfListOfElementsID.push_back( list< int >() );
4231 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
4232 for ( CORBA::ULong j = 0; j < anElemsIDGroup.length(); j++ ) {
4233 CORBA::Long id = anElemsIDGroup[ j ];
4234 aListOfElemsID.push_back( id );
4236 if ( aListOfElemsID.size() < 2 )
4237 aListOfListOfElementsID.pop_back();
4238 if ( i > 0 ) aTPythonDump << ", ";
4239 aTPythonDump << anElemsIDGroup;
4242 getEditor().MergeElements(aListOfListOfElementsID);
4244 declareMeshModified( /*isReComputeSafe=*/true );
4246 aTPythonDump << "] )";
4248 SMESH_CATCH( SMESH::throwCorbaException );
4251 //=======================================================================
4252 //function : MergeEqualElements
4254 //=======================================================================
4256 void SMESH_MeshEditor_i::MergeEqualElements()
4257 throw (SALOME::SALOME_Exception)
4262 getEditor().MergeEqualElements();
4264 declareMeshModified( /*isReComputeSafe=*/true );
4266 TPythonDump() << this << ".MergeEqualElements()";
4268 SMESH_CATCH( SMESH::throwCorbaException );
4271 //=============================================================================
4273 * Move the node to a given point
4275 //=============================================================================
4277 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
4281 throw (SALOME::SALOME_Exception)
4284 initData(/*deleteSearchers=*/false);
4286 const SMDS_MeshNode * node = getMeshDS()->FindNode( NodeID );
4290 if ( theNodeSearcher )
4291 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4293 if ( myIsPreviewMode ) // make preview data
4295 // in a preview mesh, make edges linked to a node
4296 TPreviewMesh& tmpMesh = *getPreviewMesh();
4297 TIDSortedElemSet linkedNodes;
4298 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4299 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4300 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
4301 for ( ; nIt != linkedNodes.end(); ++nIt )
4303 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
4304 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
4308 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
4309 // fill preview data
4311 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4312 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4314 getMeshDS()->MoveNode(node, x, y, z);
4316 if ( !myIsPreviewMode )
4318 // Update Python script
4319 TPythonDump() << "isDone = " << this << ".MoveNode( "
4320 << NodeID << ", " << TVar(x) << ", " << TVar(y) << ", " << TVar(z) << " )";
4321 declareMeshModified( /*isReComputeSafe=*/false );
4324 SMESH_CATCH( SMESH::throwCorbaException );
4329 //================================================================================
4331 * \brief Return ID of node closest to a given point
4333 //================================================================================
4335 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
4338 throw (SALOME::SALOME_Exception)
4341 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4343 if ( !theNodeSearcher ) {
4344 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
4347 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
4348 return node->GetID();
4350 SMESH_CATCH( SMESH::throwCorbaException );
4354 //================================================================================
4356 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
4357 * move the node closest to the point to point's location and return ID of the node
4359 //================================================================================
4361 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
4364 CORBA::Long theNodeID)
4365 throw (SALOME::SALOME_Exception)
4368 // We keep theNodeSearcher until any mesh modification:
4369 // 1) initData() deletes theNodeSearcher at any edition,
4370 // 2) TSearchersDeleter - at any mesh compute event and mesh change
4372 initData(/*deleteSearchers=*/false);
4374 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4376 int nodeID = theNodeID;
4377 const SMDS_MeshNode* node = getMeshDS()->FindNode( nodeID );
4378 if ( !node ) // preview moving node
4380 if ( !theNodeSearcher ) {
4381 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
4384 node = theNodeSearcher->FindClosestTo( p );
4387 nodeID = node->GetID();
4388 if ( myIsPreviewMode ) // make preview data
4390 // in a preview mesh, make edges linked to a node
4391 TPreviewMesh tmpMesh = *getPreviewMesh();
4392 TIDSortedElemSet linkedNodes;
4393 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4394 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4395 for ( ; nIt != linkedNodes.end(); ++nIt )
4397 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
4398 tmpMesh.Copy( &edge );
4401 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
4403 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
4404 // fill preview data
4406 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4408 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4412 getMeshDS()->MoveNode(node, x, y, z);
4416 if ( !myIsPreviewMode )
4418 TPythonDump() << "nodeID = " << this
4419 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
4420 << ", " << nodeID << " )";
4422 declareMeshModified( /*isReComputeSafe=*/false );
4427 SMESH_CATCH( SMESH::throwCorbaException );
4431 //=======================================================================
4433 * Return elements of given type where the given point is IN or ON.
4435 * 'ALL' type means elements of any type excluding nodes
4437 //=======================================================================
4439 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
4442 SMESH::ElementType type)
4443 throw (SALOME::SALOME_Exception)
4446 SMESH::long_array_var res = new SMESH::long_array;
4447 vector< const SMDS_MeshElement* > foundElems;
4449 theSearchersDeleter.Set( myMesh );
4450 if ( !theElementSearcher ) {
4451 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
4453 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4454 SMDSAbs_ElementType( type ),
4456 res->length( foundElems.size() );
4457 for ( size_t i = 0; i < foundElems.size(); ++i )
4458 res[i] = foundElems[i]->GetID();
4462 SMESH_CATCH( SMESH::throwCorbaException );
4466 //=======================================================================
4467 //function : FindAmongElementsByPoint
4468 //purpose : Searching among the given elements, return elements of given type
4469 // where the given point is IN or ON.
4470 // 'ALL' type means elements of any type excluding nodes
4471 //=======================================================================
4474 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
4478 SMESH::ElementType type)
4479 throw (SALOME::SALOME_Exception)
4482 SMESH::long_array_var res = new SMESH::long_array;
4484 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
4485 if ( types->length() == 1 && // a part contains only nodes or 0D elements
4486 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) &&
4487 type != types[0] ) // but search of elements of dim > 0
4490 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
4491 return FindElementsByPoint( x,y,z, type );
4493 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
4495 theSearchersDeleter.Set( myMesh, getPartIOR( elementIDs, type ));
4496 if ( !theElementSearcher )
4498 // create a searcher from elementIDs
4499 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
4500 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
4502 if ( !idSourceToSet( elementIDs, meshDS, elements,
4503 SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
4506 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
4507 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
4509 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt );
4512 vector< const SMDS_MeshElement* > foundElems;
4514 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4515 SMDSAbs_ElementType( type ),
4517 res->length( foundElems.size() );
4518 for ( size_t i = 0; i < foundElems.size(); ++i )
4519 res[i] = foundElems[i]->GetID();
4523 SMESH_CATCH( SMESH::throwCorbaException );
4527 //=======================================================================
4528 //function : GetPointState
4529 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
4530 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
4531 //=======================================================================
4533 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
4536 throw (SALOME::SALOME_Exception)
4539 theSearchersDeleter.Set( myMesh );
4540 if ( !theElementSearcher ) {
4541 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
4543 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
4545 SMESH_CATCH( SMESH::throwCorbaException );
4549 //=======================================================================
4550 //function : convError
4552 //=======================================================================
4554 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
4556 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
4560 RETCASE( SEW_BORDER1_NOT_FOUND );
4561 RETCASE( SEW_BORDER2_NOT_FOUND );
4562 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
4563 RETCASE( SEW_BAD_SIDE_NODES );
4564 RETCASE( SEW_VOLUMES_TO_SPLIT );
4565 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
4566 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
4567 RETCASE( SEW_BAD_SIDE1_NODES );
4568 RETCASE( SEW_BAD_SIDE2_NODES );
4569 RETCASE( SEW_INTERNAL_ERROR );
4571 return SMESH::SMESH_MeshEditor::SEW_OK;
4574 //=======================================================================
4576 * Returns groups of FreeBorder's coincident within the given tolerance.
4577 * If the tolerance <= 0.0 then one tenth of an average size of elements adjacent
4578 * to free borders being compared is used.
4580 //=======================================================================
4582 SMESH::CoincidentFreeBorders*
4583 SMESH_MeshEditor_i::FindCoincidentFreeBorders(CORBA::Double tolerance)
4585 SMESH::CoincidentFreeBorders_var aCFB = new SMESH::CoincidentFreeBorders;
4589 SMESH_MeshAlgos::CoincidentFreeBorders cfb;
4590 SMESH_MeshAlgos::FindCoincidentFreeBorders( *getMeshDS(), tolerance, cfb );
4592 // copy free borders
4593 aCFB->borders.length( cfb._borders.size() );
4594 for ( size_t i = 0; i < cfb._borders.size(); ++i )
4596 SMESH_MeshAlgos::TFreeBorder& nodes = cfb._borders[i];
4597 SMESH::FreeBorder& aBRD = aCFB->borders[i];
4598 aBRD.nodeIDs.length( nodes.size() );
4599 for ( size_t iN = 0; iN < nodes.size(); ++iN )
4600 aBRD.nodeIDs[ iN ] = nodes[ iN ]->GetID();
4603 // copy coincident parts
4604 aCFB->coincidentGroups.length( cfb._coincidentGroups.size() );
4605 for ( size_t i = 0; i < cfb._coincidentGroups.size(); ++i )
4607 SMESH_MeshAlgos::TCoincidentGroup& grp = cfb._coincidentGroups[i];
4608 SMESH::FreeBordersGroup& aGRP = aCFB->coincidentGroups[i];
4609 aGRP.length( grp.size() );
4610 for ( size_t iP = 0; iP < grp.size(); ++iP )
4612 SMESH_MeshAlgos::TFreeBorderPart& part = grp[ iP ];
4613 SMESH::FreeBorderPart& aPART = aGRP[ iP ];
4614 aPART.border = part._border;
4615 aPART.node1 = part._node1;
4616 aPART.node2 = part._node2;
4617 aPART.nodeLast = part._nodeLast;
4620 SMESH_CATCH( SMESH::doNothing );
4622 TPythonDump() << "CoincidentFreeBorders = "
4623 << this << ".FindCoincidentFreeBorders( " << tolerance << " )";
4625 return aCFB._retn();
4628 //=======================================================================
4630 * Sew FreeBorder's of each group
4632 //=======================================================================
4634 CORBA::Short SMESH_MeshEditor_i::
4635 SewCoincidentFreeBorders(const SMESH::CoincidentFreeBorders& freeBorders,
4636 CORBA::Boolean createPolygons,
4637 CORBA::Boolean createPolyhedra)
4638 throw (SALOME::SALOME_Exception)
4640 CORBA::Short nbSewed = 0;
4642 SMESH_MeshAlgos::TFreeBorderVec groups;
4643 SMESH_MeshAlgos::TFreeBorder borderNodes; // triples of nodes for every FreeBorderPart
4645 // check the input and collect nodes
4646 for ( CORBA::ULong i = 0; i < freeBorders.coincidentGroups.length(); ++i )
4648 borderNodes.clear();
4649 const SMESH::FreeBordersGroup& aGRP = freeBorders.coincidentGroups[ i ];
4650 for ( CORBA::ULong iP = 0; iP < aGRP.length(); ++iP )
4652 const SMESH::FreeBorderPart& aPART = aGRP[ iP ];
4653 if ( aPART.border < 0 || aPART.border >= (int) freeBorders.borders.length() )
4654 THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::border index", SALOME::BAD_PARAM);
4656 const SMESH::FreeBorder& aBRD = freeBorders.borders[ aPART.border ];
4658 if ( aPART.node1 < 0 || aPART.node1 > (int) aBRD.nodeIDs.length() )
4659 THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::node1", SALOME::BAD_PARAM);
4660 if ( aPART.node2 < 0 || aPART.node2 > (int) aBRD.nodeIDs.length() )
4661 THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::node2", SALOME::BAD_PARAM);
4662 if ( aPART.nodeLast < 0 || aPART.nodeLast > (int) aBRD.nodeIDs.length() )
4663 THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::nodeLast", SALOME::BAD_PARAM);
4665 // do not keep these nodes for further sewing as nodes can be removed by the sewing
4666 const SMDS_MeshNode* n1 = getMeshDS()->FindNode( aBRD.nodeIDs[ aPART.node1 ]);
4667 const SMDS_MeshNode* n2 = getMeshDS()->FindNode( aBRD.nodeIDs[ aPART.node2 ]);
4668 const SMDS_MeshNode* n3 = getMeshDS()->FindNode( aBRD.nodeIDs[ aPART.nodeLast ]);
4670 THROW_SALOME_CORBA_EXCEPTION("Nonexistent FreeBorderPart::node1", SALOME::BAD_PARAM);
4672 THROW_SALOME_CORBA_EXCEPTION("Nonexistent FreeBorderPart::node2", SALOME::BAD_PARAM);
4674 THROW_SALOME_CORBA_EXCEPTION("Nonexistent FreeBorderPart::nodeLast", SALOME::BAD_PARAM);
4676 borderNodes.push_back( n1 );
4677 borderNodes.push_back( n2 );
4678 borderNodes.push_back( n3 );
4680 groups.push_back( borderNodes );
4683 // SewFreeBorder() can merge nodes, thus nodes stored in 'groups' can become dead;
4684 // to get nodes that replace other nodes during merge we create 0D elements
4685 // on each node and MergeNodes() will replace underlying nodes of 0D elements by
4688 vector< const SMDS_MeshElement* > tmp0Delems;
4689 for ( size_t i = 0; i < groups.size(); ++i )
4691 SMESH_MeshAlgos::TFreeBorder& nodes = groups[i];
4692 for ( size_t iN = 0; iN < nodes.size(); ++iN )
4694 SMDS_ElemIteratorPtr it0D = nodes[iN]->GetInverseElementIterator(SMDSAbs_0DElement);
4696 tmp0Delems.push_back( it0D->next() );
4698 tmp0Delems.push_back( getMeshDS()->Add0DElement( nodes[iN] ));
4702 // cout << endl << "INIT" << endl;
4703 // for ( size_t i = 0; i < tmp0Delems.size(); ++i )
4705 // cout << i << " ";
4706 // if ( i % 3 == 0 ) cout << "^ ";
4707 // tmp0Delems[i]->GetNode(0)->Print( cout );
4712 ::SMESH_MeshEditor::Sew_Error res, ok = ::SMESH_MeshEditor::SEW_OK;
4714 for ( size_t i = 0; i < groups.size(); ++i )
4716 bool isBordToBord = true;
4717 bool groupSewed = false;
4718 SMESH_MeshAlgos::TFreeBorder& nodes = groups[i];
4719 for ( size_t iN = 3; iN+2 < nodes.size(); iN += 3 )
4721 const SMDS_MeshNode* n0 = tmp0Delems[ i0D + 0 ]->GetNode( 0 );
4722 const SMDS_MeshNode* n1 = tmp0Delems[ i0D + 1 ]->GetNode( 0 );
4723 const SMDS_MeshNode* n2 = tmp0Delems[ i0D + 2 ]->GetNode( 0 );
4725 const SMDS_MeshNode* n3 = tmp0Delems[ i0D + 0 + iN ]->GetNode( 0 );
4726 const SMDS_MeshNode* n4 = tmp0Delems[ i0D + 1 + iN ]->GetNode( 0 );
4727 const SMDS_MeshNode* n5 = tmp0Delems[ i0D + 2 + iN ]->GetNode( 0 );
4729 if ( !n0 || !n1 || !n2 || !n3 || !n4 || !n5 )
4732 // TIDSortedElemSet emptySet, avoidSet;
4733 // if ( !SMESH_MeshAlgos::FindFaceInSet( n0, n1, emptySet, avoidSet))
4735 // cout << "WRONG 2nd 1" << endl;
4736 // n0->Print( cout );
4737 // n1->Print( cout );
4739 // if ( !SMESH_MeshAlgos::FindFaceInSet( n3, n4, emptySet, avoidSet))
4741 // cout << "WRONG 2nd 2" << endl;
4742 // n3->Print( cout );
4743 // n4->Print( cout );
4746 if ( !isBordToBord )
4748 n1 = n2; // at border-to-side sewing only last side node (n1) is needed
4749 n2 = 0; // and n2 is not used
4751 // 1st border moves to 2nd
4752 res = getEditor().SewFreeBorder( n3, n4, n5 ,// 1st
4754 /*2ndIsFreeBorder=*/ isBordToBord,
4755 createPolygons, createPolyhedra);
4756 groupSewed = ( res == ok );
4758 isBordToBord = false;
4759 // cout << endl << "SEWED GROUP " << i << " PART " << iN / 3 << endl;
4760 // for ( size_t t = 0; t < tmp0Delems.size(); ++t )
4762 // cout << t << " ";
4763 // if ( t % 3 == 0 ) cout << "^ ";
4764 // tmp0Delems[t]->GetNode(0)->Print( cout );
4767 i0D += nodes.size();
4768 nbSewed += groupSewed;
4771 TPythonDump() << "nbSewed = " << this << ".SewCoincidentFreeBorders( "
4772 << freeBorders << ", "
4773 << createPolygons << ", "
4774 << createPolyhedra << " )";
4776 SMESH_CATCH( SMESH::doNothing );
4778 declareMeshModified( /*isReComputeSafe=*/false );
4780 // remove tmp 0D elements
4782 set< const SMDS_MeshElement* > removed0D;
4783 for ( size_t i = 0; i < tmp0Delems.size(); ++i )
4785 if ( removed0D.insert( tmp0Delems[i] ).second )
4786 getMeshDS()->RemoveFreeElement( tmp0Delems[i], /*sm=*/0, /*fromGroups=*/false );
4788 SMESH_CATCH( SMESH::throwCorbaException );
4793 //=======================================================================
4794 //function : SewFreeBorders
4796 //=======================================================================
4798 SMESH::SMESH_MeshEditor::Sew_Error
4799 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
4800 CORBA::Long SecondNodeID1,
4801 CORBA::Long LastNodeID1,
4802 CORBA::Long FirstNodeID2,
4803 CORBA::Long SecondNodeID2,
4804 CORBA::Long LastNodeID2,
4805 CORBA::Boolean CreatePolygons,
4806 CORBA::Boolean CreatePolyedrs)
4807 throw (SALOME::SALOME_Exception)
4812 SMESHDS_Mesh* aMesh = getMeshDS();
4814 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4815 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4816 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4817 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4818 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4819 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
4821 if (!aBorderFirstNode ||
4822 !aBorderSecondNode||
4824 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4825 if (!aSide2FirstNode ||
4826 !aSide2SecondNode ||
4828 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4830 TPythonDump() << "error = " << this << ".SewFreeBorders( "
4831 << FirstNodeID1 << ", "
4832 << SecondNodeID1 << ", "
4833 << LastNodeID1 << ", "
4834 << FirstNodeID2 << ", "
4835 << SecondNodeID2 << ", "
4836 << LastNodeID2 << ", "
4837 << CreatePolygons<< ", "
4838 << CreatePolyedrs<< " )";
4840 SMESH::SMESH_MeshEditor::Sew_Error error =
4841 convError( getEditor().SewFreeBorder (aBorderFirstNode,
4852 declareMeshModified( /*isReComputeSafe=*/false );
4855 SMESH_CATCH( SMESH::throwCorbaException );
4856 return SMESH::SMESH_MeshEditor::Sew_Error(0);
4860 //=======================================================================
4861 //function : SewConformFreeBorders
4863 //=======================================================================
4865 SMESH::SMESH_MeshEditor::Sew_Error
4866 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
4867 CORBA::Long SecondNodeID1,
4868 CORBA::Long LastNodeID1,
4869 CORBA::Long FirstNodeID2,
4870 CORBA::Long SecondNodeID2)
4871 throw (SALOME::SALOME_Exception)
4876 SMESHDS_Mesh* aMesh = getMeshDS();
4878 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4879 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4880 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4881 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4882 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4883 const SMDS_MeshNode* aSide2ThirdNode = 0;
4885 if (!aBorderFirstNode ||
4886 !aBorderSecondNode||
4888 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4889 if (!aSide2FirstNode ||
4891 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4893 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
4894 << FirstNodeID1 << ", "
4895 << SecondNodeID1 << ", "
4896 << LastNodeID1 << ", "
4897 << FirstNodeID2 << ", "
4898 << SecondNodeID2 << " )";
4900 SMESH::SMESH_MeshEditor::Sew_Error error =
4901 convError( getEditor().SewFreeBorder (aBorderFirstNode,
4910 declareMeshModified( /*isReComputeSafe=*/false );
4913 SMESH_CATCH( SMESH::throwCorbaException );
4914 return SMESH::SMESH_MeshEditor::Sew_Error(0);
4918 //=======================================================================
4919 //function : SewBorderToSide
4921 //=======================================================================
4923 SMESH::SMESH_MeshEditor::Sew_Error
4924 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
4925 CORBA::Long SecondNodeIDOnFreeBorder,
4926 CORBA::Long LastNodeIDOnFreeBorder,
4927 CORBA::Long FirstNodeIDOnSide,
4928 CORBA::Long LastNodeIDOnSide,
4929 CORBA::Boolean CreatePolygons,
4930 CORBA::Boolean CreatePolyedrs)
4931 throw (SALOME::SALOME_Exception)
4936 SMESHDS_Mesh* aMesh = getMeshDS();
4938 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
4939 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
4940 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
4941 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
4942 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
4943 const SMDS_MeshNode* aSide2ThirdNode = 0;
4945 if (!aBorderFirstNode ||
4946 !aBorderSecondNode||
4948 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4949 if (!aSide2FirstNode ||
4951 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
4953 TPythonDump() << "error = " << this << ".SewBorderToSide( "
4954 << FirstNodeIDOnFreeBorder << ", "
4955 << SecondNodeIDOnFreeBorder << ", "
4956 << LastNodeIDOnFreeBorder << ", "
4957 << FirstNodeIDOnSide << ", "
4958 << LastNodeIDOnSide << ", "
4959 << CreatePolygons << ", "
4960 << CreatePolyedrs << ") ";
4962 SMESH::SMESH_MeshEditor::Sew_Error error =
4963 convError( getEditor().SewFreeBorder (aBorderFirstNode,
4973 declareMeshModified( /*isReComputeSafe=*/false );
4976 SMESH_CATCH( SMESH::throwCorbaException );
4977 return SMESH::SMESH_MeshEditor::Sew_Error(0);
4981 //=======================================================================
4982 //function : SewSideElements
4984 //=======================================================================
4986 SMESH::SMESH_MeshEditor::Sew_Error
4987 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
4988 const SMESH::long_array& IDsOfSide2Elements,
4989 CORBA::Long NodeID1OfSide1ToMerge,
4990 CORBA::Long NodeID1OfSide2ToMerge,
4991 CORBA::Long NodeID2OfSide1ToMerge,
4992 CORBA::Long NodeID2OfSide2ToMerge)
4993 throw (SALOME::SALOME_Exception)
4998 SMESHDS_Mesh* aMesh = getMeshDS();
5000 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
5001 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
5002 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
5003 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
5005 if (!aFirstNode1ToMerge ||
5006 !aFirstNode2ToMerge )
5007 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
5008 if (!aSecondNode1ToMerge||
5009 !aSecondNode2ToMerge)
5010 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
5012 TIDSortedElemSet aSide1Elems, aSide2Elems;
5013 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
5014 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
5016 TPythonDump() << "error = " << this << ".SewSideElements( "
5017 << IDsOfSide1Elements << ", "
5018 << IDsOfSide2Elements << ", "
5019 << NodeID1OfSide1ToMerge << ", "
5020 << NodeID1OfSide2ToMerge << ", "
5021 << NodeID2OfSide1ToMerge << ", "
5022 << NodeID2OfSide2ToMerge << ")";
5024 SMESH::SMESH_MeshEditor::Sew_Error error =
5025 convError( getEditor().SewSideElements (aSide1Elems, aSide2Elems,
5028 aSecondNode1ToMerge,
5029 aSecondNode2ToMerge));
5031 declareMeshModified( /*isReComputeSafe=*/false );
5034 SMESH_CATCH( SMESH::throwCorbaException );
5035 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5038 //================================================================================
5040 * \brief Set new nodes for given element
5041 * \param ide - element id
5042 * \param newIDs - new node ids
5043 * \retval CORBA::Boolean - true if result is OK
5045 //================================================================================
5047 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
5048 const SMESH::long_array& newIDs)
5049 throw (SALOME::SALOME_Exception)
5054 const SMDS_MeshElement* elem = getMeshDS()->FindElement(ide);
5055 if(!elem) return false;
5057 int nbn = newIDs.length();
5059 vector<const SMDS_MeshNode*> aNodes(nbn);
5062 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(newIDs[i]);
5065 aNodes[nbn1] = aNode;
5068 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
5069 << ide << ", " << newIDs << " )";
5071 MESSAGE("ChangeElementNodes");
5072 bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
5074 declareMeshModified( /*isReComputeSafe=*/ !res );
5078 SMESH_CATCH( SMESH::throwCorbaException );
5082 //=======================================================================
5084 * \brief Makes a part of the mesh quadratic or bi-quadratic
5086 //=======================================================================
5088 void SMESH_MeshEditor_i::convertToQuadratic(CORBA::Boolean theForce3d,
5089 CORBA::Boolean theToBiQuad,
5090 SMESH::SMESH_IDSource_ptr theObject)
5091 throw (SALOME::SALOME_Exception)
5096 TIDSortedElemSet elems;
5098 if ( !( elemsOK = CORBA::is_nil( theObject )))
5100 elemsOK = idSourceToSet( theObject, getMeshDS(), elems,
5101 SMDSAbs_All, /*emptyIfIsMesh=*/true );
5105 if ( !elems.empty() && (*elems.begin())->GetType() == SMDSAbs_Node )
5106 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5108 if ( elems.empty() ) getEditor().ConvertToQuadratic(theForce3d, theToBiQuad);
5109 else getEditor().ConvertToQuadratic(theForce3d, elems, theToBiQuad);
5111 declareMeshModified( /*isReComputeSafe=*/false );
5114 SMESH_CATCH( SMESH::throwCorbaException );
5117 //=======================================================================
5118 //function : ConvertFromQuadratic
5120 //=======================================================================
5122 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
5123 throw (SALOME::SALOME_Exception)
5128 CORBA::Boolean isDone = getEditor().ConvertFromQuadratic();
5129 TPythonDump() << this << ".ConvertFromQuadratic()";
5130 declareMeshModified( /*isReComputeSafe=*/!isDone );
5133 SMESH_CATCH( SMESH::throwCorbaException );
5137 //=======================================================================
5138 //function : ConvertToQuadratic
5140 //=======================================================================
5142 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
5143 throw (SALOME::SALOME_Exception)
5145 convertToQuadratic( theForce3d, false );
5146 TPythonDump() << this << ".ConvertToQuadratic("<<theForce3d<<")";
5149 //================================================================================
5151 * \brief Makes a part of the mesh quadratic
5153 //================================================================================
5155 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
5156 SMESH::SMESH_IDSource_ptr theObject)
5157 throw (SALOME::SALOME_Exception)
5159 convertToQuadratic( theForce3d, false, theObject );
5160 TPythonDump() << this << ".ConvertToQuadraticObject("<<theForce3d<<", "<<theObject<<")";
5163 //================================================================================
5165 * \brief Makes a part of the mesh bi-quadratic
5167 //================================================================================
5169 void SMESH_MeshEditor_i::ConvertToBiQuadratic(CORBA::Boolean theForce3d,
5170 SMESH::SMESH_IDSource_ptr theObject)
5171 throw (SALOME::SALOME_Exception)
5173 convertToQuadratic( theForce3d, true, theObject );
5174 TPythonDump() << this << ".ConvertToBiQuadratic("<<theForce3d<<", "<<theObject<<")";
5177 //================================================================================
5179 * \brief Makes a part of the mesh linear
5181 //================================================================================
5183 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
5184 throw (SALOME::SALOME_Exception)
5191 TIDSortedElemSet elems;
5192 if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5194 if ( elems.empty() )
5196 ConvertFromQuadratic();
5198 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5200 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5204 getEditor().ConvertFromQuadratic(elems);
5207 declareMeshModified( /*isReComputeSafe=*/false );
5209 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
5211 SMESH_CATCH( SMESH::throwCorbaException );
5214 //=======================================================================
5215 //function : makeMesh
5216 //purpose : create a named imported mesh
5217 //=======================================================================
5219 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
5221 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
5222 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
5223 SALOMEDS::Study_var study = gen->GetCurrentStudy();
5224 SALOMEDS::SObject_wrap meshSO = gen->ObjectToSObject( study, mesh );
5225 gen->SetName( meshSO, theMeshName, "Mesh" );
5226 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
5228 return mesh._retn();
5231 //=======================================================================
5232 //function : dumpGroupsList
5234 //=======================================================================
5236 void SMESH_MeshEditor_i::dumpGroupsList(TPythonDump & theDumpPython,
5237 const SMESH::ListOfGroups * theGroupList)
5239 bool isDumpGroupList = ( theGroupList && theGroupList->length() > 0 );
5240 if ( isDumpGroupList )
5241 theDumpPython << theGroupList << " = ";
5244 //================================================================================
5246 \brief Generates the unique group name.
5247 \param thePrefix name prefix
5250 //================================================================================
5252 std::string SMESH_MeshEditor_i::generateGroupName(const std::string& thePrefix)
5254 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5255 set<std::string> groupNames;
5257 // Get existing group names
5258 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
5259 SMESH::SMESH_GroupBase_var aGroup = groups[i];
5260 if (CORBA::is_nil(aGroup))
5263 CORBA::String_var name = aGroup->GetName();
5264 groupNames.insert( name.in() );
5268 std::string name = thePrefix;
5271 while (!groupNames.insert(name).second)
5272 name = SMESH_Comment( thePrefix ) << "_" << index++;
5277 //================================================================================
5279 * \brief Prepare SMESH_IDSource for work
5281 //================================================================================
5283 void SMESH_MeshEditor_i::prepareIdSource(SMESH::SMESH_IDSource_ptr theObject)
5285 if ( SMESH::Filter_i* filter = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5287 SMESH::SMESH_Mesh_var mesh = myMesh_i->_this();
5288 filter->SetMesh( mesh );
5291 //================================================================================
5293 * \brief Retrieve elements of given type from SMESH_IDSource
5295 //================================================================================
5297 bool SMESH_MeshEditor_i::idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource,
5298 const SMESHDS_Mesh* theMeshDS,
5299 TIDSortedElemSet& theElemSet,
5300 const SMDSAbs_ElementType theType,
5301 const bool emptyIfIsMesh,
5302 IDSource_Error* error)
5305 if ( error ) *error = IDSource_OK;
5307 if ( CORBA::is_nil( theIDSource ))
5309 if ( error ) *error = IDSource_INVALID;
5312 if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
5314 if ( error && getMeshDS()->GetMeshInfo().NbElements( theType ) == 0 )
5315 *error = IDSource_EMPTY;
5318 prepareIdSource( theIDSource );
5319 SMESH::long_array_var anIDs = theIDSource->GetIDs();
5320 if ( anIDs->length() == 0 )
5322 if ( error ) *error = IDSource_EMPTY;
5325 SMESH::array_of_ElementType_var types = theIDSource->GetTypes();
5326 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
5328 if ( theType == SMDSAbs_All || theType == SMDSAbs_Node )
5330 arrayToSet( anIDs, getMeshDS(), theElemSet, SMDSAbs_Node );
5334 if ( error ) *error = IDSource_INVALID;
5340 arrayToSet( anIDs, getMeshDS(), theElemSet, theType);
5341 if ( bool(anIDs->length()) != bool(theElemSet.size()))
5343 if ( error ) *error = IDSource_INVALID;
5350 //================================================================================
5352 * \brief Duplicates given elements, i.e. creates new elements based on the
5353 * same nodes as the given ones.
5354 * \param theElements - container of elements to duplicate.
5355 * \param theGroupName - a name of group to contain the generated elements.
5356 * If a group with such a name already exists, the new elements
5357 * are added to the existng group, else a new group is created.
5358 * If \a theGroupName is empty, new elements are not added
5360 * \return a group where the new elements are added. NULL if theGroupName == "".
5363 //================================================================================
5365 SMESH::SMESH_Group_ptr
5366 SMESH_MeshEditor_i::DoubleElements(SMESH::SMESH_IDSource_ptr theElements,
5367 const char* theGroupName)
5368 throw (SALOME::SALOME_Exception)
5370 SMESH::SMESH_Group_var newGroup;
5377 TIDSortedElemSet elems;
5378 if ( idSourceToSet( theElements, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true))
5380 getEditor().DoubleElements( elems );
5382 if ( strlen( theGroupName ) && !getEditor().GetLastCreatedElems().IsEmpty() )
5385 SMESH::ElementType type =
5386 SMESH::ElementType( getEditor().GetLastCreatedElems().Value(1)->GetType() );
5387 // find existing group
5388 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5389 for ( size_t i = 0; i < groups->length(); ++i )
5390 if ( groups[i]->GetType() == type )
5392 CORBA::String_var name = groups[i]->GetName();
5393 if ( strcmp( name, theGroupName ) == 0 ) {
5394 newGroup = SMESH::SMESH_Group::_narrow( groups[i] );
5398 // create a new group
5399 if ( newGroup->_is_nil() )
5400 newGroup = myMesh_i->CreateGroup( type, theGroupName );
5402 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* >( newGroup ))
5404 SMESHDS_Group* groupDS = static_cast< SMESHDS_Group* >( group_i->GetGroupDS() );
5405 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
5406 for ( int i = 1; i <= aSeq.Length(); i++ )
5407 groupDS->SMDSGroup().Add( aSeq(i) );
5412 if ( !newGroup->_is_nil() )
5413 pyDump << newGroup << " = ";
5414 pyDump << this << ".DoubleElements( "
5415 << theElements << ", " << "'" << theGroupName <<"')";
5417 SMESH_CATCH( SMESH::throwCorbaException );
5419 return newGroup._retn();
5422 //================================================================================
5424 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5425 \param theNodes - identifiers of nodes to be doubled
5426 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
5427 nodes. If list of element identifiers is empty then nodes are doubled but
5428 they not assigned to elements
5429 \return TRUE if operation has been completed successfully, FALSE otherwise
5430 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
5432 //================================================================================
5434 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
5435 const SMESH::long_array& theModifiedElems )
5436 throw (SALOME::SALOME_Exception)
5441 list< int > aListOfNodes;
5443 for ( i = 0, n = theNodes.length(); i < n; i++ )
5444 aListOfNodes.push_back( theNodes[ i ] );
5446 list< int > aListOfElems;
5447 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5448 aListOfElems.push_back( theModifiedElems[ i ] );
5450 bool aResult = getEditor().DoubleNodes( aListOfNodes, aListOfElems );
5452 declareMeshModified( /*isReComputeSafe=*/ !aResult );
5454 // Update Python script
5455 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
5459 SMESH_CATCH( SMESH::throwCorbaException );
5463 //================================================================================
5465 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5466 This method provided for convenience works as DoubleNodes() described above.
5467 \param theNodeId - identifier of node to be doubled.
5468 \param theModifiedElems - identifiers of elements to be updated.
5469 \return TRUE if operation has been completed successfully, FALSE otherwise
5470 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
5472 //================================================================================
5474 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
5475 const SMESH::long_array& theModifiedElems )
5476 throw (SALOME::SALOME_Exception)
5479 SMESH::long_array_var aNodes = new SMESH::long_array;
5480 aNodes->length( 1 );
5481 aNodes[ 0 ] = theNodeId;
5483 TPythonDump pyDump; // suppress dump by the next line
5485 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
5487 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
5491 SMESH_CATCH( SMESH::throwCorbaException );
5495 //================================================================================
5497 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5498 This method provided for convenience works as DoubleNodes() described above.
5499 \param theNodes - group of nodes to be doubled.
5500 \param theModifiedElems - group of elements to be updated.
5501 \return TRUE if operation has been completed successfully, FALSE otherwise
5502 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
5504 //================================================================================
5506 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
5507 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5508 throw (SALOME::SALOME_Exception)
5511 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5514 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5515 SMESH::long_array_var aModifiedElems;
5516 if ( !CORBA::is_nil( theModifiedElems ) )
5517 aModifiedElems = theModifiedElems->GetListOfID();
5520 aModifiedElems = new SMESH::long_array;
5521 aModifiedElems->length( 0 );
5524 TPythonDump pyDump; // suppress dump by the next line
5526 bool done = DoubleNodes( aNodes, aModifiedElems );
5528 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
5532 SMESH_CATCH( SMESH::throwCorbaException );
5536 //================================================================================
5538 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5539 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
5540 * \param theNodes - group of nodes to be doubled.
5541 * \param theModifiedElems - group of elements to be updated.
5542 * \return a new group with newly created nodes
5543 * \sa DoubleNodeGroup()
5545 //================================================================================
5547 SMESH::SMESH_Group_ptr
5548 SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
5549 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5550 throw (SALOME::SALOME_Exception)
5553 SMESH::SMESH_Group_var aNewGroup;
5555 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5556 return aNewGroup._retn();
5559 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5560 SMESH::long_array_var aModifiedElems;
5561 if ( !CORBA::is_nil( theModifiedElems ) )
5562 aModifiedElems = theModifiedElems->GetListOfID();
5564 aModifiedElems = new SMESH::long_array;
5565 aModifiedElems->length( 0 );
5568 TPythonDump pyDump; // suppress dump by the next line
5570 bool aResult = DoubleNodes( aNodes, aModifiedElems );
5573 // Create group with newly created nodes
5574 SMESH::long_array_var anIds = GetLastCreatedNodes();
5575 if (anIds->length() > 0) {
5576 std::string anUnindexedName (theNodes->GetName());
5577 std::string aNewName = generateGroupName(anUnindexedName + "_double");
5578 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5579 aNewGroup->Add(anIds);
5580 pyDump << aNewGroup << " = ";
5584 pyDump << this << ".DoubleNodeGroupNew( " << theNodes << ", "
5585 << theModifiedElems << " )";
5587 return aNewGroup._retn();
5589 SMESH_CATCH( SMESH::throwCorbaException );
5593 //================================================================================
5595 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5596 This method provided for convenience works as DoubleNodes() described above.
5597 \param theNodes - list of groups of nodes to be doubled
5598 \param theModifiedElems - list of groups of elements to be updated.
5599 \return TRUE if operation has been completed successfully, FALSE otherwise
5600 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
5602 //================================================================================
5604 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
5605 const SMESH::ListOfGroups& theModifiedElems )
5606 throw (SALOME::SALOME_Exception)
5611 std::list< int > aNodes;
5613 for ( i = 0, n = theNodes.length(); i < n; i++ )
5615 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
5616 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
5618 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5619 for ( j = 0, m = aCurr->length(); j < m; j++ )
5620 aNodes.push_back( aCurr[ j ] );
5624 std::list< int > anElems;
5625 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5627 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
5628 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
5630 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5631 for ( j = 0, m = aCurr->length(); j < m; j++ )
5632 anElems.push_back( aCurr[ j ] );
5636 bool aResult = getEditor().DoubleNodes( aNodes, anElems );
5638 declareMeshModified( /*isReComputeSafe=*/false );
5640 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
5644 SMESH_CATCH( SMESH::throwCorbaException );
5648 //================================================================================
5650 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5651 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
5652 * \param theNodes - group of nodes to be doubled.
5653 * \param theModifiedElems - group of elements to be updated.
5654 * \return a new group with newly created nodes
5655 * \sa DoubleNodeGroups()
5657 //================================================================================
5659 SMESH::SMESH_Group_ptr
5660 SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
5661 const SMESH::ListOfGroups& theModifiedElems )
5662 throw (SALOME::SALOME_Exception)
5664 SMESH::SMESH_Group_var aNewGroup;
5666 TPythonDump pyDump; // suppress dump by the next line
5668 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
5672 // Create group with newly created nodes
5673 SMESH::long_array_var anIds = GetLastCreatedNodes();
5674 if (anIds->length() > 0) {
5675 std::string anUnindexedName (theNodes[0]->GetName());
5676 std::string aNewName = generateGroupName(anUnindexedName + "_double");
5677 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5678 aNewGroup->Add(anIds);
5679 pyDump << aNewGroup << " = ";
5683 pyDump << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
5684 << theModifiedElems << " )";
5686 return aNewGroup._retn();
5690 //================================================================================
5692 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5693 \param theElems - the list of elements (edges or faces) to be replicated
5694 The nodes for duplication could be found from these elements
5695 \param theNodesNot - list of nodes to NOT replicate
5696 \param theAffectedElems - the list of elements (cells and edges) to which the
5697 replicated nodes should be associated to.
5698 \return TRUE if operation has been completed successfully, FALSE otherwise
5699 \sa DoubleNodeGroup(), DoubleNodeGroups()
5701 //================================================================================
5703 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
5704 const SMESH::long_array& theNodesNot,
5705 const SMESH::long_array& theAffectedElems )
5706 throw (SALOME::SALOME_Exception)
5711 SMESHDS_Mesh* aMeshDS = getMeshDS();
5712 TIDSortedElemSet anElems, aNodes, anAffected;
5713 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5714 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5715 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
5717 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5719 // Update Python script
5720 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
5721 << theNodesNot << ", " << theAffectedElems << " )";
5723 declareMeshModified( /*isReComputeSafe=*/false );
5726 SMESH_CATCH( SMESH::throwCorbaException );
5730 //================================================================================
5732 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5733 \param theElems - the list of elements (edges or faces) to be replicated
5734 The nodes for duplication could be found from these elements
5735 \param theNodesNot - list of nodes to NOT replicate
5736 \param theShape - shape to detect affected elements (element which geometric center
5737 located on or inside shape).
5738 The replicated nodes should be associated to affected elements.
5739 \return TRUE if operation has been completed successfully, FALSE otherwise
5740 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
5742 //================================================================================
5744 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
5745 const SMESH::long_array& theNodesNot,
5746 GEOM::GEOM_Object_ptr theShape )
5747 throw (SALOME::SALOME_Exception)
5753 SMESHDS_Mesh* aMeshDS = getMeshDS();
5754 TIDSortedElemSet anElems, aNodes;
5755 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5756 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5758 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5759 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
5761 // Update Python script
5762 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
5763 << theNodesNot << ", " << theShape << " )";
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 - group of of elements (edges or faces) to be replicated
5776 \param theNodesNot - group of nodes not to replicated
5777 \param theAffectedElems - group of elements to which the replicated nodes
5778 should be associated to.
5779 \return TRUE if operation has been completed successfully, FALSE otherwise
5780 \sa DoubleNodes(), DoubleNodeGroups()
5782 //================================================================================
5785 SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
5786 SMESH::SMESH_GroupBase_ptr theNodesNot,
5787 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5788 throw (SALOME::SALOME_Exception)
5791 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5797 SMESHDS_Mesh* aMeshDS = getMeshDS();
5798 TIDSortedElemSet anElems, aNodes, anAffected;
5799 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5800 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5801 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5803 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5805 // Update Python script
5806 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
5807 << theNodesNot << ", " << theAffectedElems << " )";
5809 declareMeshModified( /*isReComputeSafe=*/false );
5812 SMESH_CATCH( SMESH::throwCorbaException );
5816 //================================================================================
5818 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5819 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
5820 * \param theElems - group of of elements (edges or faces) to be replicated
5821 * \param theNodesNot - group of nodes not to replicated
5822 * \param theAffectedElems - group of elements to which the replicated nodes
5823 * should be associated to.
5824 * \return a new group with newly created elements
5825 * \sa DoubleNodeElemGroup()
5827 //================================================================================
5829 SMESH::SMESH_Group_ptr
5830 SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
5831 SMESH::SMESH_GroupBase_ptr theNodesNot,
5832 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5833 throw (SALOME::SALOME_Exception)
5836 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroup2New( theElems,
5840 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
5841 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
5843 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupNew( "
5845 << theNodesNot << ", "
5846 << theAffectedElems << " )";
5848 return elemGroup._retn();
5851 //================================================================================
5853 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5854 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
5855 * \param theElems - group of of elements (edges or faces) to be replicated
5856 * \param theNodesNot - group of nodes not to replicated
5857 * \param theAffectedElems - group of elements to which the replicated nodes
5858 * should be associated to.
5859 * \return a new group with newly created elements
5860 * \sa DoubleNodeElemGroup()
5862 //================================================================================
5864 SMESH::ListOfGroups*
5865 SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
5866 SMESH::SMESH_GroupBase_ptr theNodesNot,
5867 SMESH::SMESH_GroupBase_ptr theAffectedElems,
5868 CORBA::Boolean theElemGroupNeeded,
5869 CORBA::Boolean theNodeGroupNeeded)
5870 throw (SALOME::SALOME_Exception)
5873 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
5874 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
5875 aTwoGroups->length( 2 );
5877 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5878 return aTwoGroups._retn();
5883 SMESHDS_Mesh* aMeshDS = getMeshDS();
5884 TIDSortedElemSet anElems, aNodes, anAffected;
5885 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5886 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5887 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5890 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5892 declareMeshModified( /*isReComputeSafe=*/ !aResult );
5898 // Create group with newly created elements
5899 CORBA::String_var elemGroupName = theElems->GetName();
5900 std::string aNewName = generateGroupName( std::string(elemGroupName.in()) + "_double");
5901 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
5903 SMESH::long_array_var anIds = GetLastCreatedElems();
5904 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5905 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5906 aNewElemGroup->Add(anIds);
5908 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
5910 SMESH::long_array_var anIds = GetLastCreatedNodes();
5911 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5912 aNewNodeGroup->Add(anIds);
5916 // Update Python script
5919 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
5920 else pyDump << aNewElemGroup << ", ";
5921 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
5922 else pyDump << aNewNodeGroup << " ] = ";
5924 pyDump << this << ".DoubleNodeElemGroup2New( " << theElems << ", "
5925 << theNodesNot << ", "
5926 << theAffectedElems << ", "
5927 << theElemGroupNeeded << ", "
5928 << theNodeGroupNeeded <<" )";
5930 aTwoGroups[0] = aNewElemGroup._retn();
5931 aTwoGroups[1] = aNewNodeGroup._retn();
5932 return aTwoGroups._retn();
5934 SMESH_CATCH( SMESH::throwCorbaException );
5938 //================================================================================
5940 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5941 \param theElems - group of of elements (edges or faces) to be replicated
5942 \param theNodesNot - group of nodes not to replicated
5943 \param theShape - shape to detect affected elements (element which geometric center
5944 located on or inside shape).
5945 The replicated nodes should be associated to affected elements.
5946 \return TRUE if operation has been completed successfully, FALSE otherwise
5947 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
5949 //================================================================================
5952 SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
5953 SMESH::SMESH_GroupBase_ptr theNodesNot,
5954 GEOM::GEOM_Object_ptr theShape )
5955 throw (SALOME::SALOME_Exception)
5958 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5964 SMESHDS_Mesh* aMeshDS = getMeshDS();
5965 TIDSortedElemSet anElems, aNodes, anAffected;
5966 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5967 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5969 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5970 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
5973 declareMeshModified( /*isReComputeSafe=*/ !aResult );
5975 // Update Python script
5976 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
5977 << theNodesNot << ", " << theShape << " )";
5980 SMESH_CATCH( SMESH::throwCorbaException );
5984 //================================================================================
5986 * \brief Re-load elements from a list of groups into a TIDSortedElemSet
5987 * \param [in] theGrpList - groups
5988 * \param [in] theMeshDS - mesh
5989 * \param [out] theElemSet - set of elements
5990 * \param [in] theIsNodeGrp - is \a theGrpList includes goups of nodes
5992 //================================================================================
5994 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
5995 SMESHDS_Mesh* theMeshDS,
5996 TIDSortedElemSet& theElemSet,
5997 const bool theIsNodeGrp)
5999 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
6001 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
6002 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
6003 : aGrp->GetType() != SMESH::NODE ) )
6005 SMESH::long_array_var anIDs = aGrp->GetIDs();
6006 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
6011 //================================================================================
6013 \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6014 This method provided for convenience works as DoubleNodes() described above.
6015 \param theElems - list of groups of elements (edges or faces) to be replicated
6016 \param theNodesNot - list of groups of nodes not to replicated
6017 \param theAffectedElems - group of elements to which the replicated nodes
6018 should be associated to.
6019 \return TRUE if operation has been completed successfully, FALSE otherwise
6020 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
6022 //================================================================================
6025 SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
6026 const SMESH::ListOfGroups& theNodesNot,
6027 const SMESH::ListOfGroups& theAffectedElems)
6028 throw (SALOME::SALOME_Exception)
6034 SMESHDS_Mesh* aMeshDS = getMeshDS();
6035 TIDSortedElemSet anElems, aNodes, anAffected;
6036 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6037 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6038 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6040 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6042 // Update Python script
6043 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
6044 << &theNodesNot << ", " << &theAffectedElems << " )";
6046 declareMeshModified( /*isReComputeSafe=*/false );
6049 SMESH_CATCH( SMESH::throwCorbaException );
6053 //================================================================================
6055 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6056 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
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 a new group with newly created elements
6062 * \sa DoubleNodeElemGroups()
6064 //================================================================================
6066 SMESH::SMESH_Group_ptr
6067 SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
6068 const SMESH::ListOfGroups& theNodesNot,
6069 const SMESH::ListOfGroups& theAffectedElems)
6070 throw (SALOME::SALOME_Exception)
6073 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroups2New( theElems,
6077 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
6078 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
6080 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupsNew( "
6082 << theNodesNot << ", "
6083 << theAffectedElems << " )";
6085 return elemGroup._retn();
6088 //================================================================================
6090 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6091 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6092 \param theElems - list of groups of elements (edges or faces) to be replicated
6093 \param theNodesNot - list of groups of nodes not to replicated
6094 \param theAffectedElems - group of elements to which the replicated nodes
6095 should be associated to.
6096 * \return a new group with newly created elements
6097 * \sa DoubleNodeElemGroups()
6099 //================================================================================
6101 SMESH::ListOfGroups*
6102 SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems,
6103 const SMESH::ListOfGroups& theNodesNot,
6104 const SMESH::ListOfGroups& theAffectedElems,
6105 CORBA::Boolean theElemGroupNeeded,
6106 CORBA::Boolean theNodeGroupNeeded)
6107 throw (SALOME::SALOME_Exception)
6110 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
6111 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
6112 aTwoGroups->length( 2 );
6117 SMESHDS_Mesh* aMeshDS = getMeshDS();
6118 TIDSortedElemSet anElems, aNodes, anAffected;
6119 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6120 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6121 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6123 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6125 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6130 // Create group with newly created elements
6131 CORBA::String_var elemGroupName = theElems[0]->GetName();
6132 std::string aNewName = generateGroupName( std::string(elemGroupName.in()) + "_double");
6133 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
6135 SMESH::long_array_var anIds = GetLastCreatedElems();
6136 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
6137 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
6138 aNewElemGroup->Add(anIds);
6140 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
6142 SMESH::long_array_var anIds = GetLastCreatedNodes();
6143 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6144 aNewNodeGroup->Add(anIds);
6148 // Update Python script
6151 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
6152 else pyDump << aNewElemGroup << ", ";
6153 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
6154 else pyDump << aNewNodeGroup << " ] = ";
6156 pyDump << this << ".DoubleNodeElemGroups2New( " << &theElems << ", "
6157 << &theNodesNot << ", "
6158 << &theAffectedElems << ", "
6159 << theElemGroupNeeded << ", "
6160 << theNodeGroupNeeded << " )";
6162 aTwoGroups[0] = aNewElemGroup._retn();
6163 aTwoGroups[1] = aNewNodeGroup._retn();
6164 return aTwoGroups._retn();
6166 SMESH_CATCH( SMESH::throwCorbaException );
6170 //================================================================================
6172 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6173 This method provided for convenience works as DoubleNodes() described above.
6174 \param theElems - list of groups of elements (edges or faces) to be replicated
6175 \param theNodesNot - list of groups of nodes not to replicated
6176 \param theShape - shape to detect affected elements (element which geometric center
6177 located on or inside shape).
6178 The replicated nodes should be associated to affected elements.
6179 \return TRUE if operation has been completed successfully, FALSE otherwise
6180 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
6182 //================================================================================
6185 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
6186 const SMESH::ListOfGroups& theNodesNot,
6187 GEOM::GEOM_Object_ptr theShape )
6188 throw (SALOME::SALOME_Exception)
6194 SMESHDS_Mesh* aMeshDS = getMeshDS();
6195 TIDSortedElemSet anElems, aNodes;
6196 listOfGroupToSet(theElems, aMeshDS, anElems,false );
6197 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6199 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6200 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6202 // Update Python script
6203 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
6204 << &theNodesNot << ", " << theShape << " )";
6206 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6209 SMESH_CATCH( SMESH::throwCorbaException );
6213 //================================================================================
6215 \brief Identify the elements that will be affected by node duplication (actual
6216 duplication is not performed.
6217 This method is the first step of DoubleNodeElemGroupsInRegion.
6218 \param theElems - list of groups of elements (edges or faces) to be replicated
6219 \param theNodesNot - list of groups of nodes not to replicated
6220 \param theShape - shape to detect affected elements (element which geometric center
6221 located on or inside shape).
6222 The replicated nodes should be associated to affected elements.
6223 \return groups of affected elements
6224 \sa DoubleNodeElemGroupsInRegion()
6226 //================================================================================
6227 SMESH::ListOfGroups*
6228 SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theElems,
6229 const SMESH::ListOfGroups& theNodesNot,
6230 GEOM::GEOM_Object_ptr theShape )
6231 throw (SALOME::SALOME_Exception)
6234 MESSAGE("AffectedElemGroupsInRegion");
6235 SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
6236 bool isEdgeGroup = false;
6237 bool isFaceGroup = false;
6238 bool isVolumeGroup = false;
6239 SMESH::SMESH_Group_var aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE, "affectedEdges");
6240 SMESH::SMESH_Group_var aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE, "affectedFaces");
6241 SMESH::SMESH_Group_var aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME, "affectedVolumes");
6245 ::SMESH_MeshEditor aMeshEditor(myMesh);
6247 SMESHDS_Mesh* aMeshDS = getMeshDS();
6248 TIDSortedElemSet anElems, aNodes;
6249 listOfGroupToSet(theElems, aMeshDS, anElems, false);
6250 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true);
6252 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape(theShape);
6253 TIDSortedElemSet anAffected;
6254 bool aResult = aMeshEditor.AffectedElemGroupsInRegion(anElems, aNodes, aShape, anAffected);
6257 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6262 int lg = anAffected.size();
6263 MESSAGE("lg="<< lg);
6264 SMESH::long_array_var volumeIds = new SMESH::long_array;
6265 volumeIds->length(lg);
6266 SMESH::long_array_var faceIds = new SMESH::long_array;
6267 faceIds->length(lg);
6268 SMESH::long_array_var edgeIds = new SMESH::long_array;
6269 edgeIds->length(lg);
6274 TIDSortedElemSet::const_iterator eIt = anAffected.begin();
6275 for (; eIt != anAffected.end(); ++eIt)
6277 const SMDS_MeshElement* anElem = *eIt;
6280 int elemId = anElem->GetID();
6281 if (myMesh->GetElementType(elemId, true) == SMDSAbs_Volume)
6282 volumeIds[ivol++] = elemId;
6283 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Face)
6284 faceIds[iface++] = elemId;
6285 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Edge)
6286 edgeIds[iedge++] = elemId;
6288 volumeIds->length(ivol);
6289 faceIds->length(iface);
6290 edgeIds->length(iedge);
6292 aNewVolumeGroup->Add(volumeIds);
6293 aNewFaceGroup->Add(faceIds);
6294 aNewEdgeGroup->Add(edgeIds);
6295 isVolumeGroup = (aNewVolumeGroup->Size() > 0);
6296 isFaceGroup = (aNewFaceGroup->Size() > 0);
6297 isEdgeGroup = (aNewEdgeGroup->Size() > 0);
6301 if (isEdgeGroup) nbGroups++;
6302 if (isFaceGroup) nbGroups++;
6303 if (isVolumeGroup) nbGroups++;
6304 aListOfGroups->length(nbGroups);
6307 if (isEdgeGroup) aListOfGroups[i++] = aNewEdgeGroup._retn();
6308 if (isFaceGroup) aListOfGroups[i++] = aNewFaceGroup._retn();
6309 if (isVolumeGroup) aListOfGroups[i++] = aNewVolumeGroup._retn();
6311 // Update Python script
6314 if (isEdgeGroup) pyDump << aNewEdgeGroup << ", ";
6315 if (isFaceGroup) pyDump << aNewFaceGroup << ", ";
6316 if (isVolumeGroup) pyDump << aNewVolumeGroup << ", ";
6318 pyDump << this << ".AffectedElemGroupsInRegion( "
6319 << &theElems << ", " << &theNodesNot << ", " << theShape << " )";
6321 return aListOfGroups._retn();
6323 SMESH_CATCH( SMESH::throwCorbaException );
6327 //================================================================================
6329 \brief Generated skin mesh (containing 2D cells) from 3D mesh
6330 The created 2D mesh elements based on nodes of free faces of boundary volumes
6331 \return TRUE if operation has been completed successfully, FALSE otherwise
6333 //================================================================================
6335 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
6336 throw (SALOME::SALOME_Exception)
6341 bool aResult = getEditor().Make2DMeshFrom3D();
6343 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
6345 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6348 SMESH_CATCH( SMESH::throwCorbaException );
6352 //================================================================================
6354 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
6355 * The list of groups must contain at least two groups. The groups have to be disjoint:
6356 * no common element into two different groups.
6357 * The nodes of the internal faces at the boundaries of the groups are doubled.
6358 * Optionally, the internal faces are replaced by flat elements.
6359 * Triangles are transformed into prisms, and quadrangles into hexahedrons.
6360 * The flat elements are stored in groups of volumes.
6361 * These groups are named according to the position of the group in the list:
6362 * 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.
6363 * 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.
6364 * All the flat elements are gathered into the group named "joints3D" (or "joints2D" in 2D situation).
6365 * The flat element of the multiple junctions between the simple junction are stored in a group named "jointsMultiples".
6366 * \param theDomains - list of groups of volumes
6367 * \param createJointElems - if TRUE, create the elements
6368 * \param onAllBoundaries - if TRUE, the nodes and elements are also created on
6369 * the boundary between \a theDomains and the rest mesh
6370 * \return TRUE if operation has been completed successfully, FALSE otherwise
6372 //================================================================================
6375 SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
6376 CORBA::Boolean createJointElems,
6377 CORBA::Boolean onAllBoundaries )
6378 throw (SALOME::SALOME_Exception)
6385 SMESHDS_Mesh* aMeshDS = getMeshDS();
6387 // MESSAGE("theDomains.length = "<<theDomains.length());
6388 if ( theDomains.length() <= 1 && !onAllBoundaries )
6389 THROW_SALOME_CORBA_EXCEPTION("At least 2 groups are required.", SALOME::BAD_PARAM);
6391 vector<TIDSortedElemSet> domains;
6392 domains.resize( theDomains.length() );
6394 for ( int i = 0, n = theDomains.length(); i < n; i++ )
6396 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
6397 if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
6399 // if ( aGrp->GetType() != SMESH::VOLUME )
6400 // THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
6401 SMESH::long_array_var anIDs = aGrp->GetIDs();
6402 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
6406 isOK = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems, onAllBoundaries );
6407 // TODO publish the groups of flat elements in study
6409 declareMeshModified( /*isReComputeSafe=*/ !isOK );
6411 // Update Python script
6412 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
6413 << ", " << createJointElems << ", " << onAllBoundaries << " )";
6415 SMESH_CATCH( SMESH::throwCorbaException );
6417 myMesh_i->CreateGroupServants(); // publish created groups if any
6422 //================================================================================
6424 * \brief Double nodes on some external faces and create flat elements.
6425 * Flat elements are mainly used by some types of mechanic calculations.
6427 * Each group of the list must be constituted of faces.
6428 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
6429 * @param theGroupsOfFaces - list of groups of faces
6430 * @return TRUE if operation has been completed successfully, FALSE otherwise
6432 //================================================================================
6435 SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
6436 throw (SALOME::SALOME_Exception)
6441 SMESHDS_Mesh* aMeshDS = getMeshDS();
6443 vector<TIDSortedElemSet> faceGroups;
6446 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
6448 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
6449 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
6451 TIDSortedElemSet faceGroup;
6453 faceGroups.push_back(faceGroup);
6454 SMESH::long_array_var anIDs = aGrp->GetIDs();
6455 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
6459 bool aResult = getEditor().CreateFlatElementsOnFacesGroups( faceGroups );
6460 // TODO publish the groups of flat elements in study
6462 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6464 // Update Python script
6465 TPythonDump() << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
6468 SMESH_CATCH( SMESH::throwCorbaException );
6472 //================================================================================
6474 * \brief Identify all the elements around a geom shape, get the faces delimiting
6477 * Build groups of volume to remove, groups of faces to replace on the skin of the
6478 * object, groups of faces to remove inside the object, (idem edges).
6479 * Build ordered list of nodes at the border of each group of faces to replace
6480 * (to be used to build a geom subshape).
6482 //================================================================================
6484 void SMESH_MeshEditor_i::CreateHoleSkin(CORBA::Double radius,
6485 GEOM::GEOM_Object_ptr theShape,
6486 const char* groupName,
6487 const SMESH::double_array& theNodesCoords,
6488 SMESH::array_of_long_array_out GroupsOfNodes)
6489 throw (SALOME::SALOME_Exception)
6494 std::vector<std::vector<int> > aListOfListOfNodes;
6495 ::SMESH_MeshEditor aMeshEditor( myMesh );
6497 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
6498 if ( !theNodeSearcher )
6499 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
6501 vector<double> nodesCoords;
6502 for ( CORBA::ULong i = 0; i < theNodesCoords.length(); i++)
6504 nodesCoords.push_back( theNodesCoords[i] );
6507 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6508 aMeshEditor.CreateHoleSkin(radius, aShape, theNodeSearcher, groupName,
6509 nodesCoords, aListOfListOfNodes);
6511 GroupsOfNodes = new SMESH::array_of_long_array;
6512 GroupsOfNodes->length( aListOfListOfNodes.size() );
6513 std::vector<std::vector<int> >::iterator llIt = aListOfListOfNodes.begin();
6514 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
6516 vector<int>& aListOfNodes = *llIt;
6517 vector<int>::iterator lIt = aListOfNodes.begin();;
6518 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
6519 aGroup.length( aListOfNodes.size() );
6520 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
6521 aGroup[ j ] = (*lIt);
6523 TPythonDump() << "lists_nodes = " << this << ".CreateHoleSkin( "
6526 << ", '" << groupName << "', "
6527 << theNodesCoords << " )";
6529 SMESH_CATCH( SMESH::throwCorbaException );
6532 // issue 20749 ===================================================================
6534 * \brief Creates missing boundary elements
6535 * \param elements - elements whose boundary is to be checked
6536 * \param dimension - defines type of boundary elements to create
6537 * \param groupName - a name of group to store created boundary elements in,
6538 * "" means not to create the group
6539 * \param meshName - a name of new mesh to store created boundary elements in,
6540 * "" means not to create the new mesh
6541 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
6542 * \param toCopyExistingBondary - if true, not only new but also pre-existing
6543 * boundary elements will be copied into the new mesh
6544 * \param group - returns the create group, if any
6545 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
6547 // ================================================================================
6549 SMESH::SMESH_Mesh_ptr
6550 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
6551 SMESH::Bnd_Dimension dim,
6552 const char* groupName,
6553 const char* meshName,
6554 CORBA::Boolean toCopyElements,
6555 CORBA::Boolean toCopyExistingBondary,
6556 SMESH::SMESH_Group_out group)
6557 throw (SALOME::SALOME_Exception)
6562 if ( dim > SMESH::BND_1DFROM2D )
6563 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
6565 SMESHDS_Mesh* aMeshDS = getMeshDS();
6567 SMESH::SMESH_Mesh_var mesh_var;
6568 SMESH::SMESH_Group_var group_var;
6572 TIDSortedElemSet elements;
6573 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
6574 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
6578 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
6579 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
6581 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
6583 // group of new boundary elements
6584 SMESH_Group* smesh_group = 0;
6585 if ( strlen(groupName) )
6587 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
6588 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
6589 smesh_group = group_i->GetSmeshGroup();
6593 getEditor().MakeBoundaryMesh( elements,
6594 ::SMESH_MeshEditor::Bnd_Dimension(dim),
6598 toCopyExistingBondary);
6601 smesh_mesh->GetMeshDS()->Modified();
6604 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
6606 // result of MakeBoundaryMesh() is a tuple (mesh, group)
6607 if ( mesh_var->_is_nil() )
6608 pyDump << myMesh_i->_this() << ", ";
6610 pyDump << mesh_var << ", ";
6611 if ( group_var->_is_nil() )
6612 pyDump << "_NoneGroup = "; // assignment to None is forbiden
6614 pyDump << group_var << " = ";
6615 pyDump << this << ".MakeBoundaryMesh( "
6617 << "SMESH." << dimName[int(dim)] << ", "
6618 << "'" << groupName << "', "
6619 << "'" << meshName<< "', "
6620 << toCopyElements << ", "
6621 << toCopyExistingBondary << ")";
6623 group = group_var._retn();
6624 return mesh_var._retn();
6626 SMESH_CATCH( SMESH::throwCorbaException );
6627 return SMESH::SMESH_Mesh::_nil();
6630 //================================================================================
6632 * \brief Creates missing boundary elements
6633 * \param dimension - defines type of boundary elements to create
6634 * \param groupName - a name of group to store all boundary elements in,
6635 * "" means not to create the group
6636 * \param meshName - a name of a new mesh, which is a copy of the initial
6637 * mesh + created boundary elements; "" means not to create the new mesh
6638 * \param toCopyAll - if true, the whole initial mesh will be copied into
6639 * the new mesh else only boundary elements will be copied into the new mesh
6640 * \param groups - optional groups of elements to make boundary around
6641 * \param mesh - returns the mesh where elements were added to
6642 * \param group - returns the created group, if any
6643 * \retval long - number of added boundary elements
6645 //================================================================================
6647 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
6648 const char* groupName,
6649 const char* meshName,
6650 CORBA::Boolean toCopyAll,
6651 const SMESH::ListOfIDSources& groups,
6652 SMESH::SMESH_Mesh_out mesh,
6653 SMESH::SMESH_Group_out group)
6654 throw (SALOME::SALOME_Exception)
6659 if ( dim > SMESH::BND_1DFROM2D )
6660 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
6662 // separate groups belonging to this and other mesh
6663 SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
6664 SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
6665 groupsOfThisMesh ->length( groups.length() );
6666 groupsOfOtherMesh->length( groups.length() );
6667 int nbGroups = 0, nbGroupsOfOtherMesh = 0;
6668 for ( CORBA::ULong i = 0; i < groups.length(); ++i )
6670 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
6671 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
6672 groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
6674 groupsOfThisMesh[ nbGroups++ ] = groups[i];
6675 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
6676 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
6678 groupsOfThisMesh->length( nbGroups );
6679 groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
6684 if ( nbGroupsOfOtherMesh > 0 )
6686 // process groups belonging to another mesh
6687 SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
6688 SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
6689 nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
6690 groupsOfOtherMesh, mesh, group );
6693 SMESH::SMESH_Mesh_var mesh_var;
6694 SMESH::SMESH_Group_var group_var;
6697 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
6698 const bool toCopyMesh = ( strlen( meshName ) > 0 );
6702 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
6704 /*toCopyGroups=*/false,
6705 /*toKeepIDs=*/true);
6707 mesh_var = makeMesh(meshName);
6709 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
6710 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
6713 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
6714 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
6716 // group of boundary elements
6717 SMESH_Group* smesh_group = 0;
6718 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
6719 if ( strlen(groupName) )
6721 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
6722 group_var = mesh_i->CreateGroup( groupType, groupName );
6723 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
6724 smesh_group = group_i->GetSmeshGroup();
6727 TIDSortedElemSet elements;
6729 if ( groups.length() > 0 )
6731 for ( int i = 0; i < nbGroups; ++i )
6734 if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
6736 SMESH::Bnd_Dimension bdim =
6737 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
6738 nbAdded += getEditor().MakeBoundaryMesh( elements,
6739 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
6742 /*toCopyElements=*/false,
6743 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
6744 /*toAddExistingBondary=*/true,
6745 /*aroundElements=*/true);
6751 nbAdded += getEditor().MakeBoundaryMesh( elements,
6752 ::SMESH_MeshEditor::Bnd_Dimension(dim),
6755 /*toCopyElements=*/false,
6756 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
6757 /*toAddExistingBondary=*/true);
6759 tgtMesh->GetMeshDS()->Modified();
6761 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
6763 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
6764 pyDump << "nbAdded, ";
6765 if ( mesh_var->_is_nil() )
6766 pyDump << myMesh_i->_this() << ", ";
6768 pyDump << mesh_var << ", ";
6769 if ( group_var->_is_nil() )
6770 pyDump << "_NoneGroup = "; // assignment to None is forbiden
6772 pyDump << group_var << " = ";
6773 pyDump << this << ".MakeBoundaryElements( "
6774 << "SMESH." << dimName[int(dim)] << ", "
6775 << "'" << groupName << "', "
6776 << "'" << meshName<< "', "
6777 << toCopyAll << ", "
6780 mesh = mesh_var._retn();
6781 group = group_var._retn();
6784 SMESH_CATCH( SMESH::throwCorbaException );