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 "SMDS_EdgePosition.hxx"
33 #include "SMDS_ElemIterator.hxx"
34 #include "SMDS_FacePosition.hxx"
35 #include "SMDS_IteratorOnIterators.hxx"
36 #include "SMDS_LinearEdge.hxx"
37 #include "SMDS_Mesh0DElement.hxx"
38 #include "SMDS_MeshFace.hxx"
39 #include "SMDS_MeshVolume.hxx"
40 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
41 #include "SMDS_SetIterator.hxx"
42 #include "SMDS_VolumeTool.hxx"
43 #include "SMESHDS_Group.hxx"
44 #include "SMESHDS_GroupOnGeom.hxx"
45 #include "SMESH_ControlsDef.hxx"
46 #include "SMESH_Filter_i.hxx"
47 #include "SMESH_Gen_i.hxx"
48 #include "SMESH_Group.hxx"
49 #include "SMESH_Group_i.hxx"
50 #include "SMESH_MeshPartDS.hxx"
51 #include "SMESH_MesherHelper.hxx"
52 #include "SMESH_PythonDump.hxx"
53 #include "SMESH_subMeshEventListener.hxx"
54 #include "SMESH_subMesh_i.hxx"
56 #include <utilities.h>
57 #include <Utils_ExceptHandlers.hxx>
58 #include <Utils_CorbaException.hxx>
59 #include <SALOMEDS_wrap.hxx>
61 #include <BRepAdaptor_Surface.hxx>
62 #include <BRep_Tool.hxx>
63 #include <TopExp_Explorer.hxx>
65 #include <TopoDS_Edge.hxx>
66 #include <TopoDS_Face.hxx>
71 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
75 #include <Standard_Failure.hxx>
78 #include <Standard_ErrorHandler.hxx>
84 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
86 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
89 using SMESH::TPythonDump;
92 namespace MeshEditor_I {
94 //=============================================================================
96 * \brief Mesh to apply modifications for preview purposes
98 //=============================================================================
100 struct TPreviewMesh: public SMESH_Mesh
102 SMDSAbs_ElementType myPreviewType; // type to show
104 TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
105 _isShapeToMesh = (_id =_studyId = 0);
106 _myMeshDS = new SMESHDS_Mesh( _id, true );
107 myPreviewType = previewElements;
110 virtual ~TPreviewMesh() { delete _myMeshDS; _myMeshDS = 0; }
111 //!< Copy a set of elements
112 void Copy(const TIDSortedElemSet & theElements,
113 TIDSortedElemSet& theCopyElements,
114 SMDSAbs_ElementType theSelectType = SMDSAbs_All,
115 SMDSAbs_ElementType theAvoidType = SMDSAbs_All)
117 // loop on theIDsOfElements
118 TIDSortedElemSet::const_iterator eIt = theElements.begin();
119 for ( ; eIt != theElements.end(); ++eIt )
121 const SMDS_MeshElement* anElem = *eIt;
122 if ( !anElem ) continue;
123 SMDSAbs_ElementType type = anElem->GetType();
124 if ( type == theAvoidType ||
125 ( theSelectType != SMDSAbs_All && type != theSelectType ))
127 const SMDS_MeshElement* anElemCopy;
128 if ( type == SMDSAbs_Node)
129 anElemCopy = Copy( cast2Node(anElem) );
131 anElemCopy = Copy( anElem );
133 theCopyElements.insert( theCopyElements.end(), anElemCopy );
137 SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
139 // copy element nodes
140 int anElemNbNodes = anElem->NbNodes();
141 vector< int > anElemNodesID( anElemNbNodes ) ;
142 SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
143 for ( int i = 0; itElemNodes->more(); i++)
145 const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
147 anElemNodesID[i] = anElemNode->GetID();
150 // creates a corresponding element on copied nodes
151 SMDS_MeshElement* anElemCopy = 0;
152 if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
154 const SMDS_VtkVolume* ph =
155 dynamic_cast<const SMDS_VtkVolume*> (anElem);
157 anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
158 (anElemNodesID, ph->GetQuantities(),anElem->GetID());
161 anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
168 SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
170 return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(),
171 anElemNode->GetID());
173 };// struct TPreviewMesh
175 static SMESH_NodeSearcher * theNodeSearcher = 0;
176 static SMESH_ElementSearcher * theElementSearcher = 0;
178 //=============================================================================
180 * \brief Deleter of theNodeSearcher at any compute event occured
182 //=============================================================================
184 struct TSearchersDeleter : public SMESH_subMeshEventListener
187 string myMeshPartIOR;
189 TSearchersDeleter(): SMESH_subMeshEventListener( false, // won't be deleted by submesh
190 "SMESH_MeshEditor_i::TSearchersDeleter"),
192 //!< Delete theNodeSearcher
195 if ( theNodeSearcher ) delete theNodeSearcher; theNodeSearcher = 0;
196 if ( theElementSearcher ) delete theElementSearcher; theElementSearcher = 0;
198 typedef map < int, SMESH_subMesh * > TDependsOnMap;
199 //!< The meshod called by submesh: do my main job
200 void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
201 SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
203 if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
205 Unset( sm->GetFather() );
208 //!< set self on all submeshes and delete theNodeSearcher if other mesh is set
209 void Set(SMESH_Mesh* mesh, const string& meshPartIOR = string())
211 if ( myMesh != mesh || myMeshPartIOR != meshPartIOR)
218 myMeshPartIOR = meshPartIOR;
219 if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
220 const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
221 TDependsOnMap::const_iterator sm;
222 for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
223 sm->second->SetEventListener( this, 0, sm->second );
227 //!< delete self from all submeshes
228 void Unset(SMESH_Mesh* mesh)
230 if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
231 const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
232 TDependsOnMap::const_iterator sm;
233 for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
234 sm->second->DeleteEventListener( this );
239 } theSearchersDeleter;
241 TCollection_AsciiString mirrorTypeName( SMESH::SMESH_MeshEditor::MirrorType theMirrorType )
243 TCollection_AsciiString typeStr;
244 switch ( theMirrorType ) {
245 case SMESH::SMESH_MeshEditor::POINT:
246 typeStr = "SMESH.SMESH_MeshEditor.POINT";
248 case SMESH::SMESH_MeshEditor::AXIS:
249 typeStr = "SMESH.SMESH_MeshEditor.AXIS";
252 typeStr = "SMESH.SMESH_MeshEditor.PLANE";
256 //================================================================================
258 * \brief function for conversion of long_array to TIDSortedElemSet
259 * \param IDs - array of IDs
260 * \param aMesh - mesh
261 * \param aMap - collection to fill
262 * \param aType - element type
264 //================================================================================
266 void arrayToSet(const SMESH::long_array & IDs,
267 const SMESHDS_Mesh* aMesh,
268 TIDSortedElemSet& aMap,
269 const SMDSAbs_ElementType aType = SMDSAbs_All )
271 for (int i=0; i<IDs.length(); i++) {
272 CORBA::Long ind = IDs[i];
273 const SMDS_MeshElement * elem =
274 (aType == SMDSAbs_Node ? aMesh->FindNode(ind) : aMesh->FindElement(ind));
275 if ( elem && ( aType == SMDSAbs_All || elem->GetType() == aType ))
276 aMap.insert( aMap.end(), elem );
279 //================================================================================
281 * \brief Retrieve elements of given type from SMESH_IDSource
283 //================================================================================
285 bool idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource,
286 const SMESHDS_Mesh* theMeshDS,
287 TIDSortedElemSet& theElemSet,
288 const SMDSAbs_ElementType theType,
289 const bool emptyIfIsMesh=false)
292 if ( CORBA::is_nil( theIDSource ) )
294 if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
297 SMESH::long_array_var anIDs = theIDSource->GetIDs();
298 if ( anIDs->length() == 0 )
300 SMESH::array_of_ElementType_var types = theIDSource->GetTypes();
301 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
303 if ( theType == SMDSAbs_All || theType == SMDSAbs_Node )
304 arrayToSet( anIDs, theMeshDS, theElemSet, SMDSAbs_Node );
310 arrayToSet( anIDs, theMeshDS, theElemSet, theType);
311 return bool(anIDs->length()) == bool(theElemSet.size());
315 //================================================================================
317 * \brief Retrieve nodes from SMESH_IDSource
319 //================================================================================
321 void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject,
322 const SMESHDS_Mesh* theMeshDS,
323 TIDSortedNodeSet& theNodeSet)
326 if ( CORBA::is_nil( theObject ) )
328 SMESH::array_of_ElementType_var types = theObject->GetTypes();
329 SMESH::long_array_var aElementsId = theObject->GetIDs();
330 if ( types->length() == 1 && types[0] == SMESH::NODE)
332 for(int i = 0; i < aElementsId->length(); i++)
333 if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] ))
334 theNodeSet.insert( theNodeSet.end(), n);
336 else if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
338 SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator();
339 while ( nIt->more( ))
340 if( const SMDS_MeshElement * elem = nIt->next() )
341 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
345 for(int i = 0; i < aElementsId->length(); i++)
346 if( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] ))
347 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
351 //================================================================================
353 * \brief Returns elements connected to the given elements
355 //================================================================================
357 void getElementsAround(const TIDSortedElemSet& theElements,
358 const SMESHDS_Mesh* theMeshDS,
359 TIDSortedElemSet& theElementsAround)
361 if ( theElements.empty() ) return;
363 SMDSAbs_ElementType elemType = (*theElements.begin())->GetType();
364 bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() );
366 theMeshDS->GetMeshInfo().NbElements( elemType ) == theElements.size() )
367 return; // all the elements are in theElements
370 elemType = SMDSAbs_All;
372 TIDSortedElemSet visitedNodes;
373 TIDSortedElemSet::const_iterator elemIt = theElements.begin();
374 for ( ; elemIt != theElements.end(); ++elemIt )
376 const SMDS_MeshElement* e = *elemIt;
377 int i = e->NbCornerNodes();
380 const SMDS_MeshNode* n = e->GetNode( i );
381 if ( visitedNodes.insert( n ).second )
383 SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
384 while ( invIt->more() )
386 const SMDS_MeshElement* elemAround = invIt->next();
387 if ( !theElements.count( elemAround ))
388 theElementsAround.insert( elemAround );
395 //================================================================================
397 * \brief Return a string used to detect change of mesh part on which theElementSearcher
398 * is going to be used
400 //================================================================================
402 string getPartIOR( SMESH::SMESH_IDSource_ptr theMeshPart, SMESH::ElementType type)
404 string partIOR = SMESH_Gen_i::GetORB()->object_to_string( theMeshPart );
405 if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( theMeshPart ))
406 // take into account passible group modification
407 partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() );
408 partIOR += SMESH_Comment( type );
412 } // namespace MeshEditor_I
414 using namespace MeshEditor_I;
416 //=============================================================================
420 //=============================================================================
422 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview):
424 myMesh( &theMesh->GetImpl() ),
426 myIsPreviewMode ( isPreview ),
432 //================================================================================
436 //================================================================================
438 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
440 deleteAuxIDSources();
441 delete myPreviewMesh; myPreviewMesh = 0;
442 delete myPreviewEditor; myPreviewEditor = 0;
445 //================================================================================
447 * \brief Clear members
449 //================================================================================
451 void SMESH_MeshEditor_i::initData(bool deleteSearchers)
453 if ( myIsPreviewMode ) {
454 if ( myPreviewMesh ) myPreviewMesh->Clear();
457 if ( deleteSearchers )
458 TSearchersDeleter::Delete();
460 getEditor().GetError().reset();
461 getEditor().CrearLastCreated();
463 //================================================================================
465 * \brief Return either myEditor or myPreviewEditor depending on myIsPreviewMode.
466 * WARNING: in preview mode call getPreviewMesh() before getEditor()!
468 //================================================================================
470 ::SMESH_MeshEditor& SMESH_MeshEditor_i::getEditor()
472 if ( myIsPreviewMode && !myPreviewEditor ) {
473 if ( !myPreviewMesh ) getPreviewMesh();
474 myPreviewEditor = new ::SMESH_MeshEditor( myPreviewMesh );
476 return myIsPreviewMode ? *myPreviewEditor : myEditor;
479 //================================================================================
481 * \brief Initialize and return myPreviewMesh
482 * \param previewElements - type of elements to show in preview
484 * WARNING: call it once par a method!
486 //================================================================================
488 TPreviewMesh * SMESH_MeshEditor_i::getPreviewMesh(SMDSAbs_ElementType previewElements)
490 if ( !myPreviewMesh || myPreviewMesh->myPreviewType != previewElements )
492 delete myPreviewEditor;
494 delete myPreviewMesh;
495 myPreviewMesh = new TPreviewMesh( previewElements );
497 myPreviewMesh->Clear();
498 return myPreviewMesh;
501 //================================================================================
503 * \brief Now does nothing
505 //================================================================================
507 // void SMESH_MeshEditor_i::storeResult(::SMESH_MeshEditor& )
511 //================================================================================
513 * Return data of mesh edition preview
515 //================================================================================
517 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
519 const bool hasBadElems = ( getEditor().GetError() && getEditor().GetError()->HasBadElems() );
521 if ( myIsPreviewMode || hasBadElems ) { // --- MeshPreviewStruct filling ---
523 list<int> aNodesConnectivity;
524 typedef map<int, int> TNodesMap;
527 SMESHDS_Mesh* aMeshDS;
528 std::auto_ptr< SMESH_MeshPartDS > aMeshPartDS;
530 aMeshPartDS.reset( new SMESH_MeshPartDS( getEditor().GetError()->myBadElements ));
531 aMeshDS = aMeshPartDS.get();
534 aMeshDS = getEditor().GetMeshDS();
536 int nbEdges = aMeshDS->NbEdges();
537 int nbFaces = aMeshDS->NbFaces();
538 int nbVolum = aMeshDS->NbVolumes();
539 myPreviewData = new SMESH::MeshPreviewStruct();
540 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
543 SMDSAbs_ElementType previewType = SMDSAbs_All;
545 if (TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( getEditor().GetMesh() )) {
546 previewType = aPreviewMesh->myPreviewType;
547 switch ( previewType ) {
548 case SMDSAbs_Edge : nbFaces = nbVolum = 0; break;
549 case SMDSAbs_Face : nbEdges = nbVolum = 0; break;
550 case SMDSAbs_Volume: nbEdges = nbFaces = 0; break;
555 myPreviewData->elementTypes.length(nbEdges + nbFaces + nbVolum);
557 SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator(previewType);
559 while ( itMeshElems->more() ) {
560 const SMDS_MeshElement* aMeshElem = itMeshElems->next();
561 SMDS_ElemIteratorPtr itElemNodes = aMeshElem->nodesIterator();
562 while ( itElemNodes->more() ) {
563 const SMDS_MeshNode* aMeshNode =
564 static_cast<const SMDS_MeshNode*>( itElemNodes->next() );
565 int aNodeID = aMeshNode->GetID();
566 TNodesMap::iterator anIter = nodesMap.find(aNodeID);
567 if ( anIter == nodesMap.end() ) {
568 // filling the nodes coordinates
569 myPreviewData->nodesXYZ[j].x = aMeshNode->X();
570 myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
571 myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
572 anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
575 aNodesConnectivity.push_back(anIter->second);
578 // filling the elements types
579 SMDSAbs_ElementType aType = aMeshElem->GetType();
580 bool isPoly = aMeshElem->IsPoly();
582 myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
583 myPreviewData->elementTypes[i].isPoly = isPoly;
584 myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
588 myPreviewData->nodesXYZ.length( j );
590 // filling the elements connectivities
591 list<int>::iterator aConnIter = aNodesConnectivity.begin();
592 myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
593 for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
594 myPreviewData->elementConnectivities[i] = *aConnIter;
597 return myPreviewData._retn();
600 //================================================================================
602 * \brief Returns list of it's IDs of created nodes
603 * \retval SMESH::long_array* - list of node ID
605 //================================================================================
607 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
609 SMESH::long_array_var myLastCreatedNodes = new SMESH::long_array();
610 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedNodes();
611 myLastCreatedNodes->length( aSeq.Length() );
612 for (int i = 1; i <= aSeq.Length(); i++)
613 myLastCreatedNodes[i-1] = aSeq.Value(i)->GetID();
614 return myLastCreatedNodes._retn();
617 //================================================================================
619 * \brief Returns list of it's IDs of created elements
620 * \retval SMESH::long_array* - list of elements' ID
622 //================================================================================
624 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
626 SMESH::long_array_var myLastCreatedElems = new SMESH::long_array();
627 const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
628 myLastCreatedElems->length( aSeq.Length() );
629 for ( int i = 1; i <= aSeq.Length(); i++ )
630 myLastCreatedElems[i-1] = aSeq.Value(i)->GetID();
631 return myLastCreatedElems._retn();
634 //=======================================================================
636 * Returns description of an error/warning occured during the last operation
638 //=======================================================================
640 SMESH::ComputeError* SMESH_MeshEditor_i::GetLastError()
642 SMESH::ComputeError_var errOut = new SMESH::ComputeError;
643 SMESH_ComputeErrorPtr& errIn = getEditor().GetError();
644 if ( errIn && !errIn->IsOK() )
646 errOut->code = -( errIn->myName < 0 ? errIn->myName + 1: errIn->myName ); // -1 -> 0
647 errOut->comment = errIn->myComment.c_str();
648 errOut->subShapeID = -1;
649 errOut->hasBadMesh = !errIn->myBadElements.empty();
654 errOut->subShapeID = -1;
655 errOut->hasBadMesh = false;
657 return errOut._retn();
660 //=======================================================================
661 //function : MakeIDSource
662 //purpose : Wrap a sequence of ids in a SMESH_IDSource
663 //=======================================================================
665 struct SMESH_MeshEditor_i::_IDSource : public POA_SMESH::SMESH_IDSource
667 SMESH::long_array _ids;
668 SMESH::ElementType _type;
669 SMESH::SMESH_Mesh_ptr _mesh;
670 SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); }
671 SMESH::long_array* GetMeshInfo() { return 0; }
672 SMESH::SMESH_Mesh_ptr GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _mesh ); }
673 bool IsMeshInfoCorrect() { return true; }
674 SMESH::array_of_ElementType* GetTypes()
676 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
677 if ( _ids.length() > 0 ) {
681 return types._retn();
685 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
686 SMESH::ElementType type)
688 if ( myAuxIDSources.size() > 10 )
689 deleteAuxIDSources();
691 _IDSource* idSrc = new _IDSource;
692 idSrc->_mesh = myMesh_i->_this();
695 myAuxIDSources.push_back( idSrc );
697 SMESH::SMESH_IDSource_var anIDSourceVar = idSrc->_this();
699 return anIDSourceVar._retn();
702 bool SMESH_MeshEditor_i::IsTemporaryIDSource( SMESH::SMESH_IDSource_ptr& idSource )
704 return SMESH::DownCast<SMESH_MeshEditor_i::_IDSource*>( idSource );
707 void SMESH_MeshEditor_i::deleteAuxIDSources()
709 std::list< _IDSource* >::iterator idSrcIt = myAuxIDSources.begin();
710 for ( ; idSrcIt != myAuxIDSources.end(); ++idSrcIt )
712 myAuxIDSources.clear();
715 //=============================================================================
719 //=============================================================================
722 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
728 for (int i = 0; i < IDsOfElements.length(); i++)
729 IdList.push_back( IDsOfElements[i] );
731 // Update Python script
732 TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
735 bool ret = getEditor().Remove( IdList, false );
736 myMesh->GetMeshDS()->Modified();
737 if ( IDsOfElements.length() )
738 myMesh->SetIsModified( true ); // issue 0020693
742 //=============================================================================
746 //=============================================================================
748 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
753 for (int i = 0; i < IDsOfNodes.length(); i++)
754 IdList.push_back( IDsOfNodes[i] );
756 // Update Python script
757 TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
759 bool ret = getEditor().Remove( IdList, true );
760 myMesh->GetMeshDS()->Modified();
761 if ( IDsOfNodes.length() )
762 myMesh->SetIsModified( true ); // issue 0020693
766 //=============================================================================
770 //=============================================================================
772 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
777 // Update Python script
778 TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
780 // Create filter to find all orphan nodes
781 SMESH::Controls::Filter::TIdSequence seq;
782 SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
783 SMESH::Controls::Filter::GetElementsId( getMeshDS(), predicate, seq );
785 // remove orphan nodes (if there are any)
787 for ( int i = 0; i < seq.size(); i++ )
788 IdList.push_back( seq[i] );
790 int nbNodesBefore = myMesh->NbNodes();
791 getEditor().Remove( IdList, true );
792 myMesh->GetMeshDS()->Modified();
794 myMesh->SetIsModified( true );
795 int nbNodesAfter = myMesh->NbNodes();
797 return nbNodesBefore - nbNodesAfter;
800 //=============================================================================
804 //=============================================================================
806 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,
807 CORBA::Double y, CORBA::Double z)
811 const SMDS_MeshNode* N = getMeshDS()->AddNode(x, y, z);
813 // Update Python script
814 TPythonDump() << "nodeID = " << this << ".AddNode( "
815 << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )";
817 myMesh->GetMeshDS()->Modified();
818 myMesh->SetIsModified( true ); // issue 0020693
822 //=============================================================================
824 * Create 0D element on the given node.
826 //=============================================================================
828 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
832 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
833 SMDS_MeshElement* elem = getMeshDS()->Add0DElement(aNode);
835 // Update Python script
836 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
838 myMesh->GetMeshDS()->Modified();
839 myMesh->SetIsModified( true ); // issue 0020693
842 return elem->GetID();
847 //=============================================================================
849 * Create a ball element on the given node.
851 //=============================================================================
853 CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diameter)
854 throw (SALOME::SALOME_Exception)
858 if ( diameter < std::numeric_limits<double>::min() )
859 THROW_SALOME_CORBA_EXCEPTION("Invalid diameter", SALOME::BAD_PARAM);
863 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
864 SMDS_MeshElement* elem = getMeshDS()->AddBall(aNode, diameter);
866 // Update Python script
867 TPythonDump() << "ballElem = "
868 << this << ".AddBall( " << IDOfNode << ", " << diameter <<" )";
870 myMesh->GetMeshDS()->Modified();
871 myMesh->SetIsModified( true ); // issue 0020693
874 return elem->GetID();
876 SMESH_CATCH( SMESH::throwCorbaException );
881 //=============================================================================
883 * Create an edge, either linear and quadratic (this is determed
884 * by number of given nodes, two or three)
886 //=============================================================================
888 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
892 int NbNodes = IDsOfNodes.length();
893 SMDS_MeshElement* elem = 0;
896 CORBA::Long index1 = IDsOfNodes[0];
897 CORBA::Long index2 = IDsOfNodes[1];
898 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(index1),
899 getMeshDS()->FindNode(index2));
901 // Update Python script
902 TPythonDump() << "edge = " << this << ".AddEdge([ "
903 << index1 << ", " << index2 <<" ])";
906 CORBA::Long n1 = IDsOfNodes[0];
907 CORBA::Long n2 = IDsOfNodes[1];
908 CORBA::Long n12 = IDsOfNodes[2];
909 elem = getMeshDS()->AddEdge( getMeshDS()->FindNode(n1),
910 getMeshDS()->FindNode(n2),
911 getMeshDS()->FindNode(n12));
912 // Update Python script
913 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
914 <<n1<<", "<<n2<<", "<<n12<<" ])";
917 myMesh->GetMeshDS()->Modified();
919 return myMesh->SetIsModified( true ), elem->GetID();
924 //=============================================================================
928 //=============================================================================
930 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
934 int NbNodes = IDsOfNodes.length();
940 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
941 for (int i = 0; i < NbNodes; i++)
942 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
944 SMDS_MeshElement* elem = 0;
946 elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]);
948 else if (NbNodes == 4) {
949 elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]);
951 else if (NbNodes == 6) {
952 elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
955 else if (NbNodes == 8) {
956 elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
957 nodes[4], nodes[5], nodes[6], nodes[7]);
959 else if (NbNodes == 9) {
960 elem = getMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
961 nodes[4], nodes[5], nodes[6], nodes[7], nodes[8] );
963 else if (NbNodes > 2) {
964 elem = getMeshDS()->AddPolygonalFace(nodes);
967 // Update Python script
968 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
970 myMesh->GetMeshDS()->Modified();
972 return myMesh->SetIsModified( true ), elem->GetID();
977 //=============================================================================
981 //=============================================================================
982 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
986 int NbNodes = IDsOfNodes.length();
987 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
988 for (int i = 0; i < NbNodes; i++)
989 nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
991 const SMDS_MeshElement* elem = getMeshDS()->AddPolygonalFace(nodes);
993 // Update Python script
994 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
996 myMesh->GetMeshDS()->Modified();
997 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
1000 //=============================================================================
1002 * Create volume, either linear and quadratic (this is determed
1003 * by number of given nodes)
1005 //=============================================================================
1007 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
1011 int NbNodes = IDsOfNodes.length();
1012 vector< const SMDS_MeshNode*> n(NbNodes);
1013 for(int i=0;i<NbNodes;i++)
1014 n[i]= getMeshDS()->FindNode(IDsOfNodes[i]);
1016 SMDS_MeshElement* elem = 0;
1019 case 4 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
1020 case 5 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
1021 case 6 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
1022 case 8 :elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
1023 case 10:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1024 n[6],n[7],n[8],n[9]);
1026 case 12:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
1027 n[6],n[7],n[8],n[9],n[10],n[11]);
1029 case 13:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
1030 n[7],n[8],n[9],n[10],n[11],n[12]);
1032 case 15:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
1033 n[9],n[10],n[11],n[12],n[13],n[14]);
1035 case 20:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1036 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1037 n[15],n[16],n[17],n[18],n[19]);
1039 case 27:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
1040 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
1041 n[15],n[16],n[17],n[18],n[19],
1042 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
1046 // Update Python script
1047 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
1049 myMesh->GetMeshDS()->Modified();
1051 return myMesh->SetIsModified( true ), elem->GetID();
1056 //=============================================================================
1058 * AddPolyhedralVolume
1060 //=============================================================================
1061 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
1062 const SMESH::long_array & Quantities)
1066 int NbNodes = IDsOfNodes.length();
1067 std::vector<const SMDS_MeshNode*> n (NbNodes);
1068 for (int i = 0; i < NbNodes; i++)
1070 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDsOfNodes[i]);
1071 if (!aNode) return 0;
1075 int NbFaces = Quantities.length();
1076 std::vector<int> q (NbFaces);
1077 for (int j = 0; j < NbFaces; j++)
1078 q[j] = Quantities[j];
1080 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(n, q);
1082 // Update Python script
1083 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
1084 << IDsOfNodes << ", " << Quantities << " )";
1085 myMesh->GetMeshDS()->Modified();
1087 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
1090 //=============================================================================
1092 * AddPolyhedralVolumeByFaces
1094 //=============================================================================
1096 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
1100 int NbFaces = IdsOfFaces.length();
1101 std::vector<const SMDS_MeshNode*> poly_nodes;
1102 std::vector<int> quantities (NbFaces);
1104 for (int i = 0; i < NbFaces; i++) {
1105 const SMDS_MeshElement* aFace = getMeshDS()->FindElement(IdsOfFaces[i]);
1106 quantities[i] = aFace->NbNodes();
1108 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
1109 while (It->more()) {
1110 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
1114 const SMDS_MeshElement* elem = getMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
1116 // Update Python script
1117 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
1118 << IdsOfFaces << " )";
1119 myMesh->GetMeshDS()->Modified();
1121 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
1124 //=============================================================================
1126 // \brief Create 0D elements on all nodes of the given object except those
1127 // nodes on which a 0D element already exists.
1128 // \param theObject object on whose nodes 0D elements will be created.
1129 // \param theGroupName optional name of a group to add 0D elements created
1130 // and/or found on nodes of \a theObject.
1131 // \return an object (a new group or a temporary SMESH_IDSource) holding
1132 // ids of new and/or found 0D elements.
1134 //=============================================================================
1136 SMESH::SMESH_IDSource_ptr
1137 SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObject,
1138 const char* theGroupName)
1139 throw (SALOME::SALOME_Exception)
1143 SMESH::SMESH_IDSource_var result;
1148 TIDSortedElemSet elements, elems0D;
1149 if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
1150 getEditor().Create0DElementsOnAllNodes( elements, elems0D );
1152 SMESH::long_array_var newElems = new SMESH::long_array;
1153 newElems->length( elems0D.size() );
1154 TIDSortedElemSet::iterator eIt = elems0D.begin();
1155 for ( size_t i = 0; i < elems0D.size(); ++i, ++eIt )
1156 newElems[ i ] = (*eIt)->GetID();
1158 SMESH::SMESH_GroupBase_var groupToFill;
1159 if ( theGroupName && strlen( theGroupName ))
1161 // Get existing group named theGroupName
1162 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
1163 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
1164 SMESH::SMESH_GroupBase_var group = groups[i];
1165 if ( !group->_is_nil() ) {
1166 CORBA::String_var name = group->GetName();
1167 if ( strcmp( name.in(), theGroupName ) == 0 && group->GetType() == SMESH::ELEM0D ) {
1168 groupToFill = group;
1173 if ( groupToFill->_is_nil() )
1174 groupToFill = myMesh_i->CreateGroup( SMESH::ELEM0D, theGroupName );
1175 else if ( !SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1176 groupToFill = myMesh_i->ConvertToStandalone( groupToFill );
1179 if ( SMESH_Group_i* group_i = SMESH::DownCast< SMESH_Group_i* > ( groupToFill ))
1181 group_i->Add( newElems );
1182 result = SMESH::SMESH_IDSource::_narrow( groupToFill );
1183 pyDump << groupToFill;
1187 result = MakeIDSource( newElems, SMESH::ELEM0D );
1188 pyDump << "elem0DIDs";
1191 pyDump << " = " << this << ".Create0DElementsOnAllNodes( "
1192 << theObject << ", '" << theGroupName << "' )";
1194 SMESH_CATCH( SMESH::throwCorbaException );
1196 return result._retn();
1199 //=============================================================================
1201 * \brief Bind a node to a vertex
1202 * \param NodeID - node ID
1203 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1204 * \retval boolean - false if NodeID or VertexID is invalid
1206 //=============================================================================
1208 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
1209 throw (SALOME::SALOME_Exception)
1211 Unexpect aCatch(SALOME_SalomeException);
1213 SMESHDS_Mesh * mesh = getMeshDS();
1214 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1216 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1218 if ( mesh->MaxShapeIndex() < VertexID )
1219 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1221 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
1222 if ( shape.ShapeType() != TopAbs_VERTEX )
1223 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
1225 mesh->SetNodeOnVertex( node, VertexID );
1227 myMesh->SetIsModified( true );
1230 //=============================================================================
1232 * \brief Store node position on an edge
1233 * \param NodeID - node ID
1234 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
1235 * \param paramOnEdge - parameter on edge where the node is located
1236 * \retval boolean - false if any parameter is invalid
1238 //=============================================================================
1240 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
1241 CORBA::Double paramOnEdge)
1242 throw (SALOME::SALOME_Exception)
1244 Unexpect aCatch(SALOME_SalomeException);
1246 SMESHDS_Mesh * mesh = getMeshDS();
1247 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1249 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1251 if ( mesh->MaxShapeIndex() < EdgeID )
1252 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1254 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
1255 if ( shape.ShapeType() != TopAbs_EDGE )
1256 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
1259 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
1260 if ( paramOnEdge < f || paramOnEdge > l )
1261 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
1263 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
1265 myMesh->SetIsModified( true );
1268 //=============================================================================
1270 * \brief Store node position on a face
1271 * \param NodeID - node ID
1272 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
1273 * \param u - U parameter on face where the node is located
1274 * \param v - V parameter on face where the node is located
1275 * \retval boolean - false if any parameter is invalid
1277 //=============================================================================
1279 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
1280 CORBA::Double u, CORBA::Double v)
1281 throw (SALOME::SALOME_Exception)
1283 Unexpect aCatch(SALOME_SalomeException);
1285 SMESHDS_Mesh * mesh = getMeshDS();
1286 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1288 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1290 if ( mesh->MaxShapeIndex() < FaceID )
1291 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1293 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
1294 if ( shape.ShapeType() != TopAbs_FACE )
1295 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
1297 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
1298 bool isOut = ( u < surf.FirstUParameter() ||
1299 u > surf.LastUParameter() ||
1300 v < surf.FirstVParameter() ||
1301 v > surf.LastVParameter() );
1305 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
1306 << " u( " << surf.FirstUParameter()
1307 << "," << surf.LastUParameter()
1308 << ") v( " << surf.FirstVParameter()
1309 << "," << surf.LastVParameter() << ")" );
1311 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
1314 mesh->SetNodeOnFace( node, FaceID, u, v );
1315 myMesh->SetIsModified( true );
1318 //=============================================================================
1320 * \brief Bind a node to a solid
1321 * \param NodeID - node ID
1322 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
1323 * \retval boolean - false if NodeID or SolidID is invalid
1325 //=============================================================================
1327 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
1328 throw (SALOME::SALOME_Exception)
1330 Unexpect aCatch(SALOME_SalomeException);
1332 SMESHDS_Mesh * mesh = getMeshDS();
1333 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
1335 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
1337 if ( mesh->MaxShapeIndex() < SolidID )
1338 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1340 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
1341 if ( shape.ShapeType() != TopAbs_SOLID &&
1342 shape.ShapeType() != TopAbs_SHELL)
1343 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
1345 mesh->SetNodeInVolume( node, SolidID );
1347 // myMesh->SetIsModified( true ); - SetNodeInVolume() can't prevent re-compute, I believe
1350 //=============================================================================
1352 * \brief Bind an element to a shape
1353 * \param ElementID - element ID
1354 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
1355 * \retval boolean - false if ElementID or ShapeID is invalid
1357 //=============================================================================
1359 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
1360 CORBA::Long ShapeID)
1361 throw (SALOME::SALOME_Exception)
1363 Unexpect aCatch(SALOME_SalomeException);
1365 SMESHDS_Mesh * mesh = getMeshDS();
1366 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
1368 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
1370 if ( mesh->MaxShapeIndex() < ShapeID )
1371 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1373 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1374 if ( shape.ShapeType() != TopAbs_EDGE &&
1375 shape.ShapeType() != TopAbs_FACE &&
1376 shape.ShapeType() != TopAbs_SOLID &&
1377 shape.ShapeType() != TopAbs_SHELL )
1378 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1380 mesh->SetMeshElementOnShape( elem, ShapeID );
1382 myMesh->SetIsModified( true );
1385 //=============================================================================
1389 //=============================================================================
1391 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1392 CORBA::Long NodeID2)
1396 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1397 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1401 // Update Python script
1402 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1403 << NodeID1 << ", " << NodeID2 << " )";
1406 int ret = getEditor().InverseDiag ( n1, n2 );
1407 myMesh->GetMeshDS()->Modified();
1408 myMesh->SetIsModified( true );
1412 //=============================================================================
1416 //=============================================================================
1418 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1419 CORBA::Long NodeID2)
1423 const SMDS_MeshNode * n1 = getMeshDS()->FindNode( NodeID1 );
1424 const SMDS_MeshNode * n2 = getMeshDS()->FindNode( NodeID2 );
1428 // Update Python script
1429 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1430 << NodeID1 << ", " << NodeID2 << " )";
1433 bool stat = getEditor().DeleteDiag ( n1, n2 );
1435 myMesh->GetMeshDS()->Modified();
1437 myMesh->SetIsModified( true ); // issue 0020693
1443 //=============================================================================
1447 //=============================================================================
1449 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1453 for (int i = 0; i < IDsOfElements.length(); i++)
1455 CORBA::Long index = IDsOfElements[i];
1456 const SMDS_MeshElement * elem = getMeshDS()->FindElement(index);
1458 getEditor().Reorient( elem );
1460 // Update Python script
1461 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1463 myMesh->GetMeshDS()->Modified();
1464 if ( IDsOfElements.length() )
1465 myMesh->SetIsModified( true ); // issue 0020693
1471 //=============================================================================
1475 //=============================================================================
1477 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1481 TPythonDump aTPythonDump; // suppress dump in Reorient()
1483 SMESH::long_array_var anElementsId = theObject->GetIDs();
1484 CORBA::Boolean isDone = Reorient(anElementsId);
1486 // Update Python script
1487 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1492 //=======================================================================
1493 //function : Reorient2D
1494 //purpose : Reorient faces contained in \a the2Dgroup.
1495 // the2Dgroup - the mesh or its part to reorient
1496 // theDirection - desired direction of normal of \a theFace
1497 // theFace - ID of face whose orientation is checked.
1498 // It can be < 1 then \a thePoint is used to find a face.
1499 // thePoint - is used to find a face if \a theFace < 1.
1500 // return number of reoriented elements.
1501 //=======================================================================
1503 CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
1504 const SMESH::DirStruct& theDirection,
1505 CORBA::Long theFace,
1506 const SMESH::PointStruct& thePoint)
1507 throw (SALOME::SALOME_Exception)
1509 Unexpect aCatch(SALOME_SalomeException);
1511 initData(/*deleteSearchers=*/false);
1513 TIDSortedElemSet elements;
1514 if ( !idSourceToSet( the2Dgroup, getMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1))
1515 THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
1518 const SMDS_MeshElement* face = 0;
1521 face = getMeshDS()->FindElement( theFace );
1523 THROW_SALOME_CORBA_EXCEPTION("Inexistent face given", SALOME::BAD_PARAM);
1524 if ( face->GetType() != SMDSAbs_Face )
1525 THROW_SALOME_CORBA_EXCEPTION("Wrong element type", SALOME::BAD_PARAM);
1529 // create theElementSearcher if needed
1530 theSearchersDeleter.Set( myMesh, getPartIOR( the2Dgroup, SMESH::FACE ));
1531 if ( !theElementSearcher )
1533 if ( elements.empty() ) // search in the whole mesh
1535 if ( myMesh->NbFaces() == 0 )
1536 THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM);
1538 theElementSearcher = myEditor.GetElementSearcher();
1542 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
1543 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
1545 theElementSearcher = myEditor.GetElementSearcher(elemsIt);
1549 gp_Pnt p( thePoint.x, thePoint.y, thePoint.z );
1550 face = theElementSearcher->FindClosestTo( p, SMDSAbs_Face );
1553 THROW_SALOME_CORBA_EXCEPTION("No face found by point", SALOME::INTERNAL_ERROR );
1554 if ( !elements.empty() && !elements.count( face ))
1555 THROW_SALOME_CORBA_EXCEPTION("Found face is not in the group", SALOME::BAD_PARAM );
1558 const SMESH::PointStruct * P = &theDirection.PS;
1559 gp_Vec dirVec( P->x, P->y, P->z );
1560 if ( dirVec.Magnitude() < std::numeric_limits< double >::min() )
1561 THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM);
1563 int nbReori = getEditor().Reorient2D( elements, dirVec, face );
1566 myMesh->SetIsModified( true );
1567 myMesh->GetMeshDS()->Modified();
1569 TPythonDump() << this << ".Reorient2D( "
1570 << the2Dgroup << ", "
1571 << theDirection << ", "
1573 << thePoint << " )";
1578 //=============================================================================
1582 //=============================================================================
1583 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1584 SMESH::NumericalFunctor_ptr Criterion,
1585 CORBA::Double MaxAngle)
1589 SMESHDS_Mesh* aMesh = getMeshDS();
1590 TIDSortedElemSet faces;
1591 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1593 SMESH::NumericalFunctor_i* aNumericalFunctor =
1594 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1595 SMESH::Controls::NumericalFunctorPtr aCrit;
1596 if ( !aNumericalFunctor )
1597 aCrit.reset( new SMESH::Controls::MaxElementLength2D() );
1599 aCrit = aNumericalFunctor->GetNumericalFunctor();
1601 // Update Python script
1602 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1603 << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1606 bool stat = getEditor().TriToQuad( faces, aCrit, MaxAngle );
1607 myMesh->GetMeshDS()->Modified();
1609 myMesh->SetIsModified( true ); // issue 0020693
1616 //=============================================================================
1620 //=============================================================================
1621 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1622 SMESH::NumericalFunctor_ptr Criterion,
1623 CORBA::Double MaxAngle)
1627 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1628 SMESH::long_array_var anElementsId = theObject->GetIDs();
1629 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1631 SMESH::NumericalFunctor_i* aNumericalFunctor =
1632 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1634 // Update Python script
1635 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1636 << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
1642 //=============================================================================
1646 //=============================================================================
1647 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1648 SMESH::NumericalFunctor_ptr Criterion)
1652 SMESHDS_Mesh* aMesh = getMeshDS();
1653 TIDSortedElemSet faces;
1654 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1656 SMESH::NumericalFunctor_i* aNumericalFunctor =
1657 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1658 SMESH::Controls::NumericalFunctorPtr aCrit;
1659 if ( !aNumericalFunctor )
1660 aCrit.reset( new SMESH::Controls::AspectRatio() );
1662 aCrit = aNumericalFunctor->GetNumericalFunctor();
1665 // Update Python script
1666 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1668 CORBA::Boolean stat = getEditor().QuadToTri( faces, aCrit );
1669 myMesh->GetMeshDS()->Modified();
1671 myMesh->SetIsModified( true ); // issue 0020693
1678 //=============================================================================
1682 //=============================================================================
1683 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1684 SMESH::NumericalFunctor_ptr Criterion)
1688 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1690 SMESH::long_array_var anElementsId = theObject->GetIDs();
1691 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1693 SMESH::NumericalFunctor_i* aNumericalFunctor =
1694 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1696 // Update Python script
1697 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1703 //=============================================================================
1707 //=============================================================================
1708 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1709 CORBA::Boolean Diag13)
1713 SMESHDS_Mesh* aMesh = getMeshDS();
1714 TIDSortedElemSet faces;
1715 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1717 // Update Python script
1718 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1719 << IDsOfElements << ", " << Diag13 << " )";
1721 CORBA::Boolean stat = getEditor().QuadToTri( faces, Diag13 );
1722 myMesh->GetMeshDS()->Modified();
1724 myMesh->SetIsModified( true ); // issue 0020693
1732 //=============================================================================
1736 //=============================================================================
1737 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1738 CORBA::Boolean Diag13)
1742 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
1744 SMESH::long_array_var anElementsId = theObject->GetIDs();
1745 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
1747 // Update Python script
1748 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
1749 << theObject << ", " << Diag13 << " )";
1755 //=============================================================================
1759 //=============================================================================
1760 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
1761 SMESH::NumericalFunctor_ptr Criterion)
1765 const SMDS_MeshElement* quad = getMeshDS()->FindElement(IDOfQuad);
1766 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
1768 SMESH::NumericalFunctor_i* aNumericalFunctor =
1769 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
1770 SMESH::Controls::NumericalFunctorPtr aCrit;
1771 if (aNumericalFunctor)
1772 aCrit = aNumericalFunctor->GetNumericalFunctor();
1774 aCrit.reset(new SMESH::Controls::AspectRatio());
1776 return getEditor().BestSplit(quad, aCrit);
1781 //================================================================================
1783 * \brief Split volumic elements into tetrahedrons
1785 //================================================================================
1787 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
1788 CORBA::Short methodFlags)
1789 throw (SALOME::SALOME_Exception)
1791 Unexpect aCatch(SALOME_SalomeException);
1795 SMESH::long_array_var anElementsId = elems->GetIDs();
1796 TIDSortedElemSet elemSet;
1797 arrayToSet( anElementsId, getMeshDS(), elemSet, SMDSAbs_Volume );
1799 getEditor().SplitVolumesIntoTetra( elemSet, int( methodFlags ));
1800 myMesh->GetMeshDS()->Modified();
1803 // if ( myLastCreatedElems.length() ) - it does not influence Compute()
1804 // myMesh->SetIsModified( true ); // issue 0020693
1806 TPythonDump() << this << ".SplitVolumesIntoTetra( "
1807 << elems << ", " << methodFlags << " )";
1810 //=======================================================================
1813 //=======================================================================
1816 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
1817 const SMESH::long_array & IDsOfFixedNodes,
1818 CORBA::Long MaxNbOfIterations,
1819 CORBA::Double MaxAspectRatio,
1820 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1822 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1823 MaxAspectRatio, Method, false );
1827 //=======================================================================
1828 //function : SmoothParametric
1830 //=======================================================================
1833 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
1834 const SMESH::long_array & IDsOfFixedNodes,
1835 CORBA::Long MaxNbOfIterations,
1836 CORBA::Double MaxAspectRatio,
1837 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1839 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1840 MaxAspectRatio, Method, true );
1844 //=======================================================================
1845 //function : SmoothObject
1847 //=======================================================================
1850 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
1851 const SMESH::long_array & IDsOfFixedNodes,
1852 CORBA::Long MaxNbOfIterations,
1853 CORBA::Double MaxAspectRatio,
1854 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1856 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1857 MaxAspectRatio, Method, false);
1861 //=======================================================================
1862 //function : SmoothParametricObject
1864 //=======================================================================
1867 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
1868 const SMESH::long_array & IDsOfFixedNodes,
1869 CORBA::Long MaxNbOfIterations,
1870 CORBA::Double MaxAspectRatio,
1871 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1873 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1874 MaxAspectRatio, Method, true);
1878 //=============================================================================
1882 //=============================================================================
1885 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
1886 const SMESH::long_array & IDsOfFixedNodes,
1887 CORBA::Long MaxNbOfIterations,
1888 CORBA::Double MaxAspectRatio,
1889 SMESH::SMESH_MeshEditor::Smooth_Method Method,
1894 SMESHDS_Mesh* aMesh = getMeshDS();
1896 TIDSortedElemSet elements;
1897 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
1899 set<const SMDS_MeshNode*> fixedNodes;
1900 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
1901 CORBA::Long index = IDsOfFixedNodes[i];
1902 const SMDS_MeshNode * node = aMesh->FindNode(index);
1904 fixedNodes.insert( node );
1906 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
1907 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
1908 method = ::SMESH_MeshEditor::CENTROIDAL;
1910 getEditor().Smooth(elements, fixedNodes, method,
1911 MaxNbOfIterations, MaxAspectRatio, IsParametric );
1913 myMesh->GetMeshDS()->Modified();
1914 myMesh->SetIsModified( true ); // issue 0020693
1917 // Update Python script
1918 TPythonDump() << "isDone = " << this << "."
1919 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
1920 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
1921 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
1922 << "SMESH.SMESH_MeshEditor."
1923 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1924 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1930 //=============================================================================
1934 //=============================================================================
1937 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
1938 const SMESH::long_array & IDsOfFixedNodes,
1939 CORBA::Long MaxNbOfIterations,
1940 CORBA::Double MaxAspectRatio,
1941 SMESH::SMESH_MeshEditor::Smooth_Method Method,
1946 TPythonDump aTPythonDump; // suppress dump in smooth()
1948 SMESH::long_array_var anElementsId = theObject->GetIDs();
1949 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
1950 MaxAspectRatio, Method, IsParametric);
1952 // Update Python script
1953 aTPythonDump << "isDone = " << this << "."
1954 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
1955 << theObject << ", " << IDsOfFixedNodes << ", "
1956 << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
1957 << "SMESH.SMESH_MeshEditor."
1958 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1959 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1965 //=============================================================================
1969 //=============================================================================
1971 void SMESH_MeshEditor_i::RenumberNodes()
1973 // Update Python script
1974 TPythonDump() << this << ".RenumberNodes()";
1976 getMeshDS()->Renumber( true );
1980 //=============================================================================
1984 //=============================================================================
1986 void SMESH_MeshEditor_i::RenumberElements()
1988 // Update Python script
1989 TPythonDump() << this << ".RenumberElements()";
1991 getMeshDS()->Renumber( false );
1994 //=======================================================================
1996 * \brief Return groups by their IDs
1998 //=======================================================================
2000 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
2004 myMesh_i->CreateGroupServants();
2005 return myMesh_i->GetGroups( *groupIDs );
2008 //=======================================================================
2009 //function : rotationSweep
2011 //=======================================================================
2013 SMESH::ListOfGroups*
2014 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
2015 const SMESH::AxisStruct & theAxis,
2016 CORBA::Double theAngleInRadians,
2017 CORBA::Long theNbOfSteps,
2018 CORBA::Double theTolerance,
2019 const bool theMakeGroups,
2020 const SMDSAbs_ElementType theElementType)
2024 TIDSortedElemSet inElements, copyElements;
2025 arrayToSet(theIDsOfElements, getMeshDS(), inElements, theElementType);
2027 TIDSortedElemSet* workElements = & inElements;
2028 bool makeWalls=true;
2029 if ( myIsPreviewMode )
2031 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2032 getPreviewMesh( SMDSAbs_Face )->Copy( inElements, copyElements, select, avoid );
2033 workElements = & copyElements;
2034 //makeWalls = false;
2037 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
2038 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
2040 ::SMESH_MeshEditor::PGroupIDs groupIds =
2041 getEditor().RotationSweep (*workElements, Ax1, theAngleInRadians,
2042 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
2043 myMesh->GetMeshDS()->Modified();
2045 // myMesh->SetIsModified( true ); -- it does not influence Compute()
2047 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2050 //=======================================================================
2051 //function : RotationSweep
2053 //=======================================================================
2055 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
2056 const SMESH::AxisStruct & theAxis,
2057 CORBA::Double theAngleInRadians,
2058 CORBA::Long theNbOfSteps,
2059 CORBA::Double theTolerance)
2061 if ( !myIsPreviewMode ) {
2062 TPythonDump() << this << ".RotationSweep( "
2063 << theIDsOfElements << ", "
2065 << TVar( theAngleInRadians ) << ", "
2066 << TVar( theNbOfSteps ) << ", "
2067 << TVar( theTolerance ) << " )";
2069 rotationSweep(theIDsOfElements,
2077 //=======================================================================
2078 //function : RotationSweepMakeGroups
2080 //=======================================================================
2082 SMESH::ListOfGroups*
2083 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2084 const SMESH::AxisStruct& theAxis,
2085 CORBA::Double theAngleInRadians,
2086 CORBA::Long theNbOfSteps,
2087 CORBA::Double theTolerance)
2089 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2091 SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
2097 if (!myIsPreviewMode) {
2098 DumpGroupsList(aPythonDump, aGroups);
2099 aPythonDump << this << ".RotationSweepMakeGroups( "
2100 << theIDsOfElements << ", "
2102 << TVar( theAngleInRadians ) << ", "
2103 << TVar( theNbOfSteps ) << ", "
2104 << TVar( theTolerance ) << " )";
2109 //=======================================================================
2110 //function : RotationSweepObject
2112 //=======================================================================
2114 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2115 const SMESH::AxisStruct & theAxis,
2116 CORBA::Double theAngleInRadians,
2117 CORBA::Long theNbOfSteps,
2118 CORBA::Double theTolerance)
2120 if ( !myIsPreviewMode ) {
2121 TPythonDump() << this << ".RotationSweepObject( "
2122 << theObject << ", "
2124 << theAngleInRadians << ", "
2125 << theNbOfSteps << ", "
2126 << theTolerance << " )";
2128 SMESH::long_array_var anElementsId = theObject->GetIDs();
2129 rotationSweep(anElementsId,
2137 //=======================================================================
2138 //function : RotationSweepObject1D
2140 //=======================================================================
2142 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2143 const SMESH::AxisStruct & theAxis,
2144 CORBA::Double theAngleInRadians,
2145 CORBA::Long theNbOfSteps,
2146 CORBA::Double theTolerance)
2148 if ( !myIsPreviewMode ) {
2149 TPythonDump() << this << ".RotationSweepObject1D( "
2150 << theObject << ", "
2152 << TVar( theAngleInRadians ) << ", "
2153 << TVar( theNbOfSteps ) << ", "
2154 << TVar( theTolerance ) << " )";
2156 SMESH::long_array_var anElementsId = theObject->GetIDs();
2157 rotationSweep(anElementsId,
2166 //=======================================================================
2167 //function : RotationSweepObject2D
2169 //=======================================================================
2171 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2172 const SMESH::AxisStruct & theAxis,
2173 CORBA::Double theAngleInRadians,
2174 CORBA::Long theNbOfSteps,
2175 CORBA::Double theTolerance)
2177 if ( !myIsPreviewMode ) {
2178 TPythonDump() << this << ".RotationSweepObject2D( "
2179 << theObject << ", "
2181 << TVar( theAngleInRadians ) << ", "
2182 << TVar( theNbOfSteps ) << ", "
2183 << TVar( theTolerance ) << " )";
2185 SMESH::long_array_var anElementsId = theObject->GetIDs();
2186 rotationSweep(anElementsId,
2195 //=======================================================================
2196 //function : RotationSweepObjectMakeGroups
2198 //=======================================================================
2200 SMESH::ListOfGroups*
2201 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2202 const SMESH::AxisStruct& theAxis,
2203 CORBA::Double theAngleInRadians,
2204 CORBA::Long theNbOfSteps,
2205 CORBA::Double theTolerance)
2207 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2209 SMESH::long_array_var anElementsId = theObject->GetIDs();
2210 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2216 if (!myIsPreviewMode) {
2217 DumpGroupsList(aPythonDump, aGroups);
2218 aPythonDump << this << ".RotationSweepObjectMakeGroups( "
2219 << theObject << ", "
2221 << theAngleInRadians << ", "
2222 << theNbOfSteps << ", "
2223 << theTolerance << " )";
2228 //=======================================================================
2229 //function : RotationSweepObject1DMakeGroups
2231 //=======================================================================
2233 SMESH::ListOfGroups*
2234 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2235 const SMESH::AxisStruct& theAxis,
2236 CORBA::Double theAngleInRadians,
2237 CORBA::Long theNbOfSteps,
2238 CORBA::Double theTolerance)
2240 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2242 SMESH::long_array_var anElementsId = theObject->GetIDs();
2243 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2250 if (!myIsPreviewMode) {
2251 DumpGroupsList(aPythonDump, aGroups);
2252 aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
2253 << theObject << ", "
2255 << TVar( theAngleInRadians ) << ", "
2256 << TVar( theNbOfSteps ) << ", "
2257 << TVar( theTolerance ) << " )";
2262 //=======================================================================
2263 //function : RotationSweepObject2DMakeGroups
2265 //=======================================================================
2267 SMESH::ListOfGroups*
2268 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2269 const SMESH::AxisStruct& theAxis,
2270 CORBA::Double theAngleInRadians,
2271 CORBA::Long theNbOfSteps,
2272 CORBA::Double theTolerance)
2274 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2276 SMESH::long_array_var anElementsId = theObject->GetIDs();
2277 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
2284 if (!myIsPreviewMode) {
2285 DumpGroupsList(aPythonDump, aGroups);
2286 aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
2287 << theObject << ", "
2289 << TVar( theAngleInRadians ) << ", "
2290 << TVar( theNbOfSteps ) << ", "
2291 << TVar( theTolerance ) << " )";
2297 //=======================================================================
2298 //function : extrusionSweep
2300 //=======================================================================
2302 SMESH::ListOfGroups*
2303 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
2304 const SMESH::DirStruct & theStepVector,
2305 CORBA::Long theNbOfSteps,
2307 const SMDSAbs_ElementType theElementType)
2315 TIDSortedElemSet elements, copyElements;
2316 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
2318 const SMESH::PointStruct * P = &theStepVector.PS;
2319 gp_Vec stepVec( P->x, P->y, P->z );
2321 TIDSortedElemSet* workElements = & elements;
2323 SMDSAbs_ElementType aType = SMDSAbs_Face;
2324 if (theElementType == SMDSAbs_Node)
2326 aType = SMDSAbs_Edge;
2328 if ( myIsPreviewMode ) {
2329 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2330 getPreviewMesh( aType )->Copy( elements, copyElements, select, avoid );
2331 workElements = & copyElements;
2332 theMakeGroups = false;
2335 TElemOfElemListMap aHystory;
2336 ::SMESH_MeshEditor::PGroupIDs groupIds =
2337 getEditor().ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
2339 myMesh->GetMeshDS()->Modified();
2341 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2343 } catch(Standard_Failure) {
2344 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2345 INFOS( "SMESH_MeshEditor_i::ExtrusionSweep fails - "<< aFail->GetMessageString() );
2350 //=======================================================================
2351 //function : ExtrusionSweep
2353 //=======================================================================
2355 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
2356 const SMESH::DirStruct & theStepVector,
2357 CORBA::Long theNbOfSteps)
2359 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
2360 if (!myIsPreviewMode) {
2361 TPythonDump() << this << ".ExtrusionSweep( "
2362 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps) << " )";
2366 //=======================================================================
2367 //function : ExtrusionSweep0D
2369 //=======================================================================
2371 void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElements,
2372 const SMESH::DirStruct & theStepVector,
2373 CORBA::Long theNbOfSteps)
2375 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2376 if (!myIsPreviewMode) {
2377 TPythonDump() << this << ".ExtrusionSweep0D( "
2378 << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps)<< " )";
2382 //=======================================================================
2383 //function : ExtrusionSweepObject
2385 //=======================================================================
2387 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
2388 const SMESH::DirStruct & theStepVector,
2389 CORBA::Long theNbOfSteps)
2391 SMESH::long_array_var anElementsId = theObject->GetIDs();
2392 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
2393 if (!myIsPreviewMode) {
2394 TPythonDump() << this << ".ExtrusionSweepObject( "
2395 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
2399 //=======================================================================
2400 //function : ExtrusionSweepObject0D
2402 //=======================================================================
2404 void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObject,
2405 const SMESH::DirStruct & theStepVector,
2406 CORBA::Long theNbOfSteps)
2408 SMESH::long_array_var anElementsId = theObject->GetIDs();
2409 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
2410 if ( !myIsPreviewMode ) {
2411 TPythonDump() << this << ".ExtrusionSweepObject0D( "
2412 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2416 //=======================================================================
2417 //function : ExtrusionSweepObject1D
2419 //=======================================================================
2421 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
2422 const SMESH::DirStruct & theStepVector,
2423 CORBA::Long theNbOfSteps)
2425 SMESH::long_array_var anElementsId = theObject->GetIDs();
2426 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
2427 if ( !myIsPreviewMode ) {
2428 TPythonDump() << this << ".ExtrusionSweepObject1D( "
2429 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2433 //=======================================================================
2434 //function : ExtrusionSweepObject2D
2436 //=======================================================================
2438 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
2439 const SMESH::DirStruct & theStepVector,
2440 CORBA::Long theNbOfSteps)
2442 SMESH::long_array_var anElementsId = theObject->GetIDs();
2443 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
2444 if ( !myIsPreviewMode ) {
2445 TPythonDump() << this << ".ExtrusionSweepObject2D( "
2446 << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2450 //=======================================================================
2451 //function : ExtrusionSweepMakeGroups
2453 //=======================================================================
2455 SMESH::ListOfGroups*
2456 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
2457 const SMESH::DirStruct& theStepVector,
2458 CORBA::Long theNbOfSteps)
2460 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2462 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
2464 if (!myIsPreviewMode) {
2465 DumpGroupsList(aPythonDump, aGroups);
2466 aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
2467 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2472 //=======================================================================
2473 //function : ExtrusionSweepMakeGroups0D
2475 //=======================================================================
2477 SMESH::ListOfGroups*
2478 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups0D(const SMESH::long_array& theIDsOfElements,
2479 const SMESH::DirStruct& theStepVector,
2480 CORBA::Long theNbOfSteps)
2482 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2484 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true,SMDSAbs_Node);
2486 if (!myIsPreviewMode) {
2487 DumpGroupsList(aPythonDump, aGroups);
2488 aPythonDump << this << ".ExtrusionSweepMakeGroups0D( " << theIDsOfElements
2489 << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
2494 //=======================================================================
2495 //function : ExtrusionSweepObjectMakeGroups
2497 //=======================================================================
2499 SMESH::ListOfGroups*
2500 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2501 const SMESH::DirStruct& theStepVector,
2502 CORBA::Long theNbOfSteps)
2504 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2506 SMESH::long_array_var anElementsId = theObject->GetIDs();
2507 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
2509 if (!myIsPreviewMode) {
2510 DumpGroupsList(aPythonDump, aGroups);
2511 aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
2512 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2517 //=======================================================================
2518 //function : ExtrusionSweepObject0DMakeGroups
2520 //=======================================================================
2522 SMESH::ListOfGroups*
2523 SMESH_MeshEditor_i::ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2524 const SMESH::DirStruct& theStepVector,
2525 CORBA::Long theNbOfSteps)
2527 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2529 SMESH::long_array_var anElementsId = theObject->GetIDs();
2530 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2531 theNbOfSteps, true, SMDSAbs_Node);
2532 if (!myIsPreviewMode) {
2533 DumpGroupsList(aPythonDump, aGroups);
2534 aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject
2535 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2540 //=======================================================================
2541 //function : ExtrusionSweepObject1DMakeGroups
2543 //=======================================================================
2545 SMESH::ListOfGroups*
2546 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2547 const SMESH::DirStruct& theStepVector,
2548 CORBA::Long theNbOfSteps)
2550 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2552 SMESH::long_array_var anElementsId = theObject->GetIDs();
2553 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2554 theNbOfSteps, true, SMDSAbs_Edge);
2555 if (!myIsPreviewMode) {
2556 DumpGroupsList(aPythonDump, aGroups);
2557 aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
2558 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2563 //=======================================================================
2564 //function : ExtrusionSweepObject2DMakeGroups
2566 //=======================================================================
2568 SMESH::ListOfGroups*
2569 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2570 const SMESH::DirStruct& theStepVector,
2571 CORBA::Long theNbOfSteps)
2573 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2575 SMESH::long_array_var anElementsId = theObject->GetIDs();
2576 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2577 theNbOfSteps, true, SMDSAbs_Face);
2578 if (!myIsPreviewMode) {
2579 DumpGroupsList(aPythonDump, aGroups);
2580 aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
2581 << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
2587 //=======================================================================
2588 //function : advancedExtrusion
2590 //=======================================================================
2592 SMESH::ListOfGroups*
2593 SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
2594 const SMESH::DirStruct & theStepVector,
2595 CORBA::Long theNbOfSteps,
2596 CORBA::Long theExtrFlags,
2597 CORBA::Double theSewTolerance,
2598 const bool theMakeGroups)
2602 TIDSortedElemSet elements;
2603 arrayToSet(theIDsOfElements, getMeshDS(), elements);
2605 const SMESH::PointStruct * P = &theStepVector.PS;
2606 gp_Vec stepVec( P->x, P->y, P->z );
2608 TElemOfElemListMap aHystory;
2609 ::SMESH_MeshEditor::PGroupIDs groupIds =
2610 getEditor().ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
2611 theMakeGroups, theExtrFlags, theSewTolerance);
2613 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2616 //=======================================================================
2617 //function : AdvancedExtrusion
2619 //=======================================================================
2621 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2622 const SMESH::DirStruct & theStepVector,
2623 CORBA::Long theNbOfSteps,
2624 CORBA::Long theExtrFlags,
2625 CORBA::Double theSewTolerance)
2627 if ( !myIsPreviewMode ) {
2628 TPythonDump() << "stepVector = " << theStepVector;
2629 TPythonDump() << this << ".AdvancedExtrusion("
2632 << theNbOfSteps << ","
2633 << theExtrFlags << ", "
2634 << theSewTolerance << " )";
2636 advancedExtrusion( theIDsOfElements,
2644 //=======================================================================
2645 //function : AdvancedExtrusionMakeGroups
2647 //=======================================================================
2648 SMESH::ListOfGroups*
2649 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
2650 const SMESH::DirStruct& theStepVector,
2651 CORBA::Long theNbOfSteps,
2652 CORBA::Long theExtrFlags,
2653 CORBA::Double theSewTolerance)
2655 if (!myIsPreviewMode) {
2656 TPythonDump() << "stepVector = " << theStepVector;
2658 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2660 SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
2667 if (!myIsPreviewMode) {
2668 DumpGroupsList(aPythonDump, aGroups);
2669 aPythonDump << this << ".AdvancedExtrusionMakeGroups("
2672 << theNbOfSteps << ","
2673 << theExtrFlags << ", "
2674 << theSewTolerance << " )";
2680 //================================================================================
2682 * \brief Convert extrusion error to IDL enum
2684 //================================================================================
2686 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
2688 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
2692 RETCASE( EXTR_NO_ELEMENTS );
2693 RETCASE( EXTR_PATH_NOT_EDGE );
2694 RETCASE( EXTR_BAD_PATH_SHAPE );
2695 RETCASE( EXTR_BAD_STARTING_NODE );
2696 RETCASE( EXTR_BAD_ANGLES_NUMBER );
2697 RETCASE( EXTR_CANT_GET_TANGENT );
2699 return SMESH::SMESH_MeshEditor::EXTR_OK;
2703 //=======================================================================
2704 //function : extrusionAlongPath
2706 //=======================================================================
2707 SMESH::ListOfGroups*
2708 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2709 SMESH::SMESH_Mesh_ptr thePathMesh,
2710 GEOM::GEOM_Object_ptr thePathShape,
2711 CORBA::Long theNodeStart,
2712 CORBA::Boolean theHasAngles,
2713 const SMESH::double_array & theAngles,
2714 CORBA::Boolean theHasRefPoint,
2715 const SMESH::PointStruct & theRefPoint,
2716 const bool theMakeGroups,
2717 SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
2718 const SMDSAbs_ElementType theElementType)
2720 MESSAGE("extrusionAlongPath");
2723 if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
2724 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2727 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2729 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2730 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2732 if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
2733 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2737 SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
2739 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2743 TIDSortedElemSet elements;
2744 arrayToSet(theIDsOfElements, getMeshDS(), elements, theElementType);
2746 list<double> angles;
2747 for (int i = 0; i < theAngles.length(); i++) {
2748 angles.push_back( theAngles[i] );
2751 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
2753 int nbOldGroups = myMesh->NbGroup();
2755 ::SMESH_MeshEditor::Extrusion_Error error =
2756 getEditor().ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
2757 theHasAngles, angles, false,
2758 theHasRefPoint, refPnt, theMakeGroups );
2759 myMesh->GetMeshDS()->Modified();
2760 theError = convExtrError( error );
2762 if ( theMakeGroups ) {
2763 list<int> groupIDs = myMesh->GetGroupIds();
2764 list<int>::iterator newBegin = groupIDs.begin();
2765 std::advance( newBegin, nbOldGroups ); // skip old groups
2766 groupIDs.erase( groupIDs.begin(), newBegin );
2767 return getGroups( & groupIDs );
2773 //=======================================================================
2774 //function : extrusionAlongPathX
2776 //=======================================================================
2777 SMESH::ListOfGroups*
2778 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements,
2779 SMESH::SMESH_IDSource_ptr Path,
2780 CORBA::Long NodeStart,
2781 CORBA::Boolean HasAngles,
2782 const SMESH::double_array& Angles,
2783 CORBA::Boolean LinearVariation,
2784 CORBA::Boolean HasRefPoint,
2785 const SMESH::PointStruct& RefPoint,
2787 const SMDSAbs_ElementType ElementType,
2788 SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
2790 SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
2794 list<double> angles;
2795 for (int i = 0; i < Angles.length(); i++) {
2796 angles.push_back( Angles[i] );
2798 gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
2799 int nbOldGroups = myMesh->NbGroup();
2801 if ( Path->_is_nil() ) {
2802 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2806 TIDSortedElemSet elements, copyElements;
2807 arrayToSet(IDsOfElements, getMeshDS(), elements, ElementType);
2809 TIDSortedElemSet* workElements = &elements;
2811 if ( myIsPreviewMode )
2813 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2814 getPreviewMesh( SMDSAbs_Face )->Copy( elements, copyElements, select, avoid );
2815 workElements = & copyElements;
2819 ::SMESH_MeshEditor::Extrusion_Error error;
2821 if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path ))
2824 SMDS_MeshNode* aNodeStart =
2825 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2826 if ( !aNodeStart ) {
2827 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2830 error = getEditor().ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
2831 HasAngles, angles, LinearVariation,
2832 HasRefPoint, refPnt, MakeGroups );
2833 myMesh->GetMeshDS()->Modified();
2835 else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
2838 SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
2839 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
2840 SMDS_MeshNode* aNodeStart =
2841 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2842 if ( !aNodeStart ) {
2843 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2846 SMESH_subMesh* aSubMesh =
2847 aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
2848 error = getEditor().ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
2849 HasAngles, angles, LinearVariation,
2850 HasRefPoint, refPnt, MakeGroups );
2851 myMesh->GetMeshDS()->Modified();
2853 else if ( SMESH::DownCast<SMESH_Group_i*>( Path ))
2855 // path as group of 1D elements
2861 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2865 Error = convExtrError( error );
2868 list<int> groupIDs = myMesh->GetGroupIds();
2869 list<int>::iterator newBegin = groupIDs.begin();
2870 std::advance( newBegin, nbOldGroups ); // skip old groups
2871 groupIDs.erase( groupIDs.begin(), newBegin );
2872 return getGroups( & groupIDs );
2878 //=======================================================================
2879 //function : ExtrusionAlongPath
2881 //=======================================================================
2882 SMESH::SMESH_MeshEditor::Extrusion_Error
2883 SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2884 SMESH::SMESH_Mesh_ptr thePathMesh,
2885 GEOM::GEOM_Object_ptr thePathShape,
2886 CORBA::Long theNodeStart,
2887 CORBA::Boolean theHasAngles,
2888 const SMESH::double_array & theAngles,
2889 CORBA::Boolean theHasRefPoint,
2890 const SMESH::PointStruct & theRefPoint)
2892 MESSAGE("ExtrusionAlongPath");
2893 if ( !myIsPreviewMode ) {
2894 TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
2895 << theIDsOfElements << ", "
2896 << thePathMesh << ", "
2897 << thePathShape << ", "
2898 << theNodeStart << ", "
2899 << theHasAngles << ", "
2900 << theAngles << ", "
2901 << theHasRefPoint << ", "
2902 << "SMESH.PointStruct( "
2903 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2904 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2905 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2907 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2908 extrusionAlongPath( theIDsOfElements,
2921 //=======================================================================
2922 //function : ExtrusionAlongPathObject
2924 //=======================================================================
2925 SMESH::SMESH_MeshEditor::Extrusion_Error
2926 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject,
2927 SMESH::SMESH_Mesh_ptr thePathMesh,
2928 GEOM::GEOM_Object_ptr thePathShape,
2929 CORBA::Long theNodeStart,
2930 CORBA::Boolean theHasAngles,
2931 const SMESH::double_array & theAngles,
2932 CORBA::Boolean theHasRefPoint,
2933 const SMESH::PointStruct & theRefPoint)
2935 if ( !myIsPreviewMode ) {
2936 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
2937 << theObject << ", "
2938 << thePathMesh << ", "
2939 << thePathShape << ", "
2940 << theNodeStart << ", "
2941 << theHasAngles << ", "
2942 << theAngles << ", "
2943 << theHasRefPoint << ", "
2944 << "SMESH.PointStruct( "
2945 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2946 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2947 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2949 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2950 SMESH::long_array_var anElementsId = theObject->GetIDs();
2951 extrusionAlongPath( anElementsId,
2964 //=======================================================================
2965 //function : ExtrusionAlongPathObject1D
2967 //=======================================================================
2968 SMESH::SMESH_MeshEditor::Extrusion_Error
2969 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject,
2970 SMESH::SMESH_Mesh_ptr thePathMesh,
2971 GEOM::GEOM_Object_ptr thePathShape,
2972 CORBA::Long theNodeStart,
2973 CORBA::Boolean theHasAngles,
2974 const SMESH::double_array & theAngles,
2975 CORBA::Boolean theHasRefPoint,
2976 const SMESH::PointStruct & theRefPoint)
2978 if ( !myIsPreviewMode ) {
2979 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
2980 << theObject << ", "
2981 << thePathMesh << ", "
2982 << thePathShape << ", "
2983 << theNodeStart << ", "
2984 << theHasAngles << ", "
2985 << theAngles << ", "
2986 << theHasRefPoint << ", "
2987 << "SMESH.PointStruct( "
2988 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2989 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2990 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2992 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2993 SMESH::long_array_var anElementsId = theObject->GetIDs();
2994 extrusionAlongPath( anElementsId,
3008 //=======================================================================
3009 //function : ExtrusionAlongPathObject2D
3011 //=======================================================================
3012 SMESH::SMESH_MeshEditor::Extrusion_Error
3013 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject,
3014 SMESH::SMESH_Mesh_ptr thePathMesh,
3015 GEOM::GEOM_Object_ptr thePathShape,
3016 CORBA::Long theNodeStart,
3017 CORBA::Boolean theHasAngles,
3018 const SMESH::double_array & theAngles,
3019 CORBA::Boolean theHasRefPoint,
3020 const SMESH::PointStruct & theRefPoint)
3022 if ( !myIsPreviewMode ) {
3023 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
3024 << theObject << ", "
3025 << thePathMesh << ", "
3026 << thePathShape << ", "
3027 << theNodeStart << ", "
3028 << theHasAngles << ", "
3029 << theAngles << ", "
3030 << theHasRefPoint << ", "
3031 << "SMESH.PointStruct( "
3032 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3033 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3034 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3036 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
3037 SMESH::long_array_var anElementsId = theObject->GetIDs();
3038 extrusionAlongPath( anElementsId,
3053 //=======================================================================
3054 //function : ExtrusionAlongPathMakeGroups
3056 //=======================================================================
3057 SMESH::ListOfGroups*
3058 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theIDsOfElements,
3059 SMESH::SMESH_Mesh_ptr thePathMesh,
3060 GEOM::GEOM_Object_ptr thePathShape,
3061 CORBA::Long theNodeStart,
3062 CORBA::Boolean theHasAngles,
3063 const SMESH::double_array& theAngles,
3064 CORBA::Boolean theHasRefPoint,
3065 const SMESH::PointStruct& theRefPoint,
3066 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3068 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3070 SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements,
3080 if (!myIsPreviewMode) {
3081 bool isDumpGroups = aGroups && aGroups->length() > 0;
3083 aPythonDump << "(" << aGroups << ", error)";
3085 aPythonDump <<"error";
3087 aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
3088 << theIDsOfElements << ", "
3089 << thePathMesh << ", "
3090 << thePathShape << ", "
3091 << theNodeStart << ", "
3092 << theHasAngles << ", "
3093 << theAngles << ", "
3094 << theHasRefPoint << ", "
3095 << "SMESH.PointStruct( "
3096 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3097 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3098 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3103 //=======================================================================
3104 //function : ExtrusionAlongPathObjectMakeGroups
3106 //=======================================================================
3107 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3108 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3109 SMESH::SMESH_Mesh_ptr thePathMesh,
3110 GEOM::GEOM_Object_ptr thePathShape,
3111 CORBA::Long theNodeStart,
3112 CORBA::Boolean theHasAngles,
3113 const SMESH::double_array& theAngles,
3114 CORBA::Boolean theHasRefPoint,
3115 const SMESH::PointStruct& theRefPoint,
3116 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3118 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3120 SMESH::long_array_var anElementsId = theObject->GetIDs();
3121 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3132 if (!myIsPreviewMode) {
3133 bool isDumpGroups = aGroups && aGroups->length() > 0;
3135 aPythonDump << "(" << aGroups << ", error)";
3137 aPythonDump <<"error";
3139 aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
3140 << theObject << ", "
3141 << thePathMesh << ", "
3142 << thePathShape << ", "
3143 << theNodeStart << ", "
3144 << theHasAngles << ", "
3145 << theAngles << ", "
3146 << theHasRefPoint << ", "
3147 << "SMESH.PointStruct( "
3148 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3149 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3150 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3155 //=======================================================================
3156 //function : ExtrusionAlongPathObject1DMakeGroups
3158 //=======================================================================
3159 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3160 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3161 SMESH::SMESH_Mesh_ptr thePathMesh,
3162 GEOM::GEOM_Object_ptr thePathShape,
3163 CORBA::Long theNodeStart,
3164 CORBA::Boolean theHasAngles,
3165 const SMESH::double_array& theAngles,
3166 CORBA::Boolean theHasRefPoint,
3167 const SMESH::PointStruct& theRefPoint,
3168 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3170 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3172 SMESH::long_array_var anElementsId = theObject->GetIDs();
3173 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3185 if (!myIsPreviewMode) {
3186 bool isDumpGroups = aGroups && aGroups->length() > 0;
3188 aPythonDump << "(" << aGroups << ", error)";
3190 aPythonDump << "error";
3192 aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
3193 << theObject << ", "
3194 << thePathMesh << ", "
3195 << thePathShape << ", "
3196 << theNodeStart << ", "
3197 << theHasAngles << ", "
3198 << theAngles << ", "
3199 << theHasRefPoint << ", "
3200 << "SMESH.PointStruct( "
3201 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3202 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3203 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3208 //=======================================================================
3209 //function : ExtrusionAlongPathObject2DMakeGroups
3211 //=======================================================================
3212 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3213 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3214 SMESH::SMESH_Mesh_ptr thePathMesh,
3215 GEOM::GEOM_Object_ptr thePathShape,
3216 CORBA::Long theNodeStart,
3217 CORBA::Boolean theHasAngles,
3218 const SMESH::double_array& theAngles,
3219 CORBA::Boolean theHasRefPoint,
3220 const SMESH::PointStruct& theRefPoint,
3221 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3223 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3225 SMESH::long_array_var anElementsId = theObject->GetIDs();
3226 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
3238 if (!myIsPreviewMode) {
3239 bool isDumpGroups = aGroups && aGroups->length() > 0;
3241 aPythonDump << "(" << aGroups << ", error)";
3243 aPythonDump << "error";
3245 aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
3246 << theObject << ", "
3247 << thePathMesh << ", "
3248 << thePathShape << ", "
3249 << theNodeStart << ", "
3250 << theHasAngles << ", "
3251 << theAngles << ", "
3252 << theHasRefPoint << ", "
3253 << "SMESH.PointStruct( "
3254 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
3255 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
3256 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
3262 //=======================================================================
3263 //function : ExtrusionAlongPathObjX
3265 //=======================================================================
3266 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3267 ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr Object,
3268 SMESH::SMESH_IDSource_ptr Path,
3269 CORBA::Long NodeStart,
3270 CORBA::Boolean HasAngles,
3271 const SMESH::double_array& Angles,
3272 CORBA::Boolean LinearVariation,
3273 CORBA::Boolean HasRefPoint,
3274 const SMESH::PointStruct& RefPoint,
3275 CORBA::Boolean MakeGroups,
3276 SMESH::ElementType ElemType,
3277 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3279 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3281 SMESH::long_array_var anElementsId = Object->GetIDs();
3282 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
3291 (SMDSAbs_ElementType)ElemType,
3294 if (!myIsPreviewMode) {
3295 bool isDumpGroups = aGroups && aGroups->length() > 0;
3297 aPythonDump << "(" << *aGroups << ", error)";
3299 aPythonDump << "error";
3301 aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
3304 << NodeStart << ", "
3305 << HasAngles << ", "
3306 << TVar( Angles ) << ", "
3307 << LinearVariation << ", "
3308 << HasRefPoint << ", "
3309 << "SMESH.PointStruct( "
3310 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3311 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3312 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3313 << MakeGroups << ", "
3314 << ElemType << " )";
3320 //=======================================================================
3321 //function : ExtrusionAlongPathX
3323 //=======================================================================
3324 SMESH::ListOfGroups* SMESH_MeshEditor_i::
3325 ExtrusionAlongPathX(const SMESH::long_array& IDsOfElements,
3326 SMESH::SMESH_IDSource_ptr Path,
3327 CORBA::Long NodeStart,
3328 CORBA::Boolean HasAngles,
3329 const SMESH::double_array& Angles,
3330 CORBA::Boolean LinearVariation,
3331 CORBA::Boolean HasRefPoint,
3332 const SMESH::PointStruct& RefPoint,
3333 CORBA::Boolean MakeGroups,
3334 SMESH::ElementType ElemType,
3335 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
3337 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3339 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
3348 (SMDSAbs_ElementType)ElemType,
3351 if (!myIsPreviewMode) {
3352 bool isDumpGroups = aGroups && aGroups->length() > 0;
3354 aPythonDump << "(" << *aGroups << ", error)";
3356 aPythonDump <<"error";
3358 aPythonDump << " = " << this << ".ExtrusionAlongPathX( "
3359 << IDsOfElements << ", "
3361 << NodeStart << ", "
3362 << HasAngles << ", "
3363 << TVar( Angles ) << ", "
3364 << LinearVariation << ", "
3365 << HasRefPoint << ", "
3366 << "SMESH.PointStruct( "
3367 << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
3368 << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
3369 << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
3370 << MakeGroups << ", "
3371 << ElemType << " )";
3377 //================================================================================
3379 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
3380 * of given angles along path steps
3381 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
3382 * which proceeds the extrusion
3383 * \param PathShape is shape(edge); as the mesh can be complex, the edge
3384 * is used to define the sub-mesh for the path
3386 //================================================================================
3388 SMESH::double_array*
3389 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
3390 GEOM::GEOM_Object_ptr thePathShape,
3391 const SMESH::double_array & theAngles)
3393 SMESH::double_array_var aResult = new SMESH::double_array();
3394 int nbAngles = theAngles.length();
3395 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
3397 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
3398 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
3399 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
3400 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
3401 return aResult._retn();
3402 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
3403 if ( nbSteps == nbAngles )
3405 aResult.inout() = theAngles;
3409 aResult->length( nbSteps );
3410 double rAn2St = double( nbAngles ) / double( nbSteps );
3411 double angPrev = 0, angle;
3412 for ( int iSt = 0; iSt < nbSteps; ++iSt )
3414 double angCur = rAn2St * ( iSt+1 );
3415 double angCurFloor = floor( angCur );
3416 double angPrevFloor = floor( angPrev );
3417 if ( angPrevFloor == angCurFloor )
3418 angle = rAn2St * theAngles[ int( angCurFloor ) ];
3421 int iP = int( angPrevFloor );
3422 double angPrevCeil = ceil(angPrev);
3423 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
3425 int iC = int( angCurFloor );
3426 if ( iC < nbAngles )
3427 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
3429 iP = int( angPrevCeil );
3431 angle += theAngles[ iC ];
3433 aResult[ iSt ] = angle;
3438 // Update Python script
3439 TPythonDump() << "rotAngles = " << theAngles;
3440 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
3441 << thePathMesh << ", "
3442 << thePathShape << ", "
3445 return aResult._retn();
3449 //=======================================================================
3452 //=======================================================================
3454 SMESH::ListOfGroups*
3455 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
3456 const SMESH::AxisStruct & theAxis,
3457 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3458 CORBA::Boolean theCopy,
3460 ::SMESH_Mesh* theTargetMesh)
3464 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3465 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3467 if ( theTargetMesh )
3471 switch ( theMirrorType ) {
3472 case SMESH::SMESH_MeshEditor::POINT:
3473 aTrsf.SetMirror( P );
3475 case SMESH::SMESH_MeshEditor::AXIS:
3476 aTrsf.SetMirror( gp_Ax1( P, V ));
3479 aTrsf.SetMirror( gp_Ax2( P, V ));
3482 TIDSortedElemSet copyElements;
3483 TIDSortedElemSet* workElements = & theElements;
3485 if ( myIsPreviewMode )
3487 TPreviewMesh * tmpMesh = getPreviewMesh();
3488 tmpMesh->Copy( theElements, copyElements);
3489 if ( !theCopy && !theTargetMesh )
3491 TIDSortedElemSet elemsAround, elemsAroundCopy;
3492 getElementsAround( theElements, getMeshDS(), elemsAround );
3493 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3495 workElements = & copyElements;
3496 theMakeGroups = false;
3499 ::SMESH_MeshEditor::PGroupIDs groupIds =
3500 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3502 if ( theCopy && !myIsPreviewMode)
3504 if ( theTargetMesh )
3506 theTargetMesh->GetMeshDS()->Modified();
3510 myMesh->GetMeshDS()->Modified();
3511 myMesh->SetIsModified( true );
3514 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3517 //=======================================================================
3520 //=======================================================================
3522 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3523 const SMESH::AxisStruct & theAxis,
3524 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3525 CORBA::Boolean theCopy)
3527 if ( !myIsPreviewMode ) {
3528 TPythonDump() << this << ".Mirror( "
3529 << theIDsOfElements << ", "
3531 << mirrorTypeName(theMirrorType) << ", "
3534 if ( theIDsOfElements.length() > 0 )
3536 TIDSortedElemSet elements;
3537 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3538 mirror(elements, theAxis, theMirrorType, theCopy, false);
3543 //=======================================================================
3544 //function : MirrorObject
3546 //=======================================================================
3548 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3549 const SMESH::AxisStruct & theAxis,
3550 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3551 CORBA::Boolean theCopy)
3553 if ( !myIsPreviewMode ) {
3554 TPythonDump() << this << ".MirrorObject( "
3555 << theObject << ", "
3557 << mirrorTypeName(theMirrorType) << ", "
3560 TIDSortedElemSet elements;
3562 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3564 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3565 mirror(elements, theAxis, theMirrorType, theCopy, false);
3568 //=======================================================================
3569 //function : MirrorMakeGroups
3571 //=======================================================================
3573 SMESH::ListOfGroups*
3574 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3575 const SMESH::AxisStruct& theMirror,
3576 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3578 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3580 SMESH::ListOfGroups * aGroups = 0;
3581 if ( theIDsOfElements.length() > 0 )
3583 TIDSortedElemSet elements;
3584 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3585 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3587 if (!myIsPreviewMode) {
3588 DumpGroupsList(aPythonDump, aGroups);
3589 aPythonDump << this << ".MirrorMakeGroups( "
3590 << theIDsOfElements << ", "
3591 << theMirror << ", "
3592 << mirrorTypeName(theMirrorType) << " )";
3597 //=======================================================================
3598 //function : MirrorObjectMakeGroups
3600 //=======================================================================
3602 SMESH::ListOfGroups*
3603 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3604 const SMESH::AxisStruct& theMirror,
3605 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3607 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3609 SMESH::ListOfGroups * aGroups = 0;
3610 TIDSortedElemSet elements;
3611 if ( idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3612 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3614 if (!myIsPreviewMode)
3616 DumpGroupsList(aPythonDump,aGroups);
3617 aPythonDump << this << ".MirrorObjectMakeGroups( "
3618 << theObject << ", "
3619 << theMirror << ", "
3620 << mirrorTypeName(theMirrorType) << " )";
3625 //=======================================================================
3626 //function : MirrorMakeMesh
3628 //=======================================================================
3630 SMESH::SMESH_Mesh_ptr
3631 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
3632 const SMESH::AxisStruct& theMirror,
3633 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3634 CORBA::Boolean theCopyGroups,
3635 const char* theMeshName)
3637 SMESH_Mesh_i* mesh_i;
3638 SMESH::SMESH_Mesh_var mesh;
3639 { // open new scope to dump "MakeMesh" command
3640 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3642 TPythonDump pydump; // to prevent dump at mesh creation
3644 mesh = makeMesh( theMeshName );
3645 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3646 if (mesh_i && theIDsOfElements.length() > 0 )
3648 TIDSortedElemSet elements;
3649 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3650 mirror(elements, theMirror, theMirrorType,
3651 false, theCopyGroups, & mesh_i->GetImpl());
3652 mesh_i->CreateGroupServants();
3655 if (!myIsPreviewMode) {
3656 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
3657 << theIDsOfElements << ", "
3658 << theMirror << ", "
3659 << mirrorTypeName(theMirrorType) << ", "
3660 << theCopyGroups << ", '"
3661 << theMeshName << "' )";
3666 if (!myIsPreviewMode && mesh_i)
3667 mesh_i->GetGroups();
3669 return mesh._retn();
3672 //=======================================================================
3673 //function : MirrorObjectMakeMesh
3675 //=======================================================================
3677 SMESH::SMESH_Mesh_ptr
3678 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3679 const SMESH::AxisStruct& theMirror,
3680 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3681 CORBA::Boolean theCopyGroups,
3682 const char* theMeshName)
3684 SMESH_Mesh_i* mesh_i;
3685 SMESH::SMESH_Mesh_var mesh;
3686 { // open new scope to dump "MakeMesh" command
3687 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3689 TPythonDump pydump; // to prevent dump at mesh creation
3691 mesh = makeMesh( theMeshName );
3692 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3693 TIDSortedElemSet elements;
3695 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3697 mirror(elements, theMirror, theMirrorType,
3698 false, theCopyGroups, & mesh_i->GetImpl());
3699 mesh_i->CreateGroupServants();
3701 if (!myIsPreviewMode) {
3702 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
3703 << theObject << ", "
3704 << theMirror << ", "
3705 << mirrorTypeName(theMirrorType) << ", "
3706 << theCopyGroups << ", '"
3707 << theMeshName << "' )";
3712 if (!myIsPreviewMode && mesh_i)
3713 mesh_i->GetGroups();
3715 return mesh._retn();
3718 //=======================================================================
3719 //function : translate
3721 //=======================================================================
3723 SMESH::ListOfGroups*
3724 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
3725 const SMESH::DirStruct & theVector,
3726 CORBA::Boolean theCopy,
3728 ::SMESH_Mesh* theTargetMesh)
3732 if ( theTargetMesh )
3736 const SMESH::PointStruct * P = &theVector.PS;
3737 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
3739 TIDSortedElemSet copyElements;
3740 TIDSortedElemSet* workElements = &theElements;
3742 if ( myIsPreviewMode )
3744 TPreviewMesh * tmpMesh = getPreviewMesh();
3745 tmpMesh->Copy( theElements, copyElements);
3746 if ( !theCopy && !theTargetMesh )
3748 TIDSortedElemSet elemsAround, elemsAroundCopy;
3749 getElementsAround( theElements, getMeshDS(), elemsAround );
3750 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3752 workElements = & copyElements;
3753 theMakeGroups = false;
3756 ::SMESH_MeshEditor::PGroupIDs groupIds =
3757 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3759 if ( theCopy && !myIsPreviewMode )
3761 if ( theTargetMesh )
3763 theTargetMesh->GetMeshDS()->Modified();
3767 myMesh->GetMeshDS()->Modified();
3768 myMesh->SetIsModified( true );
3772 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3775 //=======================================================================
3776 //function : Translate
3778 //=======================================================================
3780 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
3781 const SMESH::DirStruct & theVector,
3782 CORBA::Boolean theCopy)
3784 if (!myIsPreviewMode) {
3785 TPythonDump() << this << ".Translate( "
3786 << theIDsOfElements << ", "
3787 << theVector << ", "
3790 if (theIDsOfElements.length()) {
3791 TIDSortedElemSet elements;
3792 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3793 translate(elements, theVector, theCopy, false);
3797 //=======================================================================
3798 //function : TranslateObject
3800 //=======================================================================
3802 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
3803 const SMESH::DirStruct & theVector,
3804 CORBA::Boolean theCopy)
3806 if (!myIsPreviewMode) {
3807 TPythonDump() << this << ".TranslateObject( "
3808 << theObject << ", "
3809 << theVector << ", "
3812 TIDSortedElemSet elements;
3814 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
3816 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3817 translate(elements, theVector, theCopy, false);
3820 //=======================================================================
3821 //function : TranslateMakeGroups
3823 //=======================================================================
3825 SMESH::ListOfGroups*
3826 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
3827 const SMESH::DirStruct& theVector)
3829 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3831 SMESH::ListOfGroups * aGroups = 0;
3832 if (theIDsOfElements.length()) {
3833 TIDSortedElemSet elements;
3834 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3835 aGroups = translate(elements,theVector,true,true);
3837 if (!myIsPreviewMode) {
3838 DumpGroupsList(aPythonDump, aGroups);
3839 aPythonDump << this << ".TranslateMakeGroups( "
3840 << theIDsOfElements << ", "
3841 << theVector << " )";
3846 //=======================================================================
3847 //function : TranslateObjectMakeGroups
3849 //=======================================================================
3851 SMESH::ListOfGroups*
3852 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3853 const SMESH::DirStruct& theVector)
3855 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3857 SMESH::ListOfGroups * aGroups = 0;
3858 TIDSortedElemSet elements;
3859 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3860 aGroups = translate(elements, theVector, true, true);
3862 if (!myIsPreviewMode) {
3863 DumpGroupsList(aPythonDump, aGroups);
3864 aPythonDump << this << ".TranslateObjectMakeGroups( "
3865 << theObject << ", "
3866 << theVector << " )";
3871 //=======================================================================
3872 //function : TranslateMakeMesh
3874 //=======================================================================
3876 SMESH::SMESH_Mesh_ptr
3877 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
3878 const SMESH::DirStruct& theVector,
3879 CORBA::Boolean theCopyGroups,
3880 const char* theMeshName)
3882 SMESH_Mesh_i* mesh_i;
3883 SMESH::SMESH_Mesh_var mesh;
3885 { // open new scope to dump "MakeMesh" command
3886 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3888 TPythonDump pydump; // to prevent dump at mesh creation
3890 mesh = makeMesh( theMeshName );
3891 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3893 if ( mesh_i && theIDsOfElements.length() )
3895 TIDSortedElemSet elements;
3896 arrayToSet(theIDsOfElements, getMeshDS(), elements);
3897 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
3898 mesh_i->CreateGroupServants();
3901 if ( !myIsPreviewMode ) {
3902 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
3903 << theIDsOfElements << ", "
3904 << theVector << ", "
3905 << theCopyGroups << ", '"
3906 << theMeshName << "' )";
3911 if (!myIsPreviewMode && mesh_i)
3912 mesh_i->GetGroups();
3914 return mesh._retn();
3917 //=======================================================================
3918 //function : TranslateObjectMakeMesh
3920 //=======================================================================
3922 SMESH::SMESH_Mesh_ptr
3923 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3924 const SMESH::DirStruct& theVector,
3925 CORBA::Boolean theCopyGroups,
3926 const char* theMeshName)
3928 SMESH_Mesh_i* mesh_i;
3929 SMESH::SMESH_Mesh_var mesh;
3930 { // open new scope to dump "MakeMesh" command
3931 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3933 TPythonDump pydump; // to prevent dump at mesh creation
3934 mesh = makeMesh( theMeshName );
3935 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3937 TIDSortedElemSet elements;
3939 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3941 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
3942 mesh_i->CreateGroupServants();
3944 if ( !myIsPreviewMode ) {
3945 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
3946 << theObject << ", "
3947 << theVector << ", "
3948 << theCopyGroups << ", '"
3949 << theMeshName << "' )";
3954 if (!myIsPreviewMode && mesh_i)
3955 mesh_i->GetGroups();
3957 return mesh._retn();
3960 //=======================================================================
3963 //=======================================================================
3965 SMESH::ListOfGroups*
3966 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
3967 const SMESH::AxisStruct & theAxis,
3968 CORBA::Double theAngle,
3969 CORBA::Boolean theCopy,
3971 ::SMESH_Mesh* theTargetMesh)
3975 if ( theTargetMesh )
3978 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3979 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3982 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
3984 TIDSortedElemSet copyElements;
3985 TIDSortedElemSet* workElements = &theElements;
3986 if ( myIsPreviewMode ) {
3987 TPreviewMesh * tmpMesh = getPreviewMesh();
3988 tmpMesh->Copy( theElements, copyElements );
3989 if ( !theCopy && !theTargetMesh )
3991 TIDSortedElemSet elemsAround, elemsAroundCopy;
3992 getElementsAround( theElements, getMeshDS(), elemsAround );
3993 tmpMesh->Copy( elemsAround, elemsAroundCopy);
3995 workElements = ©Elements;
3996 theMakeGroups = false;
3999 ::SMESH_MeshEditor::PGroupIDs groupIds =
4000 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4002 if ( theCopy && !myIsPreviewMode)
4004 if ( theTargetMesh )
4006 theTargetMesh->GetMeshDS()->Modified();
4010 myMesh->GetMeshDS()->Modified();
4011 myMesh->SetIsModified( true );
4015 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4018 //=======================================================================
4021 //=======================================================================
4023 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
4024 const SMESH::AxisStruct & theAxis,
4025 CORBA::Double theAngle,
4026 CORBA::Boolean theCopy)
4028 if (!myIsPreviewMode) {
4029 TPythonDump() << this << ".Rotate( "
4030 << theIDsOfElements << ", "
4032 << TVar( theAngle ) << ", "
4035 if (theIDsOfElements.length() > 0)
4037 TIDSortedElemSet elements;
4038 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4039 rotate(elements,theAxis,theAngle,theCopy,false);
4043 //=======================================================================
4044 //function : RotateObject
4046 //=======================================================================
4048 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
4049 const SMESH::AxisStruct & theAxis,
4050 CORBA::Double theAngle,
4051 CORBA::Boolean theCopy)
4053 if ( !myIsPreviewMode ) {
4054 TPythonDump() << this << ".RotateObject( "
4055 << theObject << ", "
4057 << TVar( theAngle ) << ", "
4060 TIDSortedElemSet elements;
4061 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4062 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4063 rotate(elements,theAxis,theAngle,theCopy,false);
4066 //=======================================================================
4067 //function : RotateMakeGroups
4069 //=======================================================================
4071 SMESH::ListOfGroups*
4072 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
4073 const SMESH::AxisStruct& theAxis,
4074 CORBA::Double theAngle)
4076 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4078 SMESH::ListOfGroups * aGroups = 0;
4079 if (theIDsOfElements.length() > 0)
4081 TIDSortedElemSet elements;
4082 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4083 aGroups = rotate(elements,theAxis,theAngle,true,true);
4085 if (!myIsPreviewMode) {
4086 DumpGroupsList(aPythonDump, aGroups);
4087 aPythonDump << this << ".RotateMakeGroups( "
4088 << theIDsOfElements << ", "
4090 << TVar( theAngle ) << " )";
4095 //=======================================================================
4096 //function : RotateObjectMakeGroups
4098 //=======================================================================
4100 SMESH::ListOfGroups*
4101 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4102 const SMESH::AxisStruct& theAxis,
4103 CORBA::Double theAngle)
4105 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4107 SMESH::ListOfGroups * aGroups = 0;
4108 TIDSortedElemSet elements;
4109 if (idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4110 aGroups = rotate(elements, theAxis, theAngle, true, true);
4112 if (!myIsPreviewMode) {
4113 DumpGroupsList(aPythonDump, aGroups);
4114 aPythonDump << this << ".RotateObjectMakeGroups( "
4115 << theObject << ", "
4117 << TVar( theAngle ) << " )";
4122 //=======================================================================
4123 //function : RotateMakeMesh
4125 //=======================================================================
4127 SMESH::SMESH_Mesh_ptr
4128 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
4129 const SMESH::AxisStruct& theAxis,
4130 CORBA::Double theAngleInRadians,
4131 CORBA::Boolean theCopyGroups,
4132 const char* theMeshName)
4134 SMESH::SMESH_Mesh_var mesh;
4135 SMESH_Mesh_i* mesh_i;
4137 { // open new scope to dump "MakeMesh" command
4138 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4140 TPythonDump pydump; // to prevent dump at mesh creation
4142 mesh = makeMesh( theMeshName );
4143 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4145 if ( mesh_i && theIDsOfElements.length() > 0 )
4147 TIDSortedElemSet elements;
4148 arrayToSet(theIDsOfElements, getMeshDS(), elements);
4149 rotate(elements, theAxis, theAngleInRadians,
4150 false, theCopyGroups, & mesh_i->GetImpl());
4151 mesh_i->CreateGroupServants();
4153 if ( !myIsPreviewMode ) {
4154 pydump << mesh << " = " << this << ".RotateMakeMesh( "
4155 << theIDsOfElements << ", "
4157 << TVar( theAngleInRadians ) << ", "
4158 << theCopyGroups << ", '"
4159 << theMeshName << "' )";
4164 if (!myIsPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
4165 mesh_i->GetGroups();
4167 return mesh._retn();
4170 //=======================================================================
4171 //function : RotateObjectMakeMesh
4173 //=======================================================================
4175 SMESH::SMESH_Mesh_ptr
4176 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4177 const SMESH::AxisStruct& theAxis,
4178 CORBA::Double theAngleInRadians,
4179 CORBA::Boolean theCopyGroups,
4180 const char* theMeshName)
4182 SMESH::SMESH_Mesh_var mesh;
4183 SMESH_Mesh_i* mesh_i;
4185 {// open new scope to dump "MakeMesh" command
4186 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4188 TPythonDump pydump; // to prevent dump at mesh creation
4189 mesh = makeMesh( theMeshName );
4190 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4192 TIDSortedElemSet elements;
4194 idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
4196 rotate(elements, theAxis, theAngleInRadians,
4197 false, theCopyGroups, & mesh_i->GetImpl());
4198 mesh_i->CreateGroupServants();
4200 if ( !myIsPreviewMode ) {
4201 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
4202 << theObject << ", "
4204 << TVar( theAngleInRadians ) << ", "
4205 << theCopyGroups << ", '"
4206 << theMeshName << "' )";
4211 if (!myIsPreviewMode && mesh_i)
4212 mesh_i->GetGroups();
4214 return mesh._retn();
4217 //=======================================================================
4220 //=======================================================================
4222 SMESH::ListOfGroups*
4223 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
4224 const SMESH::PointStruct& thePoint,
4225 const SMESH::double_array& theScaleFact,
4226 CORBA::Boolean theCopy,
4228 ::SMESH_Mesh* theTargetMesh)
4231 if ( theScaleFact.length() < 1 )
4232 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
4233 if ( theScaleFact.length() == 2 )
4234 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
4236 if ( theTargetMesh )
4239 TIDSortedElemSet elements;
4240 bool emptyIfIsMesh = myIsPreviewMode ? false : true;
4241 if ( !idSourceToSet(theObject, getMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
4246 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
4247 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
4249 double tol = std::numeric_limits<double>::max();
4251 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
4252 0, S[1], 0, thePoint.y * (1-S[1]),
4253 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
4255 TIDSortedElemSet copyElements;
4256 TIDSortedElemSet* workElements = &elements;
4257 if ( myIsPreviewMode )
4259 TPreviewMesh * tmpMesh = getPreviewMesh();
4260 tmpMesh->Copy( elements, copyElements);
4261 if ( !theCopy && !theTargetMesh )
4263 TIDSortedElemSet elemsAround, elemsAroundCopy;
4264 getElementsAround( elements, getMeshDS(), elemsAround );
4265 tmpMesh->Copy( elemsAround, elemsAroundCopy);
4267 workElements = & copyElements;
4268 theMakeGroups = false;
4271 ::SMESH_MeshEditor::PGroupIDs groupIds =
4272 getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
4274 if ( theCopy && !myIsPreviewMode )
4276 if ( theTargetMesh )
4278 theTargetMesh->GetMeshDS()->Modified();
4282 myMesh->GetMeshDS()->Modified();
4283 myMesh->SetIsModified( true );
4287 return theMakeGroups ? getGroups(groupIds.get()) : 0;
4290 //=======================================================================
4293 //=======================================================================
4295 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
4296 const SMESH::PointStruct& thePoint,
4297 const SMESH::double_array& theScaleFact,
4298 CORBA::Boolean theCopy)
4300 if ( !myIsPreviewMode ) {
4301 TPythonDump() << this << ".Scale( "
4302 << theObject << ", "
4304 << TVar( theScaleFact ) << ", "
4307 scale(theObject, thePoint, theScaleFact, theCopy, false);
4311 //=======================================================================
4312 //function : ScaleMakeGroups
4314 //=======================================================================
4316 SMESH::ListOfGroups*
4317 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
4318 const SMESH::PointStruct& thePoint,
4319 const SMESH::double_array& theScaleFact)
4321 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
4323 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
4324 if (!myIsPreviewMode) {
4325 DumpGroupsList(aPythonDump, aGroups);
4326 aPythonDump << this << ".Scale("
4329 << TVar( theScaleFact ) << ",True,True)";
4335 //=======================================================================
4336 //function : ScaleMakeMesh
4338 //=======================================================================
4340 SMESH::SMESH_Mesh_ptr
4341 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
4342 const SMESH::PointStruct& thePoint,
4343 const SMESH::double_array& theScaleFact,
4344 CORBA::Boolean theCopyGroups,
4345 const char* theMeshName)
4347 SMESH_Mesh_i* mesh_i;
4348 SMESH::SMESH_Mesh_var mesh;
4349 { // open new scope to dump "MakeMesh" command
4350 // and then "GetGroups" using SMESH_Mesh::GetGroups()
4352 TPythonDump pydump; // to prevent dump at mesh creation
4353 mesh = makeMesh( theMeshName );
4354 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4358 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
4359 mesh_i->CreateGroupServants();
4361 if ( !myIsPreviewMode )
4362 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
4363 << theObject << ", "
4365 << TVar( theScaleFact ) << ", "
4366 << theCopyGroups << ", '"
4367 << theMeshName << "' )";
4371 if (!myIsPreviewMode && mesh_i)
4372 mesh_i->GetGroups();
4374 return mesh._retn();
4378 //=======================================================================
4379 //function : FindCoincidentNodes
4381 //=======================================================================
4383 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance,
4384 SMESH::array_of_long_array_out GroupsOfNodes)
4388 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4389 TIDSortedNodeSet nodes; // no input nodes
4390 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4392 GroupsOfNodes = new SMESH::array_of_long_array;
4393 GroupsOfNodes->length( aListOfListOfNodes.size() );
4394 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4395 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
4396 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4397 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4398 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4399 aGroup.length( aListOfNodes.size() );
4400 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4401 aGroup[ j ] = (*lIt)->GetID();
4403 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
4404 << Tolerance << " )";
4407 //=======================================================================
4408 //function : FindCoincidentNodesOnPart
4410 //=======================================================================
4411 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
4412 CORBA::Double Tolerance,
4413 SMESH::array_of_long_array_out GroupsOfNodes)
4417 TIDSortedNodeSet nodes;
4418 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4420 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4422 getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
4424 GroupsOfNodes = new SMESH::array_of_long_array;
4425 GroupsOfNodes->length( aListOfListOfNodes.size() );
4426 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4427 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4429 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4430 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4431 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
4432 aGroup.length( aListOfNodes.size() );
4433 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4434 aGroup[ j ] = (*lIt)->GetID();
4436 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
4438 << Tolerance << " )";
4441 //================================================================================
4443 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
4444 * ExceptSubMeshOrGroups
4446 //================================================================================
4448 void SMESH_MeshEditor_i::
4449 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
4450 CORBA::Double theTolerance,
4451 SMESH::array_of_long_array_out theGroupsOfNodes,
4452 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups)
4456 TIDSortedNodeSet nodes;
4457 idSourceToNodeSet( theObject, getMeshDS(), nodes );
4459 for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
4461 TIDSortedNodeSet exceptNodes;
4462 idSourceToNodeSet( theExceptSubMeshOrGroups[i], getMeshDS(), exceptNodes );
4463 TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
4464 for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
4465 nodes.erase( *avoidNode );
4467 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4469 getEditor().FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
4471 theGroupsOfNodes = new SMESH::array_of_long_array;
4472 theGroupsOfNodes->length( aListOfListOfNodes.size() );
4473 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4474 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4476 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4477 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4478 SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
4479 aGroup.length( aListOfNodes.size() );
4480 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4481 aGroup[ j ] = (*lIt)->GetID();
4483 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
4485 << theTolerance << ", "
4486 << theExceptSubMeshOrGroups << " )";
4489 //=======================================================================
4490 //function : MergeNodes
4492 //=======================================================================
4494 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
4498 SMESHDS_Mesh* aMesh = getMeshDS();
4500 TPythonDump aTPythonDump;
4501 aTPythonDump << this << ".MergeNodes([";
4502 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4503 for (int i = 0; i < GroupsOfNodes.length(); i++)
4505 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
4506 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
4507 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
4508 for ( int j = 0; j < aNodeGroup.length(); j++ )
4510 CORBA::Long index = aNodeGroup[ j ];
4511 const SMDS_MeshNode * node = aMesh->FindNode(index);
4513 aListOfNodes.push_back( node );
4515 if ( aListOfNodes.size() < 2 )
4516 aListOfListOfNodes.pop_back();
4518 if ( i > 0 ) aTPythonDump << ", ";
4519 aTPythonDump << aNodeGroup;
4521 getEditor().MergeNodes( aListOfListOfNodes );
4523 aTPythonDump << "])";
4524 myMesh->GetMeshDS()->Modified();
4525 myMesh->SetIsModified( true );
4528 //=======================================================================
4529 //function : FindEqualElements
4531 //=======================================================================
4532 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
4533 SMESH::array_of_long_array_out GroupsOfElementsID)
4537 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
4538 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
4540 TIDSortedElemSet elems;
4541 idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true);
4543 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4544 getEditor().FindEqualElements( elems, aListOfListOfElementsID );
4546 GroupsOfElementsID = new SMESH::array_of_long_array;
4547 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
4549 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt =
4550 aListOfListOfElementsID.begin();
4551 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j)
4553 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
4554 list<int>& listOfIDs = *arraysIt;
4555 aGroup.length( listOfIDs.size() );
4556 list<int>::iterator idIt = listOfIDs.begin();
4557 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k )
4558 aGroup[ k ] = *idIt;
4561 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
4566 //=======================================================================
4567 //function : MergeElements
4569 //=======================================================================
4571 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
4575 TPythonDump aTPythonDump;
4576 aTPythonDump << this << ".MergeElements( [";
4578 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4580 for (int i = 0; i < GroupsOfElementsID.length(); i++) {
4581 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
4582 aListOfListOfElementsID.push_back( list< int >() );
4583 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
4584 for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
4585 CORBA::Long id = anElemsIDGroup[ j ];
4586 aListOfElemsID.push_back( id );
4588 if ( aListOfElemsID.size() < 2 )
4589 aListOfListOfElementsID.pop_back();
4590 if ( i > 0 ) aTPythonDump << ", ";
4591 aTPythonDump << anElemsIDGroup;
4594 getEditor().MergeElements(aListOfListOfElementsID);
4595 myMesh->GetMeshDS()->Modified();
4596 myMesh->SetIsModified( true );
4598 aTPythonDump << "] )";
4601 //=======================================================================
4602 //function : MergeEqualElements
4604 //=======================================================================
4606 void SMESH_MeshEditor_i::MergeEqualElements()
4610 getEditor().MergeEqualElements();
4612 myMesh->GetMeshDS()->Modified();
4614 TPythonDump() << this << ".MergeEqualElements()";
4617 //=============================================================================
4619 * Move the node to a given point
4621 //=============================================================================
4623 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
4628 initData(/*deleteSearchers=*/false);
4630 const SMDS_MeshNode * node = getMeshDS()->FindNode( NodeID );
4634 if ( theNodeSearcher )
4635 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4637 if ( myIsPreviewMode ) // make preview data
4639 // in a preview mesh, make edges linked to a node
4640 TPreviewMesh& tmpMesh = *getPreviewMesh();
4641 TIDSortedElemSet linkedNodes;
4642 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4643 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4644 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
4645 for ( ; nIt != linkedNodes.end(); ++nIt )
4647 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
4648 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
4652 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
4653 // fill preview data
4655 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4656 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4658 getMeshDS()->MoveNode(node, x, y, z);
4660 if ( !myIsPreviewMode )
4662 // Update Python script
4663 TPythonDump() << "isDone = " << this << ".MoveNode( "
4664 << NodeID << ", " << TVar(x) << ", " << TVar(y) << ", " << TVar(z) << " )";
4665 myMesh->GetMeshDS()->Modified();
4666 myMesh->SetIsModified( true );
4672 //================================================================================
4674 * \brief Return ID of node closest to a given point
4676 //================================================================================
4678 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
4682 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4684 if ( !theNodeSearcher ) {
4685 theNodeSearcher = myEditor.GetNodeSearcher();
4688 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
4689 return node->GetID();
4694 //================================================================================
4696 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
4697 * move the node closest to the point to point's location and return ID of the node
4699 //================================================================================
4701 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
4704 CORBA::Long theNodeID)
4706 // We keep theNodeSearcher until any mesh modification:
4707 // 1) initData() deletes theNodeSearcher at any edition,
4708 // 2) TSearchersDeleter - at any mesh compute event and mesh change
4710 initData(/*deleteSearchers=*/false);
4712 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4714 int nodeID = theNodeID;
4715 const SMDS_MeshNode* node = getMeshDS()->FindNode( nodeID );
4716 if ( !node ) // preview moving node
4718 if ( !theNodeSearcher ) {
4719 theNodeSearcher = myEditor.GetNodeSearcher();
4722 node = theNodeSearcher->FindClosestTo( p );
4725 nodeID = node->GetID();
4726 if ( myIsPreviewMode ) // make preview data
4728 // in a preview mesh, make edges linked to a node
4729 TPreviewMesh tmpMesh = *getPreviewMesh();
4730 TIDSortedElemSet linkedNodes;
4731 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4732 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4733 for ( ; nIt != linkedNodes.end(); ++nIt )
4735 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
4736 tmpMesh.Copy( &edge );
4739 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
4741 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
4742 // fill preview data
4744 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4746 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4750 getMeshDS()->MoveNode(node, x, y, z);
4754 if ( !myIsPreviewMode )
4756 TPythonDump() << "nodeID = " << this
4757 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
4758 << ", " << nodeID << " )";
4760 myMesh->GetMeshDS()->Modified();
4761 myMesh->SetIsModified( true );
4767 //=======================================================================
4769 * Return elements of given type where the given point is IN or ON.
4771 * 'ALL' type means elements of any type excluding nodes
4773 //=======================================================================
4775 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
4778 SMESH::ElementType type)
4780 SMESH::long_array_var res = new SMESH::long_array;
4781 vector< const SMDS_MeshElement* > foundElems;
4783 theSearchersDeleter.Set( myMesh );
4784 if ( !theElementSearcher ) {
4785 theElementSearcher = myEditor.GetElementSearcher();
4787 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4788 SMDSAbs_ElementType( type ),
4790 res->length( foundElems.size() );
4791 for ( int i = 0; i < foundElems.size(); ++i )
4792 res[i] = foundElems[i]->GetID();
4794 if ( !myIsPreviewMode ) // call from tui
4795 TPythonDump() << "res = " << this << ".FindElementsByPoint( "
4804 //=======================================================================
4805 //function : FindAmongElementsByPoint
4806 //purpose : Searching among the given elements, return elements of given type
4807 // where the given point is IN or ON.
4808 // 'ALL' type means elements of any type excluding nodes
4809 //=======================================================================
4812 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
4816 SMESH::ElementType type)
4818 SMESH::long_array_var res = new SMESH::long_array;
4820 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
4821 if ( types->length() == 1 && // a part contains only nodes or 0D elements
4822 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) &&
4823 type != types[0] ) // but search of elements of dim > 0
4826 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
4827 return FindElementsByPoint( x,y,z, type );
4829 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
4831 theSearchersDeleter.Set( myMesh, getPartIOR( elementIDs, type ));
4832 if ( !theElementSearcher )
4834 // create a searcher from elementIDs
4835 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
4836 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
4838 if ( !idSourceToSet( elementIDs, meshDS, elements,
4839 SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
4842 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
4843 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
4845 theElementSearcher = myEditor.GetElementSearcher(elemsIt);
4848 vector< const SMDS_MeshElement* > foundElems;
4850 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4851 SMDSAbs_ElementType( type ),
4853 res->length( foundElems.size() );
4854 for ( int i = 0; i < foundElems.size(); ++i )
4855 res[i] = foundElems[i]->GetID();
4857 if ( !myIsPreviewMode ) // call from tui
4858 TPythonDump() << "res = " << this << ".FindAmongElementsByPoint( "
4859 << elementIDs << ", "
4868 //=======================================================================
4869 //function : GetPointState
4870 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
4871 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
4872 //=======================================================================
4874 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
4878 theSearchersDeleter.Set( myMesh );
4879 if ( !theElementSearcher ) {
4880 theElementSearcher = myEditor.GetElementSearcher();
4882 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
4885 //=======================================================================
4886 //function : convError
4888 //=======================================================================
4890 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
4892 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
4896 RETCASE( SEW_BORDER1_NOT_FOUND );
4897 RETCASE( SEW_BORDER2_NOT_FOUND );
4898 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
4899 RETCASE( SEW_BAD_SIDE_NODES );
4900 RETCASE( SEW_VOLUMES_TO_SPLIT );
4901 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
4902 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
4903 RETCASE( SEW_BAD_SIDE1_NODES );
4904 RETCASE( SEW_BAD_SIDE2_NODES );
4906 return SMESH::SMESH_MeshEditor::SEW_OK;
4909 //=======================================================================
4910 //function : SewFreeBorders
4912 //=======================================================================
4914 SMESH::SMESH_MeshEditor::Sew_Error
4915 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
4916 CORBA::Long SecondNodeID1,
4917 CORBA::Long LastNodeID1,
4918 CORBA::Long FirstNodeID2,
4919 CORBA::Long SecondNodeID2,
4920 CORBA::Long LastNodeID2,
4921 CORBA::Boolean CreatePolygons,
4922 CORBA::Boolean CreatePolyedrs)
4926 SMESHDS_Mesh* aMesh = getMeshDS();
4928 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4929 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4930 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4931 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4932 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4933 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
4935 if (!aBorderFirstNode ||
4936 !aBorderSecondNode||
4938 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4939 if (!aSide2FirstNode ||
4940 !aSide2SecondNode ||
4942 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4944 TPythonDump() << "error = " << this << ".SewFreeBorders( "
4945 << FirstNodeID1 << ", "
4946 << SecondNodeID1 << ", "
4947 << LastNodeID1 << ", "
4948 << FirstNodeID2 << ", "
4949 << SecondNodeID2 << ", "
4950 << LastNodeID2 << ", "
4951 << CreatePolygons<< ", "
4952 << CreatePolyedrs<< " )";
4954 SMESH::SMESH_MeshEditor::Sew_Error error =
4955 convError( getEditor().SewFreeBorder (aBorderFirstNode,
4966 myMesh->GetMeshDS()->Modified();
4967 myMesh->SetIsModified( true );
4973 //=======================================================================
4974 //function : SewConformFreeBorders
4976 //=======================================================================
4978 SMESH::SMESH_MeshEditor::Sew_Error
4979 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
4980 CORBA::Long SecondNodeID1,
4981 CORBA::Long LastNodeID1,
4982 CORBA::Long FirstNodeID2,
4983 CORBA::Long SecondNodeID2)
4987 SMESHDS_Mesh* aMesh = getMeshDS();
4989 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4990 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4991 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4992 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4993 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4994 const SMDS_MeshNode* aSide2ThirdNode = 0;
4996 if (!aBorderFirstNode ||
4997 !aBorderSecondNode||
4999 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5000 if (!aSide2FirstNode ||
5002 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
5004 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
5005 << FirstNodeID1 << ", "
5006 << SecondNodeID1 << ", "
5007 << LastNodeID1 << ", "
5008 << FirstNodeID2 << ", "
5009 << SecondNodeID2 << " )";
5011 SMESH::SMESH_MeshEditor::Sew_Error error =
5012 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5022 myMesh->GetMeshDS()->Modified();
5023 myMesh->SetIsModified( true );
5029 //=======================================================================
5030 //function : SewBorderToSide
5032 //=======================================================================
5034 SMESH::SMESH_MeshEditor::Sew_Error
5035 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
5036 CORBA::Long SecondNodeIDOnFreeBorder,
5037 CORBA::Long LastNodeIDOnFreeBorder,
5038 CORBA::Long FirstNodeIDOnSide,
5039 CORBA::Long LastNodeIDOnSide,
5040 CORBA::Boolean CreatePolygons,
5041 CORBA::Boolean CreatePolyedrs)
5045 SMESHDS_Mesh* aMesh = getMeshDS();
5047 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
5048 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
5049 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
5050 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
5051 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
5052 const SMDS_MeshNode* aSide2ThirdNode = 0;
5054 if (!aBorderFirstNode ||
5055 !aBorderSecondNode||
5057 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
5058 if (!aSide2FirstNode ||
5060 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
5062 TPythonDump() << "error = " << this << ".SewBorderToSide( "
5063 << FirstNodeIDOnFreeBorder << ", "
5064 << SecondNodeIDOnFreeBorder << ", "
5065 << LastNodeIDOnFreeBorder << ", "
5066 << FirstNodeIDOnSide << ", "
5067 << LastNodeIDOnSide << ", "
5068 << CreatePolygons << ", "
5069 << CreatePolyedrs << ") ";
5071 SMESH::SMESH_MeshEditor::Sew_Error error =
5072 convError( getEditor().SewFreeBorder (aBorderFirstNode,
5083 myMesh->GetMeshDS()->Modified();
5084 myMesh->SetIsModified( true );
5090 //=======================================================================
5091 //function : SewSideElements
5093 //=======================================================================
5095 SMESH::SMESH_MeshEditor::Sew_Error
5096 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
5097 const SMESH::long_array& IDsOfSide2Elements,
5098 CORBA::Long NodeID1OfSide1ToMerge,
5099 CORBA::Long NodeID1OfSide2ToMerge,
5100 CORBA::Long NodeID2OfSide1ToMerge,
5101 CORBA::Long NodeID2OfSide2ToMerge)
5105 SMESHDS_Mesh* aMesh = getMeshDS();
5107 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
5108 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
5109 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
5110 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
5112 if (!aFirstNode1ToMerge ||
5113 !aFirstNode2ToMerge )
5114 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
5115 if (!aSecondNode1ToMerge||
5116 !aSecondNode2ToMerge)
5117 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
5119 TIDSortedElemSet aSide1Elems, aSide2Elems;
5120 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
5121 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
5123 TPythonDump() << "error = " << this << ".SewSideElements( "
5124 << IDsOfSide1Elements << ", "
5125 << IDsOfSide2Elements << ", "
5126 << NodeID1OfSide1ToMerge << ", "
5127 << NodeID1OfSide2ToMerge << ", "
5128 << NodeID2OfSide1ToMerge << ", "
5129 << NodeID2OfSide2ToMerge << ")";
5131 SMESH::SMESH_MeshEditor::Sew_Error error =
5132 convError( getEditor().SewSideElements (aSide1Elems, aSide2Elems,
5135 aSecondNode1ToMerge,
5136 aSecondNode2ToMerge));
5139 myMesh->GetMeshDS()->Modified();
5140 myMesh->SetIsModified( true );
5145 //================================================================================
5147 * \brief Set new nodes for given element
5148 * \param ide - element id
5149 * \param newIDs - new node ids
5150 * \retval CORBA::Boolean - true if result is OK
5152 //================================================================================
5154 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
5155 const SMESH::long_array& newIDs)
5159 const SMDS_MeshElement* elem = getMeshDS()->FindElement(ide);
5160 if(!elem) return false;
5162 int nbn = newIDs.length();
5164 vector<const SMDS_MeshNode*> aNodes(nbn);
5167 const SMDS_MeshNode* aNode = getMeshDS()->FindNode(newIDs[i]);
5170 aNodes[nbn1] = aNode;
5173 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
5174 << ide << ", " << newIDs << " )";
5176 MESSAGE("ChangeElementNodes");
5177 bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
5179 myMesh->GetMeshDS()->Modified();
5181 myMesh->SetIsModified( true );
5186 //=======================================================================
5187 //function : ConvertToQuadratic
5189 //=======================================================================
5191 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
5193 getEditor().ConvertToQuadratic(theForce3d);
5194 TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )";
5195 myMesh->GetMeshDS()->Modified();
5196 myMesh->SetIsModified( true );
5199 //=======================================================================
5200 //function : ConvertFromQuadratic
5202 //=======================================================================
5204 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
5206 CORBA::Boolean isDone = getEditor().ConvertFromQuadratic();
5207 TPythonDump() << this << ".ConvertFromQuadratic()";
5208 myMesh->GetMeshDS()->Modified();
5210 myMesh->SetIsModified( true );
5213 //================================================================================
5215 * \brief Makes a part of the mesh quadratic
5217 //================================================================================
5219 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
5220 SMESH::SMESH_IDSource_ptr theObject)
5221 throw (SALOME::SALOME_Exception)
5223 Unexpect aCatch(SALOME_SalomeException);
5225 TIDSortedElemSet elems;
5226 if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5228 if ( elems.empty() )
5230 ConvertToQuadratic( theForce3d );
5232 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5234 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5238 getEditor().ConvertToQuadratic(theForce3d, elems);
5241 myMesh->GetMeshDS()->Modified();
5242 myMesh->SetIsModified( true );
5244 pyDump << this << ".ConvertToQuadraticObject( "<<theForce3d<<", "<<theObject<<" )";
5247 //================================================================================
5249 * \brief Makes a part of the mesh linear
5251 //================================================================================
5253 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
5254 throw (SALOME::SALOME_Exception)
5256 Unexpect aCatch(SALOME_SalomeException);
5258 TIDSortedElemSet elems;
5259 if ( idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
5261 if ( elems.empty() )
5263 ConvertFromQuadratic();
5265 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
5267 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
5271 getEditor().ConvertFromQuadratic(elems);
5274 myMesh->GetMeshDS()->Modified();
5275 myMesh->SetIsModified( true );
5277 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
5280 //=======================================================================
5281 //function : makeMesh
5282 //purpose : create a named imported mesh
5283 //=======================================================================
5285 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
5287 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
5288 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
5289 SALOMEDS::Study_var study = gen->GetCurrentStudy();
5290 SALOMEDS::SObject_wrap meshSO = gen->ObjectToSObject( study, mesh );
5291 gen->SetName( meshSO, theMeshName, "Mesh" );
5292 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
5294 return mesh._retn();
5297 //=======================================================================
5298 //function : DumpGroupsList
5300 //=======================================================================
5301 void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump & theDumpPython,
5302 const SMESH::ListOfGroups * theGroupList)
5304 bool isDumpGroupList = theGroupList && theGroupList->length() > 0;
5305 if(isDumpGroupList) {
5306 theDumpPython << theGroupList << " = ";
5310 //================================================================================
5312 \brief Generates the unique group name.
5313 \param thePrefix name prefix
5316 //================================================================================
5317 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
5319 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5320 set<string> groupNames;
5322 // Get existing group names
5323 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
5324 SMESH::SMESH_GroupBase_var aGroup = groups[i];
5325 if (CORBA::is_nil(aGroup))
5328 CORBA::String_var name = aGroup->GetName();
5329 groupNames.insert( name.in() );
5333 string name = thePrefix;
5336 while (!groupNames.insert(name).second)
5337 name = SMESH_Comment( thePrefix ) << "_" << index;
5342 //================================================================================
5344 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5345 \param theNodes - identifiers of nodes to be doubled
5346 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
5347 nodes. If list of element identifiers is empty then nodes are doubled but
5348 they not assigned to elements
5349 \return TRUE if operation has been completed successfully, FALSE otherwise
5350 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
5352 //================================================================================
5354 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
5355 const SMESH::long_array& theModifiedElems )
5359 list< int > aListOfNodes;
5361 for ( i = 0, n = theNodes.length(); i < n; i++ )
5362 aListOfNodes.push_back( theNodes[ i ] );
5364 list< int > aListOfElems;
5365 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5366 aListOfElems.push_back( theModifiedElems[ i ] );
5368 bool aResult = getEditor().DoubleNodes( aListOfNodes, aListOfElems );
5370 myMesh->GetMeshDS()->Modified();
5372 myMesh->SetIsModified( true );
5374 // Update Python script
5375 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
5380 //================================================================================
5382 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5383 This method provided for convenience works as DoubleNodes() described above.
5384 \param theNodeId - identifier of node to be doubled.
5385 \param theModifiedElems - identifiers of elements to be updated.
5386 \return TRUE if operation has been completed successfully, FALSE otherwise
5387 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
5389 //================================================================================
5391 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
5392 const SMESH::long_array& theModifiedElems )
5394 SMESH::long_array_var aNodes = new SMESH::long_array;
5395 aNodes->length( 1 );
5396 aNodes[ 0 ] = theNodeId;
5398 TPythonDump pyDump; // suppress dump by the next line
5400 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
5402 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
5407 //================================================================================
5409 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5410 This method provided for convenience works as DoubleNodes() described above.
5411 \param theNodes - group of nodes to be doubled.
5412 \param theModifiedElems - group of elements to be updated.
5413 \return TRUE if operation has been completed successfully, FALSE otherwise
5414 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
5416 //================================================================================
5418 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
5419 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5421 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5424 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5425 SMESH::long_array_var aModifiedElems;
5426 if ( !CORBA::is_nil( theModifiedElems ) )
5427 aModifiedElems = theModifiedElems->GetListOfID();
5430 aModifiedElems = new SMESH::long_array;
5431 aModifiedElems->length( 0 );
5434 TPythonDump pyDump; // suppress dump by the next line
5436 bool done = DoubleNodes( aNodes, aModifiedElems );
5438 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
5444 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5445 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
5446 * \param theNodes - group of nodes to be doubled.
5447 * \param theModifiedElems - group of elements to be updated.
5448 * \return a new group with newly created nodes
5449 * \sa DoubleNodeGroup()
5451 SMESH::SMESH_Group_ptr
5452 SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
5453 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5455 SMESH::SMESH_Group_var aNewGroup;
5457 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5458 return aNewGroup._retn();
5461 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5462 SMESH::long_array_var aModifiedElems;
5463 if ( !CORBA::is_nil( theModifiedElems ) )
5464 aModifiedElems = theModifiedElems->GetListOfID();
5466 aModifiedElems = new SMESH::long_array;
5467 aModifiedElems->length( 0 );
5470 TPythonDump pyDump; // suppress dump by the next line
5472 bool aResult = DoubleNodes( aNodes, aModifiedElems );
5475 // Create group with newly created nodes
5476 SMESH::long_array_var anIds = GetLastCreatedNodes();
5477 if (anIds->length() > 0) {
5478 string anUnindexedName (theNodes->GetName());
5479 string aNewName = generateGroupName(anUnindexedName + "_double");
5480 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5481 aNewGroup->Add(anIds);
5482 pyDump << aNewGroup << " = ";
5486 pyDump << this << ".DoubleNodeGroupNew( " << theNodes << ", "
5487 << theModifiedElems << " )";
5489 return aNewGroup._retn();
5492 //================================================================================
5494 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5495 This method provided for convenience works as DoubleNodes() described above.
5496 \param theNodes - list of groups of nodes to be doubled
5497 \param theModifiedElems - list of groups of elements to be updated.
5498 \return TRUE if operation has been completed successfully, FALSE otherwise
5499 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
5501 //================================================================================
5503 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
5504 const SMESH::ListOfGroups& theModifiedElems )
5509 std::list< int > aNodes;
5511 for ( i = 0, n = theNodes.length(); i < n; i++ )
5513 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
5514 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
5516 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5517 for ( j = 0, m = aCurr->length(); j < m; j++ )
5518 aNodes.push_back( aCurr[ j ] );
5522 std::list< int > anElems;
5523 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5525 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
5526 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
5528 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5529 for ( j = 0, m = aCurr->length(); j < m; j++ )
5530 anElems.push_back( aCurr[ j ] );
5534 bool aResult = getEditor().DoubleNodes( aNodes, anElems );
5537 myMesh->GetMeshDS()->Modified();
5539 myMesh->SetIsModified( true );
5542 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
5547 //================================================================================
5549 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5550 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
5551 * \param theNodes - group of nodes to be doubled.
5552 * \param theModifiedElems - group of elements to be updated.
5553 * \return a new group with newly created nodes
5554 * \sa DoubleNodeGroups()
5556 //================================================================================
5558 SMESH::SMESH_Group_ptr
5559 SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
5560 const SMESH::ListOfGroups& theModifiedElems )
5562 SMESH::SMESH_Group_var aNewGroup;
5564 TPythonDump pyDump; // suppress dump by the next line
5566 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
5570 // Create group with newly created nodes
5571 SMESH::long_array_var anIds = GetLastCreatedNodes();
5572 if (anIds->length() > 0) {
5573 string anUnindexedName (theNodes[0]->GetName());
5574 string aNewName = generateGroupName(anUnindexedName + "_double");
5575 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5576 aNewGroup->Add(anIds);
5577 pyDump << aNewGroup << " = ";
5581 pyDump << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
5582 << theModifiedElems << " )";
5584 return aNewGroup._retn();
5588 //================================================================================
5590 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5591 \param theElems - the list of elements (edges or faces) to be replicated
5592 The nodes for duplication could be found from these elements
5593 \param theNodesNot - list of nodes to NOT replicate
5594 \param theAffectedElems - the list of elements (cells and edges) to which the
5595 replicated nodes should be associated to.
5596 \return TRUE if operation has been completed successfully, FALSE otherwise
5597 \sa DoubleNodeGroup(), DoubleNodeGroups()
5599 //================================================================================
5601 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
5602 const SMESH::long_array& theNodesNot,
5603 const SMESH::long_array& theAffectedElems )
5609 SMESHDS_Mesh* aMeshDS = getMeshDS();
5610 TIDSortedElemSet anElems, aNodes, anAffected;
5611 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5612 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5613 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
5615 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5618 myMesh->GetMeshDS()->Modified();
5620 myMesh->SetIsModified( true );
5622 // Update Python script
5623 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
5624 << theNodesNot << ", " << theAffectedElems << " )";
5628 //================================================================================
5630 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5631 \param theElems - the list of elements (edges or faces) to be replicated
5632 The nodes for duplication could be found from these elements
5633 \param theNodesNot - list of nodes to NOT replicate
5634 \param theShape - shape to detect affected elements (element which geometric center
5635 located on or inside shape).
5636 The replicated nodes should be associated to affected elements.
5637 \return TRUE if operation has been completed successfully, FALSE otherwise
5638 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
5640 //================================================================================
5642 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
5643 const SMESH::long_array& theNodesNot,
5644 GEOM::GEOM_Object_ptr theShape )
5650 SMESHDS_Mesh* aMeshDS = getMeshDS();
5651 TIDSortedElemSet anElems, aNodes;
5652 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5653 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5655 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5656 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
5659 myMesh->GetMeshDS()->Modified();
5661 myMesh->SetIsModified( true );
5663 // Update Python script
5664 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
5665 << theNodesNot << ", " << theShape << " )";
5669 //================================================================================
5671 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5672 \param theElems - group of of elements (edges or faces) to be replicated
5673 \param theNodesNot - group of nodes not to replicated
5674 \param theAffectedElems - group of elements to which the replicated nodes
5675 should be associated to.
5676 \return TRUE if operation has been completed successfully, FALSE otherwise
5677 \sa DoubleNodes(), DoubleNodeGroups()
5679 //================================================================================
5681 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
5682 SMESH::SMESH_GroupBase_ptr theNodesNot,
5683 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5685 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5691 SMESHDS_Mesh* aMeshDS = getMeshDS();
5692 TIDSortedElemSet anElems, aNodes, anAffected;
5693 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5694 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5695 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5697 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5700 myMesh->GetMeshDS()->Modified();
5702 myMesh->SetIsModified( true );
5704 // Update Python script
5705 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
5706 << theNodesNot << ", " << theAffectedElems << " )";
5711 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5712 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
5713 * \param theElems - group of of elements (edges or faces) to be replicated
5714 * \param theNodesNot - group of nodes not to replicated
5715 * \param theAffectedElems - group of elements to which the replicated nodes
5716 * should be associated to.
5717 * \return a new group with newly created elements
5718 * \sa DoubleNodeElemGroup()
5720 SMESH::SMESH_Group_ptr
5721 SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
5722 SMESH::SMESH_GroupBase_ptr theNodesNot,
5723 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5726 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroup2New( theElems,
5730 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
5731 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
5733 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupNew( "
5735 << theNodesNot << ", "
5736 << theAffectedElems << " )";
5738 return elemGroup._retn();
5741 SMESH::ListOfGroups*
5742 SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
5743 SMESH::SMESH_GroupBase_ptr theNodesNot,
5744 SMESH::SMESH_GroupBase_ptr theAffectedElems,
5745 CORBA::Boolean theElemGroupNeeded,
5746 CORBA::Boolean theNodeGroupNeeded)
5748 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
5749 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
5750 aTwoGroups->length( 2 );
5752 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5753 return aTwoGroups._retn();
5758 SMESHDS_Mesh* aMeshDS = getMeshDS();
5759 TIDSortedElemSet anElems, aNodes, anAffected;
5760 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5761 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5762 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5765 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5767 myMesh->GetMeshDS()->Modified();
5773 myMesh->SetIsModified( true );
5775 // Create group with newly created elements
5776 CORBA::String_var elemGroupName = theElems->GetName();
5777 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
5778 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
5780 SMESH::long_array_var anIds = GetLastCreatedElems();
5781 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5782 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5783 aNewElemGroup->Add(anIds);
5785 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
5787 SMESH::long_array_var anIds = GetLastCreatedNodes();
5788 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5789 aNewNodeGroup->Add(anIds);
5793 // Update Python script
5796 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
5797 else pyDump << aNewElemGroup << ", ";
5798 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
5799 else pyDump << aNewNodeGroup << " ] = ";
5801 pyDump << this << ".DoubleNodeElemGroup2New( " << theElems << ", "
5802 << theNodesNot << ", "
5803 << theAffectedElems << ", "
5804 << theElemGroupNeeded << ", "
5805 << theNodeGroupNeeded <<" )";
5807 aTwoGroups[0] = aNewElemGroup._retn();
5808 aTwoGroups[1] = aNewNodeGroup._retn();
5809 return aTwoGroups._retn();
5812 //================================================================================
5814 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5815 \param theElems - group of of elements (edges or faces) to be replicated
5816 \param theNodesNot - group of nodes not to replicated
5817 \param theShape - shape to detect affected elements (element which geometric center
5818 located on or inside shape).
5819 The replicated nodes should be associated to affected elements.
5820 \return TRUE if operation has been completed successfully, FALSE otherwise
5821 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
5823 //================================================================================
5825 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
5826 SMESH::SMESH_GroupBase_ptr theNodesNot,
5827 GEOM::GEOM_Object_ptr theShape )
5830 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5836 SMESHDS_Mesh* aMeshDS = getMeshDS();
5837 TIDSortedElemSet anElems, aNodes, anAffected;
5838 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5839 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5841 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5842 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
5845 myMesh->GetMeshDS()->Modified();
5847 myMesh->SetIsModified( true );
5849 // Update Python script
5850 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
5851 << theNodesNot << ", " << theShape << " )";
5855 //================================================================================
5857 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5858 This method provided for convenience works as DoubleNodes() described above.
5859 \param theElems - list of groups of elements (edges or faces) to be replicated
5860 \param theNodesNot - list of groups of nodes not to replicated
5861 \param theAffectedElems - group of elements to which the replicated nodes
5862 should be associated to.
5863 \return TRUE if operation has been completed successfully, FALSE otherwise
5864 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
5866 //================================================================================
5868 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
5869 SMESHDS_Mesh* theMeshDS,
5870 TIDSortedElemSet& theElemSet,
5871 const bool theIsNodeGrp)
5873 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
5875 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
5876 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
5877 : aGrp->GetType() != SMESH::NODE ) )
5879 SMESH::long_array_var anIDs = aGrp->GetIDs();
5880 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
5885 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
5886 const SMESH::ListOfGroups& theNodesNot,
5887 const SMESH::ListOfGroups& theAffectedElems)
5892 SMESHDS_Mesh* aMeshDS = getMeshDS();
5893 TIDSortedElemSet anElems, aNodes, anAffected;
5894 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5895 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5896 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5898 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5901 myMesh->GetMeshDS()->Modified();
5903 myMesh->SetIsModified( true );
5905 // Update Python script
5906 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
5907 << &theNodesNot << ", " << &theAffectedElems << " )";
5911 //================================================================================
5913 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5914 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
5915 \param theElems - list of groups of elements (edges or faces) to be replicated
5916 \param theNodesNot - list of groups of nodes not to replicated
5917 \param theAffectedElems - group of elements to which the replicated nodes
5918 should be associated to.
5919 * \return a new group with newly created elements
5920 * \sa DoubleNodeElemGroups()
5922 //================================================================================
5924 SMESH::SMESH_Group_ptr
5925 SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
5926 const SMESH::ListOfGroups& theNodesNot,
5927 const SMESH::ListOfGroups& theAffectedElems)
5930 SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroups2New( theElems,
5934 SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
5935 SMESH::SMESH_Group_var elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
5937 pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupsNew( "
5939 << theNodesNot << ", "
5940 << theAffectedElems << " )";
5942 return elemGroup._retn();
5945 SMESH::ListOfGroups*
5946 SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems,
5947 const SMESH::ListOfGroups& theNodesNot,
5948 const SMESH::ListOfGroups& theAffectedElems,
5949 CORBA::Boolean theElemGroupNeeded,
5950 CORBA::Boolean theNodeGroupNeeded)
5952 SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
5953 SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
5954 aTwoGroups->length( 2 );
5959 SMESHDS_Mesh* aMeshDS = getMeshDS();
5960 TIDSortedElemSet anElems, aNodes, anAffected;
5961 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5962 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5963 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5965 bool aResult = getEditor().DoubleNodes( anElems, aNodes, anAffected );
5968 myMesh->GetMeshDS()->Modified();
5972 myMesh->SetIsModified( true );
5974 // Create group with newly created elements
5975 CORBA::String_var elemGroupName = theElems[0]->GetName();
5976 string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
5977 if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
5979 SMESH::long_array_var anIds = GetLastCreatedElems();
5980 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5981 aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5982 aNewElemGroup->Add(anIds);
5984 if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
5986 SMESH::long_array_var anIds = GetLastCreatedNodes();
5987 aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5988 aNewNodeGroup->Add(anIds);
5992 // Update Python script
5995 if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
5996 else pyDump << aNewElemGroup << ", ";
5997 if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
5998 else pyDump << aNewNodeGroup << " ] = ";
6000 pyDump << this << ".DoubleNodeElemGroups2New( " << &theElems << ", "
6001 << &theNodesNot << ", "
6002 << &theAffectedElems << ", "
6003 << theElemGroupNeeded << ", "
6004 << theNodeGroupNeeded << " )";
6006 aTwoGroups[0] = aNewElemGroup._retn();
6007 aTwoGroups[1] = aNewNodeGroup._retn();
6008 return aTwoGroups._retn();
6011 //================================================================================
6013 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
6014 This method provided for convenience works as DoubleNodes() described above.
6015 \param theElems - list of groups of elements (edges or faces) to be replicated
6016 \param theNodesNot - list of groups of nodes not to replicated
6017 \param theShape - shape to detect affected elements (element which geometric center
6018 located on or inside shape).
6019 The replicated nodes should be associated to affected elements.
6020 \return TRUE if operation has been completed successfully, FALSE otherwise
6021 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
6023 //================================================================================
6026 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
6027 const SMESH::ListOfGroups& theNodesNot,
6028 GEOM::GEOM_Object_ptr theShape )
6033 SMESHDS_Mesh* aMeshDS = getMeshDS();
6034 TIDSortedElemSet anElems, aNodes;
6035 listOfGroupToSet(theElems, aMeshDS, anElems,false );
6036 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
6038 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6039 bool aResult = getEditor().DoubleNodesInRegion( anElems, aNodes, aShape );
6042 myMesh->GetMeshDS()->Modified();
6044 myMesh->SetIsModified( true );
6046 // Update Python script
6047 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
6048 << &theNodesNot << ", " << theShape << " )";
6052 //================================================================================
6054 \brief Identify the elements that will be affected by node duplication (actual duplication is not performed.
6055 This method is the first step of DoubleNodeElemGroupsInRegion.
6056 \param theElems - list of groups of elements (edges or faces) to be replicated
6057 \param theNodesNot - list of groups of nodes not to replicated
6058 \param theShape - shape to detect affected elements (element which geometric center
6059 located on or inside shape).
6060 The replicated nodes should be associated to affected elements.
6061 \return groups of affected elements
6062 \sa DoubleNodeElemGroupsInRegion()
6064 //================================================================================
6065 SMESH::ListOfGroups*
6066 SMESH_MeshEditor_i::AffectedElemGroupsInRegion( const SMESH::ListOfGroups& theElems,
6067 const SMESH::ListOfGroups& theNodesNot,
6068 GEOM::GEOM_Object_ptr theShape )
6070 MESSAGE("AffectedElemGroupsInRegion");
6071 SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
6072 bool isEdgeGroup = false;
6073 bool isFaceGroup = false;
6074 bool isVolumeGroup = false;
6075 SMESH::SMESH_Group_var aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE, "affectedEdges");
6076 SMESH::SMESH_Group_var aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE, "affectedFaces");
6077 SMESH::SMESH_Group_var aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME, "affectedVolumes");
6081 ::SMESH_MeshEditor aMeshEditor(myMesh);
6083 SMESHDS_Mesh* aMeshDS = getMeshDS();
6084 TIDSortedElemSet anElems, aNodes;
6085 listOfGroupToSet(theElems, aMeshDS, anElems, false);
6086 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true);
6088 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape(theShape);
6089 TIDSortedElemSet anAffected;
6090 bool aResult = aMeshEditor.AffectedElemGroupsInRegion(anElems, aNodes, aShape, anAffected);
6093 myMesh->GetMeshDS()->Modified();
6097 myMesh->SetIsModified(true);
6099 int lg = anAffected.size();
6100 MESSAGE("lg="<< lg);
6101 SMESH::long_array_var volumeIds = new SMESH::long_array;
6102 volumeIds->length(lg);
6103 SMESH::long_array_var faceIds = new SMESH::long_array;
6104 faceIds->length(lg);
6105 SMESH::long_array_var edgeIds = new SMESH::long_array;
6106 edgeIds->length(lg);
6111 TIDSortedElemSet::const_iterator eIt = anAffected.begin();
6112 for (; eIt != anAffected.end(); ++eIt)
6114 const SMDS_MeshElement* anElem = *eIt;
6117 int elemId = anElem->GetID();
6118 if (myMesh->GetElementType(elemId, true) == SMDSAbs_Volume)
6119 volumeIds[ivol++] = elemId;
6120 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Face)
6121 faceIds[iface++] = elemId;
6122 else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Edge)
6123 edgeIds[iedge++] = elemId;
6125 volumeIds->length(ivol);
6126 faceIds->length(iface);
6127 edgeIds->length(iedge);
6129 aNewVolumeGroup->Add(volumeIds);
6130 aNewFaceGroup->Add(faceIds);
6131 aNewEdgeGroup->Add(edgeIds);
6132 isVolumeGroup = (aNewVolumeGroup->Size() > 0);
6133 isFaceGroup = (aNewFaceGroup->Size() > 0);
6134 isEdgeGroup = (aNewEdgeGroup->Size() > 0);
6144 aListOfGroups->length(nbGroups);
6148 aListOfGroups[i++] = aNewEdgeGroup._retn();
6150 aListOfGroups[i++] = aNewFaceGroup._retn();
6152 aListOfGroups[i++] = aNewVolumeGroup._retn();
6154 // Update Python script
6158 pyDump << aNewEdgeGroup << ", ";
6160 pyDump << aNewFaceGroup << ", ";
6162 pyDump << aNewVolumeGroup << ", ";
6164 pyDump << this << ".AffectedElemGroupsInRegion( " << &theElems << ", " << &theNodesNot << ", " << theShape << " )";
6166 return aListOfGroups._retn();
6169 //================================================================================
6171 \brief Generated skin mesh (containing 2D cells) from 3D mesh
6172 The created 2D mesh elements based on nodes of free faces of boundary volumes
6173 \return TRUE if operation has been completed successfully, FALSE otherwise
6175 //================================================================================
6177 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
6181 bool aResult = getEditor().Make2DMeshFrom3D();
6182 myMesh->GetMeshDS()->Modified();
6183 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
6187 //================================================================================
6189 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
6190 * The list of groups must describe a partition of the mesh volumes.
6191 * The nodes of the internal faces at the boundaries of the groups are doubled.
6192 * In option, the internal faces are replaced by flat elements.
6193 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
6194 * The flat elements are stored in groups of volumes.
6195 * @param theDomains - list of groups of volumes
6196 * @param createJointElems - if TRUE, create the elements
6197 * @return TRUE if operation has been completed successfully, FALSE otherwise
6199 //================================================================================
6201 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
6202 CORBA::Boolean createJointElems )
6203 throw (SALOME::SALOME_Exception)
6205 bool aResult = false;
6210 SMESHDS_Mesh* aMeshDS = getMeshDS();
6212 vector<TIDSortedElemSet> domains;
6215 for ( int i = 0, n = theDomains.length(); i < n; i++ )
6217 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
6218 if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
6220 // if ( aGrp->GetType() != SMESH::VOLUME )
6221 // THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
6222 TIDSortedElemSet domain;
6224 domains.push_back(domain);
6225 SMESH::long_array_var anIDs = aGrp->GetIDs();
6226 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
6230 aResult = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems );
6231 // TODO publish the groups of flat elements in study
6233 myMesh->GetMeshDS()->Modified();
6235 // Update Python script
6236 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
6237 << ", " << createJointElems << " )";
6239 SMESH_CATCH( SMESH::throwCorbaException );
6244 //================================================================================
6246 * \brief Double nodes on some external faces and create flat elements.
6247 * Flat elements are mainly used by some types of mechanic calculations.
6249 * Each group of the list must be constituted of faces.
6250 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
6251 * @param theGroupsOfFaces - list of groups of faces
6252 * @return TRUE if operation has been completed successfully, FALSE otherwise
6254 //================================================================================
6256 CORBA::Boolean SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
6261 SMESHDS_Mesh* aMeshDS = getMeshDS();
6263 vector<TIDSortedElemSet> faceGroups;
6266 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
6268 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
6269 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
6271 TIDSortedElemSet faceGroup;
6273 faceGroups.push_back(faceGroup);
6274 SMESH::long_array_var anIDs = aGrp->GetIDs();
6275 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
6279 bool aResult = getEditor().CreateFlatElementsOnFacesGroups( faceGroups );
6280 // TODO publish the groups of flat elements in study
6282 myMesh->GetMeshDS()->Modified();
6284 // Update Python script
6285 TPythonDump() << "isDone = " << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
6290 * \brief identify all the elements around a geom shape, get the faces delimiting the hole
6291 * Build groups of volume to remove, groups of faces to replace on the skin of the object,
6292 * groups of faces to remove inside the object, (idem edges).
6293 * Build ordered list of nodes at the border of each group of faces to replace (to be used to build a geom subshape)
6295 void SMESH_MeshEditor_i::CreateHoleSkin(CORBA::Double radius,
6296 GEOM::GEOM_Object_ptr theShape,
6297 const char* groupName,
6298 const SMESH::double_array& theNodesCoords,
6299 SMESH::array_of_long_array_out GroupsOfNodes)
6300 throw (SALOME::SALOME_Exception)
6305 std::vector<std::vector<int> > aListOfListOfNodes;
6306 ::SMESH_MeshEditor aMeshEditor( myMesh );
6308 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
6309 if ( !theNodeSearcher )
6310 theNodeSearcher = aMeshEditor.GetNodeSearcher();
6312 vector<double> nodesCoords;
6313 for (int i = 0; i < theNodesCoords.length(); i++)
6315 nodesCoords.push_back( theNodesCoords[i] );
6318 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
6319 aMeshEditor.CreateHoleSkin(radius, aShape, theNodeSearcher, groupName,
6320 nodesCoords, aListOfListOfNodes);
6322 GroupsOfNodes = new SMESH::array_of_long_array;
6323 GroupsOfNodes->length( aListOfListOfNodes.size() );
6324 std::vector<std::vector<int> >::iterator llIt = aListOfListOfNodes.begin();
6325 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
6327 vector<int>& aListOfNodes = *llIt;
6328 vector<int>::iterator lIt = aListOfNodes.begin();;
6329 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
6330 aGroup.length( aListOfNodes.size() );
6331 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
6332 aGroup[ j ] = (*lIt);
6334 TPythonDump() << "lists_nodes = " << this << ".CreateHoleSkin( "
6337 << ", '" << groupName << "', "
6338 << theNodesCoords << " )";
6340 SMESH_CATCH( SMESH::throwCorbaException );
6344 // issue 20749 ===================================================================
6346 * \brief Creates missing boundary elements
6347 * \param elements - elements whose boundary is to be checked
6348 * \param dimension - defines type of boundary elements to create
6349 * \param groupName - a name of group to store created boundary elements in,
6350 * "" means not to create the group
6351 * \param meshName - a name of new mesh to store created boundary elements in,
6352 * "" means not to create the new mesh
6353 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
6354 * \param toCopyExistingBondary - if true, not only new but also pre-existing
6355 * boundary elements will be copied into the new mesh
6356 * \param group - returns the create group, if any
6357 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
6359 // ================================================================================
6361 SMESH::SMESH_Mesh_ptr
6362 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
6363 SMESH::Bnd_Dimension dim,
6364 const char* groupName,
6365 const char* meshName,
6366 CORBA::Boolean toCopyElements,
6367 CORBA::Boolean toCopyExistingBondary,
6368 SMESH::SMESH_Group_out group)
6372 if ( dim > SMESH::BND_1DFROM2D )
6373 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
6375 SMESHDS_Mesh* aMeshDS = getMeshDS();
6377 SMESH::SMESH_Mesh_var mesh_var;
6378 SMESH::SMESH_Group_var group_var;
6382 TIDSortedElemSet elements;
6383 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
6384 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
6388 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
6389 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
6391 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
6393 // group of new boundary elements
6394 SMESH_Group* smesh_group = 0;
6395 if ( strlen(groupName) )
6397 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
6398 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
6399 smesh_group = group_i->GetSmeshGroup();
6403 getEditor().MakeBoundaryMesh( elements,
6404 ::SMESH_MeshEditor::Bnd_Dimension(dim),
6408 toCopyExistingBondary);
6411 smesh_mesh->GetMeshDS()->Modified();
6414 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
6416 // result of MakeBoundaryMesh() is a tuple (mesh, group)
6417 if ( mesh_var->_is_nil() )
6418 pyDump << myMesh_i->_this() << ", ";
6420 pyDump << mesh_var << ", ";
6421 if ( group_var->_is_nil() )
6422 pyDump << "_NoneGroup = "; // assignment to None is forbiden
6424 pyDump << group_var << " = ";
6425 pyDump << this << ".MakeBoundaryMesh( "
6427 << "SMESH." << dimName[int(dim)] << ", "
6428 << "'" << groupName << "', "
6429 << "'" << meshName<< "', "
6430 << toCopyElements << ", "
6431 << toCopyExistingBondary << ")";
6433 group = group_var._retn();
6434 return mesh_var._retn();
6437 //================================================================================
6439 * \brief Creates missing boundary elements
6440 * \param dimension - defines type of boundary elements to create
6441 * \param groupName - a name of group to store all boundary elements in,
6442 * "" means not to create the group
6443 * \param meshName - a name of a new mesh, which is a copy of the initial
6444 * mesh + created boundary elements; "" means not to create the new mesh
6445 * \param toCopyAll - if true, the whole initial mesh will be copied into
6446 * the new mesh else only boundary elements will be copied into the new mesh
6447 * \param groups - optional groups of elements to make boundary around
6448 * \param mesh - returns the mesh where elements were added to
6449 * \param group - returns the created group, if any
6450 * \retval long - number of added boundary elements
6452 //================================================================================
6454 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
6455 const char* groupName,
6456 const char* meshName,
6457 CORBA::Boolean toCopyAll,
6458 const SMESH::ListOfIDSources& groups,
6459 SMESH::SMESH_Mesh_out mesh,
6460 SMESH::SMESH_Group_out group)
6461 throw (SALOME::SALOME_Exception)
6463 Unexpect aCatch(SALOME_SalomeException);
6467 if ( dim > SMESH::BND_1DFROM2D )
6468 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
6470 // separate groups belonging to this and other mesh
6471 SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
6472 SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
6473 groupsOfThisMesh->length( groups.length() );
6474 groupsOfOtherMesh->length( groups.length() );
6475 int nbGroups = 0, nbGroupsOfOtherMesh = 0;
6476 for ( int i = 0; i < groups.length(); ++i )
6478 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
6479 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
6480 groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
6482 groupsOfThisMesh[ nbGroups++ ] = groups[i];
6483 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
6484 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
6486 groupsOfThisMesh->length( nbGroups );
6487 groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
6492 if ( nbGroupsOfOtherMesh > 0 )
6494 // process groups belonging to another mesh
6495 SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
6496 SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
6497 nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
6498 groupsOfOtherMesh, mesh, group );
6501 SMESH::SMESH_Mesh_var mesh_var;
6502 SMESH::SMESH_Group_var group_var;
6505 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
6506 const bool toCopyMesh = ( strlen( meshName ) > 0 );
6510 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
6512 /*toCopyGroups=*/false,
6513 /*toKeepIDs=*/true);
6515 mesh_var = makeMesh(meshName);
6517 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
6518 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
6521 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
6522 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
6524 // group of boundary elements
6525 SMESH_Group* smesh_group = 0;
6526 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
6527 if ( strlen(groupName) )
6529 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
6530 group_var = mesh_i->CreateGroup( groupType, groupName );
6531 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
6532 smesh_group = group_i->GetSmeshGroup();
6535 TIDSortedElemSet elements;
6537 if ( groups.length() > 0 )
6539 for ( int i = 0; i < nbGroups; ++i )
6542 if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
6544 SMESH::Bnd_Dimension bdim =
6545 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
6546 nbAdded += getEditor().MakeBoundaryMesh( elements,
6547 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
6550 /*toCopyElements=*/false,
6551 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
6552 /*toAddExistingBondary=*/true,
6553 /*aroundElements=*/true);
6559 nbAdded += getEditor().MakeBoundaryMesh( elements,
6560 ::SMESH_MeshEditor::Bnd_Dimension(dim),
6563 /*toCopyElements=*/false,
6564 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
6565 /*toAddExistingBondary=*/true);
6567 tgtMesh->GetMeshDS()->Modified();
6569 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
6571 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
6572 pyDump << "nbAdded, ";
6573 if ( mesh_var->_is_nil() )
6574 pyDump << myMesh_i->_this() << ", ";
6576 pyDump << mesh_var << ", ";
6577 if ( group_var->_is_nil() )
6578 pyDump << "_NoneGroup = "; // assignment to None is forbiden
6580 pyDump << group_var << " = ";
6581 pyDump << this << ".MakeBoundaryElements( "
6582 << "SMESH." << dimName[int(dim)] << ", "
6583 << "'" << groupName << "', "
6584 << "'" << meshName<< "', "
6585 << toCopyAll << ", "
6588 mesh = mesh_var._retn();
6589 group = group_var._retn();