1 // Copyright (C) 2007-2012 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.
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 #include "SMESH_MeshEditor_i.hxx"
32 #include "DriverMED_R_SMESHDS_Mesh.h"
33 #include "DriverMED_W_SMESHDS_Mesh.h"
34 #include "SMDS_EdgePosition.hxx"
35 #include "SMDS_ElemIterator.hxx"
36 #include "SMDS_FacePosition.hxx"
37 #include "SMDS_IteratorOnIterators.hxx"
38 #include "SMDS_LinearEdge.hxx"
39 #include "SMDS_Mesh0DElement.hxx"
40 #include "SMDS_MeshFace.hxx"
41 #include "SMDS_MeshVolume.hxx"
42 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
43 #include "SMDS_SetIterator.hxx"
44 #include "SMDS_SetIterator.hxx"
45 #include "SMDS_VolumeTool.hxx"
46 #include "SMESHDS_Command.hxx"
47 #include "SMESHDS_CommandType.hxx"
48 #include "SMESHDS_Group.hxx"
49 #include "SMESHDS_GroupOnGeom.hxx"
50 #include "SMESH_ControlsDef.hxx"
51 #include "SMESH_Filter_i.hxx"
52 #include "SMESH_Filter_i.hxx"
53 #include "SMESH_Gen_i.hxx"
54 #include "SMESH_Gen_i.hxx"
55 #include "SMESH_Group.hxx"
56 #include "SMESH_Group_i.hxx"
57 #include "SMESH_Group_i.hxx"
58 #include "SMESH_MEDMesh_i.hxx"
59 #include "SMESH_MeshEditor.hxx"
60 #include "SMESH_MeshPartDS.hxx"
61 #include "SMESH_MesherHelper.hxx"
62 #include "SMESH_PreMeshInfo.hxx"
63 #include "SMESH_PythonDump.hxx"
64 #include "SMESH_PythonDump.hxx"
65 #include "SMESH_subMeshEventListener.hxx"
66 #include "SMESH_subMesh_i.hxx"
67 #include "SMESH_subMesh_i.hxx"
69 #include "utilities.h"
70 #include "Utils_ExceptHandlers.hxx"
71 #include "Utils_CorbaException.hxx"
73 #include <BRepAdaptor_Surface.hxx>
74 #include <BRep_Tool.hxx>
75 #include <TopExp_Explorer.hxx>
77 #include <TopoDS_Edge.hxx>
78 #include <TopoDS_Face.hxx>
83 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
87 #include <Standard_Failure.hxx>
90 #include <Standard_ErrorHandler.hxx>
96 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
99 using SMESH::TPythonDump;
102 namespace MeshEditor_I {
104 //=============================================================================
106 * \brief Mesh to apply modifications for preview purposes
108 //=============================================================================
110 struct TPreviewMesh: public SMESH_Mesh
112 SMDSAbs_ElementType myPreviewType; // type to show
114 TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
115 _isShapeToMesh = (_id =_studyId =_idDoc = 0);
116 _myMeshDS = new SMESHDS_Mesh( _id, true );
117 myPreviewType = previewElements;
120 virtual ~TPreviewMesh() { delete _myMeshDS; _myMeshDS = 0; }
121 //!< Copy a set of elements
122 void Copy(const TIDSortedElemSet & theElements,
123 TIDSortedElemSet& theCopyElements,
124 SMDSAbs_ElementType theSelectType = SMDSAbs_All,
125 SMDSAbs_ElementType theAvoidType = SMDSAbs_All)
127 // loop on theIDsOfElements
128 TIDSortedElemSet::const_iterator eIt = theElements.begin();
129 for ( ; eIt != theElements.end(); ++eIt )
131 const SMDS_MeshElement* anElem = *eIt;
132 if ( !anElem ) continue;
133 SMDSAbs_ElementType type = anElem->GetType();
134 if ( type == theAvoidType ||
135 ( theSelectType != SMDSAbs_All && type != theSelectType ))
137 const SMDS_MeshElement* anElemCopy;
138 if ( type == SMDSAbs_Node)
139 anElemCopy = Copy( cast2Node(anElem) );
141 anElemCopy = Copy( anElem );
143 theCopyElements.insert( theCopyElements.end(), anElemCopy );
147 SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
149 // copy element nodes
150 int anElemNbNodes = anElem->NbNodes();
151 vector< int > anElemNodesID( anElemNbNodes ) ;
152 SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
153 for ( int i = 0; itElemNodes->more(); i++)
155 const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
157 anElemNodesID[i] = anElemNode->GetID();
160 // creates a corresponding element on copied nodes
161 SMDS_MeshElement* anElemCopy = 0;
162 if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
164 const SMDS_VtkVolume* ph =
165 dynamic_cast<const SMDS_VtkVolume*> (anElem);
167 anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
168 (anElemNodesID, ph->GetQuantities(),anElem->GetID());
171 anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
178 SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
180 return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(),
181 anElemNode->GetID());
183 };// struct TPreviewMesh
185 static SMESH_NodeSearcher * theNodeSearcher = 0;
186 static SMESH_ElementSearcher * theElementSearcher = 0;
188 //=============================================================================
190 * \brief Deleter of theNodeSearcher at any compute event occured
192 //=============================================================================
194 struct TSearchersDeleter : public SMESH_subMeshEventListener
197 string myMeshPartIOR;
199 TSearchersDeleter(): SMESH_subMeshEventListener( false, // won't be deleted by submesh
200 "SMESH_MeshEditor_i::TSearchersDeleter"),
202 //!< Delete theNodeSearcher
205 if ( theNodeSearcher ) delete theNodeSearcher; theNodeSearcher = 0;
206 if ( theElementSearcher ) delete theElementSearcher; theElementSearcher = 0;
208 typedef map < int, SMESH_subMesh * > TDependsOnMap;
209 //!< The meshod called by submesh: do my main job
210 void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
211 SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
213 if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
215 Unset( sm->GetFather() );
218 //!< set self on all submeshes and delete theNodeSearcher if other mesh is set
219 void Set(SMESH_Mesh* mesh, const string& meshPartIOR = string())
221 if ( myMesh != mesh || myMeshPartIOR != meshPartIOR)
228 myMeshPartIOR = meshPartIOR;
229 if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
230 const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
231 TDependsOnMap::const_iterator sm;
232 for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
233 sm->second->SetEventListener( this, 0, sm->second );
237 //!< delete self from all submeshes
238 void Unset(SMESH_Mesh* mesh)
240 if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
241 const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
242 TDependsOnMap::const_iterator sm;
243 for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
244 sm->second->DeleteEventListener( this );
249 } theSearchersDeleter;
251 TCollection_AsciiString mirrorTypeName( SMESH::SMESH_MeshEditor::MirrorType theMirrorType )
253 TCollection_AsciiString typeStr;
254 switch ( theMirrorType ) {
255 case SMESH::SMESH_MeshEditor::POINT:
256 typeStr = "SMESH.SMESH_MeshEditor.POINT";
258 case SMESH::SMESH_MeshEditor::AXIS:
259 typeStr = "SMESH.SMESH_MeshEditor.AXIS";
262 typeStr = "SMESH.SMESH_MeshEditor.PLANE";
266 //================================================================================
268 * \brief function for conversion of long_array to TIDSortedElemSet
269 * \param IDs - array of IDs
270 * \param aMesh - mesh
271 * \param aMap - collection to fill
272 * \param aType - element type
274 //================================================================================
276 void arrayToSet(const SMESH::long_array & IDs,
277 const SMESHDS_Mesh* aMesh,
278 TIDSortedElemSet& aMap,
279 const SMDSAbs_ElementType aType = SMDSAbs_All )
281 for (int i=0; i<IDs.length(); i++) {
282 CORBA::Long ind = IDs[i];
283 const SMDS_MeshElement * elem =
284 (aType == SMDSAbs_Node ? aMesh->FindNode(ind) : aMesh->FindElement(ind));
285 if ( elem && ( aType == SMDSAbs_All || elem->GetType() == aType ))
286 aMap.insert( aMap.end(), elem );
289 //================================================================================
291 * \brief Retrieve elements of given type from SMESH_IDSource
293 //================================================================================
295 bool idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource,
296 const SMESHDS_Mesh* theMeshDS,
297 TIDSortedElemSet& theElemSet,
298 const SMDSAbs_ElementType theType,
299 const bool emptyIfIsMesh=false)
302 if ( CORBA::is_nil( theIDSource ) )
304 if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
307 SMESH::long_array_var anIDs = theIDSource->GetIDs();
308 if ( anIDs->length() == 0 )
310 SMESH::array_of_ElementType_var types = theIDSource->GetTypes();
311 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
313 if ( theType == SMDSAbs_All || theType == SMDSAbs_Node )
314 arrayToSet( anIDs, theMeshDS, theElemSet, SMDSAbs_Node );
320 arrayToSet( anIDs, theMeshDS, theElemSet, theType);
321 return bool(anIDs->length()) == bool(theElemSet.size());
325 //================================================================================
327 * \brief Retrieve nodes from SMESH_IDSource
329 //================================================================================
331 void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject,
332 const SMESHDS_Mesh* theMeshDS,
333 TIDSortedNodeSet& theNodeSet)
336 if ( CORBA::is_nil( theObject ) )
338 SMESH::array_of_ElementType_var types = theObject->GetTypes();
339 SMESH::long_array_var aElementsId = theObject->GetIDs();
340 if ( types->length() == 1 && types[0] == SMESH::NODE)
342 for(int i = 0; i < aElementsId->length(); i++)
343 if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] ))
344 theNodeSet.insert( theNodeSet.end(), n);
346 else if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
348 SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator();
349 while ( nIt->more( ))
350 if( const SMDS_MeshElement * elem = nIt->next() )
351 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
355 for(int i = 0; i < aElementsId->length(); i++)
356 if( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] ))
357 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
361 //================================================================================
363 * \brief Returns elements connected to the given elements
365 //================================================================================
367 void getElementsAround(const TIDSortedElemSet& theElements,
368 const SMESHDS_Mesh* theMeshDS,
369 TIDSortedElemSet& theElementsAround)
371 if ( theElements.empty() ) return;
373 SMDSAbs_ElementType elemType = (*theElements.begin())->GetType();
374 bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() );
376 theMeshDS->GetMeshInfo().NbElements( elemType ) == theElements.size() )
377 return; // all the elements are in theElements
380 elemType = SMDSAbs_All;
382 TIDSortedElemSet visitedNodes;
383 TIDSortedElemSet::const_iterator elemIt = theElements.begin();
384 for ( ; elemIt != theElements.end(); ++elemIt )
386 const SMDS_MeshElement* e = *elemIt;
387 int i = e->NbCornerNodes();
390 const SMDS_MeshNode* n = e->GetNode( i );
391 if ( visitedNodes.insert( n ).second )
393 SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
394 while ( invIt->more() )
396 const SMDS_MeshElement* elemAround = invIt->next();
397 if ( !theElements.count( elemAround ))
398 theElementsAround.insert( elemAround );
405 //================================================================================
407 * \brief Return a string used to detect change of mesh part on which theElementSearcher
408 * is going to be used
410 //================================================================================
412 string getPartIOR( SMESH::SMESH_IDSource_ptr theMeshPart, SMESH::ElementType type)
414 string partIOR = SMESH_Gen_i::GetORB()->object_to_string( theMeshPart );
415 if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( theMeshPart ))
416 // take into account passible group modification
417 partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() );
418 partIOR += SMESH_Comment( type );
422 } // namespace MeshEditor_I
424 using namespace MeshEditor_I;
426 //=============================================================================
430 //=============================================================================
432 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview):
434 myMesh( &theMesh->GetImpl() ),
436 myIsPreviewMode ( isPreview ),
442 //================================================================================
446 //================================================================================
448 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
450 deleteAuxIDSources();
451 delete myPreviewMesh; myPreviewMesh = 0;
452 delete myPreviewEditor; myPreviewEditor = 0;
455 //================================================================================
457 * \brief Clear members
459 //================================================================================
461 void SMESH_MeshEditor_i::initData(bool deleteSearchers)
463 if ( myIsPreviewMode ) {
464 if ( myPreviewMesh ) myPreviewMesh->Clear();
467 if ( deleteSearchers )
468 TSearchersDeleter::Delete();
470 getEditor().GetError().reset();
471 getEditor().CrearLastCreated();
473 //================================================================================
475 * \brief Return either myEditor or myPreviewEditor depending on myIsPreviewMode.
476 * WARNING: in preview mode call getPreviewMesh() before getEditor()!
478 //================================================================================
480 ::SMESH_MeshEditor& SMESH_MeshEditor_i::getEditor()
482 if ( myIsPreviewMode && !myPreviewEditor ) {
483 if ( !myPreviewMesh ) getPreviewMesh();
484 myPreviewEditor = new ::SMESH_MeshEditor( myPreviewMesh );
486 return myIsPreviewMode ? *myPreviewEditor : myEditor;
489 //================================================================================
491 * \brief Initialize and return myPreviewMesh
492 * \param previewElements - type of elements to show in preview
494 * WARNING: call it once par a method!
496 //================================================================================
498 TPreviewMesh * SMESH_MeshEditor_i::getPreviewMesh(SMDSAbs_ElementType previewElements)
500 if ( !myPreviewMesh || myPreviewMesh->myPreviewType != previewElements )
502 delete myPreviewEditor;
504 delete myPreviewMesh;
505 myPreviewMesh = new TPreviewMesh( previewElements );
507 myPreviewMesh->Clear();
508 return myPreviewMesh;
511 //================================================================================
513 * \brief Now does nothing
515 //================================================================================
517 // void SMESH_MeshEditor_i::storeResult(::SMESH_MeshEditor& )
521 //================================================================================
523 * Return data of mesh edition preview
525 //================================================================================
527 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
529 const bool hasBadElems = ( getEditor().GetError() && getEditor().GetError()->HasBadElems() );
531 if ( myIsPreviewMode || hasBadElems ) { // --- MeshPreviewStruct filling ---
533 list<int> aNodesConnectivity;
534 typedef map<int, int> TNodesMap;
537 SMESHDS_Mesh* aMeshDS;
538 std::auto_ptr< SMESH_MeshPartDS > aMeshPartDS;
540 aMeshPartDS.reset( new SMESH_MeshPartDS( getEditor().GetError()->myBadElements ));
541 aMeshDS = aMeshPartDS.get();
544 aMeshDS = getEditor().GetMeshDS();
546 int nbEdges = aMeshDS->NbEdges();
547 int nbFaces = aMeshDS->NbFaces();
548 int nbVolum = aMeshDS->NbVolumes();
549 myPreviewData = new SMESH::MeshPreviewStruct();
550 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
553 SMDSAbs_ElementType previewType = SMDSAbs_All;
555 if (TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( getEditor().GetMesh() )) {
556 previewType = aPreviewMesh->myPreviewType;
557 switch ( previewType ) {
558 case SMDSAbs_Edge : nbFaces = nbVolum = 0; break;
559 case SMDSAbs_Face : nbEdges = nbVolum = 0; break;
560 case SMDSAbs_Volume: nbEdges = nbFaces = 0; break;
565 myPreviewData->elementTypes.length(nbEdges + nbFaces + nbVolum);
567 SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator(previewType);
569 while ( itMeshElems->more() ) {
570 const SMDS_MeshElement* aMeshElem = itMeshElems->next();
571 SMDS_ElemIteratorPtr itElemNodes = aMeshElem->nodesIterator();
572 while ( itElemNodes->more() ) {
573 const SMDS_MeshNode* aMeshNode =
574 static_cast<const SMDS_MeshNode*>( itElemNodes->next() );
575 int aNodeID = aMeshNode->GetID();
576 TNodesMap::iterator anIter = nodesMap.find(aNodeID);
577 if ( anIter == nodesMap.end() ) {
578 // filling the nodes coordinates
579 myPreviewData->nodesXYZ[j].x = aMeshNode->X();
580 myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
581 myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
582 anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
585 aNodesConnectivity.push_back(anIter->second);
588 // filling the elements types
589 SMDSAbs_ElementType aType = aMeshElem->GetType();
590 bool isPoly = aMeshElem->IsPoly();
592 myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
593 myPreviewData->elementTypes[i].isPoly = isPoly;
594 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;
607 return myPreviewData._retn();
610 //================================================================================
612 * \brief Returns list of it's IDs of created nodes
613 * \retval SMESH::long_array* - list of node ID
615 //================================================================================
617 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
619 SMESH::long_array_var myLastCreatedNodes = new SMESH::long_array();
620 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedNodes();
621 myLastCreatedNodes->length( aSeq.Length() );
622 for (int i = 1; i <= aSeq.Length(); i++)
623 myLastCreatedNodes[i-1] = aSeq.Value(i)->GetID();
624 return myLastCreatedNodes._retn();
627 //================================================================================
629 * \brief Returns list of it's IDs of created elements
630 * \retval SMESH::long_array* - list of elements' ID
632 //================================================================================
634 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
636 SMESH::long_array_var myLastCreatedElems = new SMESH::long_array();
637 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
638 myLastCreatedElems->length( aSeq.Length() );
639 for ( int i = 1; i <= aSeq.Length(); i++ )
640 myLastCreatedElems[i-1] = aSeq.Value(i)->GetID();
641 return myLastCreatedElems._retn();
644 //=======================================================================
646 * Returns description of an error/warning occured during the last operation
648 //=======================================================================
650 SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError()
652 SMESH::ComputeError* errOut = new SMESH::ComputeError;
653 SMESH_ComputeErrorPtr& errIn = getEditor().GetError();
654 if ( errIn && !errIn->IsOK() )
656 errOut->code = -( errIn->myName < 0 ? errIn->myName + 1: errIn->myName ); // -1 -> 0
657 errOut->comment = errIn->myComment.c_str();
658 errOut->subShapeID = -1;
659 errOut->hasBadMesh = !errIn->myBadElements.empty();
664 //=======================================================================
665 //function : MakeIDSource
666 //purpose : Wrap a sequence of ids in a SMESH_IDSource
667 //=======================================================================
669 struct SMESH_MeshEditor_i::_IDSource : public POA_SMESH::SMESH_IDSource
671 SMESH::long_array _ids;
672 SMESH::ElementType _type;
673 SMESH::SMESH_Mesh_ptr _mesh;
674 SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); }
675 SMESH::long_array* GetMeshInfo() { return 0; }
676 SMESH::SMESH_Mesh_ptr GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _mesh ); }
677 bool IsMeshInfoCorrect() { return true; }
678 SMESH::array_of_ElementType* GetTypes()
680 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
681 if ( _ids.length() > 0 ) {
685 return types._retn();
689 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
690 SMESH::ElementType type)
692 if ( myAuxIDSources.size() > 10 )
693 deleteAuxIDSources();
695 _IDSource* idSrc = new _IDSource;
696 idSrc->_mesh = myMesh_i->_this();
699 myAuxIDSources.push_back( idSrc );
701 SMESH::SMESH_IDSource_var anIDSourceVar = idSrc->_this();
703 return anIDSourceVar._retn();
706 void SMESH_MeshEditor_i::deleteAuxIDSources()
708 std::list< _IDSource* >::iterator idSrcIt = myAuxIDSources.begin();
709 for ( ; idSrcIt != myAuxIDSources.end(); ++idSrcIt )
711 myAuxIDSources.clear();
714 //=============================================================================
718 //=============================================================================
721 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
727 for (int i = 0; i < IDsOfElements.length(); i++)
728 IdList.push_back( IDsOfElements[i] );
730 // Update Python script
731 TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
734 bool ret = getEditor().Remove( IdList, false );
735 myMesh->GetMeshDS()->Modified();
736 if ( IDsOfElements.length() )
737 myMesh->SetIsModified( true ); // issue 0020693
741 //=============================================================================
745 //=============================================================================
747 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
752 for (int i = 0; i < IDsOfNodes.length(); i++)
753 IdList.push_back( IDsOfNodes[i] );
755 // Update Python script
756 TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
758 bool ret = getEditor().Remove( IdList, true );
759 myMesh->GetMeshDS()->Modified();
760 if ( IDsOfNodes.length() )
761 myMesh->SetIsModified( true ); // issue 0020693
765 //=============================================================================
769 //=============================================================================
771 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
776 // Update Python script
777 TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
779 // Create filter to find all orphan nodes
780 SMESH::Controls::Filter::TIdSequence seq;
781 SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
782 SMESH::Controls::Filter::GetElementsId( getMeshDS(), predicate, seq );
784 // remove orphan nodes (if there are any)
786 for ( int i = 0; i < seq.size(); i++ )
787 IdList.push_back( seq[i] );
789 int nbNodesBefore = myMesh->NbNodes();
790 getEditor().Remove( IdList, true );
791 myMesh->GetMeshDS()->Modified();
793 myMesh->SetIsModified( true );
794 int nbNodesAfter = myMesh->NbNodes();
796 return nbNodesBefore - nbNodesAfter;
799 //=============================================================================
803 //=============================================================================
805 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,
806 CORBA::Double y, CORBA::Double z)
810 const SMDS_MeshNode* N = getMeshDS()->AddNode(x, y, z);
812 // Update Python script
813 TPythonDump() << "nodeID = " << this << ".AddNode( "
814 << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )";
816 myMesh->GetMeshDS()->Modified();
817 myMesh->SetIsModified( true ); // issue 0020693
821 //=============================================================================
823 * Create 0D element on the given node.
825 //=============================================================================
827 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
831 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
832 SMDS_MeshElement* elem = getMeshDS()->Add0DElement(aNode);
834 // Update Python script
835 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
837 myMesh->GetMeshDS()->Modified();
838 myMesh->SetIsModified( true ); // issue 0020693
841 return elem->GetID();
846 //=============================================================================
848 * Create a ball element on the given node.
850 //=============================================================================
852 CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diameter)
853 throw (SALOME::SALOME_Exception)
857 if ( diameter < std::numeric_limits<double>::min() )
858 THROW_SALOME_CORBA_EXCEPTION("Invalid diameter", SALOME::BAD_PARAM);
860 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
861 SMDS_MeshElement* elem = getMeshDS()->AddBall(aNode, diameter);
863 // Update Python script
864 TPythonDump() << "ballElem = "
865 << this << ".AddBall( " << IDOfNode << ", " << diameter <<" )";
867 myMesh->GetMeshDS()->Modified();
868 myMesh->SetIsModified( true ); // issue 0020693
871 return elem->GetID();
876 //=============================================================================
878 * Create an edge, either linear and quadratic (this is determed
879 * by number of given nodes, two or three)
881 //=============================================================================
883 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
887 int NbNodes = IDsOfNodes.length();
888 SMDS_MeshElement* elem = 0;
891 CORBA::Long index1 = IDsOfNodes[0];
892 CORBA::Long index2 = IDsOfNodes[1];
893 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(index1),
894 getMeshDS()->FindNode(index2));
896 // Update Python script
897 TPythonDump() << "edge = " << this << ".AddEdge([ "
898 << index1 << ", " << index2 <<" ])";
901 CORBA::Long n1 = IDsOfNodes[0];
902 CORBA::Long n2 = IDsOfNodes[1];
903 CORBA::Long n12 = IDsOfNodes[2];
904 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(n1),
905 getMeshDS()->FindNode(n2),
906 getMeshDS()->FindNode(n12));
907 // Update Python script
908 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
909 <<n1<<", "<<n2<<", "<<n12<<" ])";
912 myMesh->GetMeshDS()->Modified();
914 return myMesh->SetIsModified( true ), elem->GetID();
919 //=============================================================================
923 //=============================================================================
925 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
929 int NbNodes = IDsOfNodes.length();
935 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
936 for (int i = 0; i < NbNodes; i++)
937 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
939 SMDS_MeshElement* elem = 0;
941 elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]);
943 else if (NbNodes == 4) {
944 elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]);
946 else if (NbNodes == 6) {
947 elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
950 else if (NbNodes == 8) {
951 elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
952 nodes[4], nodes[5], nodes[6], nodes[7]);
954 else if (NbNodes == 9) {
955 elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
956 nodes[4], nodes[5], nodes[6], nodes[7], nodes[8] );
958 else if (NbNodes > 2) {
959 elem = getMeshDS()->AddPolygonalFace(nodes);
962 // Update Python script
963 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
965 myMesh->GetMeshDS()->Modified();
967 return myMesh->SetIsModified( true ), elem->GetID();
972 //=============================================================================
976 //=============================================================================
977 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
981 int NbNodes = IDsOfNodes.length();
982 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
983 for (int i = 0; i < NbNodes; i++)
984 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
986 const SMDS_MeshElement* elem = getMeshDS()->AddPolygonalFace(nodes);
988 // Update Python script
989 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
991 myMesh->GetMeshDS()->Modified();
992 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
995 //=============================================================================
997 * Create volume, either linear and quadratic (this is determed
998 * by number of given nodes)
1000 //=============================================================================
1002 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
1006 int NbNodes = IDsOfNodes.length();
1007 vector< const SMDS_MeshNode*> n(NbNodes);
1008 for(int i=0;i<NbNodes;i++)
1009 n[i]= getMeshDS()->FindNode(IDsOfNodes[i]);
1011 SMDS_MeshElement* elem = 0;
1014 case 4 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
1015 case 5 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
1016 case 6 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
1017 case 8 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
1018 case 10:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1019 n[6],n[7],n[8],n[9]);
1021 case 12:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1022 n[6],n[7],n[8],n[9],n[10],n[11]);
1024 case 13:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
1025 n[7],n[8],n[9],n[10],n[11],n[12]);
1027 case 15:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
1028 n[9],n[10],n[11],n[12],n[13],n[14]);
1030 case 20:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1031 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1032 n[15],n[16],n[17],n[18],n[19]);
1034 case 27:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1035 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1036 n[15],n[16],n[17],n[18],n[19],
1037 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
1041 // Update Python script
1042 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
1044 myMesh->GetMeshDS()->Modified();
1046 return myMesh->SetIsModified( true ), elem->GetID();
1051 //=============================================================================
1053 * AddPolyhedralVolume
1055 //=============================================================================
1056 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
1057 const SMESH::long_array & Quantities)
1061 int NbNodes = IDsOfNodes.length();
1062 std::vector<const SMDS_MeshNode*> n (NbNodes);
1063 for (int i = 0; i < NbNodes; i++)
1065 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDsOfNodes[i]);
1066 if (!aNode) return 0;
1070 int NbFaces = Quantities.length();
1071 std::vector<int> q (NbFaces);
1072 for (int j = 0; j < NbFaces; j++)
1073 q[j] = Quantities[j];
1075 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(n, q);
1077 // Update Python script
1078 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
1079 << IDsOfNodes << ", " << Quantities << " )";
1080 myMesh->GetMeshDS()->Modified();
1082 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
1085 //=============================================================================
1087 * AddPolyhedralVolumeByFaces
1089 //=============================================================================
1091 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
1095 int NbFaces = IdsOfFaces.length();
1096 std::vector<const SMDS_MeshNode*> poly_nodes;
1097 std::vector<int> quantities (NbFaces);
1099 for (int i = 0; i < NbFaces; i++) {
1100 const SMDS_MeshElement* aFace = getMeshDS()->FindElement(IdsOfFaces[i]);
1101 quantities[i] = aFace->NbNodes();
1103 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
1104 while (It->more()) {
1105 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
1109 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
1111 // Update Python script
1112 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
1113 << IdsOfFaces << " )";
1114 myMesh->GetMeshDS()->Modified();
1116 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
1119 //=============================================================================
1121 // \brief Create 0D elements on all nodes of the given object except those
1122 // nodes on which a 0D element already exists.
1123 // \param theObject object on whose nodes 0D elements will be created.
1124 // \param theGroupName optional name of a group to add 0D elements created
1125 // and/or found on nodes of \a theObject.
1126 // \return an object (a new group or a temporary SMESH_IDSource) holding
1127 // ids of new and/or found 0D elements.
1129 //=============================================================================
1131 SMESH::SMESH_IDSource_ptr
1132 SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObject,
1133 const char* theGroupName)
1134 throw (SALOME::SALOME_Exception)
1138 SMESH::SMESH_IDSource_var result;
1141 TIDSortedElemSet elements, elems0D;
1142 if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
1143 getEditor().Create0DElementsOnAllNodes( elements, elems0D );
1145 SMESH::long_array_var newElems = new SMESH::long_array;
1146 newElems->length( elems0D.size() );
1147 TIDSortedElemSet::iterator eIt = elems0D.begin();
1148 for ( size_t i = 0; i < elems0D.size(); ++i, ++eIt )
1149 newElems[ i ] = (*eIt)->GetID();
1151 SMESH::SMESH_GroupBase_var groupToFill;
1152 if ( theGroupName && strlen( theGroupName ))
1154 // Get existing group named theGroupName
1155 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
1156 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
1157 SMESH::SMESH_GroupBase_var group = groups[i];
1158 if ( !group->_is_nil() ) {
1159 CORBA::String_var name = group->GetName();
1160 if ( strcmp( name.in(), theGroupName ) == 0 && group->GetType() == SMESH::ELEM0D ) {
1161 groupToFill = group;
1166 if ( groupToFill->_is_nil() )
1167 groupToFill = myMesh_i->CreateGroup( SMESH::ELEM0D, theGroupName );
1168 else if ( !SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1169 groupToFill = myMesh_i->ConvertToStandalone( groupToFill );
1172 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1174 group_i->Add( newElems );
1175 result = SMESH::SMESH_IDSource::_narrow( groupToFill );
1176 pyDump << groupToFill;
1180 result = MakeIDSource( newElems, SMESH::ELEM0D );
1181 pyDump << "elem0DIDs";
1184 pyDump << " = " << this << ".Create0DElementsOnAllNodes( "
1185 << theObject << ", '" << theGroupName << "' )";
1187 return result._retn();
1190 //=============================================================================
1192 * \brief Bind a node to a vertex
1193 * \param NodeID - node ID
1194 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1195 * \retval boolean - false if NodeID or VertexID is invalid
1197 //=============================================================================
1199 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
1200 throw (SALOME::SALOME_Exception)
1202 Unexpect aCatch(SALOME_SalomeException);
1204 SMESHDS_Mesh * mesh = getMeshDS();
1205 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1207 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1209 if ( mesh->MaxShapeIndex() < VertexID )
1210 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1212 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
1213 if ( shape.ShapeType() != TopAbs_VERTEX )
1214 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1216 mesh->SetNodeOnVertex( node, VertexID );
1218 myMesh->SetIsModified( true );
1221 //=============================================================================
1223 * \brief Store node position on an edge
1224 * \param NodeID - node ID
1225 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
1226 * \param paramOnEdge - parameter on edge where the node is located
1227 * \retval boolean - false if any parameter is invalid
1229 //=============================================================================
1231 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
1232 CORBA::Double paramOnEdge)
1233 throw (SALOME::SALOME_Exception)
1235 Unexpect aCatch(SALOME_SalomeException);
1237 SMESHDS_Mesh * mesh = getMeshDS();
1238 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1240 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1242 if ( mesh->MaxShapeIndex() < EdgeID )
1243 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1245 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
1246 if ( shape.ShapeType() != TopAbs_EDGE )
1247 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1250 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
1251 if ( paramOnEdge < f || paramOnEdge > l )
1252 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
1254 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
1256 myMesh->SetIsModified( true );
1259 //=============================================================================
1261 * \brief Store node position on a face
1262 * \param NodeID - node ID
1263 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
1264 * \param u - U parameter on face where the node is located
1265 * \param v - V parameter on face where the node is located
1266 * \retval boolean - false if any parameter is invalid
1268 //=============================================================================
1270 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
1271 CORBA::Double u, CORBA::Double v)
1272 throw (SALOME::SALOME_Exception)
1274 Unexpect aCatch(SALOME_SalomeException);
1276 SMESHDS_Mesh * mesh = getMeshDS();
1277 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1279 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1281 if ( mesh->MaxShapeIndex() < FaceID )
1282 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1284 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
1285 if ( shape.ShapeType() != TopAbs_FACE )
1286 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1288 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
1289 bool isOut = ( u < surf.FirstUParameter() ||
1290 u > surf.LastUParameter() ||
1291 v < surf.FirstVParameter() ||
1292 v > surf.LastVParameter() );
1296 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
1297 << " u( " << surf.FirstUParameter()
1298 << "," << surf.LastUParameter()
1299 << ") v( " << surf.FirstVParameter()
1300 << "," << surf.LastVParameter() << ")" );
1302 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
1305 mesh->SetNodeOnFace( node, FaceID, u, v );
1306 myMesh->SetIsModified( true );
1309 //=============================================================================
1311 * \brief Bind a node to a solid
1312 * \param NodeID - node ID
1313 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1314 * \retval boolean - false if NodeID or SolidID is invalid
1316 //=============================================================================
1318 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
1319 throw (SALOME::SALOME_Exception)
1321 Unexpect aCatch(SALOME_SalomeException);
1323 SMESHDS_Mesh * mesh = getMeshDS();
1324 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1326 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1328 if ( mesh->MaxShapeIndex() < SolidID )
1329 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1331 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
1332 if ( shape.ShapeType() != TopAbs_SOLID &&
1333 shape.ShapeType() != TopAbs_SHELL)
1334 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1336 mesh->SetNodeInVolume( node, SolidID );
1338 // myMesh->SetIsModified( true ); - SetNodeInVolume() can't prevent re-compute, I believe
1341 //=============================================================================
1343 * \brief Bind an element to a shape
1344 * \param ElementID - element ID
1345 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
1346 * \retval boolean - false if ElementID or ShapeID is invalid
1348 //=============================================================================
1350 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
1351 CORBA::Long ShapeID)
1352 throw (SALOME::SALOME_Exception)
1354 Unexpect aCatch(SALOME_SalomeException);
1356 SMESHDS_Mesh * mesh = getMeshDS();
1357 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
1359 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
1361 if ( mesh->MaxShapeIndex() < ShapeID )
1362 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1364 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1365 if ( shape.ShapeType() != TopAbs_EDGE &&
1366 shape.ShapeType() != TopAbs_FACE &&
1367 shape.ShapeType() != TopAbs_SOLID &&
1368 shape.ShapeType() != TopAbs_SHELL )
1369 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1371 mesh->SetMeshElementOnShape( elem, ShapeID );
1373 myMesh->SetIsModified( true );
1376 //=============================================================================
1380 //=============================================================================
1382 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1383 CORBA::Long NodeID2)
1387 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1388 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1392 // Update Python script
1393 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1394 << NodeID1 << ", " << NodeID2 << " )";
1397 int ret = getEditor().InverseDiag ( n1, n2 );
1398 myMesh->GetMeshDS()->Modified();
1399 myMesh->SetIsModified( true );
1403 //=============================================================================
1407 //=============================================================================
1409 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1410 CORBA::Long NodeID2)
1414 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1415 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1419 // Update Python script
1420 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1421 << NodeID1 << ", " << NodeID2 << " )";
1424 bool stat = getEditor().DeleteDiag ( n1, n2 );
1426 myMesh->GetMeshDS()->Modified();
1428 myMesh->SetIsModified( true ); // issue 0020693
1434 //=============================================================================
1438 //=============================================================================
1440 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1444 for (int i = 0; i < IDsOfElements.length(); i++)
1446 CORBA::Long index = IDsOfElements[i];
1447 const SMDS_MeshElement * elem = getMeshDS()->FindElement(index);
1449 getEditor().Reorient( elem );
1451 // Update Python script
1452 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1454 myMesh->GetMeshDS()->Modified();
1455 if ( IDsOfElements.length() )
1456 myMesh->SetIsModified( true ); // issue 0020693
1462 //=============================================================================
1466 //=============================================================================
1468 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1472 TPythonDump aTPythonDump; // suppress dump in Reorient()
1474 SMESH::long_array_var anElementsId = theObject->GetIDs();
1475 CORBA::Boolean isDone = Reorient(anElementsId);
1477 // Update Python script
1478 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1483 //=======================================================================
1484 //function : Reorient2D
1485 //purpose : Reorient faces contained in \a the2Dgroup.
1486 // the2Dgroup - the mesh or its part to reorient
1487 // theDirection - desired direction of normal of \a theFace
1488 // theFace - ID of face whose orientation is checked.
1489 // It can be < 1 then \a thePoint is used to find a face.
1490 // thePoint - is used to find a face if \a theFace < 1.
1491 // return number of reoriented elements.
1492 //=======================================================================
1494 CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
1495 const SMESH::DirStruct& theDirection,
1496 CORBA::Long theFace,
1497 const SMESH::PointStruct& thePoint)
1498 throw (SALOME::SALOME_Exception)
1500 Unexpect aCatch(SALOME_SalomeException);
1502 initData(/*deleteSearchers=*/false);
1504 TIDSortedElemSet elements;
1505 if ( !idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1))
1506 THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
1509 const SMDS_MeshElement* face = 0;
1512 face = getMeshDS()->FindElement( theFace );
1514 THROW_SALOME_CORBA_EXCEPTION("Inexistent face given", SALOME::BAD_PARAM);
1515 if ( face->GetType() != SMDSAbs_Face )
1516 THROW_SALOME_CORBA_EXCEPTION("Wrong element type", SALOME::BAD_PARAM);
1520 // create theElementSearcher if needed
1521 theSearchersDeleter.Set( myMesh, getPartIOR( the2Dgroup, SMESH::FACE ));
1522 if ( !theElementSearcher )
1524 if ( elements.empty() ) // search in the whole mesh
1526 if ( myMesh->NbFaces() == 0 )
1527 THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM);
1529 theElementSearcher = myEditor.GetElementSearcher();
1533 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
1534 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
1536 theElementSearcher = myEditor.GetElementSearcher(elemsIt);
1540 gp_Pnt p( thePoint.x, thePoint.y, thePoint.z );
1541 face = theElementSearcher->FindClosestTo( p, SMDSAbs_Face );
1544 THROW_SALOME_CORBA_EXCEPTION("No face found by point", SALOME::INTERNAL_ERROR );
1545 if ( !elements.empty() && !elements.count( face ))
1546 THROW_SALOME_CORBA_EXCEPTION("Found face is not in the group", SALOME::BAD_PARAM );
1549 const SMESH::PointStruct * P = &theDirection.PS;
1550 gp_Vec dirVec( P->x, P->y, P->z );
1551 if ( dirVec.Magnitude() < std::numeric_limits< double >::min() )
1552 THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM);
1554 int nbReori = getEditor().Reorient2D( elements, dirVec, face );
1557 myMesh->SetIsModified( true );
1558 myMesh->GetMeshDS()->Modified();
1560 TPythonDump() << this << ".Reorient2D( "
1561 << the2Dgroup << ", "
1562 << theDirection << ", "
1564 << thePoint << " )";
1569 //=============================================================================
1573 //=============================================================================
1574 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1575 SMESH::NumericalFunctor_ptr Criterion,
1576 CORBA::Double MaxAngle)
1580 SMESHDS_Mesh* aMesh = getMeshDS();
1581 TIDSortedElemSet faces;
1582 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1584 SMESH::NumericalFunctor_i* aNumericalFunctor =
1585 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1586 SMESH::Controls::NumericalFunctorPtr aCrit;
1587 if ( !aNumericalFunctor )
1588 aCrit.reset( new SMESH::Controls::MaxElementLength2D() );
1590 aCrit = aNumericalFunctor->GetNumericalFunctor();
1592 // Update Python script
1593 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1594 << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1597 bool stat = getEditor().TriToQuad( faces, aCrit, MaxAngle );
1598 myMesh->GetMeshDS()->Modified();
1600 myMesh->SetIsModified( true ); // issue 0020693
1607 //=============================================================================
1611 //=============================================================================
1612 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1613 SMESH::NumericalFunctor_ptr Criterion,
1614 CORBA::Double MaxAngle)
1618 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1619 SMESH::long_array_var anElementsId = theObject->GetIDs();
1620 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1622 SMESH::NumericalFunctor_i* aNumericalFunctor =
1623 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1625 // Update Python script
1626 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1627 << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1633 //=============================================================================
1637 //=============================================================================
1638 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1639 SMESH::NumericalFunctor_ptr Criterion)
1643 SMESHDS_Mesh* aMesh = getMeshDS();
1644 TIDSortedElemSet faces;
1645 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1647 SMESH::NumericalFunctor_i* aNumericalFunctor =
1648 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1649 SMESH::Controls::NumericalFunctorPtr aCrit;
1650 if ( !aNumericalFunctor )
1651 aCrit.reset( new SMESH::Controls::AspectRatio() );
1653 aCrit = aNumericalFunctor->GetNumericalFunctor();
1656 // Update Python script
1657 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1659 CORBA::Boolean stat = getEditor().QuadToTri( faces, aCrit );
1660 myMesh->GetMeshDS()->Modified();
1662 myMesh->SetIsModified( true ); // issue 0020693
1669 //=============================================================================
1673 //=============================================================================
1674 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1675 SMESH::NumericalFunctor_ptr Criterion)
1679 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1681 SMESH::long_array_var anElementsId = theObject->GetIDs();
1682 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1684 SMESH::NumericalFunctor_i* aNumericalFunctor =
1685 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1687 // Update Python script
1688 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1694 //=============================================================================
1698 //=============================================================================
1699 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1700 CORBA::Boolean Diag13)
1704 SMESHDS_Mesh* aMesh = getMeshDS();
1705 TIDSortedElemSet faces;
1706 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1708 // Update Python script
1709 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1710 << IDsOfElements << ", " << Diag13 << " )";
1712 CORBA::Boolean stat = getEditor().QuadToTri( faces, Diag13 );
1713 myMesh->GetMeshDS()->Modified();
1715 myMesh->SetIsModified( true ); // issue 0020693
1723 //=============================================================================
1727 //=============================================================================
1728 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1729 CORBA::Boolean Diag13)
1733 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
1735 SMESH::long_array_var anElementsId = theObject->GetIDs();
1736 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
1738 // Update Python script
1739 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
1740 << theObject << ", " << Diag13 << " )";
1746 //=============================================================================
1750 //=============================================================================
1751 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
1752 SMESH::NumericalFunctor_ptr Criterion)
1756 const SMDS_MeshElement* quad = getMeshDS()->FindElement(IDOfQuad);
1757 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
1759 SMESH::NumericalFunctor_i* aNumericalFunctor =
1760 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
1761 SMESH::Controls::NumericalFunctorPtr aCrit;
1762 if (aNumericalFunctor)
1763 aCrit = aNumericalFunctor->GetNumericalFunctor();
1765 aCrit.reset(new SMESH::Controls::AspectRatio());
1767 return getEditor().BestSplit(quad, aCrit);
1772 //================================================================================
1774 * \brief Split volumic elements into tetrahedrons
1776 //================================================================================
1778 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
1779 CORBA::Short methodFlags)
1780 throw (SALOME::SALOME_Exception)
1782 Unexpect aCatch(SALOME_SalomeException);
1786 SMESH::long_array_var anElementsId = elems->GetIDs();
1787 TIDSortedElemSet elemSet;
1788 arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume );
1790 getEditor().SplitVolumesIntoTetra( elemSet, int( methodFlags ));
1791 myMesh->GetMeshDS()->Modified();
1794 // if ( myLastCreatedElems.length() ) - it does not influence Compute()
1795 // myMesh->SetIsModified( true ); // issue 0020693
1797 TPythonDump() << this << ".SplitVolumesIntoTetra( "
1798 << elems << ", " << methodFlags << " )";
1801 //=======================================================================
1804 //=======================================================================
1807 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
1808 const SMESH::long_array & IDsOfFixedNodes,
1809 CORBA::Long MaxNbOfIterations,
1810 CORBA::Double MaxAspectRatio,
1811 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1813 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1814 MaxAspectRatio, Method, false );
1818 //=======================================================================
1819 //function : SmoothParametric
1821 //=======================================================================
1824 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
1825 const SMESH::long_array & IDsOfFixedNodes,
1826 CORBA::Long MaxNbOfIterations,
1827 CORBA::Double MaxAspectRatio,
1828 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1830 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1831 MaxAspectRatio, Method, true );
1835 //=======================================================================
1836 //function : SmoothObject
1838 //=======================================================================
1841 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
1842 const SMESH::long_array & IDsOfFixedNodes,
1843 CORBA::Long MaxNbOfIterations,
1844 CORBA::Double MaxAspectRatio,
1845 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1847 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1848 MaxAspectRatio, Method, false);
1852 //=======================================================================
1853 //function : SmoothParametricObject
1855 //=======================================================================
1858 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
1859 const SMESH::long_array & IDsOfFixedNodes,
1860 CORBA::Long MaxNbOfIterations,
1861 CORBA::Double MaxAspectRatio,
1862 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1864 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1865 MaxAspectRatio, Method, true);
1869 //=============================================================================
1873 //=============================================================================
1876 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
1877 const SMESH::long_array & IDsOfFixedNodes,
1878 CORBA::Long MaxNbOfIterations,
1879 CORBA::Double MaxAspectRatio,
1880 SMESH::SMESH_MeshEditor::Smooth_Method Method,
1885 SMESHDS_Mesh* aMesh = getMeshDS();
1887 TIDSortedElemSet elements;
1888 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
1890 set<const SMDS_MeshNode*> fixedNodes;
1891 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
1892 CORBA::Long index = IDsOfFixedNodes[i];
1893 const SMDS_MeshNode * node = aMesh->FindNode(index);
1895 fixedNodes.insert( node );
1897 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
1898 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
1899 method = ::SMESH_MeshEditor::CENTROIDAL;
1901 getEditor().Smooth(elements, fixedNodes, method,
1902 MaxNbOfIterations, MaxAspectRatio, IsParametric );
1904 myMesh->GetMeshDS()->Modified();
1905 myMesh->SetIsModified( true ); // issue 0020693
1908 // Update Python script
1909 TPythonDump() << "isDone = " << this << "."
1910 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
1911 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
1912 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
1913 << "SMESH.SMESH_MeshEditor."
1914 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1915 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1921 //=============================================================================
1925 //=============================================================================
1928 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
1929 const SMESH::long_array & IDsOfFixedNodes,
1930 CORBA::Long MaxNbOfIterations,
1931 CORBA::Double MaxAspectRatio,
1932 SMESH::SMESH_MeshEditor::Smooth_Method Method,
1937 TPythonDump aTPythonDump; // suppress dump in smooth()
1939 SMESH::long_array_var anElementsId = theObject->GetIDs();
1940 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
1941 MaxAspectRatio, Method, IsParametric);
1943 // Update Python script
1944 aTPythonDump << "isDone = " << this << "."
1945 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
1946 << theObject << ", " << IDsOfFixedNodes << ", "
1947 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
1948 << "SMESH.SMESH_MeshEditor."
1949 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1950 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1956 //=============================================================================
1960 //=============================================================================
1962 void SMESH_MeshEditor_i::RenumberNodes()
1964 // Update Python script
1965 TPythonDump() << this << ".RenumberNodes()";
1967 getMeshDS()->Renumber( true );
1971 //=============================================================================
1975 //=============================================================================
1977 void SMESH_MeshEditor_i::RenumberElements()
1979 // Update Python script
1980 TPythonDump() << this << ".RenumberElements()";
1982 getMeshDS()->Renumber( false );
1985 //=======================================================================
1987 * \brief Return groups by their IDs
1989 //=======================================================================
1991 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
1995 myMesh_i->CreateGroupServants();
1996 return myMesh_i->GetGroups( *groupIDs );
1999 //=======================================================================
2000 //function : rotationSweep
2002 //=======================================================================
2004 SMESH::ListOfGroups*
2005 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
2006 const SMESH::AxisStruct & theAxis,
2007 CORBA::Double theAngleInRadians,
2008 CORBA::Long theNbOfSteps,
2009 CORBA::Double theTolerance,
2010 const bool theMakeGroups,
2011 const SMDSAbs_ElementType theElementType)
2015 TIDSortedElemSet inElements, copyElements;
2016 arrayToSet(theIDsOfElements, getMeshDS(), inElements, theElementType);
2018 TIDSortedElemSet* workElements = & inElements;
2019 bool makeWalls=true;
2020 if ( myIsPreviewMode )
2022 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2023 getPreviewMesh( SMDSAbs_Face )->Copy( inElements, copyElements, select, avoid );
2024 workElements = & copyElements;
2025 //makeWalls = false;
2028 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
2029 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
2031 ::SMESH_MeshEditor::PGroupIDs groupIds =
2032 getEditor().RotationSweep (*workElements, Ax1, theAngleInRadians,
2033 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
2034 myMesh->GetMeshDS()->Modified();
2036 // myMesh->SetIsModified( true ); -- it does not influence Compute()
2038 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2041 //=======================================================================
2042 //function : RotationSweep
2044 //=======================================================================
2046 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
2047 const SMESH::AxisStruct & theAxis,
2048 CORBA::Double theAngleInRadians,
2049 CORBA::Long theNbOfSteps,
2050 CORBA::Double theTolerance)
2052 if ( !myIsPreviewMode ) {
2053 TPythonDump() << this << ".RotationSweep( "
2054 << theIDsOfElements << ", "
2056 << TVar( theAngleInRadians ) << ", "
2057 << TVar( theNbOfSteps ) << ", "
2058 << TVar( theTolerance ) << " )";
2060 rotationSweep(theIDsOfElements,
2068 //=======================================================================
2069 //function : RotationSweepMakeGroups
2071 //=======================================================================
2073 SMESH::ListOfGroups*
2074 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2075 const SMESH::AxisStruct& theAxis,
2076 CORBA::Double theAngleInRadians,
2077 CORBA::Long theNbOfSteps,
2078 CORBA::Double theTolerance)
2080 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2082 SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
2088 if (!myIsPreviewMode) {
2089 DumpGroupsList(aPythonDump, aGroups);
2090 aPythonDump << this << ".RotationSweepMakeGroups( "
2091 << theIDsOfElements << ", "
2093 << TVar( theAngleInRadians ) << ", "
2094 << TVar( theNbOfSteps ) << ", "
2095 << TVar( theTolerance ) << " )";
2100 //=======================================================================
2101 //function : RotationSweepObject
2103 //=======================================================================
2105 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2106 const SMESH::AxisStruct & theAxis,
2107 CORBA::Double theAngleInRadians,
2108 CORBA::Long theNbOfSteps,
2109 CORBA::Double theTolerance)
2111 if ( !myIsPreviewMode ) {
2112 TPythonDump() << this << ".RotationSweepObject( "
2113 << theObject << ", "
2115 << theAngleInRadians << ", "
2116 << theNbOfSteps << ", "
2117 << theTolerance << " )";
2119 SMESH::long_array_var anElementsId = theObject->GetIDs();
2120 rotationSweep(anElementsId,
2128 //=======================================================================
2129 //function : RotationSweepObject1D
2131 //=======================================================================
2133 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2134 const SMESH::AxisStruct & theAxis,
2135 CORBA::Double theAngleInRadians,
2136 CORBA::Long theNbOfSteps,
2137 CORBA::Double theTolerance)
2139 if ( !myIsPreviewMode ) {
2140 TPythonDump() << this << ".RotationSweepObject1D( "
2141 << theObject << ", "
2143 << TVar( theAngleInRadians ) << ", "
2144 << TVar( theNbOfSteps ) << ", "
2145 << TVar( theTolerance ) << " )";
2147 SMESH::long_array_var anElementsId = theObject->GetIDs();
2148 rotationSweep(anElementsId,
2157 //=======================================================================
2158 //function : RotationSweepObject2D
2160 //=======================================================================
2162 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2163 const SMESH::AxisStruct & theAxis,
2164 CORBA::Double theAngleInRadians,
2165 CORBA::Long theNbOfSteps,
2166 CORBA::Double theTolerance)
2168 if ( !myIsPreviewMode ) {
2169 TPythonDump() << this << ".RotationSweepObject2D( "
2170 << theObject << ", "
2172 << TVar( theAngleInRadians ) << ", "
2173 << TVar( theNbOfSteps ) << ", "
2174 << TVar( theTolerance ) << " )";
2176 SMESH::long_array_var anElementsId = theObject->GetIDs();
2177 rotationSweep(anElementsId,
2186 //=======================================================================
2187 //function : RotationSweepObjectMakeGroups
2189 //=======================================================================
2191 SMESH::ListOfGroups*
2192 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2193 const SMESH::AxisStruct& theAxis,
2194 CORBA::Double theAngleInRadians,
2195 CORBA::Long theNbOfSteps,
2196 CORBA::Double theTolerance)
2198 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2200 SMESH::long_array_var anElementsId = theObject->GetIDs();
2201 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2207 if (!myIsPreviewMode) {
2208 DumpGroupsList(aPythonDump, aGroups);
2209 aPythonDump << this << ".RotationSweepObjectMakeGroups( "
2210 << theObject << ", "
2212 << theAngleInRadians << ", "
2213 << theNbOfSteps << ", "
2214 << theTolerance << " )";
2219 //=======================================================================
2220 //function : RotationSweepObject1DMakeGroups
2222 //=======================================================================
2224 SMESH::ListOfGroups*
2225 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2226 const SMESH::AxisStruct& theAxis,
2227 CORBA::Double theAngleInRadians,
2228 CORBA::Long theNbOfSteps,
2229 CORBA::Double theTolerance)
2231 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2233 SMESH::long_array_var anElementsId = theObject->GetIDs();
2234 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2241 if (!myIsPreviewMode) {
2242 DumpGroupsList(aPythonDump, aGroups);
2243 aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
2244 << theObject << ", "
2246 << TVar( theAngleInRadians ) << ", "
2247 << TVar( theNbOfSteps ) << ", "
2248 << TVar( theTolerance ) << " )";
2253 //=======================================================================
2254 //function : RotationSweepObject2DMakeGroups
2256 //=======================================================================
2258 SMESH::ListOfGroups*
2259 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2260 const SMESH::AxisStruct& theAxis,
2261 CORBA::Double theAngleInRadians,
2262 CORBA::Long theNbOfSteps,
2263 CORBA::Double theTolerance)
2265 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2267 SMESH::long_array_var anElementsId = theObject->GetIDs();
2268 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2275 if (!myIsPreviewMode) {
2276 DumpGroupsList(aPythonDump, aGroups);
2277 aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
2278 << theObject << ", "
2280 << TVar( theAngleInRadians ) << ", "
2281 << TVar( theNbOfSteps ) << ", "
2282 << TVar( theTolerance ) << " )";
2288 //=======================================================================
2289 //function : extrusionSweep
2291 //=======================================================================
2293 SMESH::ListOfGroups*
2294 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
2295 const SMESH::DirStruct & theStepVector,
2296 CORBA::Long theNbOfSteps,
2298 const SMDSAbs_ElementType theElementType)
2306 TIDSortedElemSet elements, copyElements;
2307 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
2309 const SMESH::PointStruct * P = &theStepVector.PS;
2310 gp_Vec stepVec( P->x, P->y, P->z );
2312 TIDSortedElemSet* workElements = & elements;
2314 SMDSAbs_ElementType aType = SMDSAbs_Face;
2315 if (theElementType == SMDSAbs_Node)
2317 aType = SMDSAbs_Edge;
2319 if ( myIsPreviewMode ) {
2320 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2321 getPreviewMesh( aType )->Copy( elements, copyElements, select, avoid );
2322 workElements = & copyElements;
2323 theMakeGroups = false;
2326 TElemOfElemListMap aHystory;
2327 ::SMESH_MeshEditor::PGroupIDs groupIds =
2328 getEditor().ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
2330 myMesh->GetMeshDS()->Modified();
2332 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2334 } catch(Standard_Failure) {
2335 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2336 INFOS( "SMESH_MeshEditor_i::ExtrusionSweep fails - "<< aFail->GetMessageString() );
2341 //=======================================================================
2342 //function : ExtrusionSweep
2344 //=======================================================================
2346 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
2347 const SMESH::DirStruct & theStepVector,
2348 CORBA::Long theNbOfSteps)
2350 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
2351 if (!myIsPreviewMode) {
2352 TPythonDump() << this << ".ExtrusionSweep( "
2353 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps) << " )";
2357 //=======================================================================
2358 //function : ExtrusionSweep0D
2360 //=======================================================================
2362 void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElements,
2363 const SMESH::DirStruct & theStepVector,
2364 CORBA::Long theNbOfSteps)
2366 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2367 if (!myIsPreviewMode) {
2368 TPythonDump() << this << ".ExtrusionSweep0D( "
2369 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps)<< " )";
2373 //=======================================================================
2374 //function : ExtrusionSweepObject
2376 //=======================================================================
2378 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2379 const SMESH::DirStruct & theStepVector,
2380 CORBA::Long theNbOfSteps)
2382 SMESH::long_array_var anElementsId = theObject->GetIDs();
2383 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
2384 if (!myIsPreviewMode) {
2385 TPythonDump() << this << ".ExtrusionSweepObject( "
2386 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
2390 //=======================================================================
2391 //function : ExtrusionSweepObject0D
2393 //=======================================================================
2395 void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObject,
2396 const SMESH::DirStruct & theStepVector,
2397 CORBA::Long theNbOfSteps)
2399 SMESH::long_array_var anElementsId = theObject->GetIDs();
2400 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2401 if ( !myIsPreviewMode ) {
2402 TPythonDump() << this << ".ExtrusionSweepObject0D( "
2403 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2407 //=======================================================================
2408 //function : ExtrusionSweepObject1D
2410 //=======================================================================
2412 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2413 const SMESH::DirStruct & theStepVector,
2414 CORBA::Long theNbOfSteps)
2416 SMESH::long_array_var anElementsId = theObject->GetIDs();
2417 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
2418 if ( !myIsPreviewMode ) {
2419 TPythonDump() << this << ".ExtrusionSweepObject1D( "
2420 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2424 //=======================================================================
2425 //function : ExtrusionSweepObject2D
2427 //=======================================================================
2429 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2430 const SMESH::DirStruct & theStepVector,
2431 CORBA::Long theNbOfSteps)
2433 SMESH::long_array_var anElementsId = theObject->GetIDs();
2434 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
2435 if ( !myIsPreviewMode ) {
2436 TPythonDump() << this << ".ExtrusionSweepObject2D( "
2437 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2441 //=======================================================================
2442 //function : ExtrusionSweepMakeGroups
2444 //=======================================================================
2446 SMESH::ListOfGroups*
2447 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2448 const SMESH::DirStruct& theStepVector,
2449 CORBA::Long theNbOfSteps)
2451 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2453 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
2455 if (!myIsPreviewMode) {
2456 DumpGroupsList(aPythonDump, aGroups);
2457 aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
2458 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2463 //=======================================================================
2464 //function : ExtrusionSweepMakeGroups0D
2466 //=======================================================================
2468 SMESH::ListOfGroups*
2469 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups0D(const SMESH::long_array& theIDsOfElements,
2470 const SMESH::DirStruct& theStepVector,
2471 CORBA::Long theNbOfSteps)
2473 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2475 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true,SMDSAbs_Node);
2477 if (!myIsPreviewMode) {
2478 DumpGroupsList(aPythonDump, aGroups);
2479 aPythonDump << this << ".ExtrusionSweepMakeGroups0D( " << theIDsOfElements
2480 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2485 //=======================================================================
2486 //function : ExtrusionSweepObjectMakeGroups
2488 //=======================================================================
2490 SMESH::ListOfGroups*
2491 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2492 const SMESH::DirStruct& theStepVector,
2493 CORBA::Long theNbOfSteps)
2495 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2497 SMESH::long_array_var anElementsId = theObject->GetIDs();
2498 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
2500 if (!myIsPreviewMode) {
2501 DumpGroupsList(aPythonDump, aGroups);
2502 aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
2503 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2508 //=======================================================================
2509 //function : ExtrusionSweepObject0DMakeGroups
2511 //=======================================================================
2513 SMESH::ListOfGroups*
2514 SMESH_MeshEditor_i::ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2515 const SMESH::DirStruct& theStepVector,
2516 CORBA::Long theNbOfSteps)
2518 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2520 SMESH::long_array_var anElementsId = theObject->GetIDs();
2521 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2522 theNbOfSteps, true, SMDSAbs_Node);
2523 if (!myIsPreviewMode) {
2524 DumpGroupsList(aPythonDump, aGroups);
2525 aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject
2526 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2531 //=======================================================================
2532 //function : ExtrusionSweepObject1DMakeGroups
2534 //=======================================================================
2536 SMESH::ListOfGroups*
2537 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2538 const SMESH::DirStruct& theStepVector,
2539 CORBA::Long theNbOfSteps)
2541 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2543 SMESH::long_array_var anElementsId = theObject->GetIDs();
2544 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2545 theNbOfSteps, true, SMDSAbs_Edge);
2546 if (!myIsPreviewMode) {
2547 DumpGroupsList(aPythonDump, aGroups);
2548 aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
2549 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2554 //=======================================================================
2555 //function : ExtrusionSweepObject2DMakeGroups
2557 //=======================================================================
2559 SMESH::ListOfGroups*
2560 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2561 const SMESH::DirStruct& theStepVector,
2562 CORBA::Long theNbOfSteps)
2564 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2566 SMESH::long_array_var anElementsId = theObject->GetIDs();
2567 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2568 theNbOfSteps, true, SMDSAbs_Face);
2569 if (!myIsPreviewMode) {
2570 DumpGroupsList(aPythonDump, aGroups);
2571 aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
2572 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2578 //=======================================================================
2579 //function : advancedExtrusion
2581 //=======================================================================
2583 SMESH::ListOfGroups*
2584 SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
2585 const SMESH::DirStruct & theStepVector,
2586 CORBA::Long theNbOfSteps,
2587 CORBA::Long theExtrFlags,
2588 CORBA::Double theSewTolerance,
2589 const bool theMakeGroups)
2593 TIDSortedElemSet elements;
2594 arrayToSet(theIDsOfElements, getMeshDS(), elements);
2596 const SMESH::PointStruct * P = &theStepVector.PS;
2597 gp_Vec stepVec( P->x, P->y, P->z );
2599 TElemOfElemListMap aHystory;
2600 ::SMESH_MeshEditor::PGroupIDs groupIds =
2601 getEditor().ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
2602 theMakeGroups, theExtrFlags, theSewTolerance);
2604 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2607 //=======================================================================
2608 //function : AdvancedExtrusion
2610 //=======================================================================
2612 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2613 const SMESH::DirStruct & theStepVector,
2614 CORBA::Long theNbOfSteps,
2615 CORBA::Long theExtrFlags,
2616 CORBA::Double theSewTolerance)
2618 if ( !myIsPreviewMode ) {
2619 TPythonDump() << "stepVector = " << theStepVector;
2620 TPythonDump() << this << ".AdvancedExtrusion("
2623 << theNbOfSteps << ","
2624 << theExtrFlags << ", "
2625 << theSewTolerance << " )";
2627 advancedExtrusion( theIDsOfElements,
2635 //=======================================================================
2636 //function : AdvancedExtrusionMakeGroups
2638 //=======================================================================
2639 SMESH::ListOfGroups*
2640 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
2641 const SMESH::DirStruct& theStepVector,
2642 CORBA::Long theNbOfSteps,
2643 CORBA::Long theExtrFlags,
2644 CORBA::Double theSewTolerance)
2646 if (!myIsPreviewMode) {
2647 TPythonDump() << "stepVector = " << theStepVector;
2649 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2651 SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
2658 if (!myIsPreviewMode) {
2659 DumpGroupsList(aPythonDump, aGroups);
2660 aPythonDump << this << ".AdvancedExtrusionMakeGroups("
2663 << theNbOfSteps << ","
2664 << theExtrFlags << ", "
2665 << theSewTolerance << " )";
2671 //================================================================================
2673 * \brief Convert extrusion error to IDL enum
2675 //================================================================================
2677 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
2679 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
2683 RETCASE( EXTR_NO_ELEMENTS );
2684 RETCASE( EXTR_PATH_NOT_EDGE );
2685 RETCASE( EXTR_BAD_PATH_SHAPE );
2686 RETCASE( EXTR_BAD_STARTING_NODE );
2687 RETCASE( EXTR_BAD_ANGLES_NUMBER );
2688 RETCASE( EXTR_CANT_GET_TANGENT );
2690 return SMESH::SMESH_MeshEditor::EXTR_OK;
2694 //=======================================================================
2695 //function : extrusionAlongPath
2697 //=======================================================================
2698 SMESH::ListOfGroups*
2699 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2700 SMESH::SMESH_Mesh_ptr thePathMesh,
2701 GEOM::GEOM_Object_ptr thePathShape,
2702 CORBA::Long theNodeStart,
2703 CORBA::Boolean theHasAngles,
2704 const SMESH::double_array & theAngles,
2705 CORBA::Boolean theHasRefPoint,
2706 const SMESH::PointStruct & theRefPoint,
2707 const bool theMakeGroups,
2708 SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
2709 const SMDSAbs_ElementType theElementType)
2711 MESSAGE("extrusionAlongPath");
2714 if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
2715 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2718 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2720 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2721 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2723 if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
2724 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2728 SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
2730 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2734 TIDSortedElemSet elements;
2735 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
2737 list<double> angles;
2738 for (int i = 0; i < theAngles.length(); i++) {
2739 angles.push_back( theAngles[i] );
2742 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
2744 int nbOldGroups = myMesh->NbGroup();
2746 ::SMESH_MeshEditor::Extrusion_Error error =
2747 getEditor().ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
2748 theHasAngles, angles, false,
2749 theHasRefPoint, refPnt, theMakeGroups );
2750 myMesh->GetMeshDS()->Modified();
2751 theError = convExtrError( error );
2753 if ( theMakeGroups ) {
2754 list<int> groupIDs = myMesh->GetGroupIds();
2755 list<int>::iterator newBegin = groupIDs.begin();
2756 std::advance( newBegin, nbOldGroups ); // skip old groups
2757 groupIDs.erase( groupIDs.begin(), newBegin );
2758 return getGroups( & groupIDs );
2764 //=======================================================================
2765 //function : extrusionAlongPathX
2767 //=======================================================================
2768 SMESH::ListOfGroups*
2769 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements,
2770 SMESH::SMESH_IDSource_ptr Path,
2771 CORBA::Long NodeStart,
2772 CORBA::Boolean HasAngles,
2773 const SMESH::double_array& Angles,
2774 CORBA::Boolean LinearVariation,
2775 CORBA::Boolean HasRefPoint,
2776 const SMESH::PointStruct& RefPoint,
2778 const SMDSAbs_ElementType ElementType,
2779 SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
2781 SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
2785 list<double> angles;
2786 for (int i = 0; i < Angles.length(); i++) {
2787 angles.push_back( Angles[i] );
2789 gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
2790 int nbOldGroups = myMesh->NbGroup();
2792 if ( Path->_is_nil() ) {
2793 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2797 TIDSortedElemSet elements, copyElements;
2798 arrayToSet(IDsOfElements, getMeshDS(), elements, ElementType);
2800 TIDSortedElemSet* workElements = &elements;
2802 if ( myIsPreviewMode )
2804 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2805 getPreviewMesh( SMDSAbs_Face )->Copy( elements, copyElements, select, avoid );
2806 workElements = & copyElements;
2810 ::SMESH_MeshEditor::Extrusion_Error error;
2812 if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path ))
2815 SMDS_MeshNode* aNodeStart =
2816 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2817 if ( !aNodeStart ) {
2818 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2821 error = getEditor().ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
2822 HasAngles, angles, LinearVariation,
2823 HasRefPoint, refPnt, MakeGroups );
2824 myMesh->GetMeshDS()->Modified();
2826 else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
2829 SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
2830 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
2831 SMDS_MeshNode* aNodeStart =
2832 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2833 if ( !aNodeStart ) {
2834 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2837 SMESH_subMesh* aSubMesh =
2838 aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
2839 error = getEditor().ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
2840 HasAngles, angles, LinearVariation,
2841 HasRefPoint, refPnt, MakeGroups );
2842 myMesh->GetMeshDS()->Modified();
2844 else if ( SMESH::DownCast<SMESH_Group_i*>( Path ))
2846 // path as group of 1D elements
2852 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2856 Error = convExtrError( error );
2859 list<int> groupIDs = myMesh->GetGroupIds();
2860 list<int>::iterator newBegin = groupIDs.begin();
2861 std::advance( newBegin, nbOldGroups ); // skip old groups
2862 groupIDs.erase( groupIDs.begin(), newBegin );
2863 return getGroups( & groupIDs );
2869 //=======================================================================
2870 //function : ExtrusionAlongPath
2872 //=======================================================================
2873 SMESH::SMESH_MeshEditor::Extrusion_Error
2874 SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2875 SMESH::SMESH_Mesh_ptr thePathMesh,
2876 GEOM::GEOM_Object_ptr thePathShape,
2877 CORBA::Long theNodeStart,
2878 CORBA::Boolean theHasAngles,
2879 const SMESH::double_array & theAngles,
2880 CORBA::Boolean theHasRefPoint,
2881 const SMESH::PointStruct & theRefPoint)
2883 MESSAGE("ExtrusionAlongPath");
2884 if ( !myIsPreviewMode ) {
2885 TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
2886 << theIDsOfElements << ", "
2887 << thePathMesh << ", "
2888 << thePathShape << ", "
2889 << theNodeStart << ", "
2890 << theHasAngles << ", "
2891 << theAngles << ", "
2892 << theHasRefPoint << ", "
2893 << "SMESH.PointStruct( "
2894 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2895 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2896 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2898 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2899 extrusionAlongPath( theIDsOfElements,
2912 //=======================================================================
2913 //function : ExtrusionAlongPathObject
2915 //=======================================================================
2916 SMESH::SMESH_MeshEditor::Extrusion_Error
2917 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject,
2918 SMESH::SMESH_Mesh_ptr thePathMesh,
2919 GEOM::GEOM_Object_ptr thePathShape,
2920 CORBA::Long theNodeStart,
2921 CORBA::Boolean theHasAngles,
2922 const SMESH::double_array & theAngles,
2923 CORBA::Boolean theHasRefPoint,
2924 const SMESH::PointStruct & theRefPoint)
2926 if ( !myIsPreviewMode ) {
2927 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
2928 << theObject << ", "
2929 << thePathMesh << ", "
2930 << thePathShape << ", "
2931 << theNodeStart << ", "
2932 << theHasAngles << ", "
2933 << theAngles << ", "
2934 << theHasRefPoint << ", "
2935 << "SMESH.PointStruct( "
2936 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2937 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2938 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2940 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2941 SMESH::long_array_var anElementsId = theObject->GetIDs();
2942 extrusionAlongPath( anElementsId,
2955 //=======================================================================
2956 //function : ExtrusionAlongPathObject1D
2958 //=======================================================================
2959 SMESH::SMESH_MeshEditor::Extrusion_Error
2960 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject,
2961 SMESH::SMESH_Mesh_ptr thePathMesh,
2962 GEOM::GEOM_Object_ptr thePathShape,
2963 CORBA::Long theNodeStart,
2964 CORBA::Boolean theHasAngles,
2965 const SMESH::double_array & theAngles,
2966 CORBA::Boolean theHasRefPoint,
2967 const SMESH::PointStruct & theRefPoint)
2969 if ( !myIsPreviewMode ) {
2970 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
2971 << theObject << ", "
2972 << thePathMesh << ", "
2973 << thePathShape << ", "
2974 << theNodeStart << ", "
2975 << theHasAngles << ", "
2976 << theAngles << ", "
2977 << theHasRefPoint << ", "
2978 << "SMESH.PointStruct( "
2979 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2980 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2981 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2983 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2984 SMESH::long_array_var anElementsId = theObject->GetIDs();
2985 extrusionAlongPath( anElementsId,
2999 //=======================================================================
3000 //function : ExtrusionAlongPathObject2D
3002 //=======================================================================
3003 SMESH::SMESH_MeshEditor::Extrusion_Error
3004 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject,
3005 SMESH::SMESH_Mesh_ptr thePathMesh,
3006 GEOM::GEOM_Object_ptr thePathShape,
3007 CORBA::Long theNodeStart,
3008 CORBA::Boolean theHasAngles,
3009 const SMESH::double_array & theAngles,
3010 CORBA::Boolean theHasRefPoint,
3011 const SMESH::PointStruct & theRefPoint)
3013 if ( !myIsPreviewMode ) {
3014 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
3015 << theObject << ", "
3016 << thePathMesh << ", "
3017 << thePathShape << ", "
3018 << theNodeStart << ", "
3019 << theHasAngles << ", "
3020 << theAngles << ", "
3021 << theHasRefPoint << ", "
3022 << "SMESH.PointStruct( "
3023 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3024 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3025 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3027 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3028 SMESH::long_array_var anElementsId = theObject->GetIDs();
3029 extrusionAlongPath( anElementsId,
3044 //=======================================================================
3045 //function : ExtrusionAlongPathMakeGroups
3047 //=======================================================================
3048 SMESH::ListOfGroups*
3049 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theIDsOfElements,
3050 SMESH::SMESH_Mesh_ptr thePathMesh,
3051 GEOM::GEOM_Object_ptr thePathShape,
3052 CORBA::Long theNodeStart,
3053 CORBA::Boolean theHasAngles,
3054 const SMESH::double_array& theAngles,
3055 CORBA::Boolean theHasRefPoint,
3056 const SMESH::PointStruct& theRefPoint,
3057 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3059 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3061 SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements,
3071 if (!myIsPreviewMode) {
3072 bool isDumpGroups = aGroups && aGroups->length() > 0;
3074 aPythonDump << "(" << aGroups << ", error)";
3076 aPythonDump <<"error";
3078 aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
3079 << theIDsOfElements << ", "
3080 << thePathMesh << ", "
3081 << thePathShape << ", "
3082 << theNodeStart << ", "
3083 << theHasAngles << ", "
3084 << theAngles << ", "
3085 << theHasRefPoint << ", "
3086 << "SMESH.PointStruct( "
3087 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3088 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3089 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3094 //=======================================================================
3095 //function : ExtrusionAlongPathObjectMakeGroups
3097 //=======================================================================
3098 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3099 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3100 SMESH::SMESH_Mesh_ptr thePathMesh,
3101 GEOM::GEOM_Object_ptr thePathShape,
3102 CORBA::Long theNodeStart,
3103 CORBA::Boolean theHasAngles,
3104 const SMESH::double_array& theAngles,
3105 CORBA::Boolean theHasRefPoint,
3106 const SMESH::PointStruct& theRefPoint,
3107 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3109 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3111 SMESH::long_array_var anElementsId = theObject->GetIDs();
3112 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3123 if (!myIsPreviewMode) {
3124 bool isDumpGroups = aGroups && aGroups->length() > 0;
3126 aPythonDump << "(" << aGroups << ", error)";
3128 aPythonDump <<"error";
3130 aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
3131 << theObject << ", "
3132 << thePathMesh << ", "
3133 << thePathShape << ", "
3134 << theNodeStart << ", "
3135 << theHasAngles << ", "
3136 << theAngles << ", "
3137 << theHasRefPoint << ", "
3138 << "SMESH.PointStruct( "
3139 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3140 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3141 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3146 //=======================================================================
3147 //function : ExtrusionAlongPathObject1DMakeGroups
3149 //=======================================================================
3150 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3151 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3152 SMESH::SMESH_Mesh_ptr thePathMesh,
3153 GEOM::GEOM_Object_ptr thePathShape,
3154 CORBA::Long theNodeStart,
3155 CORBA::Boolean theHasAngles,
3156 const SMESH::double_array& theAngles,
3157 CORBA::Boolean theHasRefPoint,
3158 const SMESH::PointStruct& theRefPoint,
3159 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3161 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3163 SMESH::long_array_var anElementsId = theObject->GetIDs();
3164 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3176 if (!myIsPreviewMode) {
3177 bool isDumpGroups = aGroups && aGroups->length() > 0;
3179 aPythonDump << "(" << aGroups << ", error)";
3181 aPythonDump << "error";
3183 aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
3184 << theObject << ", "
3185 << thePathMesh << ", "
3186 << thePathShape << ", "
3187 << theNodeStart << ", "
3188 << theHasAngles << ", "
3189 << theAngles << ", "
3190 << theHasRefPoint << ", "
3191 << "SMESH.PointStruct( "
3192 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3193 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3194 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3199 //=======================================================================
3200 //function : ExtrusionAlongPathObject2DMakeGroups
3202 //=======================================================================
3203 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3204 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3205 SMESH::SMESH_Mesh_ptr thePathMesh,
3206 GEOM::GEOM_Object_ptr thePathShape,
3207 CORBA::Long theNodeStart,
3208 CORBA::Boolean theHasAngles,
3209 const SMESH::double_array& theAngles,
3210 CORBA::Boolean theHasRefPoint,
3211 const SMESH::PointStruct& theRefPoint,
3212 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3214 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3216 SMESH::long_array_var anElementsId = theObject->GetIDs();
3217 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3229 if (!myIsPreviewMode) {
3230 bool isDumpGroups = aGroups && aGroups->length() > 0;
3232 aPythonDump << "(" << aGroups << ", error)";
3234 aPythonDump << "error";
3236 aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
3237 << theObject << ", "
3238 << thePathMesh << ", "
3239 << thePathShape << ", "
3240 << theNodeStart << ", "
3241 << theHasAngles << ", "
3242 << theAngles << ", "
3243 << theHasRefPoint << ", "
3244 << "SMESH.PointStruct( "
3245 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3246 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3247 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3253 //=======================================================================
3254 //function : ExtrusionAlongPathObjX
3256 //=======================================================================
3257 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3258 ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr Object,
3259 SMESH::SMESH_IDSource_ptr Path,
3260 CORBA::Long NodeStart,
3261 CORBA::Boolean HasAngles,
3262 const SMESH::double_array& Angles,
3263 CORBA::Boolean LinearVariation,
3264 CORBA::Boolean HasRefPoint,
3265 const SMESH::PointStruct& RefPoint,
3266 CORBA::Boolean MakeGroups,
3267 SMESH::ElementType ElemType,
3268 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3270 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3272 SMESH::long_array_var anElementsId = Object->GetIDs();
3273 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
3282 (SMDSAbs_ElementType)ElemType,
3285 if (!myIsPreviewMode) {
3286 bool isDumpGroups = aGroups && aGroups->length() > 0;
3288 aPythonDump << "(" << *aGroups << ", error)";
3290 aPythonDump << "error";
3292 aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
3295 << NodeStart << ", "
3296 << HasAngles << ", "
3297 << TVar( Angles ) << ", "
3298 << LinearVariation << ", "
3299 << HasRefPoint << ", "
3300 << "SMESH.PointStruct( "
3301 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3302 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3303 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3304 << MakeGroups << ", "
3305 << ElemType << " )";
3311 //=======================================================================
3312 //function : ExtrusionAlongPathX
3314 //=======================================================================
3315 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3316 ExtrusionAlongPathX(const SMESH::long_array& IDsOfElements,
3317 SMESH::SMESH_IDSource_ptr Path,
3318 CORBA::Long NodeStart,
3319 CORBA::Boolean HasAngles,
3320 const SMESH::double_array& Angles,
3321 CORBA::Boolean LinearVariation,
3322 CORBA::Boolean HasRefPoint,
3323 const SMESH::PointStruct& RefPoint,
3324 CORBA::Boolean MakeGroups,
3325 SMESH::ElementType ElemType,
3326 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3328 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3330 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
3339 (SMDSAbs_ElementType)ElemType,
3342 if (!myIsPreviewMode) {
3343 bool isDumpGroups = aGroups && aGroups->length() > 0;
3345 aPythonDump << "(" << *aGroups << ", error)";
3347 aPythonDump <<"error";
3349 aPythonDump << " = " << this << ".ExtrusionAlongPathX( "
3350 << IDsOfElements << ", "
3352 << NodeStart << ", "
3353 << HasAngles << ", "
3354 << TVar( Angles ) << ", "
3355 << LinearVariation << ", "
3356 << HasRefPoint << ", "
3357 << "SMESH.PointStruct( "
3358 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3359 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3360 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3361 << MakeGroups << ", "
3362 << ElemType << " )";
3368 //================================================================================
3370 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
3371 * of given angles along path steps
3372 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
3373 * which proceeds the extrusion
3374 * \param PathShape is shape(edge); as the mesh can be complex, the edge
3375 * is used to define the sub-mesh for the path
3377 //================================================================================
3379 SMESH::double_array*
3380 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
3381 GEOM::GEOM_Object_ptr thePathShape,
3382 const SMESH::double_array & theAngles)
3384 SMESH::double_array_var aResult = new SMESH::double_array();
3385 int nbAngles = theAngles.length();
3386 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
3388 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3389 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3390 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3391 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
3392 return aResult._retn();
3393 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
3394 if ( nbSteps == nbAngles )
3396 aResult.inout() = theAngles;
3400 aResult->length( nbSteps );
3401 double rAn2St = double( nbAngles ) / double( nbSteps );
3402 double angPrev = 0, angle;
3403 for ( int iSt = 0; iSt < nbSteps; ++iSt )
3405 double angCur = rAn2St * ( iSt+1 );
3406 double angCurFloor = floor( angCur );
3407 double angPrevFloor = floor( angPrev );
3408 if ( angPrevFloor == angCurFloor )
3409 angle = rAn2St * theAngles[ int( angCurFloor ) ];
3412 int iP = int( angPrevFloor );
3413 double angPrevCeil = ceil(angPrev);
3414 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
3416 int iC = int( angCurFloor );
3417 if ( iC < nbAngles )
3418 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
3420 iP = int( angPrevCeil );
3422 angle += theAngles[ iC ];
3424 aResult[ iSt ] = angle;
3429 // Update Python script
3430 TPythonDump() << "rotAngles = " << theAngles;
3431 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
3432 << thePathMesh << ", "
3433 << thePathShape << ", "
3436 return aResult._retn();
3440 //=======================================================================
3443 //=======================================================================
3445 SMESH::ListOfGroups*
3446 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
3447 const SMESH::AxisStruct & theAxis,
3448 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3449 CORBA::Boolean theCopy,
3451 ::SMESH_Mesh* theTargetMesh)
3455 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3456 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3458 if ( theTargetMesh )
3462 switch ( theMirrorType ) {
3463 case SMESH::SMESH_MeshEditor::POINT:
3464 aTrsf.SetMirror( P );
3466 case SMESH::SMESH_MeshEditor::AXIS:
3467 aTrsf.SetMirror( gp_Ax1( P, V ));
3470 aTrsf.SetMirror( gp_Ax2( P, V ));
3473 TIDSortedElemSet copyElements;
3474 TIDSortedElemSet* workElements = & theElements;
3476 if ( myIsPreviewMode )
3478 TPreviewMesh * tmpMesh = getPreviewMesh();
3479 tmpMesh->Copy( theElements, copyElements);
3480 if ( !theCopy && !theTargetMesh )
3482 TIDSortedElemSet elemsAround, elemsAroundCopy;
3483 getElementsAround( theElements, getMeshDS(), elemsAround );
3484 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3486 workElements = & copyElements;
3487 theMakeGroups = false;
3490 ::SMESH_MeshEditor::PGroupIDs groupIds =
3491 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3493 if ( theCopy && !myIsPreviewMode)
3495 if ( theTargetMesh )
3497 theTargetMesh->GetMeshDS()->Modified();
3501 myMesh->GetMeshDS()->Modified();
3502 myMesh->SetIsModified( true );
3505 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3508 //=======================================================================
3511 //=======================================================================
3513 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3514 const SMESH::AxisStruct & theAxis,
3515 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3516 CORBA::Boolean theCopy)
3518 if ( !myIsPreviewMode ) {
3519 TPythonDump() << this << ".Mirror( "
3520 << theIDsOfElements << ", "
3522 << mirrorTypeName(theMirrorType) << ", "
3525 if ( theIDsOfElements.length() > 0 )
3527 TIDSortedElemSet elements;
3528 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3529 mirror(elements, theAxis, theMirrorType, theCopy, false);
3534 //=======================================================================
3535 //function : MirrorObject
3537 //=======================================================================
3539 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3540 const SMESH::AxisStruct & theAxis,
3541 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3542 CORBA::Boolean theCopy)
3544 if ( !myIsPreviewMode ) {
3545 TPythonDump() << this << ".MirrorObject( "
3546 << theObject << ", "
3548 << mirrorTypeName(theMirrorType) << ", "
3551 TIDSortedElemSet elements;
3553 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3555 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3556 mirror(elements, theAxis, theMirrorType, theCopy, false);
3559 //=======================================================================
3560 //function : MirrorMakeGroups
3562 //=======================================================================
3564 SMESH::ListOfGroups*
3565 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3566 const SMESH::AxisStruct& theMirror,
3567 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3569 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3571 SMESH::ListOfGroups * aGroups = 0;
3572 if ( theIDsOfElements.length() > 0 )
3574 TIDSortedElemSet elements;
3575 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3576 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3578 if (!myIsPreviewMode) {
3579 DumpGroupsList(aPythonDump, aGroups);
3580 aPythonDump << this << ".MirrorMakeGroups( "
3581 << theIDsOfElements << ", "
3582 << theMirror << ", "
3583 << mirrorTypeName(theMirrorType) << " )";
3588 //=======================================================================
3589 //function : MirrorObjectMakeGroups
3591 //=======================================================================
3593 SMESH::ListOfGroups*
3594 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3595 const SMESH::AxisStruct& theMirror,
3596 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3598 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3600 SMESH::ListOfGroups * aGroups = 0;
3601 TIDSortedElemSet elements;
3602 if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3603 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3605 if (!myIsPreviewMode)
3607 DumpGroupsList(aPythonDump,aGroups);
3608 aPythonDump << this << ".MirrorObjectMakeGroups( "
3609 << theObject << ", "
3610 << theMirror << ", "
3611 << mirrorTypeName(theMirrorType) << " )";
3616 //=======================================================================
3617 //function : MirrorMakeMesh
3619 //=======================================================================
3621 SMESH::SMESH_Mesh_ptr
3622 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
3623 const SMESH::AxisStruct& theMirror,
3624 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3625 CORBA::Boolean theCopyGroups,
3626 const char* theMeshName)
3628 SMESH_Mesh_i* mesh_i;
3629 SMESH::SMESH_Mesh_var mesh;
3630 { // open new scope to dump "MakeMesh" command
3631 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3633 TPythonDump pydump; // to prevent dump at mesh creation
3635 mesh = makeMesh( theMeshName );
3636 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3637 if (mesh_i && theIDsOfElements.length() > 0 )
3639 TIDSortedElemSet elements;
3640 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3641 mirror(elements, theMirror, theMirrorType,
3642 false, theCopyGroups, & mesh_i->GetImpl());
3643 mesh_i->CreateGroupServants();
3646 if (!myIsPreviewMode) {
3647 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
3648 << theIDsOfElements << ", "
3649 << theMirror << ", "
3650 << mirrorTypeName(theMirrorType) << ", "
3651 << theCopyGroups << ", '"
3652 << theMeshName << "' )";
3657 if (!myIsPreviewMode && mesh_i)
3658 mesh_i->GetGroups();
3660 return mesh._retn();
3663 //=======================================================================
3664 //function : MirrorObjectMakeMesh
3666 //=======================================================================
3668 SMESH::SMESH_Mesh_ptr
3669 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3670 const SMESH::AxisStruct& theMirror,
3671 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3672 CORBA::Boolean theCopyGroups,
3673 const char* theMeshName)
3675 SMESH_Mesh_i* mesh_i;
3676 SMESH::SMESH_Mesh_var mesh;
3677 { // open new scope to dump "MakeMesh" command
3678 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3680 TPythonDump pydump; // to prevent dump at mesh creation
3682 mesh = makeMesh( theMeshName );
3683 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3684 TIDSortedElemSet elements;
3686 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3688 mirror(elements, theMirror, theMirrorType,
3689 false, theCopyGroups, & mesh_i->GetImpl());
3690 mesh_i->CreateGroupServants();
3692 if (!myIsPreviewMode) {
3693 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
3694 << theObject << ", "
3695 << theMirror << ", "
3696 << mirrorTypeName(theMirrorType) << ", "
3697 << theCopyGroups << ", '"
3698 << theMeshName << "' )";
3703 if (!myIsPreviewMode && mesh_i)
3704 mesh_i->GetGroups();
3706 return mesh._retn();
3709 //=======================================================================
3710 //function : translate
3712 //=======================================================================
3714 SMESH::ListOfGroups*
3715 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
3716 const SMESH::DirStruct & theVector,
3717 CORBA::Boolean theCopy,
3719 ::SMESH_Mesh* theTargetMesh)
3723 if ( theTargetMesh )
3727 const SMESH::PointStruct * P = &theVector.PS;
3728 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
3730 TIDSortedElemSet copyElements;
3731 TIDSortedElemSet* workElements = &theElements;
3733 if ( myIsPreviewMode )
3735 TPreviewMesh * tmpMesh = getPreviewMesh();
3736 tmpMesh->Copy( theElements, copyElements);
3737 if ( !theCopy && !theTargetMesh )
3739 TIDSortedElemSet elemsAround, elemsAroundCopy;
3740 getElementsAround( theElements, getMeshDS(), elemsAround );
3741 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3743 workElements = & copyElements;
3744 theMakeGroups = false;
3747 ::SMESH_MeshEditor::PGroupIDs groupIds =
3748 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3750 if ( theCopy && !myIsPreviewMode )
3752 if ( theTargetMesh )
3754 theTargetMesh->GetMeshDS()->Modified();
3758 myMesh->GetMeshDS()->Modified();
3759 myMesh->SetIsModified( true );
3763 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3766 //=======================================================================
3767 //function : Translate
3769 //=======================================================================
3771 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
3772 const SMESH::DirStruct & theVector,
3773 CORBA::Boolean theCopy)
3775 if (!myIsPreviewMode) {
3776 TPythonDump() << this << ".Translate( "
3777 << theIDsOfElements << ", "
3778 << theVector << ", "
3781 if (theIDsOfElements.length()) {
3782 TIDSortedElemSet elements;
3783 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3784 translate(elements, theVector, theCopy, false);
3788 //=======================================================================
3789 //function : TranslateObject
3791 //=======================================================================
3793 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
3794 const SMESH::DirStruct & theVector,
3795 CORBA::Boolean theCopy)
3797 if (!myIsPreviewMode) {
3798 TPythonDump() << this << ".TranslateObject( "
3799 << theObject << ", "
3800 << theVector << ", "
3803 TIDSortedElemSet elements;
3805 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3807 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3808 translate(elements, theVector, theCopy, false);
3811 //=======================================================================
3812 //function : TranslateMakeGroups
3814 //=======================================================================
3816 SMESH::ListOfGroups*
3817 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
3818 const SMESH::DirStruct& theVector)
3820 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3822 SMESH::ListOfGroups * aGroups = 0;
3823 if (theIDsOfElements.length()) {
3824 TIDSortedElemSet elements;
3825 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3826 aGroups = translate(elements,theVector,true,true);
3828 if (!myIsPreviewMode) {
3829 DumpGroupsList(aPythonDump, aGroups);
3830 aPythonDump << this << ".TranslateMakeGroups( "
3831 << theIDsOfElements << ", "
3832 << theVector << " )";
3837 //=======================================================================
3838 //function : TranslateObjectMakeGroups
3840 //=======================================================================
3842 SMESH::ListOfGroups*
3843 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3844 const SMESH::DirStruct& theVector)
3846 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3848 SMESH::ListOfGroups * aGroups = 0;
3849 TIDSortedElemSet elements;
3850 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3851 aGroups = translate(elements, theVector, true, true);
3853 if (!myIsPreviewMode) {
3854 DumpGroupsList(aPythonDump, aGroups);
3855 aPythonDump << this << ".TranslateObjectMakeGroups( "
3856 << theObject << ", "
3857 << theVector << " )";
3862 //=======================================================================
3863 //function : TranslateMakeMesh
3865 //=======================================================================
3867 SMESH::SMESH_Mesh_ptr
3868 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
3869 const SMESH::DirStruct& theVector,
3870 CORBA::Boolean theCopyGroups,
3871 const char* theMeshName)
3873 SMESH_Mesh_i* mesh_i;
3874 SMESH::SMESH_Mesh_var mesh;
3876 { // open new scope to dump "MakeMesh" command
3877 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3879 TPythonDump pydump; // to prevent dump at mesh creation
3881 mesh = makeMesh( theMeshName );
3882 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3884 if ( mesh_i && theIDsOfElements.length() )
3886 TIDSortedElemSet elements;
3887 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3888 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
3889 mesh_i->CreateGroupServants();
3892 if ( !myIsPreviewMode ) {
3893 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
3894 << theIDsOfElements << ", "
3895 << theVector << ", "
3896 << theCopyGroups << ", '"
3897 << theMeshName << "' )";
3902 if (!myIsPreviewMode && mesh_i)
3903 mesh_i->GetGroups();
3905 return mesh._retn();
3908 //=======================================================================
3909 //function : TranslateObjectMakeMesh
3911 //=======================================================================
3913 SMESH::SMESH_Mesh_ptr
3914 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3915 const SMESH::DirStruct& theVector,
3916 CORBA::Boolean theCopyGroups,
3917 const char* theMeshName)
3919 SMESH_Mesh_i* mesh_i;
3920 SMESH::SMESH_Mesh_var mesh;
3921 { // open new scope to dump "MakeMesh" command
3922 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3924 TPythonDump pydump; // to prevent dump at mesh creation
3925 mesh = makeMesh( theMeshName );
3926 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3928 TIDSortedElemSet elements;
3930 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3932 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
3933 mesh_i->CreateGroupServants();
3935 if ( !myIsPreviewMode ) {
3936 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
3937 << theObject << ", "
3938 << theVector << ", "
3939 << theCopyGroups << ", '"
3940 << theMeshName << "' )";
3945 if (!myIsPreviewMode && mesh_i)
3946 mesh_i->GetGroups();
3948 return mesh._retn();
3951 //=======================================================================
3954 //=======================================================================
3956 SMESH::ListOfGroups*
3957 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
3958 const SMESH::AxisStruct & theAxis,
3959 CORBA::Double theAngle,
3960 CORBA::Boolean theCopy,
3962 ::SMESH_Mesh* theTargetMesh)
3966 if ( theTargetMesh )
3969 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3970 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3973 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
3975 TIDSortedElemSet copyElements;
3976 TIDSortedElemSet* workElements = &theElements;
3977 if ( myIsPreviewMode ) {
3978 TPreviewMesh * tmpMesh = getPreviewMesh();
3979 tmpMesh->Copy( theElements, copyElements );
3980 if ( !theCopy && !theTargetMesh )
3982 TIDSortedElemSet elemsAround, elemsAroundCopy;
3983 getElementsAround( theElements, getMeshDS(), elemsAround );
3984 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3986 workElements = ©Elements;
3987 theMakeGroups = false;
3990 ::SMESH_MeshEditor::PGroupIDs groupIds =
3991 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3993 if ( theCopy && !myIsPreviewMode)
3995 if ( theTargetMesh )
3997 theTargetMesh->GetMeshDS()->Modified();
4001 myMesh->GetMeshDS()->Modified();
4002 myMesh->SetIsModified( true );
4006 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4009 //=======================================================================
4012 //=======================================================================
4014 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
4015 const SMESH::AxisStruct & theAxis,
4016 CORBA::Double theAngle,
4017 CORBA::Boolean theCopy)
4019 if (!myIsPreviewMode) {
4020 TPythonDump() << this << ".Rotate( "
4021 << theIDsOfElements << ", "
4023 << TVar( theAngle ) << ", "
4026 if (theIDsOfElements.length() > 0)
4028 TIDSortedElemSet elements;
4029 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4030 rotate(elements,theAxis,theAngle,theCopy,false);
4034 //=======================================================================
4035 //function : RotateObject
4037 //=======================================================================
4039 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
4040 const SMESH::AxisStruct & theAxis,
4041 CORBA::Double theAngle,
4042 CORBA::Boolean theCopy)
4044 if ( !myIsPreviewMode ) {
4045 TPythonDump() << this << ".RotateObject( "
4046 << theObject << ", "
4048 << TVar( theAngle ) << ", "
4051 TIDSortedElemSet elements;
4052 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4053 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4054 rotate(elements,theAxis,theAngle,theCopy,false);
4057 //=======================================================================
4058 //function : RotateMakeGroups
4060 //=======================================================================
4062 SMESH::ListOfGroups*
4063 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
4064 const SMESH::AxisStruct& theAxis,
4065 CORBA::Double theAngle)
4067 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4069 SMESH::ListOfGroups * aGroups = 0;
4070 if (theIDsOfElements.length() > 0)
4072 TIDSortedElemSet elements;
4073 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4074 aGroups = rotate(elements,theAxis,theAngle,true,true);
4076 if (!myIsPreviewMode) {
4077 DumpGroupsList(aPythonDump, aGroups);
4078 aPythonDump << this << ".RotateMakeGroups( "
4079 << theIDsOfElements << ", "
4081 << TVar( theAngle ) << " )";
4086 //=======================================================================
4087 //function : RotateObjectMakeGroups
4089 //=======================================================================
4091 SMESH::ListOfGroups*
4092 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4093 const SMESH::AxisStruct& theAxis,
4094 CORBA::Double theAngle)
4096 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4098 SMESH::ListOfGroups * aGroups = 0;
4099 TIDSortedElemSet elements;
4100 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4101 aGroups = rotate(elements, theAxis, theAngle, true, true);
4103 if (!myIsPreviewMode) {
4104 DumpGroupsList(aPythonDump, aGroups);
4105 aPythonDump << this << ".RotateObjectMakeGroups( "
4106 << theObject << ", "
4108 << TVar( theAngle ) << " )";
4113 //=======================================================================
4114 //function : RotateMakeMesh
4116 //=======================================================================
4118 SMESH::SMESH_Mesh_ptr
4119 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
4120 const SMESH::AxisStruct& theAxis,
4121 CORBA::Double theAngleInRadians,
4122 CORBA::Boolean theCopyGroups,
4123 const char* theMeshName)
4125 SMESH::SMESH_Mesh_var mesh;
4126 SMESH_Mesh_i* mesh_i;
4128 { // open new scope to dump "MakeMesh" command
4129 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4131 TPythonDump pydump; // to prevent dump at mesh creation
4133 mesh = makeMesh( theMeshName );
4134 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4136 if ( mesh_i && theIDsOfElements.length() > 0 )
4138 TIDSortedElemSet elements;
4139 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4140 rotate(elements, theAxis, theAngleInRadians,
4141 false, theCopyGroups, & mesh_i->GetImpl());
4142 mesh_i->CreateGroupServants();
4144 if ( !myIsPreviewMode ) {
4145 pydump << mesh << " = " << this << ".RotateMakeMesh( "
4146 << theIDsOfElements << ", "
4148 << TVar( theAngleInRadians ) << ", "
4149 << theCopyGroups << ", '"
4150 << theMeshName << "' )";
4155 if (!myIsPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
4156 mesh_i->GetGroups();
4158 return mesh._retn();
4161 //=======================================================================
4162 //function : RotateObjectMakeMesh
4164 //=======================================================================
4166 SMESH::SMESH_Mesh_ptr
4167 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4168 const SMESH::AxisStruct& theAxis,
4169 CORBA::Double theAngleInRadians,
4170 CORBA::Boolean theCopyGroups,
4171 const char* theMeshName)
4173 SMESH::SMESH_Mesh_var mesh;
4174 SMESH_Mesh_i* mesh_i;
4176 {// open new scope to dump "MakeMesh" command
4177 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4179 TPythonDump pydump; // to prevent dump at mesh creation
4180 mesh = makeMesh( theMeshName );
4181 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4183 TIDSortedElemSet elements;
4185 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4187 rotate(elements, theAxis, theAngleInRadians,
4188 false, theCopyGroups, & mesh_i->GetImpl());
4189 mesh_i->CreateGroupServants();
4191 if ( !myIsPreviewMode ) {
4192 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
4193 << theObject << ", "
4195 << TVar( theAngleInRadians ) << ", "
4196 << theCopyGroups << ", '"
4197 << theMeshName << "' )";
4202 if (!myIsPreviewMode && mesh_i)
4203 mesh_i->GetGroups();
4205 return mesh._retn();
4208 //=======================================================================
4211 //=======================================================================
4213 SMESH::ListOfGroups*
4214 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
4215 const SMESH::PointStruct& thePoint,
4216 const SMESH::double_array& theScaleFact,
4217 CORBA::Boolean theCopy,
4219 ::SMESH_Mesh* theTargetMesh)
4222 if ( theScaleFact.length() < 1 )
4223 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
4224 if ( theScaleFact.length() == 2 )
4225 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
4227 if ( theTargetMesh )
4230 TIDSortedElemSet elements;
4231 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4232 if ( !idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4237 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
4238 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
4240 double tol = std::numeric_limits<double>::max();
4242 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
4243 0, S[1], 0, thePoint.y * (1-S[1]),
4244 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
4246 TIDSortedElemSet copyElements;
4247 TIDSortedElemSet* workElements = &elements;
4248 if ( myIsPreviewMode )
4250 TPreviewMesh * tmpMesh = getPreviewMesh();
4251 tmpMesh->Copy( elements, copyElements);
4252 if ( !theCopy && !theTargetMesh )
4254 TIDSortedElemSet elemsAround, elemsAroundCopy;
4255 getElementsAround( elements, getMeshDS(), elemsAround );
4256 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4258 workElements = & copyElements;
4259 theMakeGroups = false;
4262 ::SMESH_MeshEditor::PGroupIDs groupIds =
4263 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4265 if ( theCopy && !myIsPreviewMode )
4267 if ( theTargetMesh )
4269 theTargetMesh->GetMeshDS()->Modified();
4273 myMesh->GetMeshDS()->Modified();
4274 myMesh->SetIsModified( true );
4278 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4281 //=======================================================================
4284 //=======================================================================
4286 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
4287 const SMESH::PointStruct& thePoint,
4288 const SMESH::double_array& theScaleFact,
4289 CORBA::Boolean theCopy)
4291 if ( !myIsPreviewMode ) {
4292 TPythonDump() << this << ".Scale( "
4293 << theObject << ", "
4295 << TVar( theScaleFact ) << ", "
4298 scale(theObject, thePoint, theScaleFact, theCopy, false);
4302 //=======================================================================
4303 //function : ScaleMakeGroups
4305 //=======================================================================
4307 SMESH::ListOfGroups*
4308 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4309 const SMESH::PointStruct& thePoint,
4310 const SMESH::double_array& theScaleFact)
4312 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4314 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
4315 if (!myIsPreviewMode) {
4316 DumpGroupsList(aPythonDump, aGroups);
4317 aPythonDump << this << ".Scale("
4320 << TVar( theScaleFact ) << ",True,True)";
4326 //=======================================================================
4327 //function : ScaleMakeMesh
4329 //=======================================================================
4331 SMESH::SMESH_Mesh_ptr
4332 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4333 const SMESH::PointStruct& thePoint,
4334 const SMESH::double_array& theScaleFact,
4335 CORBA::Boolean theCopyGroups,
4336 const char* theMeshName)
4338 SMESH_Mesh_i* mesh_i;
4339 SMESH::SMESH_Mesh_var mesh;
4340 { // open new scope to dump "MakeMesh" command
4341 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4343 TPythonDump pydump; // to prevent dump at mesh creation
4344 mesh = makeMesh( theMeshName );
4345 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4349 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
4350 mesh_i->CreateGroupServants();
4352 if ( !myIsPreviewMode )
4353 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
4354 << theObject << ", "
4356 << TVar( theScaleFact ) << ", "
4357 << theCopyGroups << ", '"
4358 << theMeshName << "' )";
4362 if (!myIsPreviewMode && mesh_i)
4363 mesh_i->GetGroups();
4365 return mesh._retn();
4369 //=======================================================================
4370 //function : FindCoincidentNodes
4372 //=======================================================================
4374 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance,
4375 SMESH::array_of_long_array_out GroupsOfNodes)
4379 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4380 TIDSortedNodeSet nodes; // no input nodes
4381 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4383 GroupsOfNodes = new SMESH::array_of_long_array;
4384 GroupsOfNodes->length( aListOfListOfNodes.size() );
4385 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4386 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
4387 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4388 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4389 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4390 aGroup.length( aListOfNodes.size() );
4391 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4392 aGroup[ j ] = (*lIt)->GetID();
4394 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
4395 << Tolerance << " )";
4398 //=======================================================================
4399 //function : FindCoincidentNodesOnPart
4401 //=======================================================================
4402 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
4403 CORBA::Double Tolerance,
4404 SMESH::array_of_long_array_out GroupsOfNodes)
4408 TIDSortedNodeSet nodes;
4409 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4411 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4413 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4415 GroupsOfNodes = new SMESH::array_of_long_array;
4416 GroupsOfNodes->length( aListOfListOfNodes.size() );
4417 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4418 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4420 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4421 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4422 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4423 aGroup.length( aListOfNodes.size() );
4424 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4425 aGroup[ j ] = (*lIt)->GetID();
4427 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
4429 << Tolerance << " )";
4432 //================================================================================
4434 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
4435 * ExceptSubMeshOrGroups
4437 //================================================================================
4439 void SMESH_MeshEditor_i::
4440 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
4441 CORBA::Double theTolerance,
4442 SMESH::array_of_long_array_out theGroupsOfNodes,
4443 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups)
4447 TIDSortedNodeSet nodes;
4448 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4450 for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
4452 TIDSortedNodeSet exceptNodes;
4453 idSourceToNodeSet( theExceptSubMeshOrGroups[i], getMeshDS(), exceptNodes );
4454 TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
4455 for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
4456 nodes.erase( *avoidNode );
4458 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4460 getEditor().FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
4462 theGroupsOfNodes = new SMESH::array_of_long_array;
4463 theGroupsOfNodes->length( aListOfListOfNodes.size() );
4464 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4465 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4467 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4468 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4469 SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
4470 aGroup.length( aListOfNodes.size() );
4471 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4472 aGroup[ j ] = (*lIt)->GetID();
4474 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
4476 << theTolerance << ", "
4477 << theExceptSubMeshOrGroups << " )";
4480 //=======================================================================
4481 //function : MergeNodes
4483 //=======================================================================
4485 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
4489 SMESHDS_Mesh* aMesh = getMeshDS();
4491 TPythonDump aTPythonDump;
4492 aTPythonDump << this << ".MergeNodes([";
4493 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4494 for (int i = 0; i < GroupsOfNodes.length(); i++)
4496 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
4497 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
4498 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
4499 for ( int j = 0; j < aNodeGroup.length(); j++ )
4501 CORBA::Long index = aNodeGroup[ j ];
4502 const SMDS_MeshNode * node = aMesh->FindNode(index);
4504 aListOfNodes.push_back( node );
4506 if ( aListOfNodes.size() < 2 )
4507 aListOfListOfNodes.pop_back();
4509 if ( i > 0 ) aTPythonDump << ", ";
4510 aTPythonDump << aNodeGroup;
4512 getEditor().MergeNodes( aListOfListOfNodes );
4514 aTPythonDump << "])";
4515 myMesh->GetMeshDS()->Modified();
4516 myMesh->SetIsModified( true );
4519 //=======================================================================
4520 //function : FindEqualElements
4522 //=======================================================================
4523 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
4524 SMESH::array_of_long_array_out GroupsOfElementsID)
4528 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
4529 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
4531 TIDSortedElemSet elems;
4532 idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true);
4534 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4535 getEditor().FindEqualElements( elems, aListOfListOfElementsID );
4537 GroupsOfElementsID = new SMESH::array_of_long_array;
4538 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
4540 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt =
4541 aListOfListOfElementsID.begin();
4542 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j)
4544 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
4545 list<int>& listOfIDs = *arraysIt;
4546 aGroup.length( listOfIDs.size() );
4547 list<int>::iterator idIt = listOfIDs.begin();
4548 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k )
4549 aGroup[ k ] = *idIt;
4552 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
4557 //=======================================================================
4558 //function : MergeElements
4560 //=======================================================================
4562 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
4566 TPythonDump aTPythonDump;
4567 aTPythonDump << this << ".MergeElements( [";
4569 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4571 for (int i = 0; i < GroupsOfElementsID.length(); i++) {
4572 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
4573 aListOfListOfElementsID.push_back( list< int >() );
4574 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
4575 for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
4576 CORBA::Long id = anElemsIDGroup[ j ];
4577 aListOfElemsID.push_back( id );
4579 if ( aListOfElemsID.size() < 2 )
4580 aListOfListOfElementsID.pop_back();
4581 if ( i > 0 ) aTPythonDump << ", ";
4582 aTPythonDump << anElemsIDGroup;
4585 getEditor().MergeElements(aListOfListOfElementsID);
4586 myMesh->GetMeshDS()->Modified();
4587 myMesh->SetIsModified( true );
4589 aTPythonDump << "] )";
4592 //=======================================================================
4593 //function : MergeEqualElements
4595 //=======================================================================
4597 void SMESH_MeshEditor_i::MergeEqualElements()
4601 getEditor().MergeEqualElements();
4603 myMesh->GetMeshDS()->Modified();
4605 TPythonDump() << this << ".MergeEqualElements()";
4608 //=============================================================================
4610 * Move the node to a given point
4612 //=============================================================================
4614 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
4619 initData(/*deleteSearchers=*/false);
4621 const SMDS_MeshNode * node = getMeshDS()->FindNode( NodeID );
4625 if ( theNodeSearcher )
4626 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4628 if ( myIsPreviewMode ) // make preview data
4630 // in a preview mesh, make edges linked to a node
4631 TPreviewMesh& tmpMesh = *getPreviewMesh();
4632 TIDSortedElemSet linkedNodes;
4633 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4634 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4635 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
4636 for ( ; nIt != linkedNodes.end(); ++nIt )
4638 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
4639 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
4643 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
4644 // fill preview data
4646 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4647 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4649 getMeshDS()->MoveNode(node, x, y, z);
4651 if ( !myIsPreviewMode )
4653 // Update Python script
4654 TPythonDump() << "isDone = " << this << ".MoveNode( "
4655 << NodeID << ", " << TVar(x) << ", " << TVar(y) << ", " << TVar(z) << " )";
4656 myMesh->GetMeshDS()->Modified();
4657 myMesh->SetIsModified( true );
4663 //================================================================================
4665 * \brief Return ID of node closest to a given point
4667 //================================================================================
4669 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
4673 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4675 if ( !theNodeSearcher ) {
4676 theNodeSearcher = myEditor.GetNodeSearcher();
4679 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
4680 return node->GetID();
4685 //================================================================================
4687 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
4688 * move the node closest to the point to point's location and return ID of the node
4690 //================================================================================
4692 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
4695 CORBA::Long theNodeID)
4697 // We keep theNodeSearcher until any mesh modification:
4698 // 1) initData() deletes theNodeSearcher at any edition,
4699 // 2) TSearchersDeleter - at any mesh compute event and mesh change
4701 initData(/*deleteSearchers=*/false);
4703 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4705 int nodeID = theNodeID;
4706 const SMDS_MeshNode* node = getMeshDS()->FindNode( nodeID );
4707 if ( !node ) // preview moving node
4709 if ( !theNodeSearcher ) {
4710 theNodeSearcher = myEditor.GetNodeSearcher();
4713 node = theNodeSearcher->FindClosestTo( p );
4716 nodeID = node->GetID();
4717 if ( myIsPreviewMode ) // make preview data
4719 // in a preview mesh, make edges linked to a node
4720 TPreviewMesh tmpMesh = *getPreviewMesh();
4721 TIDSortedElemSet linkedNodes;
4722 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4723 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4724 for ( ; nIt != linkedNodes.end(); ++nIt )
4726 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
4727 tmpMesh.Copy( &edge );
4730 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
4732 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
4733 // fill preview data
4735 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4737 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4741 getMeshDS()->MoveNode(node, x, y, z);
4745 if ( !myIsPreviewMode )
4747 TPythonDump() << "nodeID = " << this
4748 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
4749 << ", " << nodeID << " )";
4751 myMesh->GetMeshDS()->Modified();
4752 myMesh->SetIsModified( true );
4758 //=======================================================================
4760 * Return elements of given type where the given point is IN or ON.
4762 * 'ALL' type means elements of any type excluding nodes
4764 //=======================================================================
4766 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
4769 SMESH::ElementType type)
4771 SMESH::long_array_var res = new SMESH::long_array;
4772 vector< const SMDS_MeshElement* > foundElems;
4774 theSearchersDeleter.Set( myMesh );
4775 if ( !theElementSearcher ) {
4776 theElementSearcher = myEditor.GetElementSearcher();
4778 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4779 SMDSAbs_ElementType( type ),
4781 res->length( foundElems.size() );
4782 for ( int i = 0; i < foundElems.size(); ++i )
4783 res[i] = foundElems[i]->GetID();
4785 if ( !myIsPreviewMode ) // call from tui
4786 TPythonDump() << "res = " << this << ".FindElementsByPoint( "
4795 //=======================================================================
4796 //function : FindAmongElementsByPoint
4797 //purpose : Searching among the given elements, return elements of given type
4798 // where the given point is IN or ON.
4799 // 'ALL' type means elements of any type excluding nodes
4800 //=======================================================================
4803 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
4807 SMESH::ElementType type)
4809 SMESH::long_array_var res = new SMESH::long_array;
4811 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
4812 if ( types->length() == 1 && // a part contains only nodes or 0D elements
4813 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) &&
4814 type != types[0] ) // but search of elements of dim > 0
4817 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
4818 return FindElementsByPoint( x,y,z, type );
4820 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
4822 theSearchersDeleter.Set( myMesh, getPartIOR( elementIDs, type ));
4823 if ( !theElementSearcher )
4825 // create a searcher from elementIDs
4826 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
4827 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
4829 if ( !idSourceToSet( elementIDs, meshDS, elements,
4830 SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
4833 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
4834 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
4836 theElementSearcher = myEditor.GetElementSearcher(elemsIt);
4839 vector< const SMDS_MeshElement* > foundElems;
4841 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4842 SMDSAbs_ElementType( type ),
4844 res->length( foundElems.size() );
4845 for ( int i = 0; i < foundElems.size(); ++i )
4846 res[i] = foundElems[i]->GetID();
4848 if ( !myIsPreviewMode ) // call from tui
4849 TPythonDump() << "res = " << this << ".FindAmongElementsByPoint( "
4850 << elementIDs << ", "
4859 //=======================================================================
4860 //function : GetPointState
4861 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
4862 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
4863 //=======================================================================
4865 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
4869 theSearchersDeleter.Set( myMesh );
4870 if ( !theElementSearcher ) {
4871 theElementSearcher = myEditor.GetElementSearcher();
4873 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
4876 //=======================================================================
4877 //function : convError
4879 //=======================================================================
4881 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
4883 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
4887 RETCASE( SEW_BORDER1_NOT_FOUND );
4888 RETCASE( SEW_BORDER2_NOT_FOUND );
4889 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
4890 RETCASE( SEW_BAD_SIDE_NODES );
4891 RETCASE( SEW_VOLUMES_TO_SPLIT );
4892 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
4893 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
4894 RETCASE( SEW_BAD_SIDE1_NODES );
4895 RETCASE( SEW_BAD_SIDE2_NODES );
4897 return SMESH::SMESH_MeshEditor::SEW_OK;
4900 //=======================================================================
4901 //function : SewFreeBorders
4903 //=======================================================================
4905 SMESH::SMESH_MeshEditor::Sew_Error
4906 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
4907 CORBA::Long SecondNodeID1,
4908 CORBA::Long LastNodeID1,
4909 CORBA::Long FirstNodeID2,
4910 CORBA::Long SecondNodeID2,
4911 CORBA::Long LastNodeID2,
4912 CORBA::Boolean CreatePolygons,
4913 CORBA::Boolean CreatePolyedrs)
4917 SMESHDS_Mesh* aMesh = getMeshDS();
4919 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4920 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4921 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4922 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4923 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4924 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
4926 if (!aBorderFirstNode ||
4927 !aBorderSecondNode||
4929 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4930 if (!aSide2FirstNode ||
4931 !aSide2SecondNode ||
4933 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4935 TPythonDump() << "error = " << this << ".SewFreeBorders( "
4936 << FirstNodeID1 << ", "
4937 << SecondNodeID1 << ", "
4938 << LastNodeID1 << ", "
4939 << FirstNodeID2 << ", "
4940 << SecondNodeID2 << ", "
4941 << LastNodeID2 << ", "
4942 << CreatePolygons<< ", "
4943 << CreatePolyedrs<< " )";
4945 SMESH::SMESH_MeshEditor::Sew_Error error =
4946 convError( getEditor().SewFreeBorder (aBorderFirstNode,
4957 myMesh->GetMeshDS()->Modified();
4958 myMesh->SetIsModified( true );
4964 //=======================================================================
4965 //function : SewConformFreeBorders
4967 //=======================================================================
4969 SMESH::SMESH_MeshEditor::Sew_Error
4970 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
4971 CORBA::Long SecondNodeID1,
4972 CORBA::Long LastNodeID1,
4973 CORBA::Long FirstNodeID2,
4974 CORBA::Long SecondNodeID2)
4978 SMESHDS_Mesh* aMesh = getMeshDS();
4980 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4981 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4982 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4983 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4984 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4985 const SMDS_MeshNode* aSide2ThirdNode = 0;
4987 if (!aBorderFirstNode ||
4988 !aBorderSecondNode||
4990 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4991 if (!aSide2FirstNode ||
4993 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4995 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
4996 << FirstNodeID1 << ", "
4997 << SecondNodeID1 << ", "
4998 << LastNodeID1 << ", "
4999 << FirstNodeID2 << ", "
5000 << SecondNodeID2 << " )";
5002 SMESH::SMESH_MeshEditor::Sew_Error error =
5003 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5013 myMesh->GetMeshDS()->Modified();
5014 myMesh->SetIsModified( true );
5020 //=======================================================================
5021 //function : SewBorderToSide
5023 //=======================================================================
5025 SMESH::SMESH_MeshEditor::Sew_Error
5026 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
5027 CORBA::Long SecondNodeIDOnFreeBorder,
5028 CORBA::Long LastNodeIDOnFreeBorder,
5029 CORBA::Long FirstNodeIDOnSide,
5030 CORBA::Long LastNodeIDOnSide,
5031 CORBA::Boolean CreatePolygons,
5032 CORBA::Boolean CreatePolyedrs)
5036 SMESHDS_Mesh* aMesh = getMeshDS();
5038 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
5039 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
5040 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
5041 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
5042 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
5043 const SMDS_MeshNode* aSide2ThirdNode = 0;
5045 if (!aBorderFirstNode ||
5046 !aBorderSecondNode||
5048 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5049 if (!aSide2FirstNode ||
5051 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
5053 TPythonDump() << "error = " << this << ".SewBorderToSide( "
5054 << FirstNodeIDOnFreeBorder << ", "
5055 << SecondNodeIDOnFreeBorder << ", "
5056 << LastNodeIDOnFreeBorder << ", "
5057 << FirstNodeIDOnSide << ", "
5058 << LastNodeIDOnSide << ", "
5059 << CreatePolygons << ", "
5060 << CreatePolyedrs << ") ";
5062 SMESH::SMESH_MeshEditor::Sew_Error error =
5063 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5074 myMesh->GetMeshDS()->Modified();
5075 myMesh->SetIsModified( true );
5081 //=======================================================================
5082 //function : SewSideElements
5084 //=======================================================================
5086 SMESH::SMESH_MeshEditor::Sew_Error
5087 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
5088 const SMESH::long_array& IDsOfSide2Elements,
5089 CORBA::Long NodeID1OfSide1ToMerge,
5090 CORBA::Long NodeID1OfSide2ToMerge,
5091 CORBA::Long NodeID2OfSide1ToMerge,
5092 CORBA::Long NodeID2OfSide2ToMerge)
5096 SMESHDS_Mesh* aMesh = getMeshDS();
5098 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
5099 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
5100 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
5101 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
5103 if (!aFirstNode1ToMerge ||
5104 !aFirstNode2ToMerge )
5105 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
5106 if (!aSecondNode1ToMerge||
5107 !aSecondNode2ToMerge)
5108 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
5110 TIDSortedElemSet aSide1Elems, aSide2Elems;
5111 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
5112 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
5114 TPythonDump() << "error = " << this << ".SewSideElements( "
5115 << IDsOfSide1Elements << ", "
5116 << IDsOfSide2Elements << ", "
5117 << NodeID1OfSide1ToMerge << ", "
5118 << NodeID1OfSide2ToMerge << ", "
5119 << NodeID2OfSide1ToMerge << ", "
5120 << NodeID2OfSide2ToMerge << ")";
5122 SMESH::SMESH_MeshEditor::Sew_Error error =
5123 convError( getEditor().SewSideElements (aSide1Elems, aSide2Elems,
5126 aSecondNode1ToMerge,
5127 aSecondNode2ToMerge));
5130 myMesh->GetMeshDS()->Modified();
5131 myMesh->SetIsModified( true );
5136 //================================================================================
5138 * \brief Set new nodes for given element
5139 * \param ide - element id
5140 * \param newIDs - new node ids
5141 * \retval CORBA::Boolean - true if result is OK
5143 //================================================================================
5145 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
5146 const SMESH::long_array& newIDs)
5150 const SMDS_MeshElement* elem = getMeshDS()->FindElement(ide);
5151 if(!elem) return false;
5153 int nbn = newIDs.length();
5155 vector<const SMDS_MeshNode*> aNodes(nbn);
5158 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(newIDs[i]);
5161 aNodes[nbn1] = aNode;
5164 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
5165 << ide << ", " << newIDs << " )";
5167 MESSAGE("ChangeElementNodes");
5168 bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
5170 myMesh->GetMeshDS()->Modified();
5172 myMesh->SetIsModified( true );
5177 //=======================================================================
5178 //function : ConvertToQuadratic
5180 //=======================================================================
5182 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
5184 getEditor().ConvertToQuadratic(theForce3d);
5185 TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )";
5186 myMesh->GetMeshDS()->Modified();
5187 myMesh->SetIsModified( true );
5190 //=======================================================================
5191 //function : ConvertFromQuadratic
5193 //=======================================================================
5195 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
5197 CORBA::Boolean isDone = getEditor().ConvertFromQuadratic();
5198 TPythonDump() << this << ".ConvertFromQuadratic()";
5199 myMesh->GetMeshDS()->Modified();
5201 myMesh->SetIsModified( true );
5204 //================================================================================
5206 * \brief Makes a part of the mesh quadratic
5208 //================================================================================
5210 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
5211 SMESH::SMESH_IDSource_ptr theObject)
5212 throw (SALOME::SALOME_Exception)
5214 Unexpect aCatch(SALOME_SalomeException);
5216 TIDSortedElemSet elems;
5217 if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5219 if ( elems.empty() )
5221 ConvertToQuadratic( theForce3d );
5223 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5225 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5229 getEditor().ConvertToQuadratic(theForce3d, elems);
5232 myMesh->GetMeshDS()->Modified();
5233 myMesh->SetIsModified( true );
5235 pyDump << this << ".ConvertToQuadraticObject( "<<theForce3d<<", "<<theObject<<" )";
5238 //================================================================================
5240 * \brief Makes a part of the mesh linear
5242 //================================================================================
5244 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
5245 throw (SALOME::SALOME_Exception)
5247 Unexpect aCatch(SALOME_SalomeException);
5249 TIDSortedElemSet elems;
5250 if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5252 if ( elems.empty() )
5254 ConvertFromQuadratic();
5256 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5258 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5262 getEditor().ConvertFromQuadratic(elems);
5265 myMesh->GetMeshDS()->Modified();
5266 myMesh->SetIsModified( true );
5268 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
5271 //=======================================================================
5272 //function : makeMesh
5273 //purpose : create a named imported mesh
5274 //=======================================================================
5276 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
5278 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
5279 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
5280 SALOMEDS::Study_var study = gen->GetCurrentStudy();
5281 SALOMEDS::SObject_var meshSO = gen->ObjectToSObject( study, mesh );
5282 gen->SetName( meshSO, theMeshName, "Mesh" );
5283 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
5285 return mesh._retn();
5288 //=======================================================================
5289 //function : DumpGroupsList
5291 //=======================================================================
5292 void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump & theDumpPython,
5293 const SMESH::ListOfGroups * theGroupList)
5295 bool isDumpGroupList = theGroupList && theGroupList->length() > 0;
5296 if(isDumpGroupList) {
5297 theDumpPython << theGroupList << " = ";
5301 //================================================================================
5303 \brief Generates the unique group name.
5304 \param thePrefix name prefix
5307 //================================================================================
5308 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
5310 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5311 set<string> groupNames;
5313 // Get existing group names
5314 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
5315 SMESH::SMESH_GroupBase_var aGroup = groups[i];
5316 if (CORBA::is_nil(aGroup))
5319 CORBA::String_var name = aGroup->GetName();
5320 groupNames.insert( name.in() );
5324 string name = thePrefix;
5327 while (!groupNames.insert(name).second)
5328 name = SMESH_Comment( thePrefix ) << "_" << index;
5333 //================================================================================
5335 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5336 \param theNodes - identifiers of nodes to be doubled
5337 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
5338 nodes. If list of element identifiers is empty then nodes are doubled but
5339 they not assigned to elements
5340 \return TRUE if operation has been completed successfully, FALSE otherwise
5341 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
5343 //================================================================================
5345 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
5346 const SMESH::long_array& theModifiedElems )
5350 list< int > aListOfNodes;
5352 for ( i = 0, n = theNodes.length(); i < n; i++ )
5353 aListOfNodes.push_back( theNodes[ i ] );
5355 list< int > aListOfElems;
5356 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5357 aListOfElems.push_back( theModifiedElems[ i ] );
5359 bool aResult = getEditor().DoubleNodes( aListOfNodes, aListOfElems );
5361 myMesh->GetMeshDS()->Modified();
5363 myMesh->SetIsModified( true );
5365 // Update Python script
5366 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
5371 //================================================================================
5373 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5374 This method provided for convenience works as DoubleNodes() described above.
5375 \param theNodeId - identifier of node to be doubled.
5376 \param theModifiedElems - identifiers of elements to be updated.
5377 \return TRUE if operation has been completed successfully, FALSE otherwise
5378 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
5380 //================================================================================
5382 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
5383 const SMESH::long_array& theModifiedElems )
5385 SMESH::long_array_var aNodes = new SMESH::long_array;
5386 aNodes->length( 1 );
5387 aNodes[ 0 ] = theNodeId;
5389 TPythonDump pyDump; // suppress dump by the next line
5391 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
5393 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
5398 //================================================================================
5400 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5401 This method provided for convenience works as DoubleNodes() described above.
5402 \param theNodes - group of nodes to be doubled.
5403 \param theModifiedElems - group of elements to be updated.
5404 \return TRUE if operation has been completed successfully, FALSE otherwise
5405 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
5407 //================================================================================
5409 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
5410 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5412 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5415 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5416 SMESH::long_array_var aModifiedElems;
5417 if ( !CORBA::is_nil( theModifiedElems ) )
5418 aModifiedElems = theModifiedElems->GetListOfID();
5421 aModifiedElems = new SMESH::long_array;
5422 aModifiedElems->length( 0 );
5425 TPythonDump pyDump; // suppress dump by the next line
5427 bool done = DoubleNodes( aNodes, aModifiedElems );
5429 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
5435 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5436 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
5437 * \param theNodes - group of nodes to be doubled.
5438 * \param theModifiedElems - group of elements to be updated.
5439 * \return a new group with newly created nodes
5440 * \sa DoubleNodeGroup()
5442 SMESH::SMESH_Group_ptr
5443 SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
5444 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5446 SMESH::SMESH_Group_var aNewGroup;
5448 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5449 return aNewGroup._retn();
5452 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5453 SMESH::long_array_var aModifiedElems;
5454 if ( !CORBA::is_nil( theModifiedElems ) )
5455 aModifiedElems = theModifiedElems->GetListOfID();
5457 aModifiedElems = new SMESH::long_array;
5458 aModifiedElems->length( 0 );
5461 TPythonDump pyDump; // suppress dump by the next line
5463 bool aResult = DoubleNodes( aNodes, aModifiedElems );
5466 // Create group with newly created nodes
5467 SMESH::long_array_var anIds = GetLastCreatedNodes();
5468 if (anIds->length() > 0) {
5469 string anUnindexedName (theNodes->GetName());
5470 string aNewName = generateGroupName(anUnindexedName + "_double");
5471 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5472 aNewGroup->Add(anIds);
5473 pyDump << aNewGroup << " = ";
5477 pyDump << this << ".DoubleNodeGroupNew( " << theNodes << ", "
5478 << theModifiedElems << " )";
5480 return aNewGroup._retn();
5483 //================================================================================
5485 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5486 This method provided for convenience works as DoubleNodes() described above.
5487 \param theNodes - list of groups of nodes to be doubled
5488 \param theModifiedElems - list of groups of elements to be updated.
5489 \return TRUE if operation has been completed successfully, FALSE otherwise
5490 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
5492 //================================================================================
5494 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
5495 const SMESH::ListOfGroups& theModifiedElems )
5500 std::list< int > aNodes;
5502 for ( i = 0, n = theNodes.length(); i < n; i++ )
5504 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
5505 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
5507 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5508 for ( j = 0, m = aCurr->length(); j < m; j++ )
5509 aNodes.push_back( aCurr[ j ] );
5513 std::list< int > anElems;
5514 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5516 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
5517 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
5519 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5520 for ( j = 0, m = aCurr->length(); j < m; j++ )
5521 anElems.push_back( aCurr[ j ] );
5525 bool aResult = getEditor().DoubleNodes( aNodes, anElems );
5528 myMesh->GetMeshDS()->Modified();
5530 myMesh->SetIsModified( true );
5533 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
5538 //================================================================================
5540 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5541 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
5542 * \param theNodes - group of nodes to be doubled.
5543 * \param theModifiedElems - group of elements to be updated.
5544 * \return a new group with newly created nodes
5545 * \sa DoubleNodeGroups()
5547 //================================================================================
5549 SMESH::SMESH_Group_ptr
5550 SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
5551 const SMESH::ListOfGroups& theModifiedElems )
5553 SMESH::SMESH_Group_var aNewGroup;
5555 TPythonDump pyDump; // suppress dump by the next line
5557 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
5561 // Create group with newly created nodes
5562 SMESH::long_array_var anIds = GetLastCreatedNodes();
5563 if (anIds->length() > 0) {
5564 string anUnindexedName (theNodes[0]->GetName());
5565 string aNewName = generateGroupName(anUnindexedName + "_double");
5566 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5567 aNewGroup->Add(anIds);
5568 pyDump << aNewGroup << " = ";
5572 pyDump << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
5573 << theModifiedElems << " )";
5575 return aNewGroup._retn();
5579 //================================================================================
5581 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5582 \param theElems - the list of elements (edges or faces) to be replicated
5583 The nodes for duplication could be found from these elements
5584 \param theNodesNot - list of nodes to NOT replicate
5585 \param theAffectedElems - the list of elements (cells and edges) to which the
5586 replicated nodes should be associated to.
5587 \return TRUE if operation has been completed successfully, FALSE otherwise
5588 \sa DoubleNodeGroup(), DoubleNodeGroups()
5590 //================================================================================
5592 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
5593 const SMESH::long_array& theNodesNot,
5594 const SMESH::long_array& theAffectedElems )
5600 SMESHDS_Mesh* aMeshDS = getMeshDS();
5601 TIDSortedElemSet anElems, aNodes, anAffected;
5602 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5603 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5604 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
5606 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5609 myMesh->GetMeshDS()->Modified();
5611 myMesh->SetIsModified( true );
5613 // Update Python script
5614 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
5615 << theNodesNot << ", " << theAffectedElems << " )";
5619 //================================================================================
5621 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5622 \param theElems - the list of elements (edges or faces) to be replicated
5623 The nodes for duplication could be found from these elements
5624 \param theNodesNot - list of nodes to NOT replicate
5625 \param theShape - shape to detect affected elements (element which geometric center
5626 located on or inside shape).
5627 The replicated nodes should be associated to affected elements.
5628 \return TRUE if operation has been completed successfully, FALSE otherwise
5629 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
5631 //================================================================================
5633 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
5634 const SMESH::long_array& theNodesNot,
5635 GEOM::GEOM_Object_ptr theShape )
5641 SMESHDS_Mesh* aMeshDS = getMeshDS();
5642 TIDSortedElemSet anElems, aNodes;
5643 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5644 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5646 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5647 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
5650 myMesh->GetMeshDS()->Modified();
5652 myMesh->SetIsModified( true );
5654 // Update Python script
5655 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
5656 << theNodesNot << ", " << theShape << " )";
5660 //================================================================================
5662 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5663 \param theElems - group of of elements (edges or faces) to be replicated
5664 \param theNodesNot - group of nodes not to replicated
5665 \param theAffectedElems - group of elements to which the replicated nodes
5666 should be associated to.
5667 \return TRUE if operation has been completed successfully, FALSE otherwise
5668 \sa DoubleNodes(), DoubleNodeGroups()
5670 //================================================================================
5672 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
5673 SMESH::SMESH_GroupBase_ptr theNodesNot,
5674 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5676 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5682 SMESHDS_Mesh* aMeshDS = getMeshDS();
5683 TIDSortedElemSet anElems, aNodes, anAffected;
5684 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5685 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5686 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5688 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5691 myMesh->GetMeshDS()->Modified();
5693 myMesh->SetIsModified( true );
5695 // Update Python script
5696 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
5697 << theNodesNot << ", " << theAffectedElems << " )";
5702 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5703 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
5704 * \param theElems - group of of elements (edges or faces) to be replicated
5705 * \param theNodesNot - group of nodes not to replicated
5706 * \param theAffectedElems - group of elements to which the replicated nodes
5707 * should be associated to.
5708 * \return a new group with newly created elements
5709 * \sa DoubleNodeElemGroup()
5711 SMESH::SMESH_Group_ptr
5712 SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
5713 SMESH::SMESH_GroupBase_ptr theNodesNot,
5714 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5717 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroup2New( theElems,
5721 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
5722 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
5724 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupNew( "
5726 << theNodesNot << ", "
5727 << theAffectedElems << " )";
5729 return elemGroup._retn();
5732 SMESH::ListOfGroups*
5733 SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
5734 SMESH::SMESH_GroupBase_ptr theNodesNot,
5735 SMESH::SMESH_GroupBase_ptr theAffectedElems,
5736 CORBA::Boolean theElemGroupNeeded,
5737 CORBA::Boolean theNodeGroupNeeded)
5739 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
5740 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
5741 aTwoGroups->length( 2 );
5743 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5744 return aTwoGroups._retn();
5749 SMESHDS_Mesh* aMeshDS = getMeshDS();
5750 TIDSortedElemSet anElems, aNodes, anAffected;
5751 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5752 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5753 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5756 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5758 myMesh->GetMeshDS()->Modified();
5764 myMesh->SetIsModified( true );
5766 // Create group with newly created elements
5767 CORBA::String_var elemGroupName = theElems->GetName();
5768 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
5769 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
5771 SMESH::long_array_var anIds = GetLastCreatedElems();
5772 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5773 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5774 aNewElemGroup->Add(anIds);
5776 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
5778 SMESH::long_array_var anIds = GetLastCreatedNodes();
5779 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5780 aNewNodeGroup->Add(anIds);
5784 // Update Python script
5787 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
5788 else pyDump << aNewElemGroup << ", ";
5789 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
5790 else pyDump << aNewNodeGroup << " ] = ";
5792 pyDump << this << ".DoubleNodeElemGroup2New( " << theElems << ", "
5793 << theNodesNot << ", "
5794 << theAffectedElems << ", "
5795 << theElemGroupNeeded << ", "
5796 << theNodeGroupNeeded <<" )";
5798 aTwoGroups[0] = aNewElemGroup._retn();
5799 aTwoGroups[1] = aNewNodeGroup._retn();
5800 return aTwoGroups._retn();
5803 //================================================================================
5805 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5806 \param theElems - group of of elements (edges or faces) to be replicated
5807 \param theNodesNot - group of nodes not to replicated
5808 \param theShape - shape to detect affected elements (element which geometric center
5809 located on or inside shape).
5810 The replicated nodes should be associated to affected elements.
5811 \return TRUE if operation has been completed successfully, FALSE otherwise
5812 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
5814 //================================================================================
5816 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
5817 SMESH::SMESH_GroupBase_ptr theNodesNot,
5818 GEOM::GEOM_Object_ptr theShape )
5821 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5827 SMESHDS_Mesh* aMeshDS = getMeshDS();
5828 TIDSortedElemSet anElems, aNodes, anAffected;
5829 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5830 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5832 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5833 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
5836 myMesh->GetMeshDS()->Modified();
5838 myMesh->SetIsModified( true );
5840 // Update Python script
5841 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
5842 << theNodesNot << ", " << theShape << " )";
5846 //================================================================================
5848 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5849 This method provided for convenience works as DoubleNodes() described above.
5850 \param theElems - list of groups of elements (edges or faces) to be replicated
5851 \param theNodesNot - list of groups of nodes not to replicated
5852 \param theAffectedElems - group of elements to which the replicated nodes
5853 should be associated to.
5854 \return TRUE if operation has been completed successfully, FALSE otherwise
5855 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
5857 //================================================================================
5859 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
5860 SMESHDS_Mesh* theMeshDS,
5861 TIDSortedElemSet& theElemSet,
5862 const bool theIsNodeGrp)
5864 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
5866 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
5867 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
5868 : aGrp->GetType() != SMESH::NODE ) )
5870 SMESH::long_array_var anIDs = aGrp->GetIDs();
5871 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
5876 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
5877 const SMESH::ListOfGroups& theNodesNot,
5878 const SMESH::ListOfGroups& theAffectedElems)
5883 SMESHDS_Mesh* aMeshDS = getMeshDS();
5884 TIDSortedElemSet anElems, aNodes, anAffected;
5885 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5886 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5887 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5889 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5892 myMesh->GetMeshDS()->Modified();
5894 myMesh->SetIsModified( true );
5896 // Update Python script
5897 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
5898 << &theNodesNot << ", " << &theAffectedElems << " )";
5902 //================================================================================
5904 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5905 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
5906 \param theElems - list of groups of elements (edges or faces) to be replicated
5907 \param theNodesNot - list of groups of nodes not to replicated
5908 \param theAffectedElems - group of elements to which the replicated nodes
5909 should be associated to.
5910 * \return a new group with newly created elements
5911 * \sa DoubleNodeElemGroups()
5913 //================================================================================
5915 SMESH::SMESH_Group_ptr
5916 SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
5917 const SMESH::ListOfGroups& theNodesNot,
5918 const SMESH::ListOfGroups& theAffectedElems)
5921 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroups2New( theElems,
5925 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
5926 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
5928 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupsNew( "
5930 << theNodesNot << ", "
5931 << theAffectedElems << " )";
5933 return elemGroup._retn();
5936 SMESH::ListOfGroups*
5937 SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems,
5938 const SMESH::ListOfGroups& theNodesNot,
5939 const SMESH::ListOfGroups& theAffectedElems,
5940 CORBA::Boolean theElemGroupNeeded,
5941 CORBA::Boolean theNodeGroupNeeded)
5943 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
5944 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
5945 aTwoGroups->length( 2 );
5950 SMESHDS_Mesh* aMeshDS = getMeshDS();
5951 TIDSortedElemSet anElems, aNodes, anAffected;
5952 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5953 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5954 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5956 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5959 myMesh->GetMeshDS()->Modified();
5963 myMesh->SetIsModified( true );
5965 // Create group with newly created elements
5966 CORBA::String_var elemGroupName = theElems[0]->GetName();
5967 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
5968 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
5970 SMESH::long_array_var anIds = GetLastCreatedElems();
5971 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5972 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5973 aNewElemGroup->Add(anIds);
5975 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
5977 SMESH::long_array_var anIds = GetLastCreatedNodes();
5978 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5979 aNewNodeGroup->Add(anIds);
5983 // Update Python script
5986 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
5987 else pyDump << aNewElemGroup << ", ";
5988 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
5989 else pyDump << aNewNodeGroup << " ] = ";
5991 pyDump << this << ".DoubleNodeElemGroups2New( " << &theElems << ", "
5992 << &theNodesNot << ", "
5993 << &theAffectedElems << ", "
5994 << theElemGroupNeeded << ", "
5995 << theNodeGroupNeeded << " )";
5997 aTwoGroups[0] = aNewElemGroup._retn();
5998 aTwoGroups[1] = aNewNodeGroup._retn();
5999 return aTwoGroups._retn();
6002 //================================================================================
6004 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6005 This method provided for convenience works as DoubleNodes() described above.
6006 \param theElems - list of groups of elements (edges or faces) to be replicated
6007 \param theNodesNot - list of groups of nodes not to replicated
6008 \param theShape - shape to detect affected elements (element which geometric center
6009 located on or inside shape).
6010 The replicated nodes should be associated to affected elements.
6011 \return TRUE if operation has been completed successfully, FALSE otherwise
6012 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
6014 //================================================================================
6017 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
6018 const SMESH::ListOfGroups& theNodesNot,
6019 GEOM::GEOM_Object_ptr theShape )
6024 SMESHDS_Mesh* aMeshDS = getMeshDS();
6025 TIDSortedElemSet anElems, aNodes;
6026 listOfGroupToSet(theElems, aMeshDS, anElems,false );
6027 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6029 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6030 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6033 myMesh->GetMeshDS()->Modified();
6035 myMesh->SetIsModified( true );
6037 // Update Python script
6038 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
6039 << &theNodesNot << ", " << theShape << " )";
6043 //================================================================================
6045 \brief Identify the elements that will be affected by node duplication (actual duplication is not performed.
6046 This method is the first step of DoubleNodeElemGroupsInRegion.
6047 \param theElems - list of groups of elements (edges or faces) to be replicated
6048 \param theNodesNot - list of groups of nodes not to replicated
6049 \param theShape - shape to detect affected elements (element which geometric center
6050 located on or inside shape).
6051 The replicated nodes should be associated to affected elements.
6052 \return groups of affected elements
6053 \sa DoubleNodeElemGroupsInRegion()
6055 //================================================================================
6056 SMESH::ListOfGroups*
6057 SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theElems,
6058 const SMESH::ListOfGroups& theNodesNot,
6059 GEOM::GEOM_Object_ptr theShape )
6061 MESSAGE("AffectedElemGroupsInRegion");
6062 SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
6063 bool isEdgeGroup = false;
6064 bool isFaceGroup = false;
6065 bool isVolumeGroup = false;
6066 SMESH::SMESH_Group_var aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE, "affectedEdges");
6067 SMESH::SMESH_Group_var aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE, "affectedFaces");
6068 SMESH::SMESH_Group_var aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME, "affectedVolumes");
6072 ::SMESH_MeshEditor aMeshEditor(myMesh);
6074 SMESHDS_Mesh* aMeshDS = getMeshDS();
6075 TIDSortedElemSet anElems, aNodes;
6076 listOfGroupToSet(theElems, aMeshDS, anElems, false);
6077 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true);
6079 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape(theShape);
6080 TIDSortedElemSet anAffected;
6081 bool aResult = aMeshEditor.AffectedElemGroupsInRegion(anElems, aNodes, aShape, anAffected);
6084 myMesh->GetMeshDS()->Modified();
6088 myMesh->SetIsModified(true);
6090 int lg = anAffected.size();
6091 MESSAGE("lg="<< lg);
6092 SMESH::long_array_var volumeIds = new SMESH::long_array;
6093 volumeIds->length(lg);
6094 SMESH::long_array_var faceIds = new SMESH::long_array;
6095 faceIds->length(lg);
6096 SMESH::long_array_var edgeIds = new SMESH::long_array;
6097 edgeIds->length(lg);
6102 TIDSortedElemSet::const_iterator eIt = anAffected.begin();
6103 for (; eIt != anAffected.end(); ++eIt)
6105 const SMDS_MeshElement* anElem = *eIt;
6108 int elemId = anElem->GetID();
6109 if (myMesh->GetElementType(elemId, true) == SMDSAbs_Volume)
6110 volumeIds[ivol++] = elemId;
6111 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Face)
6112 faceIds[iface++] = elemId;
6113 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Edge)
6114 edgeIds[iedge++] = elemId;
6116 volumeIds->length(ivol);
6117 faceIds->length(iface);
6118 edgeIds->length(iedge);
6120 aNewVolumeGroup->Add(volumeIds);
6121 aNewFaceGroup->Add(faceIds);
6122 aNewEdgeGroup->Add(edgeIds);
6123 isVolumeGroup = (aNewVolumeGroup->Size() > 0);
6124 isFaceGroup = (aNewFaceGroup->Size() > 0);
6125 isEdgeGroup = (aNewEdgeGroup->Size() > 0);
6135 aListOfGroups->length(nbGroups);
6139 aListOfGroups[i++] = aNewEdgeGroup._retn();
6141 aListOfGroups[i++] = aNewFaceGroup._retn();
6143 aListOfGroups[i++] = aNewVolumeGroup._retn();
6145 // Update Python script
6149 pyDump << aNewEdgeGroup << ", ";
6151 pyDump << aNewFaceGroup << ", ";
6153 pyDump << aNewVolumeGroup << ", ";
6155 pyDump << this << ".AffectedElemGroupsInRegion( " << &theElems << ", " << &theNodesNot << ", " << theShape << " )";
6157 return aListOfGroups._retn();
6160 //================================================================================
6162 \brief Generated skin mesh (containing 2D cells) from 3D mesh
6163 The created 2D mesh elements based on nodes of free faces of boundary volumes
6164 \return TRUE if operation has been completed successfully, FALSE otherwise
6166 //================================================================================
6168 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
6172 bool aResult = getEditor().Make2DMeshFrom3D();
6173 myMesh->GetMeshDS()->Modified();
6174 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
6178 //================================================================================
6180 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
6181 * The list of groups must describe a partition of the mesh volumes.
6182 * The nodes of the internal faces at the boundaries of the groups are doubled.
6183 * In option, the internal faces are replaced by flat elements.
6184 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
6185 * The flat elements are stored in groups of volumes.
6186 * @param theDomains - list of groups of volumes
6187 * @param createJointElems - if TRUE, create the elements
6188 * @return TRUE if operation has been completed successfully, FALSE otherwise
6190 //================================================================================
6192 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
6193 CORBA::Boolean createJointElems )
6194 throw (SALOME::SALOME_Exception)
6199 SMESHDS_Mesh* aMeshDS = getMeshDS();
6201 vector<TIDSortedElemSet> domains;
6204 for ( int i = 0, n = theDomains.length(); i < n; i++ )
6206 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
6207 if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
6209 // if ( aGrp->GetType() != SMESH::VOLUME )
6210 // THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
6211 TIDSortedElemSet domain;
6213 domains.push_back(domain);
6214 SMESH::long_array_var anIDs = aGrp->GetIDs();
6215 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
6219 bool aResult = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems );
6220 // TODO publish the groups of flat elements in study
6222 myMesh->GetMeshDS()->Modified();
6224 // Update Python script
6225 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
6226 << ", " << createJointElems << " )";
6230 //================================================================================
6232 * \brief Double nodes on some external faces and create flat elements.
6233 * Flat elements are mainly used by some types of mechanic calculations.
6235 * Each group of the list must be constituted of faces.
6236 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
6237 * @param theGroupsOfFaces - list of groups of faces
6238 * @return TRUE if operation has been completed successfully, FALSE otherwise
6240 //================================================================================
6242 CORBA::Boolean SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
6247 SMESHDS_Mesh* aMeshDS = getMeshDS();
6249 vector<TIDSortedElemSet> faceGroups;
6252 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
6254 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
6255 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
6257 TIDSortedElemSet faceGroup;
6259 faceGroups.push_back(faceGroup);
6260 SMESH::long_array_var anIDs = aGrp->GetIDs();
6261 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
6265 bool aResult = getEditor().CreateFlatElementsOnFacesGroups( faceGroups );
6266 // TODO publish the groups of flat elements in study
6268 myMesh->GetMeshDS()->Modified();
6270 // Update Python script
6271 TPythonDump() << "isDone = " << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
6276 * \brief identify all the elements around a geom shape, get the faces delimiting the hole
6277 * Build groups of volume to remove, groups of faces to replace on the skin of the object,
6278 * groups of faces to remove inside the object, (idem edges).
6279 * Build ordered list of nodes at the border of each group of faces to replace (to be used to build a geom subshape)
6281 void SMESH_MeshEditor_i::CreateHoleSkin(CORBA::Double radius,
6282 GEOM::GEOM_Object_ptr theShape,
6283 const char* groupName,
6284 const SMESH::double_array& theNodesCoords,
6285 SMESH::array_of_long_array_out GroupsOfNodes)
6286 throw (SALOME::SALOME_Exception)
6289 std::vector<std::vector<int> > aListOfListOfNodes;
6290 ::SMESH_MeshEditor aMeshEditor( myMesh );
6292 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
6293 if ( !theNodeSearcher )
6294 theNodeSearcher = aMeshEditor.GetNodeSearcher();
6296 vector<double> nodesCoords;
6297 for (int i = 0; i < theNodesCoords.length(); i++)
6299 nodesCoords.push_back( theNodesCoords[i] );
6302 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6303 aMeshEditor.CreateHoleSkin(radius, aShape, theNodeSearcher, groupName, nodesCoords, aListOfListOfNodes);
6305 GroupsOfNodes = new SMESH::array_of_long_array;
6306 GroupsOfNodes->length( aListOfListOfNodes.size() );
6307 std::vector<std::vector<int> >::iterator llIt = aListOfListOfNodes.begin();
6308 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
6310 vector<int>& aListOfNodes = *llIt;
6311 vector<int>::iterator lIt = aListOfNodes.begin();;
6312 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
6313 aGroup.length( aListOfNodes.size() );
6314 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
6315 aGroup[ j ] = (*lIt);
6317 TPythonDump() << "lists_nodes = " << this << ".CreateHoleSkin( "
6318 << radius << ", " << theShape << ", " << ", " << groupName << ", " << theNodesCoords << " )";
6322 // issue 20749 ===================================================================
6324 * \brief Creates missing boundary elements
6325 * \param elements - elements whose boundary is to be checked
6326 * \param dimension - defines type of boundary elements to create
6327 * \param groupName - a name of group to store created boundary elements in,
6328 * "" means not to create the group
6329 * \param meshName - a name of new mesh to store created boundary elements in,
6330 * "" means not to create the new mesh
6331 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
6332 * \param toCopyExistingBondary - if true, not only new but also pre-existing
6333 * boundary elements will be copied into the new mesh
6334 * \param group - returns the create group, if any
6335 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
6337 // ================================================================================
6339 SMESH::SMESH_Mesh_ptr
6340 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
6341 SMESH::Bnd_Dimension dim,
6342 const char* groupName,
6343 const char* meshName,
6344 CORBA::Boolean toCopyElements,
6345 CORBA::Boolean toCopyExistingBondary,
6346 SMESH::SMESH_Group_out group)
6350 if ( dim > SMESH::BND_1DFROM2D )
6351 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
6353 SMESHDS_Mesh* aMeshDS = getMeshDS();
6355 SMESH::SMESH_Mesh_var mesh_var;
6356 SMESH::SMESH_Group_var group_var;
6360 TIDSortedElemSet elements;
6361 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
6362 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
6366 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
6367 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
6369 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
6371 // group of new boundary elements
6372 SMESH_Group* smesh_group = 0;
6373 if ( strlen(groupName) )
6375 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
6376 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
6377 smesh_group = group_i->GetSmeshGroup();
6381 getEditor().MakeBoundaryMesh( elements,
6382 ::SMESH_MeshEditor::Bnd_Dimension(dim),
6386 toCopyExistingBondary);
6389 smesh_mesh->GetMeshDS()->Modified();
6392 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
6394 // result of MakeBoundaryMesh() is a tuple (mesh, group)
6395 if ( mesh_var->_is_nil() )
6396 pyDump << myMesh_i->_this() << ", ";
6398 pyDump << mesh_var << ", ";
6399 if ( group_var->_is_nil() )
6400 pyDump << "_NoneGroup = "; // assignment to None is forbiden
6402 pyDump << group_var << " = ";
6403 pyDump << this << ".MakeBoundaryMesh( "
6405 << "SMESH." << dimName[int(dim)] << ", "
6406 << "'" << groupName << "', "
6407 << "'" << meshName<< "', "
6408 << toCopyElements << ", "
6409 << toCopyExistingBondary << ")";
6411 group = group_var._retn();
6412 return mesh_var._retn();
6415 //================================================================================
6417 * \brief Creates missing boundary elements
6418 * \param dimension - defines type of boundary elements to create
6419 * \param groupName - a name of group to store all boundary elements in,
6420 * "" means not to create the group
6421 * \param meshName - a name of a new mesh, which is a copy of the initial
6422 * mesh + created boundary elements; "" means not to create the new mesh
6423 * \param toCopyAll - if true, the whole initial mesh will be copied into
6424 * the new mesh else only boundary elements will be copied into the new mesh
6425 * \param groups - optional groups of elements to make boundary around
6426 * \param mesh - returns the mesh where elements were added to
6427 * \param group - returns the created group, if any
6428 * \retval long - number of added boundary elements
6430 //================================================================================
6432 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
6433 const char* groupName,
6434 const char* meshName,
6435 CORBA::Boolean toCopyAll,
6436 const SMESH::ListOfIDSources& groups,
6437 SMESH::SMESH_Mesh_out mesh,
6438 SMESH::SMESH_Group_out group)
6439 throw (SALOME::SALOME_Exception)
6441 Unexpect aCatch(SALOME_SalomeException);
6445 if ( dim > SMESH::BND_1DFROM2D )
6446 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
6448 // separate groups belonging to this and other mesh
6449 SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
6450 SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
6451 groupsOfThisMesh->length( groups.length() );
6452 groupsOfOtherMesh->length( groups.length() );
6453 int nbGroups = 0, nbGroupsOfOtherMesh = 0;
6454 for ( int i = 0; i < groups.length(); ++i )
6456 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
6457 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
6458 groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
6460 groupsOfThisMesh[ nbGroups++ ] = groups[i];
6461 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
6462 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
6464 groupsOfThisMesh->length( nbGroups );
6465 groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
6470 if ( nbGroupsOfOtherMesh > 0 )
6472 // process groups belonging to another mesh
6473 SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
6474 SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
6475 nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
6476 groupsOfOtherMesh, mesh, group );
6479 SMESH::SMESH_Mesh_var mesh_var;
6480 SMESH::SMESH_Group_var group_var;
6483 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
6484 const bool toCopyMesh = ( strlen( meshName ) > 0 );
6488 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
6490 /*toCopyGroups=*/false,
6491 /*toKeepIDs=*/true);
6493 mesh_var = makeMesh(meshName);
6495 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
6496 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
6499 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
6500 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
6502 // group of boundary elements
6503 SMESH_Group* smesh_group = 0;
6504 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
6505 if ( strlen(groupName) )
6507 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
6508 group_var = mesh_i->CreateGroup( groupType, groupName );
6509 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
6510 smesh_group = group_i->GetSmeshGroup();
6513 TIDSortedElemSet elements;
6515 if ( groups.length() > 0 )
6517 for ( int i = 0; i < nbGroups; ++i )
6520 if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
6522 SMESH::Bnd_Dimension bdim =
6523 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
6524 nbAdded += getEditor().MakeBoundaryMesh( elements,
6525 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
6528 /*toCopyElements=*/false,
6529 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
6530 /*toAddExistingBondary=*/true,
6531 /*aroundElements=*/true);
6537 nbAdded += getEditor().MakeBoundaryMesh( elements,
6538 ::SMESH_MeshEditor::Bnd_Dimension(dim),
6541 /*toCopyElements=*/false,
6542 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
6543 /*toAddExistingBondary=*/true);
6545 tgtMesh->GetMeshDS()->Modified();
6547 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
6549 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
6550 pyDump << "nbAdded, ";
6551 if ( mesh_var->_is_nil() )
6552 pyDump << myMesh_i->_this() << ", ";
6554 pyDump << mesh_var << ", ";
6555 if ( group_var->_is_nil() )
6556 pyDump << "_NoneGroup = "; // assignment to None is forbiden
6558 pyDump << group_var << " = ";
6559 pyDump << this << ".MakeBoundaryElements( "
6560 << "SMESH." << dimName[int(dim)] << ", "
6561 << "'" << groupName << "', "
6562 << "'" << meshName<< "', "
6563 << toCopyAll << ", "
6566 mesh = mesh_var._retn();
6567 group = group_var._retn();