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_var 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 errOut->subShapeID = -1;
665 errOut->hasBadMesh = false;
667 return errOut._retn();
670 //=======================================================================
671 //function : MakeIDSource
672 //purpose : Wrap a sequence of ids in a SMESH_IDSource
673 //=======================================================================
675 struct SMESH_MeshEditor_i::_IDSource : public POA_SMESH::SMESH_IDSource
677 SMESH::long_array _ids;
678 SMESH::ElementType _type;
679 SMESH::SMESH_Mesh_ptr _mesh;
680 SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); }
681 SMESH::long_array* GetMeshInfo() { return 0; }
682 SMESH::SMESH_Mesh_ptr GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _mesh ); }
683 bool IsMeshInfoCorrect() { return true; }
684 SMESH::array_of_ElementType* GetTypes()
686 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
687 if ( _ids.length() > 0 ) {
691 return types._retn();
695 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
696 SMESH::ElementType type)
698 if ( myAuxIDSources.size() > 10 )
699 deleteAuxIDSources();
701 _IDSource* idSrc = new _IDSource;
702 idSrc->_mesh = myMesh_i->_this();
705 myAuxIDSources.push_back( idSrc );
707 SMESH::SMESH_IDSource_var anIDSourceVar = idSrc->_this();
709 return anIDSourceVar._retn();
712 void SMESH_MeshEditor_i::deleteAuxIDSources()
714 std::list< _IDSource* >::iterator idSrcIt = myAuxIDSources.begin();
715 for ( ; idSrcIt != myAuxIDSources.end(); ++idSrcIt )
717 myAuxIDSources.clear();
720 //=============================================================================
724 //=============================================================================
727 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
733 for (int i = 0; i < IDsOfElements.length(); i++)
734 IdList.push_back( IDsOfElements[i] );
736 // Update Python script
737 TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
740 bool ret = getEditor().Remove( IdList, false );
741 myMesh->GetMeshDS()->Modified();
742 if ( IDsOfElements.length() )
743 myMesh->SetIsModified( true ); // issue 0020693
747 //=============================================================================
751 //=============================================================================
753 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
758 for (int i = 0; i < IDsOfNodes.length(); i++)
759 IdList.push_back( IDsOfNodes[i] );
761 // Update Python script
762 TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
764 bool ret = getEditor().Remove( IdList, true );
765 myMesh->GetMeshDS()->Modified();
766 if ( IDsOfNodes.length() )
767 myMesh->SetIsModified( true ); // issue 0020693
771 //=============================================================================
775 //=============================================================================
777 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
782 // Update Python script
783 TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
785 // Create filter to find all orphan nodes
786 SMESH::Controls::Filter::TIdSequence seq;
787 SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
788 SMESH::Controls::Filter::GetElementsId( getMeshDS(), predicate, seq );
790 // remove orphan nodes (if there are any)
792 for ( int i = 0; i < seq.size(); i++ )
793 IdList.push_back( seq[i] );
795 int nbNodesBefore = myMesh->NbNodes();
796 getEditor().Remove( IdList, true );
797 myMesh->GetMeshDS()->Modified();
799 myMesh->SetIsModified( true );
800 int nbNodesAfter = myMesh->NbNodes();
802 return nbNodesBefore - nbNodesAfter;
805 //=============================================================================
809 //=============================================================================
811 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,
812 CORBA::Double y, CORBA::Double z)
816 const SMDS_MeshNode* N = getMeshDS()->AddNode(x, y, z);
818 // Update Python script
819 TPythonDump() << "nodeID = " << this << ".AddNode( "
820 << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )";
822 myMesh->GetMeshDS()->Modified();
823 myMesh->SetIsModified( true ); // issue 0020693
827 //=============================================================================
829 * Create 0D element on the given node.
831 //=============================================================================
833 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
837 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
838 SMDS_MeshElement* elem = getMeshDS()->Add0DElement(aNode);
840 // Update Python script
841 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
843 myMesh->GetMeshDS()->Modified();
844 myMesh->SetIsModified( true ); // issue 0020693
847 return elem->GetID();
852 //=============================================================================
854 * Create a ball element on the given node.
856 //=============================================================================
858 CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diameter)
859 throw (SALOME::SALOME_Exception)
863 if ( diameter < std::numeric_limits<double>::min() )
864 THROW_SALOME_CORBA_EXCEPTION("Invalid diameter", SALOME::BAD_PARAM);
866 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
867 SMDS_MeshElement* elem = getMeshDS()->AddBall(aNode, diameter);
869 // Update Python script
870 TPythonDump() << "ballElem = "
871 << this << ".AddBall( " << IDOfNode << ", " << diameter <<" )";
873 myMesh->GetMeshDS()->Modified();
874 myMesh->SetIsModified( true ); // issue 0020693
877 return elem->GetID();
882 //=============================================================================
884 * Create an edge, either linear and quadratic (this is determed
885 * by number of given nodes, two or three)
887 //=============================================================================
889 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
893 int NbNodes = IDsOfNodes.length();
894 SMDS_MeshElement* elem = 0;
897 CORBA::Long index1 = IDsOfNodes[0];
898 CORBA::Long index2 = IDsOfNodes[1];
899 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(index1),
900 getMeshDS()->FindNode(index2));
902 // Update Python script
903 TPythonDump() << "edge = " << this << ".AddEdge([ "
904 << index1 << ", " << index2 <<" ])";
907 CORBA::Long n1 = IDsOfNodes[0];
908 CORBA::Long n2 = IDsOfNodes[1];
909 CORBA::Long n12 = IDsOfNodes[2];
910 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(n1),
911 getMeshDS()->FindNode(n2),
912 getMeshDS()->FindNode(n12));
913 // Update Python script
914 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
915 <<n1<<", "<<n2<<", "<<n12<<" ])";
918 myMesh->GetMeshDS()->Modified();
920 return myMesh->SetIsModified( true ), elem->GetID();
925 //=============================================================================
929 //=============================================================================
931 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
935 int NbNodes = IDsOfNodes.length();
941 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
942 for (int i = 0; i < NbNodes; i++)
943 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
945 SMDS_MeshElement* elem = 0;
947 elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]);
949 else if (NbNodes == 4) {
950 elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]);
952 else if (NbNodes == 6) {
953 elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
956 else if (NbNodes == 8) {
957 elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
958 nodes[4], nodes[5], nodes[6], nodes[7]);
960 else if (NbNodes == 9) {
961 elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
962 nodes[4], nodes[5], nodes[6], nodes[7], nodes[8] );
964 else if (NbNodes > 2) {
965 elem = getMeshDS()->AddPolygonalFace(nodes);
968 // Update Python script
969 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
971 myMesh->GetMeshDS()->Modified();
973 return myMesh->SetIsModified( true ), elem->GetID();
978 //=============================================================================
982 //=============================================================================
983 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
987 int NbNodes = IDsOfNodes.length();
988 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
989 for (int i = 0; i < NbNodes; i++)
990 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
992 const SMDS_MeshElement* elem = getMeshDS()->AddPolygonalFace(nodes);
994 // Update Python script
995 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
997 myMesh->GetMeshDS()->Modified();
998 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
1001 //=============================================================================
1003 * Create volume, either linear and quadratic (this is determed
1004 * by number of given nodes)
1006 //=============================================================================
1008 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
1012 int NbNodes = IDsOfNodes.length();
1013 vector< const SMDS_MeshNode*> n(NbNodes);
1014 for(int i=0;i<NbNodes;i++)
1015 n[i]= getMeshDS()->FindNode(IDsOfNodes[i]);
1017 SMDS_MeshElement* elem = 0;
1020 case 4 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
1021 case 5 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
1022 case 6 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
1023 case 8 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
1024 case 10:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1025 n[6],n[7],n[8],n[9]);
1027 case 12:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1028 n[6],n[7],n[8],n[9],n[10],n[11]);
1030 case 13:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
1031 n[7],n[8],n[9],n[10],n[11],n[12]);
1033 case 15:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
1034 n[9],n[10],n[11],n[12],n[13],n[14]);
1036 case 20:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1037 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1038 n[15],n[16],n[17],n[18],n[19]);
1040 case 27:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1041 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1042 n[15],n[16],n[17],n[18],n[19],
1043 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
1047 // Update Python script
1048 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
1050 myMesh->GetMeshDS()->Modified();
1052 return myMesh->SetIsModified( true ), elem->GetID();
1057 //=============================================================================
1059 * AddPolyhedralVolume
1061 //=============================================================================
1062 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
1063 const SMESH::long_array & Quantities)
1067 int NbNodes = IDsOfNodes.length();
1068 std::vector<const SMDS_MeshNode*> n (NbNodes);
1069 for (int i = 0; i < NbNodes; i++)
1071 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDsOfNodes[i]);
1072 if (!aNode) return 0;
1076 int NbFaces = Quantities.length();
1077 std::vector<int> q (NbFaces);
1078 for (int j = 0; j < NbFaces; j++)
1079 q[j] = Quantities[j];
1081 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(n, q);
1083 // Update Python script
1084 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
1085 << IDsOfNodes << ", " << Quantities << " )";
1086 myMesh->GetMeshDS()->Modified();
1088 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
1091 //=============================================================================
1093 * AddPolyhedralVolumeByFaces
1095 //=============================================================================
1097 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
1101 int NbFaces = IdsOfFaces.length();
1102 std::vector<const SMDS_MeshNode*> poly_nodes;
1103 std::vector<int> quantities (NbFaces);
1105 for (int i = 0; i < NbFaces; i++) {
1106 const SMDS_MeshElement* aFace = getMeshDS()->FindElement(IdsOfFaces[i]);
1107 quantities[i] = aFace->NbNodes();
1109 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
1110 while (It->more()) {
1111 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
1115 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
1117 // Update Python script
1118 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
1119 << IdsOfFaces << " )";
1120 myMesh->GetMeshDS()->Modified();
1122 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
1125 //=============================================================================
1127 // \brief Create 0D elements on all nodes of the given object except those
1128 // nodes on which a 0D element already exists.
1129 // \param theObject object on whose nodes 0D elements will be created.
1130 // \param theGroupName optional name of a group to add 0D elements created
1131 // and/or found on nodes of \a theObject.
1132 // \return an object (a new group or a temporary SMESH_IDSource) holding
1133 // ids of new and/or found 0D elements.
1135 //=============================================================================
1137 SMESH::SMESH_IDSource_ptr
1138 SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObject,
1139 const char* theGroupName)
1140 throw (SALOME::SALOME_Exception)
1144 SMESH::SMESH_IDSource_var result;
1147 TIDSortedElemSet elements, elems0D;
1148 if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
1149 getEditor().Create0DElementsOnAllNodes( elements, elems0D );
1151 SMESH::long_array_var newElems = new SMESH::long_array;
1152 newElems->length( elems0D.size() );
1153 TIDSortedElemSet::iterator eIt = elems0D.begin();
1154 for ( size_t i = 0; i < elems0D.size(); ++i, ++eIt )
1155 newElems[ i ] = (*eIt)->GetID();
1157 SMESH::SMESH_GroupBase_var groupToFill;
1158 if ( theGroupName && strlen( theGroupName ))
1160 // Get existing group named theGroupName
1161 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
1162 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
1163 SMESH::SMESH_GroupBase_var group = groups[i];
1164 if ( !group->_is_nil() ) {
1165 CORBA::String_var name = group->GetName();
1166 if ( strcmp( name.in(), theGroupName ) == 0 && group->GetType() == SMESH::ELEM0D ) {
1167 groupToFill = group;
1172 if ( groupToFill->_is_nil() )
1173 groupToFill = myMesh_i->CreateGroup( SMESH::ELEM0D, theGroupName );
1174 else if ( !SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1175 groupToFill = myMesh_i->ConvertToStandalone( groupToFill );
1178 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1180 group_i->Add( newElems );
1181 result = SMESH::SMESH_IDSource::_narrow( groupToFill );
1182 pyDump << groupToFill;
1186 result = MakeIDSource( newElems, SMESH::ELEM0D );
1187 pyDump << "elem0DIDs";
1190 pyDump << " = " << this << ".Create0DElementsOnAllNodes( "
1191 << theObject << ", '" << theGroupName << "' )";
1193 return result._retn();
1196 //=============================================================================
1198 * \brief Bind a node to a vertex
1199 * \param NodeID - node ID
1200 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1201 * \retval boolean - false if NodeID or VertexID is invalid
1203 //=============================================================================
1205 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
1206 throw (SALOME::SALOME_Exception)
1208 Unexpect aCatch(SALOME_SalomeException);
1210 SMESHDS_Mesh * mesh = getMeshDS();
1211 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1213 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1215 if ( mesh->MaxShapeIndex() < VertexID )
1216 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1218 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
1219 if ( shape.ShapeType() != TopAbs_VERTEX )
1220 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1222 mesh->SetNodeOnVertex( node, VertexID );
1224 myMesh->SetIsModified( true );
1227 //=============================================================================
1229 * \brief Store node position on an edge
1230 * \param NodeID - node ID
1231 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
1232 * \param paramOnEdge - parameter on edge where the node is located
1233 * \retval boolean - false if any parameter is invalid
1235 //=============================================================================
1237 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
1238 CORBA::Double paramOnEdge)
1239 throw (SALOME::SALOME_Exception)
1241 Unexpect aCatch(SALOME_SalomeException);
1243 SMESHDS_Mesh * mesh = getMeshDS();
1244 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1246 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1248 if ( mesh->MaxShapeIndex() < EdgeID )
1249 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1251 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
1252 if ( shape.ShapeType() != TopAbs_EDGE )
1253 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1256 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
1257 if ( paramOnEdge < f || paramOnEdge > l )
1258 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
1260 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
1262 myMesh->SetIsModified( true );
1265 //=============================================================================
1267 * \brief Store node position on a face
1268 * \param NodeID - node ID
1269 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
1270 * \param u - U parameter on face where the node is located
1271 * \param v - V parameter on face where the node is located
1272 * \retval boolean - false if any parameter is invalid
1274 //=============================================================================
1276 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
1277 CORBA::Double u, CORBA::Double v)
1278 throw (SALOME::SALOME_Exception)
1280 Unexpect aCatch(SALOME_SalomeException);
1282 SMESHDS_Mesh * mesh = getMeshDS();
1283 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1285 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1287 if ( mesh->MaxShapeIndex() < FaceID )
1288 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1290 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
1291 if ( shape.ShapeType() != TopAbs_FACE )
1292 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1294 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
1295 bool isOut = ( u < surf.FirstUParameter() ||
1296 u > surf.LastUParameter() ||
1297 v < surf.FirstVParameter() ||
1298 v > surf.LastVParameter() );
1302 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
1303 << " u( " << surf.FirstUParameter()
1304 << "," << surf.LastUParameter()
1305 << ") v( " << surf.FirstVParameter()
1306 << "," << surf.LastVParameter() << ")" );
1308 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
1311 mesh->SetNodeOnFace( node, FaceID, u, v );
1312 myMesh->SetIsModified( true );
1315 //=============================================================================
1317 * \brief Bind a node to a solid
1318 * \param NodeID - node ID
1319 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1320 * \retval boolean - false if NodeID or SolidID is invalid
1322 //=============================================================================
1324 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
1325 throw (SALOME::SALOME_Exception)
1327 Unexpect aCatch(SALOME_SalomeException);
1329 SMESHDS_Mesh * mesh = getMeshDS();
1330 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1332 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1334 if ( mesh->MaxShapeIndex() < SolidID )
1335 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1337 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
1338 if ( shape.ShapeType() != TopAbs_SOLID &&
1339 shape.ShapeType() != TopAbs_SHELL)
1340 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1342 mesh->SetNodeInVolume( node, SolidID );
1344 // myMesh->SetIsModified( true ); - SetNodeInVolume() can't prevent re-compute, I believe
1347 //=============================================================================
1349 * \brief Bind an element to a shape
1350 * \param ElementID - element ID
1351 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
1352 * \retval boolean - false if ElementID or ShapeID is invalid
1354 //=============================================================================
1356 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
1357 CORBA::Long ShapeID)
1358 throw (SALOME::SALOME_Exception)
1360 Unexpect aCatch(SALOME_SalomeException);
1362 SMESHDS_Mesh * mesh = getMeshDS();
1363 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
1365 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
1367 if ( mesh->MaxShapeIndex() < ShapeID )
1368 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1370 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1371 if ( shape.ShapeType() != TopAbs_EDGE &&
1372 shape.ShapeType() != TopAbs_FACE &&
1373 shape.ShapeType() != TopAbs_SOLID &&
1374 shape.ShapeType() != TopAbs_SHELL )
1375 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1377 mesh->SetMeshElementOnShape( elem, ShapeID );
1379 myMesh->SetIsModified( true );
1382 //=============================================================================
1386 //=============================================================================
1388 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1389 CORBA::Long NodeID2)
1393 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1394 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1398 // Update Python script
1399 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1400 << NodeID1 << ", " << NodeID2 << " )";
1403 int ret = getEditor().InverseDiag ( n1, n2 );
1404 myMesh->GetMeshDS()->Modified();
1405 myMesh->SetIsModified( true );
1409 //=============================================================================
1413 //=============================================================================
1415 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1416 CORBA::Long NodeID2)
1420 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1421 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1425 // Update Python script
1426 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1427 << NodeID1 << ", " << NodeID2 << " )";
1430 bool stat = getEditor().DeleteDiag ( n1, n2 );
1432 myMesh->GetMeshDS()->Modified();
1434 myMesh->SetIsModified( true ); // issue 0020693
1440 //=============================================================================
1444 //=============================================================================
1446 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1450 for (int i = 0; i < IDsOfElements.length(); i++)
1452 CORBA::Long index = IDsOfElements[i];
1453 const SMDS_MeshElement * elem = getMeshDS()->FindElement(index);
1455 getEditor().Reorient( elem );
1457 // Update Python script
1458 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1460 myMesh->GetMeshDS()->Modified();
1461 if ( IDsOfElements.length() )
1462 myMesh->SetIsModified( true ); // issue 0020693
1468 //=============================================================================
1472 //=============================================================================
1474 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1478 TPythonDump aTPythonDump; // suppress dump in Reorient()
1480 SMESH::long_array_var anElementsId = theObject->GetIDs();
1481 CORBA::Boolean isDone = Reorient(anElementsId);
1483 // Update Python script
1484 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1489 //=======================================================================
1490 //function : Reorient2D
1491 //purpose : Reorient faces contained in \a the2Dgroup.
1492 // the2Dgroup - the mesh or its part to reorient
1493 // theDirection - desired direction of normal of \a theFace
1494 // theFace - ID of face whose orientation is checked.
1495 // It can be < 1 then \a thePoint is used to find a face.
1496 // thePoint - is used to find a face if \a theFace < 1.
1497 // return number of reoriented elements.
1498 //=======================================================================
1500 CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
1501 const SMESH::DirStruct& theDirection,
1502 CORBA::Long theFace,
1503 const SMESH::PointStruct& thePoint)
1504 throw (SALOME::SALOME_Exception)
1506 Unexpect aCatch(SALOME_SalomeException);
1508 initData(/*deleteSearchers=*/false);
1510 TIDSortedElemSet elements;
1511 if ( !idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1))
1512 THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
1515 const SMDS_MeshElement* face = 0;
1518 face = getMeshDS()->FindElement( theFace );
1520 THROW_SALOME_CORBA_EXCEPTION("Inexistent face given", SALOME::BAD_PARAM);
1521 if ( face->GetType() != SMDSAbs_Face )
1522 THROW_SALOME_CORBA_EXCEPTION("Wrong element type", SALOME::BAD_PARAM);
1526 // create theElementSearcher if needed
1527 theSearchersDeleter.Set( myMesh, getPartIOR( the2Dgroup, SMESH::FACE ));
1528 if ( !theElementSearcher )
1530 if ( elements.empty() ) // search in the whole mesh
1532 if ( myMesh->NbFaces() == 0 )
1533 THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM);
1535 theElementSearcher = myEditor.GetElementSearcher();
1539 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
1540 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
1542 theElementSearcher = myEditor.GetElementSearcher(elemsIt);
1546 gp_Pnt p( thePoint.x, thePoint.y, thePoint.z );
1547 face = theElementSearcher->FindClosestTo( p, SMDSAbs_Face );
1550 THROW_SALOME_CORBA_EXCEPTION("No face found by point", SALOME::INTERNAL_ERROR );
1551 if ( !elements.empty() && !elements.count( face ))
1552 THROW_SALOME_CORBA_EXCEPTION("Found face is not in the group", SALOME::BAD_PARAM );
1555 const SMESH::PointStruct * P = &theDirection.PS;
1556 gp_Vec dirVec( P->x, P->y, P->z );
1557 if ( dirVec.Magnitude() < std::numeric_limits< double >::min() )
1558 THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM);
1560 int nbReori = getEditor().Reorient2D( elements, dirVec, face );
1563 myMesh->SetIsModified( true );
1564 myMesh->GetMeshDS()->Modified();
1566 TPythonDump() << this << ".Reorient2D( "
1567 << the2Dgroup << ", "
1568 << theDirection << ", "
1570 << thePoint << " )";
1575 //=============================================================================
1579 //=============================================================================
1580 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1581 SMESH::NumericalFunctor_ptr Criterion,
1582 CORBA::Double MaxAngle)
1586 SMESHDS_Mesh* aMesh = getMeshDS();
1587 TIDSortedElemSet faces;
1588 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1590 SMESH::NumericalFunctor_i* aNumericalFunctor =
1591 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1592 SMESH::Controls::NumericalFunctorPtr aCrit;
1593 if ( !aNumericalFunctor )
1594 aCrit.reset( new SMESH::Controls::MaxElementLength2D() );
1596 aCrit = aNumericalFunctor->GetNumericalFunctor();
1598 // Update Python script
1599 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1600 << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1603 bool stat = getEditor().TriToQuad( faces, aCrit, MaxAngle );
1604 myMesh->GetMeshDS()->Modified();
1606 myMesh->SetIsModified( true ); // issue 0020693
1613 //=============================================================================
1617 //=============================================================================
1618 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1619 SMESH::NumericalFunctor_ptr Criterion,
1620 CORBA::Double MaxAngle)
1624 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1625 SMESH::long_array_var anElementsId = theObject->GetIDs();
1626 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1628 SMESH::NumericalFunctor_i* aNumericalFunctor =
1629 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1631 // Update Python script
1632 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1633 << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1639 //=============================================================================
1643 //=============================================================================
1644 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1645 SMESH::NumericalFunctor_ptr Criterion)
1649 SMESHDS_Mesh* aMesh = getMeshDS();
1650 TIDSortedElemSet faces;
1651 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1653 SMESH::NumericalFunctor_i* aNumericalFunctor =
1654 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1655 SMESH::Controls::NumericalFunctorPtr aCrit;
1656 if ( !aNumericalFunctor )
1657 aCrit.reset( new SMESH::Controls::AspectRatio() );
1659 aCrit = aNumericalFunctor->GetNumericalFunctor();
1662 // Update Python script
1663 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1665 CORBA::Boolean stat = getEditor().QuadToTri( faces, aCrit );
1666 myMesh->GetMeshDS()->Modified();
1668 myMesh->SetIsModified( true ); // issue 0020693
1675 //=============================================================================
1679 //=============================================================================
1680 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1681 SMESH::NumericalFunctor_ptr Criterion)
1685 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1687 SMESH::long_array_var anElementsId = theObject->GetIDs();
1688 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1690 SMESH::NumericalFunctor_i* aNumericalFunctor =
1691 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1693 // Update Python script
1694 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1700 //=============================================================================
1704 //=============================================================================
1705 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1706 CORBA::Boolean Diag13)
1710 SMESHDS_Mesh* aMesh = getMeshDS();
1711 TIDSortedElemSet faces;
1712 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1714 // Update Python script
1715 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1716 << IDsOfElements << ", " << Diag13 << " )";
1718 CORBA::Boolean stat = getEditor().QuadToTri( faces, Diag13 );
1719 myMesh->GetMeshDS()->Modified();
1721 myMesh->SetIsModified( true ); // issue 0020693
1729 //=============================================================================
1733 //=============================================================================
1734 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1735 CORBA::Boolean Diag13)
1739 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
1741 SMESH::long_array_var anElementsId = theObject->GetIDs();
1742 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
1744 // Update Python script
1745 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
1746 << theObject << ", " << Diag13 << " )";
1752 //=============================================================================
1756 //=============================================================================
1757 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
1758 SMESH::NumericalFunctor_ptr Criterion)
1762 const SMDS_MeshElement* quad = getMeshDS()->FindElement(IDOfQuad);
1763 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
1765 SMESH::NumericalFunctor_i* aNumericalFunctor =
1766 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
1767 SMESH::Controls::NumericalFunctorPtr aCrit;
1768 if (aNumericalFunctor)
1769 aCrit = aNumericalFunctor->GetNumericalFunctor();
1771 aCrit.reset(new SMESH::Controls::AspectRatio());
1773 return getEditor().BestSplit(quad, aCrit);
1778 //================================================================================
1780 * \brief Split volumic elements into tetrahedrons
1782 //================================================================================
1784 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
1785 CORBA::Short methodFlags)
1786 throw (SALOME::SALOME_Exception)
1788 Unexpect aCatch(SALOME_SalomeException);
1792 SMESH::long_array_var anElementsId = elems->GetIDs();
1793 TIDSortedElemSet elemSet;
1794 arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume );
1796 getEditor().SplitVolumesIntoTetra( elemSet, int( methodFlags ));
1797 myMesh->GetMeshDS()->Modified();
1800 // if ( myLastCreatedElems.length() ) - it does not influence Compute()
1801 // myMesh->SetIsModified( true ); // issue 0020693
1803 TPythonDump() << this << ".SplitVolumesIntoTetra( "
1804 << elems << ", " << methodFlags << " )";
1807 //=======================================================================
1810 //=======================================================================
1813 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
1814 const SMESH::long_array & IDsOfFixedNodes,
1815 CORBA::Long MaxNbOfIterations,
1816 CORBA::Double MaxAspectRatio,
1817 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1819 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1820 MaxAspectRatio, Method, false );
1824 //=======================================================================
1825 //function : SmoothParametric
1827 //=======================================================================
1830 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
1831 const SMESH::long_array & IDsOfFixedNodes,
1832 CORBA::Long MaxNbOfIterations,
1833 CORBA::Double MaxAspectRatio,
1834 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1836 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1837 MaxAspectRatio, Method, true );
1841 //=======================================================================
1842 //function : SmoothObject
1844 //=======================================================================
1847 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
1848 const SMESH::long_array & IDsOfFixedNodes,
1849 CORBA::Long MaxNbOfIterations,
1850 CORBA::Double MaxAspectRatio,
1851 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1853 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1854 MaxAspectRatio, Method, false);
1858 //=======================================================================
1859 //function : SmoothParametricObject
1861 //=======================================================================
1864 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
1865 const SMESH::long_array & IDsOfFixedNodes,
1866 CORBA::Long MaxNbOfIterations,
1867 CORBA::Double MaxAspectRatio,
1868 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1870 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1871 MaxAspectRatio, Method, true);
1875 //=============================================================================
1879 //=============================================================================
1882 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
1883 const SMESH::long_array & IDsOfFixedNodes,
1884 CORBA::Long MaxNbOfIterations,
1885 CORBA::Double MaxAspectRatio,
1886 SMESH::SMESH_MeshEditor::Smooth_Method Method,
1891 SMESHDS_Mesh* aMesh = getMeshDS();
1893 TIDSortedElemSet elements;
1894 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
1896 set<const SMDS_MeshNode*> fixedNodes;
1897 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
1898 CORBA::Long index = IDsOfFixedNodes[i];
1899 const SMDS_MeshNode * node = aMesh->FindNode(index);
1901 fixedNodes.insert( node );
1903 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
1904 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
1905 method = ::SMESH_MeshEditor::CENTROIDAL;
1907 getEditor().Smooth(elements, fixedNodes, method,
1908 MaxNbOfIterations, MaxAspectRatio, IsParametric );
1910 myMesh->GetMeshDS()->Modified();
1911 myMesh->SetIsModified( true ); // issue 0020693
1914 // Update Python script
1915 TPythonDump() << "isDone = " << this << "."
1916 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
1917 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
1918 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
1919 << "SMESH.SMESH_MeshEditor."
1920 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1921 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1927 //=============================================================================
1931 //=============================================================================
1934 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
1935 const SMESH::long_array & IDsOfFixedNodes,
1936 CORBA::Long MaxNbOfIterations,
1937 CORBA::Double MaxAspectRatio,
1938 SMESH::SMESH_MeshEditor::Smooth_Method Method,
1943 TPythonDump aTPythonDump; // suppress dump in smooth()
1945 SMESH::long_array_var anElementsId = theObject->GetIDs();
1946 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
1947 MaxAspectRatio, Method, IsParametric);
1949 // Update Python script
1950 aTPythonDump << "isDone = " << this << "."
1951 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
1952 << theObject << ", " << IDsOfFixedNodes << ", "
1953 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
1954 << "SMESH.SMESH_MeshEditor."
1955 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1956 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1962 //=============================================================================
1966 //=============================================================================
1968 void SMESH_MeshEditor_i::RenumberNodes()
1970 // Update Python script
1971 TPythonDump() << this << ".RenumberNodes()";
1973 getMeshDS()->Renumber( true );
1977 //=============================================================================
1981 //=============================================================================
1983 void SMESH_MeshEditor_i::RenumberElements()
1985 // Update Python script
1986 TPythonDump() << this << ".RenumberElements()";
1988 getMeshDS()->Renumber( false );
1991 //=======================================================================
1993 * \brief Return groups by their IDs
1995 //=======================================================================
1997 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
2001 myMesh_i->CreateGroupServants();
2002 return myMesh_i->GetGroups( *groupIDs );
2005 //=======================================================================
2006 //function : rotationSweep
2008 //=======================================================================
2010 SMESH::ListOfGroups*
2011 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
2012 const SMESH::AxisStruct & theAxis,
2013 CORBA::Double theAngleInRadians,
2014 CORBA::Long theNbOfSteps,
2015 CORBA::Double theTolerance,
2016 const bool theMakeGroups,
2017 const SMDSAbs_ElementType theElementType)
2021 TIDSortedElemSet inElements, copyElements;
2022 arrayToSet(theIDsOfElements, getMeshDS(), inElements, theElementType);
2024 TIDSortedElemSet* workElements = & inElements;
2025 bool makeWalls=true;
2026 if ( myIsPreviewMode )
2028 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2029 getPreviewMesh( SMDSAbs_Face )->Copy( inElements, copyElements, select, avoid );
2030 workElements = & copyElements;
2031 //makeWalls = false;
2034 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
2035 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
2037 ::SMESH_MeshEditor::PGroupIDs groupIds =
2038 getEditor().RotationSweep (*workElements, Ax1, theAngleInRadians,
2039 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
2040 myMesh->GetMeshDS()->Modified();
2042 // myMesh->SetIsModified( true ); -- it does not influence Compute()
2044 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2047 //=======================================================================
2048 //function : RotationSweep
2050 //=======================================================================
2052 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
2053 const SMESH::AxisStruct & theAxis,
2054 CORBA::Double theAngleInRadians,
2055 CORBA::Long theNbOfSteps,
2056 CORBA::Double theTolerance)
2058 if ( !myIsPreviewMode ) {
2059 TPythonDump() << this << ".RotationSweep( "
2060 << theIDsOfElements << ", "
2062 << TVar( theAngleInRadians ) << ", "
2063 << TVar( theNbOfSteps ) << ", "
2064 << TVar( theTolerance ) << " )";
2066 rotationSweep(theIDsOfElements,
2074 //=======================================================================
2075 //function : RotationSweepMakeGroups
2077 //=======================================================================
2079 SMESH::ListOfGroups*
2080 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2081 const SMESH::AxisStruct& theAxis,
2082 CORBA::Double theAngleInRadians,
2083 CORBA::Long theNbOfSteps,
2084 CORBA::Double theTolerance)
2086 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2088 SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
2094 if (!myIsPreviewMode) {
2095 DumpGroupsList(aPythonDump, aGroups);
2096 aPythonDump << this << ".RotationSweepMakeGroups( "
2097 << theIDsOfElements << ", "
2099 << TVar( theAngleInRadians ) << ", "
2100 << TVar( theNbOfSteps ) << ", "
2101 << TVar( theTolerance ) << " )";
2106 //=======================================================================
2107 //function : RotationSweepObject
2109 //=======================================================================
2111 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2112 const SMESH::AxisStruct & theAxis,
2113 CORBA::Double theAngleInRadians,
2114 CORBA::Long theNbOfSteps,
2115 CORBA::Double theTolerance)
2117 if ( !myIsPreviewMode ) {
2118 TPythonDump() << this << ".RotationSweepObject( "
2119 << theObject << ", "
2121 << theAngleInRadians << ", "
2122 << theNbOfSteps << ", "
2123 << theTolerance << " )";
2125 SMESH::long_array_var anElementsId = theObject->GetIDs();
2126 rotationSweep(anElementsId,
2134 //=======================================================================
2135 //function : RotationSweepObject1D
2137 //=======================================================================
2139 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2140 const SMESH::AxisStruct & theAxis,
2141 CORBA::Double theAngleInRadians,
2142 CORBA::Long theNbOfSteps,
2143 CORBA::Double theTolerance)
2145 if ( !myIsPreviewMode ) {
2146 TPythonDump() << this << ".RotationSweepObject1D( "
2147 << theObject << ", "
2149 << TVar( theAngleInRadians ) << ", "
2150 << TVar( theNbOfSteps ) << ", "
2151 << TVar( theTolerance ) << " )";
2153 SMESH::long_array_var anElementsId = theObject->GetIDs();
2154 rotationSweep(anElementsId,
2163 //=======================================================================
2164 //function : RotationSweepObject2D
2166 //=======================================================================
2168 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2169 const SMESH::AxisStruct & theAxis,
2170 CORBA::Double theAngleInRadians,
2171 CORBA::Long theNbOfSteps,
2172 CORBA::Double theTolerance)
2174 if ( !myIsPreviewMode ) {
2175 TPythonDump() << this << ".RotationSweepObject2D( "
2176 << theObject << ", "
2178 << TVar( theAngleInRadians ) << ", "
2179 << TVar( theNbOfSteps ) << ", "
2180 << TVar( theTolerance ) << " )";
2182 SMESH::long_array_var anElementsId = theObject->GetIDs();
2183 rotationSweep(anElementsId,
2192 //=======================================================================
2193 //function : RotationSweepObjectMakeGroups
2195 //=======================================================================
2197 SMESH::ListOfGroups*
2198 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2199 const SMESH::AxisStruct& theAxis,
2200 CORBA::Double theAngleInRadians,
2201 CORBA::Long theNbOfSteps,
2202 CORBA::Double theTolerance)
2204 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2206 SMESH::long_array_var anElementsId = theObject->GetIDs();
2207 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2213 if (!myIsPreviewMode) {
2214 DumpGroupsList(aPythonDump, aGroups);
2215 aPythonDump << this << ".RotationSweepObjectMakeGroups( "
2216 << theObject << ", "
2218 << theAngleInRadians << ", "
2219 << theNbOfSteps << ", "
2220 << theTolerance << " )";
2225 //=======================================================================
2226 //function : RotationSweepObject1DMakeGroups
2228 //=======================================================================
2230 SMESH::ListOfGroups*
2231 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2232 const SMESH::AxisStruct& theAxis,
2233 CORBA::Double theAngleInRadians,
2234 CORBA::Long theNbOfSteps,
2235 CORBA::Double theTolerance)
2237 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2239 SMESH::long_array_var anElementsId = theObject->GetIDs();
2240 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2247 if (!myIsPreviewMode) {
2248 DumpGroupsList(aPythonDump, aGroups);
2249 aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
2250 << theObject << ", "
2252 << TVar( theAngleInRadians ) << ", "
2253 << TVar( theNbOfSteps ) << ", "
2254 << TVar( theTolerance ) << " )";
2259 //=======================================================================
2260 //function : RotationSweepObject2DMakeGroups
2262 //=======================================================================
2264 SMESH::ListOfGroups*
2265 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2266 const SMESH::AxisStruct& theAxis,
2267 CORBA::Double theAngleInRadians,
2268 CORBA::Long theNbOfSteps,
2269 CORBA::Double theTolerance)
2271 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2273 SMESH::long_array_var anElementsId = theObject->GetIDs();
2274 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2281 if (!myIsPreviewMode) {
2282 DumpGroupsList(aPythonDump, aGroups);
2283 aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
2284 << theObject << ", "
2286 << TVar( theAngleInRadians ) << ", "
2287 << TVar( theNbOfSteps ) << ", "
2288 << TVar( theTolerance ) << " )";
2294 //=======================================================================
2295 //function : extrusionSweep
2297 //=======================================================================
2299 SMESH::ListOfGroups*
2300 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
2301 const SMESH::DirStruct & theStepVector,
2302 CORBA::Long theNbOfSteps,
2304 const SMDSAbs_ElementType theElementType)
2312 TIDSortedElemSet elements, copyElements;
2313 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
2315 const SMESH::PointStruct * P = &theStepVector.PS;
2316 gp_Vec stepVec( P->x, P->y, P->z );
2318 TIDSortedElemSet* workElements = & elements;
2320 SMDSAbs_ElementType aType = SMDSAbs_Face;
2321 if (theElementType == SMDSAbs_Node)
2323 aType = SMDSAbs_Edge;
2325 if ( myIsPreviewMode ) {
2326 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2327 getPreviewMesh( aType )->Copy( elements, copyElements, select, avoid );
2328 workElements = & copyElements;
2329 theMakeGroups = false;
2332 TElemOfElemListMap aHystory;
2333 ::SMESH_MeshEditor::PGroupIDs groupIds =
2334 getEditor().ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
2336 myMesh->GetMeshDS()->Modified();
2338 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2340 } catch(Standard_Failure) {
2341 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2342 INFOS( "SMESH_MeshEditor_i::ExtrusionSweep fails - "<< aFail->GetMessageString() );
2347 //=======================================================================
2348 //function : ExtrusionSweep
2350 //=======================================================================
2352 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
2353 const SMESH::DirStruct & theStepVector,
2354 CORBA::Long theNbOfSteps)
2356 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
2357 if (!myIsPreviewMode) {
2358 TPythonDump() << this << ".ExtrusionSweep( "
2359 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps) << " )";
2363 //=======================================================================
2364 //function : ExtrusionSweep0D
2366 //=======================================================================
2368 void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElements,
2369 const SMESH::DirStruct & theStepVector,
2370 CORBA::Long theNbOfSteps)
2372 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2373 if (!myIsPreviewMode) {
2374 TPythonDump() << this << ".ExtrusionSweep0D( "
2375 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps)<< " )";
2379 //=======================================================================
2380 //function : ExtrusionSweepObject
2382 //=======================================================================
2384 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2385 const SMESH::DirStruct & theStepVector,
2386 CORBA::Long theNbOfSteps)
2388 SMESH::long_array_var anElementsId = theObject->GetIDs();
2389 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
2390 if (!myIsPreviewMode) {
2391 TPythonDump() << this << ".ExtrusionSweepObject( "
2392 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
2396 //=======================================================================
2397 //function : ExtrusionSweepObject0D
2399 //=======================================================================
2401 void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObject,
2402 const SMESH::DirStruct & theStepVector,
2403 CORBA::Long theNbOfSteps)
2405 SMESH::long_array_var anElementsId = theObject->GetIDs();
2406 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2407 if ( !myIsPreviewMode ) {
2408 TPythonDump() << this << ".ExtrusionSweepObject0D( "
2409 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2413 //=======================================================================
2414 //function : ExtrusionSweepObject1D
2416 //=======================================================================
2418 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2419 const SMESH::DirStruct & theStepVector,
2420 CORBA::Long theNbOfSteps)
2422 SMESH::long_array_var anElementsId = theObject->GetIDs();
2423 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
2424 if ( !myIsPreviewMode ) {
2425 TPythonDump() << this << ".ExtrusionSweepObject1D( "
2426 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2430 //=======================================================================
2431 //function : ExtrusionSweepObject2D
2433 //=======================================================================
2435 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2436 const SMESH::DirStruct & theStepVector,
2437 CORBA::Long theNbOfSteps)
2439 SMESH::long_array_var anElementsId = theObject->GetIDs();
2440 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
2441 if ( !myIsPreviewMode ) {
2442 TPythonDump() << this << ".ExtrusionSweepObject2D( "
2443 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2447 //=======================================================================
2448 //function : ExtrusionSweepMakeGroups
2450 //=======================================================================
2452 SMESH::ListOfGroups*
2453 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2454 const SMESH::DirStruct& theStepVector,
2455 CORBA::Long theNbOfSteps)
2457 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2459 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
2461 if (!myIsPreviewMode) {
2462 DumpGroupsList(aPythonDump, aGroups);
2463 aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
2464 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2469 //=======================================================================
2470 //function : ExtrusionSweepMakeGroups0D
2472 //=======================================================================
2474 SMESH::ListOfGroups*
2475 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups0D(const SMESH::long_array& theIDsOfElements,
2476 const SMESH::DirStruct& theStepVector,
2477 CORBA::Long theNbOfSteps)
2479 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2481 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true,SMDSAbs_Node);
2483 if (!myIsPreviewMode) {
2484 DumpGroupsList(aPythonDump, aGroups);
2485 aPythonDump << this << ".ExtrusionSweepMakeGroups0D( " << theIDsOfElements
2486 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2491 //=======================================================================
2492 //function : ExtrusionSweepObjectMakeGroups
2494 //=======================================================================
2496 SMESH::ListOfGroups*
2497 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2498 const SMESH::DirStruct& theStepVector,
2499 CORBA::Long theNbOfSteps)
2501 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2503 SMESH::long_array_var anElementsId = theObject->GetIDs();
2504 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
2506 if (!myIsPreviewMode) {
2507 DumpGroupsList(aPythonDump, aGroups);
2508 aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
2509 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2514 //=======================================================================
2515 //function : ExtrusionSweepObject0DMakeGroups
2517 //=======================================================================
2519 SMESH::ListOfGroups*
2520 SMESH_MeshEditor_i::ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2521 const SMESH::DirStruct& theStepVector,
2522 CORBA::Long theNbOfSteps)
2524 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2526 SMESH::long_array_var anElementsId = theObject->GetIDs();
2527 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2528 theNbOfSteps, true, SMDSAbs_Node);
2529 if (!myIsPreviewMode) {
2530 DumpGroupsList(aPythonDump, aGroups);
2531 aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject
2532 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2537 //=======================================================================
2538 //function : ExtrusionSweepObject1DMakeGroups
2540 //=======================================================================
2542 SMESH::ListOfGroups*
2543 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2544 const SMESH::DirStruct& theStepVector,
2545 CORBA::Long theNbOfSteps)
2547 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2549 SMESH::long_array_var anElementsId = theObject->GetIDs();
2550 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2551 theNbOfSteps, true, SMDSAbs_Edge);
2552 if (!myIsPreviewMode) {
2553 DumpGroupsList(aPythonDump, aGroups);
2554 aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
2555 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2560 //=======================================================================
2561 //function : ExtrusionSweepObject2DMakeGroups
2563 //=======================================================================
2565 SMESH::ListOfGroups*
2566 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2567 const SMESH::DirStruct& theStepVector,
2568 CORBA::Long theNbOfSteps)
2570 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2572 SMESH::long_array_var anElementsId = theObject->GetIDs();
2573 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2574 theNbOfSteps, true, SMDSAbs_Face);
2575 if (!myIsPreviewMode) {
2576 DumpGroupsList(aPythonDump, aGroups);
2577 aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
2578 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2584 //=======================================================================
2585 //function : advancedExtrusion
2587 //=======================================================================
2589 SMESH::ListOfGroups*
2590 SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
2591 const SMESH::DirStruct & theStepVector,
2592 CORBA::Long theNbOfSteps,
2593 CORBA::Long theExtrFlags,
2594 CORBA::Double theSewTolerance,
2595 const bool theMakeGroups)
2599 TIDSortedElemSet elements;
2600 arrayToSet(theIDsOfElements, getMeshDS(), elements);
2602 const SMESH::PointStruct * P = &theStepVector.PS;
2603 gp_Vec stepVec( P->x, P->y, P->z );
2605 TElemOfElemListMap aHystory;
2606 ::SMESH_MeshEditor::PGroupIDs groupIds =
2607 getEditor().ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
2608 theMakeGroups, theExtrFlags, theSewTolerance);
2610 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2613 //=======================================================================
2614 //function : AdvancedExtrusion
2616 //=======================================================================
2618 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2619 const SMESH::DirStruct & theStepVector,
2620 CORBA::Long theNbOfSteps,
2621 CORBA::Long theExtrFlags,
2622 CORBA::Double theSewTolerance)
2624 if ( !myIsPreviewMode ) {
2625 TPythonDump() << "stepVector = " << theStepVector;
2626 TPythonDump() << this << ".AdvancedExtrusion("
2629 << theNbOfSteps << ","
2630 << theExtrFlags << ", "
2631 << theSewTolerance << " )";
2633 advancedExtrusion( theIDsOfElements,
2641 //=======================================================================
2642 //function : AdvancedExtrusionMakeGroups
2644 //=======================================================================
2645 SMESH::ListOfGroups*
2646 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
2647 const SMESH::DirStruct& theStepVector,
2648 CORBA::Long theNbOfSteps,
2649 CORBA::Long theExtrFlags,
2650 CORBA::Double theSewTolerance)
2652 if (!myIsPreviewMode) {
2653 TPythonDump() << "stepVector = " << theStepVector;
2655 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2657 SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
2664 if (!myIsPreviewMode) {
2665 DumpGroupsList(aPythonDump, aGroups);
2666 aPythonDump << this << ".AdvancedExtrusionMakeGroups("
2669 << theNbOfSteps << ","
2670 << theExtrFlags << ", "
2671 << theSewTolerance << " )";
2677 //================================================================================
2679 * \brief Convert extrusion error to IDL enum
2681 //================================================================================
2683 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
2685 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
2689 RETCASE( EXTR_NO_ELEMENTS );
2690 RETCASE( EXTR_PATH_NOT_EDGE );
2691 RETCASE( EXTR_BAD_PATH_SHAPE );
2692 RETCASE( EXTR_BAD_STARTING_NODE );
2693 RETCASE( EXTR_BAD_ANGLES_NUMBER );
2694 RETCASE( EXTR_CANT_GET_TANGENT );
2696 return SMESH::SMESH_MeshEditor::EXTR_OK;
2700 //=======================================================================
2701 //function : extrusionAlongPath
2703 //=======================================================================
2704 SMESH::ListOfGroups*
2705 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2706 SMESH::SMESH_Mesh_ptr thePathMesh,
2707 GEOM::GEOM_Object_ptr thePathShape,
2708 CORBA::Long theNodeStart,
2709 CORBA::Boolean theHasAngles,
2710 const SMESH::double_array & theAngles,
2711 CORBA::Boolean theHasRefPoint,
2712 const SMESH::PointStruct & theRefPoint,
2713 const bool theMakeGroups,
2714 SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
2715 const SMDSAbs_ElementType theElementType)
2717 MESSAGE("extrusionAlongPath");
2720 if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
2721 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2724 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2726 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2727 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2729 if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
2730 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2734 SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
2736 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2740 TIDSortedElemSet elements;
2741 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
2743 list<double> angles;
2744 for (int i = 0; i < theAngles.length(); i++) {
2745 angles.push_back( theAngles[i] );
2748 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
2750 int nbOldGroups = myMesh->NbGroup();
2752 ::SMESH_MeshEditor::Extrusion_Error error =
2753 getEditor().ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
2754 theHasAngles, angles, false,
2755 theHasRefPoint, refPnt, theMakeGroups );
2756 myMesh->GetMeshDS()->Modified();
2757 theError = convExtrError( error );
2759 if ( theMakeGroups ) {
2760 list<int> groupIDs = myMesh->GetGroupIds();
2761 list<int>::iterator newBegin = groupIDs.begin();
2762 std::advance( newBegin, nbOldGroups ); // skip old groups
2763 groupIDs.erase( groupIDs.begin(), newBegin );
2764 return getGroups( & groupIDs );
2770 //=======================================================================
2771 //function : extrusionAlongPathX
2773 //=======================================================================
2774 SMESH::ListOfGroups*
2775 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements,
2776 SMESH::SMESH_IDSource_ptr Path,
2777 CORBA::Long NodeStart,
2778 CORBA::Boolean HasAngles,
2779 const SMESH::double_array& Angles,
2780 CORBA::Boolean LinearVariation,
2781 CORBA::Boolean HasRefPoint,
2782 const SMESH::PointStruct& RefPoint,
2784 const SMDSAbs_ElementType ElementType,
2785 SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
2787 SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
2791 list<double> angles;
2792 for (int i = 0; i < Angles.length(); i++) {
2793 angles.push_back( Angles[i] );
2795 gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
2796 int nbOldGroups = myMesh->NbGroup();
2798 if ( Path->_is_nil() ) {
2799 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2803 TIDSortedElemSet elements, copyElements;
2804 arrayToSet(IDsOfElements, getMeshDS(), elements, ElementType);
2806 TIDSortedElemSet* workElements = &elements;
2808 if ( myIsPreviewMode )
2810 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2811 getPreviewMesh( SMDSAbs_Face )->Copy( elements, copyElements, select, avoid );
2812 workElements = & copyElements;
2816 ::SMESH_MeshEditor::Extrusion_Error error;
2818 if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path ))
2821 SMDS_MeshNode* aNodeStart =
2822 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2823 if ( !aNodeStart ) {
2824 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2827 error = getEditor().ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
2828 HasAngles, angles, LinearVariation,
2829 HasRefPoint, refPnt, MakeGroups );
2830 myMesh->GetMeshDS()->Modified();
2832 else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
2835 SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
2836 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
2837 SMDS_MeshNode* aNodeStart =
2838 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2839 if ( !aNodeStart ) {
2840 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2843 SMESH_subMesh* aSubMesh =
2844 aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
2845 error = getEditor().ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
2846 HasAngles, angles, LinearVariation,
2847 HasRefPoint, refPnt, MakeGroups );
2848 myMesh->GetMeshDS()->Modified();
2850 else if ( SMESH::DownCast<SMESH_Group_i*>( Path ))
2852 // path as group of 1D elements
2858 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2862 Error = convExtrError( error );
2865 list<int> groupIDs = myMesh->GetGroupIds();
2866 list<int>::iterator newBegin = groupIDs.begin();
2867 std::advance( newBegin, nbOldGroups ); // skip old groups
2868 groupIDs.erase( groupIDs.begin(), newBegin );
2869 return getGroups( & groupIDs );
2875 //=======================================================================
2876 //function : ExtrusionAlongPath
2878 //=======================================================================
2879 SMESH::SMESH_MeshEditor::Extrusion_Error
2880 SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2881 SMESH::SMESH_Mesh_ptr thePathMesh,
2882 GEOM::GEOM_Object_ptr thePathShape,
2883 CORBA::Long theNodeStart,
2884 CORBA::Boolean theHasAngles,
2885 const SMESH::double_array & theAngles,
2886 CORBA::Boolean theHasRefPoint,
2887 const SMESH::PointStruct & theRefPoint)
2889 MESSAGE("ExtrusionAlongPath");
2890 if ( !myIsPreviewMode ) {
2891 TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
2892 << theIDsOfElements << ", "
2893 << thePathMesh << ", "
2894 << thePathShape << ", "
2895 << theNodeStart << ", "
2896 << theHasAngles << ", "
2897 << theAngles << ", "
2898 << theHasRefPoint << ", "
2899 << "SMESH.PointStruct( "
2900 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2901 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2902 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2904 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2905 extrusionAlongPath( theIDsOfElements,
2918 //=======================================================================
2919 //function : ExtrusionAlongPathObject
2921 //=======================================================================
2922 SMESH::SMESH_MeshEditor::Extrusion_Error
2923 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject,
2924 SMESH::SMESH_Mesh_ptr thePathMesh,
2925 GEOM::GEOM_Object_ptr thePathShape,
2926 CORBA::Long theNodeStart,
2927 CORBA::Boolean theHasAngles,
2928 const SMESH::double_array & theAngles,
2929 CORBA::Boolean theHasRefPoint,
2930 const SMESH::PointStruct & theRefPoint)
2932 if ( !myIsPreviewMode ) {
2933 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
2934 << theObject << ", "
2935 << thePathMesh << ", "
2936 << thePathShape << ", "
2937 << theNodeStart << ", "
2938 << theHasAngles << ", "
2939 << theAngles << ", "
2940 << theHasRefPoint << ", "
2941 << "SMESH.PointStruct( "
2942 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2943 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2944 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2946 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2947 SMESH::long_array_var anElementsId = theObject->GetIDs();
2948 extrusionAlongPath( anElementsId,
2961 //=======================================================================
2962 //function : ExtrusionAlongPathObject1D
2964 //=======================================================================
2965 SMESH::SMESH_MeshEditor::Extrusion_Error
2966 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject,
2967 SMESH::SMESH_Mesh_ptr thePathMesh,
2968 GEOM::GEOM_Object_ptr thePathShape,
2969 CORBA::Long theNodeStart,
2970 CORBA::Boolean theHasAngles,
2971 const SMESH::double_array & theAngles,
2972 CORBA::Boolean theHasRefPoint,
2973 const SMESH::PointStruct & theRefPoint)
2975 if ( !myIsPreviewMode ) {
2976 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
2977 << theObject << ", "
2978 << thePathMesh << ", "
2979 << thePathShape << ", "
2980 << theNodeStart << ", "
2981 << theHasAngles << ", "
2982 << theAngles << ", "
2983 << theHasRefPoint << ", "
2984 << "SMESH.PointStruct( "
2985 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2986 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2987 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2989 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2990 SMESH::long_array_var anElementsId = theObject->GetIDs();
2991 extrusionAlongPath( anElementsId,
3005 //=======================================================================
3006 //function : ExtrusionAlongPathObject2D
3008 //=======================================================================
3009 SMESH::SMESH_MeshEditor::Extrusion_Error
3010 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject,
3011 SMESH::SMESH_Mesh_ptr thePathMesh,
3012 GEOM::GEOM_Object_ptr thePathShape,
3013 CORBA::Long theNodeStart,
3014 CORBA::Boolean theHasAngles,
3015 const SMESH::double_array & theAngles,
3016 CORBA::Boolean theHasRefPoint,
3017 const SMESH::PointStruct & theRefPoint)
3019 if ( !myIsPreviewMode ) {
3020 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
3021 << theObject << ", "
3022 << thePathMesh << ", "
3023 << thePathShape << ", "
3024 << theNodeStart << ", "
3025 << theHasAngles << ", "
3026 << theAngles << ", "
3027 << theHasRefPoint << ", "
3028 << "SMESH.PointStruct( "
3029 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3030 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3031 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3033 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3034 SMESH::long_array_var anElementsId = theObject->GetIDs();
3035 extrusionAlongPath( anElementsId,
3050 //=======================================================================
3051 //function : ExtrusionAlongPathMakeGroups
3053 //=======================================================================
3054 SMESH::ListOfGroups*
3055 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theIDsOfElements,
3056 SMESH::SMESH_Mesh_ptr thePathMesh,
3057 GEOM::GEOM_Object_ptr thePathShape,
3058 CORBA::Long theNodeStart,
3059 CORBA::Boolean theHasAngles,
3060 const SMESH::double_array& theAngles,
3061 CORBA::Boolean theHasRefPoint,
3062 const SMESH::PointStruct& theRefPoint,
3063 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3065 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3067 SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements,
3077 if (!myIsPreviewMode) {
3078 bool isDumpGroups = aGroups && aGroups->length() > 0;
3080 aPythonDump << "(" << aGroups << ", error)";
3082 aPythonDump <<"error";
3084 aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
3085 << theIDsOfElements << ", "
3086 << thePathMesh << ", "
3087 << thePathShape << ", "
3088 << theNodeStart << ", "
3089 << theHasAngles << ", "
3090 << theAngles << ", "
3091 << theHasRefPoint << ", "
3092 << "SMESH.PointStruct( "
3093 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3094 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3095 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3100 //=======================================================================
3101 //function : ExtrusionAlongPathObjectMakeGroups
3103 //=======================================================================
3104 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3105 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3106 SMESH::SMESH_Mesh_ptr thePathMesh,
3107 GEOM::GEOM_Object_ptr thePathShape,
3108 CORBA::Long theNodeStart,
3109 CORBA::Boolean theHasAngles,
3110 const SMESH::double_array& theAngles,
3111 CORBA::Boolean theHasRefPoint,
3112 const SMESH::PointStruct& theRefPoint,
3113 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3115 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3117 SMESH::long_array_var anElementsId = theObject->GetIDs();
3118 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3129 if (!myIsPreviewMode) {
3130 bool isDumpGroups = aGroups && aGroups->length() > 0;
3132 aPythonDump << "(" << aGroups << ", error)";
3134 aPythonDump <<"error";
3136 aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
3137 << theObject << ", "
3138 << thePathMesh << ", "
3139 << thePathShape << ", "
3140 << theNodeStart << ", "
3141 << theHasAngles << ", "
3142 << theAngles << ", "
3143 << theHasRefPoint << ", "
3144 << "SMESH.PointStruct( "
3145 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3146 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3147 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3152 //=======================================================================
3153 //function : ExtrusionAlongPathObject1DMakeGroups
3155 //=======================================================================
3156 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3157 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3158 SMESH::SMESH_Mesh_ptr thePathMesh,
3159 GEOM::GEOM_Object_ptr thePathShape,
3160 CORBA::Long theNodeStart,
3161 CORBA::Boolean theHasAngles,
3162 const SMESH::double_array& theAngles,
3163 CORBA::Boolean theHasRefPoint,
3164 const SMESH::PointStruct& theRefPoint,
3165 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3167 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3169 SMESH::long_array_var anElementsId = theObject->GetIDs();
3170 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3182 if (!myIsPreviewMode) {
3183 bool isDumpGroups = aGroups && aGroups->length() > 0;
3185 aPythonDump << "(" << aGroups << ", error)";
3187 aPythonDump << "error";
3189 aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
3190 << theObject << ", "
3191 << thePathMesh << ", "
3192 << thePathShape << ", "
3193 << theNodeStart << ", "
3194 << theHasAngles << ", "
3195 << theAngles << ", "
3196 << theHasRefPoint << ", "
3197 << "SMESH.PointStruct( "
3198 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3199 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3200 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3205 //=======================================================================
3206 //function : ExtrusionAlongPathObject2DMakeGroups
3208 //=======================================================================
3209 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3210 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3211 SMESH::SMESH_Mesh_ptr thePathMesh,
3212 GEOM::GEOM_Object_ptr thePathShape,
3213 CORBA::Long theNodeStart,
3214 CORBA::Boolean theHasAngles,
3215 const SMESH::double_array& theAngles,
3216 CORBA::Boolean theHasRefPoint,
3217 const SMESH::PointStruct& theRefPoint,
3218 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3220 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3222 SMESH::long_array_var anElementsId = theObject->GetIDs();
3223 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3235 if (!myIsPreviewMode) {
3236 bool isDumpGroups = aGroups && aGroups->length() > 0;
3238 aPythonDump << "(" << aGroups << ", error)";
3240 aPythonDump << "error";
3242 aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
3243 << theObject << ", "
3244 << thePathMesh << ", "
3245 << thePathShape << ", "
3246 << theNodeStart << ", "
3247 << theHasAngles << ", "
3248 << theAngles << ", "
3249 << theHasRefPoint << ", "
3250 << "SMESH.PointStruct( "
3251 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3252 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3253 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3259 //=======================================================================
3260 //function : ExtrusionAlongPathObjX
3262 //=======================================================================
3263 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3264 ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr Object,
3265 SMESH::SMESH_IDSource_ptr Path,
3266 CORBA::Long NodeStart,
3267 CORBA::Boolean HasAngles,
3268 const SMESH::double_array& Angles,
3269 CORBA::Boolean LinearVariation,
3270 CORBA::Boolean HasRefPoint,
3271 const SMESH::PointStruct& RefPoint,
3272 CORBA::Boolean MakeGroups,
3273 SMESH::ElementType ElemType,
3274 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3276 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3278 SMESH::long_array_var anElementsId = Object->GetIDs();
3279 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
3288 (SMDSAbs_ElementType)ElemType,
3291 if (!myIsPreviewMode) {
3292 bool isDumpGroups = aGroups && aGroups->length() > 0;
3294 aPythonDump << "(" << *aGroups << ", error)";
3296 aPythonDump << "error";
3298 aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
3301 << NodeStart << ", "
3302 << HasAngles << ", "
3303 << TVar( Angles ) << ", "
3304 << LinearVariation << ", "
3305 << HasRefPoint << ", "
3306 << "SMESH.PointStruct( "
3307 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3308 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3309 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3310 << MakeGroups << ", "
3311 << ElemType << " )";
3317 //=======================================================================
3318 //function : ExtrusionAlongPathX
3320 //=======================================================================
3321 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3322 ExtrusionAlongPathX(const SMESH::long_array& IDsOfElements,
3323 SMESH::SMESH_IDSource_ptr Path,
3324 CORBA::Long NodeStart,
3325 CORBA::Boolean HasAngles,
3326 const SMESH::double_array& Angles,
3327 CORBA::Boolean LinearVariation,
3328 CORBA::Boolean HasRefPoint,
3329 const SMESH::PointStruct& RefPoint,
3330 CORBA::Boolean MakeGroups,
3331 SMESH::ElementType ElemType,
3332 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3334 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3336 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
3345 (SMDSAbs_ElementType)ElemType,
3348 if (!myIsPreviewMode) {
3349 bool isDumpGroups = aGroups && aGroups->length() > 0;
3351 aPythonDump << "(" << *aGroups << ", error)";
3353 aPythonDump <<"error";
3355 aPythonDump << " = " << this << ".ExtrusionAlongPathX( "
3356 << IDsOfElements << ", "
3358 << NodeStart << ", "
3359 << HasAngles << ", "
3360 << TVar( Angles ) << ", "
3361 << LinearVariation << ", "
3362 << HasRefPoint << ", "
3363 << "SMESH.PointStruct( "
3364 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3365 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3366 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3367 << MakeGroups << ", "
3368 << ElemType << " )";
3374 //================================================================================
3376 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
3377 * of given angles along path steps
3378 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
3379 * which proceeds the extrusion
3380 * \param PathShape is shape(edge); as the mesh can be complex, the edge
3381 * is used to define the sub-mesh for the path
3383 //================================================================================
3385 SMESH::double_array*
3386 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
3387 GEOM::GEOM_Object_ptr thePathShape,
3388 const SMESH::double_array & theAngles)
3390 SMESH::double_array_var aResult = new SMESH::double_array();
3391 int nbAngles = theAngles.length();
3392 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
3394 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3395 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3396 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3397 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
3398 return aResult._retn();
3399 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
3400 if ( nbSteps == nbAngles )
3402 aResult.inout() = theAngles;
3406 aResult->length( nbSteps );
3407 double rAn2St = double( nbAngles ) / double( nbSteps );
3408 double angPrev = 0, angle;
3409 for ( int iSt = 0; iSt < nbSteps; ++iSt )
3411 double angCur = rAn2St * ( iSt+1 );
3412 double angCurFloor = floor( angCur );
3413 double angPrevFloor = floor( angPrev );
3414 if ( angPrevFloor == angCurFloor )
3415 angle = rAn2St * theAngles[ int( angCurFloor ) ];
3418 int iP = int( angPrevFloor );
3419 double angPrevCeil = ceil(angPrev);
3420 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
3422 int iC = int( angCurFloor );
3423 if ( iC < nbAngles )
3424 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
3426 iP = int( angPrevCeil );
3428 angle += theAngles[ iC ];
3430 aResult[ iSt ] = angle;
3435 // Update Python script
3436 TPythonDump() << "rotAngles = " << theAngles;
3437 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
3438 << thePathMesh << ", "
3439 << thePathShape << ", "
3442 return aResult._retn();
3446 //=======================================================================
3449 //=======================================================================
3451 SMESH::ListOfGroups*
3452 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
3453 const SMESH::AxisStruct & theAxis,
3454 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3455 CORBA::Boolean theCopy,
3457 ::SMESH_Mesh* theTargetMesh)
3461 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3462 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3464 if ( theTargetMesh )
3468 switch ( theMirrorType ) {
3469 case SMESH::SMESH_MeshEditor::POINT:
3470 aTrsf.SetMirror( P );
3472 case SMESH::SMESH_MeshEditor::AXIS:
3473 aTrsf.SetMirror( gp_Ax1( P, V ));
3476 aTrsf.SetMirror( gp_Ax2( P, V ));
3479 TIDSortedElemSet copyElements;
3480 TIDSortedElemSet* workElements = & theElements;
3482 if ( myIsPreviewMode )
3484 TPreviewMesh * tmpMesh = getPreviewMesh();
3485 tmpMesh->Copy( theElements, copyElements);
3486 if ( !theCopy && !theTargetMesh )
3488 TIDSortedElemSet elemsAround, elemsAroundCopy;
3489 getElementsAround( theElements, getMeshDS(), elemsAround );
3490 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3492 workElements = & copyElements;
3493 theMakeGroups = false;
3496 ::SMESH_MeshEditor::PGroupIDs groupIds =
3497 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3499 if ( theCopy && !myIsPreviewMode)
3501 if ( theTargetMesh )
3503 theTargetMesh->GetMeshDS()->Modified();
3507 myMesh->GetMeshDS()->Modified();
3508 myMesh->SetIsModified( true );
3511 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3514 //=======================================================================
3517 //=======================================================================
3519 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3520 const SMESH::AxisStruct & theAxis,
3521 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3522 CORBA::Boolean theCopy)
3524 if ( !myIsPreviewMode ) {
3525 TPythonDump() << this << ".Mirror( "
3526 << theIDsOfElements << ", "
3528 << mirrorTypeName(theMirrorType) << ", "
3531 if ( theIDsOfElements.length() > 0 )
3533 TIDSortedElemSet elements;
3534 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3535 mirror(elements, theAxis, theMirrorType, theCopy, false);
3540 //=======================================================================
3541 //function : MirrorObject
3543 //=======================================================================
3545 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3546 const SMESH::AxisStruct & theAxis,
3547 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3548 CORBA::Boolean theCopy)
3550 if ( !myIsPreviewMode ) {
3551 TPythonDump() << this << ".MirrorObject( "
3552 << theObject << ", "
3554 << mirrorTypeName(theMirrorType) << ", "
3557 TIDSortedElemSet elements;
3559 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3561 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3562 mirror(elements, theAxis, theMirrorType, theCopy, false);
3565 //=======================================================================
3566 //function : MirrorMakeGroups
3568 //=======================================================================
3570 SMESH::ListOfGroups*
3571 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3572 const SMESH::AxisStruct& theMirror,
3573 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3575 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3577 SMESH::ListOfGroups * aGroups = 0;
3578 if ( theIDsOfElements.length() > 0 )
3580 TIDSortedElemSet elements;
3581 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3582 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3584 if (!myIsPreviewMode) {
3585 DumpGroupsList(aPythonDump, aGroups);
3586 aPythonDump << this << ".MirrorMakeGroups( "
3587 << theIDsOfElements << ", "
3588 << theMirror << ", "
3589 << mirrorTypeName(theMirrorType) << " )";
3594 //=======================================================================
3595 //function : MirrorObjectMakeGroups
3597 //=======================================================================
3599 SMESH::ListOfGroups*
3600 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3601 const SMESH::AxisStruct& theMirror,
3602 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3604 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3606 SMESH::ListOfGroups * aGroups = 0;
3607 TIDSortedElemSet elements;
3608 if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3609 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3611 if (!myIsPreviewMode)
3613 DumpGroupsList(aPythonDump,aGroups);
3614 aPythonDump << this << ".MirrorObjectMakeGroups( "
3615 << theObject << ", "
3616 << theMirror << ", "
3617 << mirrorTypeName(theMirrorType) << " )";
3622 //=======================================================================
3623 //function : MirrorMakeMesh
3625 //=======================================================================
3627 SMESH::SMESH_Mesh_ptr
3628 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
3629 const SMESH::AxisStruct& theMirror,
3630 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3631 CORBA::Boolean theCopyGroups,
3632 const char* theMeshName)
3634 SMESH_Mesh_i* mesh_i;
3635 SMESH::SMESH_Mesh_var mesh;
3636 { // open new scope to dump "MakeMesh" command
3637 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3639 TPythonDump pydump; // to prevent dump at mesh creation
3641 mesh = makeMesh( theMeshName );
3642 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3643 if (mesh_i && theIDsOfElements.length() > 0 )
3645 TIDSortedElemSet elements;
3646 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3647 mirror(elements, theMirror, theMirrorType,
3648 false, theCopyGroups, & mesh_i->GetImpl());
3649 mesh_i->CreateGroupServants();
3652 if (!myIsPreviewMode) {
3653 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
3654 << theIDsOfElements << ", "
3655 << theMirror << ", "
3656 << mirrorTypeName(theMirrorType) << ", "
3657 << theCopyGroups << ", '"
3658 << theMeshName << "' )";
3663 if (!myIsPreviewMode && mesh_i)
3664 mesh_i->GetGroups();
3666 return mesh._retn();
3669 //=======================================================================
3670 //function : MirrorObjectMakeMesh
3672 //=======================================================================
3674 SMESH::SMESH_Mesh_ptr
3675 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3676 const SMESH::AxisStruct& theMirror,
3677 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3678 CORBA::Boolean theCopyGroups,
3679 const char* theMeshName)
3681 SMESH_Mesh_i* mesh_i;
3682 SMESH::SMESH_Mesh_var mesh;
3683 { // open new scope to dump "MakeMesh" command
3684 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3686 TPythonDump pydump; // to prevent dump at mesh creation
3688 mesh = makeMesh( theMeshName );
3689 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3690 TIDSortedElemSet elements;
3692 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3694 mirror(elements, theMirror, theMirrorType,
3695 false, theCopyGroups, & mesh_i->GetImpl());
3696 mesh_i->CreateGroupServants();
3698 if (!myIsPreviewMode) {
3699 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
3700 << theObject << ", "
3701 << theMirror << ", "
3702 << mirrorTypeName(theMirrorType) << ", "
3703 << theCopyGroups << ", '"
3704 << theMeshName << "' )";
3709 if (!myIsPreviewMode && mesh_i)
3710 mesh_i->GetGroups();
3712 return mesh._retn();
3715 //=======================================================================
3716 //function : translate
3718 //=======================================================================
3720 SMESH::ListOfGroups*
3721 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
3722 const SMESH::DirStruct & theVector,
3723 CORBA::Boolean theCopy,
3725 ::SMESH_Mesh* theTargetMesh)
3729 if ( theTargetMesh )
3733 const SMESH::PointStruct * P = &theVector.PS;
3734 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
3736 TIDSortedElemSet copyElements;
3737 TIDSortedElemSet* workElements = &theElements;
3739 if ( myIsPreviewMode )
3741 TPreviewMesh * tmpMesh = getPreviewMesh();
3742 tmpMesh->Copy( theElements, copyElements);
3743 if ( !theCopy && !theTargetMesh )
3745 TIDSortedElemSet elemsAround, elemsAroundCopy;
3746 getElementsAround( theElements, getMeshDS(), elemsAround );
3747 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3749 workElements = & copyElements;
3750 theMakeGroups = false;
3753 ::SMESH_MeshEditor::PGroupIDs groupIds =
3754 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3756 if ( theCopy && !myIsPreviewMode )
3758 if ( theTargetMesh )
3760 theTargetMesh->GetMeshDS()->Modified();
3764 myMesh->GetMeshDS()->Modified();
3765 myMesh->SetIsModified( true );
3769 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3772 //=======================================================================
3773 //function : Translate
3775 //=======================================================================
3777 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
3778 const SMESH::DirStruct & theVector,
3779 CORBA::Boolean theCopy)
3781 if (!myIsPreviewMode) {
3782 TPythonDump() << this << ".Translate( "
3783 << theIDsOfElements << ", "
3784 << theVector << ", "
3787 if (theIDsOfElements.length()) {
3788 TIDSortedElemSet elements;
3789 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3790 translate(elements, theVector, theCopy, false);
3794 //=======================================================================
3795 //function : TranslateObject
3797 //=======================================================================
3799 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
3800 const SMESH::DirStruct & theVector,
3801 CORBA::Boolean theCopy)
3803 if (!myIsPreviewMode) {
3804 TPythonDump() << this << ".TranslateObject( "
3805 << theObject << ", "
3806 << theVector << ", "
3809 TIDSortedElemSet elements;
3811 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3813 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3814 translate(elements, theVector, theCopy, false);
3817 //=======================================================================
3818 //function : TranslateMakeGroups
3820 //=======================================================================
3822 SMESH::ListOfGroups*
3823 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
3824 const SMESH::DirStruct& theVector)
3826 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3828 SMESH::ListOfGroups * aGroups = 0;
3829 if (theIDsOfElements.length()) {
3830 TIDSortedElemSet elements;
3831 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3832 aGroups = translate(elements,theVector,true,true);
3834 if (!myIsPreviewMode) {
3835 DumpGroupsList(aPythonDump, aGroups);
3836 aPythonDump << this << ".TranslateMakeGroups( "
3837 << theIDsOfElements << ", "
3838 << theVector << " )";
3843 //=======================================================================
3844 //function : TranslateObjectMakeGroups
3846 //=======================================================================
3848 SMESH::ListOfGroups*
3849 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3850 const SMESH::DirStruct& theVector)
3852 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3854 SMESH::ListOfGroups * aGroups = 0;
3855 TIDSortedElemSet elements;
3856 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3857 aGroups = translate(elements, theVector, true, true);
3859 if (!myIsPreviewMode) {
3860 DumpGroupsList(aPythonDump, aGroups);
3861 aPythonDump << this << ".TranslateObjectMakeGroups( "
3862 << theObject << ", "
3863 << theVector << " )";
3868 //=======================================================================
3869 //function : TranslateMakeMesh
3871 //=======================================================================
3873 SMESH::SMESH_Mesh_ptr
3874 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
3875 const SMESH::DirStruct& theVector,
3876 CORBA::Boolean theCopyGroups,
3877 const char* theMeshName)
3879 SMESH_Mesh_i* mesh_i;
3880 SMESH::SMESH_Mesh_var mesh;
3882 { // open new scope to dump "MakeMesh" command
3883 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3885 TPythonDump pydump; // to prevent dump at mesh creation
3887 mesh = makeMesh( theMeshName );
3888 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3890 if ( mesh_i && theIDsOfElements.length() )
3892 TIDSortedElemSet elements;
3893 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3894 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
3895 mesh_i->CreateGroupServants();
3898 if ( !myIsPreviewMode ) {
3899 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
3900 << theIDsOfElements << ", "
3901 << theVector << ", "
3902 << theCopyGroups << ", '"
3903 << theMeshName << "' )";
3908 if (!myIsPreviewMode && mesh_i)
3909 mesh_i->GetGroups();
3911 return mesh._retn();
3914 //=======================================================================
3915 //function : TranslateObjectMakeMesh
3917 //=======================================================================
3919 SMESH::SMESH_Mesh_ptr
3920 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3921 const SMESH::DirStruct& theVector,
3922 CORBA::Boolean theCopyGroups,
3923 const char* theMeshName)
3925 SMESH_Mesh_i* mesh_i;
3926 SMESH::SMESH_Mesh_var mesh;
3927 { // open new scope to dump "MakeMesh" command
3928 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3930 TPythonDump pydump; // to prevent dump at mesh creation
3931 mesh = makeMesh( theMeshName );
3932 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3934 TIDSortedElemSet elements;
3936 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3938 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
3939 mesh_i->CreateGroupServants();
3941 if ( !myIsPreviewMode ) {
3942 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
3943 << theObject << ", "
3944 << theVector << ", "
3945 << theCopyGroups << ", '"
3946 << theMeshName << "' )";
3951 if (!myIsPreviewMode && mesh_i)
3952 mesh_i->GetGroups();
3954 return mesh._retn();
3957 //=======================================================================
3960 //=======================================================================
3962 SMESH::ListOfGroups*
3963 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
3964 const SMESH::AxisStruct & theAxis,
3965 CORBA::Double theAngle,
3966 CORBA::Boolean theCopy,
3968 ::SMESH_Mesh* theTargetMesh)
3972 if ( theTargetMesh )
3975 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3976 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3979 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
3981 TIDSortedElemSet copyElements;
3982 TIDSortedElemSet* workElements = &theElements;
3983 if ( myIsPreviewMode ) {
3984 TPreviewMesh * tmpMesh = getPreviewMesh();
3985 tmpMesh->Copy( theElements, copyElements );
3986 if ( !theCopy && !theTargetMesh )
3988 TIDSortedElemSet elemsAround, elemsAroundCopy;
3989 getElementsAround( theElements, getMeshDS(), elemsAround );
3990 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3992 workElements = ©Elements;
3993 theMakeGroups = false;
3996 ::SMESH_MeshEditor::PGroupIDs groupIds =
3997 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3999 if ( theCopy && !myIsPreviewMode)
4001 if ( theTargetMesh )
4003 theTargetMesh->GetMeshDS()->Modified();
4007 myMesh->GetMeshDS()->Modified();
4008 myMesh->SetIsModified( true );
4012 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4015 //=======================================================================
4018 //=======================================================================
4020 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
4021 const SMESH::AxisStruct & theAxis,
4022 CORBA::Double theAngle,
4023 CORBA::Boolean theCopy)
4025 if (!myIsPreviewMode) {
4026 TPythonDump() << this << ".Rotate( "
4027 << theIDsOfElements << ", "
4029 << TVar( theAngle ) << ", "
4032 if (theIDsOfElements.length() > 0)
4034 TIDSortedElemSet elements;
4035 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4036 rotate(elements,theAxis,theAngle,theCopy,false);
4040 //=======================================================================
4041 //function : RotateObject
4043 //=======================================================================
4045 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
4046 const SMESH::AxisStruct & theAxis,
4047 CORBA::Double theAngle,
4048 CORBA::Boolean theCopy)
4050 if ( !myIsPreviewMode ) {
4051 TPythonDump() << this << ".RotateObject( "
4052 << theObject << ", "
4054 << TVar( theAngle ) << ", "
4057 TIDSortedElemSet elements;
4058 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4059 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4060 rotate(elements,theAxis,theAngle,theCopy,false);
4063 //=======================================================================
4064 //function : RotateMakeGroups
4066 //=======================================================================
4068 SMESH::ListOfGroups*
4069 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
4070 const SMESH::AxisStruct& theAxis,
4071 CORBA::Double theAngle)
4073 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4075 SMESH::ListOfGroups * aGroups = 0;
4076 if (theIDsOfElements.length() > 0)
4078 TIDSortedElemSet elements;
4079 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4080 aGroups = rotate(elements,theAxis,theAngle,true,true);
4082 if (!myIsPreviewMode) {
4083 DumpGroupsList(aPythonDump, aGroups);
4084 aPythonDump << this << ".RotateMakeGroups( "
4085 << theIDsOfElements << ", "
4087 << TVar( theAngle ) << " )";
4092 //=======================================================================
4093 //function : RotateObjectMakeGroups
4095 //=======================================================================
4097 SMESH::ListOfGroups*
4098 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4099 const SMESH::AxisStruct& theAxis,
4100 CORBA::Double theAngle)
4102 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4104 SMESH::ListOfGroups * aGroups = 0;
4105 TIDSortedElemSet elements;
4106 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4107 aGroups = rotate(elements, theAxis, theAngle, true, true);
4109 if (!myIsPreviewMode) {
4110 DumpGroupsList(aPythonDump, aGroups);
4111 aPythonDump << this << ".RotateObjectMakeGroups( "
4112 << theObject << ", "
4114 << TVar( theAngle ) << " )";
4119 //=======================================================================
4120 //function : RotateMakeMesh
4122 //=======================================================================
4124 SMESH::SMESH_Mesh_ptr
4125 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
4126 const SMESH::AxisStruct& theAxis,
4127 CORBA::Double theAngleInRadians,
4128 CORBA::Boolean theCopyGroups,
4129 const char* theMeshName)
4131 SMESH::SMESH_Mesh_var mesh;
4132 SMESH_Mesh_i* mesh_i;
4134 { // open new scope to dump "MakeMesh" command
4135 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4137 TPythonDump pydump; // to prevent dump at mesh creation
4139 mesh = makeMesh( theMeshName );
4140 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4142 if ( mesh_i && theIDsOfElements.length() > 0 )
4144 TIDSortedElemSet elements;
4145 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4146 rotate(elements, theAxis, theAngleInRadians,
4147 false, theCopyGroups, & mesh_i->GetImpl());
4148 mesh_i->CreateGroupServants();
4150 if ( !myIsPreviewMode ) {
4151 pydump << mesh << " = " << this << ".RotateMakeMesh( "
4152 << theIDsOfElements << ", "
4154 << TVar( theAngleInRadians ) << ", "
4155 << theCopyGroups << ", '"
4156 << theMeshName << "' )";
4161 if (!myIsPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
4162 mesh_i->GetGroups();
4164 return mesh._retn();
4167 //=======================================================================
4168 //function : RotateObjectMakeMesh
4170 //=======================================================================
4172 SMESH::SMESH_Mesh_ptr
4173 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4174 const SMESH::AxisStruct& theAxis,
4175 CORBA::Double theAngleInRadians,
4176 CORBA::Boolean theCopyGroups,
4177 const char* theMeshName)
4179 SMESH::SMESH_Mesh_var mesh;
4180 SMESH_Mesh_i* mesh_i;
4182 {// open new scope to dump "MakeMesh" command
4183 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4185 TPythonDump pydump; // to prevent dump at mesh creation
4186 mesh = makeMesh( theMeshName );
4187 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4189 TIDSortedElemSet elements;
4191 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4193 rotate(elements, theAxis, theAngleInRadians,
4194 false, theCopyGroups, & mesh_i->GetImpl());
4195 mesh_i->CreateGroupServants();
4197 if ( !myIsPreviewMode ) {
4198 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
4199 << theObject << ", "
4201 << TVar( theAngleInRadians ) << ", "
4202 << theCopyGroups << ", '"
4203 << theMeshName << "' )";
4208 if (!myIsPreviewMode && mesh_i)
4209 mesh_i->GetGroups();
4211 return mesh._retn();
4214 //=======================================================================
4217 //=======================================================================
4219 SMESH::ListOfGroups*
4220 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
4221 const SMESH::PointStruct& thePoint,
4222 const SMESH::double_array& theScaleFact,
4223 CORBA::Boolean theCopy,
4225 ::SMESH_Mesh* theTargetMesh)
4228 if ( theScaleFact.length() < 1 )
4229 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
4230 if ( theScaleFact.length() == 2 )
4231 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
4233 if ( theTargetMesh )
4236 TIDSortedElemSet elements;
4237 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4238 if ( !idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4243 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
4244 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
4246 double tol = std::numeric_limits<double>::max();
4248 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
4249 0, S[1], 0, thePoint.y * (1-S[1]),
4250 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
4252 TIDSortedElemSet copyElements;
4253 TIDSortedElemSet* workElements = &elements;
4254 if ( myIsPreviewMode )
4256 TPreviewMesh * tmpMesh = getPreviewMesh();
4257 tmpMesh->Copy( elements, copyElements);
4258 if ( !theCopy && !theTargetMesh )
4260 TIDSortedElemSet elemsAround, elemsAroundCopy;
4261 getElementsAround( elements, getMeshDS(), elemsAround );
4262 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4264 workElements = & copyElements;
4265 theMakeGroups = false;
4268 ::SMESH_MeshEditor::PGroupIDs groupIds =
4269 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4271 if ( theCopy && !myIsPreviewMode )
4273 if ( theTargetMesh )
4275 theTargetMesh->GetMeshDS()->Modified();
4279 myMesh->GetMeshDS()->Modified();
4280 myMesh->SetIsModified( true );
4284 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4287 //=======================================================================
4290 //=======================================================================
4292 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
4293 const SMESH::PointStruct& thePoint,
4294 const SMESH::double_array& theScaleFact,
4295 CORBA::Boolean theCopy)
4297 if ( !myIsPreviewMode ) {
4298 TPythonDump() << this << ".Scale( "
4299 << theObject << ", "
4301 << TVar( theScaleFact ) << ", "
4304 scale(theObject, thePoint, theScaleFact, theCopy, false);
4308 //=======================================================================
4309 //function : ScaleMakeGroups
4311 //=======================================================================
4313 SMESH::ListOfGroups*
4314 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4315 const SMESH::PointStruct& thePoint,
4316 const SMESH::double_array& theScaleFact)
4318 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4320 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
4321 if (!myIsPreviewMode) {
4322 DumpGroupsList(aPythonDump, aGroups);
4323 aPythonDump << this << ".Scale("
4326 << TVar( theScaleFact ) << ",True,True)";
4332 //=======================================================================
4333 //function : ScaleMakeMesh
4335 //=======================================================================
4337 SMESH::SMESH_Mesh_ptr
4338 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4339 const SMESH::PointStruct& thePoint,
4340 const SMESH::double_array& theScaleFact,
4341 CORBA::Boolean theCopyGroups,
4342 const char* theMeshName)
4344 SMESH_Mesh_i* mesh_i;
4345 SMESH::SMESH_Mesh_var mesh;
4346 { // open new scope to dump "MakeMesh" command
4347 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4349 TPythonDump pydump; // to prevent dump at mesh creation
4350 mesh = makeMesh( theMeshName );
4351 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4355 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
4356 mesh_i->CreateGroupServants();
4358 if ( !myIsPreviewMode )
4359 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
4360 << theObject << ", "
4362 << TVar( theScaleFact ) << ", "
4363 << theCopyGroups << ", '"
4364 << theMeshName << "' )";
4368 if (!myIsPreviewMode && mesh_i)
4369 mesh_i->GetGroups();
4371 return mesh._retn();
4375 //=======================================================================
4376 //function : FindCoincidentNodes
4378 //=======================================================================
4380 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance,
4381 SMESH::array_of_long_array_out GroupsOfNodes)
4385 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4386 TIDSortedNodeSet nodes; // no input nodes
4387 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4389 GroupsOfNodes = new SMESH::array_of_long_array;
4390 GroupsOfNodes->length( aListOfListOfNodes.size() );
4391 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4392 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
4393 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4394 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4395 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4396 aGroup.length( aListOfNodes.size() );
4397 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4398 aGroup[ j ] = (*lIt)->GetID();
4400 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
4401 << Tolerance << " )";
4404 //=======================================================================
4405 //function : FindCoincidentNodesOnPart
4407 //=======================================================================
4408 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
4409 CORBA::Double Tolerance,
4410 SMESH::array_of_long_array_out GroupsOfNodes)
4414 TIDSortedNodeSet nodes;
4415 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4417 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4419 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4421 GroupsOfNodes = new SMESH::array_of_long_array;
4422 GroupsOfNodes->length( aListOfListOfNodes.size() );
4423 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4424 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4426 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4427 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4428 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4429 aGroup.length( aListOfNodes.size() );
4430 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4431 aGroup[ j ] = (*lIt)->GetID();
4433 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
4435 << Tolerance << " )";
4438 //================================================================================
4440 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
4441 * ExceptSubMeshOrGroups
4443 //================================================================================
4445 void SMESH_MeshEditor_i::
4446 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
4447 CORBA::Double theTolerance,
4448 SMESH::array_of_long_array_out theGroupsOfNodes,
4449 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups)
4453 TIDSortedNodeSet nodes;
4454 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4456 for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
4458 TIDSortedNodeSet exceptNodes;
4459 idSourceToNodeSet( theExceptSubMeshOrGroups[i], getMeshDS(), exceptNodes );
4460 TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
4461 for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
4462 nodes.erase( *avoidNode );
4464 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4466 getEditor().FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
4468 theGroupsOfNodes = new SMESH::array_of_long_array;
4469 theGroupsOfNodes->length( aListOfListOfNodes.size() );
4470 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4471 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4473 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4474 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4475 SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
4476 aGroup.length( aListOfNodes.size() );
4477 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4478 aGroup[ j ] = (*lIt)->GetID();
4480 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
4482 << theTolerance << ", "
4483 << theExceptSubMeshOrGroups << " )";
4486 //=======================================================================
4487 //function : MergeNodes
4489 //=======================================================================
4491 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
4495 SMESHDS_Mesh* aMesh = getMeshDS();
4497 TPythonDump aTPythonDump;
4498 aTPythonDump << this << ".MergeNodes([";
4499 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4500 for (int i = 0; i < GroupsOfNodes.length(); i++)
4502 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
4503 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
4504 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
4505 for ( int j = 0; j < aNodeGroup.length(); j++ )
4507 CORBA::Long index = aNodeGroup[ j ];
4508 const SMDS_MeshNode * node = aMesh->FindNode(index);
4510 aListOfNodes.push_back( node );
4512 if ( aListOfNodes.size() < 2 )
4513 aListOfListOfNodes.pop_back();
4515 if ( i > 0 ) aTPythonDump << ", ";
4516 aTPythonDump << aNodeGroup;
4518 getEditor().MergeNodes( aListOfListOfNodes );
4520 aTPythonDump << "])";
4521 myMesh->GetMeshDS()->Modified();
4522 myMesh->SetIsModified( true );
4525 //=======================================================================
4526 //function : FindEqualElements
4528 //=======================================================================
4529 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
4530 SMESH::array_of_long_array_out GroupsOfElementsID)
4534 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
4535 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
4537 TIDSortedElemSet elems;
4538 idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true);
4540 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4541 getEditor().FindEqualElements( elems, aListOfListOfElementsID );
4543 GroupsOfElementsID = new SMESH::array_of_long_array;
4544 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
4546 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt =
4547 aListOfListOfElementsID.begin();
4548 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j)
4550 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
4551 list<int>& listOfIDs = *arraysIt;
4552 aGroup.length( listOfIDs.size() );
4553 list<int>::iterator idIt = listOfIDs.begin();
4554 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k )
4555 aGroup[ k ] = *idIt;
4558 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
4563 //=======================================================================
4564 //function : MergeElements
4566 //=======================================================================
4568 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
4572 TPythonDump aTPythonDump;
4573 aTPythonDump << this << ".MergeElements( [";
4575 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4577 for (int i = 0; i < GroupsOfElementsID.length(); i++) {
4578 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
4579 aListOfListOfElementsID.push_back( list< int >() );
4580 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
4581 for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
4582 CORBA::Long id = anElemsIDGroup[ j ];
4583 aListOfElemsID.push_back( id );
4585 if ( aListOfElemsID.size() < 2 )
4586 aListOfListOfElementsID.pop_back();
4587 if ( i > 0 ) aTPythonDump << ", ";
4588 aTPythonDump << anElemsIDGroup;
4591 getEditor().MergeElements(aListOfListOfElementsID);
4592 myMesh->GetMeshDS()->Modified();
4593 myMesh->SetIsModified( true );
4595 aTPythonDump << "] )";
4598 //=======================================================================
4599 //function : MergeEqualElements
4601 //=======================================================================
4603 void SMESH_MeshEditor_i::MergeEqualElements()
4607 getEditor().MergeEqualElements();
4609 myMesh->GetMeshDS()->Modified();
4611 TPythonDump() << this << ".MergeEqualElements()";
4614 //=============================================================================
4616 * Move the node to a given point
4618 //=============================================================================
4620 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
4625 initData(/*deleteSearchers=*/false);
4627 const SMDS_MeshNode * node = getMeshDS()->FindNode( NodeID );
4631 if ( theNodeSearcher )
4632 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4634 if ( myIsPreviewMode ) // make preview data
4636 // in a preview mesh, make edges linked to a node
4637 TPreviewMesh& tmpMesh = *getPreviewMesh();
4638 TIDSortedElemSet linkedNodes;
4639 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4640 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4641 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
4642 for ( ; nIt != linkedNodes.end(); ++nIt )
4644 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
4645 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
4649 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
4650 // fill preview data
4652 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4653 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4655 getMeshDS()->MoveNode(node, x, y, z);
4657 if ( !myIsPreviewMode )
4659 // Update Python script
4660 TPythonDump() << "isDone = " << this << ".MoveNode( "
4661 << NodeID << ", " << TVar(x) << ", " << TVar(y) << ", " << TVar(z) << " )";
4662 myMesh->GetMeshDS()->Modified();
4663 myMesh->SetIsModified( true );
4669 //================================================================================
4671 * \brief Return ID of node closest to a given point
4673 //================================================================================
4675 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
4679 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4681 if ( !theNodeSearcher ) {
4682 theNodeSearcher = myEditor.GetNodeSearcher();
4685 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
4686 return node->GetID();
4691 //================================================================================
4693 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
4694 * move the node closest to the point to point's location and return ID of the node
4696 //================================================================================
4698 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
4701 CORBA::Long theNodeID)
4703 // We keep theNodeSearcher until any mesh modification:
4704 // 1) initData() deletes theNodeSearcher at any edition,
4705 // 2) TSearchersDeleter - at any mesh compute event and mesh change
4707 initData(/*deleteSearchers=*/false);
4709 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4711 int nodeID = theNodeID;
4712 const SMDS_MeshNode* node = getMeshDS()->FindNode( nodeID );
4713 if ( !node ) // preview moving node
4715 if ( !theNodeSearcher ) {
4716 theNodeSearcher = myEditor.GetNodeSearcher();
4719 node = theNodeSearcher->FindClosestTo( p );
4722 nodeID = node->GetID();
4723 if ( myIsPreviewMode ) // make preview data
4725 // in a preview mesh, make edges linked to a node
4726 TPreviewMesh tmpMesh = *getPreviewMesh();
4727 TIDSortedElemSet linkedNodes;
4728 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4729 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4730 for ( ; nIt != linkedNodes.end(); ++nIt )
4732 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
4733 tmpMesh.Copy( &edge );
4736 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
4738 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
4739 // fill preview data
4741 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4743 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4747 getMeshDS()->MoveNode(node, x, y, z);
4751 if ( !myIsPreviewMode )
4753 TPythonDump() << "nodeID = " << this
4754 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
4755 << ", " << nodeID << " )";
4757 myMesh->GetMeshDS()->Modified();
4758 myMesh->SetIsModified( true );
4764 //=======================================================================
4766 * Return elements of given type where the given point is IN or ON.
4768 * 'ALL' type means elements of any type excluding nodes
4770 //=======================================================================
4772 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
4775 SMESH::ElementType type)
4777 SMESH::long_array_var res = new SMESH::long_array;
4778 vector< const SMDS_MeshElement* > foundElems;
4780 theSearchersDeleter.Set( myMesh );
4781 if ( !theElementSearcher ) {
4782 theElementSearcher = myEditor.GetElementSearcher();
4784 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4785 SMDSAbs_ElementType( type ),
4787 res->length( foundElems.size() );
4788 for ( int i = 0; i < foundElems.size(); ++i )
4789 res[i] = foundElems[i]->GetID();
4791 if ( !myIsPreviewMode ) // call from tui
4792 TPythonDump() << "res = " << this << ".FindElementsByPoint( "
4801 //=======================================================================
4802 //function : FindAmongElementsByPoint
4803 //purpose : Searching among the given elements, return elements of given type
4804 // where the given point is IN or ON.
4805 // 'ALL' type means elements of any type excluding nodes
4806 //=======================================================================
4809 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
4813 SMESH::ElementType type)
4815 SMESH::long_array_var res = new SMESH::long_array;
4817 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
4818 if ( types->length() == 1 && // a part contains only nodes or 0D elements
4819 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) &&
4820 type != types[0] ) // but search of elements of dim > 0
4823 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
4824 return FindElementsByPoint( x,y,z, type );
4826 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
4828 theSearchersDeleter.Set( myMesh, getPartIOR( elementIDs, type ));
4829 if ( !theElementSearcher )
4831 // create a searcher from elementIDs
4832 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
4833 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
4835 if ( !idSourceToSet( elementIDs, meshDS, elements,
4836 SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
4839 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
4840 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
4842 theElementSearcher = myEditor.GetElementSearcher(elemsIt);
4845 vector< const SMDS_MeshElement* > foundElems;
4847 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4848 SMDSAbs_ElementType( type ),
4850 res->length( foundElems.size() );
4851 for ( int i = 0; i < foundElems.size(); ++i )
4852 res[i] = foundElems[i]->GetID();
4854 if ( !myIsPreviewMode ) // call from tui
4855 TPythonDump() << "res = " << this << ".FindAmongElementsByPoint( "
4856 << elementIDs << ", "
4865 //=======================================================================
4866 //function : GetPointState
4867 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
4868 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
4869 //=======================================================================
4871 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
4875 theSearchersDeleter.Set( myMesh );
4876 if ( !theElementSearcher ) {
4877 theElementSearcher = myEditor.GetElementSearcher();
4879 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
4882 //=======================================================================
4883 //function : convError
4885 //=======================================================================
4887 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
4889 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
4893 RETCASE( SEW_BORDER1_NOT_FOUND );
4894 RETCASE( SEW_BORDER2_NOT_FOUND );
4895 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
4896 RETCASE( SEW_BAD_SIDE_NODES );
4897 RETCASE( SEW_VOLUMES_TO_SPLIT );
4898 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
4899 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
4900 RETCASE( SEW_BAD_SIDE1_NODES );
4901 RETCASE( SEW_BAD_SIDE2_NODES );
4903 return SMESH::SMESH_MeshEditor::SEW_OK;
4906 //=======================================================================
4907 //function : SewFreeBorders
4909 //=======================================================================
4911 SMESH::SMESH_MeshEditor::Sew_Error
4912 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
4913 CORBA::Long SecondNodeID1,
4914 CORBA::Long LastNodeID1,
4915 CORBA::Long FirstNodeID2,
4916 CORBA::Long SecondNodeID2,
4917 CORBA::Long LastNodeID2,
4918 CORBA::Boolean CreatePolygons,
4919 CORBA::Boolean CreatePolyedrs)
4923 SMESHDS_Mesh* aMesh = getMeshDS();
4925 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4926 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4927 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4928 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4929 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4930 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
4932 if (!aBorderFirstNode ||
4933 !aBorderSecondNode||
4935 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4936 if (!aSide2FirstNode ||
4937 !aSide2SecondNode ||
4939 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4941 TPythonDump() << "error = " << this << ".SewFreeBorders( "
4942 << FirstNodeID1 << ", "
4943 << SecondNodeID1 << ", "
4944 << LastNodeID1 << ", "
4945 << FirstNodeID2 << ", "
4946 << SecondNodeID2 << ", "
4947 << LastNodeID2 << ", "
4948 << CreatePolygons<< ", "
4949 << CreatePolyedrs<< " )";
4951 SMESH::SMESH_MeshEditor::Sew_Error error =
4952 convError( getEditor().SewFreeBorder (aBorderFirstNode,
4963 myMesh->GetMeshDS()->Modified();
4964 myMesh->SetIsModified( true );
4970 //=======================================================================
4971 //function : SewConformFreeBorders
4973 //=======================================================================
4975 SMESH::SMESH_MeshEditor::Sew_Error
4976 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
4977 CORBA::Long SecondNodeID1,
4978 CORBA::Long LastNodeID1,
4979 CORBA::Long FirstNodeID2,
4980 CORBA::Long SecondNodeID2)
4984 SMESHDS_Mesh* aMesh = getMeshDS();
4986 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4987 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4988 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4989 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4990 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4991 const SMDS_MeshNode* aSide2ThirdNode = 0;
4993 if (!aBorderFirstNode ||
4994 !aBorderSecondNode||
4996 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4997 if (!aSide2FirstNode ||
4999 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
5001 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
5002 << FirstNodeID1 << ", "
5003 << SecondNodeID1 << ", "
5004 << LastNodeID1 << ", "
5005 << FirstNodeID2 << ", "
5006 << SecondNodeID2 << " )";
5008 SMESH::SMESH_MeshEditor::Sew_Error error =
5009 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5019 myMesh->GetMeshDS()->Modified();
5020 myMesh->SetIsModified( true );
5026 //=======================================================================
5027 //function : SewBorderToSide
5029 //=======================================================================
5031 SMESH::SMESH_MeshEditor::Sew_Error
5032 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
5033 CORBA::Long SecondNodeIDOnFreeBorder,
5034 CORBA::Long LastNodeIDOnFreeBorder,
5035 CORBA::Long FirstNodeIDOnSide,
5036 CORBA::Long LastNodeIDOnSide,
5037 CORBA::Boolean CreatePolygons,
5038 CORBA::Boolean CreatePolyedrs)
5042 SMESHDS_Mesh* aMesh = getMeshDS();
5044 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
5045 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
5046 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
5047 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
5048 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
5049 const SMDS_MeshNode* aSide2ThirdNode = 0;
5051 if (!aBorderFirstNode ||
5052 !aBorderSecondNode||
5054 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5055 if (!aSide2FirstNode ||
5057 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
5059 TPythonDump() << "error = " << this << ".SewBorderToSide( "
5060 << FirstNodeIDOnFreeBorder << ", "
5061 << SecondNodeIDOnFreeBorder << ", "
5062 << LastNodeIDOnFreeBorder << ", "
5063 << FirstNodeIDOnSide << ", "
5064 << LastNodeIDOnSide << ", "
5065 << CreatePolygons << ", "
5066 << CreatePolyedrs << ") ";
5068 SMESH::SMESH_MeshEditor::Sew_Error error =
5069 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5080 myMesh->GetMeshDS()->Modified();
5081 myMesh->SetIsModified( true );
5087 //=======================================================================
5088 //function : SewSideElements
5090 //=======================================================================
5092 SMESH::SMESH_MeshEditor::Sew_Error
5093 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
5094 const SMESH::long_array& IDsOfSide2Elements,
5095 CORBA::Long NodeID1OfSide1ToMerge,
5096 CORBA::Long NodeID1OfSide2ToMerge,
5097 CORBA::Long NodeID2OfSide1ToMerge,
5098 CORBA::Long NodeID2OfSide2ToMerge)
5102 SMESHDS_Mesh* aMesh = getMeshDS();
5104 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
5105 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
5106 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
5107 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
5109 if (!aFirstNode1ToMerge ||
5110 !aFirstNode2ToMerge )
5111 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
5112 if (!aSecondNode1ToMerge||
5113 !aSecondNode2ToMerge)
5114 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
5116 TIDSortedElemSet aSide1Elems, aSide2Elems;
5117 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
5118 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
5120 TPythonDump() << "error = " << this << ".SewSideElements( "
5121 << IDsOfSide1Elements << ", "
5122 << IDsOfSide2Elements << ", "
5123 << NodeID1OfSide1ToMerge << ", "
5124 << NodeID1OfSide2ToMerge << ", "
5125 << NodeID2OfSide1ToMerge << ", "
5126 << NodeID2OfSide2ToMerge << ")";
5128 SMESH::SMESH_MeshEditor::Sew_Error error =
5129 convError( getEditor().SewSideElements (aSide1Elems, aSide2Elems,
5132 aSecondNode1ToMerge,
5133 aSecondNode2ToMerge));
5136 myMesh->GetMeshDS()->Modified();
5137 myMesh->SetIsModified( true );
5142 //================================================================================
5144 * \brief Set new nodes for given element
5145 * \param ide - element id
5146 * \param newIDs - new node ids
5147 * \retval CORBA::Boolean - true if result is OK
5149 //================================================================================
5151 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
5152 const SMESH::long_array& newIDs)
5156 const SMDS_MeshElement* elem = getMeshDS()->FindElement(ide);
5157 if(!elem) return false;
5159 int nbn = newIDs.length();
5161 vector<const SMDS_MeshNode*> aNodes(nbn);
5164 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(newIDs[i]);
5167 aNodes[nbn1] = aNode;
5170 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
5171 << ide << ", " << newIDs << " )";
5173 MESSAGE("ChangeElementNodes");
5174 bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
5176 myMesh->GetMeshDS()->Modified();
5178 myMesh->SetIsModified( true );
5183 //=======================================================================
5184 //function : ConvertToQuadratic
5186 //=======================================================================
5188 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
5190 getEditor().ConvertToQuadratic(theForce3d);
5191 TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )";
5192 myMesh->GetMeshDS()->Modified();
5193 myMesh->SetIsModified( true );
5196 //=======================================================================
5197 //function : ConvertFromQuadratic
5199 //=======================================================================
5201 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
5203 CORBA::Boolean isDone = getEditor().ConvertFromQuadratic();
5204 TPythonDump() << this << ".ConvertFromQuadratic()";
5205 myMesh->GetMeshDS()->Modified();
5207 myMesh->SetIsModified( true );
5210 //================================================================================
5212 * \brief Makes a part of the mesh quadratic
5214 //================================================================================
5216 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
5217 SMESH::SMESH_IDSource_ptr theObject)
5218 throw (SALOME::SALOME_Exception)
5220 Unexpect aCatch(SALOME_SalomeException);
5222 TIDSortedElemSet elems;
5223 if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5225 if ( elems.empty() )
5227 ConvertToQuadratic( theForce3d );
5229 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5231 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5235 getEditor().ConvertToQuadratic(theForce3d, elems);
5238 myMesh->GetMeshDS()->Modified();
5239 myMesh->SetIsModified( true );
5241 pyDump << this << ".ConvertToQuadraticObject( "<<theForce3d<<", "<<theObject<<" )";
5244 //================================================================================
5246 * \brief Makes a part of the mesh linear
5248 //================================================================================
5250 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
5251 throw (SALOME::SALOME_Exception)
5253 Unexpect aCatch(SALOME_SalomeException);
5255 TIDSortedElemSet elems;
5256 if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5258 if ( elems.empty() )
5260 ConvertFromQuadratic();
5262 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5264 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5268 getEditor().ConvertFromQuadratic(elems);
5271 myMesh->GetMeshDS()->Modified();
5272 myMesh->SetIsModified( true );
5274 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
5277 //=======================================================================
5278 //function : makeMesh
5279 //purpose : create a named imported mesh
5280 //=======================================================================
5282 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
5284 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
5285 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
5286 SALOMEDS::Study_var study = gen->GetCurrentStudy();
5287 SALOMEDS::SObject_var meshSO = gen->ObjectToSObject( study, mesh );
5288 gen->SetName( meshSO, theMeshName, "Mesh" );
5289 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
5291 return mesh._retn();
5294 //=======================================================================
5295 //function : DumpGroupsList
5297 //=======================================================================
5298 void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump & theDumpPython,
5299 const SMESH::ListOfGroups * theGroupList)
5301 bool isDumpGroupList = theGroupList && theGroupList->length() > 0;
5302 if(isDumpGroupList) {
5303 theDumpPython << theGroupList << " = ";
5307 //================================================================================
5309 \brief Generates the unique group name.
5310 \param thePrefix name prefix
5313 //================================================================================
5314 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
5316 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5317 set<string> groupNames;
5319 // Get existing group names
5320 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
5321 SMESH::SMESH_GroupBase_var aGroup = groups[i];
5322 if (CORBA::is_nil(aGroup))
5325 CORBA::String_var name = aGroup->GetName();
5326 groupNames.insert( name.in() );
5330 string name = thePrefix;
5333 while (!groupNames.insert(name).second)
5334 name = SMESH_Comment( thePrefix ) << "_" << index;
5339 //================================================================================
5341 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5342 \param theNodes - identifiers of nodes to be doubled
5343 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
5344 nodes. If list of element identifiers is empty then nodes are doubled but
5345 they not assigned to elements
5346 \return TRUE if operation has been completed successfully, FALSE otherwise
5347 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
5349 //================================================================================
5351 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
5352 const SMESH::long_array& theModifiedElems )
5356 list< int > aListOfNodes;
5358 for ( i = 0, n = theNodes.length(); i < n; i++ )
5359 aListOfNodes.push_back( theNodes[ i ] );
5361 list< int > aListOfElems;
5362 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5363 aListOfElems.push_back( theModifiedElems[ i ] );
5365 bool aResult = getEditor().DoubleNodes( aListOfNodes, aListOfElems );
5367 myMesh->GetMeshDS()->Modified();
5369 myMesh->SetIsModified( true );
5371 // Update Python script
5372 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
5377 //================================================================================
5379 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5380 This method provided for convenience works as DoubleNodes() described above.
5381 \param theNodeId - identifier of node to be doubled.
5382 \param theModifiedElems - identifiers of elements to be updated.
5383 \return TRUE if operation has been completed successfully, FALSE otherwise
5384 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
5386 //================================================================================
5388 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
5389 const SMESH::long_array& theModifiedElems )
5391 SMESH::long_array_var aNodes = new SMESH::long_array;
5392 aNodes->length( 1 );
5393 aNodes[ 0 ] = theNodeId;
5395 TPythonDump pyDump; // suppress dump by the next line
5397 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
5399 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
5404 //================================================================================
5406 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5407 This method provided for convenience works as DoubleNodes() described above.
5408 \param theNodes - group of nodes to be doubled.
5409 \param theModifiedElems - group of elements to be updated.
5410 \return TRUE if operation has been completed successfully, FALSE otherwise
5411 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
5413 //================================================================================
5415 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
5416 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5418 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5421 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5422 SMESH::long_array_var aModifiedElems;
5423 if ( !CORBA::is_nil( theModifiedElems ) )
5424 aModifiedElems = theModifiedElems->GetListOfID();
5427 aModifiedElems = new SMESH::long_array;
5428 aModifiedElems->length( 0 );
5431 TPythonDump pyDump; // suppress dump by the next line
5433 bool done = DoubleNodes( aNodes, aModifiedElems );
5435 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
5441 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5442 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
5443 * \param theNodes - group of nodes to be doubled.
5444 * \param theModifiedElems - group of elements to be updated.
5445 * \return a new group with newly created nodes
5446 * \sa DoubleNodeGroup()
5448 SMESH::SMESH_Group_ptr
5449 SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
5450 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5452 SMESH::SMESH_Group_var aNewGroup;
5454 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5455 return aNewGroup._retn();
5458 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5459 SMESH::long_array_var aModifiedElems;
5460 if ( !CORBA::is_nil( theModifiedElems ) )
5461 aModifiedElems = theModifiedElems->GetListOfID();
5463 aModifiedElems = new SMESH::long_array;
5464 aModifiedElems->length( 0 );
5467 TPythonDump pyDump; // suppress dump by the next line
5469 bool aResult = DoubleNodes( aNodes, aModifiedElems );
5472 // Create group with newly created nodes
5473 SMESH::long_array_var anIds = GetLastCreatedNodes();
5474 if (anIds->length() > 0) {
5475 string anUnindexedName (theNodes->GetName());
5476 string aNewName = generateGroupName(anUnindexedName + "_double");
5477 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5478 aNewGroup->Add(anIds);
5479 pyDump << aNewGroup << " = ";
5483 pyDump << this << ".DoubleNodeGroupNew( " << theNodes << ", "
5484 << theModifiedElems << " )";
5486 return aNewGroup._retn();
5489 //================================================================================
5491 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5492 This method provided for convenience works as DoubleNodes() described above.
5493 \param theNodes - list of groups of nodes to be doubled
5494 \param theModifiedElems - list of groups of elements to be updated.
5495 \return TRUE if operation has been completed successfully, FALSE otherwise
5496 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
5498 //================================================================================
5500 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
5501 const SMESH::ListOfGroups& theModifiedElems )
5506 std::list< int > aNodes;
5508 for ( i = 0, n = theNodes.length(); i < n; i++ )
5510 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
5511 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
5513 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5514 for ( j = 0, m = aCurr->length(); j < m; j++ )
5515 aNodes.push_back( aCurr[ j ] );
5519 std::list< int > anElems;
5520 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5522 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
5523 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
5525 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5526 for ( j = 0, m = aCurr->length(); j < m; j++ )
5527 anElems.push_back( aCurr[ j ] );
5531 bool aResult = getEditor().DoubleNodes( aNodes, anElems );
5534 myMesh->GetMeshDS()->Modified();
5536 myMesh->SetIsModified( true );
5539 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
5544 //================================================================================
5546 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5547 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
5548 * \param theNodes - group of nodes to be doubled.
5549 * \param theModifiedElems - group of elements to be updated.
5550 * \return a new group with newly created nodes
5551 * \sa DoubleNodeGroups()
5553 //================================================================================
5555 SMESH::SMESH_Group_ptr
5556 SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
5557 const SMESH::ListOfGroups& theModifiedElems )
5559 SMESH::SMESH_Group_var aNewGroup;
5561 TPythonDump pyDump; // suppress dump by the next line
5563 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
5567 // Create group with newly created nodes
5568 SMESH::long_array_var anIds = GetLastCreatedNodes();
5569 if (anIds->length() > 0) {
5570 string anUnindexedName (theNodes[0]->GetName());
5571 string aNewName = generateGroupName(anUnindexedName + "_double");
5572 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5573 aNewGroup->Add(anIds);
5574 pyDump << aNewGroup << " = ";
5578 pyDump << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
5579 << theModifiedElems << " )";
5581 return aNewGroup._retn();
5585 //================================================================================
5587 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5588 \param theElems - the list of elements (edges or faces) to be replicated
5589 The nodes for duplication could be found from these elements
5590 \param theNodesNot - list of nodes to NOT replicate
5591 \param theAffectedElems - the list of elements (cells and edges) to which the
5592 replicated nodes should be associated to.
5593 \return TRUE if operation has been completed successfully, FALSE otherwise
5594 \sa DoubleNodeGroup(), DoubleNodeGroups()
5596 //================================================================================
5598 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
5599 const SMESH::long_array& theNodesNot,
5600 const SMESH::long_array& theAffectedElems )
5606 SMESHDS_Mesh* aMeshDS = getMeshDS();
5607 TIDSortedElemSet anElems, aNodes, anAffected;
5608 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5609 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5610 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
5612 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5615 myMesh->GetMeshDS()->Modified();
5617 myMesh->SetIsModified( true );
5619 // Update Python script
5620 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
5621 << theNodesNot << ", " << theAffectedElems << " )";
5625 //================================================================================
5627 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5628 \param theElems - the list of elements (edges or faces) to be replicated
5629 The nodes for duplication could be found from these elements
5630 \param theNodesNot - list of nodes to NOT replicate
5631 \param theShape - shape to detect affected elements (element which geometric center
5632 located on or inside shape).
5633 The replicated nodes should be associated to affected elements.
5634 \return TRUE if operation has been completed successfully, FALSE otherwise
5635 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
5637 //================================================================================
5639 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
5640 const SMESH::long_array& theNodesNot,
5641 GEOM::GEOM_Object_ptr theShape )
5647 SMESHDS_Mesh* aMeshDS = getMeshDS();
5648 TIDSortedElemSet anElems, aNodes;
5649 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5650 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5652 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5653 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
5656 myMesh->GetMeshDS()->Modified();
5658 myMesh->SetIsModified( true );
5660 // Update Python script
5661 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
5662 << theNodesNot << ", " << theShape << " )";
5666 //================================================================================
5668 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5669 \param theElems - group of of elements (edges or faces) to be replicated
5670 \param theNodesNot - group of nodes not to replicated
5671 \param theAffectedElems - group of elements to which the replicated nodes
5672 should be associated to.
5673 \return TRUE if operation has been completed successfully, FALSE otherwise
5674 \sa DoubleNodes(), DoubleNodeGroups()
5676 //================================================================================
5678 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
5679 SMESH::SMESH_GroupBase_ptr theNodesNot,
5680 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5682 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5688 SMESHDS_Mesh* aMeshDS = getMeshDS();
5689 TIDSortedElemSet anElems, aNodes, anAffected;
5690 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5691 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5692 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5694 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5697 myMesh->GetMeshDS()->Modified();
5699 myMesh->SetIsModified( true );
5701 // Update Python script
5702 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
5703 << theNodesNot << ", " << theAffectedElems << " )";
5708 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5709 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
5710 * \param theElems - group of of elements (edges or faces) to be replicated
5711 * \param theNodesNot - group of nodes not to replicated
5712 * \param theAffectedElems - group of elements to which the replicated nodes
5713 * should be associated to.
5714 * \return a new group with newly created elements
5715 * \sa DoubleNodeElemGroup()
5717 SMESH::SMESH_Group_ptr
5718 SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
5719 SMESH::SMESH_GroupBase_ptr theNodesNot,
5720 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5723 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroup2New( theElems,
5727 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
5728 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
5730 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupNew( "
5732 << theNodesNot << ", "
5733 << theAffectedElems << " )";
5735 return elemGroup._retn();
5738 SMESH::ListOfGroups*
5739 SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
5740 SMESH::SMESH_GroupBase_ptr theNodesNot,
5741 SMESH::SMESH_GroupBase_ptr theAffectedElems,
5742 CORBA::Boolean theElemGroupNeeded,
5743 CORBA::Boolean theNodeGroupNeeded)
5745 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
5746 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
5747 aTwoGroups->length( 2 );
5749 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5750 return aTwoGroups._retn();
5755 SMESHDS_Mesh* aMeshDS = getMeshDS();
5756 TIDSortedElemSet anElems, aNodes, anAffected;
5757 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5758 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5759 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5762 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5764 myMesh->GetMeshDS()->Modified();
5770 myMesh->SetIsModified( true );
5772 // Create group with newly created elements
5773 CORBA::String_var elemGroupName = theElems->GetName();
5774 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
5775 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
5777 SMESH::long_array_var anIds = GetLastCreatedElems();
5778 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5779 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5780 aNewElemGroup->Add(anIds);
5782 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
5784 SMESH::long_array_var anIds = GetLastCreatedNodes();
5785 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5786 aNewNodeGroup->Add(anIds);
5790 // Update Python script
5793 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
5794 else pyDump << aNewElemGroup << ", ";
5795 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
5796 else pyDump << aNewNodeGroup << " ] = ";
5798 pyDump << this << ".DoubleNodeElemGroup2New( " << theElems << ", "
5799 << theNodesNot << ", "
5800 << theAffectedElems << ", "
5801 << theElemGroupNeeded << ", "
5802 << theNodeGroupNeeded <<" )";
5804 aTwoGroups[0] = aNewElemGroup._retn();
5805 aTwoGroups[1] = aNewNodeGroup._retn();
5806 return aTwoGroups._retn();
5809 //================================================================================
5811 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5812 \param theElems - group of of elements (edges or faces) to be replicated
5813 \param theNodesNot - group of nodes not to replicated
5814 \param theShape - shape to detect affected elements (element which geometric center
5815 located on or inside shape).
5816 The replicated nodes should be associated to affected elements.
5817 \return TRUE if operation has been completed successfully, FALSE otherwise
5818 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
5820 //================================================================================
5822 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
5823 SMESH::SMESH_GroupBase_ptr theNodesNot,
5824 GEOM::GEOM_Object_ptr theShape )
5827 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5833 SMESHDS_Mesh* aMeshDS = getMeshDS();
5834 TIDSortedElemSet anElems, aNodes, anAffected;
5835 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5836 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5838 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5839 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
5842 myMesh->GetMeshDS()->Modified();
5844 myMesh->SetIsModified( true );
5846 // Update Python script
5847 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
5848 << theNodesNot << ", " << theShape << " )";
5852 //================================================================================
5854 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5855 This method provided for convenience works as DoubleNodes() described above.
5856 \param theElems - list of groups of elements (edges or faces) to be replicated
5857 \param theNodesNot - list of groups of nodes not to replicated
5858 \param theAffectedElems - group of elements to which the replicated nodes
5859 should be associated to.
5860 \return TRUE if operation has been completed successfully, FALSE otherwise
5861 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
5863 //================================================================================
5865 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
5866 SMESHDS_Mesh* theMeshDS,
5867 TIDSortedElemSet& theElemSet,
5868 const bool theIsNodeGrp)
5870 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
5872 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
5873 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
5874 : aGrp->GetType() != SMESH::NODE ) )
5876 SMESH::long_array_var anIDs = aGrp->GetIDs();
5877 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
5882 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
5883 const SMESH::ListOfGroups& theNodesNot,
5884 const SMESH::ListOfGroups& theAffectedElems)
5889 SMESHDS_Mesh* aMeshDS = getMeshDS();
5890 TIDSortedElemSet anElems, aNodes, anAffected;
5891 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5892 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5893 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5895 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5898 myMesh->GetMeshDS()->Modified();
5900 myMesh->SetIsModified( true );
5902 // Update Python script
5903 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
5904 << &theNodesNot << ", " << &theAffectedElems << " )";
5908 //================================================================================
5910 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5911 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
5912 \param theElems - list of groups of elements (edges or faces) to be replicated
5913 \param theNodesNot - list of groups of nodes not to replicated
5914 \param theAffectedElems - group of elements to which the replicated nodes
5915 should be associated to.
5916 * \return a new group with newly created elements
5917 * \sa DoubleNodeElemGroups()
5919 //================================================================================
5921 SMESH::SMESH_Group_ptr
5922 SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
5923 const SMESH::ListOfGroups& theNodesNot,
5924 const SMESH::ListOfGroups& theAffectedElems)
5927 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroups2New( theElems,
5931 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
5932 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
5934 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupsNew( "
5936 << theNodesNot << ", "
5937 << theAffectedElems << " )";
5939 return elemGroup._retn();
5942 SMESH::ListOfGroups*
5943 SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems,
5944 const SMESH::ListOfGroups& theNodesNot,
5945 const SMESH::ListOfGroups& theAffectedElems,
5946 CORBA::Boolean theElemGroupNeeded,
5947 CORBA::Boolean theNodeGroupNeeded)
5949 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
5950 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
5951 aTwoGroups->length( 2 );
5956 SMESHDS_Mesh* aMeshDS = getMeshDS();
5957 TIDSortedElemSet anElems, aNodes, anAffected;
5958 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5959 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5960 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5962 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5965 myMesh->GetMeshDS()->Modified();
5969 myMesh->SetIsModified( true );
5971 // Create group with newly created elements
5972 CORBA::String_var elemGroupName = theElems[0]->GetName();
5973 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
5974 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
5976 SMESH::long_array_var anIds = GetLastCreatedElems();
5977 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5978 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5979 aNewElemGroup->Add(anIds);
5981 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
5983 SMESH::long_array_var anIds = GetLastCreatedNodes();
5984 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5985 aNewNodeGroup->Add(anIds);
5989 // Update Python script
5992 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
5993 else pyDump << aNewElemGroup << ", ";
5994 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
5995 else pyDump << aNewNodeGroup << " ] = ";
5997 pyDump << this << ".DoubleNodeElemGroups2New( " << &theElems << ", "
5998 << &theNodesNot << ", "
5999 << &theAffectedElems << ", "
6000 << theElemGroupNeeded << ", "
6001 << theNodeGroupNeeded << " )";
6003 aTwoGroups[0] = aNewElemGroup._retn();
6004 aTwoGroups[1] = aNewNodeGroup._retn();
6005 return aTwoGroups._retn();
6008 //================================================================================
6010 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6011 This method provided for convenience works as DoubleNodes() described above.
6012 \param theElems - list of groups of elements (edges or faces) to be replicated
6013 \param theNodesNot - list of groups of nodes not to replicated
6014 \param theShape - shape to detect affected elements (element which geometric center
6015 located on or inside shape).
6016 The replicated nodes should be associated to affected elements.
6017 \return TRUE if operation has been completed successfully, FALSE otherwise
6018 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
6020 //================================================================================
6023 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
6024 const SMESH::ListOfGroups& theNodesNot,
6025 GEOM::GEOM_Object_ptr theShape )
6030 SMESHDS_Mesh* aMeshDS = getMeshDS();
6031 TIDSortedElemSet anElems, aNodes;
6032 listOfGroupToSet(theElems, aMeshDS, anElems,false );
6033 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6035 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6036 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6039 myMesh->GetMeshDS()->Modified();
6041 myMesh->SetIsModified( true );
6043 // Update Python script
6044 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
6045 << &theNodesNot << ", " << theShape << " )";
6049 //================================================================================
6051 \brief Identify the elements that will be affected by node duplication (actual duplication is not performed.
6052 This method is the first step of DoubleNodeElemGroupsInRegion.
6053 \param theElems - list of groups of elements (edges or faces) to be replicated
6054 \param theNodesNot - list of groups of nodes not to replicated
6055 \param theShape - shape to detect affected elements (element which geometric center
6056 located on or inside shape).
6057 The replicated nodes should be associated to affected elements.
6058 \return groups of affected elements
6059 \sa DoubleNodeElemGroupsInRegion()
6061 //================================================================================
6062 SMESH::ListOfGroups*
6063 SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theElems,
6064 const SMESH::ListOfGroups& theNodesNot,
6065 GEOM::GEOM_Object_ptr theShape )
6067 MESSAGE("AffectedElemGroupsInRegion");
6068 SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
6069 bool isEdgeGroup = false;
6070 bool isFaceGroup = false;
6071 bool isVolumeGroup = false;
6072 SMESH::SMESH_Group_var aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE, "affectedEdges");
6073 SMESH::SMESH_Group_var aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE, "affectedFaces");
6074 SMESH::SMESH_Group_var aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME, "affectedVolumes");
6078 ::SMESH_MeshEditor aMeshEditor(myMesh);
6080 SMESHDS_Mesh* aMeshDS = getMeshDS();
6081 TIDSortedElemSet anElems, aNodes;
6082 listOfGroupToSet(theElems, aMeshDS, anElems, false);
6083 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true);
6085 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape(theShape);
6086 TIDSortedElemSet anAffected;
6087 bool aResult = aMeshEditor.AffectedElemGroupsInRegion(anElems, aNodes, aShape, anAffected);
6090 myMesh->GetMeshDS()->Modified();
6094 myMesh->SetIsModified(true);
6096 int lg = anAffected.size();
6097 MESSAGE("lg="<< lg);
6098 SMESH::long_array_var volumeIds = new SMESH::long_array;
6099 volumeIds->length(lg);
6100 SMESH::long_array_var faceIds = new SMESH::long_array;
6101 faceIds->length(lg);
6102 SMESH::long_array_var edgeIds = new SMESH::long_array;
6103 edgeIds->length(lg);
6108 TIDSortedElemSet::const_iterator eIt = anAffected.begin();
6109 for (; eIt != anAffected.end(); ++eIt)
6111 const SMDS_MeshElement* anElem = *eIt;
6114 int elemId = anElem->GetID();
6115 if (myMesh->GetElementType(elemId, true) == SMDSAbs_Volume)
6116 volumeIds[ivol++] = elemId;
6117 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Face)
6118 faceIds[iface++] = elemId;
6119 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Edge)
6120 edgeIds[iedge++] = elemId;
6122 volumeIds->length(ivol);
6123 faceIds->length(iface);
6124 edgeIds->length(iedge);
6126 aNewVolumeGroup->Add(volumeIds);
6127 aNewFaceGroup->Add(faceIds);
6128 aNewEdgeGroup->Add(edgeIds);
6129 isVolumeGroup = (aNewVolumeGroup->Size() > 0);
6130 isFaceGroup = (aNewFaceGroup->Size() > 0);
6131 isEdgeGroup = (aNewEdgeGroup->Size() > 0);
6141 aListOfGroups->length(nbGroups);
6145 aListOfGroups[i++] = aNewEdgeGroup._retn();
6147 aListOfGroups[i++] = aNewFaceGroup._retn();
6149 aListOfGroups[i++] = aNewVolumeGroup._retn();
6151 // Update Python script
6155 pyDump << aNewEdgeGroup << ", ";
6157 pyDump << aNewFaceGroup << ", ";
6159 pyDump << aNewVolumeGroup << ", ";
6161 pyDump << this << ".AffectedElemGroupsInRegion( " << &theElems << ", " << &theNodesNot << ", " << theShape << " )";
6163 return aListOfGroups._retn();
6166 //================================================================================
6168 \brief Generated skin mesh (containing 2D cells) from 3D mesh
6169 The created 2D mesh elements based on nodes of free faces of boundary volumes
6170 \return TRUE if operation has been completed successfully, FALSE otherwise
6172 //================================================================================
6174 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
6178 bool aResult = getEditor().Make2DMeshFrom3D();
6179 myMesh->GetMeshDS()->Modified();
6180 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
6184 //================================================================================
6186 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
6187 * The list of groups must describe a partition of the mesh volumes.
6188 * The nodes of the internal faces at the boundaries of the groups are doubled.
6189 * In option, the internal faces are replaced by flat elements.
6190 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
6191 * The flat elements are stored in groups of volumes.
6192 * @param theDomains - list of groups of volumes
6193 * @param createJointElems - if TRUE, create the elements
6194 * @return TRUE if operation has been completed successfully, FALSE otherwise
6196 //================================================================================
6198 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
6199 CORBA::Boolean createJointElems )
6200 throw (SALOME::SALOME_Exception)
6205 SMESHDS_Mesh* aMeshDS = getMeshDS();
6207 vector<TIDSortedElemSet> domains;
6210 for ( int i = 0, n = theDomains.length(); i < n; i++ )
6212 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
6213 if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
6215 // if ( aGrp->GetType() != SMESH::VOLUME )
6216 // THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
6217 TIDSortedElemSet domain;
6219 domains.push_back(domain);
6220 SMESH::long_array_var anIDs = aGrp->GetIDs();
6221 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
6225 bool aResult = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems );
6226 // TODO publish the groups of flat elements in study
6228 myMesh->GetMeshDS()->Modified();
6230 // Update Python script
6231 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
6232 << ", " << createJointElems << " )";
6236 //================================================================================
6238 * \brief Double nodes on some external faces and create flat elements.
6239 * Flat elements are mainly used by some types of mechanic calculations.
6241 * Each group of the list must be constituted of faces.
6242 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
6243 * @param theGroupsOfFaces - list of groups of faces
6244 * @return TRUE if operation has been completed successfully, FALSE otherwise
6246 //================================================================================
6248 CORBA::Boolean SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
6253 SMESHDS_Mesh* aMeshDS = getMeshDS();
6255 vector<TIDSortedElemSet> faceGroups;
6258 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
6260 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
6261 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
6263 TIDSortedElemSet faceGroup;
6265 faceGroups.push_back(faceGroup);
6266 SMESH::long_array_var anIDs = aGrp->GetIDs();
6267 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
6271 bool aResult = getEditor().CreateFlatElementsOnFacesGroups( faceGroups );
6272 // TODO publish the groups of flat elements in study
6274 myMesh->GetMeshDS()->Modified();
6276 // Update Python script
6277 TPythonDump() << "isDone = " << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
6282 * \brief identify all the elements around a geom shape, get the faces delimiting the hole
6283 * Build groups of volume to remove, groups of faces to replace on the skin of the object,
6284 * groups of faces to remove inside the object, (idem edges).
6285 * Build ordered list of nodes at the border of each group of faces to replace (to be used to build a geom subshape)
6287 void SMESH_MeshEditor_i::CreateHoleSkin(CORBA::Double radius,
6288 GEOM::GEOM_Object_ptr theShape,
6289 const char* groupName,
6290 const SMESH::double_array& theNodesCoords,
6291 SMESH::array_of_long_array_out GroupsOfNodes)
6292 throw (SALOME::SALOME_Exception)
6295 std::vector<std::vector<int> > aListOfListOfNodes;
6296 ::SMESH_MeshEditor aMeshEditor( myMesh );
6298 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
6299 if ( !theNodeSearcher )
6300 theNodeSearcher = aMeshEditor.GetNodeSearcher();
6302 vector<double> nodesCoords;
6303 for (int i = 0; i < theNodesCoords.length(); i++)
6305 nodesCoords.push_back( theNodesCoords[i] );
6308 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6309 aMeshEditor.CreateHoleSkin(radius, aShape, theNodeSearcher, groupName, nodesCoords, aListOfListOfNodes);
6311 GroupsOfNodes = new SMESH::array_of_long_array;
6312 GroupsOfNodes->length( aListOfListOfNodes.size() );
6313 std::vector<std::vector<int> >::iterator llIt = aListOfListOfNodes.begin();
6314 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
6316 vector<int>& aListOfNodes = *llIt;
6317 vector<int>::iterator lIt = aListOfNodes.begin();;
6318 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
6319 aGroup.length( aListOfNodes.size() );
6320 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
6321 aGroup[ j ] = (*lIt);
6323 TPythonDump() << "lists_nodes = " << this << ".CreateHoleSkin( "
6324 << radius << ", " << theShape << ", " << ", " << groupName << ", " << theNodesCoords << " )";
6328 // issue 20749 ===================================================================
6330 * \brief Creates missing boundary elements
6331 * \param elements - elements whose boundary is to be checked
6332 * \param dimension - defines type of boundary elements to create
6333 * \param groupName - a name of group to store created boundary elements in,
6334 * "" means not to create the group
6335 * \param meshName - a name of new mesh to store created boundary elements in,
6336 * "" means not to create the new mesh
6337 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
6338 * \param toCopyExistingBondary - if true, not only new but also pre-existing
6339 * boundary elements will be copied into the new mesh
6340 * \param group - returns the create group, if any
6341 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
6343 // ================================================================================
6345 SMESH::SMESH_Mesh_ptr
6346 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
6347 SMESH::Bnd_Dimension dim,
6348 const char* groupName,
6349 const char* meshName,
6350 CORBA::Boolean toCopyElements,
6351 CORBA::Boolean toCopyExistingBondary,
6352 SMESH::SMESH_Group_out group)
6356 if ( dim > SMESH::BND_1DFROM2D )
6357 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
6359 SMESHDS_Mesh* aMeshDS = getMeshDS();
6361 SMESH::SMESH_Mesh_var mesh_var;
6362 SMESH::SMESH_Group_var group_var;
6366 TIDSortedElemSet elements;
6367 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
6368 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
6372 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
6373 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
6375 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
6377 // group of new boundary elements
6378 SMESH_Group* smesh_group = 0;
6379 if ( strlen(groupName) )
6381 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
6382 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
6383 smesh_group = group_i->GetSmeshGroup();
6387 getEditor().MakeBoundaryMesh( elements,
6388 ::SMESH_MeshEditor::Bnd_Dimension(dim),
6392 toCopyExistingBondary);
6395 smesh_mesh->GetMeshDS()->Modified();
6398 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
6400 // result of MakeBoundaryMesh() is a tuple (mesh, group)
6401 if ( mesh_var->_is_nil() )
6402 pyDump << myMesh_i->_this() << ", ";
6404 pyDump << mesh_var << ", ";
6405 if ( group_var->_is_nil() )
6406 pyDump << "_NoneGroup = "; // assignment to None is forbiden
6408 pyDump << group_var << " = ";
6409 pyDump << this << ".MakeBoundaryMesh( "
6411 << "SMESH." << dimName[int(dim)] << ", "
6412 << "'" << groupName << "', "
6413 << "'" << meshName<< "', "
6414 << toCopyElements << ", "
6415 << toCopyExistingBondary << ")";
6417 group = group_var._retn();
6418 return mesh_var._retn();
6421 //================================================================================
6423 * \brief Creates missing boundary elements
6424 * \param dimension - defines type of boundary elements to create
6425 * \param groupName - a name of group to store all boundary elements in,
6426 * "" means not to create the group
6427 * \param meshName - a name of a new mesh, which is a copy of the initial
6428 * mesh + created boundary elements; "" means not to create the new mesh
6429 * \param toCopyAll - if true, the whole initial mesh will be copied into
6430 * the new mesh else only boundary elements will be copied into the new mesh
6431 * \param groups - optional groups of elements to make boundary around
6432 * \param mesh - returns the mesh where elements were added to
6433 * \param group - returns the created group, if any
6434 * \retval long - number of added boundary elements
6436 //================================================================================
6438 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
6439 const char* groupName,
6440 const char* meshName,
6441 CORBA::Boolean toCopyAll,
6442 const SMESH::ListOfIDSources& groups,
6443 SMESH::SMESH_Mesh_out mesh,
6444 SMESH::SMESH_Group_out group)
6445 throw (SALOME::SALOME_Exception)
6447 Unexpect aCatch(SALOME_SalomeException);
6451 if ( dim > SMESH::BND_1DFROM2D )
6452 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
6454 // separate groups belonging to this and other mesh
6455 SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
6456 SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
6457 groupsOfThisMesh->length( groups.length() );
6458 groupsOfOtherMesh->length( groups.length() );
6459 int nbGroups = 0, nbGroupsOfOtherMesh = 0;
6460 for ( int i = 0; i < groups.length(); ++i )
6462 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
6463 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
6464 groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
6466 groupsOfThisMesh[ nbGroups++ ] = groups[i];
6467 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
6468 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
6470 groupsOfThisMesh->length( nbGroups );
6471 groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
6476 if ( nbGroupsOfOtherMesh > 0 )
6478 // process groups belonging to another mesh
6479 SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
6480 SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
6481 nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
6482 groupsOfOtherMesh, mesh, group );
6485 SMESH::SMESH_Mesh_var mesh_var;
6486 SMESH::SMESH_Group_var group_var;
6489 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
6490 const bool toCopyMesh = ( strlen( meshName ) > 0 );
6494 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
6496 /*toCopyGroups=*/false,
6497 /*toKeepIDs=*/true);
6499 mesh_var = makeMesh(meshName);
6501 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
6502 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
6505 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
6506 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
6508 // group of boundary elements
6509 SMESH_Group* smesh_group = 0;
6510 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
6511 if ( strlen(groupName) )
6513 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
6514 group_var = mesh_i->CreateGroup( groupType, groupName );
6515 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
6516 smesh_group = group_i->GetSmeshGroup();
6519 TIDSortedElemSet elements;
6521 if ( groups.length() > 0 )
6523 for ( int i = 0; i < nbGroups; ++i )
6526 if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
6528 SMESH::Bnd_Dimension bdim =
6529 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
6530 nbAdded += getEditor().MakeBoundaryMesh( elements,
6531 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
6534 /*toCopyElements=*/false,
6535 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
6536 /*toAddExistingBondary=*/true,
6537 /*aroundElements=*/true);
6543 nbAdded += getEditor().MakeBoundaryMesh( elements,
6544 ::SMESH_MeshEditor::Bnd_Dimension(dim),
6547 /*toCopyElements=*/false,
6548 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
6549 /*toAddExistingBondary=*/true);
6551 tgtMesh->GetMeshDS()->Modified();
6553 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
6555 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
6556 pyDump << "nbAdded, ";
6557 if ( mesh_var->_is_nil() )
6558 pyDump << myMesh_i->_this() << ", ";
6560 pyDump << mesh_var << ", ";
6561 if ( group_var->_is_nil() )
6562 pyDump << "_NoneGroup = "; // assignment to None is forbiden
6564 pyDump << group_var << " = ";
6565 pyDump << this << ".MakeBoundaryElements( "
6566 << "SMESH." << dimName[int(dim)] << ", "
6567 << "'" << groupName << "', "
6568 << "'" << meshName<< "', "
6569 << toCopyAll << ", "
6572 mesh = mesh_var._retn();
6573 group = group_var._retn();