1 // Copyright (C) 2007-2019 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_SetIterator.hxx"
46 #include "SMDS_VolumeTool.hxx"
47 #include "SMESHDS_Group.hxx"
48 #include "SMESHDS_GroupOnGeom.hxx"
49 #include "SMESH_ControlsDef.hxx"
50 #include "SMESH_Filter_i.hxx"
51 #include "SMESH_Gen_i.hxx"
52 #include "SMESH_Group.hxx"
53 #include "SMESH_Group_i.hxx"
54 #include "SMESH_MeshAlgos.hxx"
55 #include "SMESH_MeshPartDS.hxx"
56 #include "SMESH_MesherHelper.hxx"
57 #include "SMESH_PythonDump.hxx"
58 #include "SMESH_subMeshEventListener.hxx"
59 #include "SMESH_subMesh_i.hxx"
61 #include <utilities.h>
62 #include <Utils_ExceptHandlers.hxx>
63 #include <Utils_CorbaException.hxx>
64 #include <SALOMEDS_wrap.hxx>
65 #include <SALOME_GenericObj_i.hh>
67 #include <BRepAdaptor_Surface.hxx>
68 #include <BRep_Tool.hxx>
69 #include <TopExp_Explorer.hxx>
71 #include <TopoDS_Edge.hxx>
72 #include <TopoDS_Face.hxx>
77 #include <Standard_Failure.hxx>
78 #include <Standard_ErrorHandler.hxx>
83 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
85 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
88 using SMESH::TPythonDump;
91 namespace MeshEditor_I {
93 //=============================================================================
95 * \brief Mesh to apply modifications for preview purposes
97 //=============================================================================
99 struct TPreviewMesh: public SMESH_Mesh
101 SMDSAbs_ElementType myPreviewType; // type to show
103 TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
104 _isShapeToMesh = (_id = 0);
105 _myMeshDS = new SMESHDS_Mesh( _id, true );
106 myPreviewType = previewElements;
108 //!< Copy a set of elements
109 void Copy(const TIDSortedElemSet & theElements,
110 TIDSortedElemSet& theCopyElements,
111 SMDSAbs_ElementType theSelectType = SMDSAbs_All,
112 SMDSAbs_ElementType theAvoidType = SMDSAbs_All)
114 // loop on theIDsOfElements
115 TIDSortedElemSet::const_iterator eIt = theElements.begin();
116 for ( ; eIt != theElements.end(); ++eIt )
118 const SMDS_MeshElement* anElem = *eIt;
119 if ( !anElem ) continue;
120 SMDSAbs_ElementType type = anElem->GetType();
121 if ( type == theAvoidType ||
122 ( theSelectType != SMDSAbs_All && type != theSelectType ))
124 const SMDS_MeshElement* anElemCopy;
125 if ( type == SMDSAbs_Node)
126 anElemCopy = Copy( cast2Node(anElem) );
128 anElemCopy = Copy( anElem );
130 theCopyElements.insert( theCopyElements.end(), anElemCopy );
134 SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
136 // copy element nodes
137 int anElemNbNodes = anElem->NbNodes();
138 vector< int > anElemNodesID( anElemNbNodes ) ;
139 SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
140 for ( int i = 0; itElemNodes->more(); i++)
142 const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
144 anElemNodesID[i] = anElemNode->GetID();
147 // creates a corresponding element on copied nodes
148 ::SMESH_MeshEditor::ElemFeatures elemType;
149 elemType.Init( anElem, /*basicOnly=*/false );
150 elemType.SetID( anElem->GetID() );
151 SMDS_MeshElement* anElemCopy =
152 ::SMESH_MeshEditor(this).AddElement( anElemNodesID, elemType );
156 SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
158 return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(),
159 anElemNode->GetID());
163 GetMeshDS()->ClearMesh();
165 void Remove( SMDSAbs_ElementType type )
167 Remove( GetMeshDS()->elementsIterator( type ));
169 void Remove( SMDS_ElemIteratorPtr eIt )
171 while ( eIt->more() )
172 GetMeshDS()->RemoveFreeElement( eIt->next(), /*sm=*/0, /*fromGroups=*/false );
174 };// struct TPreviewMesh
176 static SMESH_NodeSearcher * theNodeSearcher = 0;
177 static SMESH_ElementSearcher * theElementSearcher = 0;
179 //=============================================================================
181 * \brief Deleter of theNodeSearcher and theElementSearcher at any compute event occurred
183 //=============================================================================
185 struct TSearchersDeleter : public SMESH_subMeshEventListener
188 string myMeshPartIOR;
190 TSearchersDeleter(): SMESH_subMeshEventListener( false, // won't be deleted by submesh
191 "SMESH_MeshEditor_i::TSearchersDeleter"),
193 //!< Delete theNodeSearcher
196 if ( theNodeSearcher ) delete theNodeSearcher; theNodeSearcher = 0;
197 if ( theElementSearcher ) delete theElementSearcher; theElementSearcher = 0;
199 typedef map < int, SMESH_subMesh * > TDependsOnMap;
200 //!< The meshod called by submesh: do my main job
201 void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
202 SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
204 if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
206 Unset( sm->GetFather() );
209 //!< set self on all submeshes and delete theNodeSearcher if other mesh is set
210 void Set(SMESH_Mesh* mesh, const string& meshPartIOR = string())
212 if ( myMesh != mesh || myMeshPartIOR != meshPartIOR)
219 myMeshPartIOR = meshPartIOR;
220 SMESH_subMesh* sm = mesh->GetSubMesh( mesh->GetShapeToMesh() );
221 SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true );
222 while ( smIt->more() )
225 sm->SetEventListener( this, 0, sm );
229 //!< delete self from all submeshes
230 void Unset(SMESH_Mesh* mesh)
232 if ( SMESH_subMesh* sm = mesh->GetSubMeshContaining(1) ) {
233 SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator( /*includeSelf=*/true );
234 while ( smIt->more() )
235 smIt->next()->DeleteEventListener( this );
240 } theSearchersDeleter;
242 TCollection_AsciiString mirrorTypeName( SMESH::SMESH_MeshEditor::MirrorType theMirrorType )
244 TCollection_AsciiString typeStr;
245 switch ( theMirrorType ) {
246 case SMESH::SMESH_MeshEditor::POINT:
247 typeStr = "SMESH.SMESH_MeshEditor.POINT";
249 case SMESH::SMESH_MeshEditor::AXIS:
250 typeStr = "SMESH.SMESH_MeshEditor.AXIS";
253 typeStr = "SMESH.SMESH_MeshEditor.PLANE";
257 //================================================================================
259 * \brief function for conversion of long_array to TIDSortedElemSet
260 * \param IDs - array of IDs
261 * \param aMesh - mesh
262 * \param aMap - collection to fill
263 * \param aType - element type
265 //================================================================================
267 void arrayToSet(const SMESH::long_array & IDs,
268 const SMESHDS_Mesh* aMesh,
269 TIDSortedElemSet& aMap,
270 const SMDSAbs_ElementType aType = SMDSAbs_All,
271 SMDS_MeshElement::Filter* aFilter = NULL)
273 SMDS_MeshElement::NonNullFilter filter1;
274 SMDS_MeshElement::TypeFilter filter2( aType );
276 if ( aFilter == NULL )
277 aFilter = ( aType == SMDSAbs_All ) ? (SMDS_MeshElement::Filter*) &filter1 : (SMDS_MeshElement::Filter*) &filter2;
279 SMDS_MeshElement::Filter & filter = *aFilter;
281 if ( aType == SMDSAbs_Node )
282 for ( CORBA::ULong i = 0; i < IDs.length(); i++ ) {
283 const SMDS_MeshElement * elem = aMesh->FindNode( IDs[i] );
285 aMap.insert( aMap.end(), elem );
288 for ( CORBA::ULong i = 0; i<IDs.length(); i++) {
289 const SMDS_MeshElement * elem = aMesh->FindElement( IDs[i] );
291 aMap.insert( aMap.end(), elem );
295 //================================================================================
297 * \brief Retrieve nodes from SMESH_IDSource
299 //================================================================================
301 void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject,
302 const SMESHDS_Mesh* theMeshDS,
303 TIDSortedNodeSet& theNodeSet)
306 if ( CORBA::is_nil( theObject ) )
308 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
310 for ( SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator(); nIt->more(); )
311 if ( const SMDS_MeshElement * elem = nIt->next() )
312 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
316 SMESH::array_of_ElementType_var types = theObject->GetTypes();
317 SMESH::long_array_var aElementsId = theObject->GetIDs();
318 if ( types->length() == 1 && types[0] == SMESH::NODE)
320 for ( CORBA::ULong i = 0; i < aElementsId->length(); i++ )
321 if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] ))
322 theNodeSet.insert( theNodeSet.end(), n);
326 for ( CORBA::ULong i = 0; i < aElementsId->length(); i++ )
327 if ( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] ))
328 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
333 //================================================================================
335 * \brief Returns elements connected to the given elements
337 //================================================================================
339 void getElementsAround(const TIDSortedElemSet& theElements,
340 const SMESHDS_Mesh* theMeshDS,
341 TIDSortedElemSet& theElementsAround)
343 if ( theElements.empty() ) return;
345 SMDSAbs_ElementType elemType = (*theElements.begin())->GetType();
346 bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() );
348 theMeshDS->GetMeshInfo().NbElements( elemType ) == (int) theElements.size() )
349 return; // all the elements are in theElements
352 elemType = SMDSAbs_All;
354 vector<bool> isNodeChecked( theMeshDS->NbNodes(), false );
356 TIDSortedElemSet::const_iterator elemIt = theElements.begin();
357 for ( ; elemIt != theElements.end(); ++elemIt )
359 const SMDS_MeshElement* e = *elemIt;
360 int i = e->NbCornerNodes();
363 const SMDS_MeshNode* n = e->GetNode( i );
364 if ( !isNodeChecked[ n->GetID() ])
366 isNodeChecked[ n->GetID() ] = true;
367 SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
368 while ( invIt->more() )
370 const SMDS_MeshElement* elemAround = invIt->next();
371 if ( !theElements.count( elemAround ))
372 theElementsAround.insert( elemAround );
379 //================================================================================
381 * \brief Return a string used to detect change of mesh part on which theElementSearcher
382 * is going to be used
384 //================================================================================
386 string getPartIOR( SMESH::SMESH_IDSource_ptr theMeshPart, SMESH::ElementType type = SMESH::ALL )
388 if ( SMESH::DownCast<SMESH_Mesh_i*>( theMeshPart ))
390 string partIOR = SMESH_Gen_i::GetORB()->object_to_string( theMeshPart );
391 if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( theMeshPart ))
392 // take into account passible group modification
393 partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() );
394 partIOR += SMESH_Comment( type );
398 } // namespace MeshEditor_I
400 using namespace MeshEditor_I;
402 //=============================================================================
406 //=============================================================================
408 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview):
410 myMesh( &theMesh->GetImpl() ),
412 myIsPreviewMode ( isPreview ),
418 //================================================================================
422 //================================================================================
424 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
426 PortableServer::POA_var poa = SMESH_Gen_i::GetPOA();
427 PortableServer::ObjectId_var anObjectId = poa->servant_to_id(this);
428 poa->deactivate_object(anObjectId.in());
430 //deleteAuxIDSources();
431 delete myPreviewMesh; myPreviewMesh = 0;
432 delete myPreviewEditor; myPreviewEditor = 0;
435 //================================================================================
437 * \brief Returns the mesh
439 //================================================================================
441 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::GetMesh()
443 return myMesh_i->_this();
446 //================================================================================
448 * \brief Clear members
450 //================================================================================
452 void SMESH_MeshEditor_i::initData(bool deleteSearchers)
454 if ( myIsPreviewMode ) {
455 if ( myPreviewMesh ) myPreviewMesh->RemoveAll();
458 if ( deleteSearchers )
459 TSearchersDeleter::Delete();
461 getEditor().GetError().reset();
462 getEditor().ClearLastCreated();
465 //================================================================================
467 * \brief Increment mesh modif time and optionally record that the performed
468 * modification may influence further mesh re-compute.
469 * \param [in] isReComputeSafe - true if the modification does not influence
470 * further mesh re-compute
472 //================================================================================
474 void SMESH_MeshEditor_i::declareMeshModified( bool isReComputeSafe )
476 myMesh->GetMeshDS()->Modified();
477 if ( !isReComputeSafe )
478 myMesh->SetIsModified( true );
481 //================================================================================
483 * \brief Return either myEditor or myPreviewEditor depending on myIsPreviewMode.
484 * WARNING: in preview mode call getPreviewMesh() before getEditor()!
486 //================================================================================
488 ::SMESH_MeshEditor& SMESH_MeshEditor_i::getEditor()
490 if ( myIsPreviewMode && !myPreviewEditor ) {
491 if ( !myPreviewMesh ) getPreviewMesh();
492 myPreviewEditor = new ::SMESH_MeshEditor( myPreviewMesh );
494 return myIsPreviewMode ? *myPreviewEditor : myEditor;
497 //================================================================================
499 * \brief Initialize and return myPreviewMesh
500 * \param previewElements - type of elements to show in preview
502 * WARNING: call it once per method!
504 //================================================================================
506 TPreviewMesh * SMESH_MeshEditor_i::getPreviewMesh(SMDSAbs_ElementType previewElements)
508 if ( !myPreviewMesh || myPreviewMesh->myPreviewType != previewElements )
510 delete myPreviewEditor;
512 delete myPreviewMesh;
513 myPreviewMesh = new TPreviewMesh( previewElements );
515 myPreviewMesh->Clear();
516 return myPreviewMesh;
519 //================================================================================
521 * Return data of mesh edition preview
523 //================================================================================
525 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
526 throw (SALOME::SALOME_Exception)
529 const bool hasBadElems = ( getEditor().GetError() && getEditor().GetError()->HasBadElems() );
531 if ( myIsPreviewMode || hasBadElems )
533 list<int> aNodesConnectivity;
534 typedef map<int, int> TNodesMap;
537 SMESHDS_Mesh* aMeshDS;
538 std::unique_ptr< SMESH_MeshPartDS > aMeshPartDS;
540 const list<const SMDS_MeshElement*>& badElems =
541 static_cast<SMESH_BadInputElements*>( getEditor().GetError().get() )->myBadElements;
542 aMeshPartDS.reset( new SMESH_MeshPartDS( badElems ));
543 aMeshDS = aMeshPartDS.get();
546 aMeshDS = getEditor().GetMeshDS();
548 myPreviewData = new SMESH::MeshPreviewStruct();
549 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
552 SMDSAbs_ElementType previewType = SMDSAbs_All;
554 if (TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( getEditor().GetMesh() )) {
555 previewType = aPreviewMesh->myPreviewType;
556 switch ( previewType ) {
557 case SMDSAbs_Edge : break;
558 case SMDSAbs_Face : break;
559 case SMDSAbs_Volume: break;
561 if ( aMeshDS->GetMeshInfo().NbElements() == 0 ) previewType = SMDSAbs_Node;
565 myPreviewData->elementTypes.length( aMeshDS->GetMeshInfo().NbElements( previewType ));
567 SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator(previewType);
569 while ( itMeshElems->more() ) {
570 const SMDS_MeshElement* aMeshElem = itMeshElems->next();
571 SMDS_NodeIteratorPtr itElemNodes =
572 (( aMeshElem->GetEntityType() == SMDSEntity_Quad_Polygon ) ?
573 aMeshElem->interlacedNodesIterator() :
574 aMeshElem->nodeIterator() );
575 while ( itElemNodes->more() ) {
576 const SMDS_MeshNode* aMeshNode = itElemNodes->next();
577 int aNodeID = aMeshNode->GetID();
578 TNodesMap::iterator anIter = nodesMap.find(aNodeID);
579 if ( anIter == nodesMap.end() ) {
580 // filling the nodes coordinates
581 myPreviewData->nodesXYZ[j].x = aMeshNode->X();
582 myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
583 myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
584 anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
587 aNodesConnectivity.push_back(anIter->second);
590 // filling the elements types
591 SMDSAbs_ElementType aType = aMeshElem->GetType();
592 bool isPoly = aMeshElem->IsPoly();
593 myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
594 myPreviewData->elementTypes[i].isPoly = isPoly;
595 myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
598 myPreviewData->nodesXYZ.length( j );
600 // filling the elements connectivities
601 list<int>::iterator aConnIter = aNodesConnectivity.begin();
602 myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
603 for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
604 myPreviewData->elementConnectivities[i] = *aConnIter;
606 return myPreviewData._retn();
608 SMESH_CATCH( SMESH::throwCorbaException );
612 //================================================================================
614 * \brief Returns list of it's IDs of created nodes
615 * \retval SMESH::long_array* - list of node ID
617 //================================================================================
619 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
620 throw (SALOME::SALOME_Exception)
623 SMESH::long_array_var myLastCreatedNodes = new SMESH::long_array();
625 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedNodes();
626 myLastCreatedNodes->length( aSeq.size() );
627 for ( size_t i = 0; i < aSeq.size(); i++)
628 myLastCreatedNodes[i] = aSeq[i]->GetID();
630 return myLastCreatedNodes._retn();
631 SMESH_CATCH( SMESH::throwCorbaException );
635 //================================================================================
637 * \brief Returns list of it's IDs of created elements
638 * \retval SMESH::long_array* - list of elements' ID
640 //================================================================================
642 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
643 throw (SALOME::SALOME_Exception)
646 SMESH::long_array_var myLastCreatedElems = new SMESH::long_array();
648 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
649 myLastCreatedElems->length( aSeq.size() );
650 for ( size_t i = 0; i < aSeq.size(); i++ )
651 myLastCreatedElems[i] = aSeq[i]->GetID();
653 return myLastCreatedElems._retn();
654 SMESH_CATCH( SMESH::throwCorbaException );
658 //=======================================================================
659 //function : ClearLastCreated
660 //purpose : Clears sequences of last created elements and nodes
661 //=======================================================================
663 void SMESH_MeshEditor_i::ClearLastCreated() throw (SALOME::SALOME_Exception)
666 getEditor().ClearLastCreated();
667 SMESH_CATCH( SMESH::throwCorbaException );
670 //=======================================================================
672 * Returns description of an error/warning occurred during the last operation
673 * WARNING: ComputeError.code >= 100 and no corresponding enum in IDL API
675 //=======================================================================
677 SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError()
678 throw (SALOME::SALOME_Exception)
681 SMESH::ComputeError_var errOut = new SMESH::ComputeError;
682 SMESH_ComputeErrorPtr& errIn = getEditor().GetError();
683 if ( errIn && !errIn->IsOK() )
685 errOut->code = -( errIn->myName < 0 ? errIn->myName + 1: errIn->myName ); // -1 -> 0
686 errOut->comment = errIn->myComment.c_str();
687 errOut->subShapeID = -1;
688 errOut->hasBadMesh = errIn->HasBadElems();
693 errOut->subShapeID = -1;
694 errOut->hasBadMesh = false;
697 return errOut._retn();
698 SMESH_CATCH( SMESH::throwCorbaException );
702 //=======================================================================
703 //function : MakeIDSource
704 //purpose : Wrap a sequence of ids in a SMESH_IDSource.
705 // Call UnRegister() as you fininsh using it!!
706 //=======================================================================
708 struct SMESH_MeshEditor_i::_IDSource : public virtual POA_SMESH::SMESH_IDSource,
709 public virtual SALOME::GenericObj_i
711 SMESH::long_array _ids;
712 SMESH::ElementType _type;
713 SMESH::SMESH_Mesh_ptr _mesh;
714 SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); }
715 SMESH::long_array* GetMeshInfo() { return 0; }
716 SMESH::long_array* GetNbElementsByType()
718 SMESH::long_array_var aRes = new SMESH::long_array();
719 aRes->length(SMESH::NB_ELEMENT_TYPES);
720 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
721 aRes[ i ] = ( i == _type ) ? _ids.length() : 0;
724 SMESH::SMESH_Mesh_ptr GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _mesh ); }
725 bool IsMeshInfoCorrect() { return true; }
726 SMESH::array_of_ElementType* GetTypes()
728 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
729 if ( _ids.length() > 0 ) {
733 return types._retn();
735 SALOMEDS::TMPFile* GetVtkUgStream()
737 SALOMEDS::TMPFile_var SeqFile;
738 return SeqFile._retn();
742 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
743 SMESH::ElementType type)
745 _IDSource* idSrc = new _IDSource;
746 idSrc->_mesh = myMesh_i->_this();
749 if ( type == SMESH::ALL && ids.length() > 0 )
750 idSrc->_type = myMesh_i->GetElementType( ids[0], true );
752 SMESH::SMESH_IDSource_var anIDSourceVar = idSrc->_this();
754 return anIDSourceVar._retn();
757 bool SMESH_MeshEditor_i::IsTemporaryIDSource( SMESH::SMESH_IDSource_ptr& idSource )
759 return SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource );
762 CORBA::Long* SMESH_MeshEditor_i::GetTemporaryIDs( SMESH::SMESH_IDSource_ptr& idSource,
765 if ( _IDSource* tmpIdSource = SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource ))
767 nbIds = (int) tmpIdSource->_ids.length();
768 return & tmpIdSource->_ids[0];
774 // void SMESH_MeshEditor_i::deleteAuxIDSources()
776 // std::list< _IDSource* >::iterator idSrcIt = myAuxIDSources.begin();
777 // for ( ; idSrcIt != myAuxIDSources.end(); ++idSrcIt )
779 // myAuxIDSources.clear();
782 //=============================================================================
786 //=============================================================================
789 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
790 throw (SALOME::SALOME_Exception)
797 for ( CORBA::ULong i = 0; i < IDsOfElements.length(); i++ )
798 IdList.push_back( IDsOfElements[i] );
800 // Update Python script
801 TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
804 bool ret = getEditor().Remove( IdList, false );
806 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 ); // issue 0020693
809 SMESH_CATCH( SMESH::throwCorbaException );
813 //=============================================================================
817 //=============================================================================
819 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
820 throw (SALOME::SALOME_Exception)
826 for ( CORBA::ULong i = 0; i < IDsOfNodes.length(); i++)
827 IdList.push_back( IDsOfNodes[i] );
829 // Update Python script
830 TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
832 bool ret = getEditor().Remove( IdList, true );
834 declareMeshModified( /*isReComputeSafe=*/ !ret ); // issue 0020693
837 SMESH_CATCH( SMESH::throwCorbaException );
841 //=============================================================================
845 //=============================================================================
847 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
848 throw (SALOME::SALOME_Exception)
853 // Update Python script
854 TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
856 // Create filter to find all orphan nodes
857 SMESH::Controls::Filter::TIdSequence seq;
858 SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
859 SMESH::Controls::Filter::GetElementsId( getMeshDS(), predicate, seq );
861 // remove orphan nodes (if there are any)
862 list< int > IdList( seq.begin(), seq.end() );
864 int nbNodesBefore = myMesh->NbNodes();
865 getEditor().Remove( IdList, true );
866 int nbNodesAfter = myMesh->NbNodes();
868 declareMeshModified( /*isReComputeSafe=*/ IdList.size() == 0 ); // issue 0020693
869 return nbNodesBefore - nbNodesAfter;
871 SMESH_CATCH( SMESH::throwCorbaException );
875 //=============================================================================
879 //=============================================================================
881 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,CORBA::Double y, CORBA::Double z)
882 throw (SALOME::SALOME_Exception)
887 const SMDS_MeshNode* N = getMeshDS()->AddNode(x, y, z);
889 // Update Python script
890 TPythonDump() << "nodeID = " << this << ".AddNode( "
891 << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )";
893 declareMeshModified( /*isReComputeSafe=*/false );
896 SMESH_CATCH( SMESH::throwCorbaException );
900 //=============================================================================
902 * Create 0D element on the given node.
904 //=============================================================================
906 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode,
907 CORBA::Boolean DuplicateElements)
908 throw (SALOME::SALOME_Exception)
913 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
914 SMDS_ElemIteratorPtr it0D = aNode->GetInverseElementIterator( SMDSAbs_0DElement );
916 SMDS_MeshElement* elem = 0;
917 if ( DuplicateElements || !it0D->more() )
918 elem = getMeshDS()->Add0DElement(aNode);
920 // Update Python script
921 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
923 declareMeshModified( /*isReComputeSafe=*/false );
925 return elem ? elem->GetID() : 0;
927 SMESH_CATCH( SMESH::throwCorbaException );
931 //=============================================================================
933 * Create a ball element on the given node.
935 //=============================================================================
937 CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diameter)
938 throw (SALOME::SALOME_Exception)
943 if ( diameter < std::numeric_limits<double>::min() )
944 THROW_SALOME_CORBA_EXCEPTION("Invalid diameter", SALOME::BAD_PARAM);
946 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
947 SMDS_MeshElement* elem = getMeshDS()->AddBall(aNode, diameter);
949 // Update Python script
950 TPythonDump() << "ballElem = "
951 << this << ".AddBall( " << IDOfNode << ", " << diameter <<" )";
953 declareMeshModified( /*isReComputeSafe=*/false );
954 return elem ? elem->GetID() : 0;
956 SMESH_CATCH( SMESH::throwCorbaException );
960 //=============================================================================
962 * Create an edge, either linear and quadratic (this is determed
963 * by number of given nodes, two or three)
965 //=============================================================================
967 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
968 throw (SALOME::SALOME_Exception)
973 int NbNodes = IDsOfNodes.length();
974 SMDS_MeshElement* elem = 0;
977 CORBA::Long index1 = IDsOfNodes[0];
978 CORBA::Long index2 = IDsOfNodes[1];
979 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(index1),
980 getMeshDS()->FindNode(index2));
982 // Update Python script
983 TPythonDump() << "edge = " << this << ".AddEdge([ "
984 << index1 << ", " << index2 <<" ])";
987 CORBA::Long n1 = IDsOfNodes[0];
988 CORBA::Long n2 = IDsOfNodes[1];
989 CORBA::Long n12 = IDsOfNodes[2];
990 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(n1),
991 getMeshDS()->FindNode(n2),
992 getMeshDS()->FindNode(n12));
993 // Update Python script
994 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
995 <<n1<<", "<<n2<<", "<<n12<<" ])";
998 declareMeshModified( /*isReComputeSafe=*/false );
999 return elem ? elem->GetID() : 0;
1001 SMESH_CATCH( SMESH::throwCorbaException );
1005 //=============================================================================
1009 //=============================================================================
1011 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
1012 throw (SALOME::SALOME_Exception)
1017 int NbNodes = IDsOfNodes.length();
1023 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1024 for (int i = 0; i < NbNodes; i++)
1025 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1027 SMDS_MeshElement* elem = 0;
1029 case 3: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]); break;
1030 case 4: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]); break;
1031 case 6: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1032 nodes[4], nodes[5]); break;
1033 case 7: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1034 nodes[4], nodes[5], nodes[6]); break;
1035 case 8: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1036 nodes[4], nodes[5], nodes[6], nodes[7]); break;
1037 case 9: elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
1038 nodes[4], nodes[5], nodes[6], nodes[7],
1040 default: elem = getMeshDS()->AddPolygonalFace(nodes);
1043 // Update Python script
1044 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
1046 declareMeshModified( /*isReComputeSafe=*/false );
1048 return elem ? elem->GetID() : 0;
1050 SMESH_CATCH( SMESH::throwCorbaException );
1054 //=============================================================================
1058 //=============================================================================
1060 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
1061 throw (SALOME::SALOME_Exception)
1066 int NbNodes = IDsOfNodes.length();
1067 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1068 for (int i = 0; i < NbNodes; i++)
1069 if ( ! ( nodes[i] = getMeshDS()->FindNode( IDsOfNodes[i] )))
1072 const SMDS_MeshElement* elem = getMeshDS()->AddPolygonalFace(nodes);
1074 // Update Python script
1075 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
1077 declareMeshModified( /*isReComputeSafe=*/false );
1078 return elem ? elem->GetID() : 0;
1080 SMESH_CATCH( SMESH::throwCorbaException );
1084 //=============================================================================
1086 * AddQuadPolygonalFace
1088 //=============================================================================
1090 CORBA::Long SMESH_MeshEditor_i::AddQuadPolygonalFace (const SMESH::long_array & IDsOfNodes)
1091 throw (SALOME::SALOME_Exception)
1096 int NbNodes = IDsOfNodes.length();
1097 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
1098 for (int i = 0; i < NbNodes; i++)
1099 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
1101 const SMDS_MeshElement* elem = getMeshDS()->AddQuadPolygonalFace(nodes);
1103 // Update Python script
1104 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
1106 declareMeshModified( /*isReComputeSafe=*/false );
1107 return elem ? elem->GetID() : 0;
1109 SMESH_CATCH( SMESH::throwCorbaException );
1113 //=============================================================================
1115 * Create volume, either linear and quadratic (this is determed
1116 * by number of given nodes)
1118 //=============================================================================
1120 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
1121 throw (SALOME::SALOME_Exception)
1126 int NbNodes = IDsOfNodes.length();
1127 vector< const SMDS_MeshNode*> n(NbNodes);
1128 for(int i=0;i<NbNodes;i++)
1129 n[i]= getMeshDS()->FindNode(IDsOfNodes[i]);
1131 SMDS_MeshElement* elem = 0;
1134 case 4 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
1135 case 5 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
1136 case 6 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
1137 case 8 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
1138 case 10:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1139 n[6],n[7],n[8],n[9]);
1141 case 12:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1142 n[6],n[7],n[8],n[9],n[10],n[11]);
1144 case 13:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
1145 n[7],n[8],n[9],n[10],n[11],n[12]);
1147 case 15:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
1148 n[9],n[10],n[11],n[12],n[13],n[14]);
1150 case 20:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1151 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1152 n[15],n[16],n[17],n[18],n[19]);
1154 case 18:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1155 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1158 case 27:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1159 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1160 n[15],n[16],n[17],n[18],n[19],
1161 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
1165 // Update Python script
1166 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
1168 declareMeshModified( /*isReComputeSafe=*/false );
1169 return elem ? elem->GetID() : 0;
1171 SMESH_CATCH( SMESH::throwCorbaException );
1175 //=============================================================================
1177 * AddPolyhedralVolume
1179 //=============================================================================
1180 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
1181 const SMESH::long_array & Quantities)
1182 throw (SALOME::SALOME_Exception)
1187 int NbNodes = IDsOfNodes.length();
1188 std::vector<const SMDS_MeshNode*> n (NbNodes);
1189 for (int i = 0; i < NbNodes; i++)
1191 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDsOfNodes[i]);
1192 if (!aNode) return 0;
1196 int NbFaces = Quantities.length();
1197 std::vector<int> q (NbFaces);
1198 for (int j = 0; j < NbFaces; j++)
1199 q[j] = Quantities[j];
1201 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(n, q);
1203 // Update Python script
1204 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
1205 << IDsOfNodes << ", " << Quantities << " )";
1207 declareMeshModified( /*isReComputeSafe=*/false );
1208 return elem ? elem->GetID() : 0;
1210 SMESH_CATCH( SMESH::throwCorbaException );
1214 //=============================================================================
1216 * AddPolyhedralVolumeByFaces
1218 //=============================================================================
1220 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
1221 throw (SALOME::SALOME_Exception)
1226 int NbFaces = IdsOfFaces.length();
1227 std::vector<const SMDS_MeshNode*> poly_nodes;
1228 std::vector<int> quantities (NbFaces);
1230 for (int i = 0; i < NbFaces; i++) {
1231 const SMDS_MeshElement* aFace = getMeshDS()->FindElement(IdsOfFaces[i]);
1232 quantities[i] = aFace->NbNodes();
1234 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
1235 while (It->more()) {
1236 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
1240 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
1242 // Update Python script
1243 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
1244 << IdsOfFaces << " )";
1246 declareMeshModified( /*isReComputeSafe=*/false );
1247 return elem ? elem->GetID() : 0;
1249 SMESH_CATCH( SMESH::throwCorbaException );
1253 //=============================================================================
1255 // \brief Create 0D elements on all nodes of the given object.
1256 // \param theObject object on whose nodes 0D elements will be created.
1257 // \param theGroupName optional name of a group to add 0D elements created
1258 // and/or found on nodes of \a theObject.
1259 // \param DuplicateElements to add one more 0D element to a node or not.
1260 // \return an object (a new group or a temporary SMESH_IDSource) holding
1261 // ids of new and/or found 0D elements.
1263 //=============================================================================
1265 SMESH::SMESH_IDSource_ptr
1266 SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObject,
1267 const char* theGroupName,
1268 CORBA::Boolean theDuplicateElements)
1269 throw (SALOME::SALOME_Exception)
1274 SMESH::SMESH_IDSource_var result;
1277 TIDSortedElemSet elements, elems0D;
1278 if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
1279 getEditor().Create0DElementsOnAllNodes( elements, elems0D, theDuplicateElements );
1281 SMESH::long_array_var newElems = new SMESH::long_array;
1282 newElems->length( elems0D.size() );
1283 TIDSortedElemSet::iterator eIt = elems0D.begin();
1284 for ( size_t i = 0; i < elems0D.size(); ++i, ++eIt )
1285 newElems[ i ] = (*eIt)->GetID();
1287 SMESH::SMESH_GroupBase_var groupToFill;
1288 if ( theGroupName && strlen( theGroupName ))
1290 // Get existing group named theGroupName
1291 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
1292 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
1293 SMESH::SMESH_GroupBase_var group = groups[i];
1294 if ( !group->_is_nil() ) {
1295 CORBA::String_var name = group->GetName();
1296 if ( strcmp( name.in(), theGroupName ) == 0 && group->GetType() == SMESH::ELEM0D ) {
1297 groupToFill = group;
1302 if ( groupToFill->_is_nil() )
1303 groupToFill = myMesh_i->CreateGroup( SMESH::ELEM0D, theGroupName );
1304 else if ( !SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1305 groupToFill = myMesh_i->ConvertToStandalone( groupToFill );
1308 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1310 group_i->Add( newElems );
1311 result = SMESH::SMESH_IDSource::_narrow( groupToFill );
1312 pyDump << groupToFill;
1316 result = MakeIDSource( newElems, SMESH::ELEM0D );
1317 pyDump << "elem0DIDs";
1320 pyDump << " = " << this << ".Create0DElementsOnAllNodes( "
1321 << theObject << ", '" << theGroupName << "' )";
1323 return result._retn();
1325 SMESH_CATCH( SMESH::throwCorbaException );
1329 //=============================================================================
1331 * \brief Bind a node to a vertex
1332 * \param NodeID - node ID
1333 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1334 * \retval boolean - false if NodeID or VertexID is invalid
1336 //=============================================================================
1338 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
1339 throw (SALOME::SALOME_Exception)
1343 SMESHDS_Mesh * mesh = getMeshDS();
1344 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1346 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1348 if ( mesh->MaxShapeIndex() < VertexID )
1349 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1351 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
1352 if ( shape.ShapeType() != TopAbs_VERTEX )
1353 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1355 mesh->SetNodeOnVertex( node, VertexID );
1357 myMesh->SetIsModified( true );
1359 SMESH_CATCH( SMESH::throwCorbaException );
1362 //=============================================================================
1364 * \brief Store node position on an edge
1365 * \param NodeID - node ID
1366 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
1367 * \param paramOnEdge - parameter on edge where the node is located
1368 * \retval boolean - false if any parameter is invalid
1370 //=============================================================================
1372 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
1373 CORBA::Double paramOnEdge)
1374 throw (SALOME::SALOME_Exception)
1378 SMESHDS_Mesh * mesh = getMeshDS();
1379 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1381 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1383 if ( mesh->MaxShapeIndex() < EdgeID )
1384 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1386 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
1387 if ( shape.ShapeType() != TopAbs_EDGE )
1388 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1391 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
1392 if ( paramOnEdge < f || paramOnEdge > l )
1393 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
1395 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
1397 myMesh->SetIsModified( true );
1399 SMESH_CATCH( SMESH::throwCorbaException );
1402 //=============================================================================
1404 * \brief Store node position on a face
1405 * \param NodeID - node ID
1406 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
1407 * \param u - U parameter on face where the node is located
1408 * \param v - V parameter on face where the node is located
1409 * \retval boolean - false if any parameter is invalid
1411 //=============================================================================
1413 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
1414 CORBA::Double u, CORBA::Double v)
1415 throw (SALOME::SALOME_Exception)
1418 SMESHDS_Mesh * mesh = getMeshDS();
1419 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1421 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1423 if ( mesh->MaxShapeIndex() < FaceID )
1424 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1426 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
1427 if ( shape.ShapeType() != TopAbs_FACE )
1428 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1430 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
1431 bool isOut = ( u < surf.FirstUParameter() ||
1432 u > surf.LastUParameter() ||
1433 v < surf.FirstVParameter() ||
1434 v > surf.LastVParameter() );
1438 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
1439 << " u( " << surf.FirstUParameter()
1440 << "," << surf.LastUParameter()
1441 << ") v( " << surf.FirstVParameter()
1442 << "," << surf.LastVParameter() << ")" );
1444 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
1447 mesh->SetNodeOnFace( node, FaceID, u, v );
1448 myMesh->SetIsModified( true );
1450 SMESH_CATCH( SMESH::throwCorbaException );
1453 //=============================================================================
1455 * \brief Bind a node to a solid
1456 * \param NodeID - node ID
1457 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1458 * \retval boolean - false if NodeID or SolidID is invalid
1460 //=============================================================================
1462 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
1463 throw (SALOME::SALOME_Exception)
1466 SMESHDS_Mesh * mesh = getMeshDS();
1467 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1469 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1471 if ( mesh->MaxShapeIndex() < SolidID )
1472 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1474 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
1475 if ( shape.ShapeType() != TopAbs_SOLID &&
1476 shape.ShapeType() != TopAbs_SHELL)
1477 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1479 mesh->SetNodeInVolume( node, SolidID );
1481 SMESH_CATCH( SMESH::throwCorbaException );
1484 //=============================================================================
1486 * \brief Bind an element to a shape
1487 * \param ElementID - element ID
1488 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
1490 //=============================================================================
1492 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
1493 CORBA::Long ShapeID)
1494 throw (SALOME::SALOME_Exception)
1497 SMESHDS_Mesh * mesh = getMeshDS();
1498 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
1500 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
1502 if ( mesh->MaxShapeIndex() < ShapeID || ShapeID < 1 )
1503 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1505 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1506 if ( shape.ShapeType() != TopAbs_EDGE &&
1507 shape.ShapeType() != TopAbs_FACE &&
1508 shape.ShapeType() != TopAbs_SOLID &&
1509 shape.ShapeType() != TopAbs_SHELL )
1510 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1512 mesh->SetMeshElementOnShape( elem, ShapeID );
1514 myMesh->SetIsModified( true );
1516 SMESH_CATCH( SMESH::throwCorbaException );
1519 //=============================================================================
1523 //=============================================================================
1525 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1526 CORBA::Long NodeID2)
1527 throw (SALOME::SALOME_Exception)
1532 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1533 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1537 // Update Python script
1538 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1539 << NodeID1 << ", " << NodeID2 << " )";
1541 int ret = getEditor().InverseDiag ( n1, n2 );
1543 declareMeshModified( /*isReComputeSafe=*/false );
1546 SMESH_CATCH( SMESH::throwCorbaException );
1550 //=============================================================================
1554 //=============================================================================
1556 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1557 CORBA::Long NodeID2)
1558 throw (SALOME::SALOME_Exception)
1563 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1564 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1568 // Update Python script
1569 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1570 << NodeID1 << ", " << NodeID2 << " )";
1573 bool stat = getEditor().DeleteDiag ( n1, n2 );
1575 declareMeshModified( /*isReComputeSafe=*/!stat );
1579 SMESH_CATCH( SMESH::throwCorbaException );
1583 //=============================================================================
1587 //=============================================================================
1589 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1590 throw (SALOME::SALOME_Exception)
1595 for ( CORBA::ULong i = 0; i < IDsOfElements.length(); i++ )
1597 CORBA::Long index = IDsOfElements[i];
1598 const SMDS_MeshElement * elem = getMeshDS()->FindElement(index);
1600 getEditor().Reorient( elem );
1602 // Update Python script
1603 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1605 declareMeshModified( /*isReComputeSafe=*/ IDsOfElements.length() == 0 );
1608 SMESH_CATCH( SMESH::throwCorbaException );
1612 //=============================================================================
1616 //=============================================================================
1618 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1619 throw (SALOME::SALOME_Exception)
1624 TPythonDump aTPythonDump; // suppress dump in Reorient()
1626 prepareIdSource( theObject );
1628 SMESH::long_array_var anElementsId = theObject->GetIDs();
1629 CORBA::Boolean isDone = Reorient(anElementsId);
1631 // Update Python script
1632 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1634 declareMeshModified( /*isReComputeSafe=*/ anElementsId->length() == 0 );
1637 SMESH_CATCH( SMESH::throwCorbaException );
1641 //=======================================================================
1642 //function : Reorient2D
1643 //purpose : Reorient faces contained in \a the2Dgroup.
1644 // the2Dgroup - the mesh or its part to reorient
1645 // theDirection - desired direction of normal of \a theFace
1646 // theFace - ID of face whose orientation is checked.
1647 // It can be < 1 then \a thePoint is used to find a face.
1648 // thePoint - is used to find a face if \a theFace < 1.
1649 // return number of reoriented elements.
1650 //=======================================================================
1652 CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
1653 const SMESH::DirStruct& theDirection,
1654 CORBA::Long theFace,
1655 const SMESH::PointStruct& thePoint)
1656 throw (SALOME::SALOME_Exception)
1659 initData(/*deleteSearchers=*/false);
1661 TIDSortedElemSet elements;
1662 IDSource_Error error;
1663 idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error );
1664 if ( error == IDSource_EMPTY )
1666 if ( error == IDSource_INVALID )
1667 THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
1670 const SMDS_MeshElement* face = 0;
1673 face = getMeshDS()->FindElement( theFace );
1675 THROW_SALOME_CORBA_EXCEPTION("Inexistent face given", SALOME::BAD_PARAM);
1676 if ( face->GetType() != SMDSAbs_Face )
1677 THROW_SALOME_CORBA_EXCEPTION("Wrong element type", SALOME::BAD_PARAM);
1681 // create theElementSearcher if needed
1682 theSearchersDeleter.Set( myMesh, getPartIOR( the2Dgroup, SMESH::FACE ));
1683 if ( !theElementSearcher )
1685 if ( elements.empty() ) // search in the whole mesh
1687 if ( myMesh->NbFaces() == 0 )
1688 THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM);
1690 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
1694 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
1695 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
1697 theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), elemsIt);
1701 gp_Pnt p( thePoint.x, thePoint.y, thePoint.z );
1702 face = theElementSearcher->FindClosestTo( p, SMDSAbs_Face );
1705 THROW_SALOME_CORBA_EXCEPTION("No face found by point", SALOME::INTERNAL_ERROR );
1706 if ( !elements.empty() && !elements.count( face ))
1707 THROW_SALOME_CORBA_EXCEPTION("Found face is not in the group", SALOME::BAD_PARAM );
1710 const SMESH::PointStruct * P = &theDirection.PS;
1711 gp_Vec dirVec( P->x, P->y, P->z );
1712 if ( dirVec.Magnitude() < std::numeric_limits< double >::min() )
1713 THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM);
1715 int nbReori = getEditor().Reorient2D( elements, dirVec, face );
1718 declareMeshModified( /*isReComputeSafe=*/false );
1720 TPythonDump() << this << ".Reorient2D( "
1721 << the2Dgroup << ", "
1722 << theDirection << ", "
1724 << thePoint << " )";
1728 SMESH_CATCH( SMESH::throwCorbaException );
1732 //=======================================================================
1733 //function : Reorient2DBy3D
1734 //purpose : Reorient faces basing on orientation of adjacent volumes.
1735 //=======================================================================
1737 CORBA::Long SMESH_MeshEditor_i::Reorient2DBy3D(const SMESH::ListOfIDSources& faceGroups,
1738 SMESH::SMESH_IDSource_ptr volumeGroup,
1739 CORBA::Boolean outsideNormal)
1740 throw (SALOME::SALOME_Exception)
1745 TIDSortedElemSet volumes;
1746 IDSource_Error volsError;
1747 idSourceToSet( volumeGroup, getMeshDS(), volumes, SMDSAbs_Volume, /*emptyIfMesh=*/1, &volsError);
1750 for ( size_t i = 0; i < faceGroups.length(); ++i )
1752 SMESH::SMESH_IDSource_ptr faceGrp = faceGroups[i].in();
1754 TIDSortedElemSet faces;
1755 IDSource_Error error;
1756 idSourceToSet( faceGrp, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/1, &error );
1757 if ( error == IDSource_INVALID && faceGroups.length() == 1 )
1758 THROW_SALOME_CORBA_EXCEPTION("No faces in a given object", SALOME::BAD_PARAM);
1759 if ( error == IDSource_OK && volsError != IDSource_OK )
1760 THROW_SALOME_CORBA_EXCEPTION("No volumes in a given object", SALOME::BAD_PARAM);
1762 nbReori += getEditor().Reorient2DBy3D( faces, volumes, outsideNormal );
1764 if ( error != IDSource_EMPTY && faces.empty() ) // all faces in the mesh treated
1769 declareMeshModified( /*isReComputeSafe=*/false );
1771 TPythonDump() << this << ".Reorient2DBy3D( "
1772 << faceGroups << ", "
1773 << volumeGroup << ", "
1774 << outsideNormal << " )";
1778 SMESH_CATCH( SMESH::throwCorbaException );
1782 //=============================================================================
1784 * \brief Fuse neighbour triangles into quadrangles.
1786 //=============================================================================
1788 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1789 SMESH::NumericalFunctor_ptr Criterion,
1790 CORBA::Double MaxAngle)
1791 throw (SALOME::SALOME_Exception)
1796 SMESHDS_Mesh* aMesh = getMeshDS();
1797 TIDSortedElemSet faces,copyFaces;
1798 SMDS_MeshElement::GeomFilter triaFilter(SMDSGeom_TRIANGLE);
1799 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face, & triaFilter);
1800 TIDSortedElemSet* workElements = & faces;
1802 if ( myIsPreviewMode ) {
1803 SMDSAbs_ElementType select = SMDSAbs_Face;
1804 getPreviewMesh( SMDSAbs_Face )->Copy( faces, copyFaces, select );
1805 workElements = & copyFaces;
1808 SMESH::NumericalFunctor_i* aNumericalFunctor =
1809 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1810 SMESH::Controls::NumericalFunctorPtr aCrit;
1811 if ( !aNumericalFunctor )
1812 aCrit.reset( new SMESH::Controls::MaxElementLength2D() );
1814 aCrit = aNumericalFunctor->GetNumericalFunctor();
1816 if ( !myIsPreviewMode ) {
1817 // Update Python script
1818 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1819 << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1822 bool stat = getEditor().TriToQuad( *workElements, aCrit, MaxAngle );
1824 declareMeshModified( /*isReComputeSafe=*/!stat );
1827 SMESH_CATCH( SMESH::throwCorbaException );
1831 //=============================================================================
1833 * \brief Fuse neighbour triangles into quadrangles.
1835 //=============================================================================
1837 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1838 SMESH::NumericalFunctor_ptr Criterion,
1839 CORBA::Double MaxAngle)
1840 throw (SALOME::SALOME_Exception)
1845 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1847 prepareIdSource( theObject );
1848 SMESH::long_array_var anElementsId = theObject->GetIDs();
1849 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1851 if ( !myIsPreviewMode ) {
1852 SMESH::NumericalFunctor_i* aNumericalFunctor =
1853 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1855 // Update Python script
1856 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1857 << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1862 SMESH_CATCH( SMESH::throwCorbaException );
1866 //=============================================================================
1868 * \brief Split quadrangles into triangles.
1870 //=============================================================================
1872 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1873 SMESH::NumericalFunctor_ptr Criterion)
1874 throw (SALOME::SALOME_Exception)
1879 SMESHDS_Mesh* aMesh = getMeshDS();
1880 TIDSortedElemSet faces;
1881 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1883 SMESH::NumericalFunctor_i* aNumericalFunctor =
1884 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1885 SMESH::Controls::NumericalFunctorPtr aCrit;
1886 if ( !aNumericalFunctor )
1887 aCrit.reset( new SMESH::Controls::AspectRatio() );
1889 aCrit = aNumericalFunctor->GetNumericalFunctor();
1892 // Update Python script
1893 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1895 CORBA::Boolean stat = getEditor().QuadToTri( faces, aCrit );
1897 declareMeshModified( /*isReComputeSafe=*/false );
1900 SMESH_CATCH( SMESH::throwCorbaException );
1904 //=============================================================================
1906 * \brief Split quadrangles into triangles.
1908 //=============================================================================
1910 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1911 SMESH::NumericalFunctor_ptr Criterion)
1912 throw (SALOME::SALOME_Exception)
1917 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1919 prepareIdSource( theObject );
1920 SMESH::long_array_var anElementsId = theObject->GetIDs();
1921 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1923 SMESH::NumericalFunctor_i* aNumericalFunctor =
1924 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1926 // Update Python script
1927 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1929 declareMeshModified( /*isReComputeSafe=*/false );
1932 SMESH_CATCH( SMESH::throwCorbaException );
1936 //================================================================================
1938 * \brief Split each of quadrangles into 4 triangles.
1939 * \param [in] theObject - theQuads Container of quadrangles to split.
1941 //================================================================================
1943 void SMESH_MeshEditor_i::QuadTo4Tri (SMESH::SMESH_IDSource_ptr theObject)
1944 throw (SALOME::SALOME_Exception)
1949 TIDSortedElemSet faces;
1950 if ( !idSourceToSet( theObject, getMeshDS(), faces, SMDSAbs_Face, /*emptyIfIsMesh=*/true ) &&
1952 THROW_SALOME_CORBA_EXCEPTION("No faces given", SALOME::BAD_PARAM);
1954 getEditor().QuadTo4Tri( faces );
1955 TPythonDump() << this << ".QuadTo4Tri( " << theObject << " )";
1957 SMESH_CATCH( SMESH::throwCorbaException );
1960 //=============================================================================
1962 * \brief Split quadrangles into triangles.
1964 //=============================================================================
1966 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1967 CORBA::Boolean Diag13)
1968 throw (SALOME::SALOME_Exception)
1973 SMESHDS_Mesh* aMesh = getMeshDS();
1974 TIDSortedElemSet faces;
1975 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1977 // Update Python script
1978 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1979 << IDsOfElements << ", " << Diag13 << " )";
1981 CORBA::Boolean stat = getEditor().QuadToTri( faces, Diag13 );
1983 declareMeshModified( /*isReComputeSafe=*/ !stat );
1986 SMESH_CATCH( SMESH::throwCorbaException );
1990 //=============================================================================
1992 * \brief Split quadrangles into triangles.
1994 //=============================================================================
1996 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1997 CORBA::Boolean Diag13)
1998 throw (SALOME::SALOME_Exception)
2003 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
2005 prepareIdSource( theObject );
2006 SMESH::long_array_var anElementsId = theObject->GetIDs();
2007 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
2009 // Update Python script
2010 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
2011 << theObject << ", " << Diag13 << " )";
2013 declareMeshModified( /*isReComputeSafe=*/!isDone );
2016 SMESH_CATCH( SMESH::throwCorbaException );
2021 //=============================================================================
2023 * Find better splitting of the given quadrangle.
2024 * \param IDOfQuad ID of the quadrangle to be split.
2025 * \param Criterion A criterion to choose a diagonal for splitting.
2026 * \return 1 if 1-3 diagonal is better, 2 if 2-4
2027 * diagonal is better, 0 if error occurs.
2029 //=============================================================================
2031 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
2032 SMESH::NumericalFunctor_ptr Criterion)
2033 throw (SALOME::SALOME_Exception)
2038 const SMDS_MeshElement* quad = getMeshDS()->FindElement(IDOfQuad);
2039 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
2041 SMESH::NumericalFunctor_i* aNumericalFunctor =
2042 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
2043 SMESH::Controls::NumericalFunctorPtr aCrit;
2044 if (aNumericalFunctor)
2045 aCrit = aNumericalFunctor->GetNumericalFunctor();
2047 aCrit.reset(new SMESH::Controls::AspectRatio());
2049 int id = getEditor().BestSplit(quad, aCrit);
2050 declareMeshModified( /*isReComputeSafe=*/ id < 1 );
2054 SMESH_CATCH( SMESH::throwCorbaException );
2058 //================================================================================
2060 * \brief Split volumic elements into tetrahedrons
2062 //================================================================================
2064 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
2065 CORBA::Short methodFlags)
2066 throw (SALOME::SALOME_Exception)
2071 ::SMESH_MeshEditor::TFacetOfElem elemSet;
2072 const int noneFacet = -1;
2073 prepareIdSource( elems );
2074 if ( SMDS_ElemIteratorPtr volIt = myMesh_i->GetElements( elems, SMESH::VOLUME ))
2075 while ( volIt->more() )
2076 elemSet.insert( elemSet.end(), make_pair( volIt->next(), noneFacet ));
2078 getEditor().SplitVolumes( elemSet, int( methodFlags ));
2079 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2081 TPythonDump() << this << ".SplitVolumesIntoTetra( "
2082 << elems << ", " << methodFlags << " )";
2084 SMESH_CATCH( SMESH::throwCorbaException );
2087 //================================================================================
2089 * \brief Split hexahedra into triangular prisms
2090 * \param elems - elements to split
2091 * \param facetToSplitNormal - normal used to find a facet of hexahedron
2092 * to split into triangles
2093 * \param methodFlags - flags passing splitting method:
2094 * 1 - split the hexahedron into 2 prisms
2095 * 2 - split the hexahedron into 4 prisms
2097 //================================================================================
2099 void SMESH_MeshEditor_i::SplitHexahedraIntoPrisms( SMESH::SMESH_IDSource_ptr elems,
2100 const SMESH::PointStruct & startHexPoint,
2101 const SMESH::DirStruct& facetToSplitNormal,
2102 CORBA::Short methodFlags,
2103 CORBA::Boolean allDomains)
2104 throw (SALOME::SALOME_Exception)
2108 prepareIdSource( elems );
2110 gp_Ax1 facetNorm( gp_Pnt( startHexPoint.x,
2113 gp_Dir( facetToSplitNormal.PS.x,
2114 facetToSplitNormal.PS.y,
2115 facetToSplitNormal.PS.z ));
2116 TIDSortedElemSet elemSet;
2117 prepareIdSource( elems );
2118 SMESH::long_array_var anElementsId = elems->GetIDs();
2119 SMDS_MeshElement::GeomFilter filter( SMDSGeom_HEXA );
2120 arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume, &filter );
2122 ::SMESH_MeshEditor::TFacetOfElem elemFacets;
2123 while ( !elemSet.empty() )
2125 getEditor().GetHexaFacetsToSplit( elemSet, facetNorm, elemFacets );
2129 ::SMESH_MeshEditor::TFacetOfElem::iterator ef = elemFacets.begin();
2130 for ( ; ef != elemFacets.end(); ++ef )
2131 elemSet.erase( ef->first );
2134 if ( methodFlags == 2 )
2135 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_4_PRISMS );
2137 methodFlags = int( ::SMESH_MeshEditor::HEXA_TO_2_PRISMS );
2139 getEditor().SplitVolumes( elemFacets, int( methodFlags ));
2140 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2142 TPythonDump() << this << ".SplitHexahedraIntoPrisms( "
2144 << startHexPoint << ", "
2145 << facetToSplitNormal<< ", "
2146 << methodFlags<< ", "
2147 << allDomains << " )";
2149 SMESH_CATCH( SMESH::throwCorbaException );
2152 //================================================================================
2154 * \brief Split bi-quadratic elements into linear ones without creation of additional nodes:
2155 * - bi-quadratic triangle will be split into 3 linear quadrangles;
2156 * - bi-quadratic quadrangle will be split into 4 linear quadrangles;
2157 * - tri-quadratic hexahedron will be split into 8 linear hexahedra.
2158 * Quadratic elements of lower dimension adjacent to the split bi-quadratic element
2159 * will be split in order to keep the mesh conformal.
2160 * \param elems - elements to split
2162 //================================================================================
2164 void SMESH_MeshEditor_i::SplitBiQuadraticIntoLinear(const SMESH::ListOfIDSources& theElems)
2165 throw (SALOME::SALOME_Exception)
2170 TIDSortedElemSet elemSet;
2171 for ( size_t i = 0; i < theElems.length(); ++i )
2173 SMESH::SMESH_IDSource_ptr elems = theElems[i].in();
2174 SMESH::SMESH_Mesh_var mesh = elems->GetMesh();
2175 if ( mesh->GetId() != myMesh_i->GetId() )
2176 THROW_SALOME_CORBA_EXCEPTION("Wrong mesh of IDSource", SALOME::BAD_PARAM);
2178 idSourceToSet( elems, getMeshDS(), elemSet, SMDSAbs_All );
2180 getEditor().SplitBiQuadraticIntoLinear( elemSet );
2182 declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
2184 TPythonDump() << this << ".SplitBiQuadraticIntoLinear( "
2185 << theElems << " )";
2187 SMESH_CATCH( SMESH::throwCorbaException );
2190 //=======================================================================
2193 //=======================================================================
2196 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
2197 const SMESH::long_array & IDsOfFixedNodes,
2198 CORBA::Long MaxNbOfIterations,
2199 CORBA::Double MaxAspectRatio,
2200 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2201 throw (SALOME::SALOME_Exception)
2203 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2204 MaxAspectRatio, Method, false );
2208 //=======================================================================
2209 //function : SmoothParametric
2211 //=======================================================================
2214 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
2215 const SMESH::long_array & IDsOfFixedNodes,
2216 CORBA::Long MaxNbOfIterations,
2217 CORBA::Double MaxAspectRatio,
2218 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2219 throw (SALOME::SALOME_Exception)
2221 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
2222 MaxAspectRatio, Method, true );
2226 //=======================================================================
2227 //function : SmoothObject
2229 //=======================================================================
2232 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
2233 const SMESH::long_array & IDsOfFixedNodes,
2234 CORBA::Long MaxNbOfIterations,
2235 CORBA::Double MaxAspectRatio,
2236 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2237 throw (SALOME::SALOME_Exception)
2239 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2240 MaxAspectRatio, Method, false);
2244 //=======================================================================
2245 //function : SmoothParametricObject
2247 //=======================================================================
2250 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
2251 const SMESH::long_array & IDsOfFixedNodes,
2252 CORBA::Long MaxNbOfIterations,
2253 CORBA::Double MaxAspectRatio,
2254 SMESH::SMESH_MeshEditor::Smooth_Method Method)
2255 throw (SALOME::SALOME_Exception)
2257 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
2258 MaxAspectRatio, Method, true);
2262 //=============================================================================
2266 //=============================================================================
2269 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
2270 const SMESH::long_array & IDsOfFixedNodes,
2271 CORBA::Long MaxNbOfIterations,
2272 CORBA::Double MaxAspectRatio,
2273 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2275 throw (SALOME::SALOME_Exception)
2280 SMESHDS_Mesh* aMesh = getMeshDS();
2282 TIDSortedElemSet elements;
2283 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
2285 set<const SMDS_MeshNode*> fixedNodes;
2286 for ( CORBA::ULong i = 0; i < IDsOfFixedNodes.length(); i++) {
2287 CORBA::Long index = IDsOfFixedNodes[i];
2288 const SMDS_MeshNode * node = aMesh->FindNode(index);
2290 fixedNodes.insert( node );
2292 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
2293 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
2294 method = ::SMESH_MeshEditor::CENTROIDAL;
2296 getEditor().Smooth(elements, fixedNodes, method,
2297 MaxNbOfIterations, MaxAspectRatio, IsParametric );
2299 declareMeshModified( /*isReComputeSafe=*/true ); // does not prevent re-compute
2301 // Update Python script
2302 TPythonDump() << "isDone = " << this << "."
2303 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
2304 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
2305 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2306 << "SMESH.SMESH_MeshEditor."
2307 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2308 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2312 SMESH_CATCH( SMESH::throwCorbaException );
2316 //=============================================================================
2320 //=============================================================================
2323 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
2324 const SMESH::long_array & IDsOfFixedNodes,
2325 CORBA::Long MaxNbOfIterations,
2326 CORBA::Double MaxAspectRatio,
2327 SMESH::SMESH_MeshEditor::Smooth_Method Method,
2329 throw (SALOME::SALOME_Exception)
2334 TPythonDump aTPythonDump; // suppress dump in smooth()
2336 prepareIdSource( theObject );
2337 SMESH::long_array_var anElementsId = theObject->GetIDs();
2338 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
2339 MaxAspectRatio, Method, IsParametric);
2341 // Update Python script
2342 aTPythonDump << "isDone = " << this << "."
2343 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
2344 << theObject << ", " << IDsOfFixedNodes << ", "
2345 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
2346 << "SMESH.SMESH_MeshEditor."
2347 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
2348 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
2352 SMESH_CATCH( SMESH::throwCorbaException );
2356 //=============================================================================
2360 //=============================================================================
2362 void SMESH_MeshEditor_i::RenumberNodes()
2363 throw (SALOME::SALOME_Exception)
2366 // Update Python script
2367 TPythonDump() << this << ".RenumberNodes()";
2369 getMeshDS()->Renumber( true );
2371 SMESH_CATCH( SMESH::throwCorbaException );
2374 //=============================================================================
2378 //=============================================================================
2380 void SMESH_MeshEditor_i::RenumberElements()
2381 throw (SALOME::SALOME_Exception)
2384 // Update Python script
2385 TPythonDump() << this << ".RenumberElements()";
2387 getMeshDS()->Renumber( false );
2389 SMESH_CATCH( SMESH::throwCorbaException );
2392 //=======================================================================
2394 * \brief Return groups by their IDs
2396 //=======================================================================
2398 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
2399 throw (SALOME::SALOME_Exception)
2404 myMesh_i->CreateGroupServants();
2405 return myMesh_i->GetGroups( *groupIDs );
2407 SMESH_CATCH( SMESH::throwCorbaException );
2411 //=======================================================================
2412 //function : RotationSweepObjects
2414 //=======================================================================
2416 SMESH::ListOfGroups*
2417 SMESH_MeshEditor_i::RotationSweepObjects(const SMESH::ListOfIDSources & theNodes,
2418 const SMESH::ListOfIDSources & theEdges,
2419 const SMESH::ListOfIDSources & theFaces,
2420 const SMESH::AxisStruct & theAxis,
2421 CORBA::Double theAngleInRadians,
2422 CORBA::Long theNbOfSteps,
2423 CORBA::Double theTolerance,
2424 const bool theMakeGroups)
2425 throw (SALOME::SALOME_Exception)
2430 TIDSortedElemSet elemsNodes[2];
2431 for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) {
2432 if ( SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE ))
2433 while ( nIt->more() ) elemsNodes[1].insert( nIt->next() );
2435 for ( int i = 0, nb = theEdges.length(); i < nb; ++i )
2436 idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge );
2437 for ( int i = 0, nb = theFaces.length(); i < nb; ++i )
2438 idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face );
2440 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2441 bool makeWalls=true;
2442 if ( myIsPreviewMode )
2444 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2445 TPreviewMesh * tmpMesh = getPreviewMesh();
2446 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2447 tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid );
2448 workElements = & copyElements[0];
2449 //makeWalls = false; -- faces are needed for preview
2452 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2454 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
2455 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
2457 ::SMESH_MeshEditor::PGroupIDs groupIds =
2458 getEditor().RotationSweep (workElements, Ax1, theAngleInRadians,
2459 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
2461 SMESH::ListOfGroups * aGroups = theMakeGroups ? getGroups( groupIds.get()) : 0;
2463 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2465 if ( !myIsPreviewMode )
2467 dumpGroupsList( aPythonDump, aGroups );
2468 aPythonDump << this<< ".RotationSweepObjects( "
2473 << TVar( theAngleInRadians ) << ", "
2474 << TVar( theNbOfSteps ) << ", "
2475 << TVar( theTolerance ) << ", "
2476 << theMakeGroups << " )";
2480 getPreviewMesh()->Remove( SMDSAbs_Volume );
2483 return aGroups ? aGroups : new SMESH::ListOfGroups;
2485 SMESH_CATCH( SMESH::throwCorbaException );
2489 namespace MeshEditor_I
2492 * \brief Structure used to pass extrusion parameters to ::SMESH_MeshEditor
2494 struct ExtrusionParams : public ::SMESH_MeshEditor::ExtrusParam
2496 bool myIsExtrusionByNormal;
2498 static int makeFlags( CORBA::Boolean MakeGroups,
2499 CORBA::Boolean ScaleVariation = false,
2500 CORBA::Boolean AngleVariation = false,
2501 CORBA::Boolean ByAverageNormal = false,
2502 CORBA::Boolean UseInputElemsOnly = false,
2503 CORBA::Long Flags = 0,
2504 CORBA::Boolean MakeBoundary = true )
2506 if ( MakeGroups ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS;
2507 if ( ByAverageNormal ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BY_AVG_NORMAL;
2508 if ( UseInputElemsOnly) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY;
2509 if ( ScaleVariation ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_SCALE_LINEAR_VARIATION;
2510 if ( AngleVariation ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_ANGLE_LINEAR_VARIATION;
2511 if ( MakeBoundary ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BOUNDARY;
2515 ExtrusionParams(const SMESH::DirStruct & theDir,
2516 CORBA::Long theNbOfSteps,
2517 const SMESH::double_array & theScaleFactors,
2518 CORBA::Boolean theScaleVariation,
2519 const SMESH::double_array & theAngles,
2520 CORBA::Boolean theAngleVariation,
2521 const SMESH::double_array & theBasePoint,
2522 CORBA::Boolean theMakeGroups):
2523 ::SMESH_MeshEditor::ExtrusParam ( gp_Vec( theDir.PS.x,
2527 toList( theScaleFactors ),
2528 toList( theAngles ),
2529 TBasePoint( theBasePoint ),
2530 makeFlags( theMakeGroups, theScaleVariation, theAngleVariation )),
2531 myIsExtrusionByNormal( false )
2535 ExtrusionParams(const SMESH::DirStruct & theDir,
2536 CORBA::Long theNbOfSteps,
2537 CORBA::Boolean theMakeGroups,
2538 CORBA::Long theExtrFlags,
2539 CORBA::Double theSewTolerance):
2540 ::SMESH_MeshEditor::ExtrusParam ( gp_Vec( theDir.PS.x,
2544 std::list<double>(),
2545 std::list<double>(),
2547 makeFlags( theMakeGroups, false, false, false, false,
2548 theExtrFlags, false ),
2550 myIsExtrusionByNormal( false )
2553 // params for extrusion by normal
2554 ExtrusionParams(CORBA::Double theStepSize,
2555 CORBA::Long theNbOfSteps,
2556 CORBA::Short theDim,
2557 CORBA::Boolean theByAverageNormal,
2558 CORBA::Boolean theUseInputElemsOnly,
2559 CORBA::Boolean theMakeGroups ):
2560 ::SMESH_MeshEditor::ExtrusParam ( theStepSize,
2562 makeFlags( theMakeGroups, false, false,
2563 theByAverageNormal, theUseInputElemsOnly ),
2565 myIsExtrusionByNormal( true )
2571 Flags() &= ~(::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS);
2574 static std::list<double> toList( const SMESH::double_array & theScaleFactors )
2576 std::list<double> scales;
2577 for ( CORBA::ULong i = 0; i < theScaleFactors.length(); ++i )
2578 scales.push_back( theScaleFactors[i] );
2584 // structure used to convert SMESH::double_array to gp_XYZ*
2588 TBasePoint( const SMESH::double_array & theBasePoint )
2591 if ( theBasePoint.length() == 3 )
2593 p.SetCoord( theBasePoint[0], theBasePoint[1], theBasePoint[2] );
2597 operator const gp_XYZ*() const { return pp; }
2602 //=======================================================================
2604 * \brief Generate dim+1 elements by extrusion of elements along vector
2605 * \param [in] edges - edges to extrude: a list including groups, sub-meshes or a mesh
2606 * \param [in] faces - faces to extrude: a list including groups, sub-meshes or a mesh
2607 * \param [in] nodes - nodes to extrude: a list including groups, sub-meshes or a mesh
2608 * \param [in] stepVector - vector giving direction and distance of an extrusion step
2609 * \param [in] nbOfSteps - number of elements to generate from one element
2610 * \param [in] toMakeGroups - if true, new elements will be included into new groups
2611 * corresponding to groups the input elements included in.
2612 * \return ListOfGroups - new groups created if \a toMakeGroups is true
2614 //=======================================================================
2616 SMESH::ListOfGroups*
2617 SMESH_MeshEditor_i::ExtrusionSweepObjects(const SMESH::ListOfIDSources & theNodes,
2618 const SMESH::ListOfIDSources & theEdges,
2619 const SMESH::ListOfIDSources & theFaces,
2620 const SMESH::DirStruct & theStepVector,
2621 CORBA::Long theNbOfSteps,
2622 CORBA::Boolean theToMakeGroups,
2623 const SMESH::double_array & theScaleFactors,
2624 CORBA::Boolean theScalesVariation,
2625 const SMESH::double_array & theBasePoint,
2626 const SMESH::double_array & theAngles,
2627 CORBA::Boolean theAnglesVariation)
2628 throw (SALOME::SALOME_Exception)
2633 ExtrusionParams params( theStepVector, theNbOfSteps, theScaleFactors, theScalesVariation,
2634 theAngles, theAnglesVariation, theBasePoint, theToMakeGroups );
2636 TIDSortedElemSet elemsNodes[2];
2637 for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) {
2638 if ( SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE ))
2639 while ( nIt->more() ) elemsNodes[1].insert( nIt->next() );
2641 for ( int i = 0, nb = theEdges.length(); i < nb; ++i )
2642 idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge );
2643 for ( int i = 0, nb = theFaces.length(); i < nb; ++i )
2644 idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face );
2646 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2647 SMDSAbs_ElementType previewType = SMDSAbs_All; //SMDSAbs_Face;
2648 if ( myIsPreviewMode )
2650 // if ( (*elemsNodes.begin())->GetType() == SMDSAbs_Node )
2651 // previewType = SMDSAbs_Edge;
2653 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2654 TPreviewMesh * tmpMesh = getPreviewMesh( previewType );
2655 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2656 tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid );
2657 workElements = & copyElements[0];
2659 params.SetNoGroups();
2661 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2663 ::SMESH_MeshEditor::TTElemOfElemListMap aHistory;
2664 ::SMESH_MeshEditor::PGroupIDs groupIds =
2665 getEditor().ExtrusionSweep( workElements, params, aHistory );
2667 SMESH::ListOfGroups * aGroups = theToMakeGroups ? getGroups( groupIds.get()) : 0;
2669 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2671 if ( !myIsPreviewMode )
2673 dumpGroupsList( aPythonDump, aGroups );
2674 aPythonDump << this<< ".ExtrusionSweepObjects( "
2678 << theStepVector << ", "
2679 << TVar( theNbOfSteps ) << ", "
2680 << theToMakeGroups << ", "
2681 << TVar( theScaleFactors ) << ", "
2682 << theScalesVariation << ", "
2683 << TVar( theBasePoint ) << ", "
2684 << TVar( theAngles ) << ", "
2685 << theAnglesVariation << " )";
2689 getPreviewMesh( previewType )->Remove( SMDSAbs_Volume );
2692 return aGroups ? aGroups : new SMESH::ListOfGroups;
2694 SMESH_CATCH( SMESH::throwCorbaException );
2698 //=======================================================================
2699 //function : ExtrusionByNormal
2701 //=======================================================================
2703 SMESH::ListOfGroups*
2704 SMESH_MeshEditor_i::ExtrusionByNormal(const SMESH::ListOfIDSources& objects,
2705 CORBA::Double stepSize,
2706 CORBA::Long nbOfSteps,
2707 CORBA::Boolean byAverageNormal,
2708 CORBA::Boolean useInputElemsOnly,
2709 CORBA::Boolean makeGroups,
2711 throw (SALOME::SALOME_Exception)
2716 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2718 ExtrusionParams params( stepSize, nbOfSteps, dim,
2719 byAverageNormal, useInputElemsOnly, makeGroups );
2721 SMDSAbs_ElementType elemType = ( dim == 1 ? SMDSAbs_Edge : SMDSAbs_Face );
2722 if ( objects.length() > 0 && !SMESH::DownCast<SMESH_Mesh_i*>( objects[0] ))
2724 SMESH::array_of_ElementType_var elemTypes = objects[0]->GetTypes();
2725 if (( elemTypes->length() == 1 ) &&
2726 ( elemTypes[0] == SMESH::EDGE || elemTypes[0] == SMESH::FACE ))
2727 elemType = ( SMDSAbs_ElementType ) elemTypes[0];
2730 TIDSortedElemSet elemsNodes[2];
2731 for ( int i = 0, nb = objects.length(); i < nb; ++i )
2732 idSourceToSet( objects[i], getMeshDS(), elemsNodes[0], elemType );
2734 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2735 SMDSAbs_ElementType previewType = SMDSAbs_Face;
2736 if ( myIsPreviewMode )
2738 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2739 TPreviewMesh * tmpMesh = getPreviewMesh( previewType );
2740 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2741 workElements = & copyElements[0];
2743 params.SetNoGroups();
2746 ::SMESH_MeshEditor::TTElemOfElemListMap aHistory;
2747 ::SMESH_MeshEditor::PGroupIDs groupIds =
2748 getEditor().ExtrusionSweep( workElements, params, aHistory );
2750 SMESH::ListOfGroups * aGroups = makeGroups ? getGroups( groupIds.get()) : 0;
2752 if (!myIsPreviewMode) {
2753 dumpGroupsList(aPythonDump, aGroups);
2754 aPythonDump << this << ".ExtrusionByNormal( " << objects
2755 << ", " << TVar( stepSize )
2756 << ", " << TVar( nbOfSteps )
2757 << ", " << byAverageNormal
2758 << ", " << useInputElemsOnly
2759 << ", " << makeGroups
2765 getPreviewMesh( previewType )->Remove( SMDSAbs_Volume );
2768 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2770 return aGroups ? aGroups : new SMESH::ListOfGroups;
2772 SMESH_CATCH( SMESH::throwCorbaException );
2776 //=======================================================================
2777 //function : AdvancedExtrusion
2779 //=======================================================================
2781 SMESH::ListOfGroups*
2782 SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2783 const SMESH::DirStruct & theStepVector,
2784 CORBA::Long theNbOfSteps,
2785 CORBA::Long theExtrFlags,
2786 CORBA::Double theSewTolerance,
2787 CORBA::Boolean theMakeGroups)
2788 throw (SALOME::SALOME_Exception)
2793 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2795 ExtrusionParams params( theStepVector, theNbOfSteps, theMakeGroups,
2796 theExtrFlags, theSewTolerance );
2798 TIDSortedElemSet elemsNodes[2];
2799 arrayToSet( theIDsOfElements, getMeshDS(), elemsNodes[0] );
2801 ::SMESH_MeshEditor::TTElemOfElemListMap aHistory;
2802 ::SMESH_MeshEditor::PGroupIDs groupIds =
2803 getEditor().ExtrusionSweep( elemsNodes, params, aHistory );
2805 SMESH::ListOfGroups * aGroups = theMakeGroups ? getGroups( groupIds.get()) : 0;
2807 declareMeshModified( /*isReComputeSafe=*/true ); // does not influence Compute()
2809 if ( !myIsPreviewMode ) {
2810 dumpGroupsList(aPythonDump, aGroups);
2811 aPythonDump << this << ".AdvancedExtrusion( "
2812 << theIDsOfElements << ", "
2813 << theStepVector << ", "
2814 << theNbOfSteps << ", "
2815 << theExtrFlags << ", "
2816 << theSewTolerance << ", "
2817 << theMakeGroups << " )";
2821 getPreviewMesh()->Remove( SMDSAbs_Volume );
2824 return aGroups ? aGroups : new SMESH::ListOfGroups;
2826 SMESH_CATCH( SMESH::throwCorbaException );
2830 //================================================================================
2832 * \brief Convert extrusion error to IDL enum
2834 //================================================================================
2838 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
2840 SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( ::SMESH_MeshEditor::Extrusion_Error e )
2844 RETCASE( EXTR_NO_ELEMENTS );
2845 RETCASE( EXTR_PATH_NOT_EDGE );
2846 RETCASE( EXTR_BAD_PATH_SHAPE );
2847 RETCASE( EXTR_BAD_STARTING_NODE );
2848 RETCASE( EXTR_BAD_ANGLES_NUMBER );
2849 RETCASE( EXTR_CANT_GET_TANGENT );
2851 return SMESH::SMESH_MeshEditor::EXTR_OK;
2855 //=======================================================================
2856 //function : extrusionAlongPath
2858 //=======================================================================
2859 SMESH::ListOfGroups*
2860 SMESH_MeshEditor_i::ExtrusionAlongPathObjects(const SMESH::ListOfIDSources & theNodes,
2861 const SMESH::ListOfIDSources & theEdges,
2862 const SMESH::ListOfIDSources & theFaces,
2863 SMESH::SMESH_IDSource_ptr thePathObject,
2864 GEOM::GEOM_Object_ptr thePathShape,
2865 CORBA::Long theNodeStart,
2866 CORBA::Boolean theHasAngles,
2867 const SMESH::double_array & theAngles,
2868 CORBA::Boolean theAnglesVariation,
2869 CORBA::Boolean theHasRefPoint,
2870 const SMESH::PointStruct & theRefPoint,
2872 const SMESH::double_array & theScaleFactors,
2873 CORBA::Boolean theScalesVariation,
2874 SMESH::SMESH_MeshEditor::Extrusion_Error& theError)
2875 throw (SALOME::SALOME_Exception)
2880 SMESH::ListOfGroups_var aGroups = new SMESH::ListOfGroups;
2882 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2883 if ( thePathObject->_is_nil() )
2884 return aGroups._retn();
2887 SMDS_ElemIteratorPtr pathEdgesIterator;
2889 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathObject );
2890 if ( !CORBA::is_nil( thePathShape ) && aMeshImp )
2892 // get a sub-mesh of thePathShape
2893 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2894 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2896 return aGroups._retn();
2898 if ( !aSubMesh->GetSubMeshDS() )
2900 SMESHDS_Mesh * meshDS = aMeshImp->GetImpl().GetMeshDS();
2901 meshDS->AddCompoundSubmesh( aShape, TopAbs_EDGE );
2902 if ( !aSubMesh->GetSubMeshDS() )
2903 return aGroups._retn();
2905 theError = SMESH::SMESH_MeshEditor::EXTR_PATH_NOT_EDGE;
2906 pathEdgesIterator = aSubMesh->GetSubMeshDS()->GetElements();
2907 if ( !pathEdgesIterator->more() ||
2908 pathEdgesIterator->next()->GetType() != SMDSAbs_Edge )
2909 return aGroups._retn();
2911 pathEdgesIterator = aSubMesh->GetSubMeshDS()->GetElements();
2915 theError = SMESH::SMESH_MeshEditor::EXTR_PATH_NOT_EDGE;
2916 prepareIdSource( thePathObject );
2917 pathEdgesIterator = SMESH_Mesh_i::GetElements( thePathObject, SMESH::EDGE );
2918 if ( !pathEdgesIterator || !pathEdgesIterator->more() )
2919 return aGroups._retn();
2924 SMESH::SMESH_Mesh_var pathMesh = thePathObject->GetMesh();
2925 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( pathMesh );
2929 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2930 const SMDS_MeshNode* nodeStart = aMeshImp->GetImpl().GetMeshDS()->FindNode( theNodeStart );
2932 return aGroups._retn();
2935 TIDSortedElemSet elemsNodes[2];
2936 for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) {
2937 if ( SMDS_ElemIteratorPtr nIt = myMesh_i->GetElements( theNodes[i], SMESH::NODE ))
2938 while ( nIt->more() ) elemsNodes[1].insert( nIt->next() );
2940 for ( int i = 0, nb = theEdges.length(); i < nb; ++i )
2941 idSourceToSet( theEdges[i], getMeshDS(), elemsNodes[0], SMDSAbs_Edge );
2942 for ( int i = 0, nb = theFaces.length(); i < nb; ++i )
2943 idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face );
2945 list<double> angles = ExtrusionParams::toList( theAngles );
2946 list<double> scales = ExtrusionParams::toList( theScaleFactors );
2948 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
2949 const gp_Pnt *refPntPtr = theHasRefPoint ? &refPnt : 0;
2951 int nbOldGroups = myMesh->NbGroup();
2953 TIDSortedElemSet* workElements = & elemsNodes[0], copyElements[2];
2954 if ( myIsPreviewMode )
2956 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2957 TPreviewMesh * tmpMesh = getPreviewMesh();
2958 tmpMesh->Copy( elemsNodes[0], copyElements[0], select, avoid );
2959 tmpMesh->Copy( elemsNodes[1], copyElements[1], select, avoid );
2960 workElements = & copyElements[0];
2961 theMakeGroups = false;
2964 ::SMESH_MeshEditor::Extrusion_Error error =
2965 getEditor().ExtrusionAlongTrack( workElements,
2966 &(aMeshImp->GetImpl()), pathEdgesIterator, nodeStart,
2967 angles, theAnglesVariation,
2968 scales, theScalesVariation,
2969 refPntPtr, theMakeGroups );
2971 declareMeshModified( /*isReComputeSafe=*/true );
2972 theError = convExtrError( error );
2974 TPythonDump aPythonDump; // it is here to prevent dump of getGroups()
2975 if ( theMakeGroups ) {
2976 list<int> groupIDs = myMesh->GetGroupIds();
2977 list<int>::iterator newBegin = groupIDs.begin();
2978 std::advance( newBegin, nbOldGroups ); // skip old groups
2979 groupIDs.erase( groupIDs.begin(), newBegin );
2980 aGroups = getGroups( & groupIDs );
2981 if ( ! &aGroups.in() ) aGroups = new SMESH::ListOfGroups;
2984 if ( !myIsPreviewMode ) {
2985 if ( aGroups->length() > 0 ) aPythonDump << "(" << aGroups << ", error) = ";
2986 else aPythonDump << "(_noGroups, error) = ";
2987 aPythonDump << this << ".ExtrusionAlongPathObjects( "
2991 << thePathObject << ", "
2992 << thePathShape << ", "
2993 << theNodeStart << ", "
2994 << theHasAngles << ", "
2995 << TVar( theAngles ) << ", "
2996 << theAnglesVariation << ", "
2997 << theHasRefPoint << ", "
2998 << "SMESH.PointStruct( "
2999 << TVar( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3000 << TVar( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3001 << TVar( theHasRefPoint ? theRefPoint.z : 0 ) << " ), "
3002 << theMakeGroups << ", "
3003 << TVar( theScaleFactors ) << ", "
3004 << theScalesVariation << " )";
3008 getPreviewMesh()->Remove( SMDSAbs_Volume );
3011 return aGroups._retn();
3013 SMESH_CATCH( SMESH::throwCorbaException );
3017 //================================================================================
3019 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
3020 * of given angles along path steps
3021 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
3022 * which proceeds the extrusion
3023 * \param PathShape is shape(edge); as the mesh can be complex, the edge
3024 * is used to define the sub-mesh for the path
3026 //================================================================================
3028 SMESH::double_array*
3029 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
3030 GEOM::GEOM_Object_ptr thePathShape,
3031 const SMESH::double_array & theAngles)
3033 SMESH::double_array_var aResult = new SMESH::double_array();
3034 int nbAngles = theAngles.length();
3035 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
3037 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3038 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3039 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3040 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
3041 return aResult._retn();
3042 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
3043 if ( nbSteps == nbAngles )
3045 aResult.inout() = theAngles;
3049 aResult->length( nbSteps );
3050 double rAn2St = double( nbAngles ) / double( nbSteps );
3051 double angPrev = 0, angle;
3052 for ( int iSt = 0; iSt < nbSteps; ++iSt )
3054 double angCur = rAn2St * ( iSt+1 );
3055 double angCurFloor = floor( angCur );
3056 double angPrevFloor = floor( angPrev );
3057 if ( angPrevFloor == angCurFloor )
3058 angle = rAn2St * theAngles[ int( angCurFloor ) ];
3061 int iP = int( angPrevFloor );
3062 double angPrevCeil = ceil(angPrev);
3063 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
3065 int iC = int( angCurFloor );
3066 if ( iC < nbAngles )
3067 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
3069 iP = int( angPrevCeil );
3071 angle += theAngles[ iC ];
3073 aResult[ iSt ] = angle;
3078 // Update Python script
3079 TPythonDump() << "rotAngles = " << theAngles;
3080 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
3081 << thePathMesh << ", "
3082 << thePathShape << ", "
3085 return aResult._retn();
3088 //=======================================================================
3091 //=======================================================================
3093 SMESH::ListOfGroups*
3094 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
3095 const SMESH::AxisStruct & theAxis,
3096 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3097 CORBA::Boolean theCopy,
3099 ::SMESH_Mesh* theTargetMesh)
3100 throw (SALOME::SALOME_Exception)
3105 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3106 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3108 if ( theTargetMesh )
3112 switch ( theMirrorType ) {
3113 case SMESH::SMESH_MeshEditor::POINT:
3114 aTrsf.SetMirror( P );
3116 case SMESH::SMESH_MeshEditor::AXIS:
3117 aTrsf.SetMirror( gp_Ax1( P, V ));
3120 aTrsf.SetMirror( gp_Ax2( P, V ));
3123 TIDSortedElemSet copyElements;
3124 TIDSortedElemSet* workElements = & theElements;
3126 if ( myIsPreviewMode )
3128 TPreviewMesh * tmpMesh = getPreviewMesh();
3129 tmpMesh->Copy( theElements, copyElements);
3130 if ( !theCopy && !theTargetMesh )
3132 TIDSortedElemSet elemsAround, elemsAroundCopy;
3133 getElementsAround( theElements, getMeshDS(), elemsAround );
3134 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3136 workElements = & copyElements;
3137 theMakeGroups = false;
3140 ::SMESH_MeshEditor::PGroupIDs groupIds =
3141 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3143 if ( !myIsPreviewMode )
3145 if ( theTargetMesh )
3146 theTargetMesh->GetMeshDS()->Modified();
3148 declareMeshModified( /*isReComputeSafe=*/false );
3151 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3153 SMESH_CATCH( SMESH::throwCorbaException );
3157 //=======================================================================
3160 //=======================================================================
3162 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3163 const SMESH::AxisStruct & theAxis,
3164 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3165 CORBA::Boolean theCopy)
3166 throw (SALOME::SALOME_Exception)
3168 if ( !myIsPreviewMode ) {
3169 TPythonDump() << this << ".Mirror( "
3170 << theIDsOfElements << ", "
3172 << mirrorTypeName(theMirrorType) << ", "
3175 if ( theIDsOfElements.length() > 0 )
3177 TIDSortedElemSet elements;
3178 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3179 mirror(elements, theAxis, theMirrorType, theCopy, false);
3184 //=======================================================================
3185 //function : MirrorObject
3187 //=======================================================================
3189 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3190 const SMESH::AxisStruct & theAxis,
3191 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3192 CORBA::Boolean theCopy)
3193 throw (SALOME::SALOME_Exception)
3195 if ( !myIsPreviewMode ) {
3196 TPythonDump() << this << ".MirrorObject( "
3197 << theObject << ", "
3199 << mirrorTypeName(theMirrorType) << ", "
3202 TIDSortedElemSet elements;
3204 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3206 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3207 mirror(elements, theAxis, theMirrorType, theCopy, false);
3210 //=======================================================================
3211 //function : MirrorMakeGroups
3213 //=======================================================================
3215 SMESH::ListOfGroups*
3216 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3217 const SMESH::AxisStruct& theMirror,
3218 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3219 throw (SALOME::SALOME_Exception)
3221 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3223 SMESH::ListOfGroups * aGroups = 0;
3224 if ( theIDsOfElements.length() > 0 )
3226 TIDSortedElemSet elements;
3227 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3228 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3230 if (!myIsPreviewMode) {
3231 dumpGroupsList(aPythonDump, aGroups);
3232 aPythonDump << this << ".MirrorMakeGroups( "
3233 << theIDsOfElements << ", "
3234 << theMirror << ", "
3235 << mirrorTypeName(theMirrorType) << " )";
3240 //=======================================================================
3241 //function : MirrorObjectMakeGroups
3243 //=======================================================================
3245 SMESH::ListOfGroups*
3246 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3247 const SMESH::AxisStruct& theMirror,
3248 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3249 throw (SALOME::SALOME_Exception)
3251 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3253 SMESH::ListOfGroups * aGroups = 0;
3254 TIDSortedElemSet elements;
3255 if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3256 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3258 if (!myIsPreviewMode)
3260 dumpGroupsList(aPythonDump,aGroups);
3261 aPythonDump << this << ".MirrorObjectMakeGroups( "
3262 << theObject << ", "
3263 << theMirror << ", "
3264 << mirrorTypeName(theMirrorType) << " )";
3269 //=======================================================================
3270 //function : MirrorMakeMesh
3272 //=======================================================================
3274 SMESH::SMESH_Mesh_ptr
3275 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
3276 const SMESH::AxisStruct& theMirror,
3277 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3278 CORBA::Boolean theCopyGroups,
3279 const char* theMeshName)
3280 throw (SALOME::SALOME_Exception)
3282 SMESH_Mesh_i* mesh_i;
3283 SMESH::SMESH_Mesh_var mesh;
3284 { // open new scope to dump "MakeMesh" command
3285 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3287 TPythonDump pydump; // to prevent dump at mesh creation
3289 mesh = makeMesh( theMeshName );
3290 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3291 if (mesh_i && theIDsOfElements.length() > 0 )
3293 TIDSortedElemSet elements;
3294 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3295 mirror(elements, theMirror, theMirrorType,
3296 false, theCopyGroups, & mesh_i->GetImpl());
3297 mesh_i->CreateGroupServants();
3300 if (!myIsPreviewMode) {
3301 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
3302 << theIDsOfElements << ", "
3303 << theMirror << ", "
3304 << mirrorTypeName(theMirrorType) << ", "
3305 << theCopyGroups << ", '"
3306 << theMeshName << "' )";
3311 if (!myIsPreviewMode && mesh_i)
3312 mesh_i->GetGroups();
3314 return mesh._retn();
3317 //=======================================================================
3318 //function : MirrorObjectMakeMesh
3320 //=======================================================================
3322 SMESH::SMESH_Mesh_ptr
3323 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3324 const SMESH::AxisStruct& theMirror,
3325 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3326 CORBA::Boolean theCopyGroups,
3327 const char* theMeshName)
3328 throw (SALOME::SALOME_Exception)
3330 SMESH_Mesh_i* mesh_i;
3331 SMESH::SMESH_Mesh_var mesh;
3332 { // open new scope to dump "MakeMesh" command
3333 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3335 TPythonDump pydump; // to prevent dump at mesh creation
3337 mesh = makeMesh( theMeshName );
3338 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3339 TIDSortedElemSet elements;
3341 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3343 mirror(elements, theMirror, theMirrorType,
3344 false, theCopyGroups, & mesh_i->GetImpl());
3345 mesh_i->CreateGroupServants();
3347 if (!myIsPreviewMode) {
3348 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
3349 << theObject << ", "
3350 << theMirror << ", "
3351 << mirrorTypeName(theMirrorType) << ", "
3352 << theCopyGroups << ", '"
3353 << theMeshName << "' )";
3358 if (!myIsPreviewMode && mesh_i)
3359 mesh_i->GetGroups();
3361 return mesh._retn();
3364 //=======================================================================
3365 //function : translate
3367 //=======================================================================
3369 SMESH::ListOfGroups*
3370 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
3371 const SMESH::DirStruct & theVector,
3372 CORBA::Boolean theCopy,
3374 ::SMESH_Mesh* theTargetMesh)
3375 throw (SALOME::SALOME_Exception)
3380 if ( theTargetMesh )
3384 const SMESH::PointStruct * P = &theVector.PS;
3385 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
3387 TIDSortedElemSet copyElements;
3388 TIDSortedElemSet* workElements = &theElements;
3390 if ( myIsPreviewMode )
3392 TPreviewMesh * tmpMesh = getPreviewMesh();
3393 tmpMesh->Copy( theElements, copyElements);
3394 if ( !theCopy && !theTargetMesh )
3396 TIDSortedElemSet elemsAround, elemsAroundCopy;
3397 getElementsAround( theElements, getMeshDS(), elemsAround );
3398 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3400 workElements = & copyElements;
3401 theMakeGroups = false;
3404 ::SMESH_MeshEditor::PGroupIDs groupIds =
3405 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3407 if ( !myIsPreviewMode )
3409 if ( theTargetMesh )
3410 theTargetMesh->GetMeshDS()->Modified();
3412 declareMeshModified( /*isReComputeSafe=*/false );
3415 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3417 SMESH_CATCH( SMESH::throwCorbaException );
3421 //=======================================================================
3422 //function : Translate
3424 //=======================================================================
3426 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
3427 const SMESH::DirStruct & theVector,
3428 CORBA::Boolean theCopy)
3429 throw (SALOME::SALOME_Exception)
3431 if (!myIsPreviewMode) {
3432 TPythonDump() << this << ".Translate( "
3433 << theIDsOfElements << ", "
3434 << theVector << ", "
3437 if (theIDsOfElements.length()) {
3438 TIDSortedElemSet elements;
3439 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3440 translate(elements, theVector, theCopy, false);
3444 //=======================================================================
3445 //function : TranslateObject
3447 //=======================================================================
3449 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
3450 const SMESH::DirStruct & theVector,
3451 CORBA::Boolean theCopy)
3452 throw (SALOME::SALOME_Exception)
3454 if (!myIsPreviewMode) {
3455 TPythonDump() << this << ".TranslateObject( "
3456 << theObject << ", "
3457 << theVector << ", "
3460 TIDSortedElemSet elements;
3462 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3464 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3465 translate(elements, theVector, theCopy, false);
3468 //=======================================================================
3469 //function : TranslateMakeGroups
3471 //=======================================================================
3473 SMESH::ListOfGroups*
3474 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
3475 const SMESH::DirStruct& theVector)
3476 throw (SALOME::SALOME_Exception)
3478 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3480 SMESH::ListOfGroups * aGroups = 0;
3481 if (theIDsOfElements.length()) {
3482 TIDSortedElemSet elements;
3483 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3484 aGroups = translate(elements,theVector,true,true);
3486 if (!myIsPreviewMode) {
3487 dumpGroupsList(aPythonDump, aGroups);
3488 aPythonDump << this << ".TranslateMakeGroups( "
3489 << theIDsOfElements << ", "
3490 << theVector << " )";
3495 //=======================================================================
3496 //function : TranslateObjectMakeGroups
3498 //=======================================================================
3500 SMESH::ListOfGroups*
3501 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3502 const SMESH::DirStruct& theVector)
3503 throw (SALOME::SALOME_Exception)