1 // Copyright (C) 2007-2011 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_LinearEdge.hxx"
33 #include "SMDS_Mesh0DElement.hxx"
34 #include "SMDS_MeshFace.hxx"
35 #include "SMDS_MeshVolume.hxx"
36 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
37 #include "SMDS_SetIterator.hxx"
38 #include "SMESHDS_Group.hxx"
39 #include "SMESH_ControlsDef.hxx"
40 #include "SMESH_Filter_i.hxx"
41 #include "SMESH_Gen_i.hxx"
42 #include "SMESH_Group_i.hxx"
43 #include "SMESH_PythonDump.hxx"
44 #include "SMESH_subMeshEventListener.hxx"
45 #include "SMESH_subMesh_i.hxx"
47 #include "utilities.h"
48 #include "Utils_ExceptHandlers.hxx"
49 #include "Utils_CorbaException.hxx"
51 #include <BRepAdaptor_Surface.hxx>
52 #include <BRep_Tool.hxx>
53 #include <TopExp_Explorer.hxx>
55 #include <TopoDS_Edge.hxx>
56 #include <TopoDS_Face.hxx>
61 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
65 #include <Standard_Failure.hxx>
68 #include <Standard_ErrorHandler.hxx>
74 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
77 using SMESH::TPythonDump;
81 //=============================================================================
83 * \brief Mesh to apply modifications for preview purposes
85 //=============================================================================
87 struct TPreviewMesh: public SMESH_Mesh
89 SMDSAbs_ElementType myPreviewType; // type to show
91 TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
92 _isShapeToMesh = (_id =_studyId =_idDoc = 0);
93 _myMeshDS = new SMESHDS_Mesh( _id, true );
94 myPreviewType = previewElements;
97 virtual ~TPreviewMesh() { delete _myMeshDS; }
98 //!< Copy a set of elements
99 void Copy(const TIDSortedElemSet & theElements,
100 TIDSortedElemSet& theCopyElements,
101 SMDSAbs_ElementType theSelectType = SMDSAbs_All,
102 SMDSAbs_ElementType theAvoidType = SMDSAbs_All)
104 // loop on theIDsOfElements
105 TIDSortedElemSet::const_iterator eIt = theElements.begin();
106 for ( ; eIt != theElements.end(); ++eIt )
108 const SMDS_MeshElement* anElem = *eIt;
109 if ( !anElem ) continue;
110 SMDSAbs_ElementType type = anElem->GetType();
111 if ( type == theAvoidType ||
112 ( theSelectType != SMDSAbs_All && type != theSelectType ))
115 if ( const SMDS_MeshElement* anElemCopy = Copy( anElem ))
116 theCopyElements.insert( theCopyElements.end(), anElemCopy );
120 SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
122 // copy element nodes
123 int anElemNbNodes = anElem->NbNodes();
124 vector< int > anElemNodesID( anElemNbNodes ) ;
125 SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
126 for ( int i = 0; itElemNodes->more(); i++)
128 const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
130 anElemNodesID[i] = anElemNode->GetID();
133 // creates a corresponding element on copied nodes
134 SMDS_MeshElement* anElemCopy = 0;
135 if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
137 const SMDS_VtkVolume* ph =
138 dynamic_cast<const SMDS_VtkVolume*> (anElem);
140 anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
141 (anElemNodesID, ph->GetQuantities(),anElem->GetID());
144 anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
151 SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
153 return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(),
154 anElemNode->GetID());
156 };// struct TPreviewMesh
158 static SMESH_NodeSearcher * theNodeSearcher = 0;
159 static SMESH_ElementSearcher * theElementSearcher = 0;
161 //=============================================================================
163 * \brief Deleter of theNodeSearcher at any compute event occured
165 //=============================================================================
167 struct TSearchersDeleter : public SMESH_subMeshEventListener
170 string myMeshPartIOR;
172 TSearchersDeleter(): SMESH_subMeshEventListener( false, // won't be deleted by submesh
173 "SMESH_MeshEditor_i::TSearchersDeleter"),
175 //!< Delete theNodeSearcher
178 if ( theNodeSearcher ) delete theNodeSearcher; theNodeSearcher = 0;
179 if ( theElementSearcher ) delete theElementSearcher; theElementSearcher = 0;
181 typedef map < int, SMESH_subMesh * > TDependsOnMap;
182 //!< The meshod called by submesh: do my main job
183 void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
184 SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
186 if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
188 Unset( sm->GetFather() );
191 //!< set self on all submeshes and delete theNodeSearcher if other mesh is set
192 void Set(SMESH_Mesh* mesh, const string& meshPartIOR = string())
194 if ( myMesh != mesh || myMeshPartIOR != meshPartIOR)
201 myMeshPartIOR = meshPartIOR;
202 if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
203 const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
204 TDependsOnMap::const_iterator sm;
205 for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
206 sm->second->SetEventListener( this, 0, sm->second );
210 //!< delete self from all submeshes
211 void Unset(SMESH_Mesh* mesh)
213 if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
214 const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
215 TDependsOnMap::const_iterator sm;
216 for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
217 sm->second->DeleteEventListener( this );
222 } theSearchersDeleter;
224 TCollection_AsciiString mirrorTypeName( SMESH::SMESH_MeshEditor::MirrorType theMirrorType )
226 TCollection_AsciiString typeStr;
227 switch ( theMirrorType ) {
228 case SMESH::SMESH_MeshEditor::POINT:
229 typeStr = "SMESH.SMESH_MeshEditor.POINT";
231 case SMESH::SMESH_MeshEditor::AXIS:
232 typeStr = "SMESH.SMESH_MeshEditor.AXIS";
235 typeStr = "SMESH.SMESH_MeshEditor.PLANE";
239 //================================================================================
241 * \brief function for conversion of long_array to TIDSortedElemSet
242 * \param IDs - array of IDs
243 * \param aMesh - mesh
244 * \param aMap - collection to fill
245 * \param aType - element type
247 //================================================================================
249 void arrayToSet(const SMESH::long_array & IDs,
250 const SMESHDS_Mesh* aMesh,
251 TIDSortedElemSet& aMap,
252 const SMDSAbs_ElementType aType = SMDSAbs_All )
254 for (int i=0; i<IDs.length(); i++) {
255 CORBA::Long ind = IDs[i];
256 const SMDS_MeshElement * elem =
257 (aType == SMDSAbs_Node ? aMesh->FindNode(ind) : aMesh->FindElement(ind));
258 if ( elem && ( aType == SMDSAbs_All || elem->GetType() == aType ))
262 //================================================================================
264 * \brief Retrieve elements of given type from SMESH_IDSource
266 //================================================================================
268 bool idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource,
269 const SMESHDS_Mesh* theMeshDS,
270 TIDSortedElemSet& theElemSet,
271 const SMDSAbs_ElementType theType,
272 const bool emptyIfIsMesh=false)
275 if ( CORBA::is_nil( theIDSource ) )
277 if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
280 SMESH::long_array_var anIDs = theIDSource->GetIDs();
281 if ( anIDs->length() == 0 )
283 SMESH::array_of_ElementType_var types = theIDSource->GetTypes();
284 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
286 if ( theType == SMDSAbs_All || theType == SMDSAbs_Node )
287 arrayToSet( anIDs, theMeshDS, theElemSet, SMDSAbs_Node );
293 arrayToSet( anIDs, theMeshDS, theElemSet, theType);
297 //================================================================================
299 * \brief Retrieve nodes from SMESH_IDSource
301 //================================================================================
303 void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject,
304 const SMESHDS_Mesh* theMeshDS,
305 TIDSortedNodeSet& theNodeSet)
308 if ( CORBA::is_nil( theObject ) )
310 SMESH::array_of_ElementType_var types = theObject->GetTypes();
311 SMESH::long_array_var aElementsId = theObject->GetIDs();
312 if ( types->length() == 1 && types[0] == SMESH::NODE)
314 for(int i = 0; i < aElementsId->length(); i++)
315 if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] ))
316 theNodeSet.insert( theNodeSet.end(), n);
318 else if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
320 SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator();
321 while ( nIt->more( ))
322 if( const SMDS_MeshElement * elem = nIt->next() )
323 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
327 for(int i = 0; i < aElementsId->length(); i++)
328 if( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] ))
329 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
333 //================================================================================
335 * \brief Returns elements connected to the given elements
337 //================================================================================
339 void getElementsAround(const TIDSortedElemSet& theElements,
340 const SMESHDS_Mesh* theMeshDS,
341 TIDSortedElemSet& theElementsAround)
343 if ( theElements.empty() ) return;
345 SMDSAbs_ElementType elemType = (*theElements.begin())->GetType();
346 bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() );
348 theMeshDS->GetMeshInfo().NbElements( elemType ) == theElements.size() )
349 return; // all the elements are in theElements
352 elemType = SMDSAbs_All;
354 TIDSortedElemSet visitedNodes;
355 TIDSortedElemSet::const_iterator elemIt = theElements.begin();
356 for ( ; elemIt != theElements.end(); ++elemIt )
358 const SMDS_MeshElement* e = *elemIt;
359 int i = e->NbCornerNodes();
362 const SMDS_MeshNode* n = e->GetNode( i );
363 if ( visitedNodes.insert( n ).second )
365 SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
366 while ( invIt->more() )
368 const SMDS_MeshElement* elemAround = invIt->next();
369 if ( !theElements.count( elemAround ))
370 theElementsAround.insert( elemAround );
378 //=============================================================================
382 //=============================================================================
384 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview)
387 myMesh = & theMesh->GetImpl();
388 myPreviewMode = isPreview;
391 //================================================================================
395 //================================================================================
397 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
401 //================================================================================
403 * \brief Clear members
405 //================================================================================
407 void SMESH_MeshEditor_i::initData(bool deleteSearchers)
409 if ( myPreviewMode ) {
410 myPreviewData = new SMESH::MeshPreviewStruct();
413 myLastCreatedElems = new SMESH::long_array();
414 myLastCreatedNodes = new SMESH::long_array();
415 if ( deleteSearchers )
416 TSearchersDeleter::Delete();
420 //=======================================================================
421 //function : MakeIDSource
422 //purpose : Wrap a sequence of ids in a SMESH_IDSource
423 //=======================================================================
425 struct _IDSource : public POA_SMESH::SMESH_IDSource
427 SMESH::long_array _ids;
428 SMESH::ElementType _type;
429 SMESH::SMESH_Mesh_ptr _mesh;
430 SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); }
431 SMESH::long_array* GetMeshInfo() { return 0; }
432 SMESH::SMESH_Mesh_ptr GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _mesh ); }
433 SMESH::array_of_ElementType* GetTypes()
435 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
436 if ( _ids.length() > 0 ) {
440 return types._retn();
444 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
445 SMESH::ElementType type)
447 _IDSource* anIDSource = new _IDSource;
448 anIDSource->_ids = ids;
449 anIDSource->_type = type;
450 anIDSource->_mesh = myMesh_i->_this();
451 SMESH::SMESH_IDSource_var anIDSourceVar = anIDSource->_this();
453 return anIDSourceVar._retn();
456 //=============================================================================
460 //=============================================================================
463 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
467 ::SMESH_MeshEditor anEditor( myMesh );
470 for (int i = 0; i < IDsOfElements.length(); i++)
471 IdList.push_back( IDsOfElements[i] );
473 // Update Python script
474 TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
477 bool ret = anEditor.Remove( IdList, false );
478 myMesh->GetMeshDS()->Modified();
479 if ( IDsOfElements.length() )
480 myMesh->SetIsModified( true ); // issue 0020693
484 //=============================================================================
488 //=============================================================================
490 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
494 ::SMESH_MeshEditor anEditor( myMesh );
496 for (int i = 0; i < IDsOfNodes.length(); i++)
497 IdList.push_back( IDsOfNodes[i] );
499 // Update Python script
500 TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
502 bool ret = anEditor.Remove( IdList, true );
503 myMesh->GetMeshDS()->Modified();
504 if ( IDsOfNodes.length() )
505 myMesh->SetIsModified( true ); // issue 0020693
509 //=============================================================================
513 //=============================================================================
515 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
519 ::SMESH_MeshEditor anEditor( myMesh );
521 // Update Python script
522 TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
524 // Create filter to find all orphan nodes
525 SMESH::Controls::Filter::TIdSequence seq;
526 SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
527 SMESH::Controls::Filter::GetElementsId( GetMeshDS(), predicate, seq );
529 // remove orphan nodes (if there are any)
531 for ( int i = 0; i < seq.size(); i++ )
532 IdList.push_back( seq[i] );
534 bool ret = anEditor.Remove( IdList, true );
535 myMesh->GetMeshDS()->Modified();
537 myMesh->SetIsModified( true );
542 //=============================================================================
546 //=============================================================================
548 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,
549 CORBA::Double y, CORBA::Double z)
553 const SMDS_MeshNode* N = GetMeshDS()->AddNode(x, y, z);
555 // Update Python script
556 TPythonDump() << "nodeID = " << this << ".AddNode( "
557 << x << ", " << y << ", " << z << " )";
559 myMesh->GetMeshDS()->Modified();
560 myMesh->SetIsModified( true ); // issue 0020693
564 //=============================================================================
568 //=============================================================================
569 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
573 const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(IDOfNode);
574 SMDS_MeshElement* elem = GetMeshDS()->Add0DElement(aNode);
576 // Update Python script
577 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
579 myMesh->GetMeshDS()->Modified();
580 myMesh->SetIsModified( true ); // issue 0020693
583 return elem->GetID();
588 //=============================================================================
592 //=============================================================================
594 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
598 int NbNodes = IDsOfNodes.length();
599 SMDS_MeshElement* elem = 0;
602 CORBA::Long index1 = IDsOfNodes[0];
603 CORBA::Long index2 = IDsOfNodes[1];
604 elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(index1), GetMeshDS()->FindNode(index2));
606 // Update Python script
607 TPythonDump() << "edge = " << this << ".AddEdge([ "
608 << index1 << ", " << index2 <<" ])";
611 CORBA::Long n1 = IDsOfNodes[0];
612 CORBA::Long n2 = IDsOfNodes[1];
613 CORBA::Long n12 = IDsOfNodes[2];
614 elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(n1),
615 GetMeshDS()->FindNode(n2),
616 GetMeshDS()->FindNode(n12));
617 // Update Python script
618 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
619 <<n1<<", "<<n2<<", "<<n12<<" ])";
622 myMesh->GetMeshDS()->Modified();
624 return myMesh->SetIsModified( true ), elem->GetID();
629 //=============================================================================
633 //=============================================================================
635 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
639 int NbNodes = IDsOfNodes.length();
645 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
646 for (int i = 0; i < NbNodes; i++)
647 nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
649 SMDS_MeshElement* elem = 0;
651 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]);
653 else if (NbNodes == 4) {
654 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]);
656 else if (NbNodes == 6) {
657 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
660 else if (NbNodes == 8) {
661 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
662 nodes[4], nodes[5], nodes[6], nodes[7]);
664 else if (NbNodes == 9) {
665 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
666 nodes[4], nodes[5], nodes[6], nodes[7], nodes[8] );
668 else if (NbNodes > 2) {
669 elem = GetMeshDS()->AddPolygonalFace(nodes);
672 // Update Python script
673 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
675 myMesh->GetMeshDS()->Modified();
677 return myMesh->SetIsModified( true ), elem->GetID();
682 //=============================================================================
686 //=============================================================================
687 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
691 int NbNodes = IDsOfNodes.length();
692 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
693 for (int i = 0; i < NbNodes; i++)
694 nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
696 const SMDS_MeshElement* elem = GetMeshDS()->AddPolygonalFace(nodes);
698 // Update Python script
699 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
701 myMesh->GetMeshDS()->Modified();
702 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
705 //=============================================================================
709 //=============================================================================
711 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
715 int NbNodes = IDsOfNodes.length();
716 vector< const SMDS_MeshNode*> n(NbNodes);
717 for(int i=0;i<NbNodes;i++)
718 n[i]=GetMeshDS()->FindNode(IDsOfNodes[i]);
720 SMDS_MeshElement* elem = 0;
723 case 4 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
724 case 5 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
725 case 6 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
726 case 8 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
727 case 10:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
728 n[6],n[7],n[8],n[9]);
730 case 12:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
731 n[6],n[7],n[8],n[9],n[10],n[11]);
733 case 13:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
734 n[7],n[8],n[9],n[10],n[11],n[12]);
736 case 15:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
737 n[9],n[10],n[11],n[12],n[13],n[14]);
739 case 20:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
740 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
741 n[15],n[16],n[17],n[18],n[19]);
743 case 27:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
744 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
745 n[15],n[16],n[17],n[18],n[19],
746 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
750 // Update Python script
751 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
753 myMesh->GetMeshDS()->Modified();
755 return myMesh->SetIsModified( true ), elem->GetID();
760 //=============================================================================
762 * AddPolyhedralVolume
764 //=============================================================================
765 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
766 const SMESH::long_array & Quantities)
770 int NbNodes = IDsOfNodes.length();
771 std::vector<const SMDS_MeshNode*> n (NbNodes);
772 for (int i = 0; i < NbNodes; i++)
774 const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(IDsOfNodes[i]);
775 if (!aNode) return 0;
779 int NbFaces = Quantities.length();
780 std::vector<int> q (NbFaces);
781 for (int j = 0; j < NbFaces; j++)
782 q[j] = Quantities[j];
784 const SMDS_MeshElement* elem = GetMeshDS()->AddPolyhedralVolume(n, q);
786 // Update Python script
787 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
788 << IDsOfNodes << ", " << Quantities << " )";
789 myMesh->GetMeshDS()->Modified();
791 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
794 //=============================================================================
796 * AddPolyhedralVolumeByFaces
798 //=============================================================================
799 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
803 int NbFaces = IdsOfFaces.length();
804 std::vector<const SMDS_MeshNode*> poly_nodes;
805 std::vector<int> quantities (NbFaces);
807 for (int i = 0; i < NbFaces; i++) {
808 const SMDS_MeshElement* aFace = GetMeshDS()->FindElement(IdsOfFaces[i]);
809 quantities[i] = aFace->NbNodes();
811 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
813 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
817 const SMDS_MeshElement* elem = GetMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
819 // Update Python script
820 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
821 << IdsOfFaces << " )";
822 myMesh->GetMeshDS()->Modified();
824 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
827 //=============================================================================
829 * \brief Bind a node to a vertex
830 * \param NodeID - node ID
831 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
832 * \retval boolean - false if NodeID or VertexID is invalid
834 //=============================================================================
836 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
837 throw (SALOME::SALOME_Exception)
839 Unexpect aCatch(SALOME_SalomeException);
841 SMESHDS_Mesh * mesh = GetMeshDS();
842 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
844 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
846 if ( mesh->MaxShapeIndex() < VertexID )
847 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
849 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
850 if ( shape.ShapeType() != TopAbs_VERTEX )
851 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
853 mesh->SetNodeOnVertex( node, VertexID );
855 myMesh->SetIsModified( true );
858 //=============================================================================
860 * \brief Store node position on an edge
861 * \param NodeID - node ID
862 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
863 * \param paramOnEdge - parameter on edge where the node is located
864 * \retval boolean - false if any parameter is invalid
866 //=============================================================================
868 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
869 CORBA::Double paramOnEdge)
870 throw (SALOME::SALOME_Exception)
872 Unexpect aCatch(SALOME_SalomeException);
874 SMESHDS_Mesh * mesh = GetMeshDS();
875 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
877 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
879 if ( mesh->MaxShapeIndex() < EdgeID )
880 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
882 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
883 if ( shape.ShapeType() != TopAbs_EDGE )
884 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
887 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
888 if ( paramOnEdge < f || paramOnEdge > l )
889 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
891 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
893 myMesh->SetIsModified( true );
896 //=============================================================================
898 * \brief Store node position on a face
899 * \param NodeID - node ID
900 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
901 * \param u - U parameter on face where the node is located
902 * \param v - V parameter on face where the node is located
903 * \retval boolean - false if any parameter is invalid
905 //=============================================================================
907 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
908 CORBA::Double u, CORBA::Double v)
909 throw (SALOME::SALOME_Exception)
911 Unexpect aCatch(SALOME_SalomeException);
913 SMESHDS_Mesh * mesh = GetMeshDS();
914 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
916 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
918 if ( mesh->MaxShapeIndex() < FaceID )
919 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
921 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
922 if ( shape.ShapeType() != TopAbs_FACE )
923 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
925 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
926 bool isOut = ( u < surf.FirstUParameter() ||
927 u > surf.LastUParameter() ||
928 v < surf.FirstVParameter() ||
929 v > surf.LastVParameter() );
933 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
934 << " u( " << surf.FirstUParameter()
935 << "," << surf.LastUParameter()
936 << ") v( " << surf.FirstVParameter()
937 << "," << surf.LastVParameter() << ")" );
939 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
942 mesh->SetNodeOnFace( node, FaceID, u, v );
943 myMesh->SetIsModified( true );
946 //=============================================================================
948 * \brief Bind a node to a solid
949 * \param NodeID - node ID
950 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
951 * \retval boolean - false if NodeID or SolidID is invalid
953 //=============================================================================
955 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
956 throw (SALOME::SALOME_Exception)
958 Unexpect aCatch(SALOME_SalomeException);
960 SMESHDS_Mesh * mesh = GetMeshDS();
961 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
963 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
965 if ( mesh->MaxShapeIndex() < SolidID )
966 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
968 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
969 if ( shape.ShapeType() != TopAbs_SOLID &&
970 shape.ShapeType() != TopAbs_SHELL)
971 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
973 mesh->SetNodeInVolume( node, SolidID );
975 // myMesh->SetIsModified( true ); - SetNodeInVolume() can't prevent re-compute, I believe
978 //=============================================================================
980 * \brief Bind an element to a shape
981 * \param ElementID - element ID
982 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
983 * \retval boolean - false if ElementID or ShapeID is invalid
985 //=============================================================================
987 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
989 throw (SALOME::SALOME_Exception)
991 Unexpect aCatch(SALOME_SalomeException);
993 SMESHDS_Mesh * mesh = GetMeshDS();
994 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
996 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
998 if ( mesh->MaxShapeIndex() < ShapeID )
999 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1001 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1002 if ( shape.ShapeType() != TopAbs_EDGE &&
1003 shape.ShapeType() != TopAbs_FACE &&
1004 shape.ShapeType() != TopAbs_SOLID &&
1005 shape.ShapeType() != TopAbs_SHELL )
1006 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1008 mesh->SetMeshElementOnShape( elem, ShapeID );
1010 myMesh->SetIsModified( true );
1013 //=============================================================================
1017 //=============================================================================
1019 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1020 CORBA::Long NodeID2)
1024 const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
1025 const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
1029 // Update Python script
1030 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1031 << NodeID1 << ", " << NodeID2 << " )";
1034 ::SMESH_MeshEditor aMeshEditor( myMesh );
1035 int ret = aMeshEditor.InverseDiag ( n1, n2 );
1036 myMesh->GetMeshDS()->Modified();
1037 myMesh->SetIsModified( true );
1041 //=============================================================================
1045 //=============================================================================
1047 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1048 CORBA::Long NodeID2)
1052 const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
1053 const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
1057 // Update Python script
1058 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1059 << NodeID1 << ", " << NodeID2 << " )";
1061 ::SMESH_MeshEditor aMeshEditor( myMesh );
1063 bool stat = aMeshEditor.DeleteDiag ( n1, n2 );
1065 myMesh->GetMeshDS()->Modified();
1067 myMesh->SetIsModified( true ); // issue 0020693
1069 storeResult(aMeshEditor);
1074 //=============================================================================
1078 //=============================================================================
1080 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1084 ::SMESH_MeshEditor anEditor( myMesh );
1085 for (int i = 0; i < IDsOfElements.length(); i++)
1087 CORBA::Long index = IDsOfElements[i];
1088 const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
1090 anEditor.Reorient( elem );
1092 // Update Python script
1093 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1095 myMesh->GetMeshDS()->Modified();
1096 if ( IDsOfElements.length() )
1097 myMesh->SetIsModified( true ); // issue 0020693
1103 //=============================================================================
1107 //=============================================================================
1109 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1113 TPythonDump aTPythonDump; // suppress dump in Reorient()
1115 SMESH::long_array_var anElementsId = theObject->GetIDs();
1116 CORBA::Boolean isDone = Reorient(anElementsId);
1118 // Update Python script
1119 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1124 //=============================================================================
1128 //=============================================================================
1129 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1130 SMESH::NumericalFunctor_ptr Criterion,
1131 CORBA::Double MaxAngle)
1135 SMESHDS_Mesh* aMesh = GetMeshDS();
1136 TIDSortedElemSet faces;
1137 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1139 SMESH::NumericalFunctor_i* aNumericalFunctor =
1140 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1141 SMESH::Controls::NumericalFunctorPtr aCrit;
1142 if ( !aNumericalFunctor )
1143 aCrit.reset( new SMESH::Controls::AspectRatio() );
1145 aCrit = aNumericalFunctor->GetNumericalFunctor();
1147 // Update Python script
1148 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1149 << IDsOfElements << ", " << aNumericalFunctor << ", " << MaxAngle << " )";
1151 ::SMESH_MeshEditor anEditor( myMesh );
1153 bool stat = anEditor.TriToQuad( faces, aCrit, MaxAngle );
1154 myMesh->GetMeshDS()->Modified();
1156 myMesh->SetIsModified( true ); // issue 0020693
1158 storeResult(anEditor);
1164 //=============================================================================
1168 //=============================================================================
1169 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1170 SMESH::NumericalFunctor_ptr Criterion,
1171 CORBA::Double MaxAngle)
1175 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1176 SMESH::long_array_var anElementsId = theObject->GetIDs();
1177 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1179 SMESH::NumericalFunctor_i* aNumericalFunctor =
1180 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1182 // Update Python script
1183 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1184 << theObject << ", " << aNumericalFunctor << ", " << MaxAngle << " )";
1190 //=============================================================================
1194 //=============================================================================
1195 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1196 SMESH::NumericalFunctor_ptr Criterion)
1200 SMESHDS_Mesh* aMesh = GetMeshDS();
1201 TIDSortedElemSet faces;
1202 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1204 SMESH::NumericalFunctor_i* aNumericalFunctor =
1205 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1206 SMESH::Controls::NumericalFunctorPtr aCrit;
1207 if ( !aNumericalFunctor )
1208 aCrit.reset( new SMESH::Controls::AspectRatio() );
1210 aCrit = aNumericalFunctor->GetNumericalFunctor();
1213 // Update Python script
1214 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1216 ::SMESH_MeshEditor anEditor( myMesh );
1217 CORBA::Boolean stat = anEditor.QuadToTri( faces, aCrit );
1218 myMesh->GetMeshDS()->Modified();
1220 myMesh->SetIsModified( true ); // issue 0020693
1222 storeResult(anEditor);
1228 //=============================================================================
1232 //=============================================================================
1233 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1234 SMESH::NumericalFunctor_ptr Criterion)
1238 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1240 SMESH::long_array_var anElementsId = theObject->GetIDs();
1241 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1243 SMESH::NumericalFunctor_i* aNumericalFunctor =
1244 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1246 // Update Python script
1247 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1253 //=============================================================================
1257 //=============================================================================
1258 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1259 CORBA::Boolean Diag13)
1263 SMESHDS_Mesh* aMesh = GetMeshDS();
1264 TIDSortedElemSet faces;
1265 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1267 // Update Python script
1268 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1269 << IDsOfElements << ", " << Diag13 << " )";
1271 ::SMESH_MeshEditor anEditor( myMesh );
1272 CORBA::Boolean stat = anEditor.QuadToTri( faces, Diag13 );
1273 myMesh->GetMeshDS()->Modified();
1275 myMesh->SetIsModified( true ); // issue 0020693
1278 storeResult(anEditor);
1284 //=============================================================================
1288 //=============================================================================
1289 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1290 CORBA::Boolean Diag13)
1294 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
1296 SMESH::long_array_var anElementsId = theObject->GetIDs();
1297 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
1299 // Update Python script
1300 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
1301 << theObject << ", " << Diag13 << " )";
1307 //=============================================================================
1311 //=============================================================================
1312 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
1313 SMESH::NumericalFunctor_ptr Criterion)
1317 const SMDS_MeshElement* quad = GetMeshDS()->FindElement(IDOfQuad);
1318 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
1320 SMESH::NumericalFunctor_i* aNumericalFunctor =
1321 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
1322 SMESH::Controls::NumericalFunctorPtr aCrit;
1323 if (aNumericalFunctor)
1324 aCrit = aNumericalFunctor->GetNumericalFunctor();
1326 aCrit.reset(new SMESH::Controls::AspectRatio());
1328 ::SMESH_MeshEditor anEditor (myMesh);
1329 return anEditor.BestSplit(quad, aCrit);
1334 //================================================================================
1336 * \brief Split volumic elements into tetrahedrons
1338 //================================================================================
1340 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
1341 CORBA::Short methodFlags)
1342 throw (SALOME::SALOME_Exception)
1344 Unexpect aCatch(SALOME_SalomeException);
1348 SMESH::long_array_var anElementsId = elems->GetIDs();
1349 TIDSortedElemSet elemSet;
1350 arrayToSet( anElementsId, GetMeshDS(), elemSet, SMDSAbs_Volume );
1352 ::SMESH_MeshEditor anEditor (myMesh);
1353 anEditor.SplitVolumesIntoTetra( elemSet, int( methodFlags ));
1354 myMesh->GetMeshDS()->Modified();
1356 storeResult(anEditor);
1358 // if ( myLastCreatedElems.length() ) - it does not influence Compute()
1359 // myMesh->SetIsModified( true ); // issue 0020693
1361 TPythonDump() << this << ".SplitVolumesIntoTetra( "
1362 << elems << ", " << methodFlags << " )";
1365 //=======================================================================
1368 //=======================================================================
1371 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
1372 const SMESH::long_array & IDsOfFixedNodes,
1373 CORBA::Long MaxNbOfIterations,
1374 CORBA::Double MaxAspectRatio,
1375 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1377 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1378 MaxAspectRatio, Method, false );
1382 //=======================================================================
1383 //function : SmoothParametric
1385 //=======================================================================
1388 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
1389 const SMESH::long_array & IDsOfFixedNodes,
1390 CORBA::Long MaxNbOfIterations,
1391 CORBA::Double MaxAspectRatio,
1392 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1394 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1395 MaxAspectRatio, Method, true );
1399 //=======================================================================
1400 //function : SmoothObject
1402 //=======================================================================
1405 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
1406 const SMESH::long_array & IDsOfFixedNodes,
1407 CORBA::Long MaxNbOfIterations,
1408 CORBA::Double MaxAspectRatio,
1409 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1411 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1412 MaxAspectRatio, Method, false);
1416 //=======================================================================
1417 //function : SmoothParametricObject
1419 //=======================================================================
1422 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
1423 const SMESH::long_array & IDsOfFixedNodes,
1424 CORBA::Long MaxNbOfIterations,
1425 CORBA::Double MaxAspectRatio,
1426 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1428 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1429 MaxAspectRatio, Method, true);
1433 //=============================================================================
1437 //=============================================================================
1440 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
1441 const SMESH::long_array & IDsOfFixedNodes,
1442 CORBA::Long MaxNbOfIterations,
1443 CORBA::Double MaxAspectRatio,
1444 SMESH::SMESH_MeshEditor::Smooth_Method Method,
1449 SMESHDS_Mesh* aMesh = GetMeshDS();
1451 TIDSortedElemSet elements;
1452 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
1454 set<const SMDS_MeshNode*> fixedNodes;
1455 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
1456 CORBA::Long index = IDsOfFixedNodes[i];
1457 const SMDS_MeshNode * node = aMesh->FindNode(index);
1459 fixedNodes.insert( node );
1461 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
1462 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
1463 method = ::SMESH_MeshEditor::CENTROIDAL;
1465 ::SMESH_MeshEditor anEditor( myMesh );
1466 anEditor.Smooth(elements, fixedNodes, method,
1467 MaxNbOfIterations, MaxAspectRatio, IsParametric );
1469 myMesh->GetMeshDS()->Modified();
1470 myMesh->SetIsModified( true ); // issue 0020693
1472 storeResult(anEditor);
1474 // Update Python script
1475 TPythonDump() << "isDone = " << this << "."
1476 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
1477 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
1478 << MaxNbOfIterations << ", " << MaxAspectRatio << ", "
1479 << "SMESH.SMESH_MeshEditor."
1480 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1481 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1487 //=============================================================================
1491 //=============================================================================
1494 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
1495 const SMESH::long_array & IDsOfFixedNodes,
1496 CORBA::Long MaxNbOfIterations,
1497 CORBA::Double MaxAspectRatio,
1498 SMESH::SMESH_MeshEditor::Smooth_Method Method,
1503 TPythonDump aTPythonDump; // suppress dump in smooth()
1505 SMESH::long_array_var anElementsId = theObject->GetIDs();
1506 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
1507 MaxAspectRatio, Method, IsParametric);
1509 // Update Python script
1510 aTPythonDump << "isDone = " << this << "."
1511 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
1512 << theObject << ", " << IDsOfFixedNodes << ", "
1513 << MaxNbOfIterations << ", " << MaxAspectRatio << ", "
1514 << "SMESH.SMESH_MeshEditor."
1515 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1516 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1522 //=============================================================================
1526 //=============================================================================
1528 void SMESH_MeshEditor_i::RenumberNodes()
1530 // Update Python script
1531 TPythonDump() << this << ".RenumberNodes()";
1533 GetMeshDS()->Renumber( true );
1537 //=============================================================================
1541 //=============================================================================
1543 void SMESH_MeshEditor_i::RenumberElements()
1545 // Update Python script
1546 TPythonDump() << this << ".RenumberElements()";
1548 GetMeshDS()->Renumber( false );
1551 //=======================================================================
1553 * \brief Return groups by their IDs
1555 //=======================================================================
1557 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
1561 myMesh_i->CreateGroupServants();
1562 return myMesh_i->GetGroups( *groupIDs );
1565 //=======================================================================
1566 //function : rotationSweep
1568 //=======================================================================
1570 SMESH::ListOfGroups*
1571 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
1572 const SMESH::AxisStruct & theAxis,
1573 CORBA::Double theAngleInRadians,
1574 CORBA::Long theNbOfSteps,
1575 CORBA::Double theTolerance,
1576 const bool theMakeGroups,
1577 const SMDSAbs_ElementType theElementType)
1581 TIDSortedElemSet inElements, copyElements;
1582 arrayToSet(theIDsOfElements, GetMeshDS(), inElements, theElementType);
1584 TIDSortedElemSet* workElements = & inElements;
1585 TPreviewMesh tmpMesh( SMDSAbs_Face );
1586 SMESH_Mesh* mesh = 0;
1587 bool makeWalls=true;
1588 if ( myPreviewMode )
1590 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
1591 tmpMesh.Copy( inElements, copyElements, select, avoid );
1593 workElements = & copyElements;
1594 //makeWalls = false;
1601 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
1602 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
1604 ::SMESH_MeshEditor anEditor( mesh );
1605 ::SMESH_MeshEditor::PGroupIDs groupIds =
1606 anEditor.RotationSweep (*workElements, Ax1, theAngleInRadians,
1607 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
1608 storeResult(anEditor);
1609 myMesh->GetMeshDS()->Modified();
1611 // myMesh->SetIsModified( true ); -- it does not influence Compute()
1613 return theMakeGroups ? getGroups(groupIds.get()) : 0;
1616 //=======================================================================
1617 //function : RotationSweep
1619 //=======================================================================
1621 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
1622 const SMESH::AxisStruct & theAxis,
1623 CORBA::Double theAngleInRadians,
1624 CORBA::Long theNbOfSteps,
1625 CORBA::Double theTolerance)
1627 if ( !myPreviewMode ) {
1628 TPythonDump() << this << ".RotationSweep( "
1629 << theIDsOfElements << ", "
1631 << theAngleInRadians << ", "
1632 << theNbOfSteps << ", "
1633 << theTolerance << " )";
1635 rotationSweep(theIDsOfElements,
1643 //=======================================================================
1644 //function : RotationSweepMakeGroups
1646 //=======================================================================
1648 SMESH::ListOfGroups*
1649 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
1650 const SMESH::AxisStruct& theAxis,
1651 CORBA::Double theAngleInRadians,
1652 CORBA::Long theNbOfSteps,
1653 CORBA::Double theTolerance)
1655 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1657 SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
1663 if (!myPreviewMode) {
1664 DumpGroupsList(aPythonDump, aGroups);
1665 aPythonDump << this << ".RotationSweepMakeGroups( "
1666 << theIDsOfElements << ", "
1668 << theAngleInRadians << ", "
1669 << theNbOfSteps << ", "
1670 << theTolerance << " )";
1675 //=======================================================================
1676 //function : RotationSweepObject
1678 //=======================================================================
1680 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
1681 const SMESH::AxisStruct & theAxis,
1682 CORBA::Double theAngleInRadians,
1683 CORBA::Long theNbOfSteps,
1684 CORBA::Double theTolerance)
1686 if ( !myPreviewMode ) {
1687 TPythonDump() << this << ".RotationSweepObject( "
1688 << theObject << ", "
1690 << theAngleInRadians << ", "
1691 << theNbOfSteps << ", "
1692 << theTolerance << " )";
1694 SMESH::long_array_var anElementsId = theObject->GetIDs();
1695 rotationSweep(anElementsId,
1703 //=======================================================================
1704 //function : RotationSweepObject1D
1706 //=======================================================================
1708 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
1709 const SMESH::AxisStruct & theAxis,
1710 CORBA::Double theAngleInRadians,
1711 CORBA::Long theNbOfSteps,
1712 CORBA::Double theTolerance)
1714 if ( !myPreviewMode ) {
1715 TPythonDump() << this << ".RotationSweepObject1D( "
1716 << theObject << ", "
1718 << theAngleInRadians << ", "
1719 << theNbOfSteps << ", "
1720 << theTolerance << " )";
1722 SMESH::long_array_var anElementsId = theObject->GetIDs();
1723 rotationSweep(anElementsId,
1732 //=======================================================================
1733 //function : RotationSweepObject2D
1735 //=======================================================================
1737 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
1738 const SMESH::AxisStruct & theAxis,
1739 CORBA::Double theAngleInRadians,
1740 CORBA::Long theNbOfSteps,
1741 CORBA::Double theTolerance)
1743 if ( !myPreviewMode ) {
1744 TPythonDump() << this << ".RotationSweepObject2D( "
1745 << theObject << ", "
1747 << theAngleInRadians << ", "
1748 << theNbOfSteps << ", "
1749 << theTolerance << " )";
1751 SMESH::long_array_var anElementsId = theObject->GetIDs();
1752 rotationSweep(anElementsId,
1761 //=======================================================================
1762 //function : RotationSweepObjectMakeGroups
1764 //=======================================================================
1766 SMESH::ListOfGroups*
1767 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1768 const SMESH::AxisStruct& theAxis,
1769 CORBA::Double theAngleInRadians,
1770 CORBA::Long theNbOfSteps,
1771 CORBA::Double theTolerance)
1773 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1775 SMESH::long_array_var anElementsId = theObject->GetIDs();
1776 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
1782 if (!myPreviewMode) {
1783 DumpGroupsList(aPythonDump, aGroups);
1784 aPythonDump << this << ".RotationSweepObjectMakeGroups( "
1785 << theObject << ", "
1787 << theAngleInRadians << ", "
1788 << theNbOfSteps << ", "
1789 << theTolerance << " )";
1794 //=======================================================================
1795 //function : RotationSweepObject1DMakeGroups
1797 //=======================================================================
1799 SMESH::ListOfGroups*
1800 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1801 const SMESH::AxisStruct& theAxis,
1802 CORBA::Double theAngleInRadians,
1803 CORBA::Long theNbOfSteps,
1804 CORBA::Double theTolerance)
1806 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1808 SMESH::long_array_var anElementsId = theObject->GetIDs();
1809 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
1816 if (!myPreviewMode) {
1817 DumpGroupsList(aPythonDump, aGroups);
1818 aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
1819 << theObject << ", "
1821 << theAngleInRadians << ", "
1822 << theNbOfSteps << ", "
1823 << theTolerance << " )";
1828 //=======================================================================
1829 //function : RotationSweepObject2DMakeGroups
1831 //=======================================================================
1833 SMESH::ListOfGroups*
1834 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1835 const SMESH::AxisStruct& theAxis,
1836 CORBA::Double theAngleInRadians,
1837 CORBA::Long theNbOfSteps,
1838 CORBA::Double theTolerance)
1840 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1842 SMESH::long_array_var anElementsId = theObject->GetIDs();
1843 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
1850 if (!myPreviewMode) {
1851 DumpGroupsList(aPythonDump, aGroups);
1852 aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
1853 << theObject << ", "
1855 << theAngleInRadians << ", "
1856 << theNbOfSteps << ", "
1857 << theTolerance << " )";
1863 //=======================================================================
1864 //function : extrusionSweep
1866 //=======================================================================
1868 SMESH::ListOfGroups*
1869 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
1870 const SMESH::DirStruct & theStepVector,
1871 CORBA::Long theNbOfSteps,
1873 const SMDSAbs_ElementType theElementType)
1881 TIDSortedElemSet elements, copyElements;
1882 arrayToSet(theIDsOfElements, GetMeshDS(), elements, theElementType);
1884 const SMESH::PointStruct * P = &theStepVector.PS;
1885 gp_Vec stepVec( P->x, P->y, P->z );
1887 TIDSortedElemSet* workElements = & elements;
1888 TPreviewMesh tmpMesh( SMDSAbs_Face );
1889 SMESH_Mesh* mesh = myMesh;
1891 if ( myPreviewMode ) {
1892 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
1893 tmpMesh.Copy( elements, copyElements, select, avoid );
1895 workElements = & copyElements;
1896 theMakeGroups = false;
1899 TElemOfElemListMap aHystory;
1900 ::SMESH_MeshEditor anEditor( mesh );
1901 ::SMESH_MeshEditor::PGroupIDs groupIds =
1902 anEditor.ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
1904 myMesh->GetMeshDS()->Modified();
1905 storeResult(anEditor);
1907 return theMakeGroups ? getGroups(groupIds.get()) : 0;
1909 } catch(Standard_Failure) {
1910 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1911 INFOS( "SMESH_MeshEditor_i::ExtrusionSweep fails - "<< aFail->GetMessageString() );
1916 //=======================================================================
1917 //function : ExtrusionSweep
1919 //=======================================================================
1921 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
1922 const SMESH::DirStruct & theStepVector,
1923 CORBA::Long theNbOfSteps)
1925 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
1926 if (!myPreviewMode) {
1927 TPythonDump() << this << ".ExtrusionSweep( "
1928 << theIDsOfElements << ", " << theStepVector <<", " << theNbOfSteps << " )";
1933 //=======================================================================
1934 //function : ExtrusionSweepObject
1936 //=======================================================================
1938 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
1939 const SMESH::DirStruct & theStepVector,
1940 CORBA::Long theNbOfSteps)
1942 SMESH::long_array_var anElementsId = theObject->GetIDs();
1943 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
1944 if (!myPreviewMode) {
1945 TPythonDump() << this << ".ExtrusionSweepObject( "
1946 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
1950 //=======================================================================
1951 //function : ExtrusionSweepObject1D
1953 //=======================================================================
1955 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
1956 const SMESH::DirStruct & theStepVector,
1957 CORBA::Long theNbOfSteps)
1959 SMESH::long_array_var anElementsId = theObject->GetIDs();
1960 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
1961 if ( !myPreviewMode ) {
1962 TPythonDump() << this << ".ExtrusionSweepObject1D( "
1963 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
1967 //=======================================================================
1968 //function : ExtrusionSweepObject2D
1970 //=======================================================================
1972 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
1973 const SMESH::DirStruct & theStepVector,
1974 CORBA::Long theNbOfSteps)
1976 SMESH::long_array_var anElementsId = theObject->GetIDs();
1977 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
1978 if ( !myPreviewMode ) {
1979 TPythonDump() << this << ".ExtrusionSweepObject2D( "
1980 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
1984 //=======================================================================
1985 //function : ExtrusionSweepMakeGroups
1987 //=======================================================================
1989 SMESH::ListOfGroups*
1990 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
1991 const SMESH::DirStruct& theStepVector,
1992 CORBA::Long theNbOfSteps)
1994 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1996 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
1998 if (!myPreviewMode) {
1999 DumpGroupsList(aPythonDump, aGroups);
2000 aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
2001 << ", " << theStepVector <<", " << theNbOfSteps << " )";
2006 //=======================================================================
2007 //function : ExtrusionSweepObjectMakeGroups
2009 //=======================================================================
2011 SMESH::ListOfGroups*
2012 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2013 const SMESH::DirStruct& theStepVector,
2014 CORBA::Long theNbOfSteps)
2016 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2018 SMESH::long_array_var anElementsId = theObject->GetIDs();
2019 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
2021 if (!myPreviewMode) {
2022 DumpGroupsList(aPythonDump, aGroups);
2023 aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
2024 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2029 //=======================================================================
2030 //function : ExtrusionSweepObject1DMakeGroups
2032 //=======================================================================
2034 SMESH::ListOfGroups*
2035 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2036 const SMESH::DirStruct& theStepVector,
2037 CORBA::Long theNbOfSteps)
2039 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2041 SMESH::long_array_var anElementsId = theObject->GetIDs();
2042 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2043 theNbOfSteps, true, SMDSAbs_Edge);
2044 if (!myPreviewMode) {
2045 DumpGroupsList(aPythonDump, aGroups);
2046 aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
2047 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2052 //=======================================================================
2053 //function : ExtrusionSweepObject2DMakeGroups
2055 //=======================================================================
2057 SMESH::ListOfGroups*
2058 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2059 const SMESH::DirStruct& theStepVector,
2060 CORBA::Long theNbOfSteps)
2062 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2064 SMESH::long_array_var anElementsId = theObject->GetIDs();
2065 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2066 theNbOfSteps, true, SMDSAbs_Face);
2067 if (!myPreviewMode) {
2068 DumpGroupsList(aPythonDump, aGroups);
2069 aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
2070 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2076 //=======================================================================
2077 //function : advancedExtrusion
2079 //=======================================================================
2081 SMESH::ListOfGroups*
2082 SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
2083 const SMESH::DirStruct & theStepVector,
2084 CORBA::Long theNbOfSteps,
2085 CORBA::Long theExtrFlags,
2086 CORBA::Double theSewTolerance,
2087 const bool theMakeGroups)
2091 TIDSortedElemSet elements;
2092 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
2094 const SMESH::PointStruct * P = &theStepVector.PS;
2095 gp_Vec stepVec( P->x, P->y, P->z );
2097 ::SMESH_MeshEditor anEditor( myMesh );
2098 TElemOfElemListMap aHystory;
2099 ::SMESH_MeshEditor::PGroupIDs groupIds =
2100 anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
2101 theMakeGroups, theExtrFlags, theSewTolerance);
2102 storeResult(anEditor);
2104 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2107 //=======================================================================
2108 //function : AdvancedExtrusion
2110 //=======================================================================
2112 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2113 const SMESH::DirStruct & theStepVector,
2114 CORBA::Long theNbOfSteps,
2115 CORBA::Long theExtrFlags,
2116 CORBA::Double theSewTolerance)
2118 if ( !myPreviewMode ) {
2119 TPythonDump() << "stepVector = " << theStepVector;
2120 TPythonDump() << this << ".AdvancedExtrusion("
2123 << theNbOfSteps << ","
2124 << theExtrFlags << ", "
2125 << theSewTolerance << " )";
2127 advancedExtrusion( theIDsOfElements,
2135 //=======================================================================
2136 //function : AdvancedExtrusionMakeGroups
2138 //=======================================================================
2139 SMESH::ListOfGroups*
2140 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
2141 const SMESH::DirStruct& theStepVector,
2142 CORBA::Long theNbOfSteps,
2143 CORBA::Long theExtrFlags,
2144 CORBA::Double theSewTolerance)
2146 if (!myPreviewMode) {
2147 TPythonDump() << "stepVector = " << theStepVector;
2149 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2151 SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
2158 if (!myPreviewMode) {
2159 DumpGroupsList(aPythonDump, aGroups);
2160 aPythonDump << this << ".AdvancedExtrusionMakeGroups("
2163 << theNbOfSteps << ","
2164 << theExtrFlags << ", "
2165 << theSewTolerance << " )";
2171 //================================================================================
2173 * \brief Convert extrusion error to IDL enum
2175 //================================================================================
2177 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
2179 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
2183 RETCASE( EXTR_NO_ELEMENTS );
2184 RETCASE( EXTR_PATH_NOT_EDGE );
2185 RETCASE( EXTR_BAD_PATH_SHAPE );
2186 RETCASE( EXTR_BAD_STARTING_NODE );
2187 RETCASE( EXTR_BAD_ANGLES_NUMBER );
2188 RETCASE( EXTR_CANT_GET_TANGENT );
2190 return SMESH::SMESH_MeshEditor::EXTR_OK;
2194 //=======================================================================
2195 //function : extrusionAlongPath
2197 //=======================================================================
2198 SMESH::ListOfGroups*
2199 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2200 SMESH::SMESH_Mesh_ptr thePathMesh,
2201 GEOM::GEOM_Object_ptr thePathShape,
2202 CORBA::Long theNodeStart,
2203 CORBA::Boolean theHasAngles,
2204 const SMESH::double_array & theAngles,
2205 CORBA::Boolean theHasRefPoint,
2206 const SMESH::PointStruct & theRefPoint,
2207 const bool theMakeGroups,
2208 SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
2209 const SMDSAbs_ElementType theElementType)
2211 MESSAGE("extrusionAlongPath");
2214 if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
2215 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2218 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2220 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2221 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2223 if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
2224 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2228 SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
2230 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2234 TIDSortedElemSet elements;
2235 arrayToSet(theIDsOfElements, GetMeshDS(), elements, theElementType);
2237 list<double> angles;
2238 for (int i = 0; i < theAngles.length(); i++) {
2239 angles.push_back( theAngles[i] );
2242 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
2244 int nbOldGroups = myMesh->NbGroup();
2246 ::SMESH_MeshEditor anEditor( myMesh );
2247 ::SMESH_MeshEditor::Extrusion_Error error =
2248 anEditor.ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
2249 theHasAngles, angles, false,
2250 theHasRefPoint, refPnt, theMakeGroups );
2251 myMesh->GetMeshDS()->Modified();
2252 storeResult(anEditor);
2253 theError = convExtrError( error );
2255 if ( theMakeGroups ) {
2256 list<int> groupIDs = myMesh->GetGroupIds();
2257 list<int>::iterator newBegin = groupIDs.begin();
2258 std::advance( newBegin, nbOldGroups ); // skip old groups
2259 groupIDs.erase( groupIDs.begin(), newBegin );
2260 return getGroups( & groupIDs );
2266 //=======================================================================
2267 //function : extrusionAlongPathX
2269 //=======================================================================
2270 SMESH::ListOfGroups*
2271 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements,
2272 SMESH::SMESH_IDSource_ptr Path,
2273 CORBA::Long NodeStart,
2274 CORBA::Boolean HasAngles,
2275 const SMESH::double_array& Angles,
2276 CORBA::Boolean LinearVariation,
2277 CORBA::Boolean HasRefPoint,
2278 const SMESH::PointStruct& RefPoint,
2280 const SMDSAbs_ElementType ElementType,
2281 SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
2283 SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
2287 list<double> angles;
2288 for (int i = 0; i < Angles.length(); i++) {
2289 angles.push_back( Angles[i] );
2291 gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
2292 int nbOldGroups = myMesh->NbGroup();
2294 if ( Path->_is_nil() ) {
2295 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2299 TIDSortedElemSet elements, copyElements;
2300 arrayToSet(IDsOfElements, GetMeshDS(), elements, ElementType);
2302 TIDSortedElemSet* workElements = &elements;
2303 TPreviewMesh tmpMesh( SMDSAbs_Face );
2304 SMESH_Mesh* mesh = myMesh;
2306 if ( myPreviewMode )
2308 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2309 tmpMesh.Copy( elements, copyElements, select, avoid );
2311 workElements = & copyElements;
2315 ::SMESH_MeshEditor anEditor( mesh );
2316 ::SMESH_MeshEditor::Extrusion_Error error;
2318 if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path ))
2321 SMDS_MeshNode* aNodeStart =
2322 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2323 if ( !aNodeStart ) {
2324 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2327 error = anEditor.ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
2328 HasAngles, angles, LinearVariation,
2329 HasRefPoint, refPnt, MakeGroups );
2330 myMesh->GetMeshDS()->Modified();
2332 else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
2335 SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
2336 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
2337 SMDS_MeshNode* aNodeStart =
2338 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2339 if ( !aNodeStart ) {
2340 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2343 SMESH_subMesh* aSubMesh =
2344 aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
2345 error = anEditor.ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
2346 HasAngles, angles, LinearVariation,
2347 HasRefPoint, refPnt, MakeGroups );
2348 myMesh->GetMeshDS()->Modified();
2350 else if ( SMESH::DownCast<SMESH_Group_i*>( Path ))
2352 // path as group of 1D elements
2358 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2362 storeResult(anEditor);
2363 Error = convExtrError( error );
2366 list<int> groupIDs = myMesh->GetGroupIds();
2367 list<int>::iterator newBegin = groupIDs.begin();
2368 std::advance( newBegin, nbOldGroups ); // skip old groups
2369 groupIDs.erase( groupIDs.begin(), newBegin );
2370 return getGroups( & groupIDs );
2376 //=======================================================================
2377 //function : ExtrusionAlongPath
2379 //=======================================================================
2380 SMESH::SMESH_MeshEditor::Extrusion_Error
2381 SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2382 SMESH::SMESH_Mesh_ptr thePathMesh,
2383 GEOM::GEOM_Object_ptr thePathShape,
2384 CORBA::Long theNodeStart,
2385 CORBA::Boolean theHasAngles,
2386 const SMESH::double_array & theAngles,
2387 CORBA::Boolean theHasRefPoint,
2388 const SMESH::PointStruct & theRefPoint)
2390 MESSAGE("ExtrusionAlongPath");
2391 if ( !myPreviewMode ) {
2392 TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
2393 << theIDsOfElements << ", "
2394 << thePathMesh << ", "
2395 << thePathShape << ", "
2396 << theNodeStart << ", "
2397 << theHasAngles << ", "
2398 << theAngles << ", "
2399 << theHasRefPoint << ", "
2400 << "SMESH.PointStruct( "
2401 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2402 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2403 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2405 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2406 extrusionAlongPath( theIDsOfElements,
2419 //=======================================================================
2420 //function : ExtrusionAlongPathObject
2422 //=======================================================================
2423 SMESH::SMESH_MeshEditor::Extrusion_Error
2424 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject,
2425 SMESH::SMESH_Mesh_ptr thePathMesh,
2426 GEOM::GEOM_Object_ptr thePathShape,
2427 CORBA::Long theNodeStart,
2428 CORBA::Boolean theHasAngles,
2429 const SMESH::double_array & theAngles,
2430 CORBA::Boolean theHasRefPoint,
2431 const SMESH::PointStruct & theRefPoint)
2433 if ( !myPreviewMode ) {
2434 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
2435 << theObject << ", "
2436 << thePathMesh << ", "
2437 << thePathShape << ", "
2438 << theNodeStart << ", "
2439 << theHasAngles << ", "
2440 << theAngles << ", "
2441 << theHasRefPoint << ", "
2442 << "SMESH.PointStruct( "
2443 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2444 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2445 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2447 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2448 SMESH::long_array_var anElementsId = theObject->GetIDs();
2449 extrusionAlongPath( anElementsId,
2462 //=======================================================================
2463 //function : ExtrusionAlongPathObject1D
2465 //=======================================================================
2466 SMESH::SMESH_MeshEditor::Extrusion_Error
2467 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject,
2468 SMESH::SMESH_Mesh_ptr thePathMesh,
2469 GEOM::GEOM_Object_ptr thePathShape,
2470 CORBA::Long theNodeStart,
2471 CORBA::Boolean theHasAngles,
2472 const SMESH::double_array & theAngles,
2473 CORBA::Boolean theHasRefPoint,
2474 const SMESH::PointStruct & theRefPoint)
2476 if ( !myPreviewMode ) {
2477 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
2478 << theObject << ", "
2479 << thePathMesh << ", "
2480 << thePathShape << ", "
2481 << theNodeStart << ", "
2482 << theHasAngles << ", "
2483 << theAngles << ", "
2484 << theHasRefPoint << ", "
2485 << "SMESH.PointStruct( "
2486 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2487 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2488 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2490 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2491 SMESH::long_array_var anElementsId = theObject->GetIDs();
2492 extrusionAlongPath( anElementsId,
2506 //=======================================================================
2507 //function : ExtrusionAlongPathObject2D
2509 //=======================================================================
2510 SMESH::SMESH_MeshEditor::Extrusion_Error
2511 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject,
2512 SMESH::SMESH_Mesh_ptr thePathMesh,
2513 GEOM::GEOM_Object_ptr thePathShape,
2514 CORBA::Long theNodeStart,
2515 CORBA::Boolean theHasAngles,
2516 const SMESH::double_array & theAngles,
2517 CORBA::Boolean theHasRefPoint,
2518 const SMESH::PointStruct & theRefPoint)
2520 if ( !myPreviewMode ) {
2521 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
2522 << theObject << ", "
2523 << thePathMesh << ", "
2524 << thePathShape << ", "
2525 << theNodeStart << ", "
2526 << theHasAngles << ", "
2527 << theAngles << ", "
2528 << theHasRefPoint << ", "
2529 << "SMESH.PointStruct( "
2530 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2531 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2532 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2534 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2535 SMESH::long_array_var anElementsId = theObject->GetIDs();
2536 extrusionAlongPath( anElementsId,
2551 //=======================================================================
2552 //function : ExtrusionAlongPathMakeGroups
2554 //=======================================================================
2555 SMESH::ListOfGroups*
2556 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theIDsOfElements,
2557 SMESH::SMESH_Mesh_ptr thePathMesh,
2558 GEOM::GEOM_Object_ptr thePathShape,
2559 CORBA::Long theNodeStart,
2560 CORBA::Boolean theHasAngles,
2561 const SMESH::double_array& theAngles,
2562 CORBA::Boolean theHasRefPoint,
2563 const SMESH::PointStruct& theRefPoint,
2564 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2566 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2568 SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements,
2578 if (!myPreviewMode) {
2579 bool isDumpGroups = aGroups && aGroups->length() > 0;
2581 aPythonDump << "(" << aGroups << ", error)";
2583 aPythonDump <<"error";
2585 aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
2586 << theIDsOfElements << ", "
2587 << thePathMesh << ", "
2588 << thePathShape << ", "
2589 << theNodeStart << ", "
2590 << theHasAngles << ", "
2591 << theAngles << ", "
2592 << theHasRefPoint << ", "
2593 << "SMESH.PointStruct( "
2594 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2595 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2596 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2601 //=======================================================================
2602 //function : ExtrusionAlongPathObjectMakeGroups
2604 //=======================================================================
2605 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2606 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2607 SMESH::SMESH_Mesh_ptr thePathMesh,
2608 GEOM::GEOM_Object_ptr thePathShape,
2609 CORBA::Long theNodeStart,
2610 CORBA::Boolean theHasAngles,
2611 const SMESH::double_array& theAngles,
2612 CORBA::Boolean theHasRefPoint,
2613 const SMESH::PointStruct& theRefPoint,
2614 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2616 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2618 SMESH::long_array_var anElementsId = theObject->GetIDs();
2619 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
2630 if (!myPreviewMode) {
2631 bool isDumpGroups = aGroups && aGroups->length() > 0;
2633 aPythonDump << "(" << aGroups << ", error)";
2635 aPythonDump <<"error";
2637 aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
2638 << theObject << ", "
2639 << thePathMesh << ", "
2640 << thePathShape << ", "
2641 << theNodeStart << ", "
2642 << theHasAngles << ", "
2643 << theAngles << ", "
2644 << theHasRefPoint << ", "
2645 << "SMESH.PointStruct( "
2646 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2647 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2648 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2653 //=======================================================================
2654 //function : ExtrusionAlongPathObject1DMakeGroups
2656 //=======================================================================
2657 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2658 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2659 SMESH::SMESH_Mesh_ptr thePathMesh,
2660 GEOM::GEOM_Object_ptr thePathShape,
2661 CORBA::Long theNodeStart,
2662 CORBA::Boolean theHasAngles,
2663 const SMESH::double_array& theAngles,
2664 CORBA::Boolean theHasRefPoint,
2665 const SMESH::PointStruct& theRefPoint,
2666 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2668 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2670 SMESH::long_array_var anElementsId = theObject->GetIDs();
2671 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
2683 if (!myPreviewMode) {
2684 bool isDumpGroups = aGroups && aGroups->length() > 0;
2686 aPythonDump << "(" << aGroups << ", error)";
2688 aPythonDump << "error";
2690 aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
2691 << theObject << ", "
2692 << thePathMesh << ", "
2693 << thePathShape << ", "
2694 << theNodeStart << ", "
2695 << theHasAngles << ", "
2696 << theAngles << ", "
2697 << theHasRefPoint << ", "
2698 << "SMESH.PointStruct( "
2699 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2700 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2701 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2706 //=======================================================================
2707 //function : ExtrusionAlongPathObject2DMakeGroups
2709 //=======================================================================
2710 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2711 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2712 SMESH::SMESH_Mesh_ptr thePathMesh,
2713 GEOM::GEOM_Object_ptr thePathShape,
2714 CORBA::Long theNodeStart,
2715 CORBA::Boolean theHasAngles,
2716 const SMESH::double_array& theAngles,
2717 CORBA::Boolean theHasRefPoint,
2718 const SMESH::PointStruct& theRefPoint,
2719 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2721 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2723 SMESH::long_array_var anElementsId = theObject->GetIDs();
2724 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
2736 if (!myPreviewMode) {
2737 bool isDumpGroups = aGroups && aGroups->length() > 0;
2739 aPythonDump << "(" << aGroups << ", error)";
2741 aPythonDump << "error";
2743 aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
2744 << theObject << ", "
2745 << thePathMesh << ", "
2746 << thePathShape << ", "
2747 << theNodeStart << ", "
2748 << theHasAngles << ", "
2749 << theAngles << ", "
2750 << theHasRefPoint << ", "
2751 << "SMESH.PointStruct( "
2752 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2753 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2754 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2760 //=======================================================================
2761 //function : ExtrusionAlongPathObjX
2763 //=======================================================================
2764 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2765 ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr Object,
2766 SMESH::SMESH_IDSource_ptr Path,
2767 CORBA::Long NodeStart,
2768 CORBA::Boolean HasAngles,
2769 const SMESH::double_array& Angles,
2770 CORBA::Boolean LinearVariation,
2771 CORBA::Boolean HasRefPoint,
2772 const SMESH::PointStruct& RefPoint,
2773 CORBA::Boolean MakeGroups,
2774 SMESH::ElementType ElemType,
2775 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2777 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2779 SMESH::long_array_var anElementsId = Object->GetIDs();
2780 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
2789 (SMDSAbs_ElementType)ElemType,
2792 if (!myPreviewMode) {
2793 bool isDumpGroups = aGroups && aGroups->length() > 0;
2795 aPythonDump << "(" << *aGroups << ", error)";
2797 aPythonDump << "error";
2799 aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
2802 << NodeStart << ", "
2803 << HasAngles << ", "
2805 << LinearVariation << ", "
2806 << HasRefPoint << ", "
2807 << "SMESH.PointStruct( "
2808 << ( HasRefPoint ? RefPoint.x : 0 ) << ", "
2809 << ( HasRefPoint ? RefPoint.y : 0 ) << ", "
2810 << ( HasRefPoint ? RefPoint.z : 0 ) << " ), "
2811 << MakeGroups << ", "
2812 << ElemType << " )";
2818 //=======================================================================
2819 //function : ExtrusionAlongPathX
2821 //=======================================================================
2822 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2823 ExtrusionAlongPathX(const SMESH::long_array& IDsOfElements,
2824 SMESH::SMESH_IDSource_ptr Path,
2825 CORBA::Long NodeStart,
2826 CORBA::Boolean HasAngles,
2827 const SMESH::double_array& Angles,
2828 CORBA::Boolean LinearVariation,
2829 CORBA::Boolean HasRefPoint,
2830 const SMESH::PointStruct& RefPoint,
2831 CORBA::Boolean MakeGroups,
2832 SMESH::ElementType ElemType,
2833 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2835 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2837 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
2846 (SMDSAbs_ElementType)ElemType,
2849 if (!myPreviewMode) {
2850 bool isDumpGroups = aGroups && aGroups->length() > 0;
2852 aPythonDump << "(" << *aGroups << ", error)";
2854 aPythonDump <<"error";
2856 aPythonDump << " = " << this << ".ExtrusionAlongPathX( "
2857 << IDsOfElements << ", "
2859 << NodeStart << ", "
2860 << HasAngles << ", "
2862 << LinearVariation << ", "
2863 << HasRefPoint << ", "
2864 << "SMESH.PointStruct( "
2865 << ( HasRefPoint ? RefPoint.x : 0 ) << ", "
2866 << ( HasRefPoint ? RefPoint.y : 0 ) << ", "
2867 << ( HasRefPoint ? RefPoint.z : 0 ) << " ), "
2868 << MakeGroups << ", "
2869 << ElemType << " )";
2875 //================================================================================
2877 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
2878 * of given angles along path steps
2879 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
2880 * which proceeds the extrusion
2881 * \param PathShape is shape(edge); as the mesh can be complex, the edge
2882 * is used to define the sub-mesh for the path
2884 //================================================================================
2886 SMESH::double_array*
2887 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
2888 GEOM::GEOM_Object_ptr thePathShape,
2889 const SMESH::double_array & theAngles)
2891 SMESH::double_array_var aResult = new SMESH::double_array();
2892 int nbAngles = theAngles.length();
2893 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
2895 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2896 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2897 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2898 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
2899 return aResult._retn();
2900 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
2901 if ( nbSteps == nbAngles )
2903 aResult.inout() = theAngles;
2907 aResult->length( nbSteps );
2908 double rAn2St = double( nbAngles ) / double( nbSteps );
2909 double angPrev = 0, angle;
2910 for ( int iSt = 0; iSt < nbSteps; ++iSt )
2912 double angCur = rAn2St * ( iSt+1 );
2913 double angCurFloor = floor( angCur );
2914 double angPrevFloor = floor( angPrev );
2915 if ( angPrevFloor == angCurFloor )
2916 angle = rAn2St * theAngles[ int( angCurFloor ) ];
2919 int iP = int( angPrevFloor );
2920 double angPrevCeil = ceil(angPrev);
2921 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
2923 int iC = int( angCurFloor );
2924 if ( iC < nbAngles )
2925 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
2927 iP = int( angPrevCeil );
2929 angle += theAngles[ iC ];
2931 aResult[ iSt ] = angle;
2936 // Update Python script
2937 TPythonDump() << "rotAngles = " << theAngles;
2938 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
2939 << thePathMesh << ", "
2940 << thePathShape << ", "
2943 return aResult._retn();
2947 //=======================================================================
2950 //=======================================================================
2952 SMESH::ListOfGroups*
2953 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
2954 const SMESH::AxisStruct & theAxis,
2955 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
2956 CORBA::Boolean theCopy,
2958 ::SMESH_Mesh* theTargetMesh)
2962 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
2963 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
2965 if ( theTargetMesh )
2969 switch ( theMirrorType ) {
2970 case SMESH::SMESH_MeshEditor::POINT:
2971 aTrsf.SetMirror( P );
2973 case SMESH::SMESH_MeshEditor::AXIS:
2974 aTrsf.SetMirror( gp_Ax1( P, V ));
2977 aTrsf.SetMirror( gp_Ax2( P, V ));
2980 TIDSortedElemSet copyElements;
2981 TPreviewMesh tmpMesh;
2982 TIDSortedElemSet* workElements = & theElements;
2983 SMESH_Mesh* mesh = myMesh;
2985 if ( myPreviewMode )
2987 tmpMesh.Copy( theElements, copyElements);
2988 if ( !theCopy && !theTargetMesh )
2990 TIDSortedElemSet elemsAround, elemsAroundCopy;
2991 getElementsAround( theElements, GetMeshDS(), elemsAround );
2992 tmpMesh.Copy( elemsAround, elemsAroundCopy);
2995 workElements = & copyElements;
2996 theMakeGroups = false;
2999 ::SMESH_MeshEditor anEditor( mesh );
3000 ::SMESH_MeshEditor::PGroupIDs groupIds =
3001 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3003 if(theCopy || myPreviewMode)
3004 storeResult(anEditor);
3007 myMesh->SetIsModified( true );
3008 myMesh->GetMeshDS()->Modified();
3010 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3013 //=======================================================================
3016 //=======================================================================
3018 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3019 const SMESH::AxisStruct & theAxis,
3020 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3021 CORBA::Boolean theCopy)
3023 if ( !myPreviewMode ) {
3024 TPythonDump() << this << ".Mirror( "
3025 << theIDsOfElements << ", "
3027 << mirrorTypeName(theMirrorType) << ", "
3030 if ( theIDsOfElements.length() > 0 )
3032 TIDSortedElemSet elements;
3033 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3034 mirror(elements, theAxis, theMirrorType, theCopy, false);
3039 //=======================================================================
3040 //function : MirrorObject
3042 //=======================================================================
3044 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3045 const SMESH::AxisStruct & theAxis,
3046 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3047 CORBA::Boolean theCopy)
3049 if ( !myPreviewMode ) {
3050 TPythonDump() << this << ".MirrorObject( "
3051 << theObject << ", "
3053 << mirrorTypeName(theMirrorType) << ", "
3056 TIDSortedElemSet elements;
3058 bool emptyIfIsMesh = myPreviewMode ? false : true;
3060 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3061 mirror(elements, theAxis, theMirrorType, theCopy, false);
3064 //=======================================================================
3065 //function : MirrorMakeGroups
3067 //=======================================================================
3069 SMESH::ListOfGroups*
3070 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3071 const SMESH::AxisStruct& theMirror,
3072 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3074 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3076 SMESH::ListOfGroups * aGroups = 0;
3077 if ( theIDsOfElements.length() > 0 )
3079 TIDSortedElemSet elements;
3080 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3081 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3083 if (!myPreviewMode) {
3084 DumpGroupsList(aPythonDump, aGroups);
3085 aPythonDump << this << ".MirrorMakeGroups( "
3086 << theIDsOfElements << ", "
3087 << theMirror << ", "
3088 << mirrorTypeName(theMirrorType) << " )";
3093 //=======================================================================
3094 //function : MirrorObjectMakeGroups
3096 //=======================================================================
3098 SMESH::ListOfGroups*
3099 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3100 const SMESH::AxisStruct& theMirror,
3101 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3103 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3105 SMESH::ListOfGroups * aGroups = 0;
3106 TIDSortedElemSet elements;
3107 if ( idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3108 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3112 DumpGroupsList(aPythonDump,aGroups);
3113 aPythonDump << this << ".MirrorObjectMakeGroups( "
3114 << theObject << ", "
3115 << theMirror << ", "
3116 << mirrorTypeName(theMirrorType) << " )";
3121 //=======================================================================
3122 //function : MirrorMakeMesh
3124 //=======================================================================
3126 SMESH::SMESH_Mesh_ptr
3127 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
3128 const SMESH::AxisStruct& theMirror,
3129 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3130 CORBA::Boolean theCopyGroups,
3131 const char* theMeshName)
3133 SMESH_Mesh_i* mesh_i;
3134 SMESH::SMESH_Mesh_var mesh;
3135 { // open new scope to dump "MakeMesh" command
3136 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3138 TPythonDump pydump; // to prevent dump at mesh creation
3140 mesh = makeMesh( theMeshName );
3141 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3142 if (mesh_i && theIDsOfElements.length() > 0 )
3144 TIDSortedElemSet elements;
3145 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3146 mirror(elements, theMirror, theMirrorType,
3147 false, theCopyGroups, & mesh_i->GetImpl());
3148 mesh_i->CreateGroupServants();
3151 if (!myPreviewMode) {
3152 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
3153 << theIDsOfElements << ", "
3154 << theMirror << ", "
3155 << mirrorTypeName(theMirrorType) << ", "
3156 << theCopyGroups << ", '"
3157 << theMeshName << "' )";
3162 if (!myPreviewMode && mesh_i)
3163 mesh_i->GetGroups();
3165 return mesh._retn();
3168 //=======================================================================
3169 //function : MirrorObjectMakeMesh
3171 //=======================================================================
3173 SMESH::SMESH_Mesh_ptr
3174 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3175 const SMESH::AxisStruct& theMirror,
3176 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3177 CORBA::Boolean theCopyGroups,
3178 const char* theMeshName)
3180 SMESH_Mesh_i* mesh_i;
3181 SMESH::SMESH_Mesh_var mesh;
3182 { // open new scope to dump "MakeMesh" command
3183 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3185 TPythonDump pydump; // to prevent dump at mesh creation
3187 mesh = makeMesh( theMeshName );
3188 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3189 TIDSortedElemSet elements;
3191 idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3193 mirror(elements, theMirror, theMirrorType,
3194 false, theCopyGroups, & mesh_i->GetImpl());
3195 mesh_i->CreateGroupServants();
3197 if (!myPreviewMode) {
3198 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
3199 << theObject << ", "
3200 << theMirror << ", "
3201 << mirrorTypeName(theMirrorType) << ", "
3202 << theCopyGroups << ", '"
3203 << theMeshName << "' )";
3208 if (!myPreviewMode && mesh_i)
3209 mesh_i->GetGroups();
3211 return mesh._retn();
3214 //=======================================================================
3215 //function : translate
3217 //=======================================================================
3219 SMESH::ListOfGroups*
3220 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
3221 const SMESH::DirStruct & theVector,
3222 CORBA::Boolean theCopy,
3224 ::SMESH_Mesh* theTargetMesh)
3228 if ( theTargetMesh )
3232 const SMESH::PointStruct * P = &theVector.PS;
3233 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
3235 TIDSortedElemSet copyElements;
3236 TIDSortedElemSet* workElements = &theElements;
3237 TPreviewMesh tmpMesh;
3238 SMESH_Mesh* mesh = myMesh;
3240 if ( myPreviewMode )
3242 tmpMesh.Copy( theElements, copyElements);
3243 if ( !theCopy && !theTargetMesh )
3245 TIDSortedElemSet elemsAround, elemsAroundCopy;
3246 getElementsAround( theElements, GetMeshDS(), elemsAround );
3247 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3250 workElements = & copyElements;
3251 theMakeGroups = false;
3254 ::SMESH_MeshEditor anEditor( mesh );
3255 ::SMESH_MeshEditor::PGroupIDs groupIds =
3256 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3258 if(theCopy || myPreviewMode)
3259 storeResult(anEditor);
3262 myMesh->GetMeshDS()->Modified();
3263 myMesh->SetIsModified( true );
3266 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3269 //=======================================================================
3270 //function : Translate
3272 //=======================================================================
3274 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
3275 const SMESH::DirStruct & theVector,
3276 CORBA::Boolean theCopy)
3278 if (!myPreviewMode) {
3279 TPythonDump() << this << ".Translate( "
3280 << theIDsOfElements << ", "
3281 << theVector << ", "
3284 if (theIDsOfElements.length()) {
3285 TIDSortedElemSet elements;
3286 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3287 translate(elements, theVector, theCopy, false);
3291 //=======================================================================
3292 //function : TranslateObject
3294 //=======================================================================
3296 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
3297 const SMESH::DirStruct & theVector,
3298 CORBA::Boolean theCopy)
3300 if (!myPreviewMode) {
3301 TPythonDump() << this << ".TranslateObject( "
3302 << theObject << ", "
3303 << theVector << ", "
3306 TIDSortedElemSet elements;
3308 bool emptyIfIsMesh = myPreviewMode ? false : true;
3310 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3311 translate(elements, theVector, theCopy, false);
3314 //=======================================================================
3315 //function : TranslateMakeGroups
3317 //=======================================================================
3319 SMESH::ListOfGroups*
3320 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
3321 const SMESH::DirStruct& theVector)
3323 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3325 SMESH::ListOfGroups * aGroups = 0;
3326 if (theIDsOfElements.length()) {
3327 TIDSortedElemSet elements;
3328 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3329 aGroups = translate(elements,theVector,true,true);
3331 if (!myPreviewMode) {
3332 DumpGroupsList(aPythonDump, aGroups);
3333 aPythonDump << this << ".TranslateMakeGroups( "
3334 << theIDsOfElements << ", "
3335 << theVector << " )";
3340 //=======================================================================
3341 //function : TranslateObjectMakeGroups
3343 //=======================================================================
3345 SMESH::ListOfGroups*
3346 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3347 const SMESH::DirStruct& theVector)
3349 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3351 SMESH::ListOfGroups * aGroups = 0;
3352 TIDSortedElemSet elements;
3353 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3354 aGroups = translate(elements, theVector, true, true);
3356 if (!myPreviewMode) {
3357 DumpGroupsList(aPythonDump, aGroups);
3358 aPythonDump << this << ".TranslateObjectMakeGroups( "
3359 << theObject << ", "
3360 << theVector << " )";
3365 //=======================================================================
3366 //function : TranslateMakeMesh
3368 //=======================================================================
3370 SMESH::SMESH_Mesh_ptr
3371 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
3372 const SMESH::DirStruct& theVector,
3373 CORBA::Boolean theCopyGroups,
3374 const char* theMeshName)
3376 SMESH_Mesh_i* mesh_i;
3377 SMESH::SMESH_Mesh_var mesh;
3379 { // open new scope to dump "MakeMesh" command
3380 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3382 TPythonDump pydump; // to prevent dump at mesh creation
3384 mesh = makeMesh( theMeshName );
3385 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3387 if ( mesh_i && theIDsOfElements.length() )
3389 TIDSortedElemSet elements;
3390 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3391 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
3392 mesh_i->CreateGroupServants();
3395 if ( !myPreviewMode ) {
3396 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
3397 << theIDsOfElements << ", "
3398 << theVector << ", "
3399 << theCopyGroups << ", '"
3400 << theMeshName << "' )";
3405 if (!myPreviewMode && mesh_i)
3406 mesh_i->GetGroups();
3408 return mesh._retn();
3411 //=======================================================================
3412 //function : TranslateObjectMakeMesh
3414 //=======================================================================
3416 SMESH::SMESH_Mesh_ptr
3417 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3418 const SMESH::DirStruct& theVector,
3419 CORBA::Boolean theCopyGroups,
3420 const char* theMeshName)
3422 SMESH_Mesh_i* mesh_i;
3423 SMESH::SMESH_Mesh_var mesh;
3424 { // open new scope to dump "MakeMesh" command
3425 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3427 TPythonDump pydump; // to prevent dump at mesh creation
3428 mesh = makeMesh( theMeshName );
3429 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3431 TIDSortedElemSet elements;
3433 idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3435 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
3436 mesh_i->CreateGroupServants();
3438 if ( !myPreviewMode ) {
3439 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
3440 << theObject << ", "
3441 << theVector << ", "
3442 << theCopyGroups << ", '"
3443 << theMeshName << "' )";
3448 if (!myPreviewMode && mesh_i)
3449 mesh_i->GetGroups();
3451 return mesh._retn();
3454 //=======================================================================
3457 //=======================================================================
3459 SMESH::ListOfGroups*
3460 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
3461 const SMESH::AxisStruct & theAxis,
3462 CORBA::Double theAngle,
3463 CORBA::Boolean theCopy,
3465 ::SMESH_Mesh* theTargetMesh)
3469 if ( theTargetMesh )
3472 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3473 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3476 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
3478 TIDSortedElemSet copyElements;
3479 TIDSortedElemSet* workElements = &theElements;
3480 TPreviewMesh tmpMesh;
3481 SMESH_Mesh* mesh = myMesh;
3483 if ( myPreviewMode ) {
3484 tmpMesh.Copy( theElements, copyElements );
3485 if ( !theCopy && !theTargetMesh )
3487 TIDSortedElemSet elemsAround, elemsAroundCopy;
3488 getElementsAround( theElements, GetMeshDS(), elemsAround );
3489 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3492 workElements = ©Elements;
3493 theMakeGroups = false;
3496 ::SMESH_MeshEditor anEditor( mesh );
3497 ::SMESH_MeshEditor::PGroupIDs groupIds =
3498 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3500 if(theCopy || myPreviewMode)
3501 storeResult(anEditor);
3504 myMesh->GetMeshDS()->Modified();
3505 myMesh->SetIsModified( true );
3508 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3511 //=======================================================================
3514 //=======================================================================
3516 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
3517 const SMESH::AxisStruct & theAxis,
3518 CORBA::Double theAngle,
3519 CORBA::Boolean theCopy)
3521 if (!myPreviewMode) {
3522 TPythonDump() << this << ".Rotate( "
3523 << theIDsOfElements << ", "
3528 if (theIDsOfElements.length() > 0)
3530 TIDSortedElemSet elements;
3531 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3532 rotate(elements,theAxis,theAngle,theCopy,false);
3536 //=======================================================================
3537 //function : RotateObject
3539 //=======================================================================
3541 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
3542 const SMESH::AxisStruct & theAxis,
3543 CORBA::Double theAngle,
3544 CORBA::Boolean theCopy)
3546 if ( !myPreviewMode ) {
3547 TPythonDump() << this << ".RotateObject( "
3548 << theObject << ", "
3553 TIDSortedElemSet elements;
3554 bool emptyIfIsMesh = myPreviewMode ? false : true;
3555 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3556 rotate(elements,theAxis,theAngle,theCopy,false);
3559 //=======================================================================
3560 //function : RotateMakeGroups
3562 //=======================================================================
3564 SMESH::ListOfGroups*
3565 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
3566 const SMESH::AxisStruct& theAxis,
3567 CORBA::Double theAngle)
3569 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3571 SMESH::ListOfGroups * aGroups = 0;
3572 if (theIDsOfElements.length() > 0)
3574 TIDSortedElemSet elements;
3575 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3576 aGroups = rotate(elements,theAxis,theAngle,true,true);
3578 if (!myPreviewMode) {
3579 DumpGroupsList(aPythonDump, aGroups);
3580 aPythonDump << this << ".RotateMakeGroups( "
3581 << theIDsOfElements << ", "
3583 << theAngle << " )";
3588 //=======================================================================
3589 //function : RotateObjectMakeGroups
3591 //=======================================================================
3593 SMESH::ListOfGroups*
3594 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3595 const SMESH::AxisStruct& theAxis,
3596 CORBA::Double theAngle)
3598 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3600 SMESH::ListOfGroups * aGroups = 0;
3601 TIDSortedElemSet elements;
3602 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3603 aGroups = rotate(elements, theAxis, theAngle, true, true);
3605 if (!myPreviewMode) {
3606 DumpGroupsList(aPythonDump, aGroups);
3607 aPythonDump << this << ".RotateObjectMakeGroups( "
3608 << theObject << ", "
3610 << theAngle << " )";
3615 //=======================================================================
3616 //function : RotateMakeMesh
3618 //=======================================================================
3620 SMESH::SMESH_Mesh_ptr
3621 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
3622 const SMESH::AxisStruct& theAxis,
3623 CORBA::Double theAngleInRadians,
3624 CORBA::Boolean theCopyGroups,
3625 const char* theMeshName)
3627 SMESH::SMESH_Mesh_var mesh;
3628 SMESH_Mesh_i* mesh_i;
3630 { // open new scope to dump "MakeMesh" command
3631 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3633 TPythonDump pydump; // to prevent dump at mesh creation
3635 mesh = makeMesh( theMeshName );
3636 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3638 if ( mesh_i && theIDsOfElements.length() > 0 )
3640 TIDSortedElemSet elements;
3641 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3642 rotate(elements, theAxis, theAngleInRadians,
3643 false, theCopyGroups, & mesh_i->GetImpl());
3644 mesh_i->CreateGroupServants();
3646 if ( !myPreviewMode ) {
3647 pydump << mesh << " = " << this << ".RotateMakeMesh( "
3648 << theIDsOfElements << ", "
3650 << theAngleInRadians << ", "
3651 << theCopyGroups << ", '"
3652 << theMeshName << "' )";
3657 if (!myPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
3658 mesh_i->GetGroups();
3660 return mesh._retn();
3663 //=======================================================================
3664 //function : RotateObjectMakeMesh
3666 //=======================================================================
3668 SMESH::SMESH_Mesh_ptr
3669 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3670 const SMESH::AxisStruct& theAxis,
3671 CORBA::Double theAngleInRadians,
3672 CORBA::Boolean theCopyGroups,
3673 const char* theMeshName)
3675 SMESH::SMESH_Mesh_var mesh;
3676 SMESH_Mesh_i* mesh_i;
3678 {// open new scope to dump "MakeMesh" command
3679 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3681 TPythonDump pydump; // to prevent dump at mesh creation
3682 mesh = makeMesh( theMeshName );
3683 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3685 TIDSortedElemSet elements;
3687 idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3689 rotate(elements, theAxis, theAngleInRadians,
3690 false, theCopyGroups, & mesh_i->GetImpl());
3691 mesh_i->CreateGroupServants();
3693 if ( !myPreviewMode ) {
3694 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
3695 << theObject << ", "
3697 << theAngleInRadians << ", "
3698 << theCopyGroups << ", '"
3699 << theMeshName << "' )";
3704 if (!myPreviewMode && mesh_i)
3705 mesh_i->GetGroups();
3707 return mesh._retn();
3710 //=======================================================================
3713 //=======================================================================
3715 SMESH::ListOfGroups*
3716 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
3717 const SMESH::PointStruct& thePoint,
3718 const SMESH::double_array& theScaleFact,
3719 CORBA::Boolean theCopy,
3721 ::SMESH_Mesh* theTargetMesh)
3724 if ( theScaleFact.length() < 1 )
3725 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
3726 if ( theScaleFact.length() == 2 )
3727 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
3729 if ( theTargetMesh )
3732 TIDSortedElemSet elements;
3733 bool emptyIfIsMesh = myPreviewMode ? false : true;
3734 if ( !idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3739 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
3740 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
3742 double tol = std::numeric_limits<double>::max();
3744 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
3745 0, S[1], 0, thePoint.y * (1-S[1]),
3746 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
3748 TIDSortedElemSet copyElements;
3749 TPreviewMesh tmpMesh;
3750 TIDSortedElemSet* workElements = &elements;
3751 SMESH_Mesh* mesh = myMesh;
3753 if ( myPreviewMode )
3755 tmpMesh.Copy( elements, copyElements);
3756 if ( !theCopy && !theTargetMesh )
3758 TIDSortedElemSet elemsAround, elemsAroundCopy;
3759 getElementsAround( elements, GetMeshDS(), elemsAround );
3760 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3763 workElements = & copyElements;
3764 theMakeGroups = false;
3767 ::SMESH_MeshEditor anEditor( mesh );
3768 ::SMESH_MeshEditor::PGroupIDs groupIds =
3769 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3771 if(theCopy || myPreviewMode )
3772 storeResult(anEditor);
3775 myMesh->GetMeshDS()->Modified();
3776 myMesh->SetIsModified( true );
3778 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3781 //=======================================================================
3784 //=======================================================================
3786 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
3787 const SMESH::PointStruct& thePoint,
3788 const SMESH::double_array& theScaleFact,
3789 CORBA::Boolean theCopy)
3791 if ( !myPreviewMode ) {
3792 TPythonDump() << this << ".Scale( "
3793 << theObject << ", "
3794 << "SMESH.PointStruct( " << thePoint.x << ", "
3795 << thePoint.y << ", " << thePoint.z << " ) ,"
3796 << theScaleFact << ", "
3799 scale(theObject, thePoint, theScaleFact, theCopy, false);
3803 //=======================================================================
3804 //function : ScaleMakeGroups
3806 //=======================================================================
3808 SMESH::ListOfGroups*
3809 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3810 const SMESH::PointStruct& thePoint,
3811 const SMESH::double_array& theScaleFact)
3813 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3815 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
3816 if (!myPreviewMode) {
3817 DumpGroupsList(aPythonDump, aGroups);
3818 aPythonDump << this << ".Scale("
3820 << "SMESH.PointStruct(" <<thePoint.x << ","
3821 << thePoint.y << "," << thePoint.z << "),"
3822 << theScaleFact << ",True,True)";
3828 //=======================================================================
3829 //function : ScaleMakeMesh
3831 //=======================================================================
3833 SMESH::SMESH_Mesh_ptr
3834 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3835 const SMESH::PointStruct& thePoint,
3836 const SMESH::double_array& theScaleFact,
3837 CORBA::Boolean theCopyGroups,
3838 const char* theMeshName)
3840 SMESH_Mesh_i* mesh_i;
3841 SMESH::SMESH_Mesh_var mesh;
3842 { // open new scope to dump "MakeMesh" command
3843 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3845 TPythonDump pydump; // to prevent dump at mesh creation
3846 mesh = makeMesh( theMeshName );
3847 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3851 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
3852 mesh_i->CreateGroupServants();
3854 if ( !myPreviewMode )
3855 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
3856 << theObject << ", "
3857 << "SMESH.PointStruct( " << thePoint.x << ", "
3858 << thePoint.y << ", " << thePoint.z << " ) ,"
3859 << theScaleFact << ", "
3860 << theCopyGroups << ", '"
3861 << theMeshName << "' )";
3865 if (!myPreviewMode && mesh_i)
3866 mesh_i->GetGroups();
3868 return mesh._retn();
3872 //=======================================================================
3873 //function : FindCoincidentNodes
3875 //=======================================================================
3877 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance,
3878 SMESH::array_of_long_array_out GroupsOfNodes)
3882 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3883 ::SMESH_MeshEditor anEditor( myMesh );
3884 TIDSortedNodeSet nodes; // no input nodes
3885 anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
3887 GroupsOfNodes = new SMESH::array_of_long_array;
3888 GroupsOfNodes->length( aListOfListOfNodes.size() );
3889 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
3890 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
3891 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
3892 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
3893 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
3894 aGroup.length( aListOfNodes.size() );
3895 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
3896 aGroup[ j ] = (*lIt)->GetID();
3898 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
3899 << Tolerance << " )";
3902 //=======================================================================
3903 //function : FindCoincidentNodesOnPart
3905 //=======================================================================
3906 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
3907 CORBA::Double Tolerance,
3908 SMESH::array_of_long_array_out GroupsOfNodes)
3912 TIDSortedNodeSet nodes;
3913 idSourceToNodeSet( theObject, GetMeshDS(), nodes );
3915 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3916 ::SMESH_MeshEditor anEditor( myMesh );
3918 anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
3920 GroupsOfNodes = new SMESH::array_of_long_array;
3921 GroupsOfNodes->length( aListOfListOfNodes.size() );
3922 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
3923 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
3925 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
3926 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
3927 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
3928 aGroup.length( aListOfNodes.size() );
3929 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
3930 aGroup[ j ] = (*lIt)->GetID();
3932 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
3934 << Tolerance << " )";
3937 //================================================================================
3939 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
3940 * ExceptSubMeshOrGroups
3942 //================================================================================
3944 void SMESH_MeshEditor_i::
3945 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
3946 CORBA::Double theTolerance,
3947 SMESH::array_of_long_array_out theGroupsOfNodes,
3948 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups)
3952 TIDSortedNodeSet nodes;
3953 idSourceToNodeSet( theObject, GetMeshDS(), nodes );
3955 for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
3957 TIDSortedNodeSet exceptNodes;
3958 idSourceToNodeSet( theExceptSubMeshOrGroups[i], GetMeshDS(), exceptNodes );
3959 TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
3960 for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
3961 nodes.erase( *avoidNode );
3963 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3964 ::SMESH_MeshEditor anEditor( myMesh );
3966 anEditor.FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
3968 theGroupsOfNodes = new SMESH::array_of_long_array;
3969 theGroupsOfNodes->length( aListOfListOfNodes.size() );
3970 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
3971 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
3973 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
3974 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
3975 SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
3976 aGroup.length( aListOfNodes.size() );
3977 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
3978 aGroup[ j ] = (*lIt)->GetID();
3980 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
3982 << theTolerance << ", "
3983 << theExceptSubMeshOrGroups << " )";
3986 //=======================================================================
3987 //function : MergeNodes
3989 //=======================================================================
3991 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
3995 SMESHDS_Mesh* aMesh = GetMeshDS();
3997 TPythonDump aTPythonDump;
3998 aTPythonDump << this << ".MergeNodes([";
3999 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4000 for (int i = 0; i < GroupsOfNodes.length(); i++)
4002 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
4003 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
4004 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
4005 for ( int j = 0; j < aNodeGroup.length(); j++ )
4007 CORBA::Long index = aNodeGroup[ j ];
4008 const SMDS_MeshNode * node = aMesh->FindNode(index);
4010 aListOfNodes.push_back( node );
4012 if ( aListOfNodes.size() < 2 )
4013 aListOfListOfNodes.pop_back();
4015 if ( i > 0 ) aTPythonDump << ", ";
4016 aTPythonDump << aNodeGroup;
4018 ::SMESH_MeshEditor anEditor( myMesh );
4019 anEditor.MergeNodes( aListOfListOfNodes );
4021 aTPythonDump << "])";
4022 myMesh->GetMeshDS()->Modified();
4023 myMesh->SetIsModified( true );
4026 //=======================================================================
4027 //function : FindEqualElements
4029 //=======================================================================
4030 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
4031 SMESH::array_of_long_array_out GroupsOfElementsID)
4035 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
4036 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
4038 typedef list<int> TListOfIDs;
4039 set<const SMDS_MeshElement*> elems;
4040 SMESH::long_array_var aElementsId = theObject->GetIDs();
4041 SMESHDS_Mesh* aMesh = GetMeshDS();
4043 for(int i = 0; i < aElementsId->length(); i++) {
4044 CORBA::Long anID = aElementsId[i];
4045 const SMDS_MeshElement * elem = aMesh->FindElement(anID);
4051 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4052 ::SMESH_MeshEditor anEditor( myMesh );
4053 anEditor.FindEqualElements( elems, aListOfListOfElementsID );
4055 GroupsOfElementsID = new SMESH::array_of_long_array;
4056 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
4058 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt = aListOfListOfElementsID.begin();
4059 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j) {
4060 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
4061 TListOfIDs& listOfIDs = *arraysIt;
4062 aGroup.length( listOfIDs.size() );
4063 TListOfIDs::iterator idIt = listOfIDs.begin();
4064 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k ) {
4065 aGroup[ k ] = *idIt;
4069 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
4074 //=======================================================================
4075 //function : MergeElements
4077 //=======================================================================
4079 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
4083 TPythonDump aTPythonDump;
4084 aTPythonDump << this << ".MergeElements( [";
4086 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4088 for (int i = 0; i < GroupsOfElementsID.length(); i++) {
4089 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
4090 aListOfListOfElementsID.push_back( list< int >() );
4091 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
4092 for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
4093 CORBA::Long id = anElemsIDGroup[ j ];
4094 aListOfElemsID.push_back( id );
4096 if ( aListOfElemsID.size() < 2 )
4097 aListOfListOfElementsID.pop_back();
4098 if ( i > 0 ) aTPythonDump << ", ";
4099 aTPythonDump << anElemsIDGroup;
4102 ::SMESH_MeshEditor anEditor( myMesh );
4103 anEditor.MergeElements(aListOfListOfElementsID);
4104 myMesh->GetMeshDS()->Modified();
4105 myMesh->SetIsModified( true );
4107 aTPythonDump << "] )";
4110 //=======================================================================
4111 //function : MergeEqualElements
4113 //=======================================================================
4115 void SMESH_MeshEditor_i::MergeEqualElements()
4119 ::SMESH_MeshEditor anEditor( myMesh );
4120 anEditor.MergeEqualElements();
4122 TPythonDump() << this << ".MergeEqualElements()";
4125 //=============================================================================
4127 * Move the node to a given point
4129 //=============================================================================
4131 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
4136 initData(/*deleteSearchers=*/false);
4138 const SMDS_MeshNode * node = GetMeshDS()->FindNode( NodeID );
4142 if ( theNodeSearcher )
4143 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4145 if ( myPreviewMode ) // make preview data
4147 // in a preview mesh, make edges linked to a node
4148 TPreviewMesh tmpMesh;
4149 TIDSortedElemSet linkedNodes;
4150 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4151 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4152 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
4153 for ( ; nIt != linkedNodes.end(); ++nIt )
4155 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
4156 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
4160 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
4161 // fill preview data
4162 ::SMESH_MeshEditor anEditor( & tmpMesh );
4163 storeResult( anEditor );
4165 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4166 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4168 GetMeshDS()->MoveNode(node, x, y, z);
4170 if ( !myPreviewMode )
4172 // Update Python script
4173 TPythonDump() << "isDone = " << this << ".MoveNode( "
4174 << NodeID << ", " << x << ", " << y << ", " << z << " )";
4175 myMesh->GetMeshDS()->Modified();
4176 myMesh->SetIsModified( true );
4182 //================================================================================
4184 * \brief Return ID of node closest to a given point
4186 //================================================================================
4188 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
4192 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4194 if ( !theNodeSearcher ) {
4195 ::SMESH_MeshEditor anEditor( myMesh );
4196 theNodeSearcher = anEditor.GetNodeSearcher();
4199 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
4200 return node->GetID();
4205 //================================================================================
4207 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
4208 * move the node closest to the point to point's location and return ID of the node
4210 //================================================================================
4212 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
4215 CORBA::Long theNodeID)
4217 // We keep theNodeSearcher until any mesh modification:
4218 // 1) initData() deletes theNodeSearcher at any edition,
4219 // 2) TSearchersDeleter - at any mesh compute event and mesh change
4221 initData(/*deleteSearchers=*/false);
4223 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4225 int nodeID = theNodeID;
4226 const SMDS_MeshNode* node = GetMeshDS()->FindNode( nodeID );
4227 if ( !node ) // preview moving node
4229 if ( !theNodeSearcher ) {
4230 ::SMESH_MeshEditor anEditor( myMesh );
4231 theNodeSearcher = anEditor.GetNodeSearcher();
4234 node = theNodeSearcher->FindClosestTo( p );
4237 nodeID = node->GetID();
4238 if ( myPreviewMode ) // make preview data
4240 // in a preview mesh, make edges linked to a node
4241 TPreviewMesh tmpMesh;
4242 TIDSortedElemSet linkedNodes;
4243 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4244 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4245 for ( ; nIt != linkedNodes.end(); ++nIt )
4247 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
4248 tmpMesh.Copy( &edge );
4251 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
4253 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
4254 // fill preview data
4255 ::SMESH_MeshEditor anEditor( & tmpMesh );
4256 storeResult( anEditor );
4258 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4260 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4264 GetMeshDS()->MoveNode(node, x, y, z);
4268 if ( !myPreviewMode )
4270 TPythonDump() << "nodeID = " << this
4271 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
4272 << ", " << nodeID << " )";
4274 myMesh->GetMeshDS()->Modified();
4275 myMesh->SetIsModified( true );
4281 //=======================================================================
4283 * Return elements of given type where the given point is IN or ON.
4285 * 'ALL' type means elements of any type excluding nodes
4287 //=======================================================================
4289 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
4292 SMESH::ElementType type)
4294 SMESH::long_array_var res = new SMESH::long_array;
4295 vector< const SMDS_MeshElement* > foundElems;
4297 theSearchersDeleter.Set( myMesh );
4298 if ( !theElementSearcher ) {
4299 ::SMESH_MeshEditor anEditor( myMesh );
4300 theElementSearcher = anEditor.GetElementSearcher();
4302 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4303 SMDSAbs_ElementType( type ),
4305 res->length( foundElems.size() );
4306 for ( int i = 0; i < foundElems.size(); ++i )
4307 res[i] = foundElems[i]->GetID();
4309 if ( !myPreviewMode ) // call from tui
4310 TPythonDump() << "res = " << this << ".FindElementsByPoint( "
4319 //=======================================================================
4320 //function : FindAmongElementsByPoint
4321 //purpose : Searching among the given elements, return elements of given type
4322 // where the given point is IN or ON.
4323 // 'ALL' type means elements of any type excluding nodes
4324 //=======================================================================
4327 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
4331 SMESH::ElementType type)
4333 SMESH::long_array_var res = new SMESH::long_array;
4335 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
4336 if ( types->length() == 1 && // a part contains only nodes or 0D elements
4337 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D ) &&
4338 type != types[0] ) // but search of elements of dim > 0
4341 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
4342 return FindElementsByPoint( x,y,z, type );
4344 string partIOR = SMESH_Gen_i::GetORB()->object_to_string( elementIDs );
4345 if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( elementIDs ))
4346 // take into account passible group modification
4347 partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() );
4348 partIOR += SMESH_Comment( type );
4350 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
4352 theSearchersDeleter.Set( myMesh, partIOR );
4353 if ( !theElementSearcher )
4355 // create a searcher from elementIDs
4356 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
4357 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
4359 if ( !idSourceToSet( elementIDs, meshDS, elements,
4360 SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
4363 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
4364 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
4366 ::SMESH_MeshEditor anEditor( myMesh );
4367 theElementSearcher = anEditor.GetElementSearcher(elemsIt);
4370 vector< const SMDS_MeshElement* > foundElems;
4372 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4373 SMDSAbs_ElementType( type ),
4375 res->length( foundElems.size() );
4376 for ( int i = 0; i < foundElems.size(); ++i )
4377 res[i] = foundElems[i]->GetID();
4379 if ( !myPreviewMode ) // call from tui
4380 TPythonDump() << "res = " << this << ".FindAmongElementsByPoint( "
4381 << elementIDs << ", "
4390 //=======================================================================
4391 //function : GetPointState
4392 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
4393 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
4394 //=======================================================================
4396 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
4400 theSearchersDeleter.Set( myMesh );
4401 if ( !theElementSearcher ) {
4402 ::SMESH_MeshEditor anEditor( myMesh );
4403 theElementSearcher = anEditor.GetElementSearcher();
4405 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
4408 //=======================================================================
4409 //function : convError
4411 //=======================================================================
4413 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
4415 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
4419 RETCASE( SEW_BORDER1_NOT_FOUND );
4420 RETCASE( SEW_BORDER2_NOT_FOUND );
4421 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
4422 RETCASE( SEW_BAD_SIDE_NODES );
4423 RETCASE( SEW_VOLUMES_TO_SPLIT );
4424 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
4425 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
4426 RETCASE( SEW_BAD_SIDE1_NODES );
4427 RETCASE( SEW_BAD_SIDE2_NODES );
4429 return SMESH::SMESH_MeshEditor::SEW_OK;
4432 //=======================================================================
4433 //function : SewFreeBorders
4435 //=======================================================================
4437 SMESH::SMESH_MeshEditor::Sew_Error
4438 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
4439 CORBA::Long SecondNodeID1,
4440 CORBA::Long LastNodeID1,
4441 CORBA::Long FirstNodeID2,
4442 CORBA::Long SecondNodeID2,
4443 CORBA::Long LastNodeID2,
4444 CORBA::Boolean CreatePolygons,
4445 CORBA::Boolean CreatePolyedrs)
4449 SMESHDS_Mesh* aMesh = GetMeshDS();
4451 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4452 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4453 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4454 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4455 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4456 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
4458 if (!aBorderFirstNode ||
4459 !aBorderSecondNode||
4461 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4462 if (!aSide2FirstNode ||
4463 !aSide2SecondNode ||
4465 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4467 TPythonDump() << "error = " << this << ".SewFreeBorders( "
4468 << FirstNodeID1 << ", "
4469 << SecondNodeID1 << ", "
4470 << LastNodeID1 << ", "
4471 << FirstNodeID2 << ", "
4472 << SecondNodeID2 << ", "
4473 << LastNodeID2 << ", "
4474 << CreatePolygons<< ", "
4475 << CreatePolyedrs<< " )";
4477 ::SMESH_MeshEditor anEditor( myMesh );
4478 SMESH::SMESH_MeshEditor::Sew_Error error =
4479 convError( anEditor.SewFreeBorder (aBorderFirstNode,
4489 storeResult(anEditor);
4491 myMesh->GetMeshDS()->Modified();
4492 myMesh->SetIsModified( true );
4498 //=======================================================================
4499 //function : SewConformFreeBorders
4501 //=======================================================================
4503 SMESH::SMESH_MeshEditor::Sew_Error
4504 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
4505 CORBA::Long SecondNodeID1,
4506 CORBA::Long LastNodeID1,
4507 CORBA::Long FirstNodeID2,
4508 CORBA::Long SecondNodeID2)
4512 SMESHDS_Mesh* aMesh = GetMeshDS();
4514 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4515 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4516 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4517 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4518 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4519 const SMDS_MeshNode* aSide2ThirdNode = 0;
4521 if (!aBorderFirstNode ||
4522 !aBorderSecondNode||
4524 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4525 if (!aSide2FirstNode ||
4527 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4529 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
4530 << FirstNodeID1 << ", "
4531 << SecondNodeID1 << ", "
4532 << LastNodeID1 << ", "
4533 << FirstNodeID2 << ", "
4534 << SecondNodeID2 << " )";
4536 ::SMESH_MeshEditor anEditor( myMesh );
4537 SMESH::SMESH_MeshEditor::Sew_Error error =
4538 convError( anEditor.SewFreeBorder (aBorderFirstNode,
4547 storeResult(anEditor);
4549 myMesh->GetMeshDS()->Modified();
4550 myMesh->SetIsModified( true );
4556 //=======================================================================
4557 //function : SewBorderToSide
4559 //=======================================================================
4561 SMESH::SMESH_MeshEditor::Sew_Error
4562 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
4563 CORBA::Long SecondNodeIDOnFreeBorder,
4564 CORBA::Long LastNodeIDOnFreeBorder,
4565 CORBA::Long FirstNodeIDOnSide,
4566 CORBA::Long LastNodeIDOnSide,
4567 CORBA::Boolean CreatePolygons,
4568 CORBA::Boolean CreatePolyedrs)
4572 SMESHDS_Mesh* aMesh = GetMeshDS();
4574 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
4575 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
4576 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
4577 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
4578 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
4579 const SMDS_MeshNode* aSide2ThirdNode = 0;
4581 if (!aBorderFirstNode ||
4582 !aBorderSecondNode||
4584 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4585 if (!aSide2FirstNode ||
4587 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
4589 TPythonDump() << "error = " << this << ".SewBorderToSide( "
4590 << FirstNodeIDOnFreeBorder << ", "
4591 << SecondNodeIDOnFreeBorder << ", "
4592 << LastNodeIDOnFreeBorder << ", "
4593 << FirstNodeIDOnSide << ", "
4594 << LastNodeIDOnSide << ", "
4595 << CreatePolygons << ", "
4596 << CreatePolyedrs << ") ";
4598 ::SMESH_MeshEditor anEditor( myMesh );
4599 SMESH::SMESH_MeshEditor::Sew_Error error =
4600 convError( anEditor.SewFreeBorder (aBorderFirstNode,
4610 storeResult(anEditor);
4612 myMesh->GetMeshDS()->Modified();
4613 myMesh->SetIsModified( true );
4619 //=======================================================================
4620 //function : SewSideElements
4622 //=======================================================================
4624 SMESH::SMESH_MeshEditor::Sew_Error
4625 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
4626 const SMESH::long_array& IDsOfSide2Elements,
4627 CORBA::Long NodeID1OfSide1ToMerge,
4628 CORBA::Long NodeID1OfSide2ToMerge,
4629 CORBA::Long NodeID2OfSide1ToMerge,
4630 CORBA::Long NodeID2OfSide2ToMerge)
4634 SMESHDS_Mesh* aMesh = GetMeshDS();
4636 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
4637 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
4638 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
4639 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
4641 if (!aFirstNode1ToMerge ||
4642 !aFirstNode2ToMerge )
4643 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
4644 if (!aSecondNode1ToMerge||
4645 !aSecondNode2ToMerge)
4646 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
4648 TIDSortedElemSet aSide1Elems, aSide2Elems;
4649 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
4650 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
4652 TPythonDump() << "error = " << this << ".SewSideElements( "
4653 << IDsOfSide1Elements << ", "
4654 << IDsOfSide2Elements << ", "
4655 << NodeID1OfSide1ToMerge << ", "
4656 << NodeID1OfSide2ToMerge << ", "
4657 << NodeID2OfSide1ToMerge << ", "
4658 << NodeID2OfSide2ToMerge << ")";
4660 ::SMESH_MeshEditor anEditor( myMesh );
4661 SMESH::SMESH_MeshEditor::Sew_Error error =
4662 convError( anEditor.SewSideElements (aSide1Elems, aSide2Elems,
4665 aSecondNode1ToMerge,
4666 aSecondNode2ToMerge));
4668 storeResult(anEditor);
4670 myMesh->GetMeshDS()->Modified();
4671 myMesh->SetIsModified( true );
4676 //================================================================================
4678 * \brief Set new nodes for given element
4679 * \param ide - element id
4680 * \param newIDs - new node ids
4681 * \retval CORBA::Boolean - true if result is OK
4683 //================================================================================
4685 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
4686 const SMESH::long_array& newIDs)
4690 const SMDS_MeshElement* elem = GetMeshDS()->FindElement(ide);
4691 if(!elem) return false;
4693 int nbn = newIDs.length();
4695 vector<const SMDS_MeshNode*> aNodes(nbn);
4698 const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(newIDs[i]);
4701 aNodes[nbn1] = aNode;
4704 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
4705 << ide << ", " << newIDs << " )";
4707 MESSAGE("ChangeElementNodes");
4708 bool res = GetMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
4710 myMesh->GetMeshDS()->Modified();
4712 myMesh->SetIsModified( true );
4717 //================================================================================
4719 * \brief Update myLastCreated* or myPreviewData
4720 * \param anEditor - it contains last modification results
4722 //================================================================================
4724 void SMESH_MeshEditor_i::storeResult(::SMESH_MeshEditor& anEditor)
4726 if ( myPreviewMode ) { // --- MeshPreviewStruct filling ---
4728 list<int> aNodesConnectivity;
4729 typedef map<int, int> TNodesMap;
4732 TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( anEditor.GetMesh() );
4733 SMDSAbs_ElementType previewType = aPreviewMesh->myPreviewType;
4735 SMESHDS_Mesh* aMeshDS = anEditor.GetMeshDS();
4736 int nbEdges = aMeshDS->NbEdges();
4737 int nbFaces = aMeshDS->NbFaces();
4738 int nbVolum = aMeshDS->NbVolumes();
4739 switch ( previewType ) {
4740 case SMDSAbs_Edge : nbFaces = nbVolum = 0; break;
4741 case SMDSAbs_Face : nbEdges = nbVolum = 0; break;
4742 case SMDSAbs_Volume: nbEdges = nbFaces = 0; break;
4745 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
4746 myPreviewData->elementTypes.length(nbEdges + nbFaces + nbVolum);
4748 SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator();
4750 while ( itMeshElems->more() ) {
4751 const SMDS_MeshElement* aMeshElem = itMeshElems->next();
4752 if ( previewType != SMDSAbs_All && aMeshElem->GetType() != previewType )
4755 SMDS_ElemIteratorPtr itElemNodes = aMeshElem->nodesIterator();
4756 while ( itElemNodes->more() ) {
4757 const SMDS_MeshNode* aMeshNode =
4758 static_cast<const SMDS_MeshNode*>( itElemNodes->next() );
4759 int aNodeID = aMeshNode->GetID();
4760 TNodesMap::iterator anIter = nodesMap.find(aNodeID);
4761 if ( anIter == nodesMap.end() ) {
4762 // filling the nodes coordinates
4763 myPreviewData->nodesXYZ[j].x = aMeshNode->X();
4764 myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
4765 myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
4766 anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
4769 aNodesConnectivity.push_back(anIter->second);
4772 // filling the elements types
4773 SMDSAbs_ElementType aType;
4775 /*if (aMeshElem->GetType() == SMDSAbs_Volume) {
4776 aType = SMDSAbs_Node;
4780 aType = aMeshElem->GetType();
4781 isPoly = aMeshElem->IsPoly();
4784 myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
4785 myPreviewData->elementTypes[i].isPoly = isPoly;
4786 myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
4790 myPreviewData->nodesXYZ.length( j );
4792 // filling the elements connectivities
4793 list<int>::iterator aConnIter = aNodesConnectivity.begin();
4794 myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
4795 for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
4796 myPreviewData->elementConnectivities[i] = *aConnIter;
4802 // append new nodes into myLastCreatedNodes
4803 const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedNodes();
4804 int j = myLastCreatedNodes->length();
4805 int newLen = j + aSeq.Length();
4806 myLastCreatedNodes->length( newLen );
4807 for(int i=0; j<newLen; i++,j++)
4808 myLastCreatedNodes[j] = aSeq.Value(i+1)->GetID();
4811 // append new elements into myLastCreatedElems
4812 const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedElems();
4813 int j = myLastCreatedElems->length();
4814 int newLen = j + aSeq.Length();
4815 myLastCreatedElems->length( newLen );
4816 for(int i=0; j<newLen; i++,j++)
4817 myLastCreatedElems[j] = aSeq.Value(i+1)->GetID();
4821 //================================================================================
4823 * Return data of mesh edition preview
4825 //================================================================================
4827 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
4829 return myPreviewData._retn();
4832 //================================================================================
4834 * \brief Returns list of it's IDs of created nodes
4835 * \retval SMESH::long_array* - list of node ID
4837 //================================================================================
4839 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
4841 return myLastCreatedNodes._retn();
4844 //================================================================================
4846 * \brief Returns list of it's IDs of created elements
4847 * \retval SMESH::long_array* - list of elements' ID
4849 //================================================================================
4851 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
4853 return myLastCreatedElems._retn();
4856 //=======================================================================
4857 //function : ConvertToQuadratic
4859 //=======================================================================
4861 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
4863 ::SMESH_MeshEditor anEditor( myMesh );
4864 anEditor.ConvertToQuadratic(theForce3d);
4865 TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )";
4866 myMesh->GetMeshDS()->Modified();
4867 myMesh->SetIsModified( true );
4870 //=======================================================================
4871 //function : ConvertFromQuadratic
4873 //=======================================================================
4875 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
4877 ::SMESH_MeshEditor anEditor( myMesh );
4878 CORBA::Boolean isDone = anEditor.ConvertFromQuadratic();
4879 TPythonDump() << this << ".ConvertFromQuadratic()";
4880 myMesh->GetMeshDS()->Modified();
4882 myMesh->SetIsModified( true );
4885 //================================================================================
4887 * \brief Makes a part of the mesh quadratic
4889 //================================================================================
4891 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
4892 SMESH::SMESH_IDSource_ptr theObject)
4893 throw (SALOME::SALOME_Exception)
4895 Unexpect aCatch(SALOME_SalomeException);
4897 TIDSortedElemSet elems;
4898 if ( idSourceToSet( theObject, GetMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
4900 if ( elems.empty() )
4902 ConvertToQuadratic( theForce3d );
4904 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
4906 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
4910 ::SMESH_MeshEditor anEditor( myMesh );
4911 anEditor.ConvertToQuadratic(theForce3d, elems);
4914 myMesh->GetMeshDS()->Modified();
4915 myMesh->SetIsModified( true );
4917 pyDump << this << ".ConvertToQuadraticObject( "<<theForce3d<<", "<<theObject<<" )";
4920 //================================================================================
4922 * \brief Makes a part of the mesh linear
4924 //================================================================================
4926 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
4927 throw (SALOME::SALOME_Exception)
4929 Unexpect aCatch(SALOME_SalomeException);
4931 TIDSortedElemSet elems;
4932 if ( idSourceToSet( theObject, GetMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
4934 if ( elems.empty() )
4936 ConvertFromQuadratic();
4938 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
4940 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
4944 ::SMESH_MeshEditor anEditor( myMesh );
4945 anEditor.ConvertFromQuadratic(elems);
4948 myMesh->GetMeshDS()->Modified();
4949 myMesh->SetIsModified( true );
4951 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
4954 //=======================================================================
4955 //function : makeMesh
4956 //purpose : create a named imported mesh
4957 //=======================================================================
4959 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
4961 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
4962 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
4963 SALOMEDS::Study_var study = gen->GetCurrentStudy();
4964 SALOMEDS::SObject_var meshSO = gen->ObjectToSObject( study, mesh );
4965 gen->SetName( meshSO, theMeshName, "Mesh" );
4966 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
4968 return mesh._retn();
4971 //=======================================================================
4972 //function : DumpGroupsList
4974 //=======================================================================
4975 void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump & theDumpPython,
4976 const SMESH::ListOfGroups * theGroupList)
4978 bool isDumpGroupList = theGroupList && theGroupList->length() > 0;
4979 if(isDumpGroupList) {
4980 theDumpPython << theGroupList << " = ";
4984 //================================================================================
4986 \brief Generates the unique group name.
4987 \param thePrefix name prefix
4990 //================================================================================
4991 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
4993 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
4994 set<string> groupNames;
4996 // Get existing group names
4997 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
4998 SMESH::SMESH_GroupBase_var aGroup = groups[i];
4999 if (CORBA::is_nil(aGroup))
5002 groupNames.insert(aGroup->GetName());
5006 string name = thePrefix;
5009 while (!groupNames.insert(name).second) {
5014 TCollection_AsciiString nbStr(index+1);
5015 name.resize( name.rfind('_')+1 );
5016 name += nbStr.ToCString();
5024 //================================================================================
5026 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5027 \param theNodes - identifiers of nodes to be doubled
5028 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
5029 nodes. If list of element identifiers is empty then nodes are doubled but
5030 they not assigned to elements
5031 \return TRUE if operation has been completed successfully, FALSE otherwise
5032 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
5034 //================================================================================
5036 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
5037 const SMESH::long_array& theModifiedElems )
5041 ::SMESH_MeshEditor aMeshEditor( myMesh );
5042 list< int > aListOfNodes;
5044 for ( i = 0, n = theNodes.length(); i < n; i++ )
5045 aListOfNodes.push_back( theNodes[ i ] );
5047 list< int > aListOfElems;
5048 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5049 aListOfElems.push_back( theModifiedElems[ i ] );
5051 bool aResult = aMeshEditor.DoubleNodes( aListOfNodes, aListOfElems );
5053 myMesh->GetMeshDS()->Modified();
5054 storeResult( aMeshEditor) ;
5056 myMesh->SetIsModified( true );
5058 // Update Python script
5059 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
5064 //================================================================================
5066 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5067 This method provided for convenience works as DoubleNodes() described above.
5068 \param theNodeId - identifier of node to be doubled.
5069 \param theModifiedElems - identifiers of elements to be updated.
5070 \return TRUE if operation has been completed successfully, FALSE otherwise
5071 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
5073 //================================================================================
5075 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
5076 const SMESH::long_array& theModifiedElems )
5078 SMESH::long_array_var aNodes = new SMESH::long_array;
5079 aNodes->length( 1 );
5080 aNodes[ 0 ] = theNodeId;
5082 TPythonDump pyDump; // suppress dump by the next line
5084 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
5086 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
5091 //================================================================================
5093 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5094 This method provided for convenience works as DoubleNodes() described above.
5095 \param theNodes - group of nodes to be doubled.
5096 \param theModifiedElems - group of elements to be updated.
5097 \return TRUE if operation has been completed successfully, FALSE otherwise
5098 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
5100 //================================================================================
5102 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
5103 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5105 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5108 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5109 SMESH::long_array_var aModifiedElems;
5110 if ( !CORBA::is_nil( theModifiedElems ) )
5111 aModifiedElems = theModifiedElems->GetListOfID();
5114 aModifiedElems = new SMESH::long_array;
5115 aModifiedElems->length( 0 );
5118 TPythonDump pyDump; // suppress dump by the next line
5120 bool done = DoubleNodes( aNodes, aModifiedElems );
5122 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
5128 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5129 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
5130 * \param theNodes - group of nodes to be doubled.
5131 * \param theModifiedElems - group of elements to be updated.
5132 * \return a new group with newly created nodes
5133 * \sa DoubleNodeGroup()
5135 SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
5136 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5138 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5141 SMESH::SMESH_Group_var aNewGroup;
5144 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5145 SMESH::long_array_var aModifiedElems;
5146 if ( !CORBA::is_nil( theModifiedElems ) )
5147 aModifiedElems = theModifiedElems->GetListOfID();
5149 aModifiedElems = new SMESH::long_array;
5150 aModifiedElems->length( 0 );
5153 TPythonDump pyDump; // suppress dump by the next line
5155 bool aResult = DoubleNodes( aNodes, aModifiedElems );
5159 // Create group with newly created nodes
5160 SMESH::long_array_var anIds = GetLastCreatedNodes();
5161 if (anIds->length() > 0) {
5162 string anUnindexedName (theNodes->GetName());
5163 string aNewName = generateGroupName(anUnindexedName + "_double");
5164 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5165 aNewGroup->Add(anIds);
5169 pyDump << "createdNodes = " << this << ".DoubleNodeGroupNew( " << theNodes << ", "
5170 << theModifiedElems << " )";
5172 return aNewGroup._retn();
5175 //================================================================================
5177 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5178 This method provided for convenience works as DoubleNodes() described above.
5179 \param theNodes - list of groups of nodes to be doubled
5180 \param theModifiedElems - list of groups of elements to be updated.
5181 \return TRUE if operation has been completed successfully, FALSE otherwise
5182 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
5184 //================================================================================
5186 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
5187 const SMESH::ListOfGroups& theModifiedElems )
5191 ::SMESH_MeshEditor aMeshEditor( myMesh );
5193 std::list< int > aNodes;
5195 for ( i = 0, n = theNodes.length(); i < n; i++ )
5197 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
5198 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
5200 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5201 for ( j = 0, m = aCurr->length(); j < m; j++ )
5202 aNodes.push_back( aCurr[ j ] );
5206 std::list< int > anElems;
5207 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5209 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
5210 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
5212 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5213 for ( j = 0, m = aCurr->length(); j < m; j++ )
5214 anElems.push_back( aCurr[ j ] );
5218 bool aResult = aMeshEditor.DoubleNodes( aNodes, anElems );
5220 storeResult( aMeshEditor) ;
5222 myMesh->GetMeshDS()->Modified();
5224 myMesh->SetIsModified( true );
5227 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
5232 //================================================================================
5234 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5235 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
5236 * \param theNodes - group of nodes to be doubled.
5237 * \param theModifiedElems - group of elements to be updated.
5238 * \return a new group with newly created nodes
5239 * \sa DoubleNodeGroups()
5241 //================================================================================
5243 SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
5244 const SMESH::ListOfGroups& theModifiedElems )
5246 SMESH::SMESH_Group_var aNewGroup;
5248 TPythonDump pyDump; // suppress dump by the next line
5250 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
5254 // Create group with newly created nodes
5255 SMESH::long_array_var anIds = GetLastCreatedNodes();
5256 if (anIds->length() > 0) {
5257 string anUnindexedName (theNodes[0]->GetName());
5258 string aNewName = generateGroupName(anUnindexedName + "_double");
5259 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5260 aNewGroup->Add(anIds);
5264 pyDump << "createdNodes = " << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
5265 << theModifiedElems << " )";
5267 return aNewGroup._retn();
5271 //================================================================================
5273 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5274 \param theElems - the list of elements (edges or faces) to be replicated
5275 The nodes for duplication could be found from these elements
5276 \param theNodesNot - list of nodes to NOT replicate
5277 \param theAffectedElems - the list of elements (cells and edges) to which the
5278 replicated nodes should be associated to.
5279 \return TRUE if operation has been completed successfully, FALSE otherwise
5280 \sa DoubleNodeGroup(), DoubleNodeGroups()
5282 //================================================================================
5284 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
5285 const SMESH::long_array& theNodesNot,
5286 const SMESH::long_array& theAffectedElems )
5291 ::SMESH_MeshEditor aMeshEditor( myMesh );
5293 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5294 TIDSortedElemSet anElems, aNodes, anAffected;
5295 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5296 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5297 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
5299 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5301 storeResult( aMeshEditor) ;
5303 myMesh->GetMeshDS()->Modified();
5305 myMesh->SetIsModified( true );
5307 // Update Python script
5308 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
5309 << theNodesNot << ", " << theAffectedElems << " )";
5313 //================================================================================
5315 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5316 \param theElems - the list of elements (edges or faces) to be replicated
5317 The nodes for duplication could be found from these elements
5318 \param theNodesNot - list of nodes to NOT replicate
5319 \param theShape - shape to detect affected elements (element which geometric center
5320 located on or inside shape).
5321 The replicated nodes should be associated to affected elements.
5322 \return TRUE if operation has been completed successfully, FALSE otherwise
5323 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
5325 //================================================================================
5327 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
5328 const SMESH::long_array& theNodesNot,
5329 GEOM::GEOM_Object_ptr theShape )
5334 ::SMESH_MeshEditor aMeshEditor( myMesh );
5336 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5337 TIDSortedElemSet anElems, aNodes;
5338 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5339 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5341 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5342 bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5344 storeResult( aMeshEditor) ;
5346 myMesh->GetMeshDS()->Modified();
5348 myMesh->SetIsModified( true );
5350 // Update Python script
5351 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
5352 << theNodesNot << ", " << theShape << " )";
5356 //================================================================================
5358 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5359 \param theElems - group of of elements (edges or faces) to be replicated
5360 \param theNodesNot - group of nodes not to replicated
5361 \param theAffectedElems - group of elements to which the replicated nodes
5362 should be associated to.
5363 \return TRUE if operation has been completed successfully, FALSE otherwise
5364 \sa DoubleNodes(), DoubleNodeGroups()
5366 //================================================================================
5368 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
5369 SMESH::SMESH_GroupBase_ptr theNodesNot,
5370 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5372 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5377 ::SMESH_MeshEditor aMeshEditor( myMesh );
5379 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5380 TIDSortedElemSet anElems, aNodes, anAffected;
5381 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5382 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5383 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5385 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5387 storeResult( aMeshEditor) ;
5389 myMesh->GetMeshDS()->Modified();
5391 myMesh->SetIsModified( true );
5393 // Update Python script
5394 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
5395 << theNodesNot << ", " << theAffectedElems << " )";
5400 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5401 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
5402 * \param theElems - group of of elements (edges or faces) to be replicated
5403 * \param theNodesNot - group of nodes not to replicated
5404 * \param theAffectedElems - group of elements to which the replicated nodes
5405 * should be associated to.
5406 * \return a new group with newly created elements
5407 * \sa DoubleNodeElemGroup()
5409 SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
5410 SMESH::SMESH_GroupBase_ptr theNodesNot,
5411 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5413 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5416 SMESH::SMESH_Group_var aNewGroup;
5420 ::SMESH_MeshEditor aMeshEditor( myMesh );
5422 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5423 TIDSortedElemSet anElems, aNodes, anAffected;
5424 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5425 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5426 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5429 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5431 storeResult( aMeshEditor) ;
5434 myMesh->SetIsModified( true );
5436 // Create group with newly created elements
5437 SMESH::long_array_var anIds = GetLastCreatedElems();
5438 if (anIds->length() > 0) {
5439 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5440 string anUnindexedName (theElems->GetName());
5441 string aNewName = generateGroupName(anUnindexedName + "_double");
5442 aNewGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5443 aNewGroup->Add(anIds);
5447 // Update Python script
5448 TPythonDump() << "createdElems = " << this << ".DoubleNodeElemGroupNew( " << theElems << ", "
5449 << theNodesNot << ", " << theAffectedElems << " )";
5450 return aNewGroup._retn();
5453 //================================================================================
5455 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5456 \param theElems - group of of elements (edges or faces) to be replicated
5457 \param theNodesNot - group of nodes not to replicated
5458 \param theShape - shape to detect affected elements (element which geometric center
5459 located on or inside shape).
5460 The replicated nodes should be associated to affected elements.
5461 \return TRUE if operation has been completed successfully, FALSE otherwise
5462 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
5464 //================================================================================
5466 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
5467 SMESH::SMESH_GroupBase_ptr theNodesNot,
5468 GEOM::GEOM_Object_ptr theShape )
5471 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5476 ::SMESH_MeshEditor aMeshEditor( myMesh );
5478 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5479 TIDSortedElemSet anElems, aNodes, anAffected;
5480 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5481 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5483 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5484 bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5486 storeResult( aMeshEditor) ;
5488 myMesh->GetMeshDS()->Modified();
5490 myMesh->SetIsModified( true );
5492 // Update Python script
5493 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
5494 << theNodesNot << ", " << theShape << " )";
5498 //================================================================================
5500 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5501 This method provided for convenience works as DoubleNodes() described above.
5502 \param theElems - list of groups of elements (edges or faces) to be replicated
5503 \param theNodesNot - list of groups of nodes not to replicated
5504 \param theAffectedElems - group of elements to which the replicated nodes
5505 should be associated to.
5506 \return TRUE if operation has been completed successfully, FALSE otherwise
5507 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
5509 //================================================================================
5511 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
5512 SMESHDS_Mesh* theMeshDS,
5513 TIDSortedElemSet& theElemSet,
5514 const bool theIsNodeGrp)
5516 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
5518 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
5519 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
5520 : aGrp->GetType() != SMESH::NODE ) )
5522 SMESH::long_array_var anIDs = aGrp->GetIDs();
5523 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
5528 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
5529 const SMESH::ListOfGroups& theNodesNot,
5530 const SMESH::ListOfGroups& theAffectedElems)
5534 ::SMESH_MeshEditor aMeshEditor( myMesh );
5536 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5537 TIDSortedElemSet anElems, aNodes, anAffected;
5538 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5539 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5540 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5542 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5544 storeResult( aMeshEditor) ;
5546 myMesh->GetMeshDS()->Modified();
5548 myMesh->SetIsModified( true );
5550 // Update Python script
5551 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
5552 << &theNodesNot << ", " << &theAffectedElems << " )";
5556 //================================================================================
5558 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5559 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
5560 \param theElems - list of groups of elements (edges or faces) to be replicated
5561 \param theNodesNot - list of groups of nodes not to replicated
5562 \param theAffectedElems - group of elements to which the replicated nodes
5563 should be associated to.
5564 * \return a new group with newly created elements
5565 * \sa DoubleNodeElemGroups()
5567 //================================================================================
5569 SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
5570 const SMESH::ListOfGroups& theNodesNot,
5571 const SMESH::ListOfGroups& theAffectedElems)
5573 SMESH::SMESH_Group_var aNewGroup;
5577 ::SMESH_MeshEditor aMeshEditor( myMesh );
5579 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5580 TIDSortedElemSet anElems, aNodes, anAffected;
5581 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5582 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5583 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5585 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5587 storeResult( aMeshEditor) ;
5589 myMesh->GetMeshDS()->Modified();
5591 myMesh->SetIsModified( true );
5593 // Create group with newly created elements
5594 SMESH::long_array_var anIds = GetLastCreatedElems();
5595 if (anIds->length() > 0) {
5596 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5597 string anUnindexedName (theElems[0]->GetName());
5598 string aNewName = generateGroupName(anUnindexedName + "_double");
5599 aNewGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5600 aNewGroup->Add(anIds);
5604 // Update Python script
5605 TPythonDump() << "createdElems = " << this << ".DoubleNodeElemGroupsNew( " << &theElems << ", "
5606 << &theNodesNot << ", " << &theAffectedElems << " )";
5607 return aNewGroup._retn();
5610 //================================================================================
5612 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5613 This method provided for convenience works as DoubleNodes() described above.
5614 \param theElems - list of groups of elements (edges or faces) to be replicated
5615 \param theNodesNot - list of groups of nodes not to replicated
5616 \param theShape - shape to detect affected elements (element which geometric center
5617 located on or inside shape).
5618 The replicated nodes should be associated to affected elements.
5619 \return TRUE if operation has been completed successfully, FALSE otherwise
5620 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
5622 //================================================================================
5625 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
5626 const SMESH::ListOfGroups& theNodesNot,
5627 GEOM::GEOM_Object_ptr theShape )
5631 ::SMESH_MeshEditor aMeshEditor( myMesh );
5633 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5634 TIDSortedElemSet anElems, aNodes;
5635 listOfGroupToSet(theElems, aMeshDS, anElems,false );
5636 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5638 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5639 bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5641 storeResult( aMeshEditor) ;
5643 myMesh->GetMeshDS()->Modified();
5645 myMesh->SetIsModified( true );
5647 // Update Python script
5648 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
5649 << &theNodesNot << ", " << theShape << " )";
5653 //================================================================================
5655 \brief Generated skin mesh (containing 2D cells) from 3D mesh
5656 The created 2D mesh elements based on nodes of free faces of boundary volumes
5657 \return TRUE if operation has been completed successfully, FALSE otherwise
5659 //================================================================================
5661 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
5665 ::SMESH_MeshEditor aMeshEditor( myMesh );
5666 bool aResult = aMeshEditor.Make2DMeshFrom3D();
5667 storeResult( aMeshEditor) ;
5668 myMesh->GetMeshDS()->Modified();
5669 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
5673 //================================================================================
5675 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
5676 * The list of groups must describe a partition of the mesh volumes.
5677 * The nodes of the internal faces at the boundaries of the groups are doubled.
5678 * In option, the internal faces are replaced by flat elements.
5679 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
5680 * The flat elements are stored in groups of volumes.
5681 * @param theDomains - list of groups of volumes
5682 * @param createJointElems - if TRUE, create the elements
5683 * @return TRUE if operation has been completed successfully, FALSE otherwise
5685 //================================================================================
5687 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
5688 CORBA::Boolean createJointElems )
5689 throw (SALOME::SALOME_Exception)
5693 ::SMESH_MeshEditor aMeshEditor( myMesh );
5695 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5697 vector<TIDSortedElemSet> domains;
5700 for ( int i = 0, n = theDomains.length(); i < n; i++ )
5702 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
5703 if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
5705 if ( aGrp->GetType() != SMESH::VOLUME )
5706 THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
5707 TIDSortedElemSet domain;
5709 domains.push_back(domain);
5710 SMESH::long_array_var anIDs = aGrp->GetIDs();
5711 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
5715 bool aResult = aMeshEditor.DoubleNodesOnGroupBoundaries( domains, createJointElems );
5716 // TODO publish the groups of flat elements in study
5718 storeResult( aMeshEditor) ;
5719 myMesh->GetMeshDS()->Modified();
5721 // Update Python script
5722 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
5723 << ", " << createJointElems << " )";
5727 //================================================================================
5729 * \brief Double nodes on some external faces and create flat elements.
5730 * Flat elements are mainly used by some types of mechanic calculations.
5732 * Each group of the list must be constituted of faces.
5733 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
5734 * @param theGroupsOfFaces - list of groups of faces
5735 * @return TRUE if operation has been completed successfully, FALSE otherwise
5737 //================================================================================
5739 CORBA::Boolean SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
5743 ::SMESH_MeshEditor aMeshEditor( myMesh );
5745 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5747 vector<TIDSortedElemSet> faceGroups;
5750 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
5752 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
5753 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
5755 TIDSortedElemSet faceGroup;
5757 faceGroups.push_back(faceGroup);
5758 SMESH::long_array_var anIDs = aGrp->GetIDs();
5759 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
5763 bool aResult = aMeshEditor.CreateFlatElementsOnFacesGroups( faceGroups );
5764 // TODO publish the groups of flat elements in study
5766 storeResult( aMeshEditor) ;
5767 myMesh->GetMeshDS()->Modified();
5769 // Update Python script
5770 TPythonDump() << "isDone = " << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
5774 // issue 20749 ===================================================================
5776 * \brief Creates missing boundary elements
5777 * \param elements - elements whose boundary is to be checked
5778 * \param dimension - defines type of boundary elements to create
5779 * \param groupName - a name of group to store created boundary elements in,
5780 * "" means not to create the group
5781 * \param meshName - a name of new mesh to store created boundary elements in,
5782 * "" means not to create the new mesh
5783 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
5784 * \param toCopyExistingBondary - if true, not only new but also pre-existing
5785 * boundary elements will be copied into the new mesh
5786 * \param group - returns the create group, if any
5787 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
5789 // ================================================================================
5791 SMESH::SMESH_Mesh_ptr
5792 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
5793 SMESH::Bnd_Dimension dim,
5794 const char* groupName,
5795 const char* meshName,
5796 CORBA::Boolean toCopyElements,
5797 CORBA::Boolean toCopyExistingBondary,
5798 SMESH::SMESH_Group_out group)
5802 if ( dim > SMESH::BND_1DFROM2D )
5803 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
5805 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5807 SMESH::SMESH_Mesh_var mesh_var;
5808 SMESH::SMESH_Group_var group_var;
5812 TIDSortedElemSet elements;
5813 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
5814 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
5818 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
5819 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
5821 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
5823 // group of new boundary elements
5824 SMESH_Group* smesh_group = 0;
5825 if ( strlen(groupName) )
5827 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
5828 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
5829 smesh_group = group_i->GetSmeshGroup();
5833 ::SMESH_MeshEditor aMeshEditor( myMesh );
5834 aMeshEditor.MakeBoundaryMesh( elements,
5835 ::SMESH_MeshEditor::Bnd_Dimension(dim),
5839 toCopyExistingBondary);
5840 storeResult( aMeshEditor );
5843 smesh_mesh->GetMeshDS()->Modified();
5846 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
5848 // result of MakeBoundaryMesh() is a tuple (mesh, group)
5849 if ( mesh_var->_is_nil() )
5850 pyDump << myMesh_i->_this() << ", ";
5852 pyDump << mesh_var << ", ";
5853 if ( group_var->_is_nil() )
5854 pyDump << "_NoneGroup = "; // assignment to None is forbiden
5856 pyDump << group_var << " = ";
5857 pyDump << this << ".MakeBoundaryMesh( "
5859 << "SMESH." << dimName[int(dim)] << ", "
5860 << "'" << groupName << "', "
5861 << "'" << meshName<< "', "
5862 << toCopyElements << ", "
5863 << toCopyExistingBondary << ")";
5865 group = group_var._retn();
5866 return mesh_var._retn();
5869 //================================================================================
5871 * \brief Creates missing boundary elements
5872 * \param dimension - defines type of boundary elements to create
5873 * \param groupName - a name of group to store all boundary elements in,
5874 * "" means not to create the group
5875 * \param meshName - a name of a new mesh, which is a copy of the initial
5876 * mesh + created boundary elements; "" means not to create the new mesh
5877 * \param toCopyAll - if true, the whole initial mesh will be copied into
5878 * the new mesh else only boundary elements will be copied into the new mesh
5879 * \param groups - optional groups of elements to make boundary around
5880 * \param mesh - returns the mesh where elements were added to
5881 * \param group - returns the created group, if any
5882 * \retval long - number of added boundary elements
5884 //================================================================================
5886 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
5887 const char* groupName,
5888 const char* meshName,
5889 CORBA::Boolean toCopyAll,
5890 const SMESH::ListOfIDSources& groups,
5891 SMESH::SMESH_Mesh_out mesh,
5892 SMESH::SMESH_Group_out group)
5893 throw (SALOME::SALOME_Exception)
5895 Unexpect aCatch(SALOME_SalomeException);
5899 if ( dim > SMESH::BND_1DFROM2D )
5900 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
5902 // separate groups belonging to this and other mesh
5903 SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
5904 SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
5905 groupsOfThisMesh->length( groups.length() );
5906 groupsOfOtherMesh->length( groups.length() );
5907 int nbGroups = 0, nbGroupsOfOtherMesh = 0;
5908 for ( int i = 0; i < groups.length(); ++i )
5910 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
5911 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
5912 groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
5914 groupsOfThisMesh[ nbGroups++ ] = groups[i];
5915 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
5916 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
5918 groupsOfThisMesh->length( nbGroups );
5919 groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
5924 if ( nbGroupsOfOtherMesh > 0 )
5926 // process groups belonging to another mesh
5927 SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
5928 SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
5929 nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
5930 groupsOfOtherMesh, mesh, group );
5933 SMESH::SMESH_Mesh_var mesh_var;
5934 SMESH::SMESH_Group_var group_var;
5937 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
5938 const bool toCopyMesh = ( strlen( meshName ) > 0 );
5942 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
5944 /*toCopyGroups=*/false,
5945 /*toKeepIDs=*/true);
5947 mesh_var = makeMesh(meshName);
5949 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
5950 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
5953 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
5954 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
5956 // group of boundary elements
5957 SMESH_Group* smesh_group = 0;
5958 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
5959 if ( strlen(groupName) )
5961 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
5962 group_var = mesh_i->CreateGroup( groupType, groupName );
5963 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
5964 smesh_group = group_i->GetSmeshGroup();
5967 TIDSortedElemSet elements;
5969 if ( groups.length() > 0 )
5971 for ( int i = 0; i < nbGroups; ++i )
5974 if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
5976 SMESH::Bnd_Dimension bdim =
5977 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
5978 ::SMESH_MeshEditor aMeshEditor( srcMesh );
5979 nbAdded += aMeshEditor.MakeBoundaryMesh( elements,
5980 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
5983 /*toCopyElements=*/false,
5984 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
5985 /*toAddExistingBondary=*/true,
5986 /*aroundElements=*/true);
5987 storeResult( aMeshEditor );
5993 ::SMESH_MeshEditor aMeshEditor( srcMesh );
5994 nbAdded += aMeshEditor.MakeBoundaryMesh( elements,
5995 ::SMESH_MeshEditor::Bnd_Dimension(dim),
5998 /*toCopyElements=*/false,
5999 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
6000 /*toAddExistingBondary=*/true);
6001 storeResult( aMeshEditor );
6003 tgtMesh->GetMeshDS()->Modified();
6005 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
6007 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
6008 pyDump << "nbAdded, ";
6009 if ( mesh_var->_is_nil() )
6010 pyDump << myMesh_i->_this() << ", ";
6012 pyDump << mesh_var << ", ";
6013 if ( group_var->_is_nil() )
6014 pyDump << "_NoneGroup = "; // assignment to None is forbiden
6016 pyDump << group_var << " = ";
6017 pyDump << this << ".MakeBoundaryElements( "
6018 << "SMESH." << dimName[int(dim)] << ", "
6019 << "'" << groupName << "', "
6020 << "'" << meshName<< "', "
6021 << toCopyAll << ", "
6024 mesh = mesh_var._retn();
6025 group = group_var._retn();