1 // Copyright (C) 2007-2014 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>
68 #include <BRepAdaptor_Surface.hxx>
69 #include <BRep_Tool.hxx>
70 #include <TopExp_Explorer.hxx>
72 #include <TopoDS_Edge.hxx>
73 #include <TopoDS_Face.hxx>
78 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
82 #include <Standard_Failure.hxx>
85 #include <Standard_ErrorHandler.hxx>
91 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
93 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
96 using SMESH::TPythonDump;
99 namespace MeshEditor_I {
101 //=============================================================================
103 * \brief Mesh to apply modifications for preview purposes
105 //=============================================================================
107 struct TPreviewMesh: public SMESH_Mesh
109 SMDSAbs_ElementType myPreviewType; // type to show
111 TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
112 _isShapeToMesh = (_id =_studyId = 0);
113 _myMeshDS = new SMESHDS_Mesh( _id, true );
114 myPreviewType = previewElements;
117 virtual ~TPreviewMesh() { delete _myMeshDS; _myMeshDS = 0; }
118 //!< Copy a set of elements
119 void Copy(const TIDSortedElemSet & theElements,
120 TIDSortedElemSet& theCopyElements,
121 SMDSAbs_ElementType theSelectType = SMDSAbs_All,
122 SMDSAbs_ElementType theAvoidType = SMDSAbs_All)
124 // loop on theIDsOfElements
125 TIDSortedElemSet::const_iterator eIt = theElements.begin();
126 for ( ; eIt != theElements.end(); ++eIt )
128 const SMDS_MeshElement* anElem = *eIt;
129 if ( !anElem ) continue;
130 SMDSAbs_ElementType type = anElem->GetType();
131 if ( type == theAvoidType ||
132 ( theSelectType != SMDSAbs_All && type != theSelectType ))
134 const SMDS_MeshElement* anElemCopy;
135 if ( type == SMDSAbs_Node)
136 anElemCopy = Copy( cast2Node(anElem) );
138 anElemCopy = Copy( anElem );
140 theCopyElements.insert( theCopyElements.end(), anElemCopy );
144 SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
146 // copy element nodes
147 int anElemNbNodes = anElem->NbNodes();
148 vector< int > anElemNodesID( anElemNbNodes ) ;
149 SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
150 for ( int i = 0; itElemNodes->more(); i++)
152 const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
154 anElemNodesID[i] = anElemNode->GetID();
157 // creates a corresponding element on copied nodes
158 SMDS_MeshElement* anElemCopy = 0;
159 if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
161 const SMDS_VtkVolume* ph =
162 dynamic_cast<const SMDS_VtkVolume*> (anElem);
164 anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
165 (anElemNodesID, ph->GetQuantities(),anElem->GetID());
168 anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
175 SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
177 return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(),
178 anElemNode->GetID());
182 GetMeshDS()->ClearMesh();
184 };// struct TPreviewMesh
186 static SMESH_NodeSearcher * theNodeSearcher = 0;
187 static SMESH_ElementSearcher * theElementSearcher = 0;
189 //=============================================================================
191 * \brief Deleter of theNodeSearcher at any compute event occured
193 //=============================================================================
195 struct TSearchersDeleter : public SMESH_subMeshEventListener
198 string myMeshPartIOR;
200 TSearchersDeleter(): SMESH_subMeshEventListener( false, // won't be deleted by submesh
201 "SMESH_MeshEditor_i::TSearchersDeleter"),
203 //!< Delete theNodeSearcher
206 if ( theNodeSearcher ) delete theNodeSearcher; theNodeSearcher = 0;
207 if ( theElementSearcher ) delete theElementSearcher; theElementSearcher = 0;
209 typedef map < int, SMESH_subMesh * > TDependsOnMap;
210 //!< The meshod called by submesh: do my main job
211 void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
212 SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
214 if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
216 Unset( sm->GetFather() );
219 //!< set self on all submeshes and delete theNodeSearcher if other mesh is set
220 void Set(SMESH_Mesh* mesh, const string& meshPartIOR = string())
222 if ( myMesh != mesh || myMeshPartIOR != meshPartIOR)
229 myMeshPartIOR = meshPartIOR;
230 SMESH_subMesh* sm = mesh->GetSubMesh( mesh->GetShapeToMesh() );
231 SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true );
232 while ( smIt->more() )
235 sm->SetEventListener( this, 0, sm );
239 //!< delete self from all submeshes
240 void Unset(SMESH_Mesh* mesh)
242 if ( SMESH_subMesh* sm = mesh->GetSubMeshContaining(1) ) {
243 SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true );
244 while ( smIt->more() )
245 smIt->next()->DeleteEventListener( this );
250 } theSearchersDeleter;
252 TCollection_AsciiString mirrorTypeName( SMESH::SMESH_MeshEditor::MirrorType theMirrorType )
254 TCollection_AsciiString typeStr;
255 switch ( theMirrorType ) {
256 case SMESH::SMESH_MeshEditor::POINT:
257 typeStr = "SMESH.SMESH_MeshEditor.POINT";
259 case SMESH::SMESH_MeshEditor::AXIS:
260 typeStr = "SMESH.SMESH_MeshEditor.AXIS";
263 typeStr = "SMESH.SMESH_MeshEditor.PLANE";
267 //================================================================================
269 * \brief function for conversion of long_array to TIDSortedElemSet
270 * \param IDs - array of IDs
271 * \param aMesh - mesh
272 * \param aMap - collection to fill
273 * \param aType - element type
275 //================================================================================
277 void arrayToSet(const SMESH::long_array & IDs,
278 const SMESHDS_Mesh* aMesh,
279 TIDSortedElemSet& aMap,
280 const SMDSAbs_ElementType aType = SMDSAbs_All,
281 SMDS_MeshElement::Filter* aFilter = NULL)
283 SMDS_MeshElement::NonNullFilter filter1;
284 SMDS_MeshElement::TypeFilter filter2( aType );
286 if ( aFilter == NULL )
287 aFilter = ( aType == SMDSAbs_All ) ? (SMDS_MeshElement::Filter*) &filter1 : (SMDS_MeshElement::Filter*) &filter2;
289 SMDS_MeshElement::Filter & filter = *aFilter;
291 if ( aType == SMDSAbs_Node )
292 for (int i=0; i<IDs.length(); i++) {
293 const SMDS_MeshElement * elem = aMesh->FindNode( IDs[i] );
295 aMap.insert( aMap.end(), elem );
298 for (int i=0; i<IDs.length(); i++) {
299 const SMDS_MeshElement * elem = aMesh->FindElement( IDs[i] );
301 aMap.insert( aMap.end(), elem );
304 //================================================================================
306 * \brief Retrieve elements of given type from SMESH_IDSource
308 //================================================================================
310 enum IDSource_Error { IDSource_OK, IDSource_INVALID, IDSource_EMPTY };
312 bool idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource,
313 const SMESHDS_Mesh* theMeshDS,
314 TIDSortedElemSet& theElemSet,
315 const SMDSAbs_ElementType theType,
316 const bool emptyIfIsMesh = false,
317 IDSource_Error* error = 0)
320 if ( error ) *error = IDSource_OK;
322 if ( CORBA::is_nil( theIDSource ) )
324 if ( error ) *error = IDSource_INVALID;
327 if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
329 if ( error && theMeshDS->GetMeshInfo().NbElements( theType ) == 0 )
330 *error = IDSource_EMPTY;
333 SMESH::long_array_var anIDs = theIDSource->GetIDs();
334 if ( anIDs->length() == 0 )
336 if ( error ) *error = IDSource_EMPTY;
339 SMESH::array_of_ElementType_var types = theIDSource->GetTypes();
340 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
342 if ( theType == SMDSAbs_All || theType == SMDSAbs_Node )
344 arrayToSet( anIDs, theMeshDS, theElemSet, SMDSAbs_Node );
348 if ( error ) *error = IDSource_INVALID;
354 arrayToSet( anIDs, theMeshDS, theElemSet, theType);
355 if ( bool(anIDs->length()) != bool(theElemSet.size()))
357 if ( error ) *error = IDSource_INVALID;
363 //================================================================================
365 * \brief Retrieve nodes from SMESH_IDSource
367 //================================================================================
369 void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject,
370 const SMESHDS_Mesh* theMeshDS,
371 TIDSortedNodeSet& theNodeSet)
374 if ( CORBA::is_nil( theObject ) )
376 SMESH::array_of_ElementType_var types = theObject->GetTypes();
377 SMESH::long_array_var aElementsId = theObject->GetIDs();
378 if ( types->length() == 1 && types[0] == SMESH::NODE)
380 for(int i = 0; i < aElementsId->length(); i++)
381 if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] ))
382 theNodeSet.insert( theNodeSet.end(), n);
384 else if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
386 SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator();
387 while ( nIt->more( ))
388 if( const SMDS_MeshElement * elem = nIt->next() )
389 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
393 for(int i = 0; i < aElementsId->length(); i++)
394 if( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] ))
395 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
399 //================================================================================
401 * \brief Returns elements connected to the given elements
403 //================================================================================
405 void getElementsAround(const TIDSortedElemSet& theElements,
406 const SMESHDS_Mesh* theMeshDS,
407 TIDSortedElemSet& theElementsAround)
409 if ( theElements.empty() ) return;
411 SMDSAbs_ElementType elemType = (*theElements.begin())->GetType();
412 bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() );
414 theMeshDS->GetMeshInfo().NbElements( elemType ) == theElements.size() )
415 return; // all the elements are in theElements
418 elemType = SMDSAbs_All;
420 TIDSortedElemSet visitedNodes;
421 TIDSortedElemSet::const_iterator elemIt = theElements.begin();
422 for ( ; elemIt != theElements.end(); ++elemIt )
424 const SMDS_MeshElement* e = *elemIt;
425 int i = e->NbCornerNodes();
428 const SMDS_MeshNode* n = e->GetNode( i );
429 if ( visitedNodes.insert( n ).second )
431 SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
432 while ( invIt->more() )
434 const SMDS_MeshElement* elemAround = invIt->next();
435 if ( !theElements.count( elemAround ))
436 theElementsAround.insert( elemAround );
443 //================================================================================
445 * \brief Return a string used to detect change of mesh part on which theElementSearcher
446 * is going to be used
448 //================================================================================
450 string getPartIOR( SMESH::SMESH_IDSource_ptr theMeshPart, SMESH::ElementType type)
452 string partIOR = SMESH_Gen_i::GetORB()->object_to_string( theMeshPart );
453 if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( theMeshPart ))
454 // take into account passible group modification
455 partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() );
456 partIOR += SMESH_Comment( type );
460 } // namespace MeshEditor_I
462 using namespace MeshEditor_I;
464 //=============================================================================
468 //=============================================================================
470 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview):
472 myMesh( &theMesh->GetImpl() ),
474 myIsPreviewMode ( isPreview ),
480 //================================================================================
484 //================================================================================
486 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
488 PortableServer::POA_var poa = SMESH_Gen_i::GetPOA();
489 PortableServer::ObjectId_var anObjectId = poa->servant_to_id(this);
490 poa->deactivate_object(anObjectId.in());
492 //deleteAuxIDSources();
493 delete myPreviewMesh; myPreviewMesh = 0;
494 delete myPreviewEditor; myPreviewEditor = 0;
497 //================================================================================
499 * \brief Clear members
501 //================================================================================
503 void SMESH_MeshEditor_i::initData(bool deleteSearchers)
505 if ( myIsPreviewMode ) {
506 if ( myPreviewMesh ) myPreviewMesh->RemoveAll();
509 if ( deleteSearchers )
510 TSearchersDeleter::Delete();
512 getEditor().GetError().reset();
513 getEditor().CrearLastCreated();
516 //================================================================================
518 * \brief Increment mesh modif time and optionally record that the performed
519 * modification may influence futher mesh re-compute.
520 * \param [in] isReComputeSafe - true if the modification does not infulence
521 * futher mesh re-compute
523 //================================================================================
525 void SMESH_MeshEditor_i::declareMeshModified( bool isReComputeSafe )
527 myMesh->GetMeshDS()->Modified();
528 if ( !isReComputeSafe )
529 myMesh->SetIsModified( true );
532 //================================================================================
534 * \brief Return either myEditor or myPreviewEditor depending on myIsPreviewMode.
535 * WARNING: in preview mode call getPreviewMesh() before getEditor()!
537 //================================================================================
539 ::SMESH_MeshEditor& SMESH_MeshEditor_i::getEditor()
541 if ( myIsPreviewMode && !myPreviewEditor ) {
542 if ( !myPreviewMesh ) getPreviewMesh();
543 myPreviewEditor = new ::SMESH_MeshEditor( myPreviewMesh );
545 return myIsPreviewMode ? *myPreviewEditor : myEditor;
548 //================================================================================
550 * \brief Initialize and return myPreviewMesh
551 * \param previewElements - type of elements to show in preview
553 * WARNING: call it once par a method!
555 //================================================================================
557 TPreviewMesh * SMESH_MeshEditor_i::getPreviewMesh(SMDSAbs_ElementType previewElements)
559 if ( !myPreviewMesh || myPreviewMesh->myPreviewType != previewElements )
561 delete myPreviewEditor;
563 delete myPreviewMesh;
564 myPreviewMesh = new TPreviewMesh( previewElements );
566 myPreviewMesh->Clear();
567 return myPreviewMesh;
570 //================================================================================
572 * Return data of mesh edition preview
574 //================================================================================
576 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
577 throw (SALOME::SALOME_Exception)
580 const bool hasBadElems = ( getEditor().GetError() && getEditor().GetError()->HasBadElems() );
582 if ( myIsPreviewMode || hasBadElems ) { // --- MeshPreviewStruct filling ---
584 list<int> aNodesConnectivity;
585 typedef map<int, int> TNodesMap;
588 SMESHDS_Mesh* aMeshDS;
589 std::auto_ptr< SMESH_MeshPartDS > aMeshPartDS;
591 aMeshPartDS.reset( new SMESH_MeshPartDS( getEditor().GetError()->myBadElements ));
592 aMeshDS = aMeshPartDS.get();
595 aMeshDS = getEditor().GetMeshDS();
597 myPreviewData = new SMESH::MeshPreviewStruct();
598 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
601 SMDSAbs_ElementType previewType = SMDSAbs_All;
603 if (TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( getEditor().GetMesh() )) {
604 previewType = aPreviewMesh->myPreviewType;
605 switch ( previewType ) {
606 case SMDSAbs_Edge : break;
607 case SMDSAbs_Face : break;
608 case SMDSAbs_Volume: break;
610 if ( aMeshDS->GetMeshInfo().NbElements() == 0 ) previewType = SMDSAbs_Node;
614 myPreviewData->elementTypes.length( aMeshDS->GetMeshInfo().NbElements( previewType ));
616 SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator(previewType);
618 while ( itMeshElems->more() ) {
619 const SMDS_MeshElement* aMeshElem = itMeshElems->next();
620 SMDS_NodeIteratorPtr itElemNodes = aMeshElem->nodeIterator();
621 while ( itElemNodes->more() ) {
622 const SMDS_MeshNode* aMeshNode = itElemNodes->next();
623 int aNodeID = aMeshNode->GetID();
624 TNodesMap::iterator anIter = nodesMap.find(aNodeID);
625 if ( anIter == nodesMap.end() ) {
626 // filling the nodes coordinates
627 myPreviewData->nodesXYZ[j].x = aMeshNode->X();
628 myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
629 myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
630 anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
633 aNodesConnectivity.push_back(anIter->second);
636 // filling the elements types
637 SMDSAbs_ElementType aType = aMeshElem->GetType();
638 bool isPoly = aMeshElem->IsPoly();
639 myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
640 myPreviewData->elementTypes[i].isPoly = isPoly;
641 myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
644 myPreviewData->nodesXYZ.length( j );
646 // filling the elements connectivities
647 list<int>::iterator aConnIter = aNodesConnectivity.begin();
648 myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
649 for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
650 myPreviewData->elementConnectivities[i] = *aConnIter;
652 return myPreviewData._retn();
654 SMESH_CATCH( SMESH::throwCorbaException );
658 //================================================================================
660 * \brief Returns list of it's IDs of created nodes
661 * \retval SMESH::long_array* - list of node ID
663 //================================================================================
665 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
666 throw (SALOME::SALOME_Exception)
669 SMESH::long_array_var myLastCreatedNodes = new SMESH::long_array();
671 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedNodes();
672 myLastCreatedNodes->length( aSeq.Length() );
673 for (int i = 1; i <= aSeq.Length(); i++)
674 myLastCreatedNodes[i-1] = aSeq.Value(i)->GetID();
676 return myLastCreatedNodes._retn();
677 SMESH_CATCH( SMESH::throwCorbaException );
681 //================================================================================
683 * \brief Returns list of it's IDs of created elements
684 * \retval SMESH::long_array* - list of elements' ID
686 //================================================================================
688 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
689 throw (SALOME::SALOME_Exception)
692 SMESH::long_array_var myLastCreatedElems = new SMESH::long_array();
694 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
695 myLastCreatedElems->length( aSeq.Length() );
696 for ( int i = 1; i <= aSeq.Length(); i++ )
697 myLastCreatedElems[i-1] = aSeq.Value(i)->GetID();
699 return myLastCreatedElems._retn();
700 SMESH_CATCH( SMESH::throwCorbaException );
704 //=======================================================================
705 //function : ClearLastCreated
706 //purpose : Clears sequences of last created elements and nodes
707 //=======================================================================
709 void SMESH_MeshEditor_i::ClearLastCreated() throw (SALOME::SALOME_Exception)
712 getEditor().CrearLastCreated();
713 SMESH_CATCH( SMESH::throwCorbaException );
716 //=======================================================================
718 * Returns description of an error/warning occured during the last operation
719 * WARNING: ComputeError.code >= 100 and no corresponding enum in IDL API
721 //=======================================================================
723 SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError()
724 throw (SALOME::SALOME_Exception)
727 SMESH::ComputeError_var errOut = new SMESH::ComputeError;
728 SMESH_ComputeErrorPtr& errIn = getEditor().GetError();
729 if ( errIn && !errIn->IsOK() )
731 errOut->code = -( errIn->myName < 0 ? errIn->myName + 1: errIn->myName ); // -1 -> 0
732 errOut->comment = errIn->myComment.c_str();
733 errOut->subShapeID = -1;
734 errOut->hasBadMesh = !errIn->myBadElements.empty();
739 errOut->subShapeID = -1;
740 errOut->hasBadMesh = false;
743 return errOut._retn();
744 SMESH_CATCH( SMESH::throwCorbaException );
748 //=======================================================================
749 //function : MakeIDSource
750 //purpose : Wrap a sequence of ids in a SMESH_IDSource.
751 // Call UnRegister() as you fininsh using it!!
752 //=======================================================================
754 struct SMESH_MeshEditor_i::_IDSource : public virtual POA_SMESH::SMESH_IDSource,
755 public virtual SALOME::GenericObj_i
757 SMESH::long_array _ids;
758 SMESH::ElementType _type;
759 SMESH::SMESH_Mesh_ptr _mesh;
760 SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); }
761 SMESH::long_array* GetMeshInfo() { return 0; }
762 SMESH::long_array* GetNbElementsByType()
764 SMESH::long_array_var aRes = new SMESH::long_array();
765 aRes->length(SMESH::NB_ELEMENT_TYPES);
766 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
767 aRes[ i ] = ( i == _type ) ? _ids.length() : 0;
770 SMESH::SMESH_Mesh_ptr GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _mesh ); }
771 bool IsMeshInfoCorrect() { return true; }
772 SMESH::array_of_ElementType* GetTypes()
774 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
775 if ( _ids.length() > 0 ) {
779 return types._retn();
783 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
784 SMESH::ElementType type)
786 // if ( myAuxIDSources.size() > 10 ) {
787 // delete myAuxIDSources.front();
788 // myAuxIDSources.pop_front();
791 _IDSource* idSrc = new _IDSource;
792 idSrc->_mesh = myMesh_i->_this();
795 //myAuxIDSources.push_back( idSrc );
797 SMESH::SMESH_IDSource_var anIDSourceVar = idSrc->_this();
799 return anIDSourceVar._retn();
802 bool SMESH_MeshEditor_i::IsTemporaryIDSource( SMESH::SMESH_IDSource_ptr& idSource )
804 return SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource );
807 CORBA::Long* SMESH_MeshEditor_i::GetTemporaryIDs( SMESH::SMESH_IDSource_ptr& idSource,
810 if ( _IDSource* tmpIdSource = SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource ))
812 nbIds = (int) tmpIdSource->_ids.length();
813 return & tmpIdSource->_ids[0];
819 // void SMESH_MeshEditor_i::deleteAuxIDSources()
821 // std::list< _IDSource* >::iterator idSrcIt = myAuxIDSources.begin();
822 // for ( ; idSrcIt != myAuxIDSources.end(); ++idSrcIt )
824 // myAuxIDSources.clear();
827 //=============================================================================
831 //=============================================================================
834 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
835 throw (SALOME::SALOME_Exception)
842 for (int i = 0; i < IDsOfElements.length(); i++)
843 IdList.push_back( IDsOfElements[i] );
845 // Update Python script
846 TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
849 bool ret = getEditor().Remove( IdList, false );
851 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 ); // issue 0020693
854 SMESH_CATCH( SMESH::throwCorbaException );
858 //=============================================================================
862 //=============================================================================
864 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
865 throw (SALOME::SALOME_Exception)
871 for (int i = 0; i < IDsOfNodes.length(); i++)
872 IdList.push_back( IDsOfNodes[i] );
874 // Update Python script
875 TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
877 bool ret = getEditor().Remove( IdList, true );
879 declareMeshModified( /*isReComputeSafe=*/ !ret ); // issue 0020693
882 SMESH_CATCH( SMESH::throwCorbaException );
886 //=============================================================================
890 //=============================================================================
892 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
893 throw (SALOME::SALOME_Exception)
898 // Update Python script
899 TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
901 // Create filter to find all orphan nodes
902 SMESH::Controls::Filter::TIdSequence seq;
903 SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
904 SMESH::Controls::Filter::GetElementsId( getMeshDS(), predicate, seq );
906 // remove orphan nodes (if there are any)
908 for ( int i = 0; i < seq.size(); i++ )
909 IdList.push_back( seq[i] );
911 int nbNodesBefore = myMesh->NbNodes();
912 getEditor().Remove( IdList, true );
913 int nbNodesAfter = myMesh->NbNodes();
915 declareMeshModified( /*isReComputeSafe=*/ IdList.size() == 0 ); // issue 0020693
916 return nbNodesBefore - nbNodesAfter;
918 SMESH_CATCH( SMESH::throwCorbaException );
922 //=============================================================================
926 //=============================================================================
928 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,CORBA::Double y, CORBA::Double z)
929 throw (SALOME::SALOME_Exception)
934 const SMDS_MeshNode* N = getMeshDS()->AddNode(x, y, z);
936 // Update Python script
937 TPythonDump() << "nodeID = " << this << ".AddNode( "
938 << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )";
940 declareMeshModified( /*isReComputeSafe=*/false );
943 SMESH_CATCH( SMESH::throwCorbaException );
947 //=============================================================================
949 * Create 0D element on the given node.
951 //=============================================================================
953 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
954 throw (SALOME::SALOME_Exception)
959 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
960 SMDS_MeshElement* elem = getMeshDS()->Add0DElement(aNode);
962 // Update Python script
963 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
965 declareMeshModified( /*isReComputeSafe=*/false );
967 return elem ? elem->GetID() : 0;
969 SMESH_CATCH( SMESH::throwCorbaException );
973 //=============================================================================
975 * Create a ball element on the given node.
977 //=============================================================================
979 CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diameter)
980 throw (SALOME::SALOME_Exception)
985 if ( diameter < std::numeric_limits<double>::min() )
986 THROW_SALOME_CORBA_EXCEPTION("Invalid diameter", SALOME::BAD_PARAM);
988 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
989 SMDS_MeshElement* elem = getMeshDS()->AddBall(aNode, diameter);
991 // Update Python script
992 TPythonDump() << "ballElem = "
993 << this << ".AddBall( " << IDOfNode << ", " << diameter <<" )";
995 declareMeshModified( /*isReComputeSafe=*/false );
996 return elem ? elem->GetID() : 0;
998 SMESH_CATCH( SMESH::throwCorbaException );
1002 //=============================================================================
1004 * Create an edge, either linear and quadratic (this is determed
1005 * by number of given nodes, two or three)
1007 //=============================================================================
1009 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
1010 throw (SALOME::SALOME_Exception)
1015 int NbNodes = IDsOfNodes.length();
1016 SMDS_MeshElement* elem = 0;
1019 CORBA::Long index1 = IDsOfNodes[0];
1020 CORBA::Long index2 = IDsOfNodes[1];
1021 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(index1),
1022 getMeshDS()->FindNode(index2));
1024 // Update Python script
1025 TPythonDump() << "edge = " << this << ".AddEdge([ "
1026 << index1 << ", " << index2 <<" ])";
1029 CORBA::Long n1 = IDsOfNodes[0];
1030 CORBA::Long n2 = IDsOfNodes[1];
1031 CORBA::Long n12 = IDsOfNodes[2];
1032 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(n1),
1033 getMeshDS()->FindNode(n2),
1034 getMeshDS()->FindNode(n12));
1035 // Update Python script
1036 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
1037 <<n1<<", "<<n2<<", "<<n12<<" ])";
1040 declareMeshModified( /*isReComputeSafe=*/false );
1041 return elem ? elem->GetID() : 0;
1043 SMESH_CATCH( SMESH::throwCorbaException );
1047 //=============================================================================
1051 //=============================================================================
1053 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
1054 throw (SALOME::SALOME_Exception)
1059 int NbNodes = IDsOfNodes.length();
1065 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1066 for (int i = 0; i < NbNodes; i++)
1067 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1069 SMDS_MeshElement* elem = 0;
1071 case 3: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]); break;
1072 case 4: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]); break;
1073 case 6: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1074 nodes[4], nodes[5]); break;
1075 case 7: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1076 nodes[4], nodes[5], nodes[6]); break;
1077 case 8: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1078 nodes[4], nodes[5], nodes[6], nodes[7]); break;
1079 case 9: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1080 nodes[4], nodes[5], nodes[6], nodes[7],
1082 default: elem = getMeshDS()->AddPolygonalFace(nodes);
1085 // Update Python script
1086 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
1088 declareMeshModified( /*isReComputeSafe=*/false );
1090 return elem ? elem->GetID() : 0;
1092 SMESH_CATCH( SMESH::throwCorbaException );
1096 //=============================================================================
1100 //=============================================================================
1101 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
1102 throw (SALOME::SALOME_Exception)
1107 int NbNodes = IDsOfNodes.length();
1108 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1109 for (int i = 0; i < NbNodes; i++)
1110 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1112 const SMDS_MeshElement* elem = getMeshDS()->AddPolygonalFace(nodes);
1114 // Update Python script
1115 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
1117 declareMeshModified( /*isReComputeSafe=*/false );
1118 return elem ? elem->GetID() : 0;
1120 SMESH_CATCH( SMESH::throwCorbaException );
1124 //=============================================================================
1126 * Create volume, either linear and quadratic (this is determed
1127 * by number of given nodes)
1129 //=============================================================================
1131 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
1132 throw (SALOME::SALOME_Exception)
1137 int NbNodes = IDsOfNodes.length();
1138 vector< const SMDS_MeshNode*> n(NbNodes);
1139 for(int i=0;i<NbNodes;i++)
1140 n[i]= getMeshDS()->FindNode(IDsOfNodes[i]);
1142 SMDS_MeshElement* elem = 0;
1145 case 4 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
1146 case 5 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
1147 case 6 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
1148 case 8 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
1149 case 10:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1150 n[6],n[7],n[8],n[9]);
1152 case 12:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1153 n[6],n[7],n[8],n[9],n[10],n[11]);
1155 case 13:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
1156 n[7],n[8],n[9],n[10],n[11],n[12]);
1158 case 15:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
1159 n[9],n[10],n[11],n[12],n[13],n[14]);
1161 case 20:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1162 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1163 n[15],n[16],n[17],n[18],n[19]);
1165 case 27:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1166 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1167 n[15],n[16],n[17],n[18],n[19],
1168 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
1172 // Update Python script
1173 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
1175 declareMeshModified( /*isReComputeSafe=*/false );
1176 return elem ? elem->GetID() : 0;
1178 SMESH_CATCH( SMESH::throwCorbaException );
1182 //=============================================================================
1184 * AddPolyhedralVolume
1186 //=============================================================================
1187 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
1188 const SMESH::long_array & Quantities)
1189 throw (SALOME::SALOME_Exception)
1194 int NbNodes = IDsOfNodes.length();
1195 std::vector<const SMDS_MeshNode*> n (NbNodes);
1196 for (int i = 0; i < NbNodes; i++)
1198 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDsOfNodes[i]);
1199 if (!aNode) return 0;
1203 int NbFaces = Quantities.length();
1204 std::vector<int> q (NbFaces);
1205 for (int j = 0; j < NbFaces; j++)
1206 q[j] = Quantities[j];
1208 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(n, q);
1210 // Update Python script
1211 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
1212 << IDsOfNodes << ", " << Quantities << " )";
1214 declareMeshModified( /*isReComputeSafe=*/false );
1215 return elem ? elem->GetID() : 0;
1217 SMESH_CATCH( SMESH::throwCorbaException );
1221 //=============================================================================
1223 * AddPolyhedralVolumeByFaces
1225 //=============================================================================
1227 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
1228 throw (SALOME::SALOME_Exception)
1233 int NbFaces = IdsOfFaces.length();
1234 std::vector<const SMDS_MeshNode*> poly_nodes;
1235 std::vector<int> quantities (NbFaces);
1237 for (int i = 0; i < NbFaces; i++) {
1238 const SMDS_MeshElement* aFace = getMeshDS()->FindElement(IdsOfFaces[i]);
1239 quantities[i] = aFace->NbNodes();
1241 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
1242 while (It->more()) {
1243 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
1247 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
1249 // Update Python script
1250 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
1251 << IdsOfFaces << " )";
1253 declareMeshModified( /*isReComputeSafe=*/false );
1254 return elem ? elem->GetID() : 0;
1256 SMESH_CATCH( SMESH::throwCorbaException );
1260 //=============================================================================
1262 // \brief Create 0D elements on all nodes of the given object except those
1263 // nodes on which a 0D element already exists.
1264 // \param theObject object on whose nodes 0D elements will be created.
1265 // \param theGroupName optional name of a group to add 0D elements created
1266 // and/or found on nodes of \a theObject.
1267 // \return an object (a new group or a temporary SMESH_IDSource) holding
1268 // ids of new and/or found 0D elements.
1270 //=============================================================================
1272 SMESH::SMESH_IDSource_ptr
1273 SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObject,
1274 const char* theGroupName)
1275 throw (SALOME::SALOME_Exception)
1280 SMESH::SMESH_IDSource_var result;
1283 TIDSortedElemSet elements, elems0D;
1284 prepareIdSource( theObject );
1285 if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
1286 getEditor().Create0DElementsOnAllNodes( elements, elems0D );
1288 SMESH::long_array_var newElems = new SMESH::long_array;
1289 newElems->length( elems0D.size() );
1290 TIDSortedElemSet::iterator eIt = elems0D.begin();
1291 for ( size_t i = 0; i < elems0D.size(); ++i, ++eIt )
1292 newElems[ i ] = (*eIt)->GetID();
1294 SMESH::SMESH_GroupBase_var groupToFill;
1295 if ( theGroupName && strlen( theGroupName ))
1297 // Get existing group named theGroupName
1298 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
1299 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
1300 SMESH::SMESH_GroupBase_var group = groups[i];
1301 if ( !group->_is_nil() ) {
1302 CORBA::String_var name = group->GetName();
1303 if ( strcmp( name.in(), theGroupName ) == 0 && group->GetType() == SMESH::ELEM0D ) {
1304 groupToFill = group;
1309 if ( groupToFill->_is_nil() )
1310 groupToFill = myMesh_i->CreateGroup( SMESH::ELEM0D, theGroupName );
1311 else if ( !SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1312 groupToFill = myMesh_i->ConvertToStandalone( groupToFill );
1315 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1317 group_i->Add( newElems );
1318 result = SMESH::SMESH_IDSource::_narrow( groupToFill );
1319 pyDump << groupToFill;
1323 result = MakeIDSource( newElems, SMESH::ELEM0D );
1324 pyDump << "elem0DIDs";
1327 pyDump << " = " << this << ".Create0DElementsOnAllNodes( "
1328 << theObject << ", '" << theGroupName << "' )";
1330 return result._retn();
1332 SMESH_CATCH( SMESH::throwCorbaException );
1336 //=============================================================================
1338 * \brief Bind a node to a vertex
1339 * \param NodeID - node ID
1340 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1341 * \retval boolean - false if NodeID or VertexID is invalid
1343 //=============================================================================
1345 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
1346 throw (SALOME::SALOME_Exception)
1350 SMESHDS_Mesh * mesh = getMeshDS();
1351 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1353 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1355 if ( mesh->MaxShapeIndex() < VertexID )
1356 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1358 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
1359 if ( shape.ShapeType() != TopAbs_VERTEX )
1360 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1362 mesh->SetNodeOnVertex( node, VertexID );
1364 myMesh->SetIsModified( true );
1366 SMESH_CATCH( SMESH::throwCorbaException );
1369 //=============================================================================
1371 * \brief Store node position on an edge
1372 * \param NodeID - node ID
1373 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
1374 * \param paramOnEdge - parameter on edge where the node is located
1375 * \retval boolean - false if any parameter is invalid
1377 //=============================================================================
1379 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
1380 CORBA::Double paramOnEdge)
1381 throw (SALOME::SALOME_Exception)
1385 SMESHDS_Mesh * mesh = getMeshDS();
1386 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1388 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1390 if ( mesh->MaxShapeIndex() < EdgeID )
1391 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1393 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
1394 if ( shape.ShapeType() != TopAbs_EDGE )
1395 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1398 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
1399 if ( paramOnEdge < f || paramOnEdge > l )
1400 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
1402 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
1404 myMesh->SetIsModified( true );
1406 SMESH_CATCH( SMESH::throwCorbaException );
1409 //=============================================================================
1411 * \brief Store node position on a face
1412 * \param NodeID - node ID
1413 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
1414 * \param u - U parameter on face where the node is located
1415 * \param v - V parameter on face where the node is located
1416 * \retval boolean - false if any parameter is invalid
1418 //=============================================================================
1420 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
1421 CORBA::Double u, CORBA::Double v)
1422 throw (SALOME::SALOME_Exception)
1425 SMESHDS_Mesh * mesh = getMeshDS();
1426 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1428 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1430 if ( mesh->MaxShapeIndex() < FaceID )
1431 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1433 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
1434 if ( shape.ShapeType() != TopAbs_FACE )
1435 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1437 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
1438 bool isOut = ( u < surf.FirstUParameter() ||
1439 u > surf.LastUParameter() ||
1440 v < surf.FirstVParameter() ||
1441 v > surf.LastVParameter() );
1445 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
1446 << " u( " << surf.FirstUParameter()
1447 << "," << surf.LastUParameter()
1448 << ") v( " << surf.FirstVParameter()
1449 << "," << surf.LastVParameter() << ")" );
1451 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
1454 mesh->SetNodeOnFace( node, FaceID, u, v );
1455 myMesh->SetIsModified( true );
1457 SMESH_CATCH( SMESH::throwCorbaException );
1460 //=============================================================================
1462 * \brief Bind a node to a solid
1463 * \param NodeID - node ID
1464 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1465 * \retval boolean - false if NodeID or SolidID is invalid
1467 //=============================================================================
1469 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
1470 throw (SALOME::SALOME_Exception)
1473 SMESHDS_Mesh * mesh = getMeshDS();
1474 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1476 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1478 if ( mesh->MaxShapeIndex() < SolidID )
1479 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1481 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
1482 if ( shape.ShapeType() != TopAbs_SOLID &&
1483 shape.ShapeType() != TopAbs_SHELL)
1484 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1486 mesh->SetNodeInVolume( node, SolidID );
1488 SMESH_CATCH( SMESH::throwCorbaException );
1491 //=============================================================================
1493 * \brief Bind an element to a shape
1494 * \param ElementID - element ID
1495 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
1497 //=============================================================================
1499 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
1500 CORBA::Long ShapeID)
1501 throw (SALOME::SALOME_Exception)
1504 SMESHDS_Mesh * mesh = getMeshDS();
1505 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
1507 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
1509 if ( mesh->MaxShapeIndex() < ShapeID || ShapeID < 1 )
1510 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1512 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1513 if ( shape.ShapeType() != TopAbs_EDGE &&
1514 shape.ShapeType() != TopAbs_FACE &&
1515 shape.ShapeType() != TopAbs_SOLID &&
1516 shape.ShapeType() != TopAbs_SHELL )
1517 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1519 mesh->SetMeshElementOnShape( elem, ShapeID );
1521 myMesh->SetIsModified( true );
1523 SMESH_CATCH( SMESH::throwCorbaException );
1526 //=============================================================================
1530 //=============================================================================
1532 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1533 CORBA::Long NodeID2)
1534 throw (SALOME::SALOME_Exception)
1539 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1540 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1544 // Update Python script
1545 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1546 << NodeID1 << ", " << NodeID2 << " )";
1548 int ret = getEditor().InverseDiag ( n1, n2 );
1550 declareMeshModified( /*isReComputeSafe=*/false );
1553 SMESH_CATCH( SMESH::throwCorbaException );
1557 //=============================================================================
1561 //=============================================================================
1563 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1564 CORBA::Long NodeID2)
1565 throw (SALOME::SALOME_Exception)
1570 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1571 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1575 // Update Python script
1576 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1577 << NodeID1 << ", " << NodeID2 << " )";
1580 bool stat = getEditor().DeleteDiag ( n1, n2 );
1582 declareMeshModified( /*isReComputeSafe=*/!stat );
1586 SMESH_CATCH( SMESH::throwCorbaException );
1590 //=============================================================================
1594 //=============================================================================
1596 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1597 throw (SALOME::SALOME_Exception)
1602 for (int i = 0; i < IDsOfElements.length(); i++)
1604 CORBA::Long index = IDsOfElements[i];
1605 const SMDS_MeshElement * elem = getMeshDS()->FindElement(index);
1607 getEditor().Reorient( elem );
1609 // Update Python script
1610 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1612 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 );
1615 SMESH_CATCH( SMESH::throwCorbaException );
1619 //=============================================================================
1623 //=============================================================================
1625 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1626 throw (SALOME::SALOME_Exception)
1631 TPythonDump aTPythonDump; // suppress dump in Reorient()
1633 prepareIdSource( theObject );
1635 SMESH::long_array_var anElementsId = theObject->GetIDs();
1636 CORBA::Boolean isDone = Reorient(anElementsId);
1638 // Update Python script
1639 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1641 declareMeshModified( /*isReComputeSafe=*/ anElementsId->length() == 0 );
1644 SMESH_CATCH( SMESH::throwCorbaException );
1648 //=======================================================================
1649 //function : Reorient2D
1650 //purpose : Reorient faces contained in \a the2Dgroup.
1651 // the2Dgroup - the mesh or its part to reorient
1652 // theDirection - desired direction of normal of \a theFace
1653 // theFace - ID of face whose orientation is checked.
1654 // It can be < 1 then \a thePoint is used to find a face.
1655 // thePoint - is used to find a face if \a theFace < 1.
1656 // return number of reoriented elements.
1657 //=======================================================================
1659 CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
1660 const SMESH::DirStruct& theDirection,
1661 CORBA::Long theFace,
1662 const SMESH::PointStruct& thePoint)
1663 throw (SALOME::SALOME_Exception)
1666 initData(/*deleteSearchers=*/false);
1668 TIDSortedElemSet elements;
1669 prepareIdSource( the2Dgroup );
1670 IDSource_Error error;
1671 idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error );
1672 if ( error == IDSource_EMPTY )
1674 if ( error == IDSource_INVALID )
1675 THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
1678 const SMDS_MeshElement* face = 0;
1681 face = getMeshDS()->FindElement( theFace );
1683 THROW_SALOME_CORBA_EXCEPTION("Inexistent face given", SALOME::BAD_PARAM);
1684 if ( face->GetType() != SMDSAbs_Face )
1685 THROW_SALOME_CORBA_EXCEPTION("Wrong element type", SALOME::BAD_PARAM);
1689 // create theElementSearcher if needed
1690 theSearchersDeleter.Set( myMesh, getPartIOR( the2Dgroup, SMESH::FACE ));
1691 if ( !theElementSearcher )
1693 if ( elements.empty() ) // search in the whole mesh
1695 if ( myMesh->NbFaces() == 0 )
1696 THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM);
1698 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
1702 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
1703 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
1705 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt);
1709 gp_Pnt p( thePoint.x, thePoint.y, thePoint.z );
1710 face = theElementSearcher->FindClosestTo( p, SMDSAbs_Face );
1713 THROW_SALOME_CORBA_EXCEPTION("No face found by point", SALOME::INTERNAL_ERROR );
1714 if ( !elements.empty() && !elements.count( face ))
1715 THROW_SALOME_CORBA_EXCEPTION("Found face is not in the group", SALOME::BAD_PARAM );
1718 const SMESH::PointStruct * P = &theDirection.PS;
1719 gp_Vec dirVec( P->x, P->y, P->z );
1720 if ( dirVec.Magnitude() < std::numeric_limits< double >::min() )
1721 THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM);
1723 int nbReori = getEditor().Reorient2D( elements, dirVec, face );
1726 declareMeshModified( /*isReComputeSafe=*/false );
1728 TPythonDump() << this << ".Reorient2D( "
1729 << the2Dgroup << ", "
1730 << theDirection << ", "
1732 << thePoint << " )";
1736 SMESH_CATCH( SMESH::throwCorbaException );
1740 //=======================================================================
1741 //function : Reorient2DBy3D
1742 //purpose : Reorient faces basing on orientation of adjacent volumes.
1743 //=======================================================================
1745 CORBA::Long SMESH_MeshEditor_i::Reorient2DBy3D(const SMESH::ListOfIDSources& faceGroups,
1746 SMESH::SMESH_IDSource_ptr volumeGroup,
1747 CORBA::Boolean outsideNormal)
1748 throw (SALOME::SALOME_Exception)
1753 TIDSortedElemSet volumes;
1754 prepareIdSource( volumeGroup );
1755 IDSource_Error volsError;
1756 idSourceToSet( volumeGroup, getMeshDS(), volumes, SMDSAbs_Volume, /*emptyIfMesh=*/1, &volsError);
1759 for ( size_t i = 0; i < faceGroups.length(); ++i )
1761 SMESH::SMESH_IDSource_ptr faceGrp = faceGroups[i].in();
1762 prepareIdSource( faceGrp );
1764 TIDSortedElemSet faces;
1765 IDSource_Error error;
1766 idSourceToSet( faceGrp, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error );
1767 if ( error == IDSource_INVALID && faceGroups.length() == 1 )
1768 THROW_SALOME_CORBA_EXCEPTION("No faces in a given object", SALOME::BAD_PARAM);
1769 if ( error == IDSource_OK && volsError != IDSource_OK )
1770 THROW_SALOME_CORBA_EXCEPTION("No volumes in a given object", SALOME::BAD_PARAM);
1772 nbReori += getEditor().Reorient2DBy3D( faces, volumes, outsideNormal );
1774 if ( error != IDSource_EMPTY && faces.empty() ) // all faces in the mesh treated
1779 declareMeshModified( /*isReComputeSafe=*/false );
1781 TPythonDump() << this << ".Reorient2DBy3D( "
1782 << faceGroups << ", "
1783 << volumeGroup << ", "
1784 << outsideNormal << " )";
1788 SMESH_CATCH( SMESH::throwCorbaException );
1792 //=============================================================================
1794 * \brief Fuse neighbour triangles into quadrangles.
1796 //=============================================================================
1798 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1799 SMESH::NumericalFunctor_ptr Criterion,
1800 CORBA::Double MaxAngle)
1801 throw (SALOME::SALOME_Exception)
1806 SMESHDS_Mesh* aMesh = getMeshDS();
1807 TIDSortedElemSet faces,copyFaces;
1808 SMDS_MeshElement::GeomFilter triaFilter(SMDSGeom_TRIANGLE);
1809 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face, & triaFilter);
1810 TIDSortedElemSet* workElements = & faces;
1812 if ( myIsPreviewMode ) {
1813 SMDSAbs_ElementType select = SMDSAbs_Face;
1814 getPreviewMesh( SMDSAbs_Face )->Copy( faces, copyFaces, select );
1815 workElements = & copyFaces;
1818 SMESH::NumericalFunctor_i* aNumericalFunctor =
1819 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1820 SMESH::Controls::NumericalFunctorPtr aCrit;
1821 if ( !aNumericalFunctor )
1822 aCrit.reset( new SMESH::Controls::MaxElementLength2D() );
1824 aCrit = aNumericalFunctor->GetNumericalFunctor();
1826 if ( !myIsPreviewMode ) {
1827 // Update Python script
1828 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1829 << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1832 bool stat = getEditor().TriToQuad( *workElements, aCrit, MaxAngle );
1834 declareMeshModified( /*isReComputeSafe=*/!stat );
1837 SMESH_CATCH( SMESH::throwCorbaException );
1841 //=============================================================================
1843 * \brief Fuse neighbour triangles into quadrangles.
1845 //=============================================================================
1847 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1848 SMESH::NumericalFunctor_ptr Criterion,
1849 CORBA::Double MaxAngle)
1850 throw (SALOME::SALOME_Exception)
1855 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1857 prepareIdSource( theObject );
1858 SMESH::long_array_var anElementsId = theObject->GetIDs();
1859 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1861 if ( !myIsPreviewMode ) {
1862 SMESH::NumericalFunctor_i* aNumericalFunctor =
1863 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1865 // Update Python script
1866 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1867 << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1872 SMESH_CATCH( SMESH::throwCorbaException );
1876 //=============================================================================
1878 * \brief Split quadrangles into triangles.
1880 //=============================================================================
1882 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1883 SMESH::NumericalFunctor_ptr Criterion)
1884 throw (SALOME::SALOME_Exception)
1889 SMESHDS_Mesh* aMesh = getMeshDS();
1890 TIDSortedElemSet faces;
1891 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1893 SMESH::NumericalFunctor_i* aNumericalFunctor =
1894 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1895 SMESH::Controls::NumericalFunctorPtr aCrit;
1896 if ( !aNumericalFunctor )
1897 aCrit.reset( new SMESH::Controls::AspectRatio() );
1899 aCrit = aNumericalFunctor->GetNumericalFunctor();
1902 // Update Python script
1903 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1905 CORBA::Boolean stat = getEditor().QuadToTri( faces, aCrit );
1907 declareMeshModified( /*isReComputeSafe=*/false );
1910 SMESH_CATCH( SMESH::throwCorbaException );
1914 //=============================================================================
1916 * \brief Split quadrangles into triangles.
1918 //=============================================================================
1920 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1921 SMESH::NumericalFunctor_ptr Criterion)
1922 throw (SALOME::SALOME_Exception)
1927 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1929 prepareIdSource( theObject );
1930 SMESH::long_array_var anElementsId = theObject->GetIDs();
1931 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1933 SMESH::NumericalFunctor_i* aNumericalFunctor =
1934 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1936 // Update Python script
1937 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1939 declareMeshModified( /*isReComputeSafe=*/false );
1942 SMESH_CATCH( SMESH::throwCorbaException );
1946 //================================================================================
1948 * \brief Split each of quadrangles into 4 triangles.
1949 * \param [in] theObject - theQuads Container of quadrangles to split.
1951 //================================================================================
1953 void SMESH_MeshEditor_i::QuadTo4Tri (SMESH::SMESH_IDSource_ptr theObject)
1954 throw (SALOME::SALOME_Exception)
1959 TIDSortedElemSet faces;
1960 prepareIdSource( theObject );
1961 if ( !idSourceToSet( theObject, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/true ) &&
1963 THROW_SALOME_CORBA_EXCEPTION("No faces given", SALOME::BAD_PARAM);
1965 getEditor().QuadTo4Tri( faces );
1966 TPythonDump() << this << ".QuadTo4Tri( " << theObject << " )";
1968 SMESH_CATCH( SMESH::throwCorbaException );
1971 //=============================================================================
1973 * \brief Split quadrangles into triangles.
1975 //=============================================================================
1977 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1978 CORBA::Boolean Diag13)
1979 throw (SALOME::SALOME_Exception)
1984 SMESHDS_Mesh* aMesh = getMeshDS();
1985 TIDSortedElemSet faces;
1986 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1988 // Update Python script
1989 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1990 << IDsOfElements << ", " << Diag13 << " )";
1992 CORBA::Boolean stat = getEditor().QuadToTri( faces, Diag13 );
1994 declareMeshModified( /*isReComputeSafe=*/ !stat );
1997 SMESH_CATCH( SMESH::throwCorbaException );
2001 //=============================================================================
2003 * \brief Split quadrangles into triangles.
2005 //=============================================================================
2007 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
2008 CORBA::Boolean Diag13)
2009 throw (SALOME::SALOME_Exception)
2014 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
2016 prepareIdSource( theObject );
2017 SMESH::long_array_var anElementsId = theObject->GetIDs();
2018 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
2020 // Update Python script
2021 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
2022 << theObject << ", " << Diag13 << " )";
2024 declareMeshModified( /*isReComputeSafe=*/!isDone );
2027 SMESH_CATCH( SMESH::throwCorbaException );
2032 //=============================================================================
2034 * Find better splitting of the given quadrangle.
2035 * \param IDOfQuad ID of the quadrangle to be splitted.
2036 * \param Criterion A criterion to choose a diagonal for splitting.
2037 * \return 1 if 1-3 diagonal is better, 2 if 2-4
2038 * diagonal is better, 0 if error occurs.
2040 //=============================================================================
2042 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
2043 SMESH::NumericalFunctor_ptr Criterion)
2044 throw (SALOME::SALOME_Exception)
2049 const SMDS_MeshElement* quad = getMeshDS()->FindElement(IDOfQuad);
2050 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
2052 SMESH::NumericalFunctor_i* aNumericalFunctor =
2053 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
2054 SMESH::Controls::NumericalFunctorPtr aCrit;
2055 if (aNumericalFunctor)
2056 aCrit = aNumericalFunctor->GetNumericalFunctor();
2058 aCrit.reset(new SMESH::Controls::AspectRatio());
2060 int id = getEditor().BestSplit(quad, aCrit);
2061 declareMeshModified( /*isReComputeSafe=*/ id < 1 );
2065 SMESH_CATCH( SMESH::throwCorbaException );
2069 //================================================================================
2071 * \brief Split volumic elements into tetrahedrons
2073 //================================================================================
2075 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
2076 CORBA::Short methodFlags)
2077 throw (SALOME::SALOME_Exception)
2081 prepareIdSource( elems );
2083 ::SMESH_MeshEditor::TFacetOfElem elemSet;
2084 const int noneFacet = -1;
2085 SMDS_ElemIteratorPtr volIt = myMesh_i->GetElements( elems, SMESH::VOLUME );
2086 while( volIt->more() )
2087 elemSet.insert( elemSet.end(), make_pair( volIt->next(), noneFacet ));
2089 getEditor().SplitVolumes( elemSet, int( methodFlags ));
2090 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2092 TPythonDump() << this << ".SplitVolumesIntoTetra( "
2093 << elems << ", " << methodFlags << " )";
2095 SMESH_CATCH( SMESH::throwCorbaException );
2098 //================================================================================
2100 * \brief Split hexahedra into triangular prisms
2101 * \param elems - elements to split
2102 * \param facetToSplitNormal - normal used to find a facet of hexahedron
2103 * to split into triangles
2104 * \param methodFlags - flags passing splitting method:
2105 * 1 - split the hexahedron into 2 prisms
2106 * 2 - split the hexahedron into 4 prisms
2108 //================================================================================
2110 void SMESH_MeshEditor_i::SplitHexahedraIntoPrisms (SMESH::SMESH_IDSource_ptr elems,
2111 const SMESH::PointStruct & startHexPoint,
2112 const SMESH::DirStruct& facetToSplitNormal,
2113 CORBA::Short methodFlags,
2114 CORBA::Boolean allDomains)
2115 throw (SALOME::SALOME_Exception)
2119 prepareIdSource( elems );
2121 gp_Ax1 facetNorm( gp_Pnt( startHexPoint.x,
2124 gp_Dir( facetToSplitNormal.PS.x,
2125 facetToSplitNormal.PS.y,
2126 facetToSplitNormal.PS.z ));
2127 TIDSortedElemSet elemSet;
2128 SMESH::long_array_var anElementsId = elems->GetIDs();
2129 SMDS_MeshElement::GeomFilter filter( SMDSGeom_HEXA );
2130 arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume, &filter );
2132 ::SMESH_MeshEditor::TFacetOfElem elemFacets;
2133 while ( !elemSet.empty() )
2135 getEditor().GetHexaFacetsToSplit( elemSet, facetNorm, elemFacets );
2139 ::SMESH_MeshEditor::TFacetOfElem::iterator ef = elemFacets.begin();
2140 for ( ; ef != elemFacets.end(); ++ef )
2141 elemSet.erase( ef->first );
2144 if ( methodFlags == 2 )
2145 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_4_PRISMS );
2147 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_2_PRISMS );
2149 getEditor().SplitVolumes( elemFacets, int( methodFlags ));
2150 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2152 TPythonDump() << this << ".SplitHexahedraIntoPrisms( "
2154 << startHexPoint << ", "
2155 << facetToSplitNormal<< ", "
2156 << methodFlags<< ", "
2157 << allDomains << " )";
2159 SMESH_CATCH( SMESH::throwCorbaException );
2162 //=======================================================================
2165 //=======================================================================
2168 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
2169 const SMESH::long_array & IDsOfFixedNodes,
2170 CORBA::Long MaxNbOfIterations,
2171 CORBA::Double MaxAspectRatio,
2172 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2173 throw (SALOME::SALOME_Exception)
2175 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2176 MaxAspectRatio, Method, false );
2180 //=======================================================================
2181 //function : SmoothParametric
2183 //=======================================================================
2186 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
2187 const SMESH::long_array & IDsOfFixedNodes,
2188 CORBA::Long MaxNbOfIterations,
2189 CORBA::Double MaxAspectRatio,
2190 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2191 throw (SALOME::SALOME_Exception)
2193 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2194 MaxAspectRatio, Method, true );
2198 //=======================================================================
2199 //function : SmoothObject
2201 //=======================================================================
2204 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
2205 const SMESH::long_array & IDsOfFixedNodes,
2206 CORBA::Long MaxNbOfIterations,
2207 CORBA::Double MaxAspectRatio,
2208 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2209 throw (SALOME::SALOME_Exception)
2211 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2212 MaxAspectRatio, Method, false);
2216 //=======================================================================
2217 //function : SmoothParametricObject
2219 //=======================================================================
2222 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
2223 const SMESH::long_array & IDsOfFixedNodes,
2224 CORBA::Long MaxNbOfIterations,
2225 CORBA::Double MaxAspectRatio,
2226 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2227 throw (SALOME::SALOME_Exception)
2229 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2230 MaxAspectRatio, Method, true);
2234 //=============================================================================
2238 //=============================================================================
2241 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
2242 const SMESH::long_array & IDsOfFixedNodes,
2243 CORBA::Long MaxNbOfIterations,
2244 CORBA::Double MaxAspectRatio,
2245 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2247 throw (SALOME::SALOME_Exception)
2252 SMESHDS_Mesh* aMesh = getMeshDS();
2254 TIDSortedElemSet elements;
2255 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
2257 set<const SMDS_MeshNode*> fixedNodes;
2258 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
2259 CORBA::Long index = IDsOfFixedNodes[i];
2260 const SMDS_MeshNode * node = aMesh->FindNode(index);
2262 fixedNodes.insert( node );
2264 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
2265 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
2266 method = ::SMESH_MeshEditor::CENTROIDAL;
2268 getEditor().Smooth(elements, fixedNodes, method,
2269 MaxNbOfIterations, MaxAspectRatio, IsParametric );
2271 declareMeshModified( /*isReComputeSafe=*/true ); // does not prevent re-compute
2273 // Update Python script
2274 TPythonDump() << "isDone = " << this << "."
2275 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
2276 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
2277 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2278 << "SMESH.SMESH_MeshEditor."
2279 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2280 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2284 SMESH_CATCH( SMESH::throwCorbaException );
2288 //=============================================================================
2292 //=============================================================================
2295 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
2296 const SMESH::long_array & IDsOfFixedNodes,
2297 CORBA::Long MaxNbOfIterations,
2298 CORBA::Double MaxAspectRatio,
2299 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2301 throw (SALOME::SALOME_Exception)
2306 TPythonDump aTPythonDump; // suppress dump in smooth()
2308 prepareIdSource( theObject );
2309 SMESH::long_array_var anElementsId = theObject->GetIDs();
2310 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
2311 MaxAspectRatio, Method, IsParametric);
2313 // Update Python script
2314 aTPythonDump << "isDone = " << this << "."
2315 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
2316 << theObject << ", " << IDsOfFixedNodes << ", "
2317 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2318 << "SMESH.SMESH_MeshEditor."
2319 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2320 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2324 SMESH_CATCH( SMESH::throwCorbaException );
2328 //=============================================================================
2332 //=============================================================================
2334 void SMESH_MeshEditor_i::RenumberNodes()
2335 throw (SALOME::SALOME_Exception)
2338 // Update Python script
2339 TPythonDump() << this << ".RenumberNodes()";
2341 getMeshDS()->Renumber( true );
2343 SMESH_CATCH( SMESH::throwCorbaException );
2346 //=============================================================================
2350 //=============================================================================
2352 void SMESH_MeshEditor_i::RenumberElements()
2353 throw (SALOME::SALOME_Exception)
2356 // Update Python script
2357 TPythonDump() << this << ".RenumberElements()";
2359 getMeshDS()->Renumber( false );
2361 SMESH_CATCH( SMESH::throwCorbaException );
2364 //=======================================================================
2366 * \brief Return groups by their IDs
2368 //=======================================================================
2370 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
2371 throw (SALOME::SALOME_Exception)
2376 myMesh_i->CreateGroupServants();
2377 return myMesh_i->GetGroups( *groupIDs );
2379 SMESH_CATCH( SMESH::throwCorbaException );
2383 //=======================================================================
2384 //function : rotationSweep
2386 //=======================================================================
2388 SMESH::ListOfGroups*
2389 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
2390 const SMESH::AxisStruct & theAxis,
2391 CORBA::Double theAngleInRadians,
2392 CORBA::Long theNbOfSteps,
2393 CORBA::Double theTolerance,
2394 const bool theMakeGroups,
2395 const SMDSAbs_ElementType theElementType)
2396 throw (SALOME::SALOME_Exception)
2401 TIDSortedElemSet inElements, copyElements;
2402 arrayToSet(theIDsOfElements, getMeshDS(), inElements, theElementType);
2404 TIDSortedElemSet* workElements = & inElements;
2405 bool makeWalls=true;
2406 if ( myIsPreviewMode )
2408 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2409 getPreviewMesh( SMDSAbs_Face )->Copy( inElements, copyElements, select, avoid );
2410 workElements = & copyElements;
2411 //makeWalls = false;
2414 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
2415 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
2417 ::SMESH_MeshEditor::PGroupIDs groupIds =
2418 getEditor().RotationSweep (*workElements, Ax1, theAngleInRadians,
2419 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
2421 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2423 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2425 SMESH_CATCH( SMESH::throwCorbaException );
2429 //=======================================================================
2430 //function : RotationSweep
2432 //=======================================================================
2434 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
2435 const SMESH::AxisStruct & theAxis,
2436 CORBA::Double theAngleInRadians,
2437 CORBA::Long theNbOfSteps,
2438 CORBA::Double theTolerance)
2439 throw (SALOME::SALOME_Exception)
2441 if ( !myIsPreviewMode ) {
2442 TPythonDump() << this << ".RotationSweep( "
2443 << theIDsOfElements << ", "
2445 << TVar( theAngleInRadians ) << ", "
2446 << TVar( theNbOfSteps ) << ", "
2447 << TVar( theTolerance ) << " )";
2449 rotationSweep(theIDsOfElements,
2457 //=======================================================================
2458 //function : RotationSweepMakeGroups
2460 //=======================================================================
2462 SMESH::ListOfGroups*
2463 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2464 const SMESH::AxisStruct& theAxis,
2465 CORBA::Double theAngleInRadians,
2466 CORBA::Long theNbOfSteps,
2467 CORBA::Double theTolerance)
2468 throw (SALOME::SALOME_Exception)
2470 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2472 SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
2478 if (!myIsPreviewMode) {
2479 dumpGroupsList(aPythonDump, aGroups);
2480 aPythonDump << this << ".RotationSweepMakeGroups( "
2481 << theIDsOfElements << ", "
2483 << TVar( theAngleInRadians ) << ", "
2484 << TVar( theNbOfSteps ) << ", "
2485 << TVar( theTolerance ) << " )";
2490 //=======================================================================
2491 //function : RotationSweepObject
2493 //=======================================================================
2495 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2496 const SMESH::AxisStruct & theAxis,
2497 CORBA::Double theAngleInRadians,
2498 CORBA::Long theNbOfSteps,
2499 CORBA::Double theTolerance)
2500 throw (SALOME::SALOME_Exception)
2502 if ( !myIsPreviewMode ) {
2503 TPythonDump() << this << ".RotationSweepObject( "
2504 << theObject << ", "
2506 << theAngleInRadians << ", "
2507 << theNbOfSteps << ", "
2508 << theTolerance << " )";
2510 prepareIdSource( theObject );
2511 SMESH::long_array_var anElementsId = theObject->GetIDs();
2512 rotationSweep(anElementsId,
2520 //=======================================================================
2521 //function : RotationSweepObject1D
2523 //=======================================================================
2525 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2526 const SMESH::AxisStruct & theAxis,
2527 CORBA::Double theAngleInRadians,
2528 CORBA::Long theNbOfSteps,
2529 CORBA::Double theTolerance)
2530 throw (SALOME::SALOME_Exception)
2532 if ( !myIsPreviewMode ) {
2533 TPythonDump() << this << ".RotationSweepObject1D( "
2534 << theObject << ", "
2536 << TVar( theAngleInRadians ) << ", "
2537 << TVar( theNbOfSteps ) << ", "
2538 << TVar( theTolerance ) << " )";
2540 prepareIdSource( theObject );
2541 SMESH::long_array_var anElementsId = theObject->GetIDs();
2542 rotationSweep(anElementsId,
2551 //=======================================================================
2552 //function : RotationSweepObject2D
2554 //=======================================================================
2556 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2557 const SMESH::AxisStruct & theAxis,
2558 CORBA::Double theAngleInRadians,
2559 CORBA::Long theNbOfSteps,
2560 CORBA::Double theTolerance)
2561 throw (SALOME::SALOME_Exception)
2563 if ( !myIsPreviewMode ) {
2564 TPythonDump() << this << ".RotationSweepObject2D( "
2565 << theObject << ", "
2567 << TVar( theAngleInRadians ) << ", "
2568 << TVar( theNbOfSteps ) << ", "
2569 << TVar( theTolerance ) << " )";
2571 prepareIdSource( theObject );
2572 SMESH::long_array_var anElementsId = theObject->GetIDs();
2573 rotationSweep(anElementsId,
2582 //=======================================================================
2583 //function : RotationSweepObjectMakeGroups
2585 //=======================================================================
2587 SMESH::ListOfGroups*
2588 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2589 const SMESH::AxisStruct& theAxis,
2590 CORBA::Double theAngleInRadians,
2591 CORBA::Long theNbOfSteps,
2592 CORBA::Double theTolerance)
2593 throw (SALOME::SALOME_Exception)
2595 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2597 prepareIdSource( theObject );
2598 SMESH::long_array_var anElementsId = theObject->GetIDs();
2599 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2605 if (!myIsPreviewMode) {
2606 dumpGroupsList(aPythonDump, aGroups);
2607 aPythonDump << this << ".RotationSweepObjectMakeGroups( "
2608 << theObject << ", "
2610 << theAngleInRadians << ", "
2611 << theNbOfSteps << ", "
2612 << theTolerance << " )";
2617 //=======================================================================
2618 //function : RotationSweepObject1DMakeGroups
2620 //=======================================================================
2622 SMESH::ListOfGroups*
2623 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2624 const SMESH::AxisStruct& theAxis,
2625 CORBA::Double theAngleInRadians,
2626 CORBA::Long theNbOfSteps,
2627 CORBA::Double theTolerance)
2628 throw (SALOME::SALOME_Exception)
2630 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2632 prepareIdSource( theObject );
2633 SMESH::long_array_var anElementsId = theObject->GetIDs();
2634 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2641 if (!myIsPreviewMode) {
2642 dumpGroupsList(aPythonDump, aGroups);
2643 aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
2644 << theObject << ", "
2646 << TVar( theAngleInRadians ) << ", "
2647 << TVar( theNbOfSteps ) << ", "
2648 << TVar( theTolerance ) << " )";
2653 //=======================================================================
2654 //function : RotationSweepObject2DMakeGroups
2656 //=======================================================================
2658 SMESH::ListOfGroups*
2659 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2660 const SMESH::AxisStruct& theAxis,
2661 CORBA::Double theAngleInRadians,
2662 CORBA::Long theNbOfSteps,
2663 CORBA::Double theTolerance)
2664 throw (SALOME::SALOME_Exception)
2666 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2668 prepareIdSource( theObject );
2669 SMESH::long_array_var anElementsId = theObject->GetIDs();
2670 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2677 if (!myIsPreviewMode) {
2678 dumpGroupsList(aPythonDump, aGroups);
2679 aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
2680 << theObject << ", "
2682 << TVar( theAngleInRadians ) << ", "
2683 << TVar( theNbOfSteps ) << ", "
2684 << TVar( theTolerance ) << " )";
2690 //=======================================================================
2691 //function : extrusionSweep
2693 //=======================================================================
2695 SMESH::ListOfGroups*
2696 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
2697 const SMESH::DirStruct & theStepVector,
2698 CORBA::Long theNbOfSteps,
2700 const SMDSAbs_ElementType theElementType)
2701 throw (SALOME::SALOME_Exception)
2706 TIDSortedElemSet elements, copyElements;
2707 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
2709 const SMESH::PointStruct * P = &theStepVector.PS;
2710 gp_Vec stepVec( P->x, P->y, P->z );
2712 TIDSortedElemSet* workElements = & elements;
2714 SMDSAbs_ElementType aType = SMDSAbs_Face;
2715 if (theElementType == SMDSAbs_Node)
2717 aType = SMDSAbs_Edge;
2719 if ( myIsPreviewMode ) {
2720 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2721 getPreviewMesh( aType )->Copy( elements, copyElements, select, avoid );
2722 workElements = & copyElements;
2723 theMakeGroups = false;
2726 ::SMESH_MeshEditor::TTElemOfElemListMap aHystory;
2727 ::SMESH_MeshEditor::PGroupIDs groupIds =
2728 getEditor().ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
2730 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2732 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2734 SMESH_CATCH( SMESH::throwCorbaException );
2738 //=======================================================================
2739 //function : ExtrusionSweep
2741 //=======================================================================
2743 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
2744 const SMESH::DirStruct & theStepVector,
2745 CORBA::Long theNbOfSteps)
2746 throw (SALOME::SALOME_Exception)
2748 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
2749 if (!myIsPreviewMode) {
2750 TPythonDump() << this << ".ExtrusionSweep( "
2751 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps) << " )";
2755 //=======================================================================
2756 //function : ExtrusionSweep0D
2758 //=======================================================================
2760 void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElements,
2761 const SMESH::DirStruct & theStepVector,
2762 CORBA::Long theNbOfSteps)
2763 throw (SALOME::SALOME_Exception)
2765 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2766 if (!myIsPreviewMode) {
2767 TPythonDump() << this << ".ExtrusionSweep0D( "
2768 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps)<< " )";
2772 //=======================================================================
2773 //function : ExtrusionSweepObject
2775 //=======================================================================
2777 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2778 const SMESH::DirStruct & theStepVector,
2779 CORBA::Long theNbOfSteps)
2780 throw (SALOME::SALOME_Exception)
2782 prepareIdSource( theObject );
2783 SMESH::long_array_var anElementsId = theObject->GetIDs();
2784 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
2785 if (!myIsPreviewMode) {
2786 TPythonDump() << this << ".ExtrusionSweepObject( "
2787 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
2791 //=======================================================================
2792 //function : ExtrusionSweepObject0D
2794 //=======================================================================
2796 void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObject,
2797 const SMESH::DirStruct & theStepVector,
2798 CORBA::Long theNbOfSteps)
2799 throw (SALOME::SALOME_Exception)
2801 prepareIdSource( theObject );
2802 SMESH::long_array_var anElementsId = theObject->GetIDs();
2803 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2804 if ( !myIsPreviewMode ) {
2805 TPythonDump() << this << ".ExtrusionSweepObject0D( "
2806 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2810 //=======================================================================
2811 //function : ExtrusionSweepObject1D
2813 //=======================================================================
2815 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2816 const SMESH::DirStruct & theStepVector,
2817 CORBA::Long theNbOfSteps)
2818 throw (SALOME::SALOME_Exception)
2820 prepareIdSource( theObject );
2821 SMESH::long_array_var anElementsId = theObject->GetIDs();
2822 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
2823 if ( !myIsPreviewMode ) {
2824 TPythonDump() << this << ".ExtrusionSweepObject1D( "
2825 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2829 //=======================================================================
2830 //function : ExtrusionSweepObject2D
2832 //=======================================================================
2834 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2835 const SMESH::DirStruct & theStepVector,
2836 CORBA::Long theNbOfSteps)
2837 throw (SALOME::SALOME_Exception)
2839 prepareIdSource( theObject );
2840 SMESH::long_array_var anElementsId = theObject->GetIDs();
2841 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
2842 if ( !myIsPreviewMode ) {
2843 TPythonDump() << this << ".ExtrusionSweepObject2D( "
2844 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2848 //=======================================================================
2849 //function : ExtrusionSweepMakeGroups
2851 //=======================================================================
2853 SMESH::ListOfGroups*
2854 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2855 const SMESH::DirStruct& theStepVector,
2856 CORBA::Long theNbOfSteps)
2857 throw (SALOME::SALOME_Exception)
2859 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2861 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
2863 if (!myIsPreviewMode) {
2864 dumpGroupsList(aPythonDump, aGroups);
2865 aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
2866 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2871 //=======================================================================
2872 //function : ExtrusionSweepMakeGroups0D
2874 //=======================================================================
2876 SMESH::ListOfGroups*
2877 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups0D(const SMESH::long_array& theIDsOfElements,
2878 const SMESH::DirStruct& theStepVector,
2879 CORBA::Long theNbOfSteps)
2880 throw (SALOME::SALOME_Exception)
2882 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2884 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true,SMDSAbs_Node);
2886 if (!myIsPreviewMode) {
2887 dumpGroupsList(aPythonDump, aGroups);
2888 aPythonDump << this << ".ExtrusionSweepMakeGroups0D( " << theIDsOfElements
2889 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2894 //=======================================================================
2895 //function : ExtrusionSweepObjectMakeGroups
2897 //=======================================================================
2899 SMESH::ListOfGroups*
2900 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2901 const SMESH::DirStruct& theStepVector,
2902 CORBA::Long theNbOfSteps)
2903 throw (SALOME::SALOME_Exception)
2905 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2907 prepareIdSource( theObject );
2908 SMESH::long_array_var anElementsId = theObject->GetIDs();
2909 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
2911 if (!myIsPreviewMode) {
2912 dumpGroupsList(aPythonDump, aGroups);
2913 aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
2914 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2919 //=======================================================================
2920 //function : ExtrusionSweepObject0DMakeGroups
2922 //=======================================================================
2924 SMESH::ListOfGroups*
2925 SMESH_MeshEditor_i::ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2926 const SMESH::DirStruct& theStepVector,
2927 CORBA::Long theNbOfSteps)
2928 throw (SALOME::SALOME_Exception)
2930 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2932 prepareIdSource( theObject );
2933 SMESH::long_array_var anElementsId = theObject->GetIDs();
2934 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2935 theNbOfSteps, true, SMDSAbs_Node);
2936 if (!myIsPreviewMode) {
2937 dumpGroupsList(aPythonDump, aGroups);
2938 aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject
2939 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2944 //=======================================================================
2945 //function : ExtrusionSweepObject1DMakeGroups
2947 //=======================================================================
2949 SMESH::ListOfGroups*
2950 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2951 const SMESH::DirStruct& theStepVector,
2952 CORBA::Long theNbOfSteps)
2953 throw (SALOME::SALOME_Exception)
2955 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2957 prepareIdSource( theObject );
2958 SMESH::long_array_var anElementsId = theObject->GetIDs();
2959 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2960 theNbOfSteps, true, SMDSAbs_Edge);
2961 if (!myIsPreviewMode) {
2962 dumpGroupsList(aPythonDump, aGroups);
2963 aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
2964 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2969 //=======================================================================
2970 //function : ExtrusionSweepObject2DMakeGroups
2972 //=======================================================================
2974 SMESH::ListOfGroups*
2975 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2976 const SMESH::DirStruct& theStepVector,
2977 CORBA::Long theNbOfSteps)
2978 throw (SALOME::SALOME_Exception)
2980 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2982 prepareIdSource( theObject );
2983 SMESH::long_array_var anElementsId = theObject->GetIDs();
2984 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2985 theNbOfSteps, true, SMDSAbs_Face);
2986 if (!myIsPreviewMode) {
2987 dumpGroupsList(aPythonDump, aGroups);
2988 aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
2989 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2995 //=======================================================================
2996 //function : advancedExtrusion
2998 //=======================================================================
3000 SMESH::ListOfGroups*
3001 SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
3002 const SMESH::DirStruct & theStepVector,
3003 CORBA::Long theNbOfSteps,
3004 CORBA::Long theExtrFlags,
3005 CORBA::Double theSewTolerance,
3006 const bool theMakeGroups)
3007 throw (SALOME::SALOME_Exception)
3012 TIDSortedElemSet elements;
3013 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3015 const SMESH::PointStruct * P = &theStepVector.PS;
3016 gp_Vec stepVec( P->x, P->y, P->z );
3018 ::SMESH_MeshEditor::TTElemOfElemListMap aHystory;
3019 ::SMESH_MeshEditor::PGroupIDs groupIds =
3020 getEditor().ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
3021 theMakeGroups, theExtrFlags, theSewTolerance);
3023 declareMeshModified( /*isReComputeSafe=*/true );
3025 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3027 SMESH_CATCH( SMESH::throwCorbaException );
3031 //=======================================================================
3032 //function : AdvancedExtrusion
3034 //=======================================================================
3036 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
3037 const SMESH::DirStruct & theStepVector,
3038 CORBA::Long theNbOfSteps,
3039 CORBA::Long theExtrFlags,
3040 CORBA::Double theSewTolerance)
3041 throw (SALOME::SALOME_Exception)
3043 if ( !myIsPreviewMode ) {
3044 TPythonDump() << "stepVector = " << theStepVector;
3045 TPythonDump() << this << ".AdvancedExtrusion("
3048 << theNbOfSteps << ","
3049 << theExtrFlags << ", "
3050 << theSewTolerance << " )";
3052 advancedExtrusion( theIDsOfElements,
3060 //=======================================================================
3061 //function : AdvancedExtrusionMakeGroups
3063 //=======================================================================
3064 SMESH::ListOfGroups*
3065 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
3066 const SMESH::DirStruct& theStepVector,
3067 CORBA::Long theNbOfSteps,
3068 CORBA::Long theExtrFlags,
3069 CORBA::Double theSewTolerance)
3070 throw (SALOME::SALOME_Exception)
3072 if (!myIsPreviewMode) {
3073 TPythonDump() << "stepVector = " << theStepVector;
3075 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3077 SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
3084 if (!myIsPreviewMode) {
3085 dumpGroupsList(aPythonDump, aGroups);
3086 aPythonDump << this << ".AdvancedExtrusionMakeGroups("
3089 << theNbOfSteps << ","
3090 << theExtrFlags << ", "
3091 << theSewTolerance << " )";
3097 //================================================================================
3099 * \brief Convert extrusion error to IDL enum
3101 //================================================================================
3103 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
3105 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
3109 RETCASE( EXTR_NO_ELEMENTS );
3110 RETCASE( EXTR_PATH_NOT_EDGE );
3111 RETCASE( EXTR_BAD_PATH_SHAPE );
3112 RETCASE( EXTR_BAD_STARTING_NODE );
3113 RETCASE( EXTR_BAD_ANGLES_NUMBER );
3114 RETCASE( EXTR_CANT_GET_TANGENT );
3116 return SMESH::SMESH_MeshEditor::EXTR_OK;
3120 //=======================================================================
3121 //function : extrusionAlongPath
3123 //=======================================================================
3124 SMESH::ListOfGroups*
3125 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfElements,
3126 SMESH::SMESH_Mesh_ptr thePathMesh,
3127 GEOM::GEOM_Object_ptr thePathShape,
3128 CORBA::Long theNodeStart,
3129 CORBA::Boolean theHasAngles,
3130 const SMESH::double_array & theAngles,
3131 CORBA::Boolean theHasRefPoint,
3132 const SMESH::PointStruct & theRefPoint,
3133 const bool theMakeGroups,
3134 SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
3135 const SMDSAbs_ElementType theElementType)
3136 throw (SALOME::SALOME_Exception)
3139 MESSAGE("extrusionAlongPath");
3142 if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
3143 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3146 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3148 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3149 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3151 if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
3152 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3156 SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
3158 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3162 TIDSortedElemSet elements;
3163 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
3165 list<double> angles;
3166 for (int i = 0; i < theAngles.length(); i++) {
3167 angles.push_back( theAngles[i] );
3170 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
3172 int nbOldGroups = myMesh->NbGroup();
3174 ::SMESH_MeshEditor::Extrusion_Error error =
3175 getEditor().ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
3176 theHasAngles, angles, false,
3177 theHasRefPoint, refPnt, theMakeGroups );
3179 declareMeshModified( /*isReComputeSafe=*/true );
3180 theError = convExtrError( error );
3182 if ( theMakeGroups ) {
3183 list<int> groupIDs = myMesh->GetGroupIds();
3184 list<int>::iterator newBegin = groupIDs.begin();
3185 std::advance( newBegin, nbOldGroups ); // skip old groups
3186 groupIDs.erase( groupIDs.begin(), newBegin );
3187 return getGroups( & groupIDs );
3191 SMESH_CATCH( SMESH::throwCorbaException );
3195 //=======================================================================
3196 //function : extrusionAlongPathX
3198 //=======================================================================
3200 SMESH::ListOfGroups*
3201 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements,
3202 SMESH::SMESH_IDSource_ptr Path,
3203 CORBA::Long NodeStart,
3204 CORBA::Boolean HasAngles,
3205 const SMESH::double_array& Angles,
3206 CORBA::Boolean LinearVariation,
3207 CORBA::Boolean HasRefPoint,
3208 const SMESH::PointStruct& RefPoint,
3210 const SMDSAbs_ElementType ElementType,
3211 SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
3212 throw (SALOME::SALOME_Exception)
3215 SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
3219 list<double> angles;
3220 for (int i = 0; i < Angles.length(); i++) {
3221 angles.push_back( Angles[i] );
3223 gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
3224 int nbOldGroups = myMesh->NbGroup();
3226 if ( Path->_is_nil() ) {
3227 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3231 TIDSortedElemSet elements, copyElements;
3232 arrayToSet(IDsOfElements, getMeshDS(), elements, ElementType);
3234 TIDSortedElemSet* workElements = &elements;
3236 if ( myIsPreviewMode )
3238 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
3239 getPreviewMesh( SMDSAbs_Face )->Copy( elements, copyElements, select, avoid );
3240 workElements = & copyElements;
3244 ::SMESH_MeshEditor::Extrusion_Error error;
3246 if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path ))
3249 SMDS_MeshNode* aNodeStart =
3250 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
3251 if ( !aNodeStart ) {
3252 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3255 error = getEditor().ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
3256 HasAngles, angles, LinearVariation,
3257 HasRefPoint, refPnt, MakeGroups );
3258 declareMeshModified( /*isReComputeSafe=*/true );
3260 else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
3263 SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
3264 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
3265 SMDS_MeshNode* aNodeStart =
3266 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
3267 if ( !aNodeStart ) {
3268 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
3271 SMESH_subMesh* aSubMesh =
3272 aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
3273 error = getEditor().ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
3274 HasAngles, angles, LinearVariation,
3275 HasRefPoint, refPnt, MakeGroups );
3276 declareMeshModified( /*isReComputeSafe=*/true );
3278 else if ( SMESH::DownCast<SMESH_Group_i*>( Path ))
3280 // path as group of 1D elements
3286 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
3290 Error = convExtrError( error );
3293 list<int> groupIDs = myMesh->GetGroupIds();
3294 list<int>::iterator newBegin = groupIDs.begin();
3295 std::advance( newBegin, nbOldGroups ); // skip old groups
3296 groupIDs.erase( groupIDs.begin(), newBegin );
3297 return getGroups( & groupIDs );
3301 SMESH_CATCH( SMESH::throwCorbaException );
3305 //=======================================================================
3306 //function : ExtrusionAlongPath
3308 //=======================================================================
3310 SMESH::SMESH_MeshEditor::Extrusion_Error
3311 SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements,
3312 SMESH::SMESH_Mesh_ptr thePathMesh,
3313 GEOM::GEOM_Object_ptr thePathShape,
3314 CORBA::Long theNodeStart,
3315 CORBA::Boolean theHasAngles,
3316 const SMESH::double_array & theAngles,
3317 CORBA::Boolean theHasRefPoint,
3318 const SMESH::PointStruct & theRefPoint)
3319 throw (SALOME::SALOME_Exception)
3321 MESSAGE("ExtrusionAlongPath");
3322 if ( !myIsPreviewMode ) {
3323 TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
3324 << theIDsOfElements << ", "
3325 << thePathMesh << ", "
3326 << thePathShape << ", "
3327 << theNodeStart << ", "
3328 << theHasAngles << ", "
3329 << theAngles << ", "
3330 << theHasRefPoint << ", "
3331 << "SMESH.PointStruct( "
3332 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3333 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3334 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3336 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3337 extrusionAlongPath( theIDsOfElements,
3350 //=======================================================================
3351 //function : ExtrusionAlongPathObject
3353 //=======================================================================
3355 SMESH::SMESH_MeshEditor::Extrusion_Error
3356 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject,
3357 SMESH::SMESH_Mesh_ptr thePathMesh,
3358 GEOM::GEOM_Object_ptr thePathShape,
3359 CORBA::Long theNodeStart,
3360 CORBA::Boolean theHasAngles,
3361 const SMESH::double_array & theAngles,
3362 CORBA::Boolean theHasRefPoint,
3363 const SMESH::PointStruct & theRefPoint)
3364 throw (SALOME::SALOME_Exception)
3366 if ( !myIsPreviewMode ) {
3367 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
3368 << theObject << ", "
3369 << thePathMesh << ", "
3370 << thePathShape << ", "
3371 << theNodeStart << ", "
3372 << theHasAngles << ", "
3373 << theAngles << ", "
3374 << theHasRefPoint << ", "
3375 << "SMESH.PointStruct( "
3376 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3377 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3378 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3380 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3381 prepareIdSource( theObject );
3382 SMESH::long_array_var anElementsId = theObject->GetIDs();
3383 extrusionAlongPath( anElementsId,
3396 //=======================================================================
3397 //function : ExtrusionAlongPathObject1D
3399 //=======================================================================
3401 SMESH::SMESH_MeshEditor::Extrusion_Error
3402 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject,
3403 SMESH::SMESH_Mesh_ptr thePathMesh,
3404 GEOM::GEOM_Object_ptr thePathShape,
3405 CORBA::Long theNodeStart,
3406 CORBA::Boolean theHasAngles,
3407 const SMESH::double_array & theAngles,
3408 CORBA::Boolean theHasRefPoint,
3409 const SMESH::PointStruct & theRefPoint)
3410 throw (SALOME::SALOME_Exception)
3412 if ( !myIsPreviewMode ) {
3413 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
3414 << theObject << ", "
3415 << thePathMesh << ", "
3416 << thePathShape << ", "
3417 << theNodeStart << ", "
3418 << theHasAngles << ", "
3419 << theAngles << ", "
3420 << theHasRefPoint << ", "
3421 << "SMESH.PointStruct( "
3422 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3423 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3424 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3426 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3427 prepareIdSource( theObject );
3428 SMESH::long_array_var anElementsId = theObject->GetIDs();
3429 extrusionAlongPath( anElementsId,
3443 //=======================================================================
3444 //function : ExtrusionAlongPathObject2D
3446 //=======================================================================
3448 SMESH::SMESH_MeshEditor::Extrusion_Error
3449 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject,
3450 SMESH::SMESH_Mesh_ptr thePathMesh,
3451 GEOM::GEOM_Object_ptr thePathShape,
3452 CORBA::Long theNodeStart,
3453 CORBA::Boolean theHasAngles,
3454 const SMESH::double_array & theAngles,
3455 CORBA::Boolean theHasRefPoint,
3456 const SMESH::PointStruct & theRefPoint)
3457 throw (SALOME::SALOME_Exception)
3459 if ( !myIsPreviewMode ) {
3460 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
3461 << theObject << ", "
3462 << thePathMesh << ", "
3463 << thePathShape << ", "
3464 << theNodeStart << ", "
3465 << theHasAngles << ", "
3466 << theAngles << ", "
3467 << theHasRefPoint << ", "
3468 << "SMESH.PointStruct( "
3469 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3470 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3471 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3473 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3474 prepareIdSource( theObject );
3475 SMESH::long_array_var anElementsId = theObject->GetIDs();
3476 extrusionAlongPath( anElementsId,
3491 //=======================================================================
3492 //function : ExtrusionAlongPathMakeGroups
3494 //=======================================================================
3496 SMESH::ListOfGroups*
3497 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theIDsOfElements,
3498 SMESH::SMESH_Mesh_ptr thePathMesh,
3499 GEOM::GEOM_Object_ptr thePathShape,
3500 CORBA::Long theNodeStart,
3501 CORBA::Boolean theHasAngles,
3502 const SMESH::double_array& theAngles,
3503 CORBA::Boolean theHasRefPoint,
3504 const SMESH::PointStruct& theRefPoint,
3505 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3506 throw (SALOME::SALOME_Exception)
3508 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3510 SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements,
3520 if (!myIsPreviewMode) {
3521 bool isDumpGroups = aGroups && aGroups->length() > 0;
3523 aPythonDump << "(" << aGroups << ", error)";
3525 aPythonDump <<"error";
3527 aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
3528 << theIDsOfElements << ", "
3529 << thePathMesh << ", "
3530 << thePathShape << ", "
3531 << theNodeStart << ", "
3532 << theHasAngles << ", "
3533 << theAngles << ", "
3534 << theHasRefPoint << ", "
3535 << "SMESH.PointStruct( "
3536 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3537 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3538 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3543 //=======================================================================
3544 //function : ExtrusionAlongPathObjectMakeGroups
3546 //=======================================================================
3548 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3549 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3550 SMESH::SMESH_Mesh_ptr thePathMesh,
3551 GEOM::GEOM_Object_ptr thePathShape,
3552 CORBA::Long theNodeStart,
3553 CORBA::Boolean theHasAngles,
3554 const SMESH::double_array& theAngles,
3555 CORBA::Boolean theHasRefPoint,
3556 const SMESH::PointStruct& theRefPoint,
3557 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3558 throw (SALOME::SALOME_Exception)
3560 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3562 prepareIdSource( theObject );
3563 SMESH::long_array_var anElementsId = theObject->GetIDs();
3564 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3575 if (!myIsPreviewMode) {
3576 bool isDumpGroups = aGroups && aGroups->length() > 0;
3578 aPythonDump << "(" << aGroups << ", error)";
3580 aPythonDump <<"error";
3582 aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
3583 << theObject << ", "
3584 << thePathMesh << ", "
3585 << thePathShape << ", "
3586 << theNodeStart << ", "
3587 << theHasAngles << ", "
3588 << theAngles << ", "
3589 << theHasRefPoint << ", "
3590 << "SMESH.PointStruct( "
3591 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3592 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3593 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3598 //=======================================================================
3599 //function : ExtrusionAlongPathObject1DMakeGroups
3601 //=======================================================================
3603 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3604 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3605 SMESH::SMESH_Mesh_ptr thePathMesh,
3606 GEOM::GEOM_Object_ptr thePathShape,
3607 CORBA::Long theNodeStart,
3608 CORBA::Boolean theHasAngles,
3609 const SMESH::double_array& theAngles,
3610 CORBA::Boolean theHasRefPoint,
3611 const SMESH::PointStruct& theRefPoint,
3612 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3613 throw (SALOME::SALOME_Exception)
3615 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3617 prepareIdSource( theObject );
3618 SMESH::long_array_var anElementsId = theObject->GetIDs();
3619 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3631 if (!myIsPreviewMode) {
3632 bool isDumpGroups = aGroups && aGroups->length() > 0;
3634 aPythonDump << "(" << aGroups << ", error)";
3636 aPythonDump << "error";
3638 aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
3639 << theObject << ", "
3640 << thePathMesh << ", "
3641 << thePathShape << ", "
3642 << theNodeStart << ", "
3643 << theHasAngles << ", "
3644 << theAngles << ", "
3645 << theHasRefPoint << ", "
3646 << "SMESH.PointStruct( "
3647 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3648 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3649 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3654 //=======================================================================
3655 //function : ExtrusionAlongPathObject2DMakeGroups
3657 //=======================================================================
3659 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3660 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3661 SMESH::SMESH_Mesh_ptr thePathMesh,
3662 GEOM::GEOM_Object_ptr thePathShape,
3663 CORBA::Long theNodeStart,
3664 CORBA::Boolean theHasAngles,
3665 const SMESH::double_array& theAngles,
3666 CORBA::Boolean theHasRefPoint,
3667 const SMESH::PointStruct& theRefPoint,
3668 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3669 throw (SALOME::SALOME_Exception)
3671 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3673 prepareIdSource( theObject );
3674 SMESH::long_array_var anElementsId = theObject->GetIDs();
3675 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3687 if (!myIsPreviewMode) {
3688 bool isDumpGroups = aGroups && aGroups->length() > 0;
3690 aPythonDump << "(" << aGroups << ", error)";
3692 aPythonDump << "error";
3694 aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
3695 << theObject << ", "
3696 << thePathMesh << ", "
3697 << thePathShape << ", "
3698 << theNodeStart << ", "
3699 << theHasAngles << ", "
3700 << theAngles << ", "
3701 << theHasRefPoint << ", "
3702 << "SMESH.PointStruct( "
3703 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3704 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3705 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3710 //=======================================================================
3711 //function : ExtrusionAlongPathObjX
3713 //=======================================================================
3715 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3716 ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr Object,
3717 SMESH::SMESH_IDSource_ptr Path,
3718 CORBA::Long NodeStart,
3719 CORBA::Boolean HasAngles,
3720 const SMESH::double_array& Angles,
3721 CORBA::Boolean LinearVariation,
3722 CORBA::Boolean HasRefPoint,
3723 const SMESH::PointStruct& RefPoint,
3724 CORBA::Boolean MakeGroups,
3725 SMESH::ElementType ElemType,
3726 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3727 throw (SALOME::SALOME_Exception)
3729 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3731 prepareIdSource( Object );
3732 SMESH::long_array_var anElementsId = Object->GetIDs();
3733 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
3742 (SMDSAbs_ElementType)ElemType,
3745 if (!myIsPreviewMode) {
3746 bool isDumpGroups = aGroups && aGroups->length() > 0;
3748 aPythonDump << "(" << *aGroups << ", error)";
3750 aPythonDump << "error";
3752 aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
3755 << NodeStart << ", "
3756 << HasAngles << ", "
3757 << TVar( Angles ) << ", "
3758 << LinearVariation << ", "
3759 << HasRefPoint << ", "
3760 << "SMESH.PointStruct( "
3761 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3762 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3763 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3764 << MakeGroups << ", "
3765 << ElemType << " )";
3770 //=======================================================================
3771 //function : ExtrusionAlongPathX
3773 //=======================================================================
3775 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3776 ExtrusionAlongPathX(const SMESH::long_array& IDsOfElements,
3777 SMESH::SMESH_IDSource_ptr Path,
3778 CORBA::Long NodeStart,
3779 CORBA::Boolean HasAngles,
3780 const SMESH::double_array& Angles,
3781 CORBA::Boolean LinearVariation,
3782 CORBA::Boolean HasRefPoint,
3783 const SMESH::PointStruct& RefPoint,
3784 CORBA::Boolean MakeGroups,
3785 SMESH::ElementType ElemType,
3786 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3787 throw (SALOME::SALOME_Exception)
3789 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3791 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
3800 (SMDSAbs_ElementType)ElemType,
3803 if (!myIsPreviewMode) {
3804 bool isDumpGroups = aGroups && aGroups->length() > 0;
3806 aPythonDump << "(" << *aGroups << ", error)";
3808 aPythonDump <<"error";
3810 aPythonDump << " = " << this << ".ExtrusionAlongPathX( "
3811 << IDsOfElements << ", "
3813 << NodeStart << ", "
3814 << HasAngles << ", "
3815 << TVar( Angles ) << ", "
3816 << LinearVariation << ", "
3817 << HasRefPoint << ", "
3818 << "SMESH.PointStruct( "
3819 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3820 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3821 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3822 << MakeGroups << ", "
3823 << ElemType << " )";
3828 //================================================================================
3830 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
3831 * of given angles along path steps
3832 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
3833 * which proceeds the extrusion
3834 * \param PathShape is shape(edge); as the mesh can be complex, the edge
3835 * is used to define the sub-mesh for the path
3837 //================================================================================
3839 SMESH::double_array*
3840 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
3841 GEOM::GEOM_Object_ptr thePathShape,
3842 const SMESH::double_array & theAngles)
3844 SMESH::double_array_var aResult = new SMESH::double_array();
3845 int nbAngles = theAngles.length();
3846 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
3848 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3849 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3850 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3851 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
3852 return aResult._retn();
3853 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
3854 if ( nbSteps == nbAngles )
3856 aResult.inout() = theAngles;
3860 aResult->length( nbSteps );
3861 double rAn2St = double( nbAngles ) / double( nbSteps );
3862 double angPrev = 0, angle;
3863 for ( int iSt = 0; iSt < nbSteps; ++iSt )
3865 double angCur = rAn2St * ( iSt+1 );
3866 double angCurFloor = floor( angCur );
3867 double angPrevFloor = floor( angPrev );
3868 if ( angPrevFloor == angCurFloor )
3869 angle = rAn2St * theAngles[ int( angCurFloor ) ];
3872 int iP = int( angPrevFloor );
3873 double angPrevCeil = ceil(angPrev);
3874 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
3876 int iC = int( angCurFloor );
3877 if ( iC < nbAngles )
3878 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
3880 iP = int( angPrevCeil );
3882 angle += theAngles[ iC ];
3884 aResult[ iSt ] = angle;
3889 // Update Python script
3890 TPythonDump() << "rotAngles = " << theAngles;
3891 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
3892 << thePathMesh << ", "
3893 << thePathShape << ", "
3896 return aResult._retn();
3899 //=======================================================================
3902 //=======================================================================
3904 SMESH::ListOfGroups*
3905 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
3906 const SMESH::AxisStruct & theAxis,
3907 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3908 CORBA::Boolean theCopy,
3910 ::SMESH_Mesh* theTargetMesh)
3911 throw (SALOME::SALOME_Exception)
3916 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3917 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3919 if ( theTargetMesh )
3923 switch ( theMirrorType ) {
3924 case SMESH::SMESH_MeshEditor::POINT:
3925 aTrsf.SetMirror( P );
3927 case SMESH::SMESH_MeshEditor::AXIS:
3928 aTrsf.SetMirror( gp_Ax1( P, V ));
3931 aTrsf.SetMirror( gp_Ax2( P, V ));
3934 TIDSortedElemSet copyElements;
3935 TIDSortedElemSet* workElements = & theElements;
3937 if ( myIsPreviewMode )
3939 TPreviewMesh * tmpMesh = getPreviewMesh();
3940 tmpMesh->Copy( theElements, copyElements);
3941 if ( !theCopy && !theTargetMesh )
3943 TIDSortedElemSet elemsAround, elemsAroundCopy;
3944 getElementsAround( theElements, getMeshDS(), elemsAround );
3945 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3947 workElements = & copyElements;
3948 theMakeGroups = false;
3951 ::SMESH_MeshEditor::PGroupIDs groupIds =
3952 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3954 if ( theCopy && !myIsPreviewMode)
3956 if ( theTargetMesh )
3958 theTargetMesh->GetMeshDS()->Modified();
3962 declareMeshModified( /*isReComputeSafe=*/false );
3965 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3967 SMESH_CATCH( SMESH::throwCorbaException );
3971 //=======================================================================
3974 //=======================================================================
3976 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3977 const SMESH::AxisStruct & theAxis,
3978 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3979 CORBA::Boolean theCopy)
3980 throw (SALOME::SALOME_Exception)
3982 if ( !myIsPreviewMode ) {
3983 TPythonDump() << this << ".Mirror( "
3984 << theIDsOfElements << ", "
3986 << mirrorTypeName(theMirrorType) << ", "
3989 if ( theIDsOfElements.length() > 0 )
3991 TIDSortedElemSet elements;
3992 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3993 mirror(elements, theAxis, theMirrorType, theCopy, false);
3998 //=======================================================================
3999 //function : MirrorObject
4001 //=======================================================================
4003 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
4004 const SMESH::AxisStruct & theAxis,
4005 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
4006 CORBA::Boolean theCopy)
4007 throw (SALOME::SALOME_Exception)
4009 if ( !myIsPreviewMode ) {
4010 TPythonDump() << this << ".MirrorObject( "
4011 << theObject << ", "
4013 << mirrorTypeName(theMirrorType) << ", "
4016 TIDSortedElemSet elements;
4018 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4020 prepareIdSource( theObject );
4021 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4022 mirror(elements, theAxis, theMirrorType, theCopy, false);
4025 //=======================================================================
4026 //function : MirrorMakeGroups
4028 //=======================================================================
4030 SMESH::ListOfGroups*
4031 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
4032 const SMESH::AxisStruct& theMirror,
4033 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
4034 throw (SALOME::SALOME_Exception)
4036 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4038 SMESH::ListOfGroups * aGroups = 0;
4039 if ( theIDsOfElements.length() > 0 )
4041 TIDSortedElemSet elements;
4042 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4043 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
4045 if (!myIsPreviewMode) {
4046 dumpGroupsList(aPythonDump, aGroups);
4047 aPythonDump << this << ".MirrorMakeGroups( "
4048 << theIDsOfElements << ", "
4049 << theMirror << ", "
4050 << mirrorTypeName(theMirrorType) << " )";
4055 //=======================================================================
4056 //function : MirrorObjectMakeGroups
4058 //=======================================================================
4060 SMESH::ListOfGroups*
4061 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4062 const SMESH::AxisStruct& theMirror,
4063 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
4064 throw (SALOME::SALOME_Exception)
4066 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4068 SMESH::ListOfGroups * aGroups = 0;
4069 TIDSortedElemSet elements;
4070 prepareIdSource( theObject );
4071 if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4072 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
4074 if (!myIsPreviewMode)
4076 dumpGroupsList(aPythonDump,aGroups);
4077 aPythonDump << this << ".MirrorObjectMakeGroups( "
4078 << theObject << ", "
4079 << theMirror << ", "
4080 << mirrorTypeName(theMirrorType) << " )";
4085 //=======================================================================
4086 //function : MirrorMakeMesh
4088 //=======================================================================
4090 SMESH::SMESH_Mesh_ptr
4091 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
4092 const SMESH::AxisStruct& theMirror,
4093 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
4094 CORBA::Boolean theCopyGroups,
4095 const char* theMeshName)
4096 throw (SALOME::SALOME_Exception)
4098 SMESH_Mesh_i* mesh_i;
4099 SMESH::SMESH_Mesh_var mesh;
4100 { // open new scope to dump "MakeMesh" command
4101 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4103 TPythonDump pydump; // to prevent dump at mesh creation
4105 mesh = makeMesh( theMeshName );
4106 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4107 if (mesh_i && theIDsOfElements.length() > 0 )
4109 TIDSortedElemSet elements;
4110 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4111 mirror(elements, theMirror, theMirrorType,
4112 false, theCopyGroups, & mesh_i->GetImpl());
4113 mesh_i->CreateGroupServants();
4116 if (!myIsPreviewMode) {
4117 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
4118 << theIDsOfElements << ", "
4119 << theMirror << ", "
4120 << mirrorTypeName(theMirrorType) << ", "
4121 << theCopyGroups << ", '"
4122 << theMeshName << "' )";
4127 if (!myIsPreviewMode && mesh_i)
4128 mesh_i->GetGroups();
4130 return mesh._retn();
4133 //=======================================================================
4134 //function : MirrorObjectMakeMesh
4136 //=======================================================================
4138 SMESH::SMESH_Mesh_ptr
4139 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4140 const SMESH::AxisStruct& theMirror,
4141 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
4142 CORBA::Boolean theCopyGroups,
4143 const char* theMeshName)
4144 throw (SALOME::SALOME_Exception)
4146 SMESH_Mesh_i* mesh_i;
4147 SMESH::SMESH_Mesh_var mesh;
4148 { // open new scope to dump "MakeMesh" command
4149 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4151 TPythonDump pydump; // to prevent dump at mesh creation
4153 mesh = makeMesh( theMeshName );
4154 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4155 TIDSortedElemSet elements;
4156 prepareIdSource( theObject );
4158 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4160 mirror(elements, theMirror, theMirrorType,
4161 false, theCopyGroups, & mesh_i->GetImpl());
4162 mesh_i->CreateGroupServants();
4164 if (!myIsPreviewMode) {
4165 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
4166 << theObject << ", "
4167 << theMirror << ", "
4168 << mirrorTypeName(theMirrorType) << ", "
4169 << theCopyGroups << ", '"
4170 << theMeshName << "' )";
4175 if (!myIsPreviewMode && mesh_i)
4176 mesh_i->GetGroups();
4178 return mesh._retn();
4181 //=======================================================================
4182 //function : translate
4184 //=======================================================================
4186 SMESH::ListOfGroups*
4187 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
4188 const SMESH::DirStruct & theVector,
4189 CORBA::Boolean theCopy,
4191 ::SMESH_Mesh* theTargetMesh)
4192 throw (SALOME::SALOME_Exception)
4197 if ( theTargetMesh )
4201 const SMESH::PointStruct * P = &theVector.PS;
4202 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
4204 TIDSortedElemSet copyElements;
4205 TIDSortedElemSet* workElements = &theElements;
4207 if ( myIsPreviewMode )
4209 TPreviewMesh * tmpMesh = getPreviewMesh();
4210 tmpMesh->Copy( theElements, copyElements);
4211 if ( !theCopy && !theTargetMesh )
4213 TIDSortedElemSet elemsAround, elemsAroundCopy;
4214 getElementsAround( theElements, getMeshDS(), elemsAround );
4215 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4217 workElements = & copyElements;
4218 theMakeGroups = false;
4221 ::SMESH_MeshEditor::PGroupIDs groupIds =
4222 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4224 if ( theCopy && !myIsPreviewMode )
4226 if ( theTargetMesh )
4228 theTargetMesh->GetMeshDS()->Modified();
4232 declareMeshModified( /*isReComputeSafe=*/false );
4236 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4238 SMESH_CATCH( SMESH::throwCorbaException );
4242 //=======================================================================
4243 //function : Translate
4245 //=======================================================================
4247 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
4248 const SMESH::DirStruct & theVector,
4249 CORBA::Boolean theCopy)
4250 throw (SALOME::SALOME_Exception)
4252 if (!myIsPreviewMode) {
4253 TPythonDump() << this << ".Translate( "
4254 << theIDsOfElements << ", "
4255 << theVector << ", "
4258 if (theIDsOfElements.length()) {
4259 TIDSortedElemSet elements;
4260 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4261 translate(elements, theVector, theCopy, false);
4265 //=======================================================================
4266 //function : TranslateObject
4268 //=======================================================================
4270 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
4271 const SMESH::DirStruct & theVector,
4272 CORBA::Boolean theCopy)
4273 throw (SALOME::SALOME_Exception)
4275 if (!myIsPreviewMode) {
4276 TPythonDump() << this << ".TranslateObject( "
4277 << theObject << ", "
4278 << theVector << ", "
4281 TIDSortedElemSet elements;
4283 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4285 prepareIdSource( theObject );
4286 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4287 translate(elements, theVector, theCopy, false);
4290 //=======================================================================
4291 //function : TranslateMakeGroups
4293 //=======================================================================
4295 SMESH::ListOfGroups*
4296 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
4297 const SMESH::DirStruct& theVector)
4298 throw (SALOME::SALOME_Exception)
4300 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4302 SMESH::ListOfGroups * aGroups = 0;
4303 if (theIDsOfElements.length()) {
4304 TIDSortedElemSet elements;
4305 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4306 aGroups = translate(elements,theVector,true,true);
4308 if (!myIsPreviewMode) {
4309 dumpGroupsList(aPythonDump, aGroups);
4310 aPythonDump << this << ".TranslateMakeGroups( "
4311 << theIDsOfElements << ", "
4312 << theVector << " )";
4317 //=======================================================================
4318 //function : TranslateObjectMakeGroups
4320 //=======================================================================
4322 SMESH::ListOfGroups*
4323 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4324 const SMESH::DirStruct& theVector)
4325 throw (SALOME::SALOME_Exception)
4327 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4329 SMESH::ListOfGroups * aGroups = 0;
4330 TIDSortedElemSet elements;
4331 prepareIdSource( theObject );
4332 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4333 aGroups = translate(elements, theVector, true, true);
4335 if (!myIsPreviewMode) {
4336 dumpGroupsList(aPythonDump, aGroups);
4337 aPythonDump << this << ".TranslateObjectMakeGroups( "
4338 << theObject << ", "
4339 << theVector << " )";
4344 //=======================================================================
4345 //function : TranslateMakeMesh
4347 //=======================================================================
4349 SMESH::SMESH_Mesh_ptr
4350 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
4351 const SMESH::DirStruct& theVector,
4352 CORBA::Boolean theCopyGroups,
4353 const char* theMeshName)
4354 throw (SALOME::SALOME_Exception)
4356 SMESH_Mesh_i* mesh_i;
4357 SMESH::SMESH_Mesh_var mesh;
4359 { // open new scope to dump "MakeMesh" command
4360 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4362 TPythonDump pydump; // to prevent dump at mesh creation
4364 mesh = makeMesh( theMeshName );
4365 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4367 if ( mesh_i && theIDsOfElements.length() )
4369 TIDSortedElemSet elements;
4370 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4371 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
4372 mesh_i->CreateGroupServants();
4375 if ( !myIsPreviewMode ) {
4376 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
4377 << theIDsOfElements << ", "
4378 << theVector << ", "
4379 << theCopyGroups << ", '"
4380 << theMeshName << "' )";
4385 if (!myIsPreviewMode && mesh_i)
4386 mesh_i->GetGroups();
4388 return mesh._retn();
4391 //=======================================================================
4392 //function : TranslateObjectMakeMesh
4394 //=======================================================================
4396 SMESH::SMESH_Mesh_ptr
4397 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4398 const SMESH::DirStruct& theVector,
4399 CORBA::Boolean theCopyGroups,
4400 const char* theMeshName)
4401 throw (SALOME::SALOME_Exception)
4404 SMESH_Mesh_i* mesh_i;
4405 SMESH::SMESH_Mesh_var mesh;
4406 { // open new scope to dump "MakeMesh" command
4407 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4409 TPythonDump pydump; // to prevent dump at mesh creation
4410 mesh = makeMesh( theMeshName );
4411 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4413 TIDSortedElemSet elements;
4414 prepareIdSource( theObject );
4416 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4418 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
4419 mesh_i->CreateGroupServants();
4421 if ( !myIsPreviewMode ) {
4422 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
4423 << theObject << ", "
4424 << theVector << ", "
4425 << theCopyGroups << ", '"
4426 << theMeshName << "' )";
4431 if (!myIsPreviewMode && mesh_i)
4432 mesh_i->GetGroups();
4434 return mesh._retn();
4436 SMESH_CATCH( SMESH::throwCorbaException );
4440 //=======================================================================
4443 //=======================================================================
4445 SMESH::ListOfGroups*
4446 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
4447 const SMESH::AxisStruct & theAxis,
4448 CORBA::Double theAngle,
4449 CORBA::Boolean theCopy,
4451 ::SMESH_Mesh* theTargetMesh)
4452 throw (SALOME::SALOME_Exception)
4457 if ( theTargetMesh )
4460 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
4461 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
4464 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
4466 TIDSortedElemSet copyElements;
4467 TIDSortedElemSet* workElements = &theElements;
4468 if ( myIsPreviewMode ) {
4469 TPreviewMesh * tmpMesh = getPreviewMesh();
4470 tmpMesh->Copy( theElements, copyElements );
4471 if ( !theCopy && !theTargetMesh )
4473 TIDSortedElemSet elemsAround, elemsAroundCopy;
4474 getElementsAround( theElements, getMeshDS(), elemsAround );
4475 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4477 workElements = ©Elements;
4478 theMakeGroups = false;
4481 ::SMESH_MeshEditor::PGroupIDs groupIds =
4482 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4484 if ( theCopy && !myIsPreviewMode)
4486 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
4487 else declareMeshModified( /*isReComputeSafe=*/false );
4490 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4492 SMESH_CATCH( SMESH::throwCorbaException );
4496 //=======================================================================
4499 //=======================================================================
4501 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
4502 const SMESH::AxisStruct & theAxis,
4503 CORBA::Double theAngle,
4504 CORBA::Boolean theCopy)
4505 throw (SALOME::SALOME_Exception)
4507 if (!myIsPreviewMode) {
4508 TPythonDump() << this << ".Rotate( "
4509 << theIDsOfElements << ", "
4511 << TVar( theAngle ) << ", "
4514 if (theIDsOfElements.length() > 0)
4516 TIDSortedElemSet elements;
4517 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4518 rotate(elements,theAxis,theAngle,theCopy,false);
4522 //=======================================================================
4523 //function : RotateObject
4525 //=======================================================================
4527 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
4528 const SMESH::AxisStruct & theAxis,
4529 CORBA::Double theAngle,
4530 CORBA::Boolean theCopy)
4531 throw (SALOME::SALOME_Exception)
4533 if ( !myIsPreviewMode ) {
4534 TPythonDump() << this << ".RotateObject( "
4535 << theObject << ", "
4537 << TVar( theAngle ) << ", "
4540 TIDSortedElemSet elements;
4541 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4542 prepareIdSource( theObject );
4543 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4544 rotate(elements,theAxis,theAngle,theCopy,false);
4547 //=======================================================================
4548 //function : RotateMakeGroups
4550 //=======================================================================
4552 SMESH::ListOfGroups*
4553 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
4554 const SMESH::AxisStruct& theAxis,
4555 CORBA::Double theAngle)
4556 throw (SALOME::SALOME_Exception)
4558 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4560 SMESH::ListOfGroups * aGroups = 0;
4561 if (theIDsOfElements.length() > 0)
4563 TIDSortedElemSet elements;
4564 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4565 aGroups = rotate(elements,theAxis,theAngle,true,true);
4567 if (!myIsPreviewMode) {
4568 dumpGroupsList(aPythonDump, aGroups);
4569 aPythonDump << this << ".RotateMakeGroups( "
4570 << theIDsOfElements << ", "
4572 << TVar( theAngle ) << " )";
4577 //=======================================================================
4578 //function : RotateObjectMakeGroups
4580 //=======================================================================
4582 SMESH::ListOfGroups*
4583 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4584 const SMESH::AxisStruct& theAxis,
4585 CORBA::Double theAngle)
4586 throw (SALOME::SALOME_Exception)
4588 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4590 SMESH::ListOfGroups * aGroups = 0;
4591 TIDSortedElemSet elements;
4592 prepareIdSource( theObject );
4593 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4594 aGroups = rotate(elements, theAxis, theAngle, true, true);
4596 if (!myIsPreviewMode) {
4597 dumpGroupsList(aPythonDump, aGroups);
4598 aPythonDump << this << ".RotateObjectMakeGroups( "
4599 << theObject << ", "
4601 << TVar( theAngle ) << " )";
4606 //=======================================================================
4607 //function : RotateMakeMesh
4609 //=======================================================================
4611 SMESH::SMESH_Mesh_ptr
4612 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
4613 const SMESH::AxisStruct& theAxis,
4614 CORBA::Double theAngleInRadians,
4615 CORBA::Boolean theCopyGroups,
4616 const char* theMeshName)
4617 throw (SALOME::SALOME_Exception)
4620 SMESH::SMESH_Mesh_var mesh;
4621 SMESH_Mesh_i* mesh_i;
4623 { // open new scope to dump "MakeMesh" command
4624 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4626 TPythonDump pydump; // to prevent dump at mesh creation
4628 mesh = makeMesh( theMeshName );
4629 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4631 if ( mesh_i && theIDsOfElements.length() > 0 )
4633 TIDSortedElemSet elements;
4634 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4635 rotate(elements, theAxis, theAngleInRadians,
4636 false, theCopyGroups, & mesh_i->GetImpl());
4637 mesh_i->CreateGroupServants();
4639 if ( !myIsPreviewMode ) {
4640 pydump << mesh << " = " << this << ".RotateMakeMesh( "
4641 << theIDsOfElements << ", "
4643 << TVar( theAngleInRadians ) << ", "
4644 << theCopyGroups << ", '"
4645 << theMeshName << "' )";
4650 if (!myIsPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
4651 mesh_i->GetGroups();
4653 return mesh._retn();
4655 SMESH_CATCH( SMESH::throwCorbaException );
4659 //=======================================================================
4660 //function : RotateObjectMakeMesh
4662 //=======================================================================
4664 SMESH::SMESH_Mesh_ptr
4665 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4666 const SMESH::AxisStruct& theAxis,
4667 CORBA::Double theAngleInRadians,
4668 CORBA::Boolean theCopyGroups,
4669 const char* theMeshName)
4670 throw (SALOME::SALOME_Exception)
4673 SMESH::SMESH_Mesh_var mesh;
4674 SMESH_Mesh_i* mesh_i;
4676 {// open new scope to dump "MakeMesh" command
4677 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4679 TPythonDump pydump; // to prevent dump at mesh creation
4680 mesh = makeMesh( theMeshName );
4681 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4683 TIDSortedElemSet elements;
4684 prepareIdSource( theObject );
4686 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4688 rotate(elements, theAxis, theAngleInRadians,
4689 false, theCopyGroups, & mesh_i->GetImpl());
4690 mesh_i->CreateGroupServants();
4692 if ( !myIsPreviewMode ) {
4693 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
4694 << theObject << ", "
4696 << TVar( theAngleInRadians ) << ", "
4697 << theCopyGroups << ", '"
4698 << theMeshName << "' )";
4703 if (!myIsPreviewMode && mesh_i)
4704 mesh_i->GetGroups();
4706 return mesh._retn();
4708 SMESH_CATCH( SMESH::throwCorbaException );
4712 //=======================================================================
4715 //=======================================================================
4717 SMESH::ListOfGroups*
4718 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
4719 const SMESH::PointStruct& thePoint,
4720 const SMESH::double_array& theScaleFact,
4721 CORBA::Boolean theCopy,
4723 ::SMESH_Mesh* theTargetMesh)
4724 throw (SALOME::SALOME_Exception)
4728 if ( theScaleFact.length() < 1 )
4729 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
4730 if ( theScaleFact.length() == 2 )
4731 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
4733 if ( theTargetMesh )
4736 TIDSortedElemSet elements;
4737 prepareIdSource( theObject );
4738 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4739 if ( !idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4744 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
4745 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
4747 double tol = std::numeric_limits<double>::max();
4749 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
4750 0, S[1], 0, thePoint.y * (1-S[1]),
4751 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
4753 TIDSortedElemSet copyElements;
4754 TIDSortedElemSet* workElements = &elements;
4755 if ( myIsPreviewMode )
4757 TPreviewMesh * tmpMesh = getPreviewMesh();
4758 tmpMesh->Copy( elements, copyElements);
4759 if ( !theCopy && !theTargetMesh )
4761 TIDSortedElemSet elemsAround, elemsAroundCopy;
4762 getElementsAround( elements, getMeshDS(), elemsAround );
4763 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4765 workElements = & copyElements;
4766 theMakeGroups = false;
4769 ::SMESH_MeshEditor::PGroupIDs groupIds =
4770 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4772 if ( theCopy && !myIsPreviewMode )
4774 if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
4775 else declareMeshModified( /*isReComputeSafe=*/false );
4777 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4779 SMESH_CATCH( SMESH::throwCorbaException );
4783 //=======================================================================
4786 //=======================================================================
4788 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
4789 const SMESH::PointStruct& thePoint,
4790 const SMESH::double_array& theScaleFact,
4791 CORBA::Boolean theCopy)
4792 throw (SALOME::SALOME_Exception)
4794 if ( !myIsPreviewMode ) {
4795 TPythonDump() << this << ".Scale( "
4796 << theObject << ", "
4798 << TVar( theScaleFact ) << ", "
4801 scale(theObject, thePoint, theScaleFact, theCopy, false);
4805 //=======================================================================
4806 //function : ScaleMakeGroups
4808 //=======================================================================
4810 SMESH::ListOfGroups*
4811 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4812 const SMESH::PointStruct& thePoint,
4813 const SMESH::double_array& theScaleFact)
4814 throw (SALOME::SALOME_Exception)
4816 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4818 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
4819 if (!myIsPreviewMode) {
4820 dumpGroupsList(aPythonDump, aGroups);
4821 aPythonDump << this << ".Scale("
4824 << TVar( theScaleFact ) << ",True,True)";
4830 //=======================================================================
4831 //function : ScaleMakeMesh
4833 //=======================================================================
4835 SMESH::SMESH_Mesh_ptr
4836 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4837 const SMESH::PointStruct& thePoint,
4838 const SMESH::double_array& theScaleFact,
4839 CORBA::Boolean theCopyGroups,
4840 const char* theMeshName)
4841 throw (SALOME::SALOME_Exception)
4843 SMESH_Mesh_i* mesh_i;
4844 SMESH::SMESH_Mesh_var mesh;
4845 { // open new scope to dump "MakeMesh" command
4846 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4848 TPythonDump pydump; // to prevent dump at mesh creation
4849 mesh = makeMesh( theMeshName );
4850 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4854 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
4855 mesh_i->CreateGroupServants();
4857 if ( !myIsPreviewMode )
4858 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
4859 << theObject << ", "
4861 << TVar( theScaleFact ) << ", "
4862 << theCopyGroups << ", '"
4863 << theMeshName << "' )";
4867 if (!myIsPreviewMode && mesh_i)
4868 mesh_i->GetGroups();
4870 return mesh._retn();
4874 //=======================================================================
4875 //function : FindCoincidentNodes
4877 //=======================================================================
4879 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance,
4880 SMESH::array_of_long_array_out GroupsOfNodes)
4881 throw (SALOME::SALOME_Exception)
4886 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4887 TIDSortedNodeSet nodes; // no input nodes
4888 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4890 GroupsOfNodes = new SMESH::array_of_long_array;
4891 GroupsOfNodes->length( aListOfListOfNodes.size() );
4892 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4893 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
4894 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4895 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4896 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4897 aGroup.length( aListOfNodes.size() );
4898 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4899 aGroup[ j ] = (*lIt)->GetID();
4901 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
4902 << Tolerance << " )";
4904 SMESH_CATCH( SMESH::throwCorbaException );
4907 //=======================================================================
4908 //function : FindCoincidentNodesOnPart
4910 //=======================================================================
4912 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
4913 CORBA::Double Tolerance,
4914 SMESH::array_of_long_array_out GroupsOfNodes)
4915 throw (SALOME::SALOME_Exception)
4920 TIDSortedNodeSet nodes;
4921 prepareIdSource( theObject );
4922 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4924 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4926 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4928 GroupsOfNodes = new SMESH::array_of_long_array;
4929 GroupsOfNodes->length( aListOfListOfNodes.size() );
4930 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4931 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4933 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4934 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4935 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4936 aGroup.length( aListOfNodes.size() );
4937 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4938 aGroup[ j ] = (*lIt)->GetID();
4940 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
4942 << Tolerance << " )";
4944 SMESH_CATCH( SMESH::throwCorbaException );
4947 //================================================================================
4949 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
4950 * ExceptSubMeshOrGroups
4952 //================================================================================
4954 void SMESH_MeshEditor_i::
4955 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
4956 CORBA::Double theTolerance,
4957 SMESH::array_of_long_array_out theGroupsOfNodes,
4958 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups)
4959 throw (SALOME::SALOME_Exception)
4964 TIDSortedNodeSet nodes;
4965 prepareIdSource( theObject );
4966 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4968 for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
4970 TIDSortedNodeSet exceptNodes;
4971 idSourceToNodeSet( theExceptSubMeshOrGroups[i], getMeshDS(), exceptNodes );
4972 TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
4973 for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
4974 nodes.erase( *avoidNode );
4976 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4978 getEditor().FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
4980 theGroupsOfNodes = new SMESH::array_of_long_array;
4981 theGroupsOfNodes->length( aListOfListOfNodes.size() );
4982 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4983 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4985 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4986 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4987 SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
4988 aGroup.length( aListOfNodes.size() );
4989 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4990 aGroup[ j ] = (*lIt)->GetID();
4992 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
4994 << theTolerance << ", "
4995 << theExceptSubMeshOrGroups << " )";
4997 SMESH_CATCH( SMESH::throwCorbaException );
5000 //=======================================================================
5001 //function : MergeNodes
5003 //=======================================================================
5005 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
5006 throw (SALOME::SALOME_Exception)
5011 SMESHDS_Mesh* aMesh = getMeshDS();
5013 TPythonDump aTPythonDump;
5014 aTPythonDump << this << ".MergeNodes([";
5015 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
5016 for (int i = 0; i < GroupsOfNodes.length(); i++)
5018 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
5019 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
5020 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
5021 for ( int j = 0; j < aNodeGroup.length(); j++ )
5023 CORBA::Long index = aNodeGroup[ j ];
5024 const SMDS_MeshNode * node = aMesh->FindNode(index);
5026 aListOfNodes.push_back( node );
5028 if ( aListOfNodes.size() < 2 )
5029 aListOfListOfNodes.pop_back();
5031 if ( i > 0 ) aTPythonDump << ", ";
5032 aTPythonDump << aNodeGroup;
5034 getEditor().MergeNodes( aListOfListOfNodes );
5036 aTPythonDump << "])";
5038 declareMeshModified( /*isReComputeSafe=*/false );
5040 SMESH_CATCH( SMESH::throwCorbaException );
5043 //=======================================================================
5044 //function : FindEqualElements
5046 //=======================================================================
5048 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
5049 SMESH::array_of_long_array_out GroupsOfElementsID)
5050 throw (SALOME::SALOME_Exception)
5055 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
5056 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
5058 TIDSortedElemSet elems;
5059 prepareIdSource( theObject );
5060 idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true);
5062 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
5063 getEditor().FindEqualElements( elems, aListOfListOfElementsID );
5065 GroupsOfElementsID = new SMESH::array_of_long_array;
5066 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
5068 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt =
5069 aListOfListOfElementsID.begin();
5070 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j)
5072 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
5073 list<int>& listOfIDs = *arraysIt;
5074 aGroup.length( listOfIDs.size() );
5075 list<int>::iterator idIt = listOfIDs.begin();
5076 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k )
5077 aGroup[ k ] = *idIt;
5080 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
5084 SMESH_CATCH( SMESH::throwCorbaException );
5087 //=======================================================================
5088 //function : MergeElements
5090 //=======================================================================
5092 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
5093 throw (SALOME::SALOME_Exception)
5098 TPythonDump aTPythonDump;
5099 aTPythonDump << this << ".MergeElements( [";
5101 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
5103 for (int i = 0; i < GroupsOfElementsID.length(); i++) {
5104 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
5105 aListOfListOfElementsID.push_back( list< int >() );
5106 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
5107 for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
5108 CORBA::Long id = anElemsIDGroup[ j ];
5109 aListOfElemsID.push_back( id );
5111 if ( aListOfElemsID.size() < 2 )
5112 aListOfListOfElementsID.pop_back();
5113 if ( i > 0 ) aTPythonDump << ", ";
5114 aTPythonDump << anElemsIDGroup;
5117 getEditor().MergeElements(aListOfListOfElementsID);
5119 declareMeshModified( /*isReComputeSafe=*/true );
5121 aTPythonDump << "] )";
5123 SMESH_CATCH( SMESH::throwCorbaException );
5126 //=======================================================================
5127 //function : MergeEqualElements
5129 //=======================================================================
5131 void SMESH_MeshEditor_i::MergeEqualElements()
5132 throw (SALOME::SALOME_Exception)
5137 getEditor().MergeEqualElements();
5139 declareMeshModified( /*isReComputeSafe=*/true );
5141 TPythonDump() << this << ".MergeEqualElements()";
5143 SMESH_CATCH( SMESH::throwCorbaException );
5146 //=============================================================================
5148 * Move the node to a given point
5150 //=============================================================================
5152 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
5156 throw (SALOME::SALOME_Exception)
5159 initData(/*deleteSearchers=*/false);
5161 const SMDS_MeshNode * node = getMeshDS()->FindNode( NodeID );
5165 if ( theNodeSearcher )
5166 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5168 if ( myIsPreviewMode ) // make preview data
5170 // in a preview mesh, make edges linked to a node
5171 TPreviewMesh& tmpMesh = *getPreviewMesh();
5172 TIDSortedElemSet linkedNodes;
5173 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
5174 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
5175 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
5176 for ( ; nIt != linkedNodes.end(); ++nIt )
5178 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
5179 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
5183 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
5184 // fill preview data
5186 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
5187 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
5189 getMeshDS()->MoveNode(node, x, y, z);
5191 if ( !myIsPreviewMode )
5193 // Update Python script
5194 TPythonDump() << "isDone = " << this << ".MoveNode( "
5195 << NodeID << ", " << TVar(x) << ", " << TVar(y) << ", " << TVar(z) << " )";
5196 declareMeshModified( /*isReComputeSafe=*/false );
5199 SMESH_CATCH( SMESH::throwCorbaException );
5204 //================================================================================
5206 * \brief Return ID of node closest to a given point
5208 //================================================================================
5210 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
5213 throw (SALOME::SALOME_Exception)
5216 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5218 if ( !theNodeSearcher ) {
5219 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
5222 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
5223 return node->GetID();
5225 SMESH_CATCH( SMESH::throwCorbaException );
5229 //================================================================================
5231 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
5232 * move the node closest to the point to point's location and return ID of the node
5234 //================================================================================
5236 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
5239 CORBA::Long theNodeID)
5240 throw (SALOME::SALOME_Exception)
5243 // We keep theNodeSearcher until any mesh modification:
5244 // 1) initData() deletes theNodeSearcher at any edition,
5245 // 2) TSearchersDeleter - at any mesh compute event and mesh change
5247 initData(/*deleteSearchers=*/false);
5249 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
5251 int nodeID = theNodeID;
5252 const SMDS_MeshNode* node = getMeshDS()->FindNode( nodeID );
5253 if ( !node ) // preview moving node
5255 if ( !theNodeSearcher ) {
5256 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
5259 node = theNodeSearcher->FindClosestTo( p );
5262 nodeID = node->GetID();
5263 if ( myIsPreviewMode ) // make preview data
5265 // in a preview mesh, make edges linked to a node
5266 TPreviewMesh tmpMesh = *getPreviewMesh();
5267 TIDSortedElemSet linkedNodes;
5268 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
5269 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
5270 for ( ; nIt != linkedNodes.end(); ++nIt )
5272 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
5273 tmpMesh.Copy( &edge );
5276 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
5278 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
5279 // fill preview data
5281 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
5283 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
5287 getMeshDS()->MoveNode(node, x, y, z);
5291 if ( !myIsPreviewMode )
5293 TPythonDump() << "nodeID = " << this
5294 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
5295 << ", " << nodeID << " )";
5297 declareMeshModified( /*isReComputeSafe=*/false );
5302 SMESH_CATCH( SMESH::throwCorbaException );
5306 //=======================================================================
5308 * Return elements of given type where the given point is IN or ON.
5310 * 'ALL' type means elements of any type excluding nodes
5312 //=======================================================================
5314 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
5317 SMESH::ElementType type)
5318 throw (SALOME::SALOME_Exception)
5321 SMESH::long_array_var res = new SMESH::long_array;
5322 vector< const SMDS_MeshElement* > foundElems;
5324 theSearchersDeleter.Set( myMesh );
5325 if ( !theElementSearcher ) {
5326 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
5328 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
5329 SMDSAbs_ElementType( type ),
5331 res->length( foundElems.size() );
5332 for ( int i = 0; i < foundElems.size(); ++i )
5333 res[i] = foundElems[i]->GetID();
5337 SMESH_CATCH( SMESH::throwCorbaException );
5341 //=======================================================================
5342 //function : FindAmongElementsByPoint
5343 //purpose : Searching among the given elements, return elements of given type
5344 // where the given point is IN or ON.
5345 // 'ALL' type means elements of any type excluding nodes
5346 //=======================================================================
5349 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
5353 SMESH::ElementType type)
5354 throw (SALOME::SALOME_Exception)
5357 SMESH::long_array_var res = new SMESH::long_array;
5359 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
5360 if ( types->length() == 1 && // a part contains only nodes or 0D elements
5361 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) &&
5362 type != types[0] ) // but search of elements of dim > 0
5365 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
5366 return FindElementsByPoint( x,y,z, type );
5368 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
5370 theSearchersDeleter.Set( myMesh, getPartIOR( elementIDs, type ));
5371 if ( !theElementSearcher )
5373 // create a searcher from elementIDs
5374 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
5375 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
5377 if ( !idSourceToSet( elementIDs, meshDS, elements,
5378 SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
5381 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5382 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
5384 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt );
5387 vector< const SMDS_MeshElement* > foundElems;
5389 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
5390 SMDSAbs_ElementType( type ),
5392 res->length( foundElems.size() );
5393 for ( int i = 0; i < foundElems.size(); ++i )
5394 res[i] = foundElems[i]->GetID();
5398 SMESH_CATCH( SMESH::throwCorbaException );
5402 //=======================================================================
5403 //function : GetPointState
5404 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
5405 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
5406 //=======================================================================
5408 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
5411 throw (SALOME::SALOME_Exception)
5414 theSearchersDeleter.Set( myMesh );
5415 if ( !theElementSearcher ) {
5416 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
5418 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
5420 SMESH_CATCH( SMESH::throwCorbaException );
5424 //=======================================================================
5425 //function : convError
5427 //=======================================================================
5429 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
5431 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
5435 RETCASE( SEW_BORDER1_NOT_FOUND );
5436 RETCASE( SEW_BORDER2_NOT_FOUND );
5437 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
5438 RETCASE( SEW_BAD_SIDE_NODES );
5439 RETCASE( SEW_VOLUMES_TO_SPLIT );
5440 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
5441 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
5442 RETCASE( SEW_BAD_SIDE1_NODES );
5443 RETCASE( SEW_BAD_SIDE2_NODES );
5445 return SMESH::SMESH_MeshEditor::SEW_OK;
5448 //=======================================================================
5449 //function : SewFreeBorders
5451 //=======================================================================
5453 SMESH::SMESH_MeshEditor::Sew_Error
5454 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
5455 CORBA::Long SecondNodeID1,
5456 CORBA::Long LastNodeID1,
5457 CORBA::Long FirstNodeID2,
5458 CORBA::Long SecondNodeID2,
5459 CORBA::Long LastNodeID2,
5460 CORBA::Boolean CreatePolygons,
5461 CORBA::Boolean CreatePolyedrs)
5462 throw (SALOME::SALOME_Exception)
5467 SMESHDS_Mesh* aMesh = getMeshDS();
5469 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
5470 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
5471 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
5472 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
5473 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
5474 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
5476 if (!aBorderFirstNode ||
5477 !aBorderSecondNode||
5479 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5480 if (!aSide2FirstNode ||
5481 !aSide2SecondNode ||
5483 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
5485 TPythonDump() << "error = " << this << ".SewFreeBorders( "
5486 << FirstNodeID1 << ", "
5487 << SecondNodeID1 << ", "
5488 << LastNodeID1 << ", "
5489 << FirstNodeID2 << ", "
5490 << SecondNodeID2 << ", "
5491 << LastNodeID2 << ", "
5492 << CreatePolygons<< ", "
5493 << CreatePolyedrs<< " )";
5495 SMESH::SMESH_MeshEditor::Sew_Error error =
5496 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5507 declareMeshModified( /*isReComputeSafe=*/false );
5510 SMESH_CATCH( SMESH::throwCorbaException );
5511 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5515 //=======================================================================
5516 //function : SewConformFreeBorders
5518 //=======================================================================
5520 SMESH::SMESH_MeshEditor::Sew_Error
5521 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
5522 CORBA::Long SecondNodeID1,
5523 CORBA::Long LastNodeID1,
5524 CORBA::Long FirstNodeID2,
5525 CORBA::Long SecondNodeID2)
5526 throw (SALOME::SALOME_Exception)
5531 SMESHDS_Mesh* aMesh = getMeshDS();
5533 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
5534 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
5535 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
5536 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
5537 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
5538 const SMDS_MeshNode* aSide2ThirdNode = 0;
5540 if (!aBorderFirstNode ||
5541 !aBorderSecondNode||
5543 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5544 if (!aSide2FirstNode ||
5546 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
5548 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
5549 << FirstNodeID1 << ", "
5550 << SecondNodeID1 << ", "
5551 << LastNodeID1 << ", "
5552 << FirstNodeID2 << ", "
5553 << SecondNodeID2 << " )";
5555 SMESH::SMESH_MeshEditor::Sew_Error error =
5556 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5565 declareMeshModified( /*isReComputeSafe=*/false );
5568 SMESH_CATCH( SMESH::throwCorbaException );
5569 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5573 //=======================================================================
5574 //function : SewBorderToSide
5576 //=======================================================================
5578 SMESH::SMESH_MeshEditor::Sew_Error
5579 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
5580 CORBA::Long SecondNodeIDOnFreeBorder,
5581 CORBA::Long LastNodeIDOnFreeBorder,
5582 CORBA::Long FirstNodeIDOnSide,
5583 CORBA::Long LastNodeIDOnSide,
5584 CORBA::Boolean CreatePolygons,
5585 CORBA::Boolean CreatePolyedrs)
5586 throw (SALOME::SALOME_Exception)
5591 SMESHDS_Mesh* aMesh = getMeshDS();
5593 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
5594 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
5595 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
5596 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
5597 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
5598 const SMDS_MeshNode* aSide2ThirdNode = 0;
5600 if (!aBorderFirstNode ||
5601 !aBorderSecondNode||
5603 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5604 if (!aSide2FirstNode ||
5606 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
5608 TPythonDump() << "error = " << this << ".SewBorderToSide( "
5609 << FirstNodeIDOnFreeBorder << ", "
5610 << SecondNodeIDOnFreeBorder << ", "
5611 << LastNodeIDOnFreeBorder << ", "
5612 << FirstNodeIDOnSide << ", "
5613 << LastNodeIDOnSide << ", "
5614 << CreatePolygons << ", "
5615 << CreatePolyedrs << ") ";
5617 SMESH::SMESH_MeshEditor::Sew_Error error =
5618 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5628 declareMeshModified( /*isReComputeSafe=*/false );
5631 SMESH_CATCH( SMESH::throwCorbaException );
5632 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5636 //=======================================================================
5637 //function : SewSideElements
5639 //=======================================================================
5641 SMESH::SMESH_MeshEditor::Sew_Error
5642 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
5643 const SMESH::long_array& IDsOfSide2Elements,
5644 CORBA::Long NodeID1OfSide1ToMerge,
5645 CORBA::Long NodeID1OfSide2ToMerge,
5646 CORBA::Long NodeID2OfSide1ToMerge,
5647 CORBA::Long NodeID2OfSide2ToMerge)
5648 throw (SALOME::SALOME_Exception)
5653 SMESHDS_Mesh* aMesh = getMeshDS();
5655 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
5656 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
5657 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
5658 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
5660 if (!aFirstNode1ToMerge ||
5661 !aFirstNode2ToMerge )
5662 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
5663 if (!aSecondNode1ToMerge||
5664 !aSecondNode2ToMerge)
5665 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
5667 TIDSortedElemSet aSide1Elems, aSide2Elems;
5668 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
5669 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
5671 TPythonDump() << "error = " << this << ".SewSideElements( "
5672 << IDsOfSide1Elements << ", "
5673 << IDsOfSide2Elements << ", "
5674 << NodeID1OfSide1ToMerge << ", "
5675 << NodeID1OfSide2ToMerge << ", "
5676 << NodeID2OfSide1ToMerge << ", "
5677 << NodeID2OfSide2ToMerge << ")";
5679 SMESH::SMESH_MeshEditor::Sew_Error error =
5680 convError( getEditor().SewSideElements (aSide1Elems, aSide2Elems,
5683 aSecondNode1ToMerge,
5684 aSecondNode2ToMerge));
5686 declareMeshModified( /*isReComputeSafe=*/false );
5689 SMESH_CATCH( SMESH::throwCorbaException );
5690 return SMESH::SMESH_MeshEditor::Sew_Error(0);
5693 //================================================================================
5695 * \brief Set new nodes for given element
5696 * \param ide - element id
5697 * \param newIDs - new node ids
5698 * \retval CORBA::Boolean - true if result is OK
5700 //================================================================================
5702 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
5703 const SMESH::long_array& newIDs)
5704 throw (SALOME::SALOME_Exception)
5709 const SMDS_MeshElement* elem = getMeshDS()->FindElement(ide);
5710 if(!elem) return false;
5712 int nbn = newIDs.length();
5714 vector<const SMDS_MeshNode*> aNodes(nbn);
5717 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(newIDs[i]);
5720 aNodes[nbn1] = aNode;
5723 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
5724 << ide << ", " << newIDs << " )";
5726 MESSAGE("ChangeElementNodes");
5727 bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
5729 declareMeshModified( /*isReComputeSafe=*/ !res );
5733 SMESH_CATCH( SMESH::throwCorbaException );
5737 //=======================================================================
5739 * \brief Makes a part of the mesh quadratic or bi-quadratic
5741 //=======================================================================
5743 void SMESH_MeshEditor_i::convertToQuadratic(CORBA::Boolean theForce3d,
5744 CORBA::Boolean theToBiQuad,
5745 SMESH::SMESH_IDSource_ptr theObject)
5746 throw (SALOME::SALOME_Exception)
5749 TIDSortedElemSet elems;
5751 if ( !( elemsOK = CORBA::is_nil( theObject )))
5753 prepareIdSource( theObject );
5754 elemsOK = idSourceToSet( theObject, getMeshDS(), elems,
5755 SMDSAbs_All, /*emptyIfIsMesh=*/true );
5759 if ( !elems.empty() && (*elems.begin())->GetType() == SMDSAbs_Node )
5760 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5762 if ( elems.empty() ) getEditor().ConvertToQuadratic(theForce3d, theToBiQuad);
5763 else getEditor().ConvertToQuadratic(theForce3d, elems, theToBiQuad);
5765 declareMeshModified( /*isReComputeSafe=*/false );
5768 SMESH_CATCH( SMESH::throwCorbaException );
5771 //=======================================================================
5772 //function : ConvertFromQuadratic
5774 //=======================================================================
5776 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
5777 throw (SALOME::SALOME_Exception)
5779 CORBA::Boolean isDone = getEditor().ConvertFromQuadratic();
5780 TPythonDump() << this << ".ConvertFromQuadratic()";
5781 declareMeshModified( /*isReComputeSafe=*/!isDone );
5785 //=======================================================================
5786 //function : ConvertToQuadratic
5788 //=======================================================================
5790 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
5791 throw (SALOME::SALOME_Exception)
5793 convertToQuadratic( theForce3d, false );
5794 TPythonDump() << this << ".ConvertToQuadratic("<<theForce3d<<")";
5797 //================================================================================
5799 * \brief Makes a part of the mesh quadratic
5801 //================================================================================
5803 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
5804 SMESH::SMESH_IDSource_ptr theObject)
5805 throw (SALOME::SALOME_Exception)
5807 convertToQuadratic( theForce3d, false, theObject );
5808 TPythonDump() << this << ".ConvertToQuadraticObject("<<theForce3d<<", "<<theObject<<")";
5811 //================================================================================
5813 * \brief Makes a part of the mesh bi-quadratic
5815 //================================================================================
5817 void SMESH_MeshEditor_i::ConvertToBiQuadratic(CORBA::Boolean theForce3d,
5818 SMESH::SMESH_IDSource_ptr theObject)
5819 throw (SALOME::SALOME_Exception)
5821 convertToQuadratic( theForce3d, true, theObject );
5822 TPythonDump() << this << ".ConvertToBiQuadratic("<<theForce3d<<", "<<theObject<<")";
5825 //================================================================================
5827 * \brief Makes a part of the mesh linear
5829 //================================================================================
5831 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
5832 throw (SALOME::SALOME_Exception)
5838 TIDSortedElemSet elems;
5839 prepareIdSource( theObject );
5840 if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5842 if ( elems.empty() )
5844 ConvertFromQuadratic();
5846 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5848 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5852 getEditor().ConvertFromQuadratic(elems);
5855 declareMeshModified( /*isReComputeSafe=*/false );
5857 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
5859 SMESH_CATCH( SMESH::throwCorbaException );
5862 //=======================================================================
5863 //function : makeMesh
5864 //purpose : create a named imported mesh
5865 //=======================================================================
5867 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
5869 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
5870 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
5871 SALOMEDS::Study_var study = gen->GetCurrentStudy();
5872 SALOMEDS::SObject_wrap meshSO = gen->ObjectToSObject( study, mesh );
5873 gen->SetName( meshSO, theMeshName, "Mesh" );
5874 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
5876 return mesh._retn();
5879 //=======================================================================
5880 //function : dumpGroupsList
5882 //=======================================================================
5884 void SMESH_MeshEditor_i::dumpGroupsList(TPythonDump & theDumpPython,
5885 const SMESH::ListOfGroups * theGroupList)
5887 bool isDumpGroupList = ( theGroupList && theGroupList->length() > 0 );
5888 if ( isDumpGroupList )
5889 theDumpPython << theGroupList << " = ";
5892 //================================================================================
5894 \brief Generates the unique group name.
5895 \param thePrefix name prefix
5898 //================================================================================
5900 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
5902 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5903 set<string> groupNames;
5905 // Get existing group names
5906 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
5907 SMESH::SMESH_GroupBase_var aGroup = groups[i];
5908 if (CORBA::is_nil(aGroup))
5911 CORBA::String_var name = aGroup->GetName();
5912 groupNames.insert( name.in() );
5916 string name = thePrefix;
5919 while (!groupNames.insert(name).second)
5920 name = SMESH_Comment( thePrefix ) << "_" << index++;
5925 //================================================================================
5927 * \brief Prepare SMESH_IDSource for work
5929 //================================================================================
5931 void SMESH_MeshEditor_i::prepareIdSource(SMESH::SMESH_IDSource_ptr theObject)
5933 if ( SMESH::Filter_i* filter = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5935 SMESH::SMESH_Mesh_var mesh = myMesh_i->_this();
5936 filter->SetMesh( mesh );
5940 //================================================================================
5942 * \brief Duplicates given elements, i.e. creates new elements based on the
5943 * same nodes as the given ones.
5944 * \param theElements - container of elements to duplicate.
5945 * \param theGroupName - a name of group to contain the generated elements.
5946 * If a group with such a name already exists, the new elements
5947 * are added to the existng group, else a new group is created.
5948 * If \a theGroupName is empty, new elements are not added
5950 * \return a group where the new elements are added. NULL if theGroupName == "".
5953 //================================================================================
5955 SMESH::SMESH_Group_ptr
5956 SMESH_MeshEditor_i::DoubleElements(SMESH::SMESH_IDSource_ptr theElements,
5957 const char* theGroupName)
5958 throw (SALOME::SALOME_Exception)
5960 SMESH::SMESH_Group_var newGroup;
5967 TIDSortedElemSet elems;
5968 prepareIdSource( theElements );
5969 if ( idSourceToSet( theElements, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true))
5971 getEditor().DoubleElements( elems );
5973 if ( strlen( theGroupName ) && !getEditor().GetLastCreatedElems().IsEmpty() )
5976 SMESH::ElementType type =
5977 SMESH::ElementType( getEditor().GetLastCreatedElems().Value(1)->GetType() );
5978 // find existing group
5979 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5980 for ( size_t i = 0; i < groups->length(); ++i )
5981 if ( groups[i]->GetType() == type )
5983 CORBA::String_var name = groups[i]->GetName();
5984 if ( strcmp( name, theGroupName ) == 0 ) {
5985 newGroup = SMESH::SMESH_Group::_narrow( groups[i] );
5989 // create a new group
5990 if ( newGroup->_is_nil() )
5991 newGroup = myMesh_i->CreateGroup( type, theGroupName );
5993 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* >( newGroup ))
5995 SMESHDS_Group* groupDS = static_cast< SMESHDS_Group* >( group_i->GetGroupDS() );
5996 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
5997 for ( int i = 1; i <= aSeq.Length(); i++ )
5998 groupDS->SMDSGroup().Add( aSeq(i) );
6003 if ( !newGroup->_is_nil() )
6004 pyDump << newGroup << " = ";
6005 pyDump << this << ".DoubleElements( "
6006 << theElements << ", " << "'" << theGroupName <<"')";
6008 SMESH_CATCH( SMESH::throwCorbaException );
6010 return newGroup._retn();
6013 //================================================================================
6015 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6016 \param theNodes - identifiers of nodes to be doubled
6017 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
6018 nodes. If list of element identifiers is empty then nodes are doubled but
6019 they not assigned to elements
6020 \return TRUE if operation has been completed successfully, FALSE otherwise
6021 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
6023 //================================================================================
6025 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
6026 const SMESH::long_array& theModifiedElems )
6027 throw (SALOME::SALOME_Exception)
6032 list< int > aListOfNodes;
6034 for ( i = 0, n = theNodes.length(); i < n; i++ )
6035 aListOfNodes.push_back( theNodes[ i ] );
6037 list< int > aListOfElems;
6038 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
6039 aListOfElems.push_back( theModifiedElems[ i ] );
6041 bool aResult = getEditor().DoubleNodes( aListOfNodes, aListOfElems );
6043 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6045 // Update Python script
6046 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
6050 SMESH_CATCH( SMESH::throwCorbaException );
6054 //================================================================================
6056 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6057 This method provided for convenience works as DoubleNodes() described above.
6058 \param theNodeId - identifier of node to be doubled.
6059 \param theModifiedElems - identifiers of elements to be updated.
6060 \return TRUE if operation has been completed successfully, FALSE otherwise
6061 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
6063 //================================================================================
6065 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
6066 const SMESH::long_array& theModifiedElems )
6067 throw (SALOME::SALOME_Exception)
6070 SMESH::long_array_var aNodes = new SMESH::long_array;
6071 aNodes->length( 1 );
6072 aNodes[ 0 ] = theNodeId;
6074 TPythonDump pyDump; // suppress dump by the next line
6076 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
6078 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
6082 SMESH_CATCH( SMESH::throwCorbaException );
6086 //================================================================================
6088 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6089 This method provided for convenience works as DoubleNodes() described above.
6090 \param theNodes - group of nodes to be doubled.
6091 \param theModifiedElems - group of elements to be updated.
6092 \return TRUE if operation has been completed successfully, FALSE otherwise
6093 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
6095 //================================================================================
6097 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
6098 SMESH::SMESH_GroupBase_ptr theModifiedElems )
6099 throw (SALOME::SALOME_Exception)
6102 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
6105 SMESH::long_array_var aNodes = theNodes->GetListOfID();
6106 SMESH::long_array_var aModifiedElems;
6107 if ( !CORBA::is_nil( theModifiedElems ) )
6108 aModifiedElems = theModifiedElems->GetListOfID();
6111 aModifiedElems = new SMESH::long_array;
6112 aModifiedElems->length( 0 );
6115 TPythonDump pyDump; // suppress dump by the next line
6117 bool done = DoubleNodes( aNodes, aModifiedElems );
6119 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
6123 SMESH_CATCH( SMESH::throwCorbaException );
6127 //================================================================================
6129 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6130 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
6131 * \param theNodes - group of nodes to be doubled.
6132 * \param theModifiedElems - group of elements to be updated.
6133 * \return a new group with newly created nodes
6134 * \sa DoubleNodeGroup()
6136 //================================================================================
6138 SMESH::SMESH_Group_ptr
6139 SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
6140 SMESH::SMESH_GroupBase_ptr theModifiedElems )
6141 throw (SALOME::SALOME_Exception)
6144 SMESH::SMESH_Group_var aNewGroup;
6146 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
6147 return aNewGroup._retn();
6150 SMESH::long_array_var aNodes = theNodes->GetListOfID();
6151 SMESH::long_array_var aModifiedElems;
6152 if ( !CORBA::is_nil( theModifiedElems ) )
6153 aModifiedElems = theModifiedElems->GetListOfID();
6155 aModifiedElems = new SMESH::long_array;
6156 aModifiedElems->length( 0 );
6159 TPythonDump pyDump; // suppress dump by the next line
6161 bool aResult = DoubleNodes( aNodes, aModifiedElems );
6164 // Create group with newly created nodes
6165 SMESH::long_array_var anIds = GetLastCreatedNodes();
6166 if (anIds->length() > 0) {
6167 string anUnindexedName (theNodes->GetName());
6168 string aNewName = generateGroupName(anUnindexedName + "_double");
6169 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6170 aNewGroup->Add(anIds);
6171 pyDump << aNewGroup << " = ";
6175 pyDump << this << ".DoubleNodeGroupNew( " << theNodes << ", "
6176 << theModifiedElems << " )";
6178 return aNewGroup._retn();
6180 SMESH_CATCH( SMESH::throwCorbaException );
6184 //================================================================================
6186 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6187 This method provided for convenience works as DoubleNodes() described above.
6188 \param theNodes - list of groups of nodes to be doubled
6189 \param theModifiedElems - list of groups of elements to be updated.
6190 \return TRUE if operation has been completed successfully, FALSE otherwise
6191 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
6193 //================================================================================
6195 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
6196 const SMESH::ListOfGroups& theModifiedElems )
6197 throw (SALOME::SALOME_Exception)
6202 std::list< int > aNodes;
6204 for ( i = 0, n = theNodes.length(); i < n; i++ )
6206 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
6207 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
6209 SMESH::long_array_var aCurr = aGrp->GetListOfID();
6210 for ( j = 0, m = aCurr->length(); j < m; j++ )
6211 aNodes.push_back( aCurr[ j ] );
6215 std::list< int > anElems;
6216 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
6218 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
6219 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
6221 SMESH::long_array_var aCurr = aGrp->GetListOfID();
6222 for ( j = 0, m = aCurr->length(); j < m; j++ )
6223 anElems.push_back( aCurr[ j ] );
6227 bool aResult = getEditor().DoubleNodes( aNodes, anElems );
6229 declareMeshModified( /*isReComputeSafe=*/false );
6231 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
6235 SMESH_CATCH( SMESH::throwCorbaException );
6239 //================================================================================
6241 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6242 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
6243 * \param theNodes - group of nodes to be doubled.
6244 * \param theModifiedElems - group of elements to be updated.
6245 * \return a new group with newly created nodes
6246 * \sa DoubleNodeGroups()
6248 //================================================================================
6250 SMESH::SMESH_Group_ptr
6251 SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
6252 const SMESH::ListOfGroups& theModifiedElems )
6253 throw (SALOME::SALOME_Exception)
6255 SMESH::SMESH_Group_var aNewGroup;
6257 TPythonDump pyDump; // suppress dump by the next line
6259 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
6263 // Create group with newly created nodes
6264 SMESH::long_array_var anIds = GetLastCreatedNodes();
6265 if (anIds->length() > 0) {
6266 string anUnindexedName (theNodes[0]->GetName());
6267 string aNewName = generateGroupName(anUnindexedName + "_double");
6268 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6269 aNewGroup->Add(anIds);
6270 pyDump << aNewGroup << " = ";
6274 pyDump << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
6275 << theModifiedElems << " )";
6277 return aNewGroup._retn();
6281 //================================================================================
6283 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6284 \param theElems - the list of elements (edges or faces) to be replicated
6285 The nodes for duplication could be found from these elements
6286 \param theNodesNot - list of nodes to NOT replicate
6287 \param theAffectedElems - the list of elements (cells and edges) to which the
6288 replicated nodes should be associated to.
6289 \return TRUE if operation has been completed successfully, FALSE otherwise
6290 \sa DoubleNodeGroup(), DoubleNodeGroups()
6292 //================================================================================
6294 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
6295 const SMESH::long_array& theNodesNot,
6296 const SMESH::long_array& theAffectedElems )
6297 throw (SALOME::SALOME_Exception)
6302 SMESHDS_Mesh* aMeshDS = getMeshDS();
6303 TIDSortedElemSet anElems, aNodes, anAffected;
6304 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
6305 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
6306 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
6308 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6310 // Update Python script
6311 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
6312 << theNodesNot << ", " << theAffectedElems << " )";
6314 declareMeshModified( /*isReComputeSafe=*/false );
6317 SMESH_CATCH( SMESH::throwCorbaException );
6321 //================================================================================
6323 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6324 \param theElems - the list of elements (edges or faces) to be replicated
6325 The nodes for duplication could be found from these elements
6326 \param theNodesNot - list of nodes to NOT replicate
6327 \param theShape - shape to detect affected elements (element which geometric center
6328 located on or inside shape).
6329 The replicated nodes should be associated to affected elements.
6330 \return TRUE if operation has been completed successfully, FALSE otherwise
6331 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
6333 //================================================================================
6335 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
6336 const SMESH::long_array& theNodesNot,
6337 GEOM::GEOM_Object_ptr theShape )
6338 throw (SALOME::SALOME_Exception)
6344 SMESHDS_Mesh* aMeshDS = getMeshDS();
6345 TIDSortedElemSet anElems, aNodes;
6346 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
6347 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
6349 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6350 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6352 // Update Python script
6353 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
6354 << theNodesNot << ", " << theShape << " )";
6356 declareMeshModified( /*isReComputeSafe=*/false );
6359 SMESH_CATCH( SMESH::throwCorbaException );
6363 //================================================================================
6365 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6366 \param theElems - group of of elements (edges or faces) to be replicated
6367 \param theNodesNot - group of nodes not to replicated
6368 \param theAffectedElems - group of elements to which the replicated nodes
6369 should be associated to.
6370 \return TRUE if operation has been completed successfully, FALSE otherwise
6371 \sa DoubleNodes(), DoubleNodeGroups()
6373 //================================================================================
6376 SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
6377 SMESH::SMESH_GroupBase_ptr theNodesNot,
6378 SMESH::SMESH_GroupBase_ptr theAffectedElems)
6379 throw (SALOME::SALOME_Exception)
6382 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6388 SMESHDS_Mesh* aMeshDS = getMeshDS();
6389 TIDSortedElemSet anElems, aNodes, anAffected;
6390 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6391 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6392 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
6394 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6396 // Update Python script
6397 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
6398 << theNodesNot << ", " << theAffectedElems << " )";
6400 declareMeshModified( /*isReComputeSafe=*/false );
6403 SMESH_CATCH( SMESH::throwCorbaException );
6407 //================================================================================
6409 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6410 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
6411 * \param theElems - group of of elements (edges or faces) to be replicated
6412 * \param theNodesNot - group of nodes not to replicated
6413 * \param theAffectedElems - group of elements to which the replicated nodes
6414 * should be associated to.
6415 * \return a new group with newly created elements
6416 * \sa DoubleNodeElemGroup()
6418 //================================================================================
6420 SMESH::SMESH_Group_ptr
6421 SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
6422 SMESH::SMESH_GroupBase_ptr theNodesNot,
6423 SMESH::SMESH_GroupBase_ptr theAffectedElems)
6424 throw (SALOME::SALOME_Exception)
6427 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroup2New( theElems,
6431 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
6432 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
6434 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupNew( "
6436 << theNodesNot << ", "
6437 << theAffectedElems << " )";
6439 return elemGroup._retn();
6442 //================================================================================
6444 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6445 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
6446 * \param theElems - group of of elements (edges or faces) to be replicated
6447 * \param theNodesNot - group of nodes not to replicated
6448 * \param theAffectedElems - group of elements to which the replicated nodes
6449 * should be associated to.
6450 * \return a new group with newly created elements
6451 * \sa DoubleNodeElemGroup()
6453 //================================================================================
6455 SMESH::ListOfGroups*
6456 SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
6457 SMESH::SMESH_GroupBase_ptr theNodesNot,
6458 SMESH::SMESH_GroupBase_ptr theAffectedElems,
6459 CORBA::Boolean theElemGroupNeeded,
6460 CORBA::Boolean theNodeGroupNeeded)
6461 throw (SALOME::SALOME_Exception)
6464 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
6465 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
6466 aTwoGroups->length( 2 );
6468 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6469 return aTwoGroups._retn();
6474 SMESHDS_Mesh* aMeshDS = getMeshDS();
6475 TIDSortedElemSet anElems, aNodes, anAffected;
6476 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6477 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6478 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
6481 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6483 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6489 // Create group with newly created elements
6490 CORBA::String_var elemGroupName = theElems->GetName();
6491 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
6492 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
6494 SMESH::long_array_var anIds = GetLastCreatedElems();
6495 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
6496 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
6497 aNewElemGroup->Add(anIds);
6499 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
6501 SMESH::long_array_var anIds = GetLastCreatedNodes();
6502 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6503 aNewNodeGroup->Add(anIds);
6507 // Update Python script
6510 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
6511 else pyDump << aNewElemGroup << ", ";
6512 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
6513 else pyDump << aNewNodeGroup << " ] = ";
6515 pyDump << this << ".DoubleNodeElemGroup2New( " << theElems << ", "
6516 << theNodesNot << ", "
6517 << theAffectedElems << ", "
6518 << theElemGroupNeeded << ", "
6519 << theNodeGroupNeeded <<" )";
6521 aTwoGroups[0] = aNewElemGroup._retn();
6522 aTwoGroups[1] = aNewNodeGroup._retn();
6523 return aTwoGroups._retn();
6525 SMESH_CATCH( SMESH::throwCorbaException );
6529 //================================================================================
6531 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6532 \param theElems - group of of elements (edges or faces) to be replicated
6533 \param theNodesNot - group of nodes not to replicated
6534 \param theShape - shape to detect affected elements (element which geometric center
6535 located on or inside shape).
6536 The replicated nodes should be associated to affected elements.
6537 \return TRUE if operation has been completed successfully, FALSE otherwise
6538 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
6540 //================================================================================
6543 SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
6544 SMESH::SMESH_GroupBase_ptr theNodesNot,
6545 GEOM::GEOM_Object_ptr theShape )
6546 throw (SALOME::SALOME_Exception)
6549 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
6555 SMESHDS_Mesh* aMeshDS = getMeshDS();
6556 TIDSortedElemSet anElems, aNodes, anAffected;
6557 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
6558 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
6560 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6561 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6564 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6566 // Update Python script
6567 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
6568 << theNodesNot << ", " << theShape << " )";
6571 SMESH_CATCH( SMESH::throwCorbaException );
6575 //================================================================================
6577 * \brief Re-load elements from a list of groups into a TIDSortedElemSet
6578 * \param [in] theGrpList - groups
6579 * \param [in] theMeshDS - mesh
6580 * \param [out] theElemSet - set of elements
6581 * \param [in] theIsNodeGrp - is \a theGrpList includes goups of nodes
6583 //================================================================================
6585 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
6586 SMESHDS_Mesh* theMeshDS,
6587 TIDSortedElemSet& theElemSet,
6588 const bool theIsNodeGrp)
6590 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
6592 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
6593 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
6594 : aGrp->GetType() != SMESH::NODE ) )
6596 SMESH::long_array_var anIDs = aGrp->GetIDs();
6597 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
6602 //================================================================================
6604 \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
6605 This method provided for convenience works as DoubleNodes() described above.
6606 \param theElems - list of groups of elements (edges or faces) to be replicated
6607 \param theNodesNot - list of groups of nodes not to replicated
6608 \param theAffectedElems - group of elements to which the replicated nodes
6609 should be associated to.
6610 \return TRUE if operation has been completed successfully, FALSE otherwise
6611 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
6613 //================================================================================
6616 SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
6617 const SMESH::ListOfGroups& theNodesNot,
6618 const SMESH::ListOfGroups& theAffectedElems)
6619 throw (SALOME::SALOME_Exception)
6625 SMESHDS_Mesh* aMeshDS = getMeshDS();
6626 TIDSortedElemSet anElems, aNodes, anAffected;
6627 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6628 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6629 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6631 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6633 // Update Python script
6634 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
6635 << &theNodesNot << ", " << &theAffectedElems << " )";
6637 declareMeshModified( /*isReComputeSafe=*/false );
6640 SMESH_CATCH( SMESH::throwCorbaException );
6644 //================================================================================
6646 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6647 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6648 \param theElems - list of groups of elements (edges or faces) to be replicated
6649 \param theNodesNot - list of groups of nodes not to replicated
6650 \param theAffectedElems - group of elements to which the replicated nodes
6651 should be associated to.
6652 * \return a new group with newly created elements
6653 * \sa DoubleNodeElemGroups()
6655 //================================================================================
6657 SMESH::SMESH_Group_ptr
6658 SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
6659 const SMESH::ListOfGroups& theNodesNot,
6660 const SMESH::ListOfGroups& theAffectedElems)
6661 throw (SALOME::SALOME_Exception)
6664 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroups2New( theElems,
6668 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
6669 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
6671 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupsNew( "
6673 << theNodesNot << ", "
6674 << theAffectedElems << " )";
6676 return elemGroup._retn();
6679 //================================================================================
6681 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6682 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
6683 \param theElems - list of groups of elements (edges or faces) to be replicated
6684 \param theNodesNot - list of groups of nodes not to replicated
6685 \param theAffectedElems - group of elements to which the replicated nodes
6686 should be associated to.
6687 * \return a new group with newly created elements
6688 * \sa DoubleNodeElemGroups()
6690 //================================================================================
6692 SMESH::ListOfGroups*
6693 SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems,
6694 const SMESH::ListOfGroups& theNodesNot,
6695 const SMESH::ListOfGroups& theAffectedElems,
6696 CORBA::Boolean theElemGroupNeeded,
6697 CORBA::Boolean theNodeGroupNeeded)
6698 throw (SALOME::SALOME_Exception)
6701 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
6702 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
6703 aTwoGroups->length( 2 );
6708 SMESHDS_Mesh* aMeshDS = getMeshDS();
6709 TIDSortedElemSet anElems, aNodes, anAffected;
6710 listOfGroupToSet(theElems, aMeshDS, anElems, false );
6711 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6712 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
6714 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
6716 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6721 // Create group with newly created elements
6722 CORBA::String_var elemGroupName = theElems[0]->GetName();
6723 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
6724 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
6726 SMESH::long_array_var anIds = GetLastCreatedElems();
6727 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
6728 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
6729 aNewElemGroup->Add(anIds);
6731 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
6733 SMESH::long_array_var anIds = GetLastCreatedNodes();
6734 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
6735 aNewNodeGroup->Add(anIds);
6739 // Update Python script
6742 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
6743 else pyDump << aNewElemGroup << ", ";
6744 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
6745 else pyDump << aNewNodeGroup << " ] = ";
6747 pyDump << this << ".DoubleNodeElemGroups2New( " << &theElems << ", "
6748 << &theNodesNot << ", "
6749 << &theAffectedElems << ", "
6750 << theElemGroupNeeded << ", "
6751 << theNodeGroupNeeded << " )";
6753 aTwoGroups[0] = aNewElemGroup._retn();
6754 aTwoGroups[1] = aNewNodeGroup._retn();
6755 return aTwoGroups._retn();
6757 SMESH_CATCH( SMESH::throwCorbaException );
6761 //================================================================================
6763 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6764 This method provided for convenience works as DoubleNodes() described above.
6765 \param theElems - list of groups of elements (edges or faces) to be replicated
6766 \param theNodesNot - list of groups of nodes not to replicated
6767 \param theShape - shape to detect affected elements (element which geometric center
6768 located on or inside shape).
6769 The replicated nodes should be associated to affected elements.
6770 \return TRUE if operation has been completed successfully, FALSE otherwise
6771 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
6773 //================================================================================
6776 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
6777 const SMESH::ListOfGroups& theNodesNot,
6778 GEOM::GEOM_Object_ptr theShape )
6779 throw (SALOME::SALOME_Exception)
6785 SMESHDS_Mesh* aMeshDS = getMeshDS();
6786 TIDSortedElemSet anElems, aNodes;
6787 listOfGroupToSet(theElems, aMeshDS, anElems,false );
6788 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6790 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6791 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6793 // Update Python script
6794 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
6795 << &theNodesNot << ", " << theShape << " )";
6797 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6800 SMESH_CATCH( SMESH::throwCorbaException );
6804 //================================================================================
6806 \brief Identify the elements that will be affected by node duplication (actual
6807 duplication is not performed.
6808 This method is the first step of DoubleNodeElemGroupsInRegion.
6809 \param theElems - list of groups of elements (edges or faces) to be replicated
6810 \param theNodesNot - list of groups of nodes not to replicated
6811 \param theShape - shape to detect affected elements (element which geometric center
6812 located on or inside shape).
6813 The replicated nodes should be associated to affected elements.
6814 \return groups of affected elements
6815 \sa DoubleNodeElemGroupsInRegion()
6817 //================================================================================
6818 SMESH::ListOfGroups*
6819 SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theElems,
6820 const SMESH::ListOfGroups& theNodesNot,
6821 GEOM::GEOM_Object_ptr theShape )
6822 throw (SALOME::SALOME_Exception)
6825 MESSAGE("AffectedElemGroupsInRegion");
6826 SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
6827 bool isEdgeGroup = false;
6828 bool isFaceGroup = false;
6829 bool isVolumeGroup = false;
6830 SMESH::SMESH_Group_var aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE, "affectedEdges");
6831 SMESH::SMESH_Group_var aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE, "affectedFaces");
6832 SMESH::SMESH_Group_var aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME, "affectedVolumes");
6836 ::SMESH_MeshEditor aMeshEditor(myMesh);
6838 SMESHDS_Mesh* aMeshDS = getMeshDS();
6839 TIDSortedElemSet anElems, aNodes;
6840 listOfGroupToSet(theElems, aMeshDS, anElems, false);
6841 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true);
6843 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape(theShape);
6844 TIDSortedElemSet anAffected;
6845 bool aResult = aMeshEditor.AffectedElemGroupsInRegion(anElems, aNodes, aShape, anAffected);
6848 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6853 int lg = anAffected.size();
6854 MESSAGE("lg="<< lg);
6855 SMESH::long_array_var volumeIds = new SMESH::long_array;
6856 volumeIds->length(lg);
6857 SMESH::long_array_var faceIds = new SMESH::long_array;
6858 faceIds->length(lg);
6859 SMESH::long_array_var edgeIds = new SMESH::long_array;
6860 edgeIds->length(lg);
6865 TIDSortedElemSet::const_iterator eIt = anAffected.begin();
6866 for (; eIt != anAffected.end(); ++eIt)
6868 const SMDS_MeshElement* anElem = *eIt;
6871 int elemId = anElem->GetID();
6872 if (myMesh->GetElementType(elemId, true) == SMDSAbs_Volume)
6873 volumeIds[ivol++] = elemId;
6874 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Face)
6875 faceIds[iface++] = elemId;
6876 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Edge)
6877 edgeIds[iedge++] = elemId;
6879 volumeIds->length(ivol);
6880 faceIds->length(iface);
6881 edgeIds->length(iedge);
6883 aNewVolumeGroup->Add(volumeIds);
6884 aNewFaceGroup->Add(faceIds);
6885 aNewEdgeGroup->Add(edgeIds);
6886 isVolumeGroup = (aNewVolumeGroup->Size() > 0);
6887 isFaceGroup = (aNewFaceGroup->Size() > 0);
6888 isEdgeGroup = (aNewEdgeGroup->Size() > 0);
6892 if (isEdgeGroup) nbGroups++;
6893 if (isFaceGroup) nbGroups++;
6894 if (isVolumeGroup) nbGroups++;
6895 aListOfGroups->length(nbGroups);
6898 if (isEdgeGroup) aListOfGroups[i++] = aNewEdgeGroup._retn();
6899 if (isFaceGroup) aListOfGroups[i++] = aNewFaceGroup._retn();
6900 if (isVolumeGroup) aListOfGroups[i++] = aNewVolumeGroup._retn();
6902 // Update Python script
6905 if (isEdgeGroup) pyDump << aNewEdgeGroup << ", ";
6906 if (isFaceGroup) pyDump << aNewFaceGroup << ", ";
6907 if (isVolumeGroup) pyDump << aNewVolumeGroup << ", ";
6909 pyDump << this << ".AffectedElemGroupsInRegion( "
6910 << &theElems << ", " << &theNodesNot << ", " << theShape << " )";
6912 return aListOfGroups._retn();
6914 SMESH_CATCH( SMESH::throwCorbaException );
6918 //================================================================================
6920 \brief Generated skin mesh (containing 2D cells) from 3D mesh
6921 The created 2D mesh elements based on nodes of free faces of boundary volumes
6922 \return TRUE if operation has been completed successfully, FALSE otherwise
6924 //================================================================================
6926 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
6927 throw (SALOME::SALOME_Exception)
6932 bool aResult = getEditor().Make2DMeshFrom3D();
6934 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
6936 declareMeshModified( /*isReComputeSafe=*/ !aResult );
6939 SMESH_CATCH( SMESH::throwCorbaException );
6943 //================================================================================
6945 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
6946 * The list of groups must contain at least two groups. The groups have to be disjoint:
6947 * no common element into two different groups.
6948 * The nodes of the internal faces at the boundaries of the groups are doubled.
6949 * Optionally, the internal faces are replaced by flat elements.
6950 * Triangles are transformed into prisms, and quadrangles into hexahedrons.
6951 * The flat elements are stored in groups of volumes.
6952 * These groups are named according to the position of the group in the list:
6953 * 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.
6954 * 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.
6955 * All the flat elements are gathered into the group named "joints3D" (or "joints2D" in 2D situation).
6956 * The flat element of the multiple junctions between the simple junction are stored in a group named "jointsMultiples".
6957 * \param theDomains - list of groups of volumes
6958 * \param createJointElems - if TRUE, create the elements
6959 * \param onAllBoundaries - if TRUE, the nodes and elements are also created on
6960 * the boundary between \a theDomains and the rest mesh
6961 * \return TRUE if operation has been completed successfully, FALSE otherwise
6963 //================================================================================
6966 SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
6967 CORBA::Boolean createJointElems,
6968 CORBA::Boolean onAllBoundaries )
6969 throw (SALOME::SALOME_Exception)
6976 SMESHDS_Mesh* aMeshDS = getMeshDS();
6978 // MESSAGE("theDomains.length = "<<theDomains.length());
6979 if ( theDomains.length() <= 1 && !onAllBoundaries )
6980 THROW_SALOME_CORBA_EXCEPTION("At least 2 groups are required.", SALOME::BAD_PARAM);
6982 vector<TIDSortedElemSet> domains;
6983 domains.resize( theDomains.length() );
6985 for ( int i = 0, n = theDomains.length(); i < n; i++ )
6987 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
6988 if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
6990 // if ( aGrp->GetType() != SMESH::VOLUME )
6991 // THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
6992 SMESH::long_array_var anIDs = aGrp->GetIDs();
6993 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
6997 isOK = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems, onAllBoundaries );
6998 // TODO publish the groups of flat elements in study
7000 declareMeshModified( /*isReComputeSafe=*/ !isOK );
7002 // Update Python script
7003 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
7004 << ", " << createJointElems << ", " << onAllBoundaries << " )";
7006 SMESH_CATCH( SMESH::throwCorbaException );
7008 myMesh_i->CreateGroupServants(); // publish created groups if any
7013 //================================================================================
7015 * \brief Double nodes on some external faces and create flat elements.
7016 * Flat elements are mainly used by some types of mechanic calculations.
7018 * Each group of the list must be constituted of faces.
7019 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
7020 * @param theGroupsOfFaces - list of groups of faces
7021 * @return TRUE if operation has been completed successfully, FALSE otherwise
7023 //================================================================================
7026 SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
7027 throw (SALOME::SALOME_Exception)
7032 SMESHDS_Mesh* aMeshDS = getMeshDS();
7034 vector<TIDSortedElemSet> faceGroups;
7037 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
7039 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
7040 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
7042 TIDSortedElemSet faceGroup;
7044 faceGroups.push_back(faceGroup);
7045 SMESH::long_array_var anIDs = aGrp->GetIDs();
7046 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
7050 bool aResult = getEditor().CreateFlatElementsOnFacesGroups( faceGroups );
7051 // TODO publish the groups of flat elements in study
7053 declareMeshModified( /*isReComputeSafe=*/ !aResult );
7055 // Update Python script
7056 TPythonDump() << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
7059 SMESH_CATCH( SMESH::throwCorbaException );
7063 //================================================================================
7065 * \brief Identify all the elements around a geom shape, get the faces delimiting
7068 * Build groups of volume to remove, groups of faces to replace on the skin of the
7069 * object, groups of faces to remove inside the object, (idem edges).
7070 * Build ordered list of nodes at the border of each group of faces to replace
7071 * (to be used to build a geom subshape).
7073 //================================================================================
7075 void SMESH_MeshEditor_i::CreateHoleSkin(CORBA::Double radius,
7076 GEOM::GEOM_Object_ptr theShape,
7077 const char* groupName,
7078 const SMESH::double_array& theNodesCoords,
7079 SMESH::array_of_long_array_out GroupsOfNodes)
7080 throw (SALOME::SALOME_Exception)
7085 std::vector<std::vector<int> > aListOfListOfNodes;
7086 ::SMESH_MeshEditor aMeshEditor( myMesh );
7088 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
7089 if ( !theNodeSearcher )
7090 theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
7092 vector<double> nodesCoords;
7093 for (int i = 0; i < theNodesCoords.length(); i++)
7095 nodesCoords.push_back( theNodesCoords[i] );
7098 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
7099 aMeshEditor.CreateHoleSkin(radius, aShape, theNodeSearcher, groupName,
7100 nodesCoords, aListOfListOfNodes);
7102 GroupsOfNodes = new SMESH::array_of_long_array;
7103 GroupsOfNodes->length( aListOfListOfNodes.size() );
7104 std::vector<std::vector<int> >::iterator llIt = aListOfListOfNodes.begin();
7105 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
7107 vector<int>& aListOfNodes = *llIt;
7108 vector<int>::iterator lIt = aListOfNodes.begin();;
7109 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
7110 aGroup.length( aListOfNodes.size() );
7111 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
7112 aGroup[ j ] = (*lIt);
7114 TPythonDump() << "lists_nodes = " << this << ".CreateHoleSkin( "
7117 << ", '" << groupName << "', "
7118 << theNodesCoords << " )";
7120 SMESH_CATCH( SMESH::throwCorbaException );
7123 // issue 20749 ===================================================================
7125 * \brief Creates missing boundary elements
7126 * \param elements - elements whose boundary is to be checked
7127 * \param dimension - defines type of boundary elements to create
7128 * \param groupName - a name of group to store created boundary elements in,
7129 * "" means not to create the group
7130 * \param meshName - a name of new mesh to store created boundary elements in,
7131 * "" means not to create the new mesh
7132 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
7133 * \param toCopyExistingBondary - if true, not only new but also pre-existing
7134 * boundary elements will be copied into the new mesh
7135 * \param group - returns the create group, if any
7136 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
7138 // ================================================================================
7140 SMESH::SMESH_Mesh_ptr
7141 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
7142 SMESH::Bnd_Dimension dim,
7143 const char* groupName,
7144 const char* meshName,
7145 CORBA::Boolean toCopyElements,
7146 CORBA::Boolean toCopyExistingBondary,
7147 SMESH::SMESH_Group_out group)
7148 throw (SALOME::SALOME_Exception)
7153 if ( dim > SMESH::BND_1DFROM2D )
7154 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
7156 SMESHDS_Mesh* aMeshDS = getMeshDS();
7158 SMESH::SMESH_Mesh_var mesh_var;
7159 SMESH::SMESH_Group_var group_var;
7163 TIDSortedElemSet elements;
7164 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
7165 prepareIdSource( idSource );
7166 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
7170 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
7171 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
7173 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
7175 // group of new boundary elements
7176 SMESH_Group* smesh_group = 0;
7177 if ( strlen(groupName) )
7179 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
7180 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
7181 smesh_group = group_i->GetSmeshGroup();
7185 getEditor().MakeBoundaryMesh( elements,
7186 ::SMESH_MeshEditor::Bnd_Dimension(dim),
7190 toCopyExistingBondary);
7193 smesh_mesh->GetMeshDS()->Modified();
7196 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
7198 // result of MakeBoundaryMesh() is a tuple (mesh, group)
7199 if ( mesh_var->_is_nil() )
7200 pyDump << myMesh_i->_this() << ", ";
7202 pyDump << mesh_var << ", ";
7203 if ( group_var->_is_nil() )
7204 pyDump << "_NoneGroup = "; // assignment to None is forbiden
7206 pyDump << group_var << " = ";
7207 pyDump << this << ".MakeBoundaryMesh( "
7209 << "SMESH." << dimName[int(dim)] << ", "
7210 << "'" << groupName << "', "
7211 << "'" << meshName<< "', "
7212 << toCopyElements << ", "
7213 << toCopyExistingBondary << ")";
7215 group = group_var._retn();
7216 return mesh_var._retn();
7218 SMESH_CATCH( SMESH::throwCorbaException );
7219 return SMESH::SMESH_Mesh::_nil();
7222 //================================================================================
7224 * \brief Creates missing boundary elements
7225 * \param dimension - defines type of boundary elements to create
7226 * \param groupName - a name of group to store all boundary elements in,
7227 * "" means not to create the group
7228 * \param meshName - a name of a new mesh, which is a copy of the initial
7229 * mesh + created boundary elements; "" means not to create the new mesh
7230 * \param toCopyAll - if true, the whole initial mesh will be copied into
7231 * the new mesh else only boundary elements will be copied into the new mesh
7232 * \param groups - optional groups of elements to make boundary around
7233 * \param mesh - returns the mesh where elements were added to
7234 * \param group - returns the created group, if any
7235 * \retval long - number of added boundary elements
7237 //================================================================================
7239 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
7240 const char* groupName,
7241 const char* meshName,
7242 CORBA::Boolean toCopyAll,
7243 const SMESH::ListOfIDSources& groups,
7244 SMESH::SMESH_Mesh_out mesh,
7245 SMESH::SMESH_Group_out group)
7246 throw (SALOME::SALOME_Exception)
7251 if ( dim > SMESH::BND_1DFROM2D )
7252 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
7254 // separate groups belonging to this and other mesh
7255 SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
7256 SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
7257 groupsOfThisMesh->length( groups.length() );
7258 groupsOfOtherMesh->length( groups.length() );
7259 int nbGroups = 0, nbGroupsOfOtherMesh = 0;
7260 for ( int i = 0; i < groups.length(); ++i )
7262 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
7263 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
7264 groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
7266 groupsOfThisMesh[ nbGroups++ ] = groups[i];
7267 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
7268 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
7270 groupsOfThisMesh->length( nbGroups );
7271 groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
7276 if ( nbGroupsOfOtherMesh > 0 )
7278 // process groups belonging to another mesh
7279 SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
7280 SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
7281 nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
7282 groupsOfOtherMesh, mesh, group );
7285 SMESH::SMESH_Mesh_var mesh_var;
7286 SMESH::SMESH_Group_var group_var;
7289 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
7290 const bool toCopyMesh = ( strlen( meshName ) > 0 );
7294 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
7296 /*toCopyGroups=*/false,
7297 /*toKeepIDs=*/true);
7299 mesh_var = makeMesh(meshName);
7301 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
7302 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
7305 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
7306 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
7308 // group of boundary elements
7309 SMESH_Group* smesh_group = 0;
7310 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
7311 if ( strlen(groupName) )
7313 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
7314 group_var = mesh_i->CreateGroup( groupType, groupName );
7315 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
7316 smesh_group = group_i->GetSmeshGroup();
7319 TIDSortedElemSet elements;
7321 if ( groups.length() > 0 )
7323 for ( int i = 0; i < nbGroups; ++i )
7326 if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
7328 SMESH::Bnd_Dimension bdim =
7329 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
7330 nbAdded += getEditor().MakeBoundaryMesh( elements,
7331 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
7334 /*toCopyElements=*/false,
7335 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
7336 /*toAddExistingBondary=*/true,
7337 /*aroundElements=*/true);
7343 nbAdded += getEditor().MakeBoundaryMesh( elements,
7344 ::SMESH_MeshEditor::Bnd_Dimension(dim),
7347 /*toCopyElements=*/false,
7348 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
7349 /*toAddExistingBondary=*/true);
7351 tgtMesh->GetMeshDS()->Modified();
7353 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
7355 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
7356 pyDump << "nbAdded, ";
7357 if ( mesh_var->_is_nil() )
7358 pyDump << myMesh_i->_this() << ", ";
7360 pyDump << mesh_var << ", ";
7361 if ( group_var->_is_nil() )
7362 pyDump << "_NoneGroup = "; // assignment to None is forbiden
7364 pyDump << group_var << " = ";
7365 pyDump << this << ".MakeBoundaryElements( "
7366 << "SMESH." << dimName[int(dim)] << ", "
7367 << "'" << groupName << "', "
7368 << "'" << meshName<< "', "
7369 << toCopyAll << ", "
7372 mesh = mesh_var._retn();
7373 group = group_var._retn();
7376 SMESH_CATCH( SMESH::throwCorbaException );