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; _myMeshDS = 0; }
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 int nbNodesBefore = myMesh->NbNodes();
535 anEditor.Remove( IdList, true );
536 myMesh->GetMeshDS()->Modified();
538 myMesh->SetIsModified( true );
539 int nbNodesAfter = myMesh->NbNodes();
541 return nbNodesBefore - nbNodesAfter;
544 //=============================================================================
548 //=============================================================================
550 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,
551 CORBA::Double y, CORBA::Double z)
555 const SMDS_MeshNode* N = GetMeshDS()->AddNode(x, y, z);
557 // Update Python script
558 TPythonDump() << "nodeID = " << this << ".AddNode( "
559 << x << ", " << y << ", " << z << " )";
561 myMesh->GetMeshDS()->Modified();
562 myMesh->SetIsModified( true ); // issue 0020693
566 //=============================================================================
570 //=============================================================================
571 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
575 const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(IDOfNode);
576 SMDS_MeshElement* elem = GetMeshDS()->Add0DElement(aNode);
578 // Update Python script
579 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
581 myMesh->GetMeshDS()->Modified();
582 myMesh->SetIsModified( true ); // issue 0020693
585 return elem->GetID();
590 //=============================================================================
594 //=============================================================================
596 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
600 int NbNodes = IDsOfNodes.length();
601 SMDS_MeshElement* elem = 0;
604 CORBA::Long index1 = IDsOfNodes[0];
605 CORBA::Long index2 = IDsOfNodes[1];
606 elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(index1), GetMeshDS()->FindNode(index2));
608 // Update Python script
609 TPythonDump() << "edge = " << this << ".AddEdge([ "
610 << index1 << ", " << index2 <<" ])";
613 CORBA::Long n1 = IDsOfNodes[0];
614 CORBA::Long n2 = IDsOfNodes[1];
615 CORBA::Long n12 = IDsOfNodes[2];
616 elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(n1),
617 GetMeshDS()->FindNode(n2),
618 GetMeshDS()->FindNode(n12));
619 // Update Python script
620 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
621 <<n1<<", "<<n2<<", "<<n12<<" ])";
624 myMesh->GetMeshDS()->Modified();
626 return myMesh->SetIsModified( true ), elem->GetID();
631 //=============================================================================
635 //=============================================================================
637 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
641 int NbNodes = IDsOfNodes.length();
647 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
648 for (int i = 0; i < NbNodes; i++)
649 nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
651 SMDS_MeshElement* elem = 0;
653 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]);
655 else if (NbNodes == 4) {
656 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]);
658 else if (NbNodes == 6) {
659 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
662 else if (NbNodes == 8) {
663 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
664 nodes[4], nodes[5], nodes[6], nodes[7]);
666 else if (NbNodes == 9) {
667 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
668 nodes[4], nodes[5], nodes[6], nodes[7], nodes[8] );
670 else if (NbNodes > 2) {
671 elem = GetMeshDS()->AddPolygonalFace(nodes);
674 // Update Python script
675 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
677 myMesh->GetMeshDS()->Modified();
679 return myMesh->SetIsModified( true ), elem->GetID();
684 //=============================================================================
688 //=============================================================================
689 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
693 int NbNodes = IDsOfNodes.length();
694 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
695 for (int i = 0; i < NbNodes; i++)
696 nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
698 const SMDS_MeshElement* elem = GetMeshDS()->AddPolygonalFace(nodes);
700 // Update Python script
701 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
703 myMesh->GetMeshDS()->Modified();
704 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
707 //=============================================================================
711 //=============================================================================
713 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
717 int NbNodes = IDsOfNodes.length();
718 vector< const SMDS_MeshNode*> n(NbNodes);
719 for(int i=0;i<NbNodes;i++)
720 n[i]=GetMeshDS()->FindNode(IDsOfNodes[i]);
722 SMDS_MeshElement* elem = 0;
725 case 4 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
726 case 5 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
727 case 6 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
728 case 8 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
729 case 10:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
730 n[6],n[7],n[8],n[9]);
732 case 12:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
733 n[6],n[7],n[8],n[9],n[10],n[11]);
735 case 13:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
736 n[7],n[8],n[9],n[10],n[11],n[12]);
738 case 15:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
739 n[9],n[10],n[11],n[12],n[13],n[14]);
741 case 20:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
742 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
743 n[15],n[16],n[17],n[18],n[19]);
745 case 27:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
746 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
747 n[15],n[16],n[17],n[18],n[19],
748 n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
752 // Update Python script
753 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
755 myMesh->GetMeshDS()->Modified();
757 return myMesh->SetIsModified( true ), elem->GetID();
762 //=============================================================================
764 * AddPolyhedralVolume
766 //=============================================================================
767 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
768 const SMESH::long_array & Quantities)
772 int NbNodes = IDsOfNodes.length();
773 std::vector<const SMDS_MeshNode*> n (NbNodes);
774 for (int i = 0; i < NbNodes; i++)
776 const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(IDsOfNodes[i]);
777 if (!aNode) return 0;
781 int NbFaces = Quantities.length();
782 std::vector<int> q (NbFaces);
783 for (int j = 0; j < NbFaces; j++)
784 q[j] = Quantities[j];
786 const SMDS_MeshElement* elem = GetMeshDS()->AddPolyhedralVolume(n, q);
788 // Update Python script
789 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
790 << IDsOfNodes << ", " << Quantities << " )";
791 myMesh->GetMeshDS()->Modified();
793 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
796 //=============================================================================
798 * AddPolyhedralVolumeByFaces
800 //=============================================================================
801 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
805 int NbFaces = IdsOfFaces.length();
806 std::vector<const SMDS_MeshNode*> poly_nodes;
807 std::vector<int> quantities (NbFaces);
809 for (int i = 0; i < NbFaces; i++) {
810 const SMDS_MeshElement* aFace = GetMeshDS()->FindElement(IdsOfFaces[i]);
811 quantities[i] = aFace->NbNodes();
813 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
815 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
819 const SMDS_MeshElement* elem = GetMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
821 // Update Python script
822 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
823 << IdsOfFaces << " )";
824 myMesh->GetMeshDS()->Modified();
826 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
829 //=============================================================================
831 * \brief Bind a node to a vertex
832 * \param NodeID - node ID
833 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
834 * \retval boolean - false if NodeID or VertexID is invalid
836 //=============================================================================
838 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
839 throw (SALOME::SALOME_Exception)
841 Unexpect aCatch(SALOME_SalomeException);
843 SMESHDS_Mesh * mesh = GetMeshDS();
844 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
846 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
848 if ( mesh->MaxShapeIndex() < VertexID )
849 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
851 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
852 if ( shape.ShapeType() != TopAbs_VERTEX )
853 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
855 mesh->SetNodeOnVertex( node, VertexID );
857 myMesh->SetIsModified( true );
860 //=============================================================================
862 * \brief Store node position on an edge
863 * \param NodeID - node ID
864 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
865 * \param paramOnEdge - parameter on edge where the node is located
866 * \retval boolean - false if any parameter is invalid
868 //=============================================================================
870 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
871 CORBA::Double paramOnEdge)
872 throw (SALOME::SALOME_Exception)
874 Unexpect aCatch(SALOME_SalomeException);
876 SMESHDS_Mesh * mesh = GetMeshDS();
877 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
879 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
881 if ( mesh->MaxShapeIndex() < EdgeID )
882 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
884 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
885 if ( shape.ShapeType() != TopAbs_EDGE )
886 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
889 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
890 if ( paramOnEdge < f || paramOnEdge > l )
891 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
893 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
895 myMesh->SetIsModified( true );
898 //=============================================================================
900 * \brief Store node position on a face
901 * \param NodeID - node ID
902 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
903 * \param u - U parameter on face where the node is located
904 * \param v - V parameter on face where the node is located
905 * \retval boolean - false if any parameter is invalid
907 //=============================================================================
909 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
910 CORBA::Double u, CORBA::Double v)
911 throw (SALOME::SALOME_Exception)
913 Unexpect aCatch(SALOME_SalomeException);
915 SMESHDS_Mesh * mesh = GetMeshDS();
916 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
918 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
920 if ( mesh->MaxShapeIndex() < FaceID )
921 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
923 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
924 if ( shape.ShapeType() != TopAbs_FACE )
925 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
927 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
928 bool isOut = ( u < surf.FirstUParameter() ||
929 u > surf.LastUParameter() ||
930 v < surf.FirstVParameter() ||
931 v > surf.LastVParameter() );
935 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
936 << " u( " << surf.FirstUParameter()
937 << "," << surf.LastUParameter()
938 << ") v( " << surf.FirstVParameter()
939 << "," << surf.LastVParameter() << ")" );
941 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
944 mesh->SetNodeOnFace( node, FaceID, u, v );
945 myMesh->SetIsModified( true );
948 //=============================================================================
950 * \brief Bind a node to a solid
951 * \param NodeID - node ID
952 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
953 * \retval boolean - false if NodeID or SolidID is invalid
955 //=============================================================================
957 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
958 throw (SALOME::SALOME_Exception)
960 Unexpect aCatch(SALOME_SalomeException);
962 SMESHDS_Mesh * mesh = GetMeshDS();
963 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
965 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
967 if ( mesh->MaxShapeIndex() < SolidID )
968 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
970 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
971 if ( shape.ShapeType() != TopAbs_SOLID &&
972 shape.ShapeType() != TopAbs_SHELL)
973 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
975 mesh->SetNodeInVolume( node, SolidID );
977 // myMesh->SetIsModified( true ); - SetNodeInVolume() can't prevent re-compute, I believe
980 //=============================================================================
982 * \brief Bind an element to a shape
983 * \param ElementID - element ID
984 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
985 * \retval boolean - false if ElementID or ShapeID is invalid
987 //=============================================================================
989 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
991 throw (SALOME::SALOME_Exception)
993 Unexpect aCatch(SALOME_SalomeException);
995 SMESHDS_Mesh * mesh = GetMeshDS();
996 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
998 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
1000 if ( mesh->MaxShapeIndex() < ShapeID )
1001 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
1003 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
1004 if ( shape.ShapeType() != TopAbs_EDGE &&
1005 shape.ShapeType() != TopAbs_FACE &&
1006 shape.ShapeType() != TopAbs_SOLID &&
1007 shape.ShapeType() != TopAbs_SHELL )
1008 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
1010 mesh->SetMeshElementOnShape( elem, ShapeID );
1012 myMesh->SetIsModified( true );
1015 //=============================================================================
1019 //=============================================================================
1021 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1022 CORBA::Long NodeID2)
1026 const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
1027 const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
1031 // Update Python script
1032 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1033 << NodeID1 << ", " << NodeID2 << " )";
1036 ::SMESH_MeshEditor aMeshEditor( myMesh );
1037 int ret = aMeshEditor.InverseDiag ( n1, n2 );
1038 myMesh->GetMeshDS()->Modified();
1039 myMesh->SetIsModified( true );
1043 //=============================================================================
1047 //=============================================================================
1049 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1050 CORBA::Long NodeID2)
1054 const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
1055 const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
1059 // Update Python script
1060 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1061 << NodeID1 << ", " << NodeID2 << " )";
1063 ::SMESH_MeshEditor aMeshEditor( myMesh );
1065 bool stat = aMeshEditor.DeleteDiag ( n1, n2 );
1067 myMesh->GetMeshDS()->Modified();
1069 myMesh->SetIsModified( true ); // issue 0020693
1071 storeResult(aMeshEditor);
1076 //=============================================================================
1080 //=============================================================================
1082 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1086 ::SMESH_MeshEditor anEditor( myMesh );
1087 for (int i = 0; i < IDsOfElements.length(); i++)
1089 CORBA::Long index = IDsOfElements[i];
1090 const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
1092 anEditor.Reorient( elem );
1094 // Update Python script
1095 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1097 myMesh->GetMeshDS()->Modified();
1098 if ( IDsOfElements.length() )
1099 myMesh->SetIsModified( true ); // issue 0020693
1105 //=============================================================================
1109 //=============================================================================
1111 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1115 TPythonDump aTPythonDump; // suppress dump in Reorient()
1117 SMESH::long_array_var anElementsId = theObject->GetIDs();
1118 CORBA::Boolean isDone = Reorient(anElementsId);
1120 // Update Python script
1121 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1126 //=============================================================================
1130 //=============================================================================
1131 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1132 SMESH::NumericalFunctor_ptr Criterion,
1133 CORBA::Double MaxAngle)
1137 SMESHDS_Mesh* aMesh = GetMeshDS();
1138 TIDSortedElemSet faces;
1139 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1141 SMESH::NumericalFunctor_i* aNumericalFunctor =
1142 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1143 SMESH::Controls::NumericalFunctorPtr aCrit;
1144 if ( !aNumericalFunctor )
1145 aCrit.reset( new SMESH::Controls::AspectRatio() );
1147 aCrit = aNumericalFunctor->GetNumericalFunctor();
1149 // Update Python script
1150 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1151 << IDsOfElements << ", " << aNumericalFunctor << ", " << MaxAngle << " )";
1153 ::SMESH_MeshEditor anEditor( myMesh );
1155 bool stat = anEditor.TriToQuad( faces, aCrit, MaxAngle );
1156 myMesh->GetMeshDS()->Modified();
1158 myMesh->SetIsModified( true ); // issue 0020693
1160 storeResult(anEditor);
1166 //=============================================================================
1170 //=============================================================================
1171 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1172 SMESH::NumericalFunctor_ptr Criterion,
1173 CORBA::Double MaxAngle)
1177 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1178 SMESH::long_array_var anElementsId = theObject->GetIDs();
1179 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1181 SMESH::NumericalFunctor_i* aNumericalFunctor =
1182 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1184 // Update Python script
1185 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1186 << theObject << ", " << aNumericalFunctor << ", " << MaxAngle << " )";
1192 //=============================================================================
1196 //=============================================================================
1197 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1198 SMESH::NumericalFunctor_ptr Criterion)
1202 SMESHDS_Mesh* aMesh = GetMeshDS();
1203 TIDSortedElemSet faces;
1204 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1206 SMESH::NumericalFunctor_i* aNumericalFunctor =
1207 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1208 SMESH::Controls::NumericalFunctorPtr aCrit;
1209 if ( !aNumericalFunctor )
1210 aCrit.reset( new SMESH::Controls::AspectRatio() );
1212 aCrit = aNumericalFunctor->GetNumericalFunctor();
1215 // Update Python script
1216 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1218 ::SMESH_MeshEditor anEditor( myMesh );
1219 CORBA::Boolean stat = anEditor.QuadToTri( faces, aCrit );
1220 myMesh->GetMeshDS()->Modified();
1222 myMesh->SetIsModified( true ); // issue 0020693
1224 storeResult(anEditor);
1230 //=============================================================================
1234 //=============================================================================
1235 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1236 SMESH::NumericalFunctor_ptr Criterion)
1240 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1242 SMESH::long_array_var anElementsId = theObject->GetIDs();
1243 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1245 SMESH::NumericalFunctor_i* aNumericalFunctor =
1246 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1248 // Update Python script
1249 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1255 //=============================================================================
1259 //=============================================================================
1260 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1261 CORBA::Boolean Diag13)
1265 SMESHDS_Mesh* aMesh = GetMeshDS();
1266 TIDSortedElemSet faces;
1267 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1269 // Update Python script
1270 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1271 << IDsOfElements << ", " << Diag13 << " )";
1273 ::SMESH_MeshEditor anEditor( myMesh );
1274 CORBA::Boolean stat = anEditor.QuadToTri( faces, Diag13 );
1275 myMesh->GetMeshDS()->Modified();
1277 myMesh->SetIsModified( true ); // issue 0020693
1280 storeResult(anEditor);
1286 //=============================================================================
1290 //=============================================================================
1291 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1292 CORBA::Boolean Diag13)
1296 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
1298 SMESH::long_array_var anElementsId = theObject->GetIDs();
1299 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
1301 // Update Python script
1302 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
1303 << theObject << ", " << Diag13 << " )";
1309 //=============================================================================
1313 //=============================================================================
1314 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
1315 SMESH::NumericalFunctor_ptr Criterion)
1319 const SMDS_MeshElement* quad = GetMeshDS()->FindElement(IDOfQuad);
1320 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
1322 SMESH::NumericalFunctor_i* aNumericalFunctor =
1323 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
1324 SMESH::Controls::NumericalFunctorPtr aCrit;
1325 if (aNumericalFunctor)
1326 aCrit = aNumericalFunctor->GetNumericalFunctor();
1328 aCrit.reset(new SMESH::Controls::AspectRatio());
1330 ::SMESH_MeshEditor anEditor (myMesh);
1331 return anEditor.BestSplit(quad, aCrit);
1336 //================================================================================
1338 * \brief Split volumic elements into tetrahedrons
1340 //================================================================================
1342 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
1343 CORBA::Short methodFlags)
1344 throw (SALOME::SALOME_Exception)
1346 Unexpect aCatch(SALOME_SalomeException);
1350 SMESH::long_array_var anElementsId = elems->GetIDs();
1351 TIDSortedElemSet elemSet;
1352 arrayToSet( anElementsId, GetMeshDS(), elemSet, SMDSAbs_Volume );
1354 ::SMESH_MeshEditor anEditor (myMesh);
1355 anEditor.SplitVolumesIntoTetra( elemSet, int( methodFlags ));
1356 myMesh->GetMeshDS()->Modified();
1358 storeResult(anEditor);
1360 // if ( myLastCreatedElems.length() ) - it does not influence Compute()
1361 // myMesh->SetIsModified( true ); // issue 0020693
1363 TPythonDump() << this << ".SplitVolumesIntoTetra( "
1364 << elems << ", " << methodFlags << " )";
1367 //=======================================================================
1370 //=======================================================================
1373 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
1374 const SMESH::long_array & IDsOfFixedNodes,
1375 CORBA::Long MaxNbOfIterations,
1376 CORBA::Double MaxAspectRatio,
1377 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1379 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1380 MaxAspectRatio, Method, false );
1384 //=======================================================================
1385 //function : SmoothParametric
1387 //=======================================================================
1390 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
1391 const SMESH::long_array & IDsOfFixedNodes,
1392 CORBA::Long MaxNbOfIterations,
1393 CORBA::Double MaxAspectRatio,
1394 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1396 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1397 MaxAspectRatio, Method, true );
1401 //=======================================================================
1402 //function : SmoothObject
1404 //=======================================================================
1407 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
1408 const SMESH::long_array & IDsOfFixedNodes,
1409 CORBA::Long MaxNbOfIterations,
1410 CORBA::Double MaxAspectRatio,
1411 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1413 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1414 MaxAspectRatio, Method, false);
1418 //=======================================================================
1419 //function : SmoothParametricObject
1421 //=======================================================================
1424 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
1425 const SMESH::long_array & IDsOfFixedNodes,
1426 CORBA::Long MaxNbOfIterations,
1427 CORBA::Double MaxAspectRatio,
1428 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1430 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1431 MaxAspectRatio, Method, true);
1435 //=============================================================================
1439 //=============================================================================
1442 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
1443 const SMESH::long_array & IDsOfFixedNodes,
1444 CORBA::Long MaxNbOfIterations,
1445 CORBA::Double MaxAspectRatio,
1446 SMESH::SMESH_MeshEditor::Smooth_Method Method,
1451 SMESHDS_Mesh* aMesh = GetMeshDS();
1453 TIDSortedElemSet elements;
1454 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
1456 set<const SMDS_MeshNode*> fixedNodes;
1457 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
1458 CORBA::Long index = IDsOfFixedNodes[i];
1459 const SMDS_MeshNode * node = aMesh->FindNode(index);
1461 fixedNodes.insert( node );
1463 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
1464 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
1465 method = ::SMESH_MeshEditor::CENTROIDAL;
1467 ::SMESH_MeshEditor anEditor( myMesh );
1468 anEditor.Smooth(elements, fixedNodes, method,
1469 MaxNbOfIterations, MaxAspectRatio, IsParametric );
1471 myMesh->GetMeshDS()->Modified();
1472 myMesh->SetIsModified( true ); // issue 0020693
1474 storeResult(anEditor);
1476 // Update Python script
1477 TPythonDump() << "isDone = " << this << "."
1478 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
1479 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
1480 << MaxNbOfIterations << ", " << MaxAspectRatio << ", "
1481 << "SMESH.SMESH_MeshEditor."
1482 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1483 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1489 //=============================================================================
1493 //=============================================================================
1496 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
1497 const SMESH::long_array & IDsOfFixedNodes,
1498 CORBA::Long MaxNbOfIterations,
1499 CORBA::Double MaxAspectRatio,
1500 SMESH::SMESH_MeshEditor::Smooth_Method Method,
1505 TPythonDump aTPythonDump; // suppress dump in smooth()
1507 SMESH::long_array_var anElementsId = theObject->GetIDs();
1508 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
1509 MaxAspectRatio, Method, IsParametric);
1511 // Update Python script
1512 aTPythonDump << "isDone = " << this << "."
1513 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
1514 << theObject << ", " << IDsOfFixedNodes << ", "
1515 << MaxNbOfIterations << ", " << MaxAspectRatio << ", "
1516 << "SMESH.SMESH_MeshEditor."
1517 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1518 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1524 //=============================================================================
1528 //=============================================================================
1530 void SMESH_MeshEditor_i::RenumberNodes()
1532 // Update Python script
1533 TPythonDump() << this << ".RenumberNodes()";
1535 GetMeshDS()->Renumber( true );
1539 //=============================================================================
1543 //=============================================================================
1545 void SMESH_MeshEditor_i::RenumberElements()
1547 // Update Python script
1548 TPythonDump() << this << ".RenumberElements()";
1550 GetMeshDS()->Renumber( false );
1553 //=======================================================================
1555 * \brief Return groups by their IDs
1557 //=======================================================================
1559 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
1563 myMesh_i->CreateGroupServants();
1564 return myMesh_i->GetGroups( *groupIDs );
1567 //=======================================================================
1568 //function : rotationSweep
1570 //=======================================================================
1572 SMESH::ListOfGroups*
1573 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
1574 const SMESH::AxisStruct & theAxis,
1575 CORBA::Double theAngleInRadians,
1576 CORBA::Long theNbOfSteps,
1577 CORBA::Double theTolerance,
1578 const bool theMakeGroups,
1579 const SMDSAbs_ElementType theElementType)
1583 TIDSortedElemSet inElements, copyElements;
1584 arrayToSet(theIDsOfElements, GetMeshDS(), inElements, theElementType);
1586 TIDSortedElemSet* workElements = & inElements;
1587 TPreviewMesh tmpMesh( SMDSAbs_Face );
1588 SMESH_Mesh* mesh = 0;
1589 bool makeWalls=true;
1590 if ( myPreviewMode )
1592 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
1593 tmpMesh.Copy( inElements, copyElements, select, avoid );
1595 workElements = & copyElements;
1596 //makeWalls = false;
1603 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
1604 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
1606 ::SMESH_MeshEditor anEditor( mesh );
1607 ::SMESH_MeshEditor::PGroupIDs groupIds =
1608 anEditor.RotationSweep (*workElements, Ax1, theAngleInRadians,
1609 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
1610 storeResult(anEditor);
1611 myMesh->GetMeshDS()->Modified();
1613 // myMesh->SetIsModified( true ); -- it does not influence Compute()
1615 return theMakeGroups ? getGroups(groupIds.get()) : 0;
1618 //=======================================================================
1619 //function : RotationSweep
1621 //=======================================================================
1623 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
1624 const SMESH::AxisStruct & theAxis,
1625 CORBA::Double theAngleInRadians,
1626 CORBA::Long theNbOfSteps,
1627 CORBA::Double theTolerance)
1629 if ( !myPreviewMode ) {
1630 TPythonDump() << this << ".RotationSweep( "
1631 << theIDsOfElements << ", "
1633 << theAngleInRadians << ", "
1634 << theNbOfSteps << ", "
1635 << theTolerance << " )";
1637 rotationSweep(theIDsOfElements,
1645 //=======================================================================
1646 //function : RotationSweepMakeGroups
1648 //=======================================================================
1650 SMESH::ListOfGroups*
1651 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
1652 const SMESH::AxisStruct& theAxis,
1653 CORBA::Double theAngleInRadians,
1654 CORBA::Long theNbOfSteps,
1655 CORBA::Double theTolerance)
1657 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1659 SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
1665 if (!myPreviewMode) {
1666 DumpGroupsList(aPythonDump, aGroups);
1667 aPythonDump << this << ".RotationSweepMakeGroups( "
1668 << theIDsOfElements << ", "
1670 << theAngleInRadians << ", "
1671 << theNbOfSteps << ", "
1672 << theTolerance << " )";
1677 //=======================================================================
1678 //function : RotationSweepObject
1680 //=======================================================================
1682 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
1683 const SMESH::AxisStruct & theAxis,
1684 CORBA::Double theAngleInRadians,
1685 CORBA::Long theNbOfSteps,
1686 CORBA::Double theTolerance)
1688 if ( !myPreviewMode ) {
1689 TPythonDump() << this << ".RotationSweepObject( "
1690 << theObject << ", "
1692 << theAngleInRadians << ", "
1693 << theNbOfSteps << ", "
1694 << theTolerance << " )";
1696 SMESH::long_array_var anElementsId = theObject->GetIDs();
1697 rotationSweep(anElementsId,
1705 //=======================================================================
1706 //function : RotationSweepObject1D
1708 //=======================================================================
1710 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
1711 const SMESH::AxisStruct & theAxis,
1712 CORBA::Double theAngleInRadians,
1713 CORBA::Long theNbOfSteps,
1714 CORBA::Double theTolerance)
1716 if ( !myPreviewMode ) {
1717 TPythonDump() << this << ".RotationSweepObject1D( "
1718 << theObject << ", "
1720 << theAngleInRadians << ", "
1721 << theNbOfSteps << ", "
1722 << theTolerance << " )";
1724 SMESH::long_array_var anElementsId = theObject->GetIDs();
1725 rotationSweep(anElementsId,
1734 //=======================================================================
1735 //function : RotationSweepObject2D
1737 //=======================================================================
1739 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
1740 const SMESH::AxisStruct & theAxis,
1741 CORBA::Double theAngleInRadians,
1742 CORBA::Long theNbOfSteps,
1743 CORBA::Double theTolerance)
1745 if ( !myPreviewMode ) {
1746 TPythonDump() << this << ".RotationSweepObject2D( "
1747 << theObject << ", "
1749 << theAngleInRadians << ", "
1750 << theNbOfSteps << ", "
1751 << theTolerance << " )";
1753 SMESH::long_array_var anElementsId = theObject->GetIDs();
1754 rotationSweep(anElementsId,
1763 //=======================================================================
1764 //function : RotationSweepObjectMakeGroups
1766 //=======================================================================
1768 SMESH::ListOfGroups*
1769 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1770 const SMESH::AxisStruct& theAxis,
1771 CORBA::Double theAngleInRadians,
1772 CORBA::Long theNbOfSteps,
1773 CORBA::Double theTolerance)
1775 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1777 SMESH::long_array_var anElementsId = theObject->GetIDs();
1778 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
1784 if (!myPreviewMode) {
1785 DumpGroupsList(aPythonDump, aGroups);
1786 aPythonDump << this << ".RotationSweepObjectMakeGroups( "
1787 << theObject << ", "
1789 << theAngleInRadians << ", "
1790 << theNbOfSteps << ", "
1791 << theTolerance << " )";
1796 //=======================================================================
1797 //function : RotationSweepObject1DMakeGroups
1799 //=======================================================================
1801 SMESH::ListOfGroups*
1802 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1803 const SMESH::AxisStruct& theAxis,
1804 CORBA::Double theAngleInRadians,
1805 CORBA::Long theNbOfSteps,
1806 CORBA::Double theTolerance)
1808 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1810 SMESH::long_array_var anElementsId = theObject->GetIDs();
1811 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
1818 if (!myPreviewMode) {
1819 DumpGroupsList(aPythonDump, aGroups);
1820 aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
1821 << theObject << ", "
1823 << theAngleInRadians << ", "
1824 << theNbOfSteps << ", "
1825 << theTolerance << " )";
1830 //=======================================================================
1831 //function : RotationSweepObject2DMakeGroups
1833 //=======================================================================
1835 SMESH::ListOfGroups*
1836 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1837 const SMESH::AxisStruct& theAxis,
1838 CORBA::Double theAngleInRadians,
1839 CORBA::Long theNbOfSteps,
1840 CORBA::Double theTolerance)
1842 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1844 SMESH::long_array_var anElementsId = theObject->GetIDs();
1845 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
1852 if (!myPreviewMode) {
1853 DumpGroupsList(aPythonDump, aGroups);
1854 aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
1855 << theObject << ", "
1857 << theAngleInRadians << ", "
1858 << theNbOfSteps << ", "
1859 << theTolerance << " )";
1865 //=======================================================================
1866 //function : extrusionSweep
1868 //=======================================================================
1870 SMESH::ListOfGroups*
1871 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
1872 const SMESH::DirStruct & theStepVector,
1873 CORBA::Long theNbOfSteps,
1875 const SMDSAbs_ElementType theElementType)
1883 TIDSortedElemSet elements, copyElements;
1884 arrayToSet(theIDsOfElements, GetMeshDS(), elements, theElementType);
1886 const SMESH::PointStruct * P = &theStepVector.PS;
1887 gp_Vec stepVec( P->x, P->y, P->z );
1889 TIDSortedElemSet* workElements = & elements;
1890 TPreviewMesh tmpMesh( SMDSAbs_Face );
1891 SMESH_Mesh* mesh = myMesh;
1893 if ( myPreviewMode ) {
1894 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
1895 tmpMesh.Copy( elements, copyElements, select, avoid );
1897 workElements = & copyElements;
1898 theMakeGroups = false;
1901 TElemOfElemListMap aHystory;
1902 ::SMESH_MeshEditor anEditor( mesh );
1903 ::SMESH_MeshEditor::PGroupIDs groupIds =
1904 anEditor.ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
1906 myMesh->GetMeshDS()->Modified();
1907 storeResult(anEditor);
1909 return theMakeGroups ? getGroups(groupIds.get()) : 0;
1911 } catch(Standard_Failure) {
1912 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1913 INFOS( "SMESH_MeshEditor_i::ExtrusionSweep fails - "<< aFail->GetMessageString() );
1918 //=======================================================================
1919 //function : ExtrusionSweep
1921 //=======================================================================
1923 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
1924 const SMESH::DirStruct & theStepVector,
1925 CORBA::Long theNbOfSteps)
1927 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
1928 if (!myPreviewMode) {
1929 TPythonDump() << this << ".ExtrusionSweep( "
1930 << theIDsOfElements << ", " << theStepVector <<", " << theNbOfSteps << " )";
1935 //=======================================================================
1936 //function : ExtrusionSweepObject
1938 //=======================================================================
1940 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
1941 const SMESH::DirStruct & theStepVector,
1942 CORBA::Long theNbOfSteps)
1944 SMESH::long_array_var anElementsId = theObject->GetIDs();
1945 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
1946 if (!myPreviewMode) {
1947 TPythonDump() << this << ".ExtrusionSweepObject( "
1948 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
1952 //=======================================================================
1953 //function : ExtrusionSweepObject1D
1955 //=======================================================================
1957 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
1958 const SMESH::DirStruct & theStepVector,
1959 CORBA::Long theNbOfSteps)
1961 SMESH::long_array_var anElementsId = theObject->GetIDs();
1962 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
1963 if ( !myPreviewMode ) {
1964 TPythonDump() << this << ".ExtrusionSweepObject1D( "
1965 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
1969 //=======================================================================
1970 //function : ExtrusionSweepObject2D
1972 //=======================================================================
1974 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
1975 const SMESH::DirStruct & theStepVector,
1976 CORBA::Long theNbOfSteps)
1978 SMESH::long_array_var anElementsId = theObject->GetIDs();
1979 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
1980 if ( !myPreviewMode ) {
1981 TPythonDump() << this << ".ExtrusionSweepObject2D( "
1982 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
1986 //=======================================================================
1987 //function : ExtrusionSweepMakeGroups
1989 //=======================================================================
1991 SMESH::ListOfGroups*
1992 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
1993 const SMESH::DirStruct& theStepVector,
1994 CORBA::Long theNbOfSteps)
1996 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1998 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
2000 if (!myPreviewMode) {
2001 DumpGroupsList(aPythonDump, aGroups);
2002 aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
2003 << ", " << theStepVector <<", " << theNbOfSteps << " )";
2008 //=======================================================================
2009 //function : ExtrusionSweepObjectMakeGroups
2011 //=======================================================================
2013 SMESH::ListOfGroups*
2014 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2015 const SMESH::DirStruct& theStepVector,
2016 CORBA::Long theNbOfSteps)
2018 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2020 SMESH::long_array_var anElementsId = theObject->GetIDs();
2021 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
2023 if (!myPreviewMode) {
2024 DumpGroupsList(aPythonDump, aGroups);
2025 aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
2026 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2031 //=======================================================================
2032 //function : ExtrusionSweepObject1DMakeGroups
2034 //=======================================================================
2036 SMESH::ListOfGroups*
2037 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2038 const SMESH::DirStruct& theStepVector,
2039 CORBA::Long theNbOfSteps)
2041 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2043 SMESH::long_array_var anElementsId = theObject->GetIDs();
2044 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2045 theNbOfSteps, true, SMDSAbs_Edge);
2046 if (!myPreviewMode) {
2047 DumpGroupsList(aPythonDump, aGroups);
2048 aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
2049 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2054 //=======================================================================
2055 //function : ExtrusionSweepObject2DMakeGroups
2057 //=======================================================================
2059 SMESH::ListOfGroups*
2060 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2061 const SMESH::DirStruct& theStepVector,
2062 CORBA::Long theNbOfSteps)
2064 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2066 SMESH::long_array_var anElementsId = theObject->GetIDs();
2067 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2068 theNbOfSteps, true, SMDSAbs_Face);
2069 if (!myPreviewMode) {
2070 DumpGroupsList(aPythonDump, aGroups);
2071 aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
2072 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2078 //=======================================================================
2079 //function : advancedExtrusion
2081 //=======================================================================
2083 SMESH::ListOfGroups*
2084 SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
2085 const SMESH::DirStruct & theStepVector,
2086 CORBA::Long theNbOfSteps,
2087 CORBA::Long theExtrFlags,
2088 CORBA::Double theSewTolerance,
2089 const bool theMakeGroups)
2093 TIDSortedElemSet elements;
2094 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
2096 const SMESH::PointStruct * P = &theStepVector.PS;
2097 gp_Vec stepVec( P->x, P->y, P->z );
2099 ::SMESH_MeshEditor anEditor( myMesh );
2100 TElemOfElemListMap aHystory;
2101 ::SMESH_MeshEditor::PGroupIDs groupIds =
2102 anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
2103 theMakeGroups, theExtrFlags, theSewTolerance);
2104 storeResult(anEditor);
2106 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2109 //=======================================================================
2110 //function : AdvancedExtrusion
2112 //=======================================================================
2114 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2115 const SMESH::DirStruct & theStepVector,
2116 CORBA::Long theNbOfSteps,
2117 CORBA::Long theExtrFlags,
2118 CORBA::Double theSewTolerance)
2120 if ( !myPreviewMode ) {
2121 TPythonDump() << "stepVector = " << theStepVector;
2122 TPythonDump() << this << ".AdvancedExtrusion("
2125 << theNbOfSteps << ","
2126 << theExtrFlags << ", "
2127 << theSewTolerance << " )";
2129 advancedExtrusion( theIDsOfElements,
2137 //=======================================================================
2138 //function : AdvancedExtrusionMakeGroups
2140 //=======================================================================
2141 SMESH::ListOfGroups*
2142 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
2143 const SMESH::DirStruct& theStepVector,
2144 CORBA::Long theNbOfSteps,
2145 CORBA::Long theExtrFlags,
2146 CORBA::Double theSewTolerance)
2148 if (!myPreviewMode) {
2149 TPythonDump() << "stepVector = " << theStepVector;
2151 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2153 SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
2160 if (!myPreviewMode) {
2161 DumpGroupsList(aPythonDump, aGroups);
2162 aPythonDump << this << ".AdvancedExtrusionMakeGroups("
2165 << theNbOfSteps << ","
2166 << theExtrFlags << ", "
2167 << theSewTolerance << " )";
2173 //================================================================================
2175 * \brief Convert extrusion error to IDL enum
2177 //================================================================================
2179 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
2181 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
2185 RETCASE( EXTR_NO_ELEMENTS );
2186 RETCASE( EXTR_PATH_NOT_EDGE );
2187 RETCASE( EXTR_BAD_PATH_SHAPE );
2188 RETCASE( EXTR_BAD_STARTING_NODE );
2189 RETCASE( EXTR_BAD_ANGLES_NUMBER );
2190 RETCASE( EXTR_CANT_GET_TANGENT );
2192 return SMESH::SMESH_MeshEditor::EXTR_OK;
2196 //=======================================================================
2197 //function : extrusionAlongPath
2199 //=======================================================================
2200 SMESH::ListOfGroups*
2201 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2202 SMESH::SMESH_Mesh_ptr thePathMesh,
2203 GEOM::GEOM_Object_ptr thePathShape,
2204 CORBA::Long theNodeStart,
2205 CORBA::Boolean theHasAngles,
2206 const SMESH::double_array & theAngles,
2207 CORBA::Boolean theHasRefPoint,
2208 const SMESH::PointStruct & theRefPoint,
2209 const bool theMakeGroups,
2210 SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
2211 const SMDSAbs_ElementType theElementType)
2213 MESSAGE("extrusionAlongPath");
2216 if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
2217 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2220 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2222 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2223 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2225 if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
2226 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2230 SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
2232 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2236 TIDSortedElemSet elements;
2237 arrayToSet(theIDsOfElements, GetMeshDS(), elements, theElementType);
2239 list<double> angles;
2240 for (int i = 0; i < theAngles.length(); i++) {
2241 angles.push_back( theAngles[i] );
2244 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
2246 int nbOldGroups = myMesh->NbGroup();
2248 ::SMESH_MeshEditor anEditor( myMesh );
2249 ::SMESH_MeshEditor::Extrusion_Error error =
2250 anEditor.ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
2251 theHasAngles, angles, false,
2252 theHasRefPoint, refPnt, theMakeGroups );
2253 myMesh->GetMeshDS()->Modified();
2254 storeResult(anEditor);
2255 theError = convExtrError( error );
2257 if ( theMakeGroups ) {
2258 list<int> groupIDs = myMesh->GetGroupIds();
2259 list<int>::iterator newBegin = groupIDs.begin();
2260 std::advance( newBegin, nbOldGroups ); // skip old groups
2261 groupIDs.erase( groupIDs.begin(), newBegin );
2262 return getGroups( & groupIDs );
2268 //=======================================================================
2269 //function : extrusionAlongPathX
2271 //=======================================================================
2272 SMESH::ListOfGroups*
2273 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements,
2274 SMESH::SMESH_IDSource_ptr Path,
2275 CORBA::Long NodeStart,
2276 CORBA::Boolean HasAngles,
2277 const SMESH::double_array& Angles,
2278 CORBA::Boolean LinearVariation,
2279 CORBA::Boolean HasRefPoint,
2280 const SMESH::PointStruct& RefPoint,
2282 const SMDSAbs_ElementType ElementType,
2283 SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
2285 SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
2289 list<double> angles;
2290 for (int i = 0; i < Angles.length(); i++) {
2291 angles.push_back( Angles[i] );
2293 gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
2294 int nbOldGroups = myMesh->NbGroup();
2296 if ( Path->_is_nil() ) {
2297 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2301 TIDSortedElemSet elements, copyElements;
2302 arrayToSet(IDsOfElements, GetMeshDS(), elements, ElementType);
2304 TIDSortedElemSet* workElements = &elements;
2305 TPreviewMesh tmpMesh( SMDSAbs_Face );
2306 SMESH_Mesh* mesh = myMesh;
2308 if ( myPreviewMode )
2310 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2311 tmpMesh.Copy( elements, copyElements, select, avoid );
2313 workElements = & copyElements;
2317 ::SMESH_MeshEditor anEditor( mesh );
2318 ::SMESH_MeshEditor::Extrusion_Error error;
2320 if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path ))
2323 SMDS_MeshNode* aNodeStart =
2324 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2325 if ( !aNodeStart ) {
2326 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2329 error = anEditor.ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
2330 HasAngles, angles, LinearVariation,
2331 HasRefPoint, refPnt, MakeGroups );
2332 myMesh->GetMeshDS()->Modified();
2334 else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
2337 SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
2338 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
2339 SMDS_MeshNode* aNodeStart =
2340 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2341 if ( !aNodeStart ) {
2342 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2345 SMESH_subMesh* aSubMesh =
2346 aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
2347 error = anEditor.ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
2348 HasAngles, angles, LinearVariation,
2349 HasRefPoint, refPnt, MakeGroups );
2350 myMesh->GetMeshDS()->Modified();
2352 else if ( SMESH::DownCast<SMESH_Group_i*>( Path ))
2354 // path as group of 1D elements
2360 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2364 storeResult(anEditor);
2365 Error = convExtrError( error );
2368 list<int> groupIDs = myMesh->GetGroupIds();
2369 list<int>::iterator newBegin = groupIDs.begin();
2370 std::advance( newBegin, nbOldGroups ); // skip old groups
2371 groupIDs.erase( groupIDs.begin(), newBegin );
2372 return getGroups( & groupIDs );
2378 //=======================================================================
2379 //function : ExtrusionAlongPath
2381 //=======================================================================
2382 SMESH::SMESH_MeshEditor::Extrusion_Error
2383 SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2384 SMESH::SMESH_Mesh_ptr thePathMesh,
2385 GEOM::GEOM_Object_ptr thePathShape,
2386 CORBA::Long theNodeStart,
2387 CORBA::Boolean theHasAngles,
2388 const SMESH::double_array & theAngles,
2389 CORBA::Boolean theHasRefPoint,
2390 const SMESH::PointStruct & theRefPoint)
2392 MESSAGE("ExtrusionAlongPath");
2393 if ( !myPreviewMode ) {
2394 TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
2395 << theIDsOfElements << ", "
2396 << thePathMesh << ", "
2397 << thePathShape << ", "
2398 << theNodeStart << ", "
2399 << theHasAngles << ", "
2400 << theAngles << ", "
2401 << theHasRefPoint << ", "
2402 << "SMESH.PointStruct( "
2403 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2404 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2405 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2407 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2408 extrusionAlongPath( theIDsOfElements,
2421 //=======================================================================
2422 //function : ExtrusionAlongPathObject
2424 //=======================================================================
2425 SMESH::SMESH_MeshEditor::Extrusion_Error
2426 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject,
2427 SMESH::SMESH_Mesh_ptr thePathMesh,
2428 GEOM::GEOM_Object_ptr thePathShape,
2429 CORBA::Long theNodeStart,
2430 CORBA::Boolean theHasAngles,
2431 const SMESH::double_array & theAngles,
2432 CORBA::Boolean theHasRefPoint,
2433 const SMESH::PointStruct & theRefPoint)
2435 if ( !myPreviewMode ) {
2436 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
2437 << theObject << ", "
2438 << thePathMesh << ", "
2439 << thePathShape << ", "
2440 << theNodeStart << ", "
2441 << theHasAngles << ", "
2442 << theAngles << ", "
2443 << theHasRefPoint << ", "
2444 << "SMESH.PointStruct( "
2445 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2446 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2447 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2449 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2450 SMESH::long_array_var anElementsId = theObject->GetIDs();
2451 extrusionAlongPath( anElementsId,
2464 //=======================================================================
2465 //function : ExtrusionAlongPathObject1D
2467 //=======================================================================
2468 SMESH::SMESH_MeshEditor::Extrusion_Error
2469 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject,
2470 SMESH::SMESH_Mesh_ptr thePathMesh,
2471 GEOM::GEOM_Object_ptr thePathShape,
2472 CORBA::Long theNodeStart,
2473 CORBA::Boolean theHasAngles,
2474 const SMESH::double_array & theAngles,
2475 CORBA::Boolean theHasRefPoint,
2476 const SMESH::PointStruct & theRefPoint)
2478 if ( !myPreviewMode ) {
2479 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
2480 << theObject << ", "
2481 << thePathMesh << ", "
2482 << thePathShape << ", "
2483 << theNodeStart << ", "
2484 << theHasAngles << ", "
2485 << theAngles << ", "
2486 << theHasRefPoint << ", "
2487 << "SMESH.PointStruct( "
2488 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2489 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2490 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2492 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2493 SMESH::long_array_var anElementsId = theObject->GetIDs();
2494 extrusionAlongPath( anElementsId,
2508 //=======================================================================
2509 //function : ExtrusionAlongPathObject2D
2511 //=======================================================================
2512 SMESH::SMESH_MeshEditor::Extrusion_Error
2513 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject,
2514 SMESH::SMESH_Mesh_ptr thePathMesh,
2515 GEOM::GEOM_Object_ptr thePathShape,
2516 CORBA::Long theNodeStart,
2517 CORBA::Boolean theHasAngles,
2518 const SMESH::double_array & theAngles,
2519 CORBA::Boolean theHasRefPoint,
2520 const SMESH::PointStruct & theRefPoint)
2522 if ( !myPreviewMode ) {
2523 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
2524 << theObject << ", "
2525 << thePathMesh << ", "
2526 << thePathShape << ", "
2527 << theNodeStart << ", "
2528 << theHasAngles << ", "
2529 << theAngles << ", "
2530 << theHasRefPoint << ", "
2531 << "SMESH.PointStruct( "
2532 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2533 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2534 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2536 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2537 SMESH::long_array_var anElementsId = theObject->GetIDs();
2538 extrusionAlongPath( anElementsId,
2553 //=======================================================================
2554 //function : ExtrusionAlongPathMakeGroups
2556 //=======================================================================
2557 SMESH::ListOfGroups*
2558 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theIDsOfElements,
2559 SMESH::SMESH_Mesh_ptr thePathMesh,
2560 GEOM::GEOM_Object_ptr thePathShape,
2561 CORBA::Long theNodeStart,
2562 CORBA::Boolean theHasAngles,
2563 const SMESH::double_array& theAngles,
2564 CORBA::Boolean theHasRefPoint,
2565 const SMESH::PointStruct& theRefPoint,
2566 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2568 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2570 SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements,
2580 if (!myPreviewMode) {
2581 bool isDumpGroups = aGroups && aGroups->length() > 0;
2583 aPythonDump << "(" << aGroups << ", error)";
2585 aPythonDump <<"error";
2587 aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
2588 << theIDsOfElements << ", "
2589 << thePathMesh << ", "
2590 << thePathShape << ", "
2591 << theNodeStart << ", "
2592 << theHasAngles << ", "
2593 << theAngles << ", "
2594 << theHasRefPoint << ", "
2595 << "SMESH.PointStruct( "
2596 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2597 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2598 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2603 //=======================================================================
2604 //function : ExtrusionAlongPathObjectMakeGroups
2606 //=======================================================================
2607 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2608 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2609 SMESH::SMESH_Mesh_ptr thePathMesh,
2610 GEOM::GEOM_Object_ptr thePathShape,
2611 CORBA::Long theNodeStart,
2612 CORBA::Boolean theHasAngles,
2613 const SMESH::double_array& theAngles,
2614 CORBA::Boolean theHasRefPoint,
2615 const SMESH::PointStruct& theRefPoint,
2616 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2618 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2620 SMESH::long_array_var anElementsId = theObject->GetIDs();
2621 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
2632 if (!myPreviewMode) {
2633 bool isDumpGroups = aGroups && aGroups->length() > 0;
2635 aPythonDump << "(" << aGroups << ", error)";
2637 aPythonDump <<"error";
2639 aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
2640 << theObject << ", "
2641 << thePathMesh << ", "
2642 << thePathShape << ", "
2643 << theNodeStart << ", "
2644 << theHasAngles << ", "
2645 << theAngles << ", "
2646 << theHasRefPoint << ", "
2647 << "SMESH.PointStruct( "
2648 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2649 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2650 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2655 //=======================================================================
2656 //function : ExtrusionAlongPathObject1DMakeGroups
2658 //=======================================================================
2659 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2660 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2661 SMESH::SMESH_Mesh_ptr thePathMesh,
2662 GEOM::GEOM_Object_ptr thePathShape,
2663 CORBA::Long theNodeStart,
2664 CORBA::Boolean theHasAngles,
2665 const SMESH::double_array& theAngles,
2666 CORBA::Boolean theHasRefPoint,
2667 const SMESH::PointStruct& theRefPoint,
2668 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2670 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2672 SMESH::long_array_var anElementsId = theObject->GetIDs();
2673 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
2685 if (!myPreviewMode) {
2686 bool isDumpGroups = aGroups && aGroups->length() > 0;
2688 aPythonDump << "(" << aGroups << ", error)";
2690 aPythonDump << "error";
2692 aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
2693 << theObject << ", "
2694 << thePathMesh << ", "
2695 << thePathShape << ", "
2696 << theNodeStart << ", "
2697 << theHasAngles << ", "
2698 << theAngles << ", "
2699 << theHasRefPoint << ", "
2700 << "SMESH.PointStruct( "
2701 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2702 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2703 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2708 //=======================================================================
2709 //function : ExtrusionAlongPathObject2DMakeGroups
2711 //=======================================================================
2712 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2713 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2714 SMESH::SMESH_Mesh_ptr thePathMesh,
2715 GEOM::GEOM_Object_ptr thePathShape,
2716 CORBA::Long theNodeStart,
2717 CORBA::Boolean theHasAngles,
2718 const SMESH::double_array& theAngles,
2719 CORBA::Boolean theHasRefPoint,
2720 const SMESH::PointStruct& theRefPoint,
2721 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2723 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2725 SMESH::long_array_var anElementsId = theObject->GetIDs();
2726 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
2738 if (!myPreviewMode) {
2739 bool isDumpGroups = aGroups && aGroups->length() > 0;
2741 aPythonDump << "(" << aGroups << ", error)";
2743 aPythonDump << "error";
2745 aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
2746 << theObject << ", "
2747 << thePathMesh << ", "
2748 << thePathShape << ", "
2749 << theNodeStart << ", "
2750 << theHasAngles << ", "
2751 << theAngles << ", "
2752 << theHasRefPoint << ", "
2753 << "SMESH.PointStruct( "
2754 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2755 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2756 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2762 //=======================================================================
2763 //function : ExtrusionAlongPathObjX
2765 //=======================================================================
2766 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2767 ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr Object,
2768 SMESH::SMESH_IDSource_ptr Path,
2769 CORBA::Long NodeStart,
2770 CORBA::Boolean HasAngles,
2771 const SMESH::double_array& Angles,
2772 CORBA::Boolean LinearVariation,
2773 CORBA::Boolean HasRefPoint,
2774 const SMESH::PointStruct& RefPoint,
2775 CORBA::Boolean MakeGroups,
2776 SMESH::ElementType ElemType,
2777 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2779 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2781 SMESH::long_array_var anElementsId = Object->GetIDs();
2782 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
2791 (SMDSAbs_ElementType)ElemType,
2794 if (!myPreviewMode) {
2795 bool isDumpGroups = aGroups && aGroups->length() > 0;
2797 aPythonDump << "(" << *aGroups << ", error)";
2799 aPythonDump << "error";
2801 aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
2804 << NodeStart << ", "
2805 << HasAngles << ", "
2807 << LinearVariation << ", "
2808 << HasRefPoint << ", "
2809 << "SMESH.PointStruct( "
2810 << ( HasRefPoint ? RefPoint.x : 0 ) << ", "
2811 << ( HasRefPoint ? RefPoint.y : 0 ) << ", "
2812 << ( HasRefPoint ? RefPoint.z : 0 ) << " ), "
2813 << MakeGroups << ", "
2814 << ElemType << " )";
2820 //=======================================================================
2821 //function : ExtrusionAlongPathX
2823 //=======================================================================
2824 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2825 ExtrusionAlongPathX(const SMESH::long_array& IDsOfElements,
2826 SMESH::SMESH_IDSource_ptr Path,
2827 CORBA::Long NodeStart,
2828 CORBA::Boolean HasAngles,
2829 const SMESH::double_array& Angles,
2830 CORBA::Boolean LinearVariation,
2831 CORBA::Boolean HasRefPoint,
2832 const SMESH::PointStruct& RefPoint,
2833 CORBA::Boolean MakeGroups,
2834 SMESH::ElementType ElemType,
2835 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2837 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2839 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
2848 (SMDSAbs_ElementType)ElemType,
2851 if (!myPreviewMode) {
2852 bool isDumpGroups = aGroups && aGroups->length() > 0;
2854 aPythonDump << "(" << *aGroups << ", error)";
2856 aPythonDump <<"error";
2858 aPythonDump << " = " << this << ".ExtrusionAlongPathX( "
2859 << IDsOfElements << ", "
2861 << NodeStart << ", "
2862 << HasAngles << ", "
2864 << LinearVariation << ", "
2865 << HasRefPoint << ", "
2866 << "SMESH.PointStruct( "
2867 << ( HasRefPoint ? RefPoint.x : 0 ) << ", "
2868 << ( HasRefPoint ? RefPoint.y : 0 ) << ", "
2869 << ( HasRefPoint ? RefPoint.z : 0 ) << " ), "
2870 << MakeGroups << ", "
2871 << ElemType << " )";
2877 //================================================================================
2879 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
2880 * of given angles along path steps
2881 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
2882 * which proceeds the extrusion
2883 * \param PathShape is shape(edge); as the mesh can be complex, the edge
2884 * is used to define the sub-mesh for the path
2886 //================================================================================
2888 SMESH::double_array*
2889 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
2890 GEOM::GEOM_Object_ptr thePathShape,
2891 const SMESH::double_array & theAngles)
2893 SMESH::double_array_var aResult = new SMESH::double_array();
2894 int nbAngles = theAngles.length();
2895 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
2897 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2898 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2899 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2900 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
2901 return aResult._retn();
2902 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
2903 if ( nbSteps == nbAngles )
2905 aResult.inout() = theAngles;
2909 aResult->length( nbSteps );
2910 double rAn2St = double( nbAngles ) / double( nbSteps );
2911 double angPrev = 0, angle;
2912 for ( int iSt = 0; iSt < nbSteps; ++iSt )
2914 double angCur = rAn2St * ( iSt+1 );
2915 double angCurFloor = floor( angCur );
2916 double angPrevFloor = floor( angPrev );
2917 if ( angPrevFloor == angCurFloor )
2918 angle = rAn2St * theAngles[ int( angCurFloor ) ];
2921 int iP = int( angPrevFloor );
2922 double angPrevCeil = ceil(angPrev);
2923 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
2925 int iC = int( angCurFloor );
2926 if ( iC < nbAngles )
2927 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
2929 iP = int( angPrevCeil );
2931 angle += theAngles[ iC ];
2933 aResult[ iSt ] = angle;
2938 // Update Python script
2939 TPythonDump() << "rotAngles = " << theAngles;
2940 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
2941 << thePathMesh << ", "
2942 << thePathShape << ", "
2945 return aResult._retn();
2949 //=======================================================================
2952 //=======================================================================
2954 SMESH::ListOfGroups*
2955 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
2956 const SMESH::AxisStruct & theAxis,
2957 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
2958 CORBA::Boolean theCopy,
2960 ::SMESH_Mesh* theTargetMesh)
2964 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
2965 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
2967 if ( theTargetMesh )
2971 switch ( theMirrorType ) {
2972 case SMESH::SMESH_MeshEditor::POINT:
2973 aTrsf.SetMirror( P );
2975 case SMESH::SMESH_MeshEditor::AXIS:
2976 aTrsf.SetMirror( gp_Ax1( P, V ));
2979 aTrsf.SetMirror( gp_Ax2( P, V ));
2982 TIDSortedElemSet copyElements;
2983 TPreviewMesh tmpMesh;
2984 TIDSortedElemSet* workElements = & theElements;
2985 SMESH_Mesh* mesh = myMesh;
2987 if ( myPreviewMode )
2989 tmpMesh.Copy( theElements, copyElements);
2990 if ( !theCopy && !theTargetMesh )
2992 TIDSortedElemSet elemsAround, elemsAroundCopy;
2993 getElementsAround( theElements, GetMeshDS(), elemsAround );
2994 tmpMesh.Copy( elemsAround, elemsAroundCopy);
2997 workElements = & copyElements;
2998 theMakeGroups = false;
3001 ::SMESH_MeshEditor anEditor( mesh );
3002 ::SMESH_MeshEditor::PGroupIDs groupIds =
3003 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3005 if(theCopy || myPreviewMode)
3006 storeResult(anEditor);
3009 myMesh->SetIsModified( true );
3010 myMesh->GetMeshDS()->Modified();
3012 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3015 //=======================================================================
3018 //=======================================================================
3020 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3021 const SMESH::AxisStruct & theAxis,
3022 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3023 CORBA::Boolean theCopy)
3025 if ( !myPreviewMode ) {
3026 TPythonDump() << this << ".Mirror( "
3027 << theIDsOfElements << ", "
3029 << mirrorTypeName(theMirrorType) << ", "
3032 if ( theIDsOfElements.length() > 0 )
3034 TIDSortedElemSet elements;
3035 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3036 mirror(elements, theAxis, theMirrorType, theCopy, false);
3041 //=======================================================================
3042 //function : MirrorObject
3044 //=======================================================================
3046 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3047 const SMESH::AxisStruct & theAxis,
3048 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3049 CORBA::Boolean theCopy)
3051 if ( !myPreviewMode ) {
3052 TPythonDump() << this << ".MirrorObject( "
3053 << theObject << ", "
3055 << mirrorTypeName(theMirrorType) << ", "
3058 TIDSortedElemSet elements;
3060 bool emptyIfIsMesh = myPreviewMode ? false : true;
3062 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3063 mirror(elements, theAxis, theMirrorType, theCopy, false);
3066 //=======================================================================
3067 //function : MirrorMakeGroups
3069 //=======================================================================
3071 SMESH::ListOfGroups*
3072 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3073 const SMESH::AxisStruct& theMirror,
3074 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3076 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3078 SMESH::ListOfGroups * aGroups = 0;
3079 if ( theIDsOfElements.length() > 0 )
3081 TIDSortedElemSet elements;
3082 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3083 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3085 if (!myPreviewMode) {
3086 DumpGroupsList(aPythonDump, aGroups);
3087 aPythonDump << this << ".MirrorMakeGroups( "
3088 << theIDsOfElements << ", "
3089 << theMirror << ", "
3090 << mirrorTypeName(theMirrorType) << " )";
3095 //=======================================================================
3096 //function : MirrorObjectMakeGroups
3098 //=======================================================================
3100 SMESH::ListOfGroups*
3101 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3102 const SMESH::AxisStruct& theMirror,
3103 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3105 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3107 SMESH::ListOfGroups * aGroups = 0;
3108 TIDSortedElemSet elements;
3109 if ( idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3110 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3114 DumpGroupsList(aPythonDump,aGroups);
3115 aPythonDump << this << ".MirrorObjectMakeGroups( "
3116 << theObject << ", "
3117 << theMirror << ", "
3118 << mirrorTypeName(theMirrorType) << " )";
3123 //=======================================================================
3124 //function : MirrorMakeMesh
3126 //=======================================================================
3128 SMESH::SMESH_Mesh_ptr
3129 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
3130 const SMESH::AxisStruct& theMirror,
3131 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3132 CORBA::Boolean theCopyGroups,
3133 const char* theMeshName)
3135 SMESH_Mesh_i* mesh_i;
3136 SMESH::SMESH_Mesh_var mesh;
3137 { // open new scope to dump "MakeMesh" command
3138 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3140 TPythonDump pydump; // to prevent dump at mesh creation
3142 mesh = makeMesh( theMeshName );
3143 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3144 if (mesh_i && theIDsOfElements.length() > 0 )
3146 TIDSortedElemSet elements;
3147 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3148 mirror(elements, theMirror, theMirrorType,
3149 false, theCopyGroups, & mesh_i->GetImpl());
3150 mesh_i->CreateGroupServants();
3153 if (!myPreviewMode) {
3154 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
3155 << theIDsOfElements << ", "
3156 << theMirror << ", "
3157 << mirrorTypeName(theMirrorType) << ", "
3158 << theCopyGroups << ", '"
3159 << theMeshName << "' )";
3164 if (!myPreviewMode && mesh_i)
3165 mesh_i->GetGroups();
3167 return mesh._retn();
3170 //=======================================================================
3171 //function : MirrorObjectMakeMesh
3173 //=======================================================================
3175 SMESH::SMESH_Mesh_ptr
3176 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3177 const SMESH::AxisStruct& theMirror,
3178 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3179 CORBA::Boolean theCopyGroups,
3180 const char* theMeshName)
3182 SMESH_Mesh_i* mesh_i;
3183 SMESH::SMESH_Mesh_var mesh;
3184 { // open new scope to dump "MakeMesh" command
3185 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3187 TPythonDump pydump; // to prevent dump at mesh creation
3189 mesh = makeMesh( theMeshName );
3190 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3191 TIDSortedElemSet elements;
3193 idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3195 mirror(elements, theMirror, theMirrorType,
3196 false, theCopyGroups, & mesh_i->GetImpl());
3197 mesh_i->CreateGroupServants();
3199 if (!myPreviewMode) {
3200 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
3201 << theObject << ", "
3202 << theMirror << ", "
3203 << mirrorTypeName(theMirrorType) << ", "
3204 << theCopyGroups << ", '"
3205 << theMeshName << "' )";
3210 if (!myPreviewMode && mesh_i)
3211 mesh_i->GetGroups();
3213 return mesh._retn();
3216 //=======================================================================
3217 //function : translate
3219 //=======================================================================
3221 SMESH::ListOfGroups*
3222 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
3223 const SMESH::DirStruct & theVector,
3224 CORBA::Boolean theCopy,
3226 ::SMESH_Mesh* theTargetMesh)
3230 if ( theTargetMesh )
3234 const SMESH::PointStruct * P = &theVector.PS;
3235 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
3237 TIDSortedElemSet copyElements;
3238 TIDSortedElemSet* workElements = &theElements;
3239 TPreviewMesh tmpMesh;
3240 SMESH_Mesh* mesh = myMesh;
3242 if ( myPreviewMode )
3244 tmpMesh.Copy( theElements, copyElements);
3245 if ( !theCopy && !theTargetMesh )
3247 TIDSortedElemSet elemsAround, elemsAroundCopy;
3248 getElementsAround( theElements, GetMeshDS(), elemsAround );
3249 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3252 workElements = & copyElements;
3253 theMakeGroups = false;
3256 ::SMESH_MeshEditor anEditor( mesh );
3257 ::SMESH_MeshEditor::PGroupIDs groupIds =
3258 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3260 if(theCopy || myPreviewMode)
3261 storeResult(anEditor);
3264 myMesh->GetMeshDS()->Modified();
3265 myMesh->SetIsModified( true );
3268 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3271 //=======================================================================
3272 //function : Translate
3274 //=======================================================================
3276 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
3277 const SMESH::DirStruct & theVector,
3278 CORBA::Boolean theCopy)
3280 if (!myPreviewMode) {
3281 TPythonDump() << this << ".Translate( "
3282 << theIDsOfElements << ", "
3283 << theVector << ", "
3286 if (theIDsOfElements.length()) {
3287 TIDSortedElemSet elements;
3288 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3289 translate(elements, theVector, theCopy, false);
3293 //=======================================================================
3294 //function : TranslateObject
3296 //=======================================================================
3298 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
3299 const SMESH::DirStruct & theVector,
3300 CORBA::Boolean theCopy)
3302 if (!myPreviewMode) {
3303 TPythonDump() << this << ".TranslateObject( "
3304 << theObject << ", "
3305 << theVector << ", "
3308 TIDSortedElemSet elements;
3310 bool emptyIfIsMesh = myPreviewMode ? false : true;
3312 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3313 translate(elements, theVector, theCopy, false);
3316 //=======================================================================
3317 //function : TranslateMakeGroups
3319 //=======================================================================
3321 SMESH::ListOfGroups*
3322 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
3323 const SMESH::DirStruct& theVector)
3325 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3327 SMESH::ListOfGroups * aGroups = 0;
3328 if (theIDsOfElements.length()) {
3329 TIDSortedElemSet elements;
3330 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3331 aGroups = translate(elements,theVector,true,true);
3333 if (!myPreviewMode) {
3334 DumpGroupsList(aPythonDump, aGroups);
3335 aPythonDump << this << ".TranslateMakeGroups( "
3336 << theIDsOfElements << ", "
3337 << theVector << " )";
3342 //=======================================================================
3343 //function : TranslateObjectMakeGroups
3345 //=======================================================================
3347 SMESH::ListOfGroups*
3348 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3349 const SMESH::DirStruct& theVector)
3351 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3353 SMESH::ListOfGroups * aGroups = 0;
3354 TIDSortedElemSet elements;
3355 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3356 aGroups = translate(elements, theVector, true, true);
3358 if (!myPreviewMode) {
3359 DumpGroupsList(aPythonDump, aGroups);
3360 aPythonDump << this << ".TranslateObjectMakeGroups( "
3361 << theObject << ", "
3362 << theVector << " )";
3367 //=======================================================================
3368 //function : TranslateMakeMesh
3370 //=======================================================================
3372 SMESH::SMESH_Mesh_ptr
3373 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
3374 const SMESH::DirStruct& theVector,
3375 CORBA::Boolean theCopyGroups,
3376 const char* theMeshName)
3378 SMESH_Mesh_i* mesh_i;
3379 SMESH::SMESH_Mesh_var mesh;
3381 { // open new scope to dump "MakeMesh" command
3382 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3384 TPythonDump pydump; // to prevent dump at mesh creation
3386 mesh = makeMesh( theMeshName );
3387 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3389 if ( mesh_i && theIDsOfElements.length() )
3391 TIDSortedElemSet elements;
3392 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3393 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
3394 mesh_i->CreateGroupServants();
3397 if ( !myPreviewMode ) {
3398 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
3399 << theIDsOfElements << ", "
3400 << theVector << ", "
3401 << theCopyGroups << ", '"
3402 << theMeshName << "' )";
3407 if (!myPreviewMode && mesh_i)
3408 mesh_i->GetGroups();
3410 return mesh._retn();
3413 //=======================================================================
3414 //function : TranslateObjectMakeMesh
3416 //=======================================================================
3418 SMESH::SMESH_Mesh_ptr
3419 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3420 const SMESH::DirStruct& theVector,
3421 CORBA::Boolean theCopyGroups,
3422 const char* theMeshName)
3424 SMESH_Mesh_i* mesh_i;
3425 SMESH::SMESH_Mesh_var mesh;
3426 { // open new scope to dump "MakeMesh" command
3427 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3429 TPythonDump pydump; // to prevent dump at mesh creation
3430 mesh = makeMesh( theMeshName );
3431 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3433 TIDSortedElemSet elements;
3435 idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3437 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
3438 mesh_i->CreateGroupServants();
3440 if ( !myPreviewMode ) {
3441 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
3442 << theObject << ", "
3443 << theVector << ", "
3444 << theCopyGroups << ", '"
3445 << theMeshName << "' )";
3450 if (!myPreviewMode && mesh_i)
3451 mesh_i->GetGroups();
3453 return mesh._retn();
3456 //=======================================================================
3459 //=======================================================================
3461 SMESH::ListOfGroups*
3462 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
3463 const SMESH::AxisStruct & theAxis,
3464 CORBA::Double theAngle,
3465 CORBA::Boolean theCopy,
3467 ::SMESH_Mesh* theTargetMesh)
3471 if ( theTargetMesh )
3474 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3475 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3478 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
3480 TIDSortedElemSet copyElements;
3481 TIDSortedElemSet* workElements = &theElements;
3482 TPreviewMesh tmpMesh;
3483 SMESH_Mesh* mesh = myMesh;
3485 if ( myPreviewMode ) {
3486 tmpMesh.Copy( theElements, copyElements );
3487 if ( !theCopy && !theTargetMesh )
3489 TIDSortedElemSet elemsAround, elemsAroundCopy;
3490 getElementsAround( theElements, GetMeshDS(), elemsAround );
3491 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3494 workElements = ©Elements;
3495 theMakeGroups = false;
3498 ::SMESH_MeshEditor anEditor( mesh );
3499 ::SMESH_MeshEditor::PGroupIDs groupIds =
3500 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3502 if(theCopy || myPreviewMode)
3503 storeResult(anEditor);
3506 myMesh->GetMeshDS()->Modified();
3507 myMesh->SetIsModified( true );
3510 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3513 //=======================================================================
3516 //=======================================================================
3518 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
3519 const SMESH::AxisStruct & theAxis,
3520 CORBA::Double theAngle,
3521 CORBA::Boolean theCopy)
3523 if (!myPreviewMode) {
3524 TPythonDump() << this << ".Rotate( "
3525 << theIDsOfElements << ", "
3530 if (theIDsOfElements.length() > 0)
3532 TIDSortedElemSet elements;
3533 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3534 rotate(elements,theAxis,theAngle,theCopy,false);
3538 //=======================================================================
3539 //function : RotateObject
3541 //=======================================================================
3543 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
3544 const SMESH::AxisStruct & theAxis,
3545 CORBA::Double theAngle,
3546 CORBA::Boolean theCopy)
3548 if ( !myPreviewMode ) {
3549 TPythonDump() << this << ".RotateObject( "
3550 << theObject << ", "
3555 TIDSortedElemSet elements;
3556 bool emptyIfIsMesh = myPreviewMode ? false : true;
3557 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3558 rotate(elements,theAxis,theAngle,theCopy,false);
3561 //=======================================================================
3562 //function : RotateMakeGroups
3564 //=======================================================================
3566 SMESH::ListOfGroups*
3567 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
3568 const SMESH::AxisStruct& theAxis,
3569 CORBA::Double theAngle)
3571 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3573 SMESH::ListOfGroups * aGroups = 0;
3574 if (theIDsOfElements.length() > 0)
3576 TIDSortedElemSet elements;
3577 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3578 aGroups = rotate(elements,theAxis,theAngle,true,true);
3580 if (!myPreviewMode) {
3581 DumpGroupsList(aPythonDump, aGroups);
3582 aPythonDump << this << ".RotateMakeGroups( "
3583 << theIDsOfElements << ", "
3585 << theAngle << " )";
3590 //=======================================================================
3591 //function : RotateObjectMakeGroups
3593 //=======================================================================
3595 SMESH::ListOfGroups*
3596 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3597 const SMESH::AxisStruct& theAxis,
3598 CORBA::Double theAngle)
3600 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3602 SMESH::ListOfGroups * aGroups = 0;
3603 TIDSortedElemSet elements;
3604 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3605 aGroups = rotate(elements, theAxis, theAngle, true, true);
3607 if (!myPreviewMode) {
3608 DumpGroupsList(aPythonDump, aGroups);
3609 aPythonDump << this << ".RotateObjectMakeGroups( "
3610 << theObject << ", "
3612 << theAngle << " )";
3617 //=======================================================================
3618 //function : RotateMakeMesh
3620 //=======================================================================
3622 SMESH::SMESH_Mesh_ptr
3623 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
3624 const SMESH::AxisStruct& theAxis,
3625 CORBA::Double theAngleInRadians,
3626 CORBA::Boolean theCopyGroups,
3627 const char* theMeshName)
3629 SMESH::SMESH_Mesh_var mesh;
3630 SMESH_Mesh_i* mesh_i;
3632 { // open new scope to dump "MakeMesh" command
3633 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3635 TPythonDump pydump; // to prevent dump at mesh creation
3637 mesh = makeMesh( theMeshName );
3638 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3640 if ( mesh_i && theIDsOfElements.length() > 0 )
3642 TIDSortedElemSet elements;
3643 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3644 rotate(elements, theAxis, theAngleInRadians,
3645 false, theCopyGroups, & mesh_i->GetImpl());
3646 mesh_i->CreateGroupServants();
3648 if ( !myPreviewMode ) {
3649 pydump << mesh << " = " << this << ".RotateMakeMesh( "
3650 << theIDsOfElements << ", "
3652 << theAngleInRadians << ", "
3653 << theCopyGroups << ", '"
3654 << theMeshName << "' )";
3659 if (!myPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
3660 mesh_i->GetGroups();
3662 return mesh._retn();
3665 //=======================================================================
3666 //function : RotateObjectMakeMesh
3668 //=======================================================================
3670 SMESH::SMESH_Mesh_ptr
3671 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3672 const SMESH::AxisStruct& theAxis,
3673 CORBA::Double theAngleInRadians,
3674 CORBA::Boolean theCopyGroups,
3675 const char* theMeshName)
3677 SMESH::SMESH_Mesh_var mesh;
3678 SMESH_Mesh_i* mesh_i;
3680 {// open new scope to dump "MakeMesh" command
3681 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3683 TPythonDump pydump; // to prevent dump at mesh creation
3684 mesh = makeMesh( theMeshName );
3685 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3687 TIDSortedElemSet elements;
3689 idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3691 rotate(elements, theAxis, theAngleInRadians,
3692 false, theCopyGroups, & mesh_i->GetImpl());
3693 mesh_i->CreateGroupServants();
3695 if ( !myPreviewMode ) {
3696 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
3697 << theObject << ", "
3699 << theAngleInRadians << ", "
3700 << theCopyGroups << ", '"
3701 << theMeshName << "' )";
3706 if (!myPreviewMode && mesh_i)
3707 mesh_i->GetGroups();
3709 return mesh._retn();
3712 //=======================================================================
3715 //=======================================================================
3717 SMESH::ListOfGroups*
3718 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
3719 const SMESH::PointStruct& thePoint,
3720 const SMESH::double_array& theScaleFact,
3721 CORBA::Boolean theCopy,
3723 ::SMESH_Mesh* theTargetMesh)
3726 if ( theScaleFact.length() < 1 )
3727 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
3728 if ( theScaleFact.length() == 2 )
3729 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
3731 if ( theTargetMesh )
3734 TIDSortedElemSet elements;
3735 bool emptyIfIsMesh = myPreviewMode ? false : true;
3736 if ( !idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3741 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
3742 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
3744 double tol = std::numeric_limits<double>::max();
3746 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
3747 0, S[1], 0, thePoint.y * (1-S[1]),
3748 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
3750 TIDSortedElemSet copyElements;
3751 TPreviewMesh tmpMesh;
3752 TIDSortedElemSet* workElements = &elements;
3753 SMESH_Mesh* mesh = myMesh;
3755 if ( myPreviewMode )
3757 tmpMesh.Copy( elements, copyElements);
3758 if ( !theCopy && !theTargetMesh )
3760 TIDSortedElemSet elemsAround, elemsAroundCopy;
3761 getElementsAround( elements, GetMeshDS(), elemsAround );
3762 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3765 workElements = & copyElements;
3766 theMakeGroups = false;
3769 ::SMESH_MeshEditor anEditor( mesh );
3770 ::SMESH_MeshEditor::PGroupIDs groupIds =
3771 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3773 if(theCopy || myPreviewMode )
3774 storeResult(anEditor);
3777 myMesh->GetMeshDS()->Modified();
3778 myMesh->SetIsModified( true );
3780 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3783 //=======================================================================
3786 //=======================================================================
3788 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
3789 const SMESH::PointStruct& thePoint,
3790 const SMESH::double_array& theScaleFact,
3791 CORBA::Boolean theCopy)
3793 if ( !myPreviewMode ) {
3794 TPythonDump() << this << ".Scale( "
3795 << theObject << ", "
3796 << "SMESH.PointStruct( " << thePoint.x << ", "
3797 << thePoint.y << ", " << thePoint.z << " ) ,"
3798 << theScaleFact << ", "
3801 scale(theObject, thePoint, theScaleFact, theCopy, false);
3805 //=======================================================================
3806 //function : ScaleMakeGroups
3808 //=======================================================================
3810 SMESH::ListOfGroups*
3811 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3812 const SMESH::PointStruct& thePoint,
3813 const SMESH::double_array& theScaleFact)
3815 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3817 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
3818 if (!myPreviewMode) {
3819 DumpGroupsList(aPythonDump, aGroups);
3820 aPythonDump << this << ".Scale("
3822 << "SMESH.PointStruct(" <<thePoint.x << ","
3823 << thePoint.y << "," << thePoint.z << "),"
3824 << theScaleFact << ",True,True)";
3830 //=======================================================================
3831 //function : ScaleMakeMesh
3833 //=======================================================================
3835 SMESH::SMESH_Mesh_ptr
3836 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3837 const SMESH::PointStruct& thePoint,
3838 const SMESH::double_array& theScaleFact,
3839 CORBA::Boolean theCopyGroups,
3840 const char* theMeshName)
3842 SMESH_Mesh_i* mesh_i;
3843 SMESH::SMESH_Mesh_var mesh;
3844 { // open new scope to dump "MakeMesh" command
3845 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3847 TPythonDump pydump; // to prevent dump at mesh creation
3848 mesh = makeMesh( theMeshName );
3849 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3853 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
3854 mesh_i->CreateGroupServants();
3856 if ( !myPreviewMode )
3857 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
3858 << theObject << ", "
3859 << "SMESH.PointStruct( " << thePoint.x << ", "
3860 << thePoint.y << ", " << thePoint.z << " ) ,"
3861 << theScaleFact << ", "
3862 << theCopyGroups << ", '"
3863 << theMeshName << "' )";
3867 if (!myPreviewMode && mesh_i)
3868 mesh_i->GetGroups();
3870 return mesh._retn();
3874 //=======================================================================
3875 //function : FindCoincidentNodes
3877 //=======================================================================
3879 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance,
3880 SMESH::array_of_long_array_out GroupsOfNodes)
3884 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3885 ::SMESH_MeshEditor anEditor( myMesh );
3886 TIDSortedNodeSet nodes; // no input nodes
3887 anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
3889 GroupsOfNodes = new SMESH::array_of_long_array;
3890 GroupsOfNodes->length( aListOfListOfNodes.size() );
3891 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
3892 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
3893 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
3894 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
3895 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
3896 aGroup.length( aListOfNodes.size() );
3897 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
3898 aGroup[ j ] = (*lIt)->GetID();
3900 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
3901 << Tolerance << " )";
3904 //=======================================================================
3905 //function : FindCoincidentNodesOnPart
3907 //=======================================================================
3908 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
3909 CORBA::Double Tolerance,
3910 SMESH::array_of_long_array_out GroupsOfNodes)
3914 TIDSortedNodeSet nodes;
3915 idSourceToNodeSet( theObject, GetMeshDS(), nodes );
3917 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3918 ::SMESH_MeshEditor anEditor( myMesh );
3920 anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
3922 GroupsOfNodes = new SMESH::array_of_long_array;
3923 GroupsOfNodes->length( aListOfListOfNodes.size() );
3924 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
3925 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
3927 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
3928 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
3929 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
3930 aGroup.length( aListOfNodes.size() );
3931 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
3932 aGroup[ j ] = (*lIt)->GetID();
3934 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
3936 << Tolerance << " )";
3939 //================================================================================
3941 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
3942 * ExceptSubMeshOrGroups
3944 //================================================================================
3946 void SMESH_MeshEditor_i::
3947 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
3948 CORBA::Double theTolerance,
3949 SMESH::array_of_long_array_out theGroupsOfNodes,
3950 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups)
3954 TIDSortedNodeSet nodes;
3955 idSourceToNodeSet( theObject, GetMeshDS(), nodes );
3957 for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
3959 TIDSortedNodeSet exceptNodes;
3960 idSourceToNodeSet( theExceptSubMeshOrGroups[i], GetMeshDS(), exceptNodes );
3961 TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
3962 for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
3963 nodes.erase( *avoidNode );
3965 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3966 ::SMESH_MeshEditor anEditor( myMesh );
3968 anEditor.FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
3970 theGroupsOfNodes = new SMESH::array_of_long_array;
3971 theGroupsOfNodes->length( aListOfListOfNodes.size() );
3972 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
3973 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
3975 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
3976 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
3977 SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
3978 aGroup.length( aListOfNodes.size() );
3979 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
3980 aGroup[ j ] = (*lIt)->GetID();
3982 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
3984 << theTolerance << ", "
3985 << theExceptSubMeshOrGroups << " )";
3988 //=======================================================================
3989 //function : MergeNodes
3991 //=======================================================================
3993 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
3997 SMESHDS_Mesh* aMesh = GetMeshDS();
3999 TPythonDump aTPythonDump;
4000 aTPythonDump << this << ".MergeNodes([";
4001 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4002 for (int i = 0; i < GroupsOfNodes.length(); i++)
4004 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
4005 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
4006 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
4007 for ( int j = 0; j < aNodeGroup.length(); j++ )
4009 CORBA::Long index = aNodeGroup[ j ];
4010 const SMDS_MeshNode * node = aMesh->FindNode(index);
4012 aListOfNodes.push_back( node );
4014 if ( aListOfNodes.size() < 2 )
4015 aListOfListOfNodes.pop_back();
4017 if ( i > 0 ) aTPythonDump << ", ";
4018 aTPythonDump << aNodeGroup;
4020 ::SMESH_MeshEditor anEditor( myMesh );
4021 anEditor.MergeNodes( aListOfListOfNodes );
4023 aTPythonDump << "])";
4024 myMesh->GetMeshDS()->Modified();
4025 myMesh->SetIsModified( true );
4028 //=======================================================================
4029 //function : FindEqualElements
4031 //=======================================================================
4032 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
4033 SMESH::array_of_long_array_out GroupsOfElementsID)
4037 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
4038 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
4040 typedef list<int> TListOfIDs;
4041 set<const SMDS_MeshElement*> elems;
4042 SMESH::long_array_var aElementsId = theObject->GetIDs();
4043 SMESHDS_Mesh* aMesh = GetMeshDS();
4045 for(int i = 0; i < aElementsId->length(); i++) {
4046 CORBA::Long anID = aElementsId[i];
4047 const SMDS_MeshElement * elem = aMesh->FindElement(anID);
4053 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4054 ::SMESH_MeshEditor anEditor( myMesh );
4055 anEditor.FindEqualElements( elems, aListOfListOfElementsID );
4057 GroupsOfElementsID = new SMESH::array_of_long_array;
4058 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
4060 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt = aListOfListOfElementsID.begin();
4061 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j) {
4062 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
4063 TListOfIDs& listOfIDs = *arraysIt;
4064 aGroup.length( listOfIDs.size() );
4065 TListOfIDs::iterator idIt = listOfIDs.begin();
4066 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k ) {
4067 aGroup[ k ] = *idIt;
4071 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
4076 //=======================================================================
4077 //function : MergeElements
4079 //=======================================================================
4081 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
4085 TPythonDump aTPythonDump;
4086 aTPythonDump << this << ".MergeElements( [";
4088 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4090 for (int i = 0; i < GroupsOfElementsID.length(); i++) {
4091 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
4092 aListOfListOfElementsID.push_back( list< int >() );
4093 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
4094 for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
4095 CORBA::Long id = anElemsIDGroup[ j ];
4096 aListOfElemsID.push_back( id );
4098 if ( aListOfElemsID.size() < 2 )
4099 aListOfListOfElementsID.pop_back();
4100 if ( i > 0 ) aTPythonDump << ", ";
4101 aTPythonDump << anElemsIDGroup;
4104 ::SMESH_MeshEditor anEditor( myMesh );
4105 anEditor.MergeElements(aListOfListOfElementsID);
4106 myMesh->GetMeshDS()->Modified();
4107 myMesh->SetIsModified( true );
4109 aTPythonDump << "] )";
4112 //=======================================================================
4113 //function : MergeEqualElements
4115 //=======================================================================
4117 void SMESH_MeshEditor_i::MergeEqualElements()
4121 ::SMESH_MeshEditor anEditor( myMesh );
4122 anEditor.MergeEqualElements();
4124 TPythonDump() << this << ".MergeEqualElements()";
4127 //=============================================================================
4129 * Move the node to a given point
4131 //=============================================================================
4133 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
4138 initData(/*deleteSearchers=*/false);
4140 const SMDS_MeshNode * node = GetMeshDS()->FindNode( NodeID );
4144 if ( theNodeSearcher )
4145 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4147 if ( myPreviewMode ) // make preview data
4149 // in a preview mesh, make edges linked to a node
4150 TPreviewMesh tmpMesh;
4151 TIDSortedElemSet linkedNodes;
4152 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4153 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4154 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
4155 for ( ; nIt != linkedNodes.end(); ++nIt )
4157 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
4158 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
4162 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
4163 // fill preview data
4164 ::SMESH_MeshEditor anEditor( & tmpMesh );
4165 storeResult( anEditor );
4167 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4168 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4170 GetMeshDS()->MoveNode(node, x, y, z);
4172 if ( !myPreviewMode )
4174 // Update Python script
4175 TPythonDump() << "isDone = " << this << ".MoveNode( "
4176 << NodeID << ", " << x << ", " << y << ", " << z << " )";
4177 myMesh->GetMeshDS()->Modified();
4178 myMesh->SetIsModified( true );
4184 //================================================================================
4186 * \brief Return ID of node closest to a given point
4188 //================================================================================
4190 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
4194 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4196 if ( !theNodeSearcher ) {
4197 ::SMESH_MeshEditor anEditor( myMesh );
4198 theNodeSearcher = anEditor.GetNodeSearcher();
4201 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
4202 return node->GetID();
4207 //================================================================================
4209 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
4210 * move the node closest to the point to point's location and return ID of the node
4212 //================================================================================
4214 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
4217 CORBA::Long theNodeID)
4219 // We keep theNodeSearcher until any mesh modification:
4220 // 1) initData() deletes theNodeSearcher at any edition,
4221 // 2) TSearchersDeleter - at any mesh compute event and mesh change
4223 initData(/*deleteSearchers=*/false);
4225 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4227 int nodeID = theNodeID;
4228 const SMDS_MeshNode* node = GetMeshDS()->FindNode( nodeID );
4229 if ( !node ) // preview moving node
4231 if ( !theNodeSearcher ) {
4232 ::SMESH_MeshEditor anEditor( myMesh );
4233 theNodeSearcher = anEditor.GetNodeSearcher();
4236 node = theNodeSearcher->FindClosestTo( p );
4239 nodeID = node->GetID();
4240 if ( myPreviewMode ) // make preview data
4242 // in a preview mesh, make edges linked to a node
4243 TPreviewMesh tmpMesh;
4244 TIDSortedElemSet linkedNodes;
4245 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4246 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4247 for ( ; nIt != linkedNodes.end(); ++nIt )
4249 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
4250 tmpMesh.Copy( &edge );
4253 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
4255 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
4256 // fill preview data
4257 ::SMESH_MeshEditor anEditor( & tmpMesh );
4258 storeResult( anEditor );
4260 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4262 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4266 GetMeshDS()->MoveNode(node, x, y, z);
4270 if ( !myPreviewMode )
4272 TPythonDump() << "nodeID = " << this
4273 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
4274 << ", " << nodeID << " )";
4276 myMesh->GetMeshDS()->Modified();
4277 myMesh->SetIsModified( true );
4283 //=======================================================================
4285 * Return elements of given type where the given point is IN or ON.
4287 * 'ALL' type means elements of any type excluding nodes
4289 //=======================================================================
4291 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
4294 SMESH::ElementType type)
4296 SMESH::long_array_var res = new SMESH::long_array;
4297 vector< const SMDS_MeshElement* > foundElems;
4299 theSearchersDeleter.Set( myMesh );
4300 if ( !theElementSearcher ) {
4301 ::SMESH_MeshEditor anEditor( myMesh );
4302 theElementSearcher = anEditor.GetElementSearcher();
4304 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4305 SMDSAbs_ElementType( type ),
4307 res->length( foundElems.size() );
4308 for ( int i = 0; i < foundElems.size(); ++i )
4309 res[i] = foundElems[i]->GetID();
4311 if ( !myPreviewMode ) // call from tui
4312 TPythonDump() << "res = " << this << ".FindElementsByPoint( "
4321 //=======================================================================
4322 //function : FindAmongElementsByPoint
4323 //purpose : Searching among the given elements, return elements of given type
4324 // where the given point is IN or ON.
4325 // 'ALL' type means elements of any type excluding nodes
4326 //=======================================================================
4329 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
4333 SMESH::ElementType type)
4335 SMESH::long_array_var res = new SMESH::long_array;
4337 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
4338 if ( types->length() == 1 && // a part contains only nodes or 0D elements
4339 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D ) &&
4340 type != types[0] ) // but search of elements of dim > 0
4343 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
4344 return FindElementsByPoint( x,y,z, type );
4346 string partIOR = SMESH_Gen_i::GetORB()->object_to_string( elementIDs );
4347 if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( elementIDs ))
4348 // take into account passible group modification
4349 partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() );
4350 partIOR += SMESH_Comment( type );
4352 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
4354 theSearchersDeleter.Set( myMesh, partIOR );
4355 if ( !theElementSearcher )
4357 // create a searcher from elementIDs
4358 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
4359 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
4361 if ( !idSourceToSet( elementIDs, meshDS, elements,
4362 SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
4365 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
4366 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
4368 ::SMESH_MeshEditor anEditor( myMesh );
4369 theElementSearcher = anEditor.GetElementSearcher(elemsIt);
4372 vector< const SMDS_MeshElement* > foundElems;
4374 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4375 SMDSAbs_ElementType( type ),
4377 res->length( foundElems.size() );
4378 for ( int i = 0; i < foundElems.size(); ++i )
4379 res[i] = foundElems[i]->GetID();
4381 if ( !myPreviewMode ) // call from tui
4382 TPythonDump() << "res = " << this << ".FindAmongElementsByPoint( "
4383 << elementIDs << ", "
4392 //=======================================================================
4393 //function : GetPointState
4394 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
4395 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
4396 //=======================================================================
4398 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
4402 theSearchersDeleter.Set( myMesh );
4403 if ( !theElementSearcher ) {
4404 ::SMESH_MeshEditor anEditor( myMesh );
4405 theElementSearcher = anEditor.GetElementSearcher();
4407 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
4410 //=======================================================================
4411 //function : convError
4413 //=======================================================================
4415 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
4417 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
4421 RETCASE( SEW_BORDER1_NOT_FOUND );
4422 RETCASE( SEW_BORDER2_NOT_FOUND );
4423 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
4424 RETCASE( SEW_BAD_SIDE_NODES );
4425 RETCASE( SEW_VOLUMES_TO_SPLIT );
4426 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
4427 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
4428 RETCASE( SEW_BAD_SIDE1_NODES );
4429 RETCASE( SEW_BAD_SIDE2_NODES );
4431 return SMESH::SMESH_MeshEditor::SEW_OK;
4434 //=======================================================================
4435 //function : SewFreeBorders
4437 //=======================================================================
4439 SMESH::SMESH_MeshEditor::Sew_Error
4440 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
4441 CORBA::Long SecondNodeID1,
4442 CORBA::Long LastNodeID1,
4443 CORBA::Long FirstNodeID2,
4444 CORBA::Long SecondNodeID2,
4445 CORBA::Long LastNodeID2,
4446 CORBA::Boolean CreatePolygons,
4447 CORBA::Boolean CreatePolyedrs)
4451 SMESHDS_Mesh* aMesh = GetMeshDS();
4453 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4454 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4455 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4456 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4457 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4458 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
4460 if (!aBorderFirstNode ||
4461 !aBorderSecondNode||
4463 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4464 if (!aSide2FirstNode ||
4465 !aSide2SecondNode ||
4467 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4469 TPythonDump() << "error = " << this << ".SewFreeBorders( "
4470 << FirstNodeID1 << ", "
4471 << SecondNodeID1 << ", "
4472 << LastNodeID1 << ", "
4473 << FirstNodeID2 << ", "
4474 << SecondNodeID2 << ", "
4475 << LastNodeID2 << ", "
4476 << CreatePolygons<< ", "
4477 << CreatePolyedrs<< " )";
4479 ::SMESH_MeshEditor anEditor( myMesh );
4480 SMESH::SMESH_MeshEditor::Sew_Error error =
4481 convError( anEditor.SewFreeBorder (aBorderFirstNode,
4491 storeResult(anEditor);
4493 myMesh->GetMeshDS()->Modified();
4494 myMesh->SetIsModified( true );
4500 //=======================================================================
4501 //function : SewConformFreeBorders
4503 //=======================================================================
4505 SMESH::SMESH_MeshEditor::Sew_Error
4506 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
4507 CORBA::Long SecondNodeID1,
4508 CORBA::Long LastNodeID1,
4509 CORBA::Long FirstNodeID2,
4510 CORBA::Long SecondNodeID2)
4514 SMESHDS_Mesh* aMesh = GetMeshDS();
4516 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4517 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4518 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4519 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4520 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4521 const SMDS_MeshNode* aSide2ThirdNode = 0;
4523 if (!aBorderFirstNode ||
4524 !aBorderSecondNode||
4526 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4527 if (!aSide2FirstNode ||
4529 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4531 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
4532 << FirstNodeID1 << ", "
4533 << SecondNodeID1 << ", "
4534 << LastNodeID1 << ", "
4535 << FirstNodeID2 << ", "
4536 << SecondNodeID2 << " )";
4538 ::SMESH_MeshEditor anEditor( myMesh );
4539 SMESH::SMESH_MeshEditor::Sew_Error error =
4540 convError( anEditor.SewFreeBorder (aBorderFirstNode,
4549 storeResult(anEditor);
4551 myMesh->GetMeshDS()->Modified();
4552 myMesh->SetIsModified( true );
4558 //=======================================================================
4559 //function : SewBorderToSide
4561 //=======================================================================
4563 SMESH::SMESH_MeshEditor::Sew_Error
4564 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
4565 CORBA::Long SecondNodeIDOnFreeBorder,
4566 CORBA::Long LastNodeIDOnFreeBorder,
4567 CORBA::Long FirstNodeIDOnSide,
4568 CORBA::Long LastNodeIDOnSide,
4569 CORBA::Boolean CreatePolygons,
4570 CORBA::Boolean CreatePolyedrs)
4574 SMESHDS_Mesh* aMesh = GetMeshDS();
4576 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
4577 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
4578 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
4579 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
4580 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
4581 const SMDS_MeshNode* aSide2ThirdNode = 0;
4583 if (!aBorderFirstNode ||
4584 !aBorderSecondNode||
4586 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4587 if (!aSide2FirstNode ||
4589 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
4591 TPythonDump() << "error = " << this << ".SewBorderToSide( "
4592 << FirstNodeIDOnFreeBorder << ", "
4593 << SecondNodeIDOnFreeBorder << ", "
4594 << LastNodeIDOnFreeBorder << ", "
4595 << FirstNodeIDOnSide << ", "
4596 << LastNodeIDOnSide << ", "
4597 << CreatePolygons << ", "
4598 << CreatePolyedrs << ") ";
4600 ::SMESH_MeshEditor anEditor( myMesh );
4601 SMESH::SMESH_MeshEditor::Sew_Error error =
4602 convError( anEditor.SewFreeBorder (aBorderFirstNode,
4612 storeResult(anEditor);
4614 myMesh->GetMeshDS()->Modified();
4615 myMesh->SetIsModified( true );
4621 //=======================================================================
4622 //function : SewSideElements
4624 //=======================================================================
4626 SMESH::SMESH_MeshEditor::Sew_Error
4627 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
4628 const SMESH::long_array& IDsOfSide2Elements,
4629 CORBA::Long NodeID1OfSide1ToMerge,
4630 CORBA::Long NodeID1OfSide2ToMerge,
4631 CORBA::Long NodeID2OfSide1ToMerge,
4632 CORBA::Long NodeID2OfSide2ToMerge)
4636 SMESHDS_Mesh* aMesh = GetMeshDS();
4638 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
4639 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
4640 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
4641 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
4643 if (!aFirstNode1ToMerge ||
4644 !aFirstNode2ToMerge )
4645 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
4646 if (!aSecondNode1ToMerge||
4647 !aSecondNode2ToMerge)
4648 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
4650 TIDSortedElemSet aSide1Elems, aSide2Elems;
4651 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
4652 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
4654 TPythonDump() << "error = " << this << ".SewSideElements( "
4655 << IDsOfSide1Elements << ", "
4656 << IDsOfSide2Elements << ", "
4657 << NodeID1OfSide1ToMerge << ", "
4658 << NodeID1OfSide2ToMerge << ", "
4659 << NodeID2OfSide1ToMerge << ", "
4660 << NodeID2OfSide2ToMerge << ")";
4662 ::SMESH_MeshEditor anEditor( myMesh );
4663 SMESH::SMESH_MeshEditor::Sew_Error error =
4664 convError( anEditor.SewSideElements (aSide1Elems, aSide2Elems,
4667 aSecondNode1ToMerge,
4668 aSecondNode2ToMerge));
4670 storeResult(anEditor);
4672 myMesh->GetMeshDS()->Modified();
4673 myMesh->SetIsModified( true );
4678 //================================================================================
4680 * \brief Set new nodes for given element
4681 * \param ide - element id
4682 * \param newIDs - new node ids
4683 * \retval CORBA::Boolean - true if result is OK
4685 //================================================================================
4687 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
4688 const SMESH::long_array& newIDs)
4692 const SMDS_MeshElement* elem = GetMeshDS()->FindElement(ide);
4693 if(!elem) return false;
4695 int nbn = newIDs.length();
4697 vector<const SMDS_MeshNode*> aNodes(nbn);
4700 const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(newIDs[i]);
4703 aNodes[nbn1] = aNode;
4706 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
4707 << ide << ", " << newIDs << " )";
4709 MESSAGE("ChangeElementNodes");
4710 bool res = GetMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
4712 myMesh->GetMeshDS()->Modified();
4714 myMesh->SetIsModified( true );
4719 //================================================================================
4721 * \brief Update myLastCreated* or myPreviewData
4722 * \param anEditor - it contains last modification results
4724 //================================================================================
4726 void SMESH_MeshEditor_i::storeResult(::SMESH_MeshEditor& anEditor)
4728 if ( myPreviewMode ) { // --- MeshPreviewStruct filling ---
4730 list<int> aNodesConnectivity;
4731 typedef map<int, int> TNodesMap;
4734 TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( anEditor.GetMesh() );
4735 SMDSAbs_ElementType previewType = aPreviewMesh->myPreviewType;
4737 SMESHDS_Mesh* aMeshDS = anEditor.GetMeshDS();
4738 int nbEdges = aMeshDS->NbEdges();
4739 int nbFaces = aMeshDS->NbFaces();
4740 int nbVolum = aMeshDS->NbVolumes();
4741 switch ( previewType ) {
4742 case SMDSAbs_Edge : nbFaces = nbVolum = 0; break;
4743 case SMDSAbs_Face : nbEdges = nbVolum = 0; break;
4744 case SMDSAbs_Volume: nbEdges = nbFaces = 0; break;
4747 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
4748 myPreviewData->elementTypes.length(nbEdges + nbFaces + nbVolum);
4750 SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator();
4752 while ( itMeshElems->more() ) {
4753 const SMDS_MeshElement* aMeshElem = itMeshElems->next();
4754 if ( previewType != SMDSAbs_All && aMeshElem->GetType() != previewType )
4757 SMDS_ElemIteratorPtr itElemNodes = aMeshElem->nodesIterator();
4758 while ( itElemNodes->more() ) {
4759 const SMDS_MeshNode* aMeshNode =
4760 static_cast<const SMDS_MeshNode*>( itElemNodes->next() );
4761 int aNodeID = aMeshNode->GetID();
4762 TNodesMap::iterator anIter = nodesMap.find(aNodeID);
4763 if ( anIter == nodesMap.end() ) {
4764 // filling the nodes coordinates
4765 myPreviewData->nodesXYZ[j].x = aMeshNode->X();
4766 myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
4767 myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
4768 anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
4771 aNodesConnectivity.push_back(anIter->second);
4774 // filling the elements types
4775 SMDSAbs_ElementType aType;
4777 /*if (aMeshElem->GetType() == SMDSAbs_Volume) {
4778 aType = SMDSAbs_Node;
4782 aType = aMeshElem->GetType();
4783 isPoly = aMeshElem->IsPoly();
4786 myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
4787 myPreviewData->elementTypes[i].isPoly = isPoly;
4788 myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
4792 myPreviewData->nodesXYZ.length( j );
4794 // filling the elements connectivities
4795 list<int>::iterator aConnIter = aNodesConnectivity.begin();
4796 myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
4797 for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
4798 myPreviewData->elementConnectivities[i] = *aConnIter;
4804 // append new nodes into myLastCreatedNodes
4805 const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedNodes();
4806 int j = myLastCreatedNodes->length();
4807 int newLen = j + aSeq.Length();
4808 myLastCreatedNodes->length( newLen );
4809 for(int i=0; j<newLen; i++,j++)
4810 myLastCreatedNodes[j] = aSeq.Value(i+1)->GetID();
4813 // append new elements into myLastCreatedElems
4814 const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedElems();
4815 int j = myLastCreatedElems->length();
4816 int newLen = j + aSeq.Length();
4817 myLastCreatedElems->length( newLen );
4818 for(int i=0; j<newLen; i++,j++)
4819 myLastCreatedElems[j] = aSeq.Value(i+1)->GetID();
4823 //================================================================================
4825 * Return data of mesh edition preview
4827 //================================================================================
4829 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
4831 return myPreviewData._retn();
4834 //================================================================================
4836 * \brief Returns list of it's IDs of created nodes
4837 * \retval SMESH::long_array* - list of node ID
4839 //================================================================================
4841 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
4843 return myLastCreatedNodes._retn();
4846 //================================================================================
4848 * \brief Returns list of it's IDs of created elements
4849 * \retval SMESH::long_array* - list of elements' ID
4851 //================================================================================
4853 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
4855 return myLastCreatedElems._retn();
4858 //=======================================================================
4859 //function : ConvertToQuadratic
4861 //=======================================================================
4863 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
4865 ::SMESH_MeshEditor anEditor( myMesh );
4866 anEditor.ConvertToQuadratic(theForce3d);
4867 TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )";
4868 myMesh->GetMeshDS()->Modified();
4869 myMesh->SetIsModified( true );
4872 //=======================================================================
4873 //function : ConvertFromQuadratic
4875 //=======================================================================
4877 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
4879 ::SMESH_MeshEditor anEditor( myMesh );
4880 CORBA::Boolean isDone = anEditor.ConvertFromQuadratic();
4881 TPythonDump() << this << ".ConvertFromQuadratic()";
4882 myMesh->GetMeshDS()->Modified();
4884 myMesh->SetIsModified( true );
4887 //================================================================================
4889 * \brief Makes a part of the mesh quadratic
4891 //================================================================================
4893 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
4894 SMESH::SMESH_IDSource_ptr theObject)
4895 throw (SALOME::SALOME_Exception)
4897 Unexpect aCatch(SALOME_SalomeException);
4899 TIDSortedElemSet elems;
4900 if ( idSourceToSet( theObject, GetMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
4902 if ( elems.empty() )
4904 ConvertToQuadratic( theForce3d );
4906 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
4908 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
4912 ::SMESH_MeshEditor anEditor( myMesh );
4913 anEditor.ConvertToQuadratic(theForce3d, elems);
4916 myMesh->GetMeshDS()->Modified();
4917 myMesh->SetIsModified( true );
4919 pyDump << this << ".ConvertToQuadraticObject( "<<theForce3d<<", "<<theObject<<" )";
4922 //================================================================================
4924 * \brief Makes a part of the mesh linear
4926 //================================================================================
4928 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
4929 throw (SALOME::SALOME_Exception)
4931 Unexpect aCatch(SALOME_SalomeException);
4933 TIDSortedElemSet elems;
4934 if ( idSourceToSet( theObject, GetMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
4936 if ( elems.empty() )
4938 ConvertFromQuadratic();
4940 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
4942 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
4946 ::SMESH_MeshEditor anEditor( myMesh );
4947 anEditor.ConvertFromQuadratic(elems);
4950 myMesh->GetMeshDS()->Modified();
4951 myMesh->SetIsModified( true );
4953 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
4956 //=======================================================================
4957 //function : makeMesh
4958 //purpose : create a named imported mesh
4959 //=======================================================================
4961 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
4963 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
4964 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
4965 SALOMEDS::Study_var study = gen->GetCurrentStudy();
4966 SALOMEDS::SObject_var meshSO = gen->ObjectToSObject( study, mesh );
4967 gen->SetName( meshSO, theMeshName, "Mesh" );
4968 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
4970 return mesh._retn();
4973 //=======================================================================
4974 //function : DumpGroupsList
4976 //=======================================================================
4977 void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump & theDumpPython,
4978 const SMESH::ListOfGroups * theGroupList)
4980 bool isDumpGroupList = theGroupList && theGroupList->length() > 0;
4981 if(isDumpGroupList) {
4982 theDumpPython << theGroupList << " = ";
4986 //================================================================================
4988 \brief Generates the unique group name.
4989 \param thePrefix name prefix
4992 //================================================================================
4993 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
4995 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
4996 set<string> groupNames;
4998 // Get existing group names
4999 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
5000 SMESH::SMESH_GroupBase_var aGroup = groups[i];
5001 if (CORBA::is_nil(aGroup))
5004 groupNames.insert(aGroup->GetName());
5008 string name = thePrefix;
5011 while (!groupNames.insert(name).second) {
5016 TCollection_AsciiString nbStr(index+1);
5017 name.resize( name.rfind('_')+1 );
5018 name += nbStr.ToCString();
5026 //================================================================================
5028 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5029 \param theNodes - identifiers of nodes to be doubled
5030 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
5031 nodes. If list of element identifiers is empty then nodes are doubled but
5032 they not assigned to elements
5033 \return TRUE if operation has been completed successfully, FALSE otherwise
5034 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
5036 //================================================================================
5038 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
5039 const SMESH::long_array& theModifiedElems )
5043 ::SMESH_MeshEditor aMeshEditor( myMesh );
5044 list< int > aListOfNodes;
5046 for ( i = 0, n = theNodes.length(); i < n; i++ )
5047 aListOfNodes.push_back( theNodes[ i ] );
5049 list< int > aListOfElems;
5050 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5051 aListOfElems.push_back( theModifiedElems[ i ] );
5053 bool aResult = aMeshEditor.DoubleNodes( aListOfNodes, aListOfElems );
5055 myMesh->GetMeshDS()->Modified();
5056 storeResult( aMeshEditor) ;
5058 myMesh->SetIsModified( true );
5060 // Update Python script
5061 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
5066 //================================================================================
5068 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5069 This method provided for convenience works as DoubleNodes() described above.
5070 \param theNodeId - identifier of node to be doubled.
5071 \param theModifiedElems - identifiers of elements to be updated.
5072 \return TRUE if operation has been completed successfully, FALSE otherwise
5073 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
5075 //================================================================================
5077 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
5078 const SMESH::long_array& theModifiedElems )
5080 SMESH::long_array_var aNodes = new SMESH::long_array;
5081 aNodes->length( 1 );
5082 aNodes[ 0 ] = theNodeId;
5084 TPythonDump pyDump; // suppress dump by the next line
5086 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
5088 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
5093 //================================================================================
5095 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5096 This method provided for convenience works as DoubleNodes() described above.
5097 \param theNodes - group of nodes to be doubled.
5098 \param theModifiedElems - group of elements to be updated.
5099 \return TRUE if operation has been completed successfully, FALSE otherwise
5100 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
5102 //================================================================================
5104 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
5105 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5107 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5110 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5111 SMESH::long_array_var aModifiedElems;
5112 if ( !CORBA::is_nil( theModifiedElems ) )
5113 aModifiedElems = theModifiedElems->GetListOfID();
5116 aModifiedElems = new SMESH::long_array;
5117 aModifiedElems->length( 0 );
5120 TPythonDump pyDump; // suppress dump by the next line
5122 bool done = DoubleNodes( aNodes, aModifiedElems );
5124 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
5130 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5131 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
5132 * \param theNodes - group of nodes to be doubled.
5133 * \param theModifiedElems - group of elements to be updated.
5134 * \return a new group with newly created nodes
5135 * \sa DoubleNodeGroup()
5137 SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
5138 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5140 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5143 SMESH::SMESH_Group_var aNewGroup;
5146 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5147 SMESH::long_array_var aModifiedElems;
5148 if ( !CORBA::is_nil( theModifiedElems ) )
5149 aModifiedElems = theModifiedElems->GetListOfID();
5151 aModifiedElems = new SMESH::long_array;
5152 aModifiedElems->length( 0 );
5155 TPythonDump pyDump; // suppress dump by the next line
5157 bool aResult = DoubleNodes( aNodes, aModifiedElems );
5161 // Create group with newly created nodes
5162 SMESH::long_array_var anIds = GetLastCreatedNodes();
5163 if (anIds->length() > 0) {
5164 string anUnindexedName (theNodes->GetName());
5165 string aNewName = generateGroupName(anUnindexedName + "_double");
5166 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5167 aNewGroup->Add(anIds);
5171 pyDump << "createdNodes = " << this << ".DoubleNodeGroupNew( " << theNodes << ", "
5172 << theModifiedElems << " )";
5174 return aNewGroup._retn();
5177 //================================================================================
5179 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5180 This method provided for convenience works as DoubleNodes() described above.
5181 \param theNodes - list of groups of nodes to be doubled
5182 \param theModifiedElems - list of groups of elements to be updated.
5183 \return TRUE if operation has been completed successfully, FALSE otherwise
5184 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
5186 //================================================================================
5188 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
5189 const SMESH::ListOfGroups& theModifiedElems )
5193 ::SMESH_MeshEditor aMeshEditor( myMesh );
5195 std::list< int > aNodes;
5197 for ( i = 0, n = theNodes.length(); i < n; i++ )
5199 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
5200 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
5202 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5203 for ( j = 0, m = aCurr->length(); j < m; j++ )
5204 aNodes.push_back( aCurr[ j ] );
5208 std::list< int > anElems;
5209 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5211 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
5212 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
5214 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5215 for ( j = 0, m = aCurr->length(); j < m; j++ )
5216 anElems.push_back( aCurr[ j ] );
5220 bool aResult = aMeshEditor.DoubleNodes( aNodes, anElems );
5222 storeResult( aMeshEditor) ;
5224 myMesh->GetMeshDS()->Modified();
5226 myMesh->SetIsModified( true );
5229 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
5234 //================================================================================
5236 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5237 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
5238 * \param theNodes - group of nodes to be doubled.
5239 * \param theModifiedElems - group of elements to be updated.
5240 * \return a new group with newly created nodes
5241 * \sa DoubleNodeGroups()
5243 //================================================================================
5245 SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
5246 const SMESH::ListOfGroups& theModifiedElems )
5248 SMESH::SMESH_Group_var aNewGroup;
5250 TPythonDump pyDump; // suppress dump by the next line
5252 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
5256 // Create group with newly created nodes
5257 SMESH::long_array_var anIds = GetLastCreatedNodes();
5258 if (anIds->length() > 0) {
5259 string anUnindexedName (theNodes[0]->GetName());
5260 string aNewName = generateGroupName(anUnindexedName + "_double");
5261 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5262 aNewGroup->Add(anIds);
5266 pyDump << "createdNodes = " << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
5267 << theModifiedElems << " )";
5269 return aNewGroup._retn();
5273 //================================================================================
5275 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5276 \param theElems - the list of elements (edges or faces) to be replicated
5277 The nodes for duplication could be found from these elements
5278 \param theNodesNot - list of nodes to NOT replicate
5279 \param theAffectedElems - the list of elements (cells and edges) to which the
5280 replicated nodes should be associated to.
5281 \return TRUE if operation has been completed successfully, FALSE otherwise
5282 \sa DoubleNodeGroup(), DoubleNodeGroups()
5284 //================================================================================
5286 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
5287 const SMESH::long_array& theNodesNot,
5288 const SMESH::long_array& theAffectedElems )
5293 ::SMESH_MeshEditor aMeshEditor( myMesh );
5295 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5296 TIDSortedElemSet anElems, aNodes, anAffected;
5297 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5298 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5299 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
5301 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5303 storeResult( aMeshEditor) ;
5305 myMesh->GetMeshDS()->Modified();
5307 myMesh->SetIsModified( true );
5309 // Update Python script
5310 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
5311 << theNodesNot << ", " << theAffectedElems << " )";
5315 //================================================================================
5317 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5318 \param theElems - the list of elements (edges or faces) to be replicated
5319 The nodes for duplication could be found from these elements
5320 \param theNodesNot - list of nodes to NOT replicate
5321 \param theShape - shape to detect affected elements (element which geometric center
5322 located on or inside shape).
5323 The replicated nodes should be associated to affected elements.
5324 \return TRUE if operation has been completed successfully, FALSE otherwise
5325 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
5327 //================================================================================
5329 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
5330 const SMESH::long_array& theNodesNot,
5331 GEOM::GEOM_Object_ptr theShape )
5336 ::SMESH_MeshEditor aMeshEditor( myMesh );
5338 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5339 TIDSortedElemSet anElems, aNodes;
5340 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5341 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5343 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5344 bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5346 storeResult( aMeshEditor) ;
5348 myMesh->GetMeshDS()->Modified();
5350 myMesh->SetIsModified( true );
5352 // Update Python script
5353 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
5354 << theNodesNot << ", " << theShape << " )";
5358 //================================================================================
5360 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5361 \param theElems - group of of elements (edges or faces) to be replicated
5362 \param theNodesNot - group of nodes not to replicated
5363 \param theAffectedElems - group of elements to which the replicated nodes
5364 should be associated to.
5365 \return TRUE if operation has been completed successfully, FALSE otherwise
5366 \sa DoubleNodes(), DoubleNodeGroups()
5368 //================================================================================
5370 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
5371 SMESH::SMESH_GroupBase_ptr theNodesNot,
5372 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5374 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5379 ::SMESH_MeshEditor aMeshEditor( myMesh );
5381 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5382 TIDSortedElemSet anElems, aNodes, anAffected;
5383 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5384 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5385 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5387 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5389 storeResult( aMeshEditor) ;
5391 myMesh->GetMeshDS()->Modified();
5393 myMesh->SetIsModified( true );
5395 // Update Python script
5396 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
5397 << theNodesNot << ", " << theAffectedElems << " )";
5402 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5403 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
5404 * \param theElems - group of of elements (edges or faces) to be replicated
5405 * \param theNodesNot - group of nodes not to replicated
5406 * \param theAffectedElems - group of elements to which the replicated nodes
5407 * should be associated to.
5408 * \return a new group with newly created elements
5409 * \sa DoubleNodeElemGroup()
5411 SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
5412 SMESH::SMESH_GroupBase_ptr theNodesNot,
5413 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5415 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5418 SMESH::SMESH_Group_var aNewGroup;
5422 ::SMESH_MeshEditor aMeshEditor( myMesh );
5424 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5425 TIDSortedElemSet anElems, aNodes, anAffected;
5426 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5427 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5428 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5431 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5433 storeResult( aMeshEditor) ;
5436 myMesh->SetIsModified( true );
5438 // Create group with newly created elements
5439 SMESH::long_array_var anIds = GetLastCreatedElems();
5440 if (anIds->length() > 0) {
5441 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5442 string anUnindexedName (theElems->GetName());
5443 string aNewName = generateGroupName(anUnindexedName + "_double");
5444 aNewGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5445 aNewGroup->Add(anIds);
5449 // Update Python script
5450 TPythonDump() << "createdElems = " << this << ".DoubleNodeElemGroupNew( " << theElems << ", "
5451 << theNodesNot << ", " << theAffectedElems << " )";
5452 return aNewGroup._retn();
5455 //================================================================================
5457 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5458 \param theElems - group of of elements (edges or faces) to be replicated
5459 \param theNodesNot - group of nodes not to replicated
5460 \param theShape - shape to detect affected elements (element which geometric center
5461 located on or inside shape).
5462 The replicated nodes should be associated to affected elements.
5463 \return TRUE if operation has been completed successfully, FALSE otherwise
5464 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
5466 //================================================================================
5468 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
5469 SMESH::SMESH_GroupBase_ptr theNodesNot,
5470 GEOM::GEOM_Object_ptr theShape )
5473 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5478 ::SMESH_MeshEditor aMeshEditor( myMesh );
5480 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5481 TIDSortedElemSet anElems, aNodes, anAffected;
5482 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5483 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5485 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5486 bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5488 storeResult( aMeshEditor) ;
5490 myMesh->GetMeshDS()->Modified();
5492 myMesh->SetIsModified( true );
5494 // Update Python script
5495 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
5496 << theNodesNot << ", " << theShape << " )";
5500 //================================================================================
5502 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5503 This method provided for convenience works as DoubleNodes() described above.
5504 \param theElems - list of groups of elements (edges or faces) to be replicated
5505 \param theNodesNot - list of groups of nodes not to replicated
5506 \param theAffectedElems - group of elements to which the replicated nodes
5507 should be associated to.
5508 \return TRUE if operation has been completed successfully, FALSE otherwise
5509 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
5511 //================================================================================
5513 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
5514 SMESHDS_Mesh* theMeshDS,
5515 TIDSortedElemSet& theElemSet,
5516 const bool theIsNodeGrp)
5518 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
5520 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
5521 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
5522 : aGrp->GetType() != SMESH::NODE ) )
5524 SMESH::long_array_var anIDs = aGrp->GetIDs();
5525 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
5530 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
5531 const SMESH::ListOfGroups& theNodesNot,
5532 const SMESH::ListOfGroups& theAffectedElems)
5536 ::SMESH_MeshEditor aMeshEditor( myMesh );
5538 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5539 TIDSortedElemSet anElems, aNodes, anAffected;
5540 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5541 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5542 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5544 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5546 storeResult( aMeshEditor) ;
5548 myMesh->GetMeshDS()->Modified();
5550 myMesh->SetIsModified( true );
5552 // Update Python script
5553 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
5554 << &theNodesNot << ", " << &theAffectedElems << " )";
5558 //================================================================================
5560 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5561 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
5562 \param theElems - list of groups of elements (edges or faces) to be replicated
5563 \param theNodesNot - list of groups of nodes not to replicated
5564 \param theAffectedElems - group of elements to which the replicated nodes
5565 should be associated to.
5566 * \return a new group with newly created elements
5567 * \sa DoubleNodeElemGroups()
5569 //================================================================================
5571 SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
5572 const SMESH::ListOfGroups& theNodesNot,
5573 const SMESH::ListOfGroups& theAffectedElems)
5575 SMESH::SMESH_Group_var aNewGroup;
5579 ::SMESH_MeshEditor aMeshEditor( myMesh );
5581 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5582 TIDSortedElemSet anElems, aNodes, anAffected;
5583 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5584 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5585 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5587 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5589 storeResult( aMeshEditor) ;
5591 myMesh->GetMeshDS()->Modified();
5593 myMesh->SetIsModified( true );
5595 // Create group with newly created elements
5596 SMESH::long_array_var anIds = GetLastCreatedElems();
5597 if (anIds->length() > 0) {
5598 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5599 string anUnindexedName (theElems[0]->GetName());
5600 string aNewName = generateGroupName(anUnindexedName + "_double");
5601 aNewGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5602 aNewGroup->Add(anIds);
5606 // Update Python script
5607 TPythonDump() << "createdElems = " << this << ".DoubleNodeElemGroupsNew( " << &theElems << ", "
5608 << &theNodesNot << ", " << &theAffectedElems << " )";
5609 return aNewGroup._retn();
5612 //================================================================================
5614 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5615 This method provided for convenience works as DoubleNodes() described above.
5616 \param theElems - list of groups of elements (edges or faces) to be replicated
5617 \param theNodesNot - list of groups of nodes not to replicated
5618 \param theShape - shape to detect affected elements (element which geometric center
5619 located on or inside shape).
5620 The replicated nodes should be associated to affected elements.
5621 \return TRUE if operation has been completed successfully, FALSE otherwise
5622 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
5624 //================================================================================
5627 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
5628 const SMESH::ListOfGroups& theNodesNot,
5629 GEOM::GEOM_Object_ptr theShape )
5633 ::SMESH_MeshEditor aMeshEditor( myMesh );
5635 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5636 TIDSortedElemSet anElems, aNodes;
5637 listOfGroupToSet(theElems, aMeshDS, anElems,false );
5638 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5640 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5641 bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5643 storeResult( aMeshEditor) ;
5645 myMesh->GetMeshDS()->Modified();
5647 myMesh->SetIsModified( true );
5649 // Update Python script
5650 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
5651 << &theNodesNot << ", " << theShape << " )";
5655 //================================================================================
5657 \brief Generated skin mesh (containing 2D cells) from 3D mesh
5658 The created 2D mesh elements based on nodes of free faces of boundary volumes
5659 \return TRUE if operation has been completed successfully, FALSE otherwise
5661 //================================================================================
5663 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
5667 ::SMESH_MeshEditor aMeshEditor( myMesh );
5668 bool aResult = aMeshEditor.Make2DMeshFrom3D();
5669 storeResult( aMeshEditor) ;
5670 myMesh->GetMeshDS()->Modified();
5671 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
5675 //================================================================================
5677 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
5678 * The list of groups must describe a partition of the mesh volumes.
5679 * The nodes of the internal faces at the boundaries of the groups are doubled.
5680 * In option, the internal faces are replaced by flat elements.
5681 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
5682 * The flat elements are stored in groups of volumes.
5683 * @param theDomains - list of groups of volumes
5684 * @param createJointElems - if TRUE, create the elements
5685 * @return TRUE if operation has been completed successfully, FALSE otherwise
5687 //================================================================================
5689 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
5690 CORBA::Boolean createJointElems )
5691 throw (SALOME::SALOME_Exception)
5695 ::SMESH_MeshEditor aMeshEditor( myMesh );
5697 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5699 vector<TIDSortedElemSet> domains;
5702 for ( int i = 0, n = theDomains.length(); i < n; i++ )
5704 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
5705 if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
5707 if ( aGrp->GetType() != SMESH::VOLUME )
5708 THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
5709 TIDSortedElemSet domain;
5711 domains.push_back(domain);
5712 SMESH::long_array_var anIDs = aGrp->GetIDs();
5713 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
5717 bool aResult = aMeshEditor.DoubleNodesOnGroupBoundaries( domains, createJointElems );
5718 // TODO publish the groups of flat elements in study
5720 storeResult( aMeshEditor) ;
5721 myMesh->GetMeshDS()->Modified();
5723 // Update Python script
5724 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
5725 << ", " << createJointElems << " )";
5729 //================================================================================
5731 * \brief Double nodes on some external faces and create flat elements.
5732 * Flat elements are mainly used by some types of mechanic calculations.
5734 * Each group of the list must be constituted of faces.
5735 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
5736 * @param theGroupsOfFaces - list of groups of faces
5737 * @return TRUE if operation has been completed successfully, FALSE otherwise
5739 //================================================================================
5741 CORBA::Boolean SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
5745 ::SMESH_MeshEditor aMeshEditor( myMesh );
5747 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5749 vector<TIDSortedElemSet> faceGroups;
5752 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
5754 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
5755 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
5757 TIDSortedElemSet faceGroup;
5759 faceGroups.push_back(faceGroup);
5760 SMESH::long_array_var anIDs = aGrp->GetIDs();
5761 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
5765 bool aResult = aMeshEditor.CreateFlatElementsOnFacesGroups( faceGroups );
5766 // TODO publish the groups of flat elements in study
5768 storeResult( aMeshEditor) ;
5769 myMesh->GetMeshDS()->Modified();
5771 // Update Python script
5772 TPythonDump() << "isDone = " << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
5776 // issue 20749 ===================================================================
5778 * \brief Creates missing boundary elements
5779 * \param elements - elements whose boundary is to be checked
5780 * \param dimension - defines type of boundary elements to create
5781 * \param groupName - a name of group to store created boundary elements in,
5782 * "" means not to create the group
5783 * \param meshName - a name of new mesh to store created boundary elements in,
5784 * "" means not to create the new mesh
5785 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
5786 * \param toCopyExistingBondary - if true, not only new but also pre-existing
5787 * boundary elements will be copied into the new mesh
5788 * \param group - returns the create group, if any
5789 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
5791 // ================================================================================
5793 SMESH::SMESH_Mesh_ptr
5794 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
5795 SMESH::Bnd_Dimension dim,
5796 const char* groupName,
5797 const char* meshName,
5798 CORBA::Boolean toCopyElements,
5799 CORBA::Boolean toCopyExistingBondary,
5800 SMESH::SMESH_Group_out group)
5804 if ( dim > SMESH::BND_1DFROM2D )
5805 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
5807 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5809 SMESH::SMESH_Mesh_var mesh_var;
5810 SMESH::SMESH_Group_var group_var;
5814 TIDSortedElemSet elements;
5815 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
5816 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
5820 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
5821 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
5823 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
5825 // group of new boundary elements
5826 SMESH_Group* smesh_group = 0;
5827 if ( strlen(groupName) )
5829 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
5830 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
5831 smesh_group = group_i->GetSmeshGroup();
5835 ::SMESH_MeshEditor aMeshEditor( myMesh );
5836 aMeshEditor.MakeBoundaryMesh( elements,
5837 ::SMESH_MeshEditor::Bnd_Dimension(dim),
5841 toCopyExistingBondary);
5842 storeResult( aMeshEditor );
5845 smesh_mesh->GetMeshDS()->Modified();
5848 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
5850 // result of MakeBoundaryMesh() is a tuple (mesh, group)
5851 if ( mesh_var->_is_nil() )
5852 pyDump << myMesh_i->_this() << ", ";
5854 pyDump << mesh_var << ", ";
5855 if ( group_var->_is_nil() )
5856 pyDump << "_NoneGroup = "; // assignment to None is forbiden
5858 pyDump << group_var << " = ";
5859 pyDump << this << ".MakeBoundaryMesh( "
5861 << "SMESH." << dimName[int(dim)] << ", "
5862 << "'" << groupName << "', "
5863 << "'" << meshName<< "', "
5864 << toCopyElements << ", "
5865 << toCopyExistingBondary << ")";
5867 group = group_var._retn();
5868 return mesh_var._retn();
5871 //================================================================================
5873 * \brief Creates missing boundary elements
5874 * \param dimension - defines type of boundary elements to create
5875 * \param groupName - a name of group to store all boundary elements in,
5876 * "" means not to create the group
5877 * \param meshName - a name of a new mesh, which is a copy of the initial
5878 * mesh + created boundary elements; "" means not to create the new mesh
5879 * \param toCopyAll - if true, the whole initial mesh will be copied into
5880 * the new mesh else only boundary elements will be copied into the new mesh
5881 * \param groups - optional groups of elements to make boundary around
5882 * \param mesh - returns the mesh where elements were added to
5883 * \param group - returns the created group, if any
5884 * \retval long - number of added boundary elements
5886 //================================================================================
5888 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
5889 const char* groupName,
5890 const char* meshName,
5891 CORBA::Boolean toCopyAll,
5892 const SMESH::ListOfIDSources& groups,
5893 SMESH::SMESH_Mesh_out mesh,
5894 SMESH::SMESH_Group_out group)
5895 throw (SALOME::SALOME_Exception)
5897 Unexpect aCatch(SALOME_SalomeException);
5901 if ( dim > SMESH::BND_1DFROM2D )
5902 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
5904 // separate groups belonging to this and other mesh
5905 SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
5906 SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
5907 groupsOfThisMesh->length( groups.length() );
5908 groupsOfOtherMesh->length( groups.length() );
5909 int nbGroups = 0, nbGroupsOfOtherMesh = 0;
5910 for ( int i = 0; i < groups.length(); ++i )
5912 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
5913 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
5914 groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
5916 groupsOfThisMesh[ nbGroups++ ] = groups[i];
5917 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
5918 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
5920 groupsOfThisMesh->length( nbGroups );
5921 groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
5926 if ( nbGroupsOfOtherMesh > 0 )
5928 // process groups belonging to another mesh
5929 SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
5930 SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
5931 nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
5932 groupsOfOtherMesh, mesh, group );
5935 SMESH::SMESH_Mesh_var mesh_var;
5936 SMESH::SMESH_Group_var group_var;
5939 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
5940 const bool toCopyMesh = ( strlen( meshName ) > 0 );
5944 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
5946 /*toCopyGroups=*/false,
5947 /*toKeepIDs=*/true);
5949 mesh_var = makeMesh(meshName);
5951 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
5952 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
5955 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
5956 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
5958 // group of boundary elements
5959 SMESH_Group* smesh_group = 0;
5960 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
5961 if ( strlen(groupName) )
5963 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
5964 group_var = mesh_i->CreateGroup( groupType, groupName );
5965 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
5966 smesh_group = group_i->GetSmeshGroup();
5969 TIDSortedElemSet elements;
5971 if ( groups.length() > 0 )
5973 for ( int i = 0; i < nbGroups; ++i )
5976 if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
5978 SMESH::Bnd_Dimension bdim =
5979 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
5980 ::SMESH_MeshEditor aMeshEditor( srcMesh );
5981 nbAdded += aMeshEditor.MakeBoundaryMesh( elements,
5982 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
5985 /*toCopyElements=*/false,
5986 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
5987 /*toAddExistingBondary=*/true,
5988 /*aroundElements=*/true);
5989 storeResult( aMeshEditor );
5995 ::SMESH_MeshEditor aMeshEditor( srcMesh );
5996 nbAdded += aMeshEditor.MakeBoundaryMesh( elements,
5997 ::SMESH_MeshEditor::Bnd_Dimension(dim),
6000 /*toCopyElements=*/false,
6001 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
6002 /*toAddExistingBondary=*/true);
6003 storeResult( aMeshEditor );
6005 tgtMesh->GetMeshDS()->Modified();
6007 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
6009 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
6010 pyDump << "nbAdded, ";
6011 if ( mesh_var->_is_nil() )
6012 pyDump << myMesh_i->_this() << ", ";
6014 pyDump << mesh_var << ", ";
6015 if ( group_var->_is_nil() )
6016 pyDump << "_NoneGroup = "; // assignment to None is forbiden
6018 pyDump << group_var << " = ";
6019 pyDump << this << ".MakeBoundaryElements( "
6020 << "SMESH." << dimName[int(dim)] << ", "
6021 << "'" << groupName << "', "
6022 << "'" << meshName<< "', "
6023 << toCopyAll << ", "
6026 mesh = mesh_var._retn();
6027 group = group_var._retn();