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); // store preview data or new elements
3008 if ( !myPreviewMode )
3010 if ( theTargetMesh )
3012 theTargetMesh->GetMeshDS()->Modified();
3016 myMesh->GetMeshDS()->Modified();
3017 myMesh->SetIsModified( true );
3020 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3023 //=======================================================================
3026 //=======================================================================
3028 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3029 const SMESH::AxisStruct & theAxis,
3030 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3031 CORBA::Boolean theCopy)
3033 if ( !myPreviewMode ) {
3034 TPythonDump() << this << ".Mirror( "
3035 << theIDsOfElements << ", "
3037 << mirrorTypeName(theMirrorType) << ", "
3040 if ( theIDsOfElements.length() > 0 )
3042 TIDSortedElemSet elements;
3043 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3044 mirror(elements, theAxis, theMirrorType, theCopy, false);
3049 //=======================================================================
3050 //function : MirrorObject
3052 //=======================================================================
3054 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3055 const SMESH::AxisStruct & theAxis,
3056 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3057 CORBA::Boolean theCopy)
3059 if ( !myPreviewMode ) {
3060 TPythonDump() << this << ".MirrorObject( "
3061 << theObject << ", "
3063 << mirrorTypeName(theMirrorType) << ", "
3066 TIDSortedElemSet elements;
3068 bool emptyIfIsMesh = myPreviewMode ? false : true;
3070 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3071 mirror(elements, theAxis, theMirrorType, theCopy, false);
3074 //=======================================================================
3075 //function : MirrorMakeGroups
3077 //=======================================================================
3079 SMESH::ListOfGroups*
3080 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3081 const SMESH::AxisStruct& theMirror,
3082 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3084 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3086 SMESH::ListOfGroups * aGroups = 0;
3087 if ( theIDsOfElements.length() > 0 )
3089 TIDSortedElemSet elements;
3090 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3091 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3093 if (!myPreviewMode) {
3094 DumpGroupsList(aPythonDump, aGroups);
3095 aPythonDump << this << ".MirrorMakeGroups( "
3096 << theIDsOfElements << ", "
3097 << theMirror << ", "
3098 << mirrorTypeName(theMirrorType) << " )";
3103 //=======================================================================
3104 //function : MirrorObjectMakeGroups
3106 //=======================================================================
3108 SMESH::ListOfGroups*
3109 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3110 const SMESH::AxisStruct& theMirror,
3111 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3113 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3115 SMESH::ListOfGroups * aGroups = 0;
3116 TIDSortedElemSet elements;
3117 if ( idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3118 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3122 DumpGroupsList(aPythonDump,aGroups);
3123 aPythonDump << this << ".MirrorObjectMakeGroups( "
3124 << theObject << ", "
3125 << theMirror << ", "
3126 << mirrorTypeName(theMirrorType) << " )";
3131 //=======================================================================
3132 //function : MirrorMakeMesh
3134 //=======================================================================
3136 SMESH::SMESH_Mesh_ptr
3137 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
3138 const SMESH::AxisStruct& theMirror,
3139 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3140 CORBA::Boolean theCopyGroups,
3141 const char* theMeshName)
3143 SMESH_Mesh_i* mesh_i;
3144 SMESH::SMESH_Mesh_var mesh;
3145 { // open new scope to dump "MakeMesh" command
3146 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3148 TPythonDump pydump; // to prevent dump at mesh creation
3150 mesh = makeMesh( theMeshName );
3151 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3152 if (mesh_i && theIDsOfElements.length() > 0 )
3154 TIDSortedElemSet elements;
3155 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3156 mirror(elements, theMirror, theMirrorType,
3157 false, theCopyGroups, & mesh_i->GetImpl());
3158 mesh_i->CreateGroupServants();
3161 if (!myPreviewMode) {
3162 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
3163 << theIDsOfElements << ", "
3164 << theMirror << ", "
3165 << mirrorTypeName(theMirrorType) << ", "
3166 << theCopyGroups << ", '"
3167 << theMeshName << "' )";
3172 if (!myPreviewMode && mesh_i)
3173 mesh_i->GetGroups();
3175 return mesh._retn();
3178 //=======================================================================
3179 //function : MirrorObjectMakeMesh
3181 //=======================================================================
3183 SMESH::SMESH_Mesh_ptr
3184 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3185 const SMESH::AxisStruct& theMirror,
3186 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3187 CORBA::Boolean theCopyGroups,
3188 const char* theMeshName)
3190 SMESH_Mesh_i* mesh_i;
3191 SMESH::SMESH_Mesh_var mesh;
3192 { // open new scope to dump "MakeMesh" command
3193 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3195 TPythonDump pydump; // to prevent dump at mesh creation
3197 mesh = makeMesh( theMeshName );
3198 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3199 TIDSortedElemSet elements;
3201 idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3203 mirror(elements, theMirror, theMirrorType,
3204 false, theCopyGroups, & mesh_i->GetImpl());
3205 mesh_i->CreateGroupServants();
3207 if (!myPreviewMode) {
3208 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
3209 << theObject << ", "
3210 << theMirror << ", "
3211 << mirrorTypeName(theMirrorType) << ", "
3212 << theCopyGroups << ", '"
3213 << theMeshName << "' )";
3218 if (!myPreviewMode && mesh_i)
3219 mesh_i->GetGroups();
3221 return mesh._retn();
3224 //=======================================================================
3225 //function : translate
3227 //=======================================================================
3229 SMESH::ListOfGroups*
3230 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
3231 const SMESH::DirStruct & theVector,
3232 CORBA::Boolean theCopy,
3234 ::SMESH_Mesh* theTargetMesh)
3238 if ( theTargetMesh )
3242 const SMESH::PointStruct * P = &theVector.PS;
3243 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
3245 TIDSortedElemSet copyElements;
3246 TIDSortedElemSet* workElements = &theElements;
3247 TPreviewMesh tmpMesh;
3248 SMESH_Mesh* mesh = myMesh;
3250 if ( myPreviewMode )
3252 tmpMesh.Copy( theElements, copyElements);
3253 if ( !theCopy && !theTargetMesh )
3255 TIDSortedElemSet elemsAround, elemsAroundCopy;
3256 getElementsAround( theElements, GetMeshDS(), elemsAround );
3257 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3260 workElements = & copyElements;
3261 theMakeGroups = false;
3264 ::SMESH_MeshEditor anEditor( mesh );
3265 ::SMESH_MeshEditor::PGroupIDs groupIds =
3266 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3268 if(theCopy || myPreviewMode)
3269 storeResult(anEditor);
3271 if ( !myPreviewMode )
3273 if ( theTargetMesh )
3275 theTargetMesh->GetMeshDS()->Modified();
3279 myMesh->GetMeshDS()->Modified();
3280 myMesh->SetIsModified( true );
3284 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3287 //=======================================================================
3288 //function : Translate
3290 //=======================================================================
3292 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
3293 const SMESH::DirStruct & theVector,
3294 CORBA::Boolean theCopy)
3296 if (!myPreviewMode) {
3297 TPythonDump() << this << ".Translate( "
3298 << theIDsOfElements << ", "
3299 << theVector << ", "
3302 if (theIDsOfElements.length()) {
3303 TIDSortedElemSet elements;
3304 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3305 translate(elements, theVector, theCopy, false);
3309 //=======================================================================
3310 //function : TranslateObject
3312 //=======================================================================
3314 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
3315 const SMESH::DirStruct & theVector,
3316 CORBA::Boolean theCopy)
3318 if (!myPreviewMode) {
3319 TPythonDump() << this << ".TranslateObject( "
3320 << theObject << ", "
3321 << theVector << ", "
3324 TIDSortedElemSet elements;
3326 bool emptyIfIsMesh = myPreviewMode ? false : true;
3328 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3329 translate(elements, theVector, theCopy, false);
3332 //=======================================================================
3333 //function : TranslateMakeGroups
3335 //=======================================================================
3337 SMESH::ListOfGroups*
3338 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
3339 const SMESH::DirStruct& theVector)
3341 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3343 SMESH::ListOfGroups * aGroups = 0;
3344 if (theIDsOfElements.length()) {
3345 TIDSortedElemSet elements;
3346 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3347 aGroups = translate(elements,theVector,true,true);
3349 if (!myPreviewMode) {
3350 DumpGroupsList(aPythonDump, aGroups);
3351 aPythonDump << this << ".TranslateMakeGroups( "
3352 << theIDsOfElements << ", "
3353 << theVector << " )";
3358 //=======================================================================
3359 //function : TranslateObjectMakeGroups
3361 //=======================================================================
3363 SMESH::ListOfGroups*
3364 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3365 const SMESH::DirStruct& theVector)
3367 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3369 SMESH::ListOfGroups * aGroups = 0;
3370 TIDSortedElemSet elements;
3371 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3372 aGroups = translate(elements, theVector, true, true);
3374 if (!myPreviewMode) {
3375 DumpGroupsList(aPythonDump, aGroups);
3376 aPythonDump << this << ".TranslateObjectMakeGroups( "
3377 << theObject << ", "
3378 << theVector << " )";
3383 //=======================================================================
3384 //function : TranslateMakeMesh
3386 //=======================================================================
3388 SMESH::SMESH_Mesh_ptr
3389 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
3390 const SMESH::DirStruct& theVector,
3391 CORBA::Boolean theCopyGroups,
3392 const char* theMeshName)
3394 SMESH_Mesh_i* mesh_i;
3395 SMESH::SMESH_Mesh_var mesh;
3397 { // open new scope to dump "MakeMesh" command
3398 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3400 TPythonDump pydump; // to prevent dump at mesh creation
3402 mesh = makeMesh( theMeshName );
3403 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3405 if ( mesh_i && theIDsOfElements.length() )
3407 TIDSortedElemSet elements;
3408 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3409 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
3410 mesh_i->CreateGroupServants();
3413 if ( !myPreviewMode ) {
3414 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
3415 << theIDsOfElements << ", "
3416 << theVector << ", "
3417 << theCopyGroups << ", '"
3418 << theMeshName << "' )";
3423 if (!myPreviewMode && mesh_i)
3424 mesh_i->GetGroups();
3426 return mesh._retn();
3429 //=======================================================================
3430 //function : TranslateObjectMakeMesh
3432 //=======================================================================
3434 SMESH::SMESH_Mesh_ptr
3435 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3436 const SMESH::DirStruct& theVector,
3437 CORBA::Boolean theCopyGroups,
3438 const char* theMeshName)
3440 SMESH_Mesh_i* mesh_i;
3441 SMESH::SMESH_Mesh_var mesh;
3442 { // open new scope to dump "MakeMesh" command
3443 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3445 TPythonDump pydump; // to prevent dump at mesh creation
3446 mesh = makeMesh( theMeshName );
3447 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3449 TIDSortedElemSet elements;
3451 idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3453 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
3454 mesh_i->CreateGroupServants();
3456 if ( !myPreviewMode ) {
3457 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
3458 << theObject << ", "
3459 << theVector << ", "
3460 << theCopyGroups << ", '"
3461 << theMeshName << "' )";
3466 if (!myPreviewMode && mesh_i)
3467 mesh_i->GetGroups();
3469 return mesh._retn();
3472 //=======================================================================
3475 //=======================================================================
3477 SMESH::ListOfGroups*
3478 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
3479 const SMESH::AxisStruct & theAxis,
3480 CORBA::Double theAngle,
3481 CORBA::Boolean theCopy,
3483 ::SMESH_Mesh* theTargetMesh)
3487 if ( theTargetMesh )
3490 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3491 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3494 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
3496 TIDSortedElemSet copyElements;
3497 TIDSortedElemSet* workElements = &theElements;
3498 TPreviewMesh tmpMesh;
3499 SMESH_Mesh* mesh = myMesh;
3501 if ( myPreviewMode ) {
3502 tmpMesh.Copy( theElements, copyElements );
3503 if ( !theCopy && !theTargetMesh )
3505 TIDSortedElemSet elemsAround, elemsAroundCopy;
3506 getElementsAround( theElements, GetMeshDS(), elemsAround );
3507 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3510 workElements = ©Elements;
3511 theMakeGroups = false;
3514 ::SMESH_MeshEditor anEditor( mesh );
3515 ::SMESH_MeshEditor::PGroupIDs groupIds =
3516 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3518 if(theCopy || myPreviewMode)
3519 storeResult(anEditor);
3521 if ( !myPreviewMode )
3523 if ( theTargetMesh )
3525 theTargetMesh->GetMeshDS()->Modified();
3529 myMesh->GetMeshDS()->Modified();
3530 myMesh->SetIsModified( true );
3534 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3537 //=======================================================================
3540 //=======================================================================
3542 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
3543 const SMESH::AxisStruct & theAxis,
3544 CORBA::Double theAngle,
3545 CORBA::Boolean theCopy)
3547 if (!myPreviewMode) {
3548 TPythonDump() << this << ".Rotate( "
3549 << theIDsOfElements << ", "
3554 if (theIDsOfElements.length() > 0)
3556 TIDSortedElemSet elements;
3557 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3558 rotate(elements,theAxis,theAngle,theCopy,false);
3562 //=======================================================================
3563 //function : RotateObject
3565 //=======================================================================
3567 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
3568 const SMESH::AxisStruct & theAxis,
3569 CORBA::Double theAngle,
3570 CORBA::Boolean theCopy)
3572 if ( !myPreviewMode ) {
3573 TPythonDump() << this << ".RotateObject( "
3574 << theObject << ", "
3579 TIDSortedElemSet elements;
3580 bool emptyIfIsMesh = myPreviewMode ? false : true;
3581 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3582 rotate(elements,theAxis,theAngle,theCopy,false);
3585 //=======================================================================
3586 //function : RotateMakeGroups
3588 //=======================================================================
3590 SMESH::ListOfGroups*
3591 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
3592 const SMESH::AxisStruct& theAxis,
3593 CORBA::Double theAngle)
3595 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3597 SMESH::ListOfGroups * aGroups = 0;
3598 if (theIDsOfElements.length() > 0)
3600 TIDSortedElemSet elements;
3601 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3602 aGroups = rotate(elements,theAxis,theAngle,true,true);
3604 if (!myPreviewMode) {
3605 DumpGroupsList(aPythonDump, aGroups);
3606 aPythonDump << this << ".RotateMakeGroups( "
3607 << theIDsOfElements << ", "
3609 << theAngle << " )";
3614 //=======================================================================
3615 //function : RotateObjectMakeGroups
3617 //=======================================================================
3619 SMESH::ListOfGroups*
3620 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3621 const SMESH::AxisStruct& theAxis,
3622 CORBA::Double theAngle)
3624 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3626 SMESH::ListOfGroups * aGroups = 0;
3627 TIDSortedElemSet elements;
3628 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3629 aGroups = rotate(elements, theAxis, theAngle, true, true);
3631 if (!myPreviewMode) {
3632 DumpGroupsList(aPythonDump, aGroups);
3633 aPythonDump << this << ".RotateObjectMakeGroups( "
3634 << theObject << ", "
3636 << theAngle << " )";
3641 //=======================================================================
3642 //function : RotateMakeMesh
3644 //=======================================================================
3646 SMESH::SMESH_Mesh_ptr
3647 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
3648 const SMESH::AxisStruct& theAxis,
3649 CORBA::Double theAngleInRadians,
3650 CORBA::Boolean theCopyGroups,
3651 const char* theMeshName)
3653 SMESH::SMESH_Mesh_var mesh;
3654 SMESH_Mesh_i* mesh_i;
3656 { // open new scope to dump "MakeMesh" command
3657 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3659 TPythonDump pydump; // to prevent dump at mesh creation
3661 mesh = makeMesh( theMeshName );
3662 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3664 if ( mesh_i && theIDsOfElements.length() > 0 )
3666 TIDSortedElemSet elements;
3667 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3668 rotate(elements, theAxis, theAngleInRadians,
3669 false, theCopyGroups, & mesh_i->GetImpl());
3670 mesh_i->CreateGroupServants();
3672 if ( !myPreviewMode ) {
3673 pydump << mesh << " = " << this << ".RotateMakeMesh( "
3674 << theIDsOfElements << ", "
3676 << theAngleInRadians << ", "
3677 << theCopyGroups << ", '"
3678 << theMeshName << "' )";
3683 if (!myPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
3684 mesh_i->GetGroups();
3686 return mesh._retn();
3689 //=======================================================================
3690 //function : RotateObjectMakeMesh
3692 //=======================================================================
3694 SMESH::SMESH_Mesh_ptr
3695 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3696 const SMESH::AxisStruct& theAxis,
3697 CORBA::Double theAngleInRadians,
3698 CORBA::Boolean theCopyGroups,
3699 const char* theMeshName)
3701 SMESH::SMESH_Mesh_var mesh;
3702 SMESH_Mesh_i* mesh_i;
3704 {// open new scope to dump "MakeMesh" command
3705 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3707 TPythonDump pydump; // to prevent dump at mesh creation
3708 mesh = makeMesh( theMeshName );
3709 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3711 TIDSortedElemSet elements;
3713 idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3715 rotate(elements, theAxis, theAngleInRadians,
3716 false, theCopyGroups, & mesh_i->GetImpl());
3717 mesh_i->CreateGroupServants();
3719 if ( !myPreviewMode ) {
3720 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
3721 << theObject << ", "
3723 << theAngleInRadians << ", "
3724 << theCopyGroups << ", '"
3725 << theMeshName << "' )";
3730 if (!myPreviewMode && mesh_i)
3731 mesh_i->GetGroups();
3733 return mesh._retn();
3736 //=======================================================================
3739 //=======================================================================
3741 SMESH::ListOfGroups*
3742 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
3743 const SMESH::PointStruct& thePoint,
3744 const SMESH::double_array& theScaleFact,
3745 CORBA::Boolean theCopy,
3747 ::SMESH_Mesh* theTargetMesh)
3750 if ( theScaleFact.length() < 1 )
3751 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
3752 if ( theScaleFact.length() == 2 )
3753 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
3755 if ( theTargetMesh )
3758 TIDSortedElemSet elements;
3759 bool emptyIfIsMesh = myPreviewMode ? false : true;
3760 if ( !idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3765 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
3766 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
3768 double tol = std::numeric_limits<double>::max();
3770 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
3771 0, S[1], 0, thePoint.y * (1-S[1]),
3772 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
3774 TIDSortedElemSet copyElements;
3775 TPreviewMesh tmpMesh;
3776 TIDSortedElemSet* workElements = &elements;
3777 SMESH_Mesh* mesh = myMesh;
3779 if ( myPreviewMode )
3781 tmpMesh.Copy( elements, copyElements);
3782 if ( !theCopy && !theTargetMesh )
3784 TIDSortedElemSet elemsAround, elemsAroundCopy;
3785 getElementsAround( elements, GetMeshDS(), elemsAround );
3786 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3789 workElements = & copyElements;
3790 theMakeGroups = false;
3793 ::SMESH_MeshEditor anEditor( mesh );
3794 ::SMESH_MeshEditor::PGroupIDs groupIds =
3795 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3797 if(theCopy || myPreviewMode )
3798 storeResult(anEditor);
3800 if ( !myPreviewMode )
3802 if ( theTargetMesh )
3804 theTargetMesh->GetMeshDS()->Modified();
3808 myMesh->GetMeshDS()->Modified();
3809 myMesh->SetIsModified( true );
3813 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3816 //=======================================================================
3819 //=======================================================================
3821 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
3822 const SMESH::PointStruct& thePoint,
3823 const SMESH::double_array& theScaleFact,
3824 CORBA::Boolean theCopy)
3826 if ( !myPreviewMode ) {
3827 TPythonDump() << this << ".Scale( "
3828 << theObject << ", "
3829 << "SMESH.PointStruct( " << thePoint.x << ", "
3830 << thePoint.y << ", " << thePoint.z << " ) ,"
3831 << theScaleFact << ", "
3834 scale(theObject, thePoint, theScaleFact, theCopy, false);
3838 //=======================================================================
3839 //function : ScaleMakeGroups
3841 //=======================================================================
3843 SMESH::ListOfGroups*
3844 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3845 const SMESH::PointStruct& thePoint,
3846 const SMESH::double_array& theScaleFact)
3848 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3850 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
3851 if (!myPreviewMode) {
3852 DumpGroupsList(aPythonDump, aGroups);
3853 aPythonDump << this << ".Scale("
3855 << "SMESH.PointStruct(" <<thePoint.x << ","
3856 << thePoint.y << "," << thePoint.z << "),"
3857 << theScaleFact << ",True,True)";
3863 //=======================================================================
3864 //function : ScaleMakeMesh
3866 //=======================================================================
3868 SMESH::SMESH_Mesh_ptr
3869 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3870 const SMESH::PointStruct& thePoint,
3871 const SMESH::double_array& theScaleFact,
3872 CORBA::Boolean theCopyGroups,
3873 const char* theMeshName)
3875 SMESH_Mesh_i* mesh_i;
3876 SMESH::SMESH_Mesh_var mesh;
3877 { // open new scope to dump "MakeMesh" command
3878 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3880 TPythonDump pydump; // to prevent dump at mesh creation
3881 mesh = makeMesh( theMeshName );
3882 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3886 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
3887 mesh_i->CreateGroupServants();
3889 if ( !myPreviewMode )
3890 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
3891 << theObject << ", "
3892 << "SMESH.PointStruct( " << thePoint.x << ", "
3893 << thePoint.y << ", " << thePoint.z << " ) ,"
3894 << theScaleFact << ", "
3895 << theCopyGroups << ", '"
3896 << theMeshName << "' )";
3900 if (!myPreviewMode && mesh_i)
3901 mesh_i->GetGroups();
3903 return mesh._retn();
3907 //=======================================================================
3908 //function : FindCoincidentNodes
3910 //=======================================================================
3912 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance,
3913 SMESH::array_of_long_array_out GroupsOfNodes)
3917 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3918 ::SMESH_MeshEditor anEditor( myMesh );
3919 TIDSortedNodeSet nodes; // no input nodes
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++ ) {
3926 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
3927 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
3928 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
3929 aGroup.length( aListOfNodes.size() );
3930 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
3931 aGroup[ j ] = (*lIt)->GetID();
3933 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
3934 << Tolerance << " )";
3937 //=======================================================================
3938 //function : FindCoincidentNodesOnPart
3940 //=======================================================================
3941 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
3942 CORBA::Double Tolerance,
3943 SMESH::array_of_long_array_out GroupsOfNodes)
3947 TIDSortedNodeSet nodes;
3948 idSourceToNodeSet( theObject, GetMeshDS(), nodes );
3950 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3951 ::SMESH_MeshEditor anEditor( myMesh );
3953 anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
3955 GroupsOfNodes = new SMESH::array_of_long_array;
3956 GroupsOfNodes->length( aListOfListOfNodes.size() );
3957 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
3958 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
3960 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
3961 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
3962 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
3963 aGroup.length( aListOfNodes.size() );
3964 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
3965 aGroup[ j ] = (*lIt)->GetID();
3967 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
3969 << Tolerance << " )";
3972 //================================================================================
3974 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
3975 * ExceptSubMeshOrGroups
3977 //================================================================================
3979 void SMESH_MeshEditor_i::
3980 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
3981 CORBA::Double theTolerance,
3982 SMESH::array_of_long_array_out theGroupsOfNodes,
3983 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups)
3987 TIDSortedNodeSet nodes;
3988 idSourceToNodeSet( theObject, GetMeshDS(), nodes );
3990 for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
3992 TIDSortedNodeSet exceptNodes;
3993 idSourceToNodeSet( theExceptSubMeshOrGroups[i], GetMeshDS(), exceptNodes );
3994 TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
3995 for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
3996 nodes.erase( *avoidNode );
3998 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3999 ::SMESH_MeshEditor anEditor( myMesh );
4001 anEditor.FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
4003 theGroupsOfNodes = new SMESH::array_of_long_array;
4004 theGroupsOfNodes->length( aListOfListOfNodes.size() );
4005 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
4006 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
4008 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
4009 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
4010 SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
4011 aGroup.length( aListOfNodes.size() );
4012 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
4013 aGroup[ j ] = (*lIt)->GetID();
4015 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
4017 << theTolerance << ", "
4018 << theExceptSubMeshOrGroups << " )";
4021 //=======================================================================
4022 //function : MergeNodes
4024 //=======================================================================
4026 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
4030 SMESHDS_Mesh* aMesh = GetMeshDS();
4032 TPythonDump aTPythonDump;
4033 aTPythonDump << this << ".MergeNodes([";
4034 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
4035 for (int i = 0; i < GroupsOfNodes.length(); i++)
4037 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
4038 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
4039 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
4040 for ( int j = 0; j < aNodeGroup.length(); j++ )
4042 CORBA::Long index = aNodeGroup[ j ];
4043 const SMDS_MeshNode * node = aMesh->FindNode(index);
4045 aListOfNodes.push_back( node );
4047 if ( aListOfNodes.size() < 2 )
4048 aListOfListOfNodes.pop_back();
4050 if ( i > 0 ) aTPythonDump << ", ";
4051 aTPythonDump << aNodeGroup;
4053 ::SMESH_MeshEditor anEditor( myMesh );
4054 anEditor.MergeNodes( aListOfListOfNodes );
4056 aTPythonDump << "])";
4057 myMesh->GetMeshDS()->Modified();
4058 myMesh->SetIsModified( true );
4061 //=======================================================================
4062 //function : FindEqualElements
4064 //=======================================================================
4065 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
4066 SMESH::array_of_long_array_out GroupsOfElementsID)
4070 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
4071 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
4073 typedef list<int> TListOfIDs;
4074 set<const SMDS_MeshElement*> elems;
4075 SMESH::long_array_var aElementsId = theObject->GetIDs();
4076 SMESHDS_Mesh* aMesh = GetMeshDS();
4078 for(int i = 0; i < aElementsId->length(); i++) {
4079 CORBA::Long anID = aElementsId[i];
4080 const SMDS_MeshElement * elem = aMesh->FindElement(anID);
4086 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4087 ::SMESH_MeshEditor anEditor( myMesh );
4088 anEditor.FindEqualElements( elems, aListOfListOfElementsID );
4090 GroupsOfElementsID = new SMESH::array_of_long_array;
4091 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
4093 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt = aListOfListOfElementsID.begin();
4094 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j) {
4095 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
4096 TListOfIDs& listOfIDs = *arraysIt;
4097 aGroup.length( listOfIDs.size() );
4098 TListOfIDs::iterator idIt = listOfIDs.begin();
4099 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k ) {
4100 aGroup[ k ] = *idIt;
4104 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
4109 //=======================================================================
4110 //function : MergeElements
4112 //=======================================================================
4114 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
4118 TPythonDump aTPythonDump;
4119 aTPythonDump << this << ".MergeElements( [";
4121 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4123 for (int i = 0; i < GroupsOfElementsID.length(); i++) {
4124 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
4125 aListOfListOfElementsID.push_back( list< int >() );
4126 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
4127 for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
4128 CORBA::Long id = anElemsIDGroup[ j ];
4129 aListOfElemsID.push_back( id );
4131 if ( aListOfElemsID.size() < 2 )
4132 aListOfListOfElementsID.pop_back();
4133 if ( i > 0 ) aTPythonDump << ", ";
4134 aTPythonDump << anElemsIDGroup;
4137 ::SMESH_MeshEditor anEditor( myMesh );
4138 anEditor.MergeElements(aListOfListOfElementsID);
4139 myMesh->GetMeshDS()->Modified();
4140 myMesh->SetIsModified( true );
4142 aTPythonDump << "] )";
4145 //=======================================================================
4146 //function : MergeEqualElements
4148 //=======================================================================
4150 void SMESH_MeshEditor_i::MergeEqualElements()
4154 ::SMESH_MeshEditor anEditor( myMesh );
4155 anEditor.MergeEqualElements();
4157 myMesh->GetMeshDS()->Modified();
4159 TPythonDump() << this << ".MergeEqualElements()";
4162 //=============================================================================
4164 * Move the node to a given point
4166 //=============================================================================
4168 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
4173 initData(/*deleteSearchers=*/false);
4175 const SMDS_MeshNode * node = GetMeshDS()->FindNode( NodeID );
4179 if ( theNodeSearcher )
4180 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4182 if ( myPreviewMode ) // make preview data
4184 // in a preview mesh, make edges linked to a node
4185 TPreviewMesh tmpMesh;
4186 TIDSortedElemSet linkedNodes;
4187 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4188 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4189 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
4190 for ( ; nIt != linkedNodes.end(); ++nIt )
4192 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
4193 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
4197 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
4198 // fill preview data
4199 ::SMESH_MeshEditor anEditor( & tmpMesh );
4200 storeResult( anEditor );
4202 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4203 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4205 GetMeshDS()->MoveNode(node, x, y, z);
4207 if ( !myPreviewMode )
4209 // Update Python script
4210 TPythonDump() << "isDone = " << this << ".MoveNode( "
4211 << NodeID << ", " << x << ", " << y << ", " << z << " )";
4212 myMesh->GetMeshDS()->Modified();
4213 myMesh->SetIsModified( true );
4219 //================================================================================
4221 * \brief Return ID of node closest to a given point
4223 //================================================================================
4225 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
4229 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4231 if ( !theNodeSearcher ) {
4232 ::SMESH_MeshEditor anEditor( myMesh );
4233 theNodeSearcher = anEditor.GetNodeSearcher();
4236 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
4237 return node->GetID();
4242 //================================================================================
4244 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
4245 * move the node closest to the point to point's location and return ID of the node
4247 //================================================================================
4249 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
4252 CORBA::Long theNodeID)
4254 // We keep theNodeSearcher until any mesh modification:
4255 // 1) initData() deletes theNodeSearcher at any edition,
4256 // 2) TSearchersDeleter - at any mesh compute event and mesh change
4258 initData(/*deleteSearchers=*/false);
4260 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4262 int nodeID = theNodeID;
4263 const SMDS_MeshNode* node = GetMeshDS()->FindNode( nodeID );
4264 if ( !node ) // preview moving node
4266 if ( !theNodeSearcher ) {
4267 ::SMESH_MeshEditor anEditor( myMesh );
4268 theNodeSearcher = anEditor.GetNodeSearcher();
4271 node = theNodeSearcher->FindClosestTo( p );
4274 nodeID = node->GetID();
4275 if ( myPreviewMode ) // make preview data
4277 // in a preview mesh, make edges linked to a node
4278 TPreviewMesh tmpMesh;
4279 TIDSortedElemSet linkedNodes;
4280 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4281 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4282 for ( ; nIt != linkedNodes.end(); ++nIt )
4284 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
4285 tmpMesh.Copy( &edge );
4288 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
4290 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
4291 // fill preview data
4292 ::SMESH_MeshEditor anEditor( & tmpMesh );
4293 storeResult( anEditor );
4295 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4297 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4301 GetMeshDS()->MoveNode(node, x, y, z);
4305 if ( !myPreviewMode )
4307 TPythonDump() << "nodeID = " << this
4308 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
4309 << ", " << nodeID << " )";
4311 myMesh->GetMeshDS()->Modified();
4312 myMesh->SetIsModified( true );
4318 //=======================================================================
4320 * Return elements of given type where the given point is IN or ON.
4322 * 'ALL' type means elements of any type excluding nodes
4324 //=======================================================================
4326 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
4329 SMESH::ElementType type)
4331 SMESH::long_array_var res = new SMESH::long_array;
4332 vector< const SMDS_MeshElement* > foundElems;
4334 theSearchersDeleter.Set( myMesh );
4335 if ( !theElementSearcher ) {
4336 ::SMESH_MeshEditor anEditor( myMesh );
4337 theElementSearcher = anEditor.GetElementSearcher();
4339 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4340 SMDSAbs_ElementType( type ),
4342 res->length( foundElems.size() );
4343 for ( int i = 0; i < foundElems.size(); ++i )
4344 res[i] = foundElems[i]->GetID();
4346 if ( !myPreviewMode ) // call from tui
4347 TPythonDump() << "res = " << this << ".FindElementsByPoint( "
4356 //=======================================================================
4357 //function : FindAmongElementsByPoint
4358 //purpose : Searching among the given elements, return elements of given type
4359 // where the given point is IN or ON.
4360 // 'ALL' type means elements of any type excluding nodes
4361 //=======================================================================
4364 SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
4368 SMESH::ElementType type)
4370 SMESH::long_array_var res = new SMESH::long_array;
4372 SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
4373 if ( types->length() == 1 && // a part contains only nodes or 0D elements
4374 ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D ) &&
4375 type != types[0] ) // but search of elements of dim > 0
4378 if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
4379 return FindElementsByPoint( x,y,z, type );
4381 string partIOR = SMESH_Gen_i::GetORB()->object_to_string( elementIDs );
4382 if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( elementIDs ))
4383 // take into account passible group modification
4384 partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() );
4385 partIOR += SMESH_Comment( type );
4387 TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
4389 theSearchersDeleter.Set( myMesh, partIOR );
4390 if ( !theElementSearcher )
4392 // create a searcher from elementIDs
4393 SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
4394 SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
4396 if ( !idSourceToSet( elementIDs, meshDS, elements,
4397 SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
4400 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
4401 SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
4403 ::SMESH_MeshEditor anEditor( myMesh );
4404 theElementSearcher = anEditor.GetElementSearcher(elemsIt);
4407 vector< const SMDS_MeshElement* > foundElems;
4409 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4410 SMDSAbs_ElementType( type ),
4412 res->length( foundElems.size() );
4413 for ( int i = 0; i < foundElems.size(); ++i )
4414 res[i] = foundElems[i]->GetID();
4416 if ( !myPreviewMode ) // call from tui
4417 TPythonDump() << "res = " << this << ".FindAmongElementsByPoint( "
4418 << elementIDs << ", "
4427 //=======================================================================
4428 //function : GetPointState
4429 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
4430 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
4431 //=======================================================================
4433 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
4437 theSearchersDeleter.Set( myMesh );
4438 if ( !theElementSearcher ) {
4439 ::SMESH_MeshEditor anEditor( myMesh );
4440 theElementSearcher = anEditor.GetElementSearcher();
4442 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
4445 //=======================================================================
4446 //function : convError
4448 //=======================================================================
4450 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
4452 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
4456 RETCASE( SEW_BORDER1_NOT_FOUND );
4457 RETCASE( SEW_BORDER2_NOT_FOUND );
4458 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
4459 RETCASE( SEW_BAD_SIDE_NODES );
4460 RETCASE( SEW_VOLUMES_TO_SPLIT );
4461 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
4462 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
4463 RETCASE( SEW_BAD_SIDE1_NODES );
4464 RETCASE( SEW_BAD_SIDE2_NODES );
4466 return SMESH::SMESH_MeshEditor::SEW_OK;
4469 //=======================================================================
4470 //function : SewFreeBorders
4472 //=======================================================================
4474 SMESH::SMESH_MeshEditor::Sew_Error
4475 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
4476 CORBA::Long SecondNodeID1,
4477 CORBA::Long LastNodeID1,
4478 CORBA::Long FirstNodeID2,
4479 CORBA::Long SecondNodeID2,
4480 CORBA::Long LastNodeID2,
4481 CORBA::Boolean CreatePolygons,
4482 CORBA::Boolean CreatePolyedrs)
4486 SMESHDS_Mesh* aMesh = GetMeshDS();
4488 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4489 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4490 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4491 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4492 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4493 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
4495 if (!aBorderFirstNode ||
4496 !aBorderSecondNode||
4498 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4499 if (!aSide2FirstNode ||
4500 !aSide2SecondNode ||
4502 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4504 TPythonDump() << "error = " << this << ".SewFreeBorders( "
4505 << FirstNodeID1 << ", "
4506 << SecondNodeID1 << ", "
4507 << LastNodeID1 << ", "
4508 << FirstNodeID2 << ", "
4509 << SecondNodeID2 << ", "
4510 << LastNodeID2 << ", "
4511 << CreatePolygons<< ", "
4512 << CreatePolyedrs<< " )";
4514 ::SMESH_MeshEditor anEditor( myMesh );
4515 SMESH::SMESH_MeshEditor::Sew_Error error =
4516 convError( anEditor.SewFreeBorder (aBorderFirstNode,
4526 storeResult(anEditor);
4528 myMesh->GetMeshDS()->Modified();
4529 myMesh->SetIsModified( true );
4535 //=======================================================================
4536 //function : SewConformFreeBorders
4538 //=======================================================================
4540 SMESH::SMESH_MeshEditor::Sew_Error
4541 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
4542 CORBA::Long SecondNodeID1,
4543 CORBA::Long LastNodeID1,
4544 CORBA::Long FirstNodeID2,
4545 CORBA::Long SecondNodeID2)
4549 SMESHDS_Mesh* aMesh = GetMeshDS();
4551 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4552 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4553 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4554 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4555 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4556 const SMDS_MeshNode* aSide2ThirdNode = 0;
4558 if (!aBorderFirstNode ||
4559 !aBorderSecondNode||
4561 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4562 if (!aSide2FirstNode ||
4564 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4566 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
4567 << FirstNodeID1 << ", "
4568 << SecondNodeID1 << ", "
4569 << LastNodeID1 << ", "
4570 << FirstNodeID2 << ", "
4571 << SecondNodeID2 << " )";
4573 ::SMESH_MeshEditor anEditor( myMesh );
4574 SMESH::SMESH_MeshEditor::Sew_Error error =
4575 convError( anEditor.SewFreeBorder (aBorderFirstNode,
4584 storeResult(anEditor);
4586 myMesh->GetMeshDS()->Modified();
4587 myMesh->SetIsModified( true );
4593 //=======================================================================
4594 //function : SewBorderToSide
4596 //=======================================================================
4598 SMESH::SMESH_MeshEditor::Sew_Error
4599 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
4600 CORBA::Long SecondNodeIDOnFreeBorder,
4601 CORBA::Long LastNodeIDOnFreeBorder,
4602 CORBA::Long FirstNodeIDOnSide,
4603 CORBA::Long LastNodeIDOnSide,
4604 CORBA::Boolean CreatePolygons,
4605 CORBA::Boolean CreatePolyedrs)
4609 SMESHDS_Mesh* aMesh = GetMeshDS();
4611 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
4612 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
4613 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
4614 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
4615 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
4616 const SMDS_MeshNode* aSide2ThirdNode = 0;
4618 if (!aBorderFirstNode ||
4619 !aBorderSecondNode||
4621 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4622 if (!aSide2FirstNode ||
4624 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
4626 TPythonDump() << "error = " << this << ".SewBorderToSide( "
4627 << FirstNodeIDOnFreeBorder << ", "
4628 << SecondNodeIDOnFreeBorder << ", "
4629 << LastNodeIDOnFreeBorder << ", "
4630 << FirstNodeIDOnSide << ", "
4631 << LastNodeIDOnSide << ", "
4632 << CreatePolygons << ", "
4633 << CreatePolyedrs << ") ";
4635 ::SMESH_MeshEditor anEditor( myMesh );
4636 SMESH::SMESH_MeshEditor::Sew_Error error =
4637 convError( anEditor.SewFreeBorder (aBorderFirstNode,
4647 storeResult(anEditor);
4649 myMesh->GetMeshDS()->Modified();
4650 myMesh->SetIsModified( true );
4656 //=======================================================================
4657 //function : SewSideElements
4659 //=======================================================================
4661 SMESH::SMESH_MeshEditor::Sew_Error
4662 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
4663 const SMESH::long_array& IDsOfSide2Elements,
4664 CORBA::Long NodeID1OfSide1ToMerge,
4665 CORBA::Long NodeID1OfSide2ToMerge,
4666 CORBA::Long NodeID2OfSide1ToMerge,
4667 CORBA::Long NodeID2OfSide2ToMerge)
4671 SMESHDS_Mesh* aMesh = GetMeshDS();
4673 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
4674 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
4675 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
4676 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
4678 if (!aFirstNode1ToMerge ||
4679 !aFirstNode2ToMerge )
4680 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
4681 if (!aSecondNode1ToMerge||
4682 !aSecondNode2ToMerge)
4683 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
4685 TIDSortedElemSet aSide1Elems, aSide2Elems;
4686 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
4687 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
4689 TPythonDump() << "error = " << this << ".SewSideElements( "
4690 << IDsOfSide1Elements << ", "
4691 << IDsOfSide2Elements << ", "
4692 << NodeID1OfSide1ToMerge << ", "
4693 << NodeID1OfSide2ToMerge << ", "
4694 << NodeID2OfSide1ToMerge << ", "
4695 << NodeID2OfSide2ToMerge << ")";
4697 ::SMESH_MeshEditor anEditor( myMesh );
4698 SMESH::SMESH_MeshEditor::Sew_Error error =
4699 convError( anEditor.SewSideElements (aSide1Elems, aSide2Elems,
4702 aSecondNode1ToMerge,
4703 aSecondNode2ToMerge));
4705 storeResult(anEditor);
4707 myMesh->GetMeshDS()->Modified();
4708 myMesh->SetIsModified( true );
4713 //================================================================================
4715 * \brief Set new nodes for given element
4716 * \param ide - element id
4717 * \param newIDs - new node ids
4718 * \retval CORBA::Boolean - true if result is OK
4720 //================================================================================
4722 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
4723 const SMESH::long_array& newIDs)
4727 const SMDS_MeshElement* elem = GetMeshDS()->FindElement(ide);
4728 if(!elem) return false;
4730 int nbn = newIDs.length();
4732 vector<const SMDS_MeshNode*> aNodes(nbn);
4735 const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(newIDs[i]);
4738 aNodes[nbn1] = aNode;
4741 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
4742 << ide << ", " << newIDs << " )";
4744 MESSAGE("ChangeElementNodes");
4745 bool res = GetMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
4747 myMesh->GetMeshDS()->Modified();
4749 myMesh->SetIsModified( true );
4754 //================================================================================
4756 * \brief Update myLastCreated* or myPreviewData
4757 * \param anEditor - it contains last modification results
4759 //================================================================================
4761 void SMESH_MeshEditor_i::storeResult(::SMESH_MeshEditor& anEditor)
4763 if ( myPreviewMode ) { // --- MeshPreviewStruct filling ---
4765 list<int> aNodesConnectivity;
4766 typedef map<int, int> TNodesMap;
4769 TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( anEditor.GetMesh() );
4770 SMDSAbs_ElementType previewType = aPreviewMesh->myPreviewType;
4772 SMESHDS_Mesh* aMeshDS = anEditor.GetMeshDS();
4773 int nbEdges = aMeshDS->NbEdges();
4774 int nbFaces = aMeshDS->NbFaces();
4775 int nbVolum = aMeshDS->NbVolumes();
4776 switch ( previewType ) {
4777 case SMDSAbs_Edge : nbFaces = nbVolum = 0; break;
4778 case SMDSAbs_Face : nbEdges = nbVolum = 0; break;
4779 case SMDSAbs_Volume: nbEdges = nbFaces = 0; break;
4782 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
4783 myPreviewData->elementTypes.length(nbEdges + nbFaces + nbVolum);
4785 SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator();
4787 while ( itMeshElems->more() ) {
4788 const SMDS_MeshElement* aMeshElem = itMeshElems->next();
4789 if ( previewType != SMDSAbs_All && aMeshElem->GetType() != previewType )
4792 SMDS_ElemIteratorPtr itElemNodes = aMeshElem->nodesIterator();
4793 while ( itElemNodes->more() ) {
4794 const SMDS_MeshNode* aMeshNode =
4795 static_cast<const SMDS_MeshNode*>( itElemNodes->next() );
4796 int aNodeID = aMeshNode->GetID();
4797 TNodesMap::iterator anIter = nodesMap.find(aNodeID);
4798 if ( anIter == nodesMap.end() ) {
4799 // filling the nodes coordinates
4800 myPreviewData->nodesXYZ[j].x = aMeshNode->X();
4801 myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
4802 myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
4803 anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
4806 aNodesConnectivity.push_back(anIter->second);
4809 // filling the elements types
4810 SMDSAbs_ElementType aType;
4812 /*if (aMeshElem->GetType() == SMDSAbs_Volume) {
4813 aType = SMDSAbs_Node;
4817 aType = aMeshElem->GetType();
4818 isPoly = aMeshElem->IsPoly();
4821 myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
4822 myPreviewData->elementTypes[i].isPoly = isPoly;
4823 myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
4827 myPreviewData->nodesXYZ.length( j );
4829 // filling the elements connectivities
4830 list<int>::iterator aConnIter = aNodesConnectivity.begin();
4831 myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
4832 for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
4833 myPreviewData->elementConnectivities[i] = *aConnIter;
4839 // append new nodes into myLastCreatedNodes
4840 const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedNodes();
4841 int j = myLastCreatedNodes->length();
4842 int newLen = j + aSeq.Length();
4843 myLastCreatedNodes->length( newLen );
4844 for(int i=0; j<newLen; i++,j++)
4845 myLastCreatedNodes[j] = aSeq.Value(i+1)->GetID();
4848 // append new elements into myLastCreatedElems
4849 const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedElems();
4850 int j = myLastCreatedElems->length();
4851 int newLen = j + aSeq.Length();
4852 myLastCreatedElems->length( newLen );
4853 for(int i=0; j<newLen; i++,j++)
4854 myLastCreatedElems[j] = aSeq.Value(i+1)->GetID();
4858 //================================================================================
4860 * Return data of mesh edition preview
4862 //================================================================================
4864 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
4866 return myPreviewData._retn();
4869 //================================================================================
4871 * \brief Returns list of it's IDs of created nodes
4872 * \retval SMESH::long_array* - list of node ID
4874 //================================================================================
4876 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
4878 return myLastCreatedNodes._retn();
4881 //================================================================================
4883 * \brief Returns list of it's IDs of created elements
4884 * \retval SMESH::long_array* - list of elements' ID
4886 //================================================================================
4888 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
4890 return myLastCreatedElems._retn();
4893 //=======================================================================
4894 //function : ConvertToQuadratic
4896 //=======================================================================
4898 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
4900 ::SMESH_MeshEditor anEditor( myMesh );
4901 anEditor.ConvertToQuadratic(theForce3d);
4902 TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )";
4903 myMesh->GetMeshDS()->Modified();
4904 myMesh->SetIsModified( true );
4907 //=======================================================================
4908 //function : ConvertFromQuadratic
4910 //=======================================================================
4912 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
4914 ::SMESH_MeshEditor anEditor( myMesh );
4915 CORBA::Boolean isDone = anEditor.ConvertFromQuadratic();
4916 TPythonDump() << this << ".ConvertFromQuadratic()";
4917 myMesh->GetMeshDS()->Modified();
4919 myMesh->SetIsModified( true );
4922 //================================================================================
4924 * \brief Makes a part of the mesh quadratic
4926 //================================================================================
4928 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
4929 SMESH::SMESH_IDSource_ptr theObject)
4930 throw (SALOME::SALOME_Exception)
4932 Unexpect aCatch(SALOME_SalomeException);
4934 TIDSortedElemSet elems;
4935 if ( idSourceToSet( theObject, GetMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
4937 if ( elems.empty() )
4939 ConvertToQuadratic( theForce3d );
4941 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
4943 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
4947 ::SMESH_MeshEditor anEditor( myMesh );
4948 anEditor.ConvertToQuadratic(theForce3d, elems);
4951 myMesh->GetMeshDS()->Modified();
4952 myMesh->SetIsModified( true );
4954 pyDump << this << ".ConvertToQuadraticObject( "<<theForce3d<<", "<<theObject<<" )";
4957 //================================================================================
4959 * \brief Makes a part of the mesh linear
4961 //================================================================================
4963 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
4964 throw (SALOME::SALOME_Exception)
4966 Unexpect aCatch(SALOME_SalomeException);
4968 TIDSortedElemSet elems;
4969 if ( idSourceToSet( theObject, GetMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
4971 if ( elems.empty() )
4973 ConvertFromQuadratic();
4975 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
4977 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
4981 ::SMESH_MeshEditor anEditor( myMesh );
4982 anEditor.ConvertFromQuadratic(elems);
4985 myMesh->GetMeshDS()->Modified();
4986 myMesh->SetIsModified( true );
4988 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
4991 //=======================================================================
4992 //function : makeMesh
4993 //purpose : create a named imported mesh
4994 //=======================================================================
4996 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
4998 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
4999 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
5000 SALOMEDS::Study_var study = gen->GetCurrentStudy();
5001 SALOMEDS::SObject_var meshSO = gen->ObjectToSObject( study, mesh );
5002 gen->SetName( meshSO, theMeshName, "Mesh" );
5003 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
5005 return mesh._retn();
5008 //=======================================================================
5009 //function : DumpGroupsList
5011 //=======================================================================
5012 void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump & theDumpPython,
5013 const SMESH::ListOfGroups * theGroupList)
5015 bool isDumpGroupList = theGroupList && theGroupList->length() > 0;
5016 if(isDumpGroupList) {
5017 theDumpPython << theGroupList << " = ";
5021 //================================================================================
5023 \brief Generates the unique group name.
5024 \param thePrefix name prefix
5027 //================================================================================
5028 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
5030 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
5031 set<string> groupNames;
5033 // Get existing group names
5034 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
5035 SMESH::SMESH_GroupBase_var aGroup = groups[i];
5036 if (CORBA::is_nil(aGroup))
5039 groupNames.insert(aGroup->GetName());
5043 string name = thePrefix;
5046 while (!groupNames.insert(name).second) {
5051 TCollection_AsciiString nbStr(index+1);
5052 name.resize( name.rfind('_')+1 );
5053 name += nbStr.ToCString();
5061 //================================================================================
5063 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5064 \param theNodes - identifiers of nodes to be doubled
5065 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
5066 nodes. If list of element identifiers is empty then nodes are doubled but
5067 they not assigned to elements
5068 \return TRUE if operation has been completed successfully, FALSE otherwise
5069 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
5071 //================================================================================
5073 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
5074 const SMESH::long_array& theModifiedElems )
5078 ::SMESH_MeshEditor aMeshEditor( myMesh );
5079 list< int > aListOfNodes;
5081 for ( i = 0, n = theNodes.length(); i < n; i++ )
5082 aListOfNodes.push_back( theNodes[ i ] );
5084 list< int > aListOfElems;
5085 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5086 aListOfElems.push_back( theModifiedElems[ i ] );
5088 bool aResult = aMeshEditor.DoubleNodes( aListOfNodes, aListOfElems );
5090 myMesh->GetMeshDS()->Modified();
5091 storeResult( aMeshEditor) ;
5093 myMesh->SetIsModified( true );
5095 // Update Python script
5096 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
5101 //================================================================================
5103 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5104 This method provided for convenience works as DoubleNodes() described above.
5105 \param theNodeId - identifier of node to be doubled.
5106 \param theModifiedElems - identifiers of elements to be updated.
5107 \return TRUE if operation has been completed successfully, FALSE otherwise
5108 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
5110 //================================================================================
5112 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
5113 const SMESH::long_array& theModifiedElems )
5115 SMESH::long_array_var aNodes = new SMESH::long_array;
5116 aNodes->length( 1 );
5117 aNodes[ 0 ] = theNodeId;
5119 TPythonDump pyDump; // suppress dump by the next line
5121 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
5123 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
5128 //================================================================================
5130 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5131 This method provided for convenience works as DoubleNodes() described above.
5132 \param theNodes - group of nodes to be doubled.
5133 \param theModifiedElems - group of elements to be updated.
5134 \return TRUE if operation has been completed successfully, FALSE otherwise
5135 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
5137 //================================================================================
5139 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
5140 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5142 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5145 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5146 SMESH::long_array_var aModifiedElems;
5147 if ( !CORBA::is_nil( theModifiedElems ) )
5148 aModifiedElems = theModifiedElems->GetListOfID();
5151 aModifiedElems = new SMESH::long_array;
5152 aModifiedElems->length( 0 );
5155 TPythonDump pyDump; // suppress dump by the next line
5157 bool done = DoubleNodes( aNodes, aModifiedElems );
5159 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
5165 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5166 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
5167 * \param theNodes - group of nodes to be doubled.
5168 * \param theModifiedElems - group of elements to be updated.
5169 * \return a new group with newly created nodes
5170 * \sa DoubleNodeGroup()
5172 SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
5173 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5175 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5178 SMESH::SMESH_Group_var aNewGroup;
5181 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5182 SMESH::long_array_var aModifiedElems;
5183 if ( !CORBA::is_nil( theModifiedElems ) )
5184 aModifiedElems = theModifiedElems->GetListOfID();
5186 aModifiedElems = new SMESH::long_array;
5187 aModifiedElems->length( 0 );
5190 TPythonDump pyDump; // suppress dump by the next line
5192 bool aResult = DoubleNodes( aNodes, aModifiedElems );
5196 // Create group with newly created nodes
5197 SMESH::long_array_var anIds = GetLastCreatedNodes();
5198 if (anIds->length() > 0) {
5199 string anUnindexedName (theNodes->GetName());
5200 string aNewName = generateGroupName(anUnindexedName + "_double");
5201 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5202 aNewGroup->Add(anIds);
5206 pyDump << "createdNodes = " << this << ".DoubleNodeGroupNew( " << theNodes << ", "
5207 << theModifiedElems << " )";
5209 return aNewGroup._retn();
5212 //================================================================================
5214 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5215 This method provided for convenience works as DoubleNodes() described above.
5216 \param theNodes - list of groups of nodes to be doubled
5217 \param theModifiedElems - list of groups of elements to be updated.
5218 \return TRUE if operation has been completed successfully, FALSE otherwise
5219 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
5221 //================================================================================
5223 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
5224 const SMESH::ListOfGroups& theModifiedElems )
5228 ::SMESH_MeshEditor aMeshEditor( myMesh );
5230 std::list< int > aNodes;
5232 for ( i = 0, n = theNodes.length(); i < n; i++ )
5234 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
5235 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
5237 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5238 for ( j = 0, m = aCurr->length(); j < m; j++ )
5239 aNodes.push_back( aCurr[ j ] );
5243 std::list< int > anElems;
5244 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5246 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
5247 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
5249 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5250 for ( j = 0, m = aCurr->length(); j < m; j++ )
5251 anElems.push_back( aCurr[ j ] );
5255 bool aResult = aMeshEditor.DoubleNodes( aNodes, anElems );
5257 storeResult( aMeshEditor) ;
5259 myMesh->GetMeshDS()->Modified();
5261 myMesh->SetIsModified( true );
5264 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
5269 //================================================================================
5271 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5272 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
5273 * \param theNodes - group of nodes to be doubled.
5274 * \param theModifiedElems - group of elements to be updated.
5275 * \return a new group with newly created nodes
5276 * \sa DoubleNodeGroups()
5278 //================================================================================
5280 SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
5281 const SMESH::ListOfGroups& theModifiedElems )
5283 SMESH::SMESH_Group_var aNewGroup;
5285 TPythonDump pyDump; // suppress dump by the next line
5287 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
5291 // Create group with newly created nodes
5292 SMESH::long_array_var anIds = GetLastCreatedNodes();
5293 if (anIds->length() > 0) {
5294 string anUnindexedName (theNodes[0]->GetName());
5295 string aNewName = generateGroupName(anUnindexedName + "_double");
5296 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5297 aNewGroup->Add(anIds);
5301 pyDump << "createdNodes = " << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
5302 << theModifiedElems << " )";
5304 return aNewGroup._retn();
5308 //================================================================================
5310 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5311 \param theElems - the list of elements (edges or faces) to be replicated
5312 The nodes for duplication could be found from these elements
5313 \param theNodesNot - list of nodes to NOT replicate
5314 \param theAffectedElems - the list of elements (cells and edges) to which the
5315 replicated nodes should be associated to.
5316 \return TRUE if operation has been completed successfully, FALSE otherwise
5317 \sa DoubleNodeGroup(), DoubleNodeGroups()
5319 //================================================================================
5321 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
5322 const SMESH::long_array& theNodesNot,
5323 const SMESH::long_array& theAffectedElems )
5328 ::SMESH_MeshEditor aMeshEditor( myMesh );
5330 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5331 TIDSortedElemSet anElems, aNodes, anAffected;
5332 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5333 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5334 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
5336 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5338 storeResult( aMeshEditor) ;
5340 myMesh->GetMeshDS()->Modified();
5342 myMesh->SetIsModified( true );
5344 // Update Python script
5345 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
5346 << theNodesNot << ", " << theAffectedElems << " )";
5350 //================================================================================
5352 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5353 \param theElems - the list of elements (edges or faces) to be replicated
5354 The nodes for duplication could be found from these elements
5355 \param theNodesNot - list of nodes to NOT replicate
5356 \param theShape - shape to detect affected elements (element which geometric center
5357 located on or inside shape).
5358 The replicated nodes should be associated to affected elements.
5359 \return TRUE if operation has been completed successfully, FALSE otherwise
5360 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
5362 //================================================================================
5364 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
5365 const SMESH::long_array& theNodesNot,
5366 GEOM::GEOM_Object_ptr theShape )
5371 ::SMESH_MeshEditor aMeshEditor( myMesh );
5373 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5374 TIDSortedElemSet anElems, aNodes;
5375 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5376 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5378 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5379 bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5381 storeResult( aMeshEditor) ;
5383 myMesh->GetMeshDS()->Modified();
5385 myMesh->SetIsModified( true );
5387 // Update Python script
5388 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
5389 << theNodesNot << ", " << theShape << " )";
5393 //================================================================================
5395 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5396 \param theElems - group of of elements (edges or faces) to be replicated
5397 \param theNodesNot - group of nodes not to replicated
5398 \param theAffectedElems - group of elements to which the replicated nodes
5399 should be associated to.
5400 \return TRUE if operation has been completed successfully, FALSE otherwise
5401 \sa DoubleNodes(), DoubleNodeGroups()
5403 //================================================================================
5405 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
5406 SMESH::SMESH_GroupBase_ptr theNodesNot,
5407 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5409 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5414 ::SMESH_MeshEditor aMeshEditor( myMesh );
5416 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5417 TIDSortedElemSet anElems, aNodes, anAffected;
5418 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5419 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5420 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5422 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5424 storeResult( aMeshEditor) ;
5426 myMesh->GetMeshDS()->Modified();
5428 myMesh->SetIsModified( true );
5430 // Update Python script
5431 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
5432 << theNodesNot << ", " << theAffectedElems << " )";
5437 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5438 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
5439 * \param theElems - group of of elements (edges or faces) to be replicated
5440 * \param theNodesNot - group of nodes not to replicated
5441 * \param theAffectedElems - group of elements to which the replicated nodes
5442 * should be associated to.
5443 * \return a new group with newly created elements
5444 * \sa DoubleNodeElemGroup()
5446 SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
5447 SMESH::SMESH_GroupBase_ptr theNodesNot,
5448 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5450 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5453 SMESH::SMESH_Group_var aNewGroup;
5457 ::SMESH_MeshEditor aMeshEditor( myMesh );
5459 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5460 TIDSortedElemSet anElems, aNodes, anAffected;
5461 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5462 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5463 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5466 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5468 storeResult( aMeshEditor) ;
5471 myMesh->SetIsModified( true );
5473 // Create group with newly created elements
5474 SMESH::long_array_var anIds = GetLastCreatedElems();
5475 if (anIds->length() > 0) {
5476 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5477 string anUnindexedName (theElems->GetName());
5478 string aNewName = generateGroupName(anUnindexedName + "_double");
5479 aNewGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5480 aNewGroup->Add(anIds);
5484 // Update Python script
5485 TPythonDump() << "createdElems = " << this << ".DoubleNodeElemGroupNew( " << theElems << ", "
5486 << theNodesNot << ", " << theAffectedElems << " )";
5487 return aNewGroup._retn();
5490 //================================================================================
5492 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5493 \param theElems - group of of elements (edges or faces) to be replicated
5494 \param theNodesNot - group of nodes not to replicated
5495 \param theShape - shape to detect affected elements (element which geometric center
5496 located on or inside shape).
5497 The replicated nodes should be associated to affected elements.
5498 \return TRUE if operation has been completed successfully, FALSE otherwise
5499 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
5501 //================================================================================
5503 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
5504 SMESH::SMESH_GroupBase_ptr theNodesNot,
5505 GEOM::GEOM_Object_ptr theShape )
5508 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5513 ::SMESH_MeshEditor aMeshEditor( myMesh );
5515 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5516 TIDSortedElemSet anElems, aNodes, anAffected;
5517 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5518 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5520 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5521 bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5523 storeResult( aMeshEditor) ;
5525 myMesh->GetMeshDS()->Modified();
5527 myMesh->SetIsModified( true );
5529 // Update Python script
5530 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
5531 << theNodesNot << ", " << theShape << " )";
5535 //================================================================================
5537 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5538 This method provided for convenience works as DoubleNodes() described above.
5539 \param theElems - list of groups of elements (edges or faces) to be replicated
5540 \param theNodesNot - list of groups of nodes not to replicated
5541 \param theAffectedElems - group of elements to which the replicated nodes
5542 should be associated to.
5543 \return TRUE if operation has been completed successfully, FALSE otherwise
5544 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
5546 //================================================================================
5548 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
5549 SMESHDS_Mesh* theMeshDS,
5550 TIDSortedElemSet& theElemSet,
5551 const bool theIsNodeGrp)
5553 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
5555 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
5556 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
5557 : aGrp->GetType() != SMESH::NODE ) )
5559 SMESH::long_array_var anIDs = aGrp->GetIDs();
5560 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
5565 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
5566 const SMESH::ListOfGroups& theNodesNot,
5567 const SMESH::ListOfGroups& theAffectedElems)
5571 ::SMESH_MeshEditor aMeshEditor( myMesh );
5573 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5574 TIDSortedElemSet anElems, aNodes, anAffected;
5575 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5576 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5577 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5579 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5581 storeResult( aMeshEditor) ;
5583 myMesh->GetMeshDS()->Modified();
5585 myMesh->SetIsModified( true );
5587 // Update Python script
5588 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
5589 << &theNodesNot << ", " << &theAffectedElems << " )";
5593 //================================================================================
5595 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5596 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
5597 \param theElems - list of groups of elements (edges or faces) to be replicated
5598 \param theNodesNot - list of groups of nodes not to replicated
5599 \param theAffectedElems - group of elements to which the replicated nodes
5600 should be associated to.
5601 * \return a new group with newly created elements
5602 * \sa DoubleNodeElemGroups()
5604 //================================================================================
5606 SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
5607 const SMESH::ListOfGroups& theNodesNot,
5608 const SMESH::ListOfGroups& theAffectedElems)
5610 SMESH::SMESH_Group_var aNewGroup;
5614 ::SMESH_MeshEditor aMeshEditor( myMesh );
5616 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5617 TIDSortedElemSet anElems, aNodes, anAffected;
5618 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5619 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5620 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5622 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5624 storeResult( aMeshEditor) ;
5626 myMesh->GetMeshDS()->Modified();
5628 myMesh->SetIsModified( true );
5630 // Create group with newly created elements
5631 SMESH::long_array_var anIds = GetLastCreatedElems();
5632 if (anIds->length() > 0) {
5633 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5634 string anUnindexedName (theElems[0]->GetName());
5635 string aNewName = generateGroupName(anUnindexedName + "_double");
5636 aNewGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5637 aNewGroup->Add(anIds);
5641 // Update Python script
5642 TPythonDump() << "createdElems = " << this << ".DoubleNodeElemGroupsNew( " << &theElems << ", "
5643 << &theNodesNot << ", " << &theAffectedElems << " )";
5644 return aNewGroup._retn();
5647 //================================================================================
5649 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5650 This method provided for convenience works as DoubleNodes() described above.
5651 \param theElems - list of groups of elements (edges or faces) to be replicated
5652 \param theNodesNot - list of groups of nodes not to replicated
5653 \param theShape - shape to detect affected elements (element which geometric center
5654 located on or inside shape).
5655 The replicated nodes should be associated to affected elements.
5656 \return TRUE if operation has been completed successfully, FALSE otherwise
5657 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
5659 //================================================================================
5662 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
5663 const SMESH::ListOfGroups& theNodesNot,
5664 GEOM::GEOM_Object_ptr theShape )
5668 ::SMESH_MeshEditor aMeshEditor( myMesh );
5670 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5671 TIDSortedElemSet anElems, aNodes;
5672 listOfGroupToSet(theElems, aMeshDS, anElems,false );
5673 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5675 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5676 bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5678 storeResult( aMeshEditor) ;
5680 myMesh->GetMeshDS()->Modified();
5682 myMesh->SetIsModified( true );
5684 // Update Python script
5685 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
5686 << &theNodesNot << ", " << theShape << " )";
5690 //================================================================================
5692 \brief Generated skin mesh (containing 2D cells) from 3D mesh
5693 The created 2D mesh elements based on nodes of free faces of boundary volumes
5694 \return TRUE if operation has been completed successfully, FALSE otherwise
5696 //================================================================================
5698 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
5702 ::SMESH_MeshEditor aMeshEditor( myMesh );
5703 bool aResult = aMeshEditor.Make2DMeshFrom3D();
5704 storeResult( aMeshEditor) ;
5705 myMesh->GetMeshDS()->Modified();
5706 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
5710 //================================================================================
5712 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
5713 * The list of groups must describe a partition of the mesh volumes.
5714 * The nodes of the internal faces at the boundaries of the groups are doubled.
5715 * In option, the internal faces are replaced by flat elements.
5716 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
5717 * The flat elements are stored in groups of volumes.
5718 * @param theDomains - list of groups of volumes
5719 * @param createJointElems - if TRUE, create the elements
5720 * @return TRUE if operation has been completed successfully, FALSE otherwise
5722 //================================================================================
5724 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
5725 CORBA::Boolean createJointElems )
5726 throw (SALOME::SALOME_Exception)
5730 ::SMESH_MeshEditor aMeshEditor( myMesh );
5732 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5734 vector<TIDSortedElemSet> domains;
5737 for ( int i = 0, n = theDomains.length(); i < n; i++ )
5739 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
5740 if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
5742 if ( aGrp->GetType() != SMESH::VOLUME )
5743 THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
5744 TIDSortedElemSet domain;
5746 domains.push_back(domain);
5747 SMESH::long_array_var anIDs = aGrp->GetIDs();
5748 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
5752 bool aResult = aMeshEditor.DoubleNodesOnGroupBoundaries( domains, createJointElems );
5753 // TODO publish the groups of flat elements in study
5755 storeResult( aMeshEditor) ;
5756 myMesh->GetMeshDS()->Modified();
5758 // Update Python script
5759 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
5760 << ", " << createJointElems << " )";
5764 //================================================================================
5766 * \brief Double nodes on some external faces and create flat elements.
5767 * Flat elements are mainly used by some types of mechanic calculations.
5769 * Each group of the list must be constituted of faces.
5770 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
5771 * @param theGroupsOfFaces - list of groups of faces
5772 * @return TRUE if operation has been completed successfully, FALSE otherwise
5774 //================================================================================
5776 CORBA::Boolean SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
5780 ::SMESH_MeshEditor aMeshEditor( myMesh );
5782 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5784 vector<TIDSortedElemSet> faceGroups;
5787 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
5789 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
5790 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
5792 TIDSortedElemSet faceGroup;
5794 faceGroups.push_back(faceGroup);
5795 SMESH::long_array_var anIDs = aGrp->GetIDs();
5796 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
5800 bool aResult = aMeshEditor.CreateFlatElementsOnFacesGroups( faceGroups );
5801 // TODO publish the groups of flat elements in study
5803 storeResult( aMeshEditor) ;
5804 myMesh->GetMeshDS()->Modified();
5806 // Update Python script
5807 TPythonDump() << "isDone = " << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
5811 // issue 20749 ===================================================================
5813 * \brief Creates missing boundary elements
5814 * \param elements - elements whose boundary is to be checked
5815 * \param dimension - defines type of boundary elements to create
5816 * \param groupName - a name of group to store created boundary elements in,
5817 * "" means not to create the group
5818 * \param meshName - a name of new mesh to store created boundary elements in,
5819 * "" means not to create the new mesh
5820 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
5821 * \param toCopyExistingBondary - if true, not only new but also pre-existing
5822 * boundary elements will be copied into the new mesh
5823 * \param group - returns the create group, if any
5824 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
5826 // ================================================================================
5828 SMESH::SMESH_Mesh_ptr
5829 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
5830 SMESH::Bnd_Dimension dim,
5831 const char* groupName,
5832 const char* meshName,
5833 CORBA::Boolean toCopyElements,
5834 CORBA::Boolean toCopyExistingBondary,
5835 SMESH::SMESH_Group_out group)
5839 if ( dim > SMESH::BND_1DFROM2D )
5840 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
5842 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5844 SMESH::SMESH_Mesh_var mesh_var;
5845 SMESH::SMESH_Group_var group_var;
5849 TIDSortedElemSet elements;
5850 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
5851 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
5855 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
5856 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
5858 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
5860 // group of new boundary elements
5861 SMESH_Group* smesh_group = 0;
5862 if ( strlen(groupName) )
5864 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
5865 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
5866 smesh_group = group_i->GetSmeshGroup();
5870 ::SMESH_MeshEditor aMeshEditor( myMesh );
5871 aMeshEditor.MakeBoundaryMesh( elements,
5872 ::SMESH_MeshEditor::Bnd_Dimension(dim),
5876 toCopyExistingBondary);
5877 storeResult( aMeshEditor );
5880 smesh_mesh->GetMeshDS()->Modified();
5883 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
5885 // result of MakeBoundaryMesh() is a tuple (mesh, group)
5886 if ( mesh_var->_is_nil() )
5887 pyDump << myMesh_i->_this() << ", ";
5889 pyDump << mesh_var << ", ";
5890 if ( group_var->_is_nil() )
5891 pyDump << "_NoneGroup = "; // assignment to None is forbiden
5893 pyDump << group_var << " = ";
5894 pyDump << this << ".MakeBoundaryMesh( "
5896 << "SMESH." << dimName[int(dim)] << ", "
5897 << "'" << groupName << "', "
5898 << "'" << meshName<< "', "
5899 << toCopyElements << ", "
5900 << toCopyExistingBondary << ")";
5902 group = group_var._retn();
5903 return mesh_var._retn();
5906 //================================================================================
5908 * \brief Creates missing boundary elements
5909 * \param dimension - defines type of boundary elements to create
5910 * \param groupName - a name of group to store all boundary elements in,
5911 * "" means not to create the group
5912 * \param meshName - a name of a new mesh, which is a copy of the initial
5913 * mesh + created boundary elements; "" means not to create the new mesh
5914 * \param toCopyAll - if true, the whole initial mesh will be copied into
5915 * the new mesh else only boundary elements will be copied into the new mesh
5916 * \param groups - optional groups of elements to make boundary around
5917 * \param mesh - returns the mesh where elements were added to
5918 * \param group - returns the created group, if any
5919 * \retval long - number of added boundary elements
5921 //================================================================================
5923 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
5924 const char* groupName,
5925 const char* meshName,
5926 CORBA::Boolean toCopyAll,
5927 const SMESH::ListOfIDSources& groups,
5928 SMESH::SMESH_Mesh_out mesh,
5929 SMESH::SMESH_Group_out group)
5930 throw (SALOME::SALOME_Exception)
5932 Unexpect aCatch(SALOME_SalomeException);
5936 if ( dim > SMESH::BND_1DFROM2D )
5937 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
5939 // separate groups belonging to this and other mesh
5940 SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
5941 SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
5942 groupsOfThisMesh->length( groups.length() );
5943 groupsOfOtherMesh->length( groups.length() );
5944 int nbGroups = 0, nbGroupsOfOtherMesh = 0;
5945 for ( int i = 0; i < groups.length(); ++i )
5947 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
5948 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
5949 groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
5951 groupsOfThisMesh[ nbGroups++ ] = groups[i];
5952 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
5953 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
5955 groupsOfThisMesh->length( nbGroups );
5956 groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
5961 if ( nbGroupsOfOtherMesh > 0 )
5963 // process groups belonging to another mesh
5964 SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
5965 SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
5966 nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
5967 groupsOfOtherMesh, mesh, group );
5970 SMESH::SMESH_Mesh_var mesh_var;
5971 SMESH::SMESH_Group_var group_var;
5974 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
5975 const bool toCopyMesh = ( strlen( meshName ) > 0 );
5979 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
5981 /*toCopyGroups=*/false,
5982 /*toKeepIDs=*/true);
5984 mesh_var = makeMesh(meshName);
5986 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
5987 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
5990 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
5991 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
5993 // group of boundary elements
5994 SMESH_Group* smesh_group = 0;
5995 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
5996 if ( strlen(groupName) )
5998 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
5999 group_var = mesh_i->CreateGroup( groupType, groupName );
6000 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
6001 smesh_group = group_i->GetSmeshGroup();
6004 TIDSortedElemSet elements;
6006 if ( groups.length() > 0 )
6008 for ( int i = 0; i < nbGroups; ++i )
6011 if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
6013 SMESH::Bnd_Dimension bdim =
6014 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
6015 ::SMESH_MeshEditor aMeshEditor( srcMesh );
6016 nbAdded += aMeshEditor.MakeBoundaryMesh( elements,
6017 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
6020 /*toCopyElements=*/false,
6021 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
6022 /*toAddExistingBondary=*/true,
6023 /*aroundElements=*/true);
6024 storeResult( aMeshEditor );
6030 ::SMESH_MeshEditor aMeshEditor( srcMesh );
6031 nbAdded += aMeshEditor.MakeBoundaryMesh( elements,
6032 ::SMESH_MeshEditor::Bnd_Dimension(dim),
6035 /*toCopyElements=*/false,
6036 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
6037 /*toAddExistingBondary=*/true);
6038 storeResult( aMeshEditor );
6040 tgtMesh->GetMeshDS()->Modified();
6042 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
6044 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
6045 pyDump << "nbAdded, ";
6046 if ( mesh_var->_is_nil() )
6047 pyDump << myMesh_i->_this() << ", ";
6049 pyDump << mesh_var << ", ";
6050 if ( group_var->_is_nil() )
6051 pyDump << "_NoneGroup = "; // assignment to None is forbiden
6053 pyDump << group_var << " = ";
6054 pyDump << this << ".MakeBoundaryElements( "
6055 << "SMESH." << dimName[int(dim)] << ", "
6056 << "'" << groupName << "', "
6057 << "'" << meshName<< "', "
6058 << toCopyAll << ", "
6061 mesh = mesh_var._retn();
6062 group = group_var._retn();