1 // Copyright (C) 2007-2010 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 // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
23 // File : SMESH_MeshEditor_i.cxx
24 // Author : Nicolas REJNERI
31 #include "SMESH_MeshEditor_i.hxx"
33 #include "SMDS_Mesh0DElement.hxx"
34 #include "SMDS_LinearEdge.hxx"
35 #include "SMDS_MeshFace.hxx"
36 #include "SMDS_MeshVolume.hxx"
37 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
38 #include "SMESH_subMeshEventListener.hxx"
39 #include "SMESH_Gen_i.hxx"
40 #include "SMESH_Filter_i.hxx"
41 #include "SMESH_subMesh_i.hxx"
42 #include "SMESH_Group_i.hxx"
43 #include "SMESH_PythonDump.hxx"
44 #include "SMESH_ControlsDef.hxx"
46 #include "utilities.h"
47 #include "Utils_ExceptHandlers.hxx"
48 #include "Utils_CorbaException.hxx"
50 #include <BRepAdaptor_Surface.hxx>
51 #include <BRep_Tool.hxx>
52 #include <TopExp_Explorer.hxx>
54 #include <TopoDS_Edge.hxx>
55 #include <TopoDS_Face.hxx>
60 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
64 #include <Standard_Failure.hxx>
67 #include <Standard_ErrorHandler.hxx>
73 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
76 using SMESH::TPythonDump;
80 //=============================================================================
82 * \brief Mesh to apply modifications for preview purposes
84 //=============================================================================
86 struct TPreviewMesh: public SMESH_Mesh
88 SMDSAbs_ElementType myPreviewType; // type to show
90 TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
91 _isShapeToMesh = (_id =_studyId =_idDoc = 0);
92 _myMeshDS = new SMESHDS_Mesh( _id, true );
93 myPreviewType = previewElements;
96 virtual ~TPreviewMesh() { delete _myMeshDS; }
97 //!< Copy a set of elements
98 void Copy(const TIDSortedElemSet & theElements,
99 TIDSortedElemSet& theCopyElements,
100 SMDSAbs_ElementType theSelectType = SMDSAbs_All,
101 SMDSAbs_ElementType theAvoidType = SMDSAbs_All)
103 // loop on theIDsOfElements
104 TIDSortedElemSet::const_iterator eIt = theElements.begin();
105 for ( ; eIt != theElements.end(); ++eIt )
107 const SMDS_MeshElement* anElem = *eIt;
108 if ( !anElem ) continue;
109 SMDSAbs_ElementType type = anElem->GetType();
110 if ( type == theAvoidType ||
111 ( theSelectType != SMDSAbs_All && type != theSelectType ))
114 if ( const SMDS_MeshElement* anElemCopy = Copy( anElem ))
115 theCopyElements.insert( theCopyElements.end(), anElemCopy );
119 SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
121 // copy element nodes
122 int anElemNbNodes = anElem->NbNodes();
123 vector< int > anElemNodesID( anElemNbNodes ) ;
124 SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
125 for ( int i = 0; itElemNodes->more(); i++)
127 const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
129 anElemNodesID[i] = anElemNode->GetID();
132 // creates a corresponding element on copied nodes
133 SMDS_MeshElement* anElemCopy = 0;
134 if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
136 const SMDS_VtkVolume* ph =
137 dynamic_cast<const SMDS_VtkVolume*> (anElem);
139 anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
140 (anElemNodesID, ph->GetQuantities(),anElem->GetID());
143 anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
150 SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
152 return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(),
153 anElemNode->GetID());
155 };// struct TPreviewMesh
157 static SMESH_NodeSearcher * theNodeSearcher = 0;
158 static SMESH_ElementSearcher * theElementSearcher = 0;
160 //=============================================================================
162 * \brief Deleter of theNodeSearcher at any compute event occured
164 //=============================================================================
166 struct TSearchersDeleter : public SMESH_subMeshEventListener
170 TSearchersDeleter(): SMESH_subMeshEventListener( false ), // won't be deleted by submesh
172 //!< Delete theNodeSearcher
175 if ( theNodeSearcher ) delete theNodeSearcher; theNodeSearcher = 0;
176 if ( theElementSearcher ) delete theElementSearcher; theElementSearcher = 0;
178 typedef map < int, SMESH_subMesh * > TDependsOnMap;
179 //!< The meshod called by submesh: do my main job
180 void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
181 SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
183 if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
185 Unset( sm->GetFather() );
188 //!< set self on all submeshes and delete theNodeSearcher if other mesh is set
189 void Set(SMESH_Mesh* mesh)
191 if ( myMesh != mesh )
198 if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
199 const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
200 TDependsOnMap::const_iterator sm;
201 for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
202 sm->second->SetEventListener( this, 0, sm->second );
206 //!< delete self from all submeshes
207 void Unset(SMESH_Mesh* mesh)
209 if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
210 const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
211 TDependsOnMap::const_iterator sm;
212 for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
213 sm->second->DeleteEventListener( this );
218 } theSearchersDeleter;
220 TCollection_AsciiString mirrorTypeName( SMESH::SMESH_MeshEditor::MirrorType theMirrorType )
222 TCollection_AsciiString typeStr;
223 switch ( theMirrorType ) {
224 case SMESH::SMESH_MeshEditor::POINT:
225 typeStr = "SMESH.SMESH_MeshEditor.POINT";
227 case SMESH::SMESH_MeshEditor::AXIS:
228 typeStr = "SMESH.SMESH_MeshEditor.AXIS";
231 typeStr = "SMESH.SMESH_MeshEditor.PLANE";
235 //================================================================================
237 * \brief function for conversion of long_array to TIDSortedElemSet
238 * \param IDs - array of IDs
239 * \param aMesh - mesh
240 * \param aMap - collection to fill
241 * \param aType - element type
243 //================================================================================
245 void arrayToSet(const SMESH::long_array & IDs,
246 const SMESHDS_Mesh* aMesh,
247 TIDSortedElemSet& aMap,
248 const SMDSAbs_ElementType aType = SMDSAbs_All )
250 for (int i=0; i<IDs.length(); i++) {
251 CORBA::Long ind = IDs[i];
252 const SMDS_MeshElement * elem =
253 (aType == SMDSAbs_Node ? aMesh->FindNode(ind) : aMesh->FindElement(ind));
254 if ( elem && ( aType == SMDSAbs_All || elem->GetType() == aType ))
258 //================================================================================
260 * \brief Retrieve elements of given type from SMESH_IDSource
262 //================================================================================
264 bool idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource,
265 const SMESHDS_Mesh* theMeshDS,
266 TIDSortedElemSet& theElemSet,
267 const SMDSAbs_ElementType theType,
268 const bool emptyIfIsMesh=false)
271 if ( CORBA::is_nil( theIDSource ) )
273 if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
276 SMESH::long_array_var anIDs = theIDSource->GetIDs();
277 if ( anIDs->length() == 0 )
279 SMESH::array_of_ElementType_var types = theIDSource->GetTypes();
280 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
282 if ( theType == SMDSAbs_All || theType == SMDSAbs_Node )
283 arrayToSet( anIDs, theMeshDS, theElemSet, SMDSAbs_Node );
289 arrayToSet( anIDs, theMeshDS, theElemSet, theType);
293 //================================================================================
295 * \brief Retrieve nodes from SMESH_IDSource
297 //================================================================================
299 void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject,
300 const SMESHDS_Mesh* theMeshDS,
301 TIDSortedNodeSet& theNodeSet)
304 if ( CORBA::is_nil( theObject ) )
306 SMESH::array_of_ElementType_var types = theObject->GetTypes();
307 SMESH::long_array_var aElementsId = theObject->GetIDs();
308 if ( types->length() == 1 && types[0] == SMESH::NODE)
310 for(int i = 0; i < aElementsId->length(); i++)
311 if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] ))
312 theNodeSet.insert( theNodeSet.end(), n);
314 else if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
316 SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator();
317 while ( nIt->more( ))
318 if( const SMDS_MeshElement * elem = nIt->next() )
319 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
323 for(int i = 0; i < aElementsId->length(); i++)
324 if( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] ))
325 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
329 //================================================================================
331 * \brief Returns elements connected to the given elements
333 //================================================================================
335 void getElementsAround(const TIDSortedElemSet& theElements,
336 const SMESHDS_Mesh* theMeshDS,
337 TIDSortedElemSet& theElementsAround)
339 if ( theElements.empty() ) return;
341 SMDSAbs_ElementType elemType = (*theElements.begin())->GetType();
342 bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() );
344 theMeshDS->GetMeshInfo().NbElements( elemType ) == theElements.size() )
345 return; // all the elements are in theElements
348 elemType = SMDSAbs_All;
350 TIDSortedElemSet visitedNodes;
351 TIDSortedElemSet::const_iterator elemIt = theElements.begin();
352 for ( ; elemIt != theElements.end(); ++elemIt )
354 const SMDS_MeshElement* e = *elemIt;
355 int i = e->NbCornerNodes();
358 const SMDS_MeshNode* n = e->GetNode( i );
359 if ( visitedNodes.insert( n ).second )
361 SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
362 while ( invIt->more() )
364 const SMDS_MeshElement* elemAround = invIt->next();
365 if ( !theElements.count( elemAround ))
366 theElementsAround.insert( elemAround );
374 //=============================================================================
378 //=============================================================================
380 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview)
383 myMesh = & theMesh->GetImpl();
384 myPreviewMode = isPreview;
387 //================================================================================
391 //================================================================================
393 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
397 //================================================================================
399 * \brief Clear members
401 //================================================================================
403 void SMESH_MeshEditor_i::initData(bool deleteSearchers)
405 if ( myPreviewMode ) {
406 myPreviewData = new SMESH::MeshPreviewStruct();
409 myLastCreatedElems = new SMESH::long_array();
410 myLastCreatedNodes = new SMESH::long_array();
411 if ( deleteSearchers )
412 TSearchersDeleter::Delete();
416 //=======================================================================
417 //function : MakeIDSource
418 //purpose : Wrap a sequence of ids in a SMESH_IDSource
419 //=======================================================================
421 struct _IDSource : public POA_SMESH::SMESH_IDSource
423 SMESH::long_array _ids;
424 SMESH::ElementType _type;
425 SMESH::SMESH_Mesh_ptr _mesh;
426 SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); }
427 SMESH::long_array* GetMeshInfo() { return 0; }
428 SMESH::SMESH_Mesh_ptr GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _mesh ); }
429 SMESH::array_of_ElementType* GetTypes()
431 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
434 return types._retn();
438 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
439 SMESH::ElementType type)
441 _IDSource* anIDSource = new _IDSource;
442 anIDSource->_ids = ids;
443 anIDSource->_type = type;
444 anIDSource->_mesh = myMesh_i->_this();
445 SMESH::SMESH_IDSource_var anIDSourceVar = anIDSource->_this();
447 return anIDSourceVar._retn();
450 //=============================================================================
454 //=============================================================================
457 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
461 ::SMESH_MeshEditor anEditor( myMesh );
464 for (int i = 0; i < IDsOfElements.length(); i++)
465 IdList.push_back( IDsOfElements[i] );
467 // Update Python script
468 TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
471 bool ret = anEditor.Remove( IdList, false );
472 myMesh->GetMeshDS()->Modified();
473 if ( IDsOfElements.length() )
474 myMesh->SetIsModified( true ); // issue 0020693
478 //=============================================================================
482 //=============================================================================
484 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
488 ::SMESH_MeshEditor anEditor( myMesh );
490 for (int i = 0; i < IDsOfNodes.length(); i++)
491 IdList.push_back( IDsOfNodes[i] );
493 // Update Python script
494 TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
496 bool ret = anEditor.Remove( IdList, true );
497 myMesh->GetMeshDS()->Modified();
498 if ( IDsOfNodes.length() )
499 myMesh->SetIsModified( true ); // issue 0020693
503 //=============================================================================
507 //=============================================================================
509 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
513 ::SMESH_MeshEditor anEditor( myMesh );
515 // Update Python script
516 TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
518 // Create filter to find all orphan nodes
519 SMESH::Controls::Filter::TIdSequence seq;
520 SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
521 SMESH::Controls::Filter::GetElementsId( GetMeshDS(), predicate, seq );
523 // remove orphan nodes (if there are any)
525 for ( int i = 0; i < seq.size(); i++ )
526 IdList.push_back( seq[i] );
528 bool ret = anEditor.Remove( IdList, true );
529 myMesh->GetMeshDS()->Modified();
531 myMesh->SetIsModified( true );
536 //=============================================================================
540 //=============================================================================
542 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,
543 CORBA::Double y, CORBA::Double z)
547 const SMDS_MeshNode* N = GetMeshDS()->AddNode(x, y, z);
549 // Update Python script
550 TPythonDump() << "nodeID = " << this << ".AddNode( "
551 << x << ", " << y << ", " << z << " )";
553 myMesh->GetMeshDS()->Modified();
554 myMesh->SetIsModified( true ); // issue 0020693
558 //=============================================================================
562 //=============================================================================
563 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
567 const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(IDOfNode);
568 SMDS_MeshElement* elem = GetMeshDS()->Add0DElement(aNode);
570 // Update Python script
571 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
573 myMesh->GetMeshDS()->Modified();
574 myMesh->SetIsModified( true ); // issue 0020693
577 return elem->GetID();
582 //=============================================================================
586 //=============================================================================
588 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
592 int NbNodes = IDsOfNodes.length();
593 SMDS_MeshElement* elem = 0;
596 CORBA::Long index1 = IDsOfNodes[0];
597 CORBA::Long index2 = IDsOfNodes[1];
598 elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(index1), GetMeshDS()->FindNode(index2));
600 // Update Python script
601 TPythonDump() << "edge = " << this << ".AddEdge([ "
602 << index1 << ", " << index2 <<" ])";
605 CORBA::Long n1 = IDsOfNodes[0];
606 CORBA::Long n2 = IDsOfNodes[1];
607 CORBA::Long n12 = IDsOfNodes[2];
608 elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(n1),
609 GetMeshDS()->FindNode(n2),
610 GetMeshDS()->FindNode(n12));
611 // Update Python script
612 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
613 <<n1<<", "<<n2<<", "<<n12<<" ])";
616 myMesh->GetMeshDS()->Modified();
618 return myMesh->SetIsModified( true ), elem->GetID();
623 //=============================================================================
627 //=============================================================================
629 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
633 int NbNodes = IDsOfNodes.length();
639 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
640 for (int i = 0; i < NbNodes; i++)
641 nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
643 SMDS_MeshElement* elem = 0;
645 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]);
647 else if (NbNodes == 4) {
648 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]);
650 else if (NbNodes == 6) {
651 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
654 else if (NbNodes == 8) {
655 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
656 nodes[4], nodes[5], nodes[6], nodes[7]);
658 else if (NbNodes > 2) {
659 elem = GetMeshDS()->AddPolygonalFace(nodes);
662 // Update Python script
663 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
665 myMesh->GetMeshDS()->Modified();
667 return myMesh->SetIsModified( true ), elem->GetID();
672 //=============================================================================
676 //=============================================================================
677 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
681 int NbNodes = IDsOfNodes.length();
682 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
683 for (int i = 0; i < NbNodes; i++)
684 nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
686 const SMDS_MeshElement* elem = GetMeshDS()->AddPolygonalFace(nodes);
688 // Update Python script
689 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
691 myMesh->GetMeshDS()->Modified();
692 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
695 //=============================================================================
699 //=============================================================================
701 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
705 int NbNodes = IDsOfNodes.length();
706 vector< const SMDS_MeshNode*> n(NbNodes);
707 for(int i=0;i<NbNodes;i++)
708 n[i]=GetMeshDS()->FindNode(IDsOfNodes[i]);
710 SMDS_MeshElement* elem = 0;
713 case 4 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
714 case 5 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
715 case 6 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
716 case 8 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
717 case 10:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
718 n[6],n[7],n[8],n[9]);
720 case 13:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
721 n[7],n[8],n[9],n[10],n[11],n[12]);
723 case 15:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
724 n[9],n[10],n[11],n[12],n[13],n[14]);
726 case 20:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
727 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
728 n[15],n[16],n[17],n[18],n[19]);
732 // Update Python script
733 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
735 myMesh->GetMeshDS()->Modified();
737 return myMesh->SetIsModified( true ), elem->GetID();
742 //=============================================================================
744 * AddPolyhedralVolume
746 //=============================================================================
747 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
748 const SMESH::long_array & Quantities)
752 int NbNodes = IDsOfNodes.length();
753 std::vector<const SMDS_MeshNode*> n (NbNodes);
754 for (int i = 0; i < NbNodes; i++)
756 const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(IDsOfNodes[i]);
757 if (!aNode) return 0;
761 int NbFaces = Quantities.length();
762 std::vector<int> q (NbFaces);
763 for (int j = 0; j < NbFaces; j++)
764 q[j] = Quantities[j];
766 const SMDS_MeshElement* elem = GetMeshDS()->AddPolyhedralVolume(n, q);
768 // Update Python script
769 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
770 << IDsOfNodes << ", " << Quantities << " )";
771 myMesh->GetMeshDS()->Modified();
773 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
776 //=============================================================================
778 * AddPolyhedralVolumeByFaces
780 //=============================================================================
781 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
785 int NbFaces = IdsOfFaces.length();
786 std::vector<const SMDS_MeshNode*> poly_nodes;
787 std::vector<int> quantities (NbFaces);
789 for (int i = 0; i < NbFaces; i++) {
790 const SMDS_MeshElement* aFace = GetMeshDS()->FindElement(IdsOfFaces[i]);
791 quantities[i] = aFace->NbNodes();
793 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
795 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
799 const SMDS_MeshElement* elem = GetMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
801 // Update Python script
802 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
803 << IdsOfFaces << " )";
804 myMesh->GetMeshDS()->Modified();
806 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
809 //=============================================================================
811 * \brief Bind a node to a vertex
812 * \param NodeID - node ID
813 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
814 * \retval boolean - false if NodeID or VertexID is invalid
816 //=============================================================================
818 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
819 throw (SALOME::SALOME_Exception)
821 Unexpect aCatch(SALOME_SalomeException);
823 SMESHDS_Mesh * mesh = GetMeshDS();
824 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
826 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
828 if ( mesh->MaxShapeIndex() < VertexID )
829 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
831 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
832 if ( shape.ShapeType() != TopAbs_VERTEX )
833 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
835 mesh->SetNodeOnVertex( node, VertexID );
837 myMesh->SetIsModified( true );
840 //=============================================================================
842 * \brief Store node position on an edge
843 * \param NodeID - node ID
844 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
845 * \param paramOnEdge - parameter on edge where the node is located
846 * \retval boolean - false if any parameter is invalid
848 //=============================================================================
850 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
851 CORBA::Double paramOnEdge)
852 throw (SALOME::SALOME_Exception)
854 Unexpect aCatch(SALOME_SalomeException);
856 SMESHDS_Mesh * mesh = GetMeshDS();
857 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
859 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
861 if ( mesh->MaxShapeIndex() < EdgeID )
862 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
864 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
865 if ( shape.ShapeType() != TopAbs_EDGE )
866 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
869 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
870 if ( paramOnEdge < f || paramOnEdge > l )
871 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
873 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
875 myMesh->SetIsModified( true );
878 //=============================================================================
880 * \brief Store node position on a face
881 * \param NodeID - node ID
882 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
883 * \param u - U parameter on face where the node is located
884 * \param v - V parameter on face where the node is located
885 * \retval boolean - false if any parameter is invalid
887 //=============================================================================
889 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
890 CORBA::Double u, CORBA::Double v)
891 throw (SALOME::SALOME_Exception)
893 Unexpect aCatch(SALOME_SalomeException);
895 SMESHDS_Mesh * mesh = GetMeshDS();
896 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
898 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
900 if ( mesh->MaxShapeIndex() < FaceID )
901 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
903 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
904 if ( shape.ShapeType() != TopAbs_FACE )
905 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
907 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
908 bool isOut = ( u < surf.FirstUParameter() ||
909 u > surf.LastUParameter() ||
910 v < surf.FirstVParameter() ||
911 v > surf.LastVParameter() );
915 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
916 << " u( " << surf.FirstUParameter()
917 << "," << surf.LastUParameter()
918 << ") v( " << surf.FirstVParameter()
919 << "," << surf.LastVParameter() << ")" );
921 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
924 mesh->SetNodeOnFace( node, FaceID, u, v );
925 myMesh->SetIsModified( true );
928 //=============================================================================
930 * \brief Bind a node to a solid
931 * \param NodeID - node ID
932 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
933 * \retval boolean - false if NodeID or SolidID is invalid
935 //=============================================================================
937 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
938 throw (SALOME::SALOME_Exception)
940 Unexpect aCatch(SALOME_SalomeException);
942 SMESHDS_Mesh * mesh = GetMeshDS();
943 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
945 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
947 if ( mesh->MaxShapeIndex() < SolidID )
948 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
950 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
951 if ( shape.ShapeType() != TopAbs_SOLID &&
952 shape.ShapeType() != TopAbs_SHELL)
953 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
955 mesh->SetNodeInVolume( node, SolidID );
957 // myMesh->SetIsModified( true ); - SetNodeInVolume() can't prevent re-compute, I believe
960 //=============================================================================
962 * \brief Bind an element to a shape
963 * \param ElementID - element ID
964 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
965 * \retval boolean - false if ElementID or ShapeID is invalid
967 //=============================================================================
969 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
971 throw (SALOME::SALOME_Exception)
973 Unexpect aCatch(SALOME_SalomeException);
975 SMESHDS_Mesh * mesh = GetMeshDS();
976 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
978 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
980 if ( mesh->MaxShapeIndex() < ShapeID )
981 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
983 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
984 if ( shape.ShapeType() != TopAbs_EDGE &&
985 shape.ShapeType() != TopAbs_FACE &&
986 shape.ShapeType() != TopAbs_SOLID &&
987 shape.ShapeType() != TopAbs_SHELL )
988 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
990 mesh->SetMeshElementOnShape( elem, ShapeID );
992 myMesh->SetIsModified( true );
995 //=============================================================================
999 //=============================================================================
1001 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1002 CORBA::Long NodeID2)
1006 const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
1007 const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
1011 // Update Python script
1012 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1013 << NodeID1 << ", " << NodeID2 << " )";
1016 ::SMESH_MeshEditor aMeshEditor( myMesh );
1017 int ret = aMeshEditor.InverseDiag ( n1, n2 );
1018 myMesh->GetMeshDS()->Modified();
1019 myMesh->SetIsModified( true );
1023 //=============================================================================
1027 //=============================================================================
1029 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1030 CORBA::Long NodeID2)
1034 const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
1035 const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
1039 // Update Python script
1040 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1041 << NodeID1 << ", " << NodeID2 << " )";
1043 ::SMESH_MeshEditor aMeshEditor( myMesh );
1045 bool stat = aMeshEditor.DeleteDiag ( n1, n2 );
1047 myMesh->GetMeshDS()->Modified();
1049 myMesh->SetIsModified( true ); // issue 0020693
1051 storeResult(aMeshEditor);
1056 //=============================================================================
1060 //=============================================================================
1062 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1066 ::SMESH_MeshEditor anEditor( myMesh );
1067 for (int i = 0; i < IDsOfElements.length(); i++)
1069 CORBA::Long index = IDsOfElements[i];
1070 const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
1072 anEditor.Reorient( elem );
1074 // Update Python script
1075 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1077 myMesh->GetMeshDS()->Modified();
1078 if ( IDsOfElements.length() )
1079 myMesh->SetIsModified( true ); // issue 0020693
1085 //=============================================================================
1089 //=============================================================================
1091 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1095 TPythonDump aTPythonDump; // suppress dump in Reorient()
1097 SMESH::long_array_var anElementsId = theObject->GetIDs();
1098 CORBA::Boolean isDone = Reorient(anElementsId);
1100 // Update Python script
1101 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1106 //=============================================================================
1110 //=============================================================================
1111 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1112 SMESH::NumericalFunctor_ptr Criterion,
1113 CORBA::Double MaxAngle)
1117 SMESHDS_Mesh* aMesh = GetMeshDS();
1118 TIDSortedElemSet faces;
1119 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1121 SMESH::NumericalFunctor_i* aNumericalFunctor =
1122 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1123 SMESH::Controls::NumericalFunctorPtr aCrit;
1124 if ( !aNumericalFunctor )
1125 aCrit.reset( new SMESH::Controls::AspectRatio() );
1127 aCrit = aNumericalFunctor->GetNumericalFunctor();
1129 // Update Python script
1130 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1131 << IDsOfElements << ", " << aNumericalFunctor << ", " << MaxAngle << " )";
1133 ::SMESH_MeshEditor anEditor( myMesh );
1135 bool stat = anEditor.TriToQuad( faces, aCrit, MaxAngle );
1136 myMesh->GetMeshDS()->Modified();
1138 myMesh->SetIsModified( true ); // issue 0020693
1140 storeResult(anEditor);
1146 //=============================================================================
1150 //=============================================================================
1151 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1152 SMESH::NumericalFunctor_ptr Criterion,
1153 CORBA::Double MaxAngle)
1157 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1158 SMESH::long_array_var anElementsId = theObject->GetIDs();
1159 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1161 SMESH::NumericalFunctor_i* aNumericalFunctor =
1162 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1164 // Update Python script
1165 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1166 << theObject << ", " << aNumericalFunctor << ", " << MaxAngle << " )";
1172 //=============================================================================
1176 //=============================================================================
1177 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1178 SMESH::NumericalFunctor_ptr Criterion)
1182 SMESHDS_Mesh* aMesh = GetMeshDS();
1183 TIDSortedElemSet faces;
1184 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1186 SMESH::NumericalFunctor_i* aNumericalFunctor =
1187 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1188 SMESH::Controls::NumericalFunctorPtr aCrit;
1189 if ( !aNumericalFunctor )
1190 aCrit.reset( new SMESH::Controls::AspectRatio() );
1192 aCrit = aNumericalFunctor->GetNumericalFunctor();
1195 // Update Python script
1196 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1198 ::SMESH_MeshEditor anEditor( myMesh );
1199 CORBA::Boolean stat = anEditor.QuadToTri( faces, aCrit );
1200 myMesh->GetMeshDS()->Modified();
1202 myMesh->SetIsModified( true ); // issue 0020693
1204 storeResult(anEditor);
1210 //=============================================================================
1214 //=============================================================================
1215 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1216 SMESH::NumericalFunctor_ptr Criterion)
1220 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1222 SMESH::long_array_var anElementsId = theObject->GetIDs();
1223 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1225 SMESH::NumericalFunctor_i* aNumericalFunctor =
1226 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1228 // Update Python script
1229 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1235 //=============================================================================
1239 //=============================================================================
1240 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1241 CORBA::Boolean Diag13)
1245 SMESHDS_Mesh* aMesh = GetMeshDS();
1246 TIDSortedElemSet faces;
1247 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1249 // Update Python script
1250 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1251 << IDsOfElements << ", " << Diag13 << " )";
1253 ::SMESH_MeshEditor anEditor( myMesh );
1254 CORBA::Boolean stat = anEditor.QuadToTri( faces, Diag13 );
1255 myMesh->GetMeshDS()->Modified();
1257 myMesh->SetIsModified( true ); // issue 0020693
1260 storeResult(anEditor);
1266 //=============================================================================
1270 //=============================================================================
1271 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1272 CORBA::Boolean Diag13)
1276 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
1278 SMESH::long_array_var anElementsId = theObject->GetIDs();
1279 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
1281 // Update Python script
1282 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
1283 << theObject << ", " << Diag13 << " )";
1289 //=============================================================================
1293 //=============================================================================
1294 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
1295 SMESH::NumericalFunctor_ptr Criterion)
1299 const SMDS_MeshElement* quad = GetMeshDS()->FindElement(IDOfQuad);
1300 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
1302 SMESH::NumericalFunctor_i* aNumericalFunctor =
1303 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
1304 SMESH::Controls::NumericalFunctorPtr aCrit;
1305 if (aNumericalFunctor)
1306 aCrit = aNumericalFunctor->GetNumericalFunctor();
1308 aCrit.reset(new SMESH::Controls::AspectRatio());
1310 ::SMESH_MeshEditor anEditor (myMesh);
1311 return anEditor.BestSplit(quad, aCrit);
1316 //================================================================================
1318 * \brief Split volumic elements into tetrahedrons
1320 //================================================================================
1322 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
1323 CORBA::Short methodFlags)
1324 throw (SALOME::SALOME_Exception)
1326 Unexpect aCatch(SALOME_SalomeException);
1330 SMESH::long_array_var anElementsId = elems->GetIDs();
1331 TIDSortedElemSet elemSet;
1332 arrayToSet( anElementsId, GetMeshDS(), elemSet, SMDSAbs_Volume );
1334 ::SMESH_MeshEditor anEditor (myMesh);
1335 anEditor.SplitVolumesIntoTetra( elemSet, int( methodFlags ));
1336 myMesh->GetMeshDS()->Modified();
1338 storeResult(anEditor);
1340 // if ( myLastCreatedElems.length() ) - it does not influence Compute()
1341 // myMesh->SetIsModified( true ); // issue 0020693
1343 TPythonDump() << this << ".SplitVolumesIntoTetra( "
1344 << elems << ", " << methodFlags << " )";
1347 //=======================================================================
1350 //=======================================================================
1353 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
1354 const SMESH::long_array & IDsOfFixedNodes,
1355 CORBA::Long MaxNbOfIterations,
1356 CORBA::Double MaxAspectRatio,
1357 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1359 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1360 MaxAspectRatio, Method, false );
1364 //=======================================================================
1365 //function : SmoothParametric
1367 //=======================================================================
1370 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
1371 const SMESH::long_array & IDsOfFixedNodes,
1372 CORBA::Long MaxNbOfIterations,
1373 CORBA::Double MaxAspectRatio,
1374 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1376 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1377 MaxAspectRatio, Method, true );
1381 //=======================================================================
1382 //function : SmoothObject
1384 //=======================================================================
1387 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
1388 const SMESH::long_array & IDsOfFixedNodes,
1389 CORBA::Long MaxNbOfIterations,
1390 CORBA::Double MaxAspectRatio,
1391 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1393 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1394 MaxAspectRatio, Method, false);
1398 //=======================================================================
1399 //function : SmoothParametricObject
1401 //=======================================================================
1404 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
1405 const SMESH::long_array & IDsOfFixedNodes,
1406 CORBA::Long MaxNbOfIterations,
1407 CORBA::Double MaxAspectRatio,
1408 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1410 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1411 MaxAspectRatio, Method, true);
1415 //=============================================================================
1419 //=============================================================================
1422 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
1423 const SMESH::long_array & IDsOfFixedNodes,
1424 CORBA::Long MaxNbOfIterations,
1425 CORBA::Double MaxAspectRatio,
1426 SMESH::SMESH_MeshEditor::Smooth_Method Method,
1431 SMESHDS_Mesh* aMesh = GetMeshDS();
1433 TIDSortedElemSet elements;
1434 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
1436 set<const SMDS_MeshNode*> fixedNodes;
1437 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
1438 CORBA::Long index = IDsOfFixedNodes[i];
1439 const SMDS_MeshNode * node = aMesh->FindNode(index);
1441 fixedNodes.insert( node );
1443 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
1444 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
1445 method = ::SMESH_MeshEditor::CENTROIDAL;
1447 ::SMESH_MeshEditor anEditor( myMesh );
1448 anEditor.Smooth(elements, fixedNodes, method,
1449 MaxNbOfIterations, MaxAspectRatio, IsParametric );
1451 myMesh->GetMeshDS()->Modified();
1452 myMesh->SetIsModified( true ); // issue 0020693
1454 storeResult(anEditor);
1456 // Update Python script
1457 TPythonDump() << "isDone = " << this << "."
1458 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
1459 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
1460 << MaxNbOfIterations << ", " << MaxAspectRatio << ", "
1461 << "SMESH.SMESH_MeshEditor."
1462 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1463 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1469 //=============================================================================
1473 //=============================================================================
1476 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
1477 const SMESH::long_array & IDsOfFixedNodes,
1478 CORBA::Long MaxNbOfIterations,
1479 CORBA::Double MaxAspectRatio,
1480 SMESH::SMESH_MeshEditor::Smooth_Method Method,
1485 TPythonDump aTPythonDump; // suppress dump in smooth()
1487 SMESH::long_array_var anElementsId = theObject->GetIDs();
1488 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
1489 MaxAspectRatio, Method, IsParametric);
1491 // Update Python script
1492 aTPythonDump << "isDone = " << this << "."
1493 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
1494 << theObject << ", " << IDsOfFixedNodes << ", "
1495 << MaxNbOfIterations << ", " << MaxAspectRatio << ", "
1496 << "SMESH.SMESH_MeshEditor."
1497 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1498 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1504 //=============================================================================
1508 //=============================================================================
1510 void SMESH_MeshEditor_i::RenumberNodes()
1512 // Update Python script
1513 TPythonDump() << this << ".RenumberNodes()";
1515 GetMeshDS()->Renumber( true );
1519 //=============================================================================
1523 //=============================================================================
1525 void SMESH_MeshEditor_i::RenumberElements()
1527 // Update Python script
1528 TPythonDump() << this << ".RenumberElements()";
1530 GetMeshDS()->Renumber( false );
1533 //=======================================================================
1535 * \brief Return groups by their IDs
1537 //=======================================================================
1539 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
1543 myMesh_i->CreateGroupServants();
1544 return myMesh_i->GetGroups( *groupIDs );
1547 //=======================================================================
1548 //function : rotationSweep
1550 //=======================================================================
1552 SMESH::ListOfGroups*
1553 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
1554 const SMESH::AxisStruct & theAxis,
1555 CORBA::Double theAngleInRadians,
1556 CORBA::Long theNbOfSteps,
1557 CORBA::Double theTolerance,
1558 const bool theMakeGroups,
1559 const SMDSAbs_ElementType theElementType)
1563 TIDSortedElemSet inElements, copyElements;
1564 arrayToSet(theIDsOfElements, GetMeshDS(), inElements, theElementType);
1566 TIDSortedElemSet* workElements = & inElements;
1567 TPreviewMesh tmpMesh( SMDSAbs_Face );
1568 SMESH_Mesh* mesh = 0;
1569 bool makeWalls=true;
1570 if ( myPreviewMode )
1572 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
1573 tmpMesh.Copy( inElements, copyElements, select, avoid );
1575 workElements = & copyElements;
1576 //makeWalls = false;
1583 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
1584 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
1586 ::SMESH_MeshEditor anEditor( mesh );
1587 ::SMESH_MeshEditor::PGroupIDs groupIds =
1588 anEditor.RotationSweep (*workElements, Ax1, theAngleInRadians,
1589 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
1590 storeResult(anEditor);
1591 myMesh->GetMeshDS()->Modified();
1593 // myMesh->SetIsModified( true ); -- it does not influence Compute()
1595 return theMakeGroups ? getGroups(groupIds.get()) : 0;
1598 //=======================================================================
1599 //function : RotationSweep
1601 //=======================================================================
1603 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
1604 const SMESH::AxisStruct & theAxis,
1605 CORBA::Double theAngleInRadians,
1606 CORBA::Long theNbOfSteps,
1607 CORBA::Double theTolerance)
1609 if ( !myPreviewMode ) {
1610 TPythonDump() << this << ".RotationSweep( "
1611 << theIDsOfElements << ", "
1613 << theAngleInRadians << ", "
1614 << theNbOfSteps << ", "
1615 << theTolerance << " )";
1617 rotationSweep(theIDsOfElements,
1625 //=======================================================================
1626 //function : RotationSweepMakeGroups
1628 //=======================================================================
1630 SMESH::ListOfGroups*
1631 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
1632 const SMESH::AxisStruct& theAxis,
1633 CORBA::Double theAngleInRadians,
1634 CORBA::Long theNbOfSteps,
1635 CORBA::Double theTolerance)
1637 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1639 SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
1645 if (!myPreviewMode) {
1646 DumpGroupsList(aPythonDump, aGroups);
1647 aPythonDump << this << ".RotationSweepMakeGroups( "
1648 << theIDsOfElements << ", "
1650 << theAngleInRadians << ", "
1651 << theNbOfSteps << ", "
1652 << theTolerance << " )";
1657 //=======================================================================
1658 //function : RotationSweepObject
1660 //=======================================================================
1662 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
1663 const SMESH::AxisStruct & theAxis,
1664 CORBA::Double theAngleInRadians,
1665 CORBA::Long theNbOfSteps,
1666 CORBA::Double theTolerance)
1668 if ( !myPreviewMode ) {
1669 TPythonDump() << this << ".RotationSweepObject( "
1670 << theObject << ", "
1672 << theAngleInRadians << ", "
1673 << theNbOfSteps << ", "
1674 << theTolerance << " )";
1676 SMESH::long_array_var anElementsId = theObject->GetIDs();
1677 rotationSweep(anElementsId,
1685 //=======================================================================
1686 //function : RotationSweepObject1D
1688 //=======================================================================
1690 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
1691 const SMESH::AxisStruct & theAxis,
1692 CORBA::Double theAngleInRadians,
1693 CORBA::Long theNbOfSteps,
1694 CORBA::Double theTolerance)
1696 if ( !myPreviewMode ) {
1697 TPythonDump() << this << ".RotationSweepObject1D( "
1698 << theObject << ", "
1700 << theAngleInRadians << ", "
1701 << theNbOfSteps << ", "
1702 << theTolerance << " )";
1704 SMESH::long_array_var anElementsId = theObject->GetIDs();
1705 rotationSweep(anElementsId,
1714 //=======================================================================
1715 //function : RotationSweepObject2D
1717 //=======================================================================
1719 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
1720 const SMESH::AxisStruct & theAxis,
1721 CORBA::Double theAngleInRadians,
1722 CORBA::Long theNbOfSteps,
1723 CORBA::Double theTolerance)
1725 if ( !myPreviewMode ) {
1726 TPythonDump() << this << ".RotationSweepObject2D( "
1727 << theObject << ", "
1729 << theAngleInRadians << ", "
1730 << theNbOfSteps << ", "
1731 << theTolerance << " )";
1733 SMESH::long_array_var anElementsId = theObject->GetIDs();
1734 rotationSweep(anElementsId,
1743 //=======================================================================
1744 //function : RotationSweepObjectMakeGroups
1746 //=======================================================================
1748 SMESH::ListOfGroups*
1749 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1750 const SMESH::AxisStruct& theAxis,
1751 CORBA::Double theAngleInRadians,
1752 CORBA::Long theNbOfSteps,
1753 CORBA::Double theTolerance)
1755 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1757 SMESH::long_array_var anElementsId = theObject->GetIDs();
1758 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
1764 if (!myPreviewMode) {
1765 DumpGroupsList(aPythonDump, aGroups);
1766 aPythonDump << this << ".RotationSweepObjectMakeGroups( "
1767 << theObject << ", "
1769 << theAngleInRadians << ", "
1770 << theNbOfSteps << ", "
1771 << theTolerance << " )";
1776 //=======================================================================
1777 //function : RotationSweepObject1DMakeGroups
1779 //=======================================================================
1781 SMESH::ListOfGroups*
1782 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1783 const SMESH::AxisStruct& theAxis,
1784 CORBA::Double theAngleInRadians,
1785 CORBA::Long theNbOfSteps,
1786 CORBA::Double theTolerance)
1788 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1790 SMESH::long_array_var anElementsId = theObject->GetIDs();
1791 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
1798 if (!myPreviewMode) {
1799 DumpGroupsList(aPythonDump, aGroups);
1800 aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
1801 << theObject << ", "
1803 << theAngleInRadians << ", "
1804 << theNbOfSteps << ", "
1805 << theTolerance << " )";
1810 //=======================================================================
1811 //function : RotationSweepObject2DMakeGroups
1813 //=======================================================================
1815 SMESH::ListOfGroups*
1816 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1817 const SMESH::AxisStruct& theAxis,
1818 CORBA::Double theAngleInRadians,
1819 CORBA::Long theNbOfSteps,
1820 CORBA::Double theTolerance)
1822 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1824 SMESH::long_array_var anElementsId = theObject->GetIDs();
1825 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
1832 if (!myPreviewMode) {
1833 DumpGroupsList(aPythonDump, aGroups);
1834 aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
1835 << theObject << ", "
1837 << theAngleInRadians << ", "
1838 << theNbOfSteps << ", "
1839 << theTolerance << " )";
1845 //=======================================================================
1846 //function : extrusionSweep
1848 //=======================================================================
1850 SMESH::ListOfGroups*
1851 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
1852 const SMESH::DirStruct & theStepVector,
1853 CORBA::Long theNbOfSteps,
1855 const SMDSAbs_ElementType theElementType)
1863 TIDSortedElemSet elements, copyElements;
1864 arrayToSet(theIDsOfElements, GetMeshDS(), elements, theElementType);
1866 const SMESH::PointStruct * P = &theStepVector.PS;
1867 gp_Vec stepVec( P->x, P->y, P->z );
1869 TIDSortedElemSet* workElements = & elements;
1870 TPreviewMesh tmpMesh( SMDSAbs_Face );
1871 SMESH_Mesh* mesh = myMesh;
1873 if ( myPreviewMode ) {
1874 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
1875 tmpMesh.Copy( elements, copyElements, select, avoid );
1877 workElements = & copyElements;
1878 theMakeGroups = false;
1881 TElemOfElemListMap aHystory;
1882 ::SMESH_MeshEditor anEditor( mesh );
1883 ::SMESH_MeshEditor::PGroupIDs groupIds =
1884 anEditor.ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
1886 myMesh->GetMeshDS()->Modified();
1887 storeResult(anEditor);
1889 return theMakeGroups ? getGroups(groupIds.get()) : 0;
1891 } catch(Standard_Failure) {
1892 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1893 INFOS( "SMESH_MeshEditor_i::ExtrusionSweep fails - "<< aFail->GetMessageString() );
1898 //=======================================================================
1899 //function : ExtrusionSweep
1901 //=======================================================================
1903 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
1904 const SMESH::DirStruct & theStepVector,
1905 CORBA::Long theNbOfSteps)
1907 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
1908 if (!myPreviewMode) {
1909 TPythonDump() << this << ".ExtrusionSweep( "
1910 << theIDsOfElements << ", " << theStepVector <<", " << theNbOfSteps << " )";
1915 //=======================================================================
1916 //function : ExtrusionSweepObject
1918 //=======================================================================
1920 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
1921 const SMESH::DirStruct & theStepVector,
1922 CORBA::Long theNbOfSteps)
1924 SMESH::long_array_var anElementsId = theObject->GetIDs();
1925 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
1926 if (!myPreviewMode) {
1927 TPythonDump() << this << ".ExtrusionSweepObject( "
1928 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
1932 //=======================================================================
1933 //function : ExtrusionSweepObject1D
1935 //=======================================================================
1937 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
1938 const SMESH::DirStruct & theStepVector,
1939 CORBA::Long theNbOfSteps)
1941 SMESH::long_array_var anElementsId = theObject->GetIDs();
1942 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
1943 if ( !myPreviewMode ) {
1944 TPythonDump() << this << ".ExtrusionSweepObject1D( "
1945 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
1949 //=======================================================================
1950 //function : ExtrusionSweepObject2D
1952 //=======================================================================
1954 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
1955 const SMESH::DirStruct & theStepVector,
1956 CORBA::Long theNbOfSteps)
1958 SMESH::long_array_var anElementsId = theObject->GetIDs();
1959 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
1960 if ( !myPreviewMode ) {
1961 TPythonDump() << this << ".ExtrusionSweepObject2D( "
1962 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
1966 //=======================================================================
1967 //function : ExtrusionSweepMakeGroups
1969 //=======================================================================
1971 SMESH::ListOfGroups*
1972 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
1973 const SMESH::DirStruct& theStepVector,
1974 CORBA::Long theNbOfSteps)
1976 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1978 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
1980 if (!myPreviewMode) {
1981 DumpGroupsList(aPythonDump, aGroups);
1982 aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
1983 << ", " << theStepVector <<", " << theNbOfSteps << " )";
1988 //=======================================================================
1989 //function : ExtrusionSweepObjectMakeGroups
1991 //=======================================================================
1993 SMESH::ListOfGroups*
1994 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1995 const SMESH::DirStruct& theStepVector,
1996 CORBA::Long theNbOfSteps)
1998 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2000 SMESH::long_array_var anElementsId = theObject->GetIDs();
2001 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
2003 if (!myPreviewMode) {
2004 DumpGroupsList(aPythonDump, aGroups);
2005 aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
2006 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2011 //=======================================================================
2012 //function : ExtrusionSweepObject1DMakeGroups
2014 //=======================================================================
2016 SMESH::ListOfGroups*
2017 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2018 const SMESH::DirStruct& theStepVector,
2019 CORBA::Long theNbOfSteps)
2021 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2023 SMESH::long_array_var anElementsId = theObject->GetIDs();
2024 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2025 theNbOfSteps, true, SMDSAbs_Edge);
2026 if (!myPreviewMode) {
2027 DumpGroupsList(aPythonDump, aGroups);
2028 aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
2029 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2034 //=======================================================================
2035 //function : ExtrusionSweepObject2DMakeGroups
2037 //=======================================================================
2039 SMESH::ListOfGroups*
2040 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2041 const SMESH::DirStruct& theStepVector,
2042 CORBA::Long theNbOfSteps)
2044 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2046 SMESH::long_array_var anElementsId = theObject->GetIDs();
2047 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2048 theNbOfSteps, true, SMDSAbs_Face);
2049 if (!myPreviewMode) {
2050 DumpGroupsList(aPythonDump, aGroups);
2051 aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
2052 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2058 //=======================================================================
2059 //function : advancedExtrusion
2061 //=======================================================================
2063 SMESH::ListOfGroups*
2064 SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
2065 const SMESH::DirStruct & theStepVector,
2066 CORBA::Long theNbOfSteps,
2067 CORBA::Long theExtrFlags,
2068 CORBA::Double theSewTolerance,
2069 const bool theMakeGroups)
2073 TIDSortedElemSet elements;
2074 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
2076 const SMESH::PointStruct * P = &theStepVector.PS;
2077 gp_Vec stepVec( P->x, P->y, P->z );
2079 ::SMESH_MeshEditor anEditor( myMesh );
2080 TElemOfElemListMap aHystory;
2081 ::SMESH_MeshEditor::PGroupIDs groupIds =
2082 anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
2083 theMakeGroups, theExtrFlags, theSewTolerance);
2084 storeResult(anEditor);
2086 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2089 //=======================================================================
2090 //function : AdvancedExtrusion
2092 //=======================================================================
2094 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2095 const SMESH::DirStruct & theStepVector,
2096 CORBA::Long theNbOfSteps,
2097 CORBA::Long theExtrFlags,
2098 CORBA::Double theSewTolerance)
2100 if ( !myPreviewMode ) {
2101 TPythonDump() << "stepVector = " << theStepVector;
2102 TPythonDump() << this << ".AdvancedExtrusion("
2105 << theNbOfSteps << ","
2106 << theExtrFlags << ", "
2107 << theSewTolerance << " )";
2109 advancedExtrusion( theIDsOfElements,
2117 //=======================================================================
2118 //function : AdvancedExtrusionMakeGroups
2120 //=======================================================================
2121 SMESH::ListOfGroups*
2122 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
2123 const SMESH::DirStruct& theStepVector,
2124 CORBA::Long theNbOfSteps,
2125 CORBA::Long theExtrFlags,
2126 CORBA::Double theSewTolerance)
2128 if (!myPreviewMode) {
2129 TPythonDump() << "stepVector = " << theStepVector;
2131 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2133 SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
2140 if (!myPreviewMode) {
2141 DumpGroupsList(aPythonDump, aGroups);
2142 aPythonDump << this << ".AdvancedExtrusionMakeGroups("
2145 << theNbOfSteps << ","
2146 << theExtrFlags << ", "
2147 << theSewTolerance << " )";
2153 //================================================================================
2155 * \brief Convert extrusion error to IDL enum
2157 //================================================================================
2159 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
2161 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
2165 RETCASE( EXTR_NO_ELEMENTS );
2166 RETCASE( EXTR_PATH_NOT_EDGE );
2167 RETCASE( EXTR_BAD_PATH_SHAPE );
2168 RETCASE( EXTR_BAD_STARTING_NODE );
2169 RETCASE( EXTR_BAD_ANGLES_NUMBER );
2170 RETCASE( EXTR_CANT_GET_TANGENT );
2172 return SMESH::SMESH_MeshEditor::EXTR_OK;
2176 //=======================================================================
2177 //function : extrusionAlongPath
2179 //=======================================================================
2180 SMESH::ListOfGroups*
2181 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2182 SMESH::SMESH_Mesh_ptr thePathMesh,
2183 GEOM::GEOM_Object_ptr thePathShape,
2184 CORBA::Long theNodeStart,
2185 CORBA::Boolean theHasAngles,
2186 const SMESH::double_array & theAngles,
2187 CORBA::Boolean theHasRefPoint,
2188 const SMESH::PointStruct & theRefPoint,
2189 const bool theMakeGroups,
2190 SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
2191 const SMDSAbs_ElementType theElementType)
2193 MESSAGE("extrusionAlongPath");
2196 if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
2197 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2200 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2202 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2203 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2205 if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
2206 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2210 SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
2212 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2216 TIDSortedElemSet elements;
2217 arrayToSet(theIDsOfElements, GetMeshDS(), elements, theElementType);
2219 list<double> angles;
2220 for (int i = 0; i < theAngles.length(); i++) {
2221 angles.push_back( theAngles[i] );
2224 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
2226 int nbOldGroups = myMesh->NbGroup();
2228 ::SMESH_MeshEditor anEditor( myMesh );
2229 ::SMESH_MeshEditor::Extrusion_Error error =
2230 anEditor.ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
2231 theHasAngles, angles, false,
2232 theHasRefPoint, refPnt, theMakeGroups );
2233 myMesh->GetMeshDS()->Modified();
2234 storeResult(anEditor);
2235 theError = convExtrError( error );
2237 if ( theMakeGroups ) {
2238 list<int> groupIDs = myMesh->GetGroupIds();
2239 list<int>::iterator newBegin = groupIDs.begin();
2240 std::advance( newBegin, nbOldGroups ); // skip old groups
2241 groupIDs.erase( groupIDs.begin(), newBegin );
2242 return getGroups( & groupIDs );
2248 //=======================================================================
2249 //function : extrusionAlongPathX
2251 //=======================================================================
2252 SMESH::ListOfGroups*
2253 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements,
2254 SMESH::SMESH_IDSource_ptr Path,
2255 CORBA::Long NodeStart,
2256 CORBA::Boolean HasAngles,
2257 const SMESH::double_array& Angles,
2258 CORBA::Boolean LinearVariation,
2259 CORBA::Boolean HasRefPoint,
2260 const SMESH::PointStruct& RefPoint,
2262 const SMDSAbs_ElementType ElementType,
2263 SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
2265 SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
2269 list<double> angles;
2270 for (int i = 0; i < Angles.length(); i++) {
2271 angles.push_back( Angles[i] );
2273 gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
2274 int nbOldGroups = myMesh->NbGroup();
2276 if ( Path->_is_nil() ) {
2277 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2281 TIDSortedElemSet elements, copyElements;
2282 arrayToSet(IDsOfElements, GetMeshDS(), elements, ElementType);
2284 TIDSortedElemSet* workElements = &elements;
2285 TPreviewMesh tmpMesh( SMDSAbs_Face );
2286 SMESH_Mesh* mesh = myMesh;
2288 if ( myPreviewMode )
2290 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2291 tmpMesh.Copy( elements, copyElements, select, avoid );
2293 workElements = & copyElements;
2297 ::SMESH_MeshEditor anEditor( mesh );
2298 ::SMESH_MeshEditor::Extrusion_Error error;
2300 if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path ))
2303 SMDS_MeshNode* aNodeStart =
2304 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2305 if ( !aNodeStart ) {
2306 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2309 error = anEditor.ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
2310 HasAngles, angles, LinearVariation,
2311 HasRefPoint, refPnt, MakeGroups );
2312 myMesh->GetMeshDS()->Modified();
2314 else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
2317 SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
2318 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
2319 SMDS_MeshNode* aNodeStart =
2320 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2321 if ( !aNodeStart ) {
2322 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2325 SMESH_subMesh* aSubMesh =
2326 aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
2327 error = anEditor.ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
2328 HasAngles, angles, LinearVariation,
2329 HasRefPoint, refPnt, MakeGroups );
2330 myMesh->GetMeshDS()->Modified();
2332 else if ( SMESH::DownCast<SMESH_Group_i*>( Path ))
2334 // path as group of 1D elements
2340 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2344 storeResult(anEditor);
2345 Error = convExtrError( error );
2348 list<int> groupIDs = myMesh->GetGroupIds();
2349 list<int>::iterator newBegin = groupIDs.begin();
2350 std::advance( newBegin, nbOldGroups ); // skip old groups
2351 groupIDs.erase( groupIDs.begin(), newBegin );
2352 return getGroups( & groupIDs );
2358 //=======================================================================
2359 //function : ExtrusionAlongPath
2361 //=======================================================================
2362 SMESH::SMESH_MeshEditor::Extrusion_Error
2363 SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2364 SMESH::SMESH_Mesh_ptr thePathMesh,
2365 GEOM::GEOM_Object_ptr thePathShape,
2366 CORBA::Long theNodeStart,
2367 CORBA::Boolean theHasAngles,
2368 const SMESH::double_array & theAngles,
2369 CORBA::Boolean theHasRefPoint,
2370 const SMESH::PointStruct & theRefPoint)
2372 MESSAGE("ExtrusionAlongPath");
2373 if ( !myPreviewMode ) {
2374 TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
2375 << theIDsOfElements << ", "
2376 << thePathMesh << ", "
2377 << thePathShape << ", "
2378 << theNodeStart << ", "
2379 << theHasAngles << ", "
2380 << theAngles << ", "
2381 << theHasRefPoint << ", "
2382 << "SMESH.PointStruct( "
2383 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2384 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2385 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2387 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2388 extrusionAlongPath( theIDsOfElements,
2401 //=======================================================================
2402 //function : ExtrusionAlongPathObject
2404 //=======================================================================
2405 SMESH::SMESH_MeshEditor::Extrusion_Error
2406 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject,
2407 SMESH::SMESH_Mesh_ptr thePathMesh,
2408 GEOM::GEOM_Object_ptr thePathShape,
2409 CORBA::Long theNodeStart,
2410 CORBA::Boolean theHasAngles,
2411 const SMESH::double_array & theAngles,
2412 CORBA::Boolean theHasRefPoint,
2413 const SMESH::PointStruct & theRefPoint)
2415 if ( !myPreviewMode ) {
2416 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
2417 << theObject << ", "
2418 << thePathMesh << ", "
2419 << thePathShape << ", "
2420 << theNodeStart << ", "
2421 << theHasAngles << ", "
2422 << theAngles << ", "
2423 << theHasRefPoint << ", "
2424 << "SMESH.PointStruct( "
2425 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2426 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2427 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2429 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2430 SMESH::long_array_var anElementsId = theObject->GetIDs();
2431 extrusionAlongPath( anElementsId,
2444 //=======================================================================
2445 //function : ExtrusionAlongPathObject1D
2447 //=======================================================================
2448 SMESH::SMESH_MeshEditor::Extrusion_Error
2449 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject,
2450 SMESH::SMESH_Mesh_ptr thePathMesh,
2451 GEOM::GEOM_Object_ptr thePathShape,
2452 CORBA::Long theNodeStart,
2453 CORBA::Boolean theHasAngles,
2454 const SMESH::double_array & theAngles,
2455 CORBA::Boolean theHasRefPoint,
2456 const SMESH::PointStruct & theRefPoint)
2458 if ( !myPreviewMode ) {
2459 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
2460 << theObject << ", "
2461 << thePathMesh << ", "
2462 << thePathShape << ", "
2463 << theNodeStart << ", "
2464 << theHasAngles << ", "
2465 << theAngles << ", "
2466 << theHasRefPoint << ", "
2467 << "SMESH.PointStruct( "
2468 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2469 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2470 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2472 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2473 SMESH::long_array_var anElementsId = theObject->GetIDs();
2474 extrusionAlongPath( anElementsId,
2488 //=======================================================================
2489 //function : ExtrusionAlongPathObject2D
2491 //=======================================================================
2492 SMESH::SMESH_MeshEditor::Extrusion_Error
2493 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject,
2494 SMESH::SMESH_Mesh_ptr thePathMesh,
2495 GEOM::GEOM_Object_ptr thePathShape,
2496 CORBA::Long theNodeStart,
2497 CORBA::Boolean theHasAngles,
2498 const SMESH::double_array & theAngles,
2499 CORBA::Boolean theHasRefPoint,
2500 const SMESH::PointStruct & theRefPoint)
2502 if ( !myPreviewMode ) {
2503 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
2504 << theObject << ", "
2505 << thePathMesh << ", "
2506 << thePathShape << ", "
2507 << theNodeStart << ", "
2508 << theHasAngles << ", "
2509 << theAngles << ", "
2510 << theHasRefPoint << ", "
2511 << "SMESH.PointStruct( "
2512 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2513 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2514 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2516 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2517 SMESH::long_array_var anElementsId = theObject->GetIDs();
2518 extrusionAlongPath( anElementsId,
2533 //=======================================================================
2534 //function : ExtrusionAlongPathMakeGroups
2536 //=======================================================================
2537 SMESH::ListOfGroups*
2538 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theIDsOfElements,
2539 SMESH::SMESH_Mesh_ptr thePathMesh,
2540 GEOM::GEOM_Object_ptr thePathShape,
2541 CORBA::Long theNodeStart,
2542 CORBA::Boolean theHasAngles,
2543 const SMESH::double_array& theAngles,
2544 CORBA::Boolean theHasRefPoint,
2545 const SMESH::PointStruct& theRefPoint,
2546 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2548 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2550 SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements,
2560 if (!myPreviewMode) {
2561 bool isDumpGroups = aGroups && aGroups->length() > 0;
2563 aPythonDump << "(" << aGroups << ", error)";
2565 aPythonDump <<"error";
2567 aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
2568 << theIDsOfElements << ", "
2569 << thePathMesh << ", "
2570 << thePathShape << ", "
2571 << theNodeStart << ", "
2572 << theHasAngles << ", "
2573 << theAngles << ", "
2574 << theHasRefPoint << ", "
2575 << "SMESH.PointStruct( "
2576 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2577 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2578 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2583 //=======================================================================
2584 //function : ExtrusionAlongPathObjectMakeGroups
2586 //=======================================================================
2587 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2588 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2589 SMESH::SMESH_Mesh_ptr thePathMesh,
2590 GEOM::GEOM_Object_ptr thePathShape,
2591 CORBA::Long theNodeStart,
2592 CORBA::Boolean theHasAngles,
2593 const SMESH::double_array& theAngles,
2594 CORBA::Boolean theHasRefPoint,
2595 const SMESH::PointStruct& theRefPoint,
2596 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2598 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2600 SMESH::long_array_var anElementsId = theObject->GetIDs();
2601 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
2612 if (!myPreviewMode) {
2613 bool isDumpGroups = aGroups && aGroups->length() > 0;
2615 aPythonDump << "(" << aGroups << ", error)";
2617 aPythonDump <<"error";
2619 aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
2620 << theObject << ", "
2621 << thePathMesh << ", "
2622 << thePathShape << ", "
2623 << theNodeStart << ", "
2624 << theHasAngles << ", "
2625 << theAngles << ", "
2626 << theHasRefPoint << ", "
2627 << "SMESH.PointStruct( "
2628 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2629 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2630 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2635 //=======================================================================
2636 //function : ExtrusionAlongPathObject1DMakeGroups
2638 //=======================================================================
2639 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2640 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2641 SMESH::SMESH_Mesh_ptr thePathMesh,
2642 GEOM::GEOM_Object_ptr thePathShape,
2643 CORBA::Long theNodeStart,
2644 CORBA::Boolean theHasAngles,
2645 const SMESH::double_array& theAngles,
2646 CORBA::Boolean theHasRefPoint,
2647 const SMESH::PointStruct& theRefPoint,
2648 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2650 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2652 SMESH::long_array_var anElementsId = theObject->GetIDs();
2653 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
2665 if (!myPreviewMode) {
2666 bool isDumpGroups = aGroups && aGroups->length() > 0;
2668 aPythonDump << "(" << aGroups << ", error)";
2670 aPythonDump << "error";
2672 aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
2673 << theObject << ", "
2674 << thePathMesh << ", "
2675 << thePathShape << ", "
2676 << theNodeStart << ", "
2677 << theHasAngles << ", "
2678 << theAngles << ", "
2679 << theHasRefPoint << ", "
2680 << "SMESH.PointStruct( "
2681 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2682 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2683 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2688 //=======================================================================
2689 //function : ExtrusionAlongPathObject2DMakeGroups
2691 //=======================================================================
2692 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2693 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2694 SMESH::SMESH_Mesh_ptr thePathMesh,
2695 GEOM::GEOM_Object_ptr thePathShape,
2696 CORBA::Long theNodeStart,
2697 CORBA::Boolean theHasAngles,
2698 const SMESH::double_array& theAngles,
2699 CORBA::Boolean theHasRefPoint,
2700 const SMESH::PointStruct& theRefPoint,
2701 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2703 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2705 SMESH::long_array_var anElementsId = theObject->GetIDs();
2706 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
2718 if (!myPreviewMode) {
2719 bool isDumpGroups = aGroups && aGroups->length() > 0;
2721 aPythonDump << "(" << aGroups << ", error)";
2723 aPythonDump << "error";
2725 aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
2726 << theObject << ", "
2727 << thePathMesh << ", "
2728 << thePathShape << ", "
2729 << theNodeStart << ", "
2730 << theHasAngles << ", "
2731 << theAngles << ", "
2732 << theHasRefPoint << ", "
2733 << "SMESH.PointStruct( "
2734 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2735 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2736 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2742 //=======================================================================
2743 //function : ExtrusionAlongPathObjX
2745 //=======================================================================
2746 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2747 ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr Object,
2748 SMESH::SMESH_IDSource_ptr Path,
2749 CORBA::Long NodeStart,
2750 CORBA::Boolean HasAngles,
2751 const SMESH::double_array& Angles,
2752 CORBA::Boolean LinearVariation,
2753 CORBA::Boolean HasRefPoint,
2754 const SMESH::PointStruct& RefPoint,
2755 CORBA::Boolean MakeGroups,
2756 SMESH::ElementType ElemType,
2757 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2759 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2761 SMESH::long_array_var anElementsId = Object->GetIDs();
2762 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
2771 (SMDSAbs_ElementType)ElemType,
2774 if (!myPreviewMode) {
2775 bool isDumpGroups = aGroups && aGroups->length() > 0;
2777 aPythonDump << "(" << *aGroups << ", error)";
2779 aPythonDump << "error";
2781 aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
2784 << NodeStart << ", "
2785 << HasAngles << ", "
2787 << LinearVariation << ", "
2788 << HasRefPoint << ", "
2789 << "SMESH.PointStruct( "
2790 << ( HasRefPoint ? RefPoint.x : 0 ) << ", "
2791 << ( HasRefPoint ? RefPoint.y : 0 ) << ", "
2792 << ( HasRefPoint ? RefPoint.z : 0 ) << " ), "
2793 << MakeGroups << ", "
2794 << ElemType << " )";
2800 //=======================================================================
2801 //function : ExtrusionAlongPathX
2803 //=======================================================================
2804 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2805 ExtrusionAlongPathX(const SMESH::long_array& IDsOfElements,
2806 SMESH::SMESH_IDSource_ptr Path,
2807 CORBA::Long NodeStart,
2808 CORBA::Boolean HasAngles,
2809 const SMESH::double_array& Angles,
2810 CORBA::Boolean LinearVariation,
2811 CORBA::Boolean HasRefPoint,
2812 const SMESH::PointStruct& RefPoint,
2813 CORBA::Boolean MakeGroups,
2814 SMESH::ElementType ElemType,
2815 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2817 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2819 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
2828 (SMDSAbs_ElementType)ElemType,
2831 if (!myPreviewMode) {
2832 bool isDumpGroups = aGroups && aGroups->length() > 0;
2834 aPythonDump << "(" << *aGroups << ", error)";
2836 aPythonDump <<"error";
2838 aPythonDump << " = " << this << ".ExtrusionAlongPathX( "
2839 << IDsOfElements << ", "
2841 << NodeStart << ", "
2842 << HasAngles << ", "
2844 << LinearVariation << ", "
2845 << HasRefPoint << ", "
2846 << "SMESH.PointStruct( "
2847 << ( HasRefPoint ? RefPoint.x : 0 ) << ", "
2848 << ( HasRefPoint ? RefPoint.y : 0 ) << ", "
2849 << ( HasRefPoint ? RefPoint.z : 0 ) << " ), "
2850 << MakeGroups << ", "
2851 << ElemType << " )";
2857 //================================================================================
2859 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
2860 * of given angles along path steps
2861 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
2862 * which proceeds the extrusion
2863 * \param PathShape is shape(edge); as the mesh can be complex, the edge
2864 * is used to define the sub-mesh for the path
2866 //================================================================================
2868 SMESH::double_array*
2869 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
2870 GEOM::GEOM_Object_ptr thePathShape,
2871 const SMESH::double_array & theAngles)
2873 SMESH::double_array_var aResult = new SMESH::double_array();
2874 int nbAngles = theAngles.length();
2875 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
2877 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2878 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2879 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2880 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
2881 return aResult._retn();
2882 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
2883 if ( nbSteps == nbAngles )
2885 aResult.inout() = theAngles;
2889 aResult->length( nbSteps );
2890 double rAn2St = double( nbAngles ) / double( nbSteps );
2891 double angPrev = 0, angle;
2892 for ( int iSt = 0; iSt < nbSteps; ++iSt )
2894 double angCur = rAn2St * ( iSt+1 );
2895 double angCurFloor = floor( angCur );
2896 double angPrevFloor = floor( angPrev );
2897 if ( angPrevFloor == angCurFloor )
2898 angle = rAn2St * theAngles[ int( angCurFloor ) ];
2901 int iP = int( angPrevFloor );
2902 double angPrevCeil = ceil(angPrev);
2903 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
2905 int iC = int( angCurFloor );
2906 if ( iC < nbAngles )
2907 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
2909 iP = int( angPrevCeil );
2911 angle += theAngles[ iC ];
2913 aResult[ iSt ] = angle;
2918 // Update Python script
2919 TPythonDump() << "rotAngles = " << theAngles;
2920 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
2921 << thePathMesh << ", "
2922 << thePathShape << ", "
2925 return aResult._retn();
2929 //=======================================================================
2932 //=======================================================================
2934 SMESH::ListOfGroups*
2935 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
2936 const SMESH::AxisStruct & theAxis,
2937 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
2938 CORBA::Boolean theCopy,
2940 ::SMESH_Mesh* theTargetMesh)
2944 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
2945 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
2947 if ( theTargetMesh )
2951 switch ( theMirrorType ) {
2952 case SMESH::SMESH_MeshEditor::POINT:
2953 aTrsf.SetMirror( P );
2955 case SMESH::SMESH_MeshEditor::AXIS:
2956 aTrsf.SetMirror( gp_Ax1( P, V ));
2959 aTrsf.SetMirror( gp_Ax2( P, V ));
2962 TIDSortedElemSet copyElements;
2963 TPreviewMesh tmpMesh;
2964 TIDSortedElemSet* workElements = & theElements;
2965 SMESH_Mesh* mesh = myMesh;
2967 if ( myPreviewMode )
2969 tmpMesh.Copy( theElements, copyElements);
2970 if ( !theCopy && !theTargetMesh )
2972 TIDSortedElemSet elemsAround, elemsAroundCopy;
2973 getElementsAround( theElements, GetMeshDS(), elemsAround );
2974 tmpMesh.Copy( elemsAround, elemsAroundCopy);
2977 workElements = & copyElements;
2978 theMakeGroups = false;
2981 ::SMESH_MeshEditor anEditor( mesh );
2982 ::SMESH_MeshEditor::PGroupIDs groupIds =
2983 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
2985 if(theCopy || myPreviewMode)
2986 storeResult(anEditor);
2989 myMesh->SetIsModified( true );
2990 myMesh->GetMeshDS()->Modified();
2992 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2995 //=======================================================================
2998 //=======================================================================
3000 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3001 const SMESH::AxisStruct & theAxis,
3002 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3003 CORBA::Boolean theCopy)
3005 if ( !myPreviewMode ) {
3006 TPythonDump() << this << ".Mirror( "
3007 << theIDsOfElements << ", "
3009 << mirrorTypeName(theMirrorType) << ", "
3012 if ( theIDsOfElements.length() > 0 )
3014 TIDSortedElemSet elements;
3015 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3016 mirror(elements, theAxis, theMirrorType, theCopy, false);
3021 //=======================================================================
3022 //function : MirrorObject
3024 //=======================================================================
3026 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3027 const SMESH::AxisStruct & theAxis,
3028 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3029 CORBA::Boolean theCopy)
3031 if ( !myPreviewMode ) {
3032 TPythonDump() << this << ".MirrorObject( "
3033 << theObject << ", "
3035 << mirrorTypeName(theMirrorType) << ", "
3038 TIDSortedElemSet elements;
3040 bool emptyIfIsMesh = myPreviewMode ? false : true;
3042 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3043 mirror(elements, theAxis, theMirrorType, theCopy, false);
3046 //=======================================================================
3047 //function : MirrorMakeGroups
3049 //=======================================================================
3051 SMESH::ListOfGroups*
3052 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3053 const SMESH::AxisStruct& theMirror,
3054 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3056 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3058 SMESH::ListOfGroups * aGroups = 0;
3059 if ( theIDsOfElements.length() > 0 )
3061 TIDSortedElemSet elements;
3062 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3063 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3065 if (!myPreviewMode) {
3066 DumpGroupsList(aPythonDump, aGroups);
3067 aPythonDump << this << ".MirrorMakeGroups( "
3068 << theIDsOfElements << ", "
3069 << theMirror << ", "
3070 << mirrorTypeName(theMirrorType) << " )";
3075 //=======================================================================
3076 //function : MirrorObjectMakeGroups
3078 //=======================================================================
3080 SMESH::ListOfGroups*
3081 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3082 const SMESH::AxisStruct& theMirror,
3083 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3085 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3087 SMESH::ListOfGroups * aGroups = 0;
3088 TIDSortedElemSet elements;
3089 if ( idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3090 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3094 DumpGroupsList(aPythonDump,aGroups);
3095 aPythonDump << this << ".MirrorObjectMakeGroups( "
3096 << theObject << ", "
3097 << theMirror << ", "
3098 << mirrorTypeName(theMirrorType) << " )";
3103 //=======================================================================
3104 //function : MirrorMakeMesh
3106 //=======================================================================
3108 SMESH::SMESH_Mesh_ptr
3109 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
3110 const SMESH::AxisStruct& theMirror,
3111 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3112 CORBA::Boolean theCopyGroups,
3113 const char* theMeshName)
3115 SMESH_Mesh_i* mesh_i;
3116 SMESH::SMESH_Mesh_var mesh;
3117 { // open new scope to dump "MakeMesh" command
3118 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3120 TPythonDump pydump; // to prevent dump at mesh creation
3122 mesh = makeMesh( theMeshName );
3123 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3124 if (mesh_i && theIDsOfElements.length() > 0 )
3126 TIDSortedElemSet elements;
3127 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3128 mirror(elements, theMirror, theMirrorType,
3129 false, theCopyGroups, & mesh_i->GetImpl());
3130 mesh_i->CreateGroupServants();
3133 if (!myPreviewMode) {
3134 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
3135 << theIDsOfElements << ", "
3136 << theMirror << ", "
3137 << mirrorTypeName(theMirrorType) << ", "
3138 << theCopyGroups << ", '"
3139 << theMeshName << "' )";
3144 if (!myPreviewMode && mesh_i)
3145 mesh_i->GetGroups();
3147 return mesh._retn();
3150 //=======================================================================
3151 //function : MirrorObjectMakeMesh
3153 //=======================================================================
3155 SMESH::SMESH_Mesh_ptr
3156 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3157 const SMESH::AxisStruct& theMirror,
3158 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3159 CORBA::Boolean theCopyGroups,
3160 const char* theMeshName)
3162 SMESH_Mesh_i* mesh_i;
3163 SMESH::SMESH_Mesh_var mesh;
3164 { // open new scope to dump "MakeMesh" command
3165 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3167 TPythonDump pydump; // to prevent dump at mesh creation
3169 mesh = makeMesh( theMeshName );
3170 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3171 TIDSortedElemSet elements;
3173 idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3175 mirror(elements, theMirror, theMirrorType,
3176 false, theCopyGroups, & mesh_i->GetImpl());
3177 mesh_i->CreateGroupServants();
3179 if (!myPreviewMode) {
3180 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
3181 << theObject << ", "
3182 << theMirror << ", "
3183 << mirrorTypeName(theMirrorType) << ", "
3184 << theCopyGroups << ", '"
3185 << theMeshName << "' )";
3190 if (!myPreviewMode && mesh_i)
3191 mesh_i->GetGroups();
3193 return mesh._retn();
3196 //=======================================================================
3197 //function : translate
3199 //=======================================================================
3201 SMESH::ListOfGroups*
3202 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
3203 const SMESH::DirStruct & theVector,
3204 CORBA::Boolean theCopy,
3206 ::SMESH_Mesh* theTargetMesh)
3210 if ( theTargetMesh )
3214 const SMESH::PointStruct * P = &theVector.PS;
3215 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
3217 TIDSortedElemSet copyElements;
3218 TIDSortedElemSet* workElements = &theElements;
3219 TPreviewMesh tmpMesh;
3220 SMESH_Mesh* mesh = myMesh;
3222 if ( myPreviewMode )
3224 tmpMesh.Copy( theElements, copyElements);
3225 if ( !theCopy && !theTargetMesh )
3227 TIDSortedElemSet elemsAround, elemsAroundCopy;
3228 getElementsAround( theElements, GetMeshDS(), elemsAround );
3229 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3232 workElements = & copyElements;
3233 theMakeGroups = false;
3236 ::SMESH_MeshEditor anEditor( mesh );
3237 ::SMESH_MeshEditor::PGroupIDs groupIds =
3238 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3240 if(theCopy || myPreviewMode)
3241 storeResult(anEditor);
3244 myMesh->GetMeshDS()->Modified();
3245 myMesh->SetIsModified( true );
3248 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3251 //=======================================================================
3252 //function : Translate
3254 //=======================================================================
3256 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
3257 const SMESH::DirStruct & theVector,
3258 CORBA::Boolean theCopy)
3260 if (!myPreviewMode) {
3261 TPythonDump() << this << ".Translate( "
3262 << theIDsOfElements << ", "
3263 << theVector << ", "
3266 if (theIDsOfElements.length()) {
3267 TIDSortedElemSet elements;
3268 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3269 translate(elements, theVector, theCopy, false);
3273 //=======================================================================
3274 //function : TranslateObject
3276 //=======================================================================
3278 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
3279 const SMESH::DirStruct & theVector,
3280 CORBA::Boolean theCopy)
3282 if (!myPreviewMode) {
3283 TPythonDump() << this << ".TranslateObject( "
3284 << theObject << ", "
3285 << theVector << ", "
3288 TIDSortedElemSet elements;
3290 bool emptyIfIsMesh = myPreviewMode ? false : true;
3292 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3293 translate(elements, theVector, theCopy, false);
3296 //=======================================================================
3297 //function : TranslateMakeGroups
3299 //=======================================================================
3301 SMESH::ListOfGroups*
3302 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
3303 const SMESH::DirStruct& theVector)
3305 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3307 SMESH::ListOfGroups * aGroups = 0;
3308 if (theIDsOfElements.length()) {
3309 TIDSortedElemSet elements;
3310 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3311 aGroups = translate(elements,theVector,true,true);
3313 if (!myPreviewMode) {
3314 DumpGroupsList(aPythonDump, aGroups);
3315 aPythonDump << this << ".TranslateMakeGroups( "
3316 << theIDsOfElements << ", "
3317 << theVector << " )";
3322 //=======================================================================
3323 //function : TranslateObjectMakeGroups
3325 //=======================================================================
3327 SMESH::ListOfGroups*
3328 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3329 const SMESH::DirStruct& theVector)
3331 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3333 SMESH::ListOfGroups * aGroups = 0;
3334 TIDSortedElemSet elements;
3335 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3336 aGroups = translate(elements, theVector, true, true);
3338 if (!myPreviewMode) {
3339 DumpGroupsList(aPythonDump, aGroups);
3340 aPythonDump << this << ".TranslateObjectMakeGroups( "
3341 << theObject << ", "
3342 << theVector << " )";
3347 //=======================================================================
3348 //function : TranslateMakeMesh
3350 //=======================================================================
3352 SMESH::SMESH_Mesh_ptr
3353 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
3354 const SMESH::DirStruct& theVector,
3355 CORBA::Boolean theCopyGroups,
3356 const char* theMeshName)
3358 SMESH_Mesh_i* mesh_i;
3359 SMESH::SMESH_Mesh_var mesh;
3361 { // open new scope to dump "MakeMesh" command
3362 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3364 TPythonDump pydump; // to prevent dump at mesh creation
3366 mesh = makeMesh( theMeshName );
3367 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3369 if ( mesh_i && theIDsOfElements.length() )
3371 TIDSortedElemSet elements;
3372 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3373 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
3374 mesh_i->CreateGroupServants();
3377 if ( !myPreviewMode ) {
3378 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
3379 << theIDsOfElements << ", "
3380 << theVector << ", "
3381 << theCopyGroups << ", '"
3382 << theMeshName << "' )";
3387 if (!myPreviewMode && mesh_i)
3388 mesh_i->GetGroups();
3390 return mesh._retn();
3393 //=======================================================================
3394 //function : TranslateObjectMakeMesh
3396 //=======================================================================
3398 SMESH::SMESH_Mesh_ptr
3399 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3400 const SMESH::DirStruct& theVector,
3401 CORBA::Boolean theCopyGroups,
3402 const char* theMeshName)
3404 SMESH_Mesh_i* mesh_i;
3405 SMESH::SMESH_Mesh_var mesh;
3406 { // open new scope to dump "MakeMesh" command
3407 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3409 TPythonDump pydump; // to prevent dump at mesh creation
3410 mesh = makeMesh( theMeshName );
3411 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3413 TIDSortedElemSet elements;
3415 idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3417 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
3418 mesh_i->CreateGroupServants();
3420 if ( !myPreviewMode ) {
3421 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
3422 << theObject << ", "
3423 << theVector << ", "
3424 << theCopyGroups << ", '"
3425 << theMeshName << "' )";
3430 if (!myPreviewMode && mesh_i)
3431 mesh_i->GetGroups();
3433 return mesh._retn();
3436 //=======================================================================
3439 //=======================================================================
3441 SMESH::ListOfGroups*
3442 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
3443 const SMESH::AxisStruct & theAxis,
3444 CORBA::Double theAngle,
3445 CORBA::Boolean theCopy,
3447 ::SMESH_Mesh* theTargetMesh)
3451 if ( theTargetMesh )
3454 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3455 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3458 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
3460 TIDSortedElemSet copyElements;
3461 TIDSortedElemSet* workElements = &theElements;
3462 TPreviewMesh tmpMesh;
3463 SMESH_Mesh* mesh = myMesh;
3465 if ( myPreviewMode ) {
3466 tmpMesh.Copy( theElements, copyElements );
3467 if ( !theCopy && !theTargetMesh )
3469 TIDSortedElemSet elemsAround, elemsAroundCopy;
3470 getElementsAround( theElements, GetMeshDS(), elemsAround );
3471 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3474 workElements = ©Elements;
3475 theMakeGroups = false;
3478 ::SMESH_MeshEditor anEditor( mesh );
3479 ::SMESH_MeshEditor::PGroupIDs groupIds =
3480 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3482 if(theCopy || myPreviewMode)
3483 storeResult(anEditor);
3486 myMesh->GetMeshDS()->Modified();
3487 myMesh->SetIsModified( true );
3490 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3493 //=======================================================================
3496 //=======================================================================
3498 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
3499 const SMESH::AxisStruct & theAxis,
3500 CORBA::Double theAngle,
3501 CORBA::Boolean theCopy)
3503 if (!myPreviewMode) {
3504 TPythonDump() << this << ".Rotate( "
3505 << theIDsOfElements << ", "
3510 if (theIDsOfElements.length() > 0)
3512 TIDSortedElemSet elements;
3513 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3514 rotate(elements,theAxis,theAngle,theCopy,false);
3518 //=======================================================================
3519 //function : RotateObject
3521 //=======================================================================
3523 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
3524 const SMESH::AxisStruct & theAxis,
3525 CORBA::Double theAngle,
3526 CORBA::Boolean theCopy)
3528 if ( !myPreviewMode ) {
3529 TPythonDump() << this << ".RotateObject( "
3530 << theObject << ", "
3535 TIDSortedElemSet elements;
3536 bool emptyIfIsMesh = myPreviewMode ? false : true;
3537 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3538 rotate(elements,theAxis,theAngle,theCopy,false);
3541 //=======================================================================
3542 //function : RotateMakeGroups
3544 //=======================================================================
3546 SMESH::ListOfGroups*
3547 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
3548 const SMESH::AxisStruct& theAxis,
3549 CORBA::Double theAngle)
3551 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3553 SMESH::ListOfGroups * aGroups = 0;
3554 if (theIDsOfElements.length() > 0)
3556 TIDSortedElemSet elements;
3557 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3558 aGroups = rotate(elements,theAxis,theAngle,true,true);
3560 if (!myPreviewMode) {
3561 DumpGroupsList(aPythonDump, aGroups);
3562 aPythonDump << this << ".RotateMakeGroups( "
3563 << theIDsOfElements << ", "
3565 << theAngle << " )";
3570 //=======================================================================
3571 //function : RotateObjectMakeGroups
3573 //=======================================================================
3575 SMESH::ListOfGroups*
3576 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3577 const SMESH::AxisStruct& theAxis,
3578 CORBA::Double theAngle)
3580 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3582 SMESH::ListOfGroups * aGroups = 0;
3583 TIDSortedElemSet elements;
3584 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3585 aGroups = rotate(elements, theAxis, theAngle, true, true);
3587 if (!myPreviewMode) {
3588 DumpGroupsList(aPythonDump, aGroups);
3589 aPythonDump << this << ".RotateObjectMakeGroups( "
3590 << theObject << ", "
3592 << theAngle << " )";
3597 //=======================================================================
3598 //function : RotateMakeMesh
3600 //=======================================================================
3602 SMESH::SMESH_Mesh_ptr
3603 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
3604 const SMESH::AxisStruct& theAxis,
3605 CORBA::Double theAngleInRadians,
3606 CORBA::Boolean theCopyGroups,
3607 const char* theMeshName)
3609 SMESH::SMESH_Mesh_var mesh;
3610 SMESH_Mesh_i* mesh_i;
3612 { // open new scope to dump "MakeMesh" command
3613 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3615 TPythonDump pydump; // to prevent dump at mesh creation
3617 mesh = makeMesh( theMeshName );
3618 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3620 if ( mesh_i && theIDsOfElements.length() > 0 )
3622 TIDSortedElemSet elements;
3623 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3624 rotate(elements, theAxis, theAngleInRadians,
3625 false, theCopyGroups, & mesh_i->GetImpl());
3626 mesh_i->CreateGroupServants();
3628 if ( !myPreviewMode ) {
3629 pydump << mesh << " = " << this << ".RotateMakeMesh( "
3630 << theIDsOfElements << ", "
3632 << theAngleInRadians << ", "
3633 << theCopyGroups << ", '"
3634 << theMeshName << "' )";
3639 if (!myPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
3640 mesh_i->GetGroups();
3642 return mesh._retn();
3645 //=======================================================================
3646 //function : RotateObjectMakeMesh
3648 //=======================================================================
3650 SMESH::SMESH_Mesh_ptr
3651 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3652 const SMESH::AxisStruct& theAxis,
3653 CORBA::Double theAngleInRadians,
3654 CORBA::Boolean theCopyGroups,
3655 const char* theMeshName)
3657 SMESH::SMESH_Mesh_var mesh;
3658 SMESH_Mesh_i* mesh_i;
3660 {// open new scope to dump "MakeMesh" command
3661 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3663 TPythonDump pydump; // to prevent dump at mesh creation
3664 mesh = makeMesh( theMeshName );
3665 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3667 TIDSortedElemSet elements;
3669 idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3671 rotate(elements, theAxis, theAngleInRadians,
3672 false, theCopyGroups, & mesh_i->GetImpl());
3673 mesh_i->CreateGroupServants();
3675 if ( !myPreviewMode ) {
3676 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
3677 << theObject << ", "
3679 << theAngleInRadians << ", "
3680 << theCopyGroups << ", '"
3681 << theMeshName << "' )";
3686 if (!myPreviewMode && mesh_i)
3687 mesh_i->GetGroups();
3689 return mesh._retn();
3692 //=======================================================================
3695 //=======================================================================
3697 SMESH::ListOfGroups*
3698 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
3699 const SMESH::PointStruct& thePoint,
3700 const SMESH::double_array& theScaleFact,
3701 CORBA::Boolean theCopy,
3703 ::SMESH_Mesh* theTargetMesh)
3706 if ( theScaleFact.length() < 1 )
3707 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
3708 if ( theScaleFact.length() == 2 )
3709 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
3711 if ( theTargetMesh )
3714 TIDSortedElemSet elements;
3715 bool emptyIfIsMesh = myPreviewMode ? false : true;
3716 if ( !idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3721 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
3722 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
3724 double tol = std::numeric_limits<double>::max();
3726 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
3727 0, S[1], 0, thePoint.y * (1-S[1]),
3728 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
3730 TIDSortedElemSet copyElements;
3731 TPreviewMesh tmpMesh;
3732 TIDSortedElemSet* workElements = &elements;
3733 SMESH_Mesh* mesh = myMesh;
3735 if ( myPreviewMode )
3737 tmpMesh.Copy( elements, copyElements);
3738 if ( !theCopy && !theTargetMesh )
3740 TIDSortedElemSet elemsAround, elemsAroundCopy;
3741 getElementsAround( elements, GetMeshDS(), elemsAround );
3742 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3745 workElements = & copyElements;
3746 theMakeGroups = false;
3749 ::SMESH_MeshEditor anEditor( mesh );
3750 ::SMESH_MeshEditor::PGroupIDs groupIds =
3751 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3753 if(theCopy || myPreviewMode )
3754 storeResult(anEditor);
3757 myMesh->GetMeshDS()->Modified();
3758 myMesh->SetIsModified( true );
3760 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3763 //=======================================================================
3766 //=======================================================================
3768 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
3769 const SMESH::PointStruct& thePoint,
3770 const SMESH::double_array& theScaleFact,
3771 CORBA::Boolean theCopy)
3773 if ( !myPreviewMode ) {
3774 TPythonDump() << this << ".Scale( "
3775 << theObject << ", "
3776 << "SMESH.PointStruct( " << thePoint.x << ", "
3777 << thePoint.y << ", " << thePoint.z << " ) ,"
3778 << theScaleFact << ", "
3781 scale(theObject, thePoint, theScaleFact, theCopy, false);
3785 //=======================================================================
3786 //function : ScaleMakeGroups
3788 //=======================================================================
3790 SMESH::ListOfGroups*
3791 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3792 const SMESH::PointStruct& thePoint,
3793 const SMESH::double_array& theScaleFact)
3795 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3797 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
3798 if (!myPreviewMode) {
3799 DumpGroupsList(aPythonDump, aGroups);
3800 aPythonDump << this << ".Scale("
3802 << "SMESH.PointStruct(" <<thePoint.x << ","
3803 << thePoint.y << "," << thePoint.z << "),"
3804 << theScaleFact << ",True,True)";
3810 //=======================================================================
3811 //function : ScaleMakeMesh
3813 //=======================================================================
3815 SMESH::SMESH_Mesh_ptr
3816 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3817 const SMESH::PointStruct& thePoint,
3818 const SMESH::double_array& theScaleFact,
3819 CORBA::Boolean theCopyGroups,
3820 const char* theMeshName)
3822 SMESH_Mesh_i* mesh_i;
3823 SMESH::SMESH_Mesh_var mesh;
3824 { // open new scope to dump "MakeMesh" command
3825 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3827 TPythonDump pydump; // to prevent dump at mesh creation
3828 mesh = makeMesh( theMeshName );
3829 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3833 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
3834 mesh_i->CreateGroupServants();
3836 if ( !myPreviewMode )
3837 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
3838 << theObject << ", "
3839 << "SMESH.PointStruct( " << thePoint.x << ", "
3840 << thePoint.y << ", " << thePoint.z << " ) ,"
3841 << theScaleFact << ", "
3842 << theCopyGroups << ", '"
3843 << theMeshName << "' )";
3847 if (!myPreviewMode && mesh_i)
3848 mesh_i->GetGroups();
3850 return mesh._retn();
3854 //=======================================================================
3855 //function : FindCoincidentNodes
3857 //=======================================================================
3859 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance,
3860 SMESH::array_of_long_array_out GroupsOfNodes)
3864 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3865 ::SMESH_MeshEditor anEditor( myMesh );
3866 TIDSortedNodeSet nodes; // no input nodes
3867 anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
3869 GroupsOfNodes = new SMESH::array_of_long_array;
3870 GroupsOfNodes->length( aListOfListOfNodes.size() );
3871 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
3872 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
3873 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
3874 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
3875 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
3876 aGroup.length( aListOfNodes.size() );
3877 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
3878 aGroup[ j ] = (*lIt)->GetID();
3880 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
3881 << Tolerance << " )";
3884 //=======================================================================
3885 //function : FindCoincidentNodesOnPart
3887 //=======================================================================
3888 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
3889 CORBA::Double Tolerance,
3890 SMESH::array_of_long_array_out GroupsOfNodes)
3894 TIDSortedNodeSet nodes;
3895 idSourceToNodeSet( theObject, GetMeshDS(), nodes );
3897 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3898 ::SMESH_MeshEditor anEditor( myMesh );
3900 anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
3902 GroupsOfNodes = new SMESH::array_of_long_array;
3903 GroupsOfNodes->length( aListOfListOfNodes.size() );
3904 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
3905 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
3907 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
3908 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
3909 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
3910 aGroup.length( aListOfNodes.size() );
3911 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
3912 aGroup[ j ] = (*lIt)->GetID();
3914 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
3916 << Tolerance << " )";
3919 //================================================================================
3921 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
3922 * ExceptSubMeshOrGroups
3924 //================================================================================
3926 void SMESH_MeshEditor_i::
3927 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
3928 CORBA::Double theTolerance,
3929 SMESH::array_of_long_array_out theGroupsOfNodes,
3930 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups)
3934 TIDSortedNodeSet nodes;
3935 idSourceToNodeSet( theObject, GetMeshDS(), nodes );
3937 for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
3939 TIDSortedNodeSet exceptNodes;
3940 idSourceToNodeSet( theExceptSubMeshOrGroups[i], GetMeshDS(), exceptNodes );
3941 TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
3942 for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
3943 nodes.erase( *avoidNode );
3945 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3946 ::SMESH_MeshEditor anEditor( myMesh );
3948 anEditor.FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
3950 theGroupsOfNodes = new SMESH::array_of_long_array;
3951 theGroupsOfNodes->length( aListOfListOfNodes.size() );
3952 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
3953 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
3955 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
3956 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
3957 SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
3958 aGroup.length( aListOfNodes.size() );
3959 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
3960 aGroup[ j ] = (*lIt)->GetID();
3962 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
3964 << theTolerance << ", "
3965 << theExceptSubMeshOrGroups << " )";
3968 //=======================================================================
3969 //function : MergeNodes
3971 //=======================================================================
3973 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
3977 SMESHDS_Mesh* aMesh = GetMeshDS();
3979 TPythonDump aTPythonDump;
3980 aTPythonDump << this << ".MergeNodes([";
3981 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3982 for (int i = 0; i < GroupsOfNodes.length(); i++)
3984 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
3985 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
3986 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
3987 for ( int j = 0; j < aNodeGroup.length(); j++ )
3989 CORBA::Long index = aNodeGroup[ j ];
3990 const SMDS_MeshNode * node = aMesh->FindNode(index);
3992 aListOfNodes.push_back( node );
3994 if ( aListOfNodes.size() < 2 )
3995 aListOfListOfNodes.pop_back();
3997 if ( i > 0 ) aTPythonDump << ", ";
3998 aTPythonDump << aNodeGroup;
4000 ::SMESH_MeshEditor anEditor( myMesh );
4001 anEditor.MergeNodes( aListOfListOfNodes );
4003 aTPythonDump << "])";
4004 myMesh->GetMeshDS()->Modified();
4005 myMesh->SetIsModified( true );
4008 //=======================================================================
4009 //function : FindEqualElements
4011 //=======================================================================
4012 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
4013 SMESH::array_of_long_array_out GroupsOfElementsID)
4017 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
4018 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
4020 typedef list<int> TListOfIDs;
4021 set<const SMDS_MeshElement*> elems;
4022 SMESH::long_array_var aElementsId = theObject->GetIDs();
4023 SMESHDS_Mesh* aMesh = GetMeshDS();
4025 for(int i = 0; i < aElementsId->length(); i++) {
4026 CORBA::Long anID = aElementsId[i];
4027 const SMDS_MeshElement * elem = aMesh->FindElement(anID);
4033 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4034 ::SMESH_MeshEditor anEditor( myMesh );
4035 anEditor.FindEqualElements( elems, aListOfListOfElementsID );
4037 GroupsOfElementsID = new SMESH::array_of_long_array;
4038 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
4040 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt = aListOfListOfElementsID.begin();
4041 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j) {
4042 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
4043 TListOfIDs& listOfIDs = *arraysIt;
4044 aGroup.length( listOfIDs.size() );
4045 TListOfIDs::iterator idIt = listOfIDs.begin();
4046 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k ) {
4047 aGroup[ k ] = *idIt;
4051 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
4056 //=======================================================================
4057 //function : MergeElements
4059 //=======================================================================
4061 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
4065 TPythonDump aTPythonDump;
4066 aTPythonDump << this << ".MergeElements( [";
4068 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4070 for (int i = 0; i < GroupsOfElementsID.length(); i++) {
4071 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
4072 aListOfListOfElementsID.push_back( list< int >() );
4073 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
4074 for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
4075 CORBA::Long id = anElemsIDGroup[ j ];
4076 aListOfElemsID.push_back( id );
4078 if ( aListOfElemsID.size() < 2 )
4079 aListOfListOfElementsID.pop_back();
4080 if ( i > 0 ) aTPythonDump << ", ";
4081 aTPythonDump << anElemsIDGroup;
4084 ::SMESH_MeshEditor anEditor( myMesh );
4085 anEditor.MergeElements(aListOfListOfElementsID);
4086 myMesh->GetMeshDS()->Modified();
4087 myMesh->SetIsModified( true );
4089 aTPythonDump << "] )";
4092 //=======================================================================
4093 //function : MergeEqualElements
4095 //=======================================================================
4097 void SMESH_MeshEditor_i::MergeEqualElements()
4101 ::SMESH_MeshEditor anEditor( myMesh );
4102 anEditor.MergeEqualElements();
4104 TPythonDump() << this << ".MergeEqualElements()";
4107 //=============================================================================
4109 * Move the node to a given point
4111 //=============================================================================
4113 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
4118 initData(/*deleteSearchers=*/false);
4120 const SMDS_MeshNode * node = GetMeshDS()->FindNode( NodeID );
4124 if ( theNodeSearcher )
4125 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4127 if ( myPreviewMode ) // make preview data
4129 // in a preview mesh, make edges linked to a node
4130 TPreviewMesh tmpMesh;
4131 TIDSortedElemSet linkedNodes;
4132 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4133 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4134 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
4135 for ( ; nIt != linkedNodes.end(); ++nIt )
4137 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
4138 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
4142 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
4143 // fill preview data
4144 ::SMESH_MeshEditor anEditor( & tmpMesh );
4145 storeResult( anEditor );
4147 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4148 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4150 GetMeshDS()->MoveNode(node, x, y, z);
4152 if ( !myPreviewMode )
4154 // Update Python script
4155 TPythonDump() << "isDone = " << this << ".MoveNode( "
4156 << NodeID << ", " << x << ", " << y << ", " << z << " )";
4157 myMesh->GetMeshDS()->Modified();
4158 myMesh->SetIsModified( true );
4164 //================================================================================
4166 * \brief Return ID of node closest to a given point
4168 //================================================================================
4170 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
4174 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4176 if ( !theNodeSearcher ) {
4177 ::SMESH_MeshEditor anEditor( myMesh );
4178 theNodeSearcher = anEditor.GetNodeSearcher();
4181 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
4182 return node->GetID();
4187 //================================================================================
4189 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
4190 * move the node closest to the point to point's location and return ID of the node
4192 //================================================================================
4194 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
4197 CORBA::Long theNodeID)
4199 // We keep theNodeSearcher until any mesh modification:
4200 // 1) initData() deletes theNodeSearcher at any edition,
4201 // 2) TSearchersDeleter - at any mesh compute event and mesh change
4203 initData(/*deleteSearchers=*/false);
4205 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4207 int nodeID = theNodeID;
4208 const SMDS_MeshNode* node = GetMeshDS()->FindNode( nodeID );
4209 if ( !node ) // preview moving node
4211 if ( !theNodeSearcher ) {
4212 ::SMESH_MeshEditor anEditor( myMesh );
4213 theNodeSearcher = anEditor.GetNodeSearcher();
4216 node = theNodeSearcher->FindClosestTo( p );
4219 nodeID = node->GetID();
4220 if ( myPreviewMode ) // make preview data
4222 // in a preview mesh, make edges linked to a node
4223 TPreviewMesh tmpMesh;
4224 TIDSortedElemSet linkedNodes;
4225 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4226 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4227 for ( ; nIt != linkedNodes.end(); ++nIt )
4229 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
4230 tmpMesh.Copy( &edge );
4233 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
4235 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
4236 // fill preview data
4237 ::SMESH_MeshEditor anEditor( & tmpMesh );
4238 storeResult( anEditor );
4240 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4242 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4246 GetMeshDS()->MoveNode(node, x, y, z);
4250 if ( !myPreviewMode )
4252 TPythonDump() << "nodeID = " << this
4253 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
4254 << ", " << nodeID << " )";
4256 myMesh->GetMeshDS()->Modified();
4257 myMesh->SetIsModified( true );
4263 //=======================================================================
4265 * Return elements of given type where the given point is IN or ON.
4267 * 'ALL' type means elements of any type excluding nodes
4269 //=======================================================================
4271 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
4274 SMESH::ElementType type)
4276 SMESH::long_array_var res = new SMESH::long_array;
4277 vector< const SMDS_MeshElement* > foundElems;
4279 theSearchersDeleter.Set( myMesh );
4280 if ( !theElementSearcher ) {
4281 ::SMESH_MeshEditor anEditor( myMesh );
4282 theElementSearcher = anEditor.GetElementSearcher();
4284 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4285 SMDSAbs_ElementType( type ),
4287 res->length( foundElems.size() );
4288 for ( int i = 0; i < foundElems.size(); ++i )
4289 res[i] = foundElems[i]->GetID();
4291 if ( !myPreviewMode ) // call from tui
4292 TPythonDump() << res << " = " << this << ".FindElementsByPoint( "
4301 //=======================================================================
4302 //function : GetPointState
4303 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
4304 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
4305 //=======================================================================
4307 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
4311 theSearchersDeleter.Set( myMesh );
4312 if ( !theElementSearcher ) {
4313 ::SMESH_MeshEditor anEditor( myMesh );
4314 theElementSearcher = anEditor.GetElementSearcher();
4316 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
4319 //=======================================================================
4320 //function : convError
4322 //=======================================================================
4324 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
4326 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
4330 RETCASE( SEW_BORDER1_NOT_FOUND );
4331 RETCASE( SEW_BORDER2_NOT_FOUND );
4332 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
4333 RETCASE( SEW_BAD_SIDE_NODES );
4334 RETCASE( SEW_VOLUMES_TO_SPLIT );
4335 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
4336 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
4337 RETCASE( SEW_BAD_SIDE1_NODES );
4338 RETCASE( SEW_BAD_SIDE2_NODES );
4340 return SMESH::SMESH_MeshEditor::SEW_OK;
4343 //=======================================================================
4344 //function : SewFreeBorders
4346 //=======================================================================
4348 SMESH::SMESH_MeshEditor::Sew_Error
4349 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
4350 CORBA::Long SecondNodeID1,
4351 CORBA::Long LastNodeID1,
4352 CORBA::Long FirstNodeID2,
4353 CORBA::Long SecondNodeID2,
4354 CORBA::Long LastNodeID2,
4355 CORBA::Boolean CreatePolygons,
4356 CORBA::Boolean CreatePolyedrs)
4360 SMESHDS_Mesh* aMesh = GetMeshDS();
4362 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4363 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4364 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4365 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4366 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4367 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
4369 if (!aBorderFirstNode ||
4370 !aBorderSecondNode||
4372 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4373 if (!aSide2FirstNode ||
4374 !aSide2SecondNode ||
4376 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4378 TPythonDump() << "error = " << this << ".SewFreeBorders( "
4379 << FirstNodeID1 << ", "
4380 << SecondNodeID1 << ", "
4381 << LastNodeID1 << ", "
4382 << FirstNodeID2 << ", "
4383 << SecondNodeID2 << ", "
4384 << LastNodeID2 << ", "
4385 << CreatePolygons<< ", "
4386 << CreatePolyedrs<< " )";
4388 ::SMESH_MeshEditor anEditor( myMesh );
4389 SMESH::SMESH_MeshEditor::Sew_Error error =
4390 convError( anEditor.SewFreeBorder (aBorderFirstNode,
4400 storeResult(anEditor);
4402 myMesh->GetMeshDS()->Modified();
4403 myMesh->SetIsModified( true );
4409 //=======================================================================
4410 //function : SewConformFreeBorders
4412 //=======================================================================
4414 SMESH::SMESH_MeshEditor::Sew_Error
4415 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
4416 CORBA::Long SecondNodeID1,
4417 CORBA::Long LastNodeID1,
4418 CORBA::Long FirstNodeID2,
4419 CORBA::Long SecondNodeID2)
4423 SMESHDS_Mesh* aMesh = GetMeshDS();
4425 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4426 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4427 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4428 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4429 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4430 const SMDS_MeshNode* aSide2ThirdNode = 0;
4432 if (!aBorderFirstNode ||
4433 !aBorderSecondNode||
4435 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4436 if (!aSide2FirstNode ||
4438 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4440 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
4441 << FirstNodeID1 << ", "
4442 << SecondNodeID1 << ", "
4443 << LastNodeID1 << ", "
4444 << FirstNodeID2 << ", "
4445 << SecondNodeID2 << " )";
4447 ::SMESH_MeshEditor anEditor( myMesh );
4448 SMESH::SMESH_MeshEditor::Sew_Error error =
4449 convError( anEditor.SewFreeBorder (aBorderFirstNode,
4458 storeResult(anEditor);
4460 myMesh->GetMeshDS()->Modified();
4461 myMesh->SetIsModified( true );
4467 //=======================================================================
4468 //function : SewBorderToSide
4470 //=======================================================================
4472 SMESH::SMESH_MeshEditor::Sew_Error
4473 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
4474 CORBA::Long SecondNodeIDOnFreeBorder,
4475 CORBA::Long LastNodeIDOnFreeBorder,
4476 CORBA::Long FirstNodeIDOnSide,
4477 CORBA::Long LastNodeIDOnSide,
4478 CORBA::Boolean CreatePolygons,
4479 CORBA::Boolean CreatePolyedrs)
4483 SMESHDS_Mesh* aMesh = GetMeshDS();
4485 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
4486 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
4487 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
4488 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
4489 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
4490 const SMDS_MeshNode* aSide2ThirdNode = 0;
4492 if (!aBorderFirstNode ||
4493 !aBorderSecondNode||
4495 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4496 if (!aSide2FirstNode ||
4498 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
4500 TPythonDump() << "error = " << this << ".SewBorderToSide( "
4501 << FirstNodeIDOnFreeBorder << ", "
4502 << SecondNodeIDOnFreeBorder << ", "
4503 << LastNodeIDOnFreeBorder << ", "
4504 << FirstNodeIDOnSide << ", "
4505 << LastNodeIDOnSide << ", "
4506 << CreatePolygons << ", "
4507 << CreatePolyedrs << ") ";
4509 ::SMESH_MeshEditor anEditor( myMesh );
4510 SMESH::SMESH_MeshEditor::Sew_Error error =
4511 convError( anEditor.SewFreeBorder (aBorderFirstNode,
4521 storeResult(anEditor);
4523 myMesh->GetMeshDS()->Modified();
4524 myMesh->SetIsModified( true );
4530 //=======================================================================
4531 //function : SewSideElements
4533 //=======================================================================
4535 SMESH::SMESH_MeshEditor::Sew_Error
4536 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
4537 const SMESH::long_array& IDsOfSide2Elements,
4538 CORBA::Long NodeID1OfSide1ToMerge,
4539 CORBA::Long NodeID1OfSide2ToMerge,
4540 CORBA::Long NodeID2OfSide1ToMerge,
4541 CORBA::Long NodeID2OfSide2ToMerge)
4545 SMESHDS_Mesh* aMesh = GetMeshDS();
4547 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
4548 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
4549 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
4550 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
4552 if (!aFirstNode1ToMerge ||
4553 !aFirstNode2ToMerge )
4554 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
4555 if (!aSecondNode1ToMerge||
4556 !aSecondNode2ToMerge)
4557 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
4559 TIDSortedElemSet aSide1Elems, aSide2Elems;
4560 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
4561 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
4563 TPythonDump() << "error = " << this << ".SewSideElements( "
4564 << IDsOfSide1Elements << ", "
4565 << IDsOfSide2Elements << ", "
4566 << NodeID1OfSide1ToMerge << ", "
4567 << NodeID1OfSide2ToMerge << ", "
4568 << NodeID2OfSide1ToMerge << ", "
4569 << NodeID2OfSide2ToMerge << ")";
4571 ::SMESH_MeshEditor anEditor( myMesh );
4572 SMESH::SMESH_MeshEditor::Sew_Error error =
4573 convError( anEditor.SewSideElements (aSide1Elems, aSide2Elems,
4576 aSecondNode1ToMerge,
4577 aSecondNode2ToMerge));
4579 storeResult(anEditor);
4581 myMesh->GetMeshDS()->Modified();
4582 myMesh->SetIsModified( true );
4587 //================================================================================
4589 * \brief Set new nodes for given element
4590 * \param ide - element id
4591 * \param newIDs - new node ids
4592 * \retval CORBA::Boolean - true if result is OK
4594 //================================================================================
4596 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
4597 const SMESH::long_array& newIDs)
4601 const SMDS_MeshElement* elem = GetMeshDS()->FindElement(ide);
4602 if(!elem) return false;
4604 int nbn = newIDs.length();
4606 vector<const SMDS_MeshNode*> aNodes(nbn);
4609 const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(newIDs[i]);
4612 aNodes[nbn1] = aNode;
4615 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
4616 << ide << ", " << newIDs << " )";
4618 MESSAGE("ChangeElementNodes");
4619 bool res = GetMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
4621 myMesh->GetMeshDS()->Modified();
4623 myMesh->SetIsModified( true );
4628 //================================================================================
4630 * \brief Update myLastCreated* or myPreviewData
4631 * \param anEditor - it contains last modification results
4633 //================================================================================
4635 void SMESH_MeshEditor_i::storeResult(::SMESH_MeshEditor& anEditor)
4637 if ( myPreviewMode ) { // --- MeshPreviewStruct filling ---
4639 list<int> aNodesConnectivity;
4640 typedef map<int, int> TNodesMap;
4643 TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( anEditor.GetMesh() );
4644 SMDSAbs_ElementType previewType = aPreviewMesh->myPreviewType;
4646 SMESHDS_Mesh* aMeshDS = anEditor.GetMeshDS();
4647 int nbEdges = aMeshDS->NbEdges();
4648 int nbFaces = aMeshDS->NbFaces();
4649 int nbVolum = aMeshDS->NbVolumes();
4650 switch ( previewType ) {
4651 case SMDSAbs_Edge : nbFaces = nbVolum = 0; break;
4652 case SMDSAbs_Face : nbEdges = nbVolum = 0; break;
4653 case SMDSAbs_Volume: nbEdges = nbFaces = 0; break;
4656 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
4657 myPreviewData->elementTypes.length(nbEdges + nbFaces + nbVolum);
4659 SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator();
4661 while ( itMeshElems->more() ) {
4662 const SMDS_MeshElement* aMeshElem = itMeshElems->next();
4663 if ( previewType != SMDSAbs_All && aMeshElem->GetType() != previewType )
4666 SMDS_ElemIteratorPtr itElemNodes = aMeshElem->nodesIterator();
4667 while ( itElemNodes->more() ) {
4668 const SMDS_MeshNode* aMeshNode =
4669 static_cast<const SMDS_MeshNode*>( itElemNodes->next() );
4670 int aNodeID = aMeshNode->GetID();
4671 TNodesMap::iterator anIter = nodesMap.find(aNodeID);
4672 if ( anIter == nodesMap.end() ) {
4673 // filling the nodes coordinates
4674 myPreviewData->nodesXYZ[j].x = aMeshNode->X();
4675 myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
4676 myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
4677 anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
4680 aNodesConnectivity.push_back(anIter->second);
4683 // filling the elements types
4684 SMDSAbs_ElementType aType;
4686 /*if (aMeshElem->GetType() == SMDSAbs_Volume) {
4687 aType = SMDSAbs_Node;
4691 aType = aMeshElem->GetType();
4692 isPoly = aMeshElem->IsPoly();
4695 myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
4696 myPreviewData->elementTypes[i].isPoly = isPoly;
4697 myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
4701 myPreviewData->nodesXYZ.length( j );
4703 // filling the elements connectivities
4704 list<int>::iterator aConnIter = aNodesConnectivity.begin();
4705 myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
4706 for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
4707 myPreviewData->elementConnectivities[i] = *aConnIter;
4713 // append new nodes into myLastCreatedNodes
4714 const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedNodes();
4715 int j = myLastCreatedNodes->length();
4716 int newLen = j + aSeq.Length();
4717 myLastCreatedNodes->length( newLen );
4718 for(int i=0; j<newLen; i++,j++)
4719 myLastCreatedNodes[j] = aSeq.Value(i+1)->GetID();
4722 // append new elements into myLastCreatedElems
4723 const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedElems();
4724 int j = myLastCreatedElems->length();
4725 int newLen = j + aSeq.Length();
4726 myLastCreatedElems->length( newLen );
4727 for(int i=0; j<newLen; i++,j++)
4728 myLastCreatedElems[j] = aSeq.Value(i+1)->GetID();
4732 //================================================================================
4734 * Return data of mesh edition preview
4736 //================================================================================
4738 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
4740 return myPreviewData._retn();
4743 //================================================================================
4745 * \brief Returns list of it's IDs of created nodes
4746 * \retval SMESH::long_array* - list of node ID
4748 //================================================================================
4750 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
4752 return myLastCreatedNodes._retn();
4755 //================================================================================
4757 * \brief Returns list of it's IDs of created elements
4758 * \retval SMESH::long_array* - list of elements' ID
4760 //================================================================================
4762 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
4764 return myLastCreatedElems._retn();
4767 //=======================================================================
4768 //function : ConvertToQuadratic
4770 //=======================================================================
4772 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
4774 ::SMESH_MeshEditor anEditor( myMesh );
4775 anEditor.ConvertToQuadratic(theForce3d);
4776 TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )";
4777 myMesh->GetMeshDS()->Modified();
4778 myMesh->SetIsModified( true );
4781 //=======================================================================
4782 //function : ConvertFromQuadratic
4784 //=======================================================================
4786 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
4788 ::SMESH_MeshEditor anEditor( myMesh );
4789 CORBA::Boolean isDone = anEditor.ConvertFromQuadratic();
4790 TPythonDump() << this << ".ConvertFromQuadratic()";
4791 myMesh->GetMeshDS()->Modified();
4793 myMesh->SetIsModified( true );
4796 //================================================================================
4798 * \brief Makes a part of the mesh quadratic
4800 //================================================================================
4802 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
4803 SMESH::SMESH_IDSource_ptr theObject)
4804 throw (SALOME::SALOME_Exception)
4806 Unexpect aCatch(SALOME_SalomeException);
4808 TIDSortedElemSet elems;
4809 if ( idSourceToSet( theObject, GetMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
4811 if ( elems.empty() )
4813 ConvertToQuadratic( theForce3d );
4815 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
4817 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
4821 ::SMESH_MeshEditor anEditor( myMesh );
4822 anEditor.ConvertToQuadratic(theForce3d, elems);
4825 myMesh->GetMeshDS()->Modified();
4826 myMesh->SetIsModified( true );
4828 pyDump << this << ".ConvertToQuadraticObject( "<<theForce3d<<", "<<theObject<<" )";
4831 //================================================================================
4833 * \brief Makes a part of the mesh linear
4835 //================================================================================
4837 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
4838 throw (SALOME::SALOME_Exception)
4840 Unexpect aCatch(SALOME_SalomeException);
4842 TIDSortedElemSet elems;
4843 if ( idSourceToSet( theObject, GetMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
4845 if ( elems.empty() )
4847 ConvertFromQuadratic();
4849 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
4851 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
4855 ::SMESH_MeshEditor anEditor( myMesh );
4856 anEditor.ConvertFromQuadratic(elems);
4859 myMesh->GetMeshDS()->Modified();
4860 myMesh->SetIsModified( true );
4862 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
4865 //=======================================================================
4866 //function : makeMesh
4867 //purpose : create a named imported mesh
4868 //=======================================================================
4870 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
4872 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
4873 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
4874 SALOMEDS::Study_var study = gen->GetCurrentStudy();
4875 SALOMEDS::SObject_var meshSO = gen->ObjectToSObject( study, mesh );
4876 gen->SetName( meshSO, theMeshName, "Mesh" );
4877 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
4879 return mesh._retn();
4882 //=======================================================================
4883 //function : DumpGroupsList
4885 //=======================================================================
4886 void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump & theDumpPython,
4887 const SMESH::ListOfGroups * theGroupList)
4889 bool isDumpGroupList = theGroupList && theGroupList->length() > 0;
4890 if(isDumpGroupList) {
4891 theDumpPython << theGroupList << " = ";
4895 //================================================================================
4897 \brief Generates the unique group name.
4898 \param thePrefix name prefix
4901 //================================================================================
4902 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
4904 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
4905 set<string> groupNames;
4907 // Get existing group names
4908 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
4909 SMESH::SMESH_GroupBase_var aGroup = groups[i];
4910 if (CORBA::is_nil(aGroup))
4913 groupNames.insert(aGroup->GetName());
4917 string name = thePrefix;
4920 while (!groupNames.insert(name).second) {
4925 TCollection_AsciiString nbStr(index+1);
4926 name.resize( name.rfind('_')+1 );
4927 name += nbStr.ToCString();
4935 //================================================================================
4937 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
4938 \param theNodes - identifiers of nodes to be doubled
4939 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
4940 nodes. If list of element identifiers is empty then nodes are doubled but
4941 they not assigned to elements
4942 \return TRUE if operation has been completed successfully, FALSE otherwise
4943 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
4945 //================================================================================
4947 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
4948 const SMESH::long_array& theModifiedElems )
4952 ::SMESH_MeshEditor aMeshEditor( myMesh );
4953 list< int > aListOfNodes;
4955 for ( i = 0, n = theNodes.length(); i < n; i++ )
4956 aListOfNodes.push_back( theNodes[ i ] );
4958 list< int > aListOfElems;
4959 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
4960 aListOfElems.push_back( theModifiedElems[ i ] );
4962 bool aResult = aMeshEditor.DoubleNodes( aListOfNodes, aListOfElems );
4964 myMesh->GetMeshDS()->Modified();
4965 storeResult( aMeshEditor) ;
4967 myMesh->SetIsModified( true );
4969 // Update Python script
4970 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
4975 //================================================================================
4977 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
4978 This method provided for convenience works as DoubleNodes() described above.
4979 \param theNodeId - identifier of node to be doubled.
4980 \param theModifiedElems - identifiers of elements to be updated.
4981 \return TRUE if operation has been completed successfully, FALSE otherwise
4982 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
4984 //================================================================================
4986 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
4987 const SMESH::long_array& theModifiedElems )
4989 SMESH::long_array_var aNodes = new SMESH::long_array;
4990 aNodes->length( 1 );
4991 aNodes[ 0 ] = theNodeId;
4993 TPythonDump pyDump; // suppress dump by the next line
4995 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
4997 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
5002 //================================================================================
5004 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5005 This method provided for convenience works as DoubleNodes() described above.
5006 \param theNodes - group of nodes to be doubled.
5007 \param theModifiedElems - group of elements to be updated.
5008 \return TRUE if operation has been completed successfully, FALSE otherwise
5009 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
5011 //================================================================================
5013 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
5014 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5016 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5019 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5020 SMESH::long_array_var aModifiedElems;
5021 if ( !CORBA::is_nil( theModifiedElems ) )
5022 aModifiedElems = theModifiedElems->GetListOfID();
5025 aModifiedElems = new SMESH::long_array;
5026 aModifiedElems->length( 0 );
5029 TPythonDump pyDump; // suppress dump by the next line
5031 bool done = DoubleNodes( aNodes, aModifiedElems );
5033 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
5039 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5040 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
5041 * \param theNodes - group of nodes to be doubled.
5042 * \param theModifiedElems - group of elements to be updated.
5043 * \return a new group with newly created nodes
5044 * \sa DoubleNodeGroup()
5046 SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
5047 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5049 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5052 SMESH::SMESH_Group_var aNewGroup;
5055 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5056 SMESH::long_array_var aModifiedElems;
5057 if ( !CORBA::is_nil( theModifiedElems ) )
5058 aModifiedElems = theModifiedElems->GetListOfID();
5060 aModifiedElems = new SMESH::long_array;
5061 aModifiedElems->length( 0 );
5064 TPythonDump pyDump; // suppress dump by the next line
5066 bool aResult = DoubleNodes( aNodes, aModifiedElems );
5070 // Create group with newly created nodes
5071 SMESH::long_array_var anIds = GetLastCreatedNodes();
5072 if (anIds->length() > 0) {
5073 string anUnindexedName (theNodes->GetName());
5074 string aNewName = generateGroupName(anUnindexedName + "_double");
5075 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5076 aNewGroup->Add(anIds);
5080 pyDump << "createdNodes = " << this << ".DoubleNodeGroupNew( " << theNodes << ", "
5081 << theModifiedElems << " )";
5083 return aNewGroup._retn();
5086 //================================================================================
5088 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5089 This method provided for convenience works as DoubleNodes() described above.
5090 \param theNodes - list of groups of nodes to be doubled
5091 \param theModifiedElems - list of groups of elements to be updated.
5092 \return TRUE if operation has been completed successfully, FALSE otherwise
5093 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
5095 //================================================================================
5097 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
5098 const SMESH::ListOfGroups& theModifiedElems )
5102 ::SMESH_MeshEditor aMeshEditor( myMesh );
5104 std::list< int > aNodes;
5106 for ( i = 0, n = theNodes.length(); i < n; i++ )
5108 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
5109 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
5111 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5112 for ( j = 0, m = aCurr->length(); j < m; j++ )
5113 aNodes.push_back( aCurr[ j ] );
5117 std::list< int > anElems;
5118 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5120 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
5121 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
5123 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5124 for ( j = 0, m = aCurr->length(); j < m; j++ )
5125 anElems.push_back( aCurr[ j ] );
5129 bool aResult = aMeshEditor.DoubleNodes( aNodes, anElems );
5131 storeResult( aMeshEditor) ;
5133 myMesh->GetMeshDS()->Modified();
5135 myMesh->SetIsModified( true );
5138 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
5143 //================================================================================
5145 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5146 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
5147 * \param theNodes - group of nodes to be doubled.
5148 * \param theModifiedElems - group of elements to be updated.
5149 * \return a new group with newly created nodes
5150 * \sa DoubleNodeGroups()
5152 //================================================================================
5154 SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
5155 const SMESH::ListOfGroups& theModifiedElems )
5157 SMESH::SMESH_Group_var aNewGroup;
5159 TPythonDump pyDump; // suppress dump by the next line
5161 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
5165 // Create group with newly created nodes
5166 SMESH::long_array_var anIds = GetLastCreatedNodes();
5167 if (anIds->length() > 0) {
5168 string anUnindexedName (theNodes[0]->GetName());
5169 string aNewName = generateGroupName(anUnindexedName + "_double");
5170 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5171 aNewGroup->Add(anIds);
5175 pyDump << "createdNodes = " << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
5176 << theModifiedElems << " )";
5178 return aNewGroup._retn();
5182 //================================================================================
5184 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5185 \param theElems - the list of elements (edges or faces) to be replicated
5186 The nodes for duplication could be found from these elements
5187 \param theNodesNot - list of nodes to NOT replicate
5188 \param theAffectedElems - the list of elements (cells and edges) to which the
5189 replicated nodes should be associated to.
5190 \return TRUE if operation has been completed successfully, FALSE otherwise
5191 \sa DoubleNodeGroup(), DoubleNodeGroups()
5193 //================================================================================
5195 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
5196 const SMESH::long_array& theNodesNot,
5197 const SMESH::long_array& theAffectedElems )
5202 ::SMESH_MeshEditor aMeshEditor( myMesh );
5204 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5205 TIDSortedElemSet anElems, aNodes, anAffected;
5206 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5207 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5208 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
5210 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5212 storeResult( aMeshEditor) ;
5214 myMesh->GetMeshDS()->Modified();
5216 myMesh->SetIsModified( true );
5218 // Update Python script
5219 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
5220 << theNodesNot << ", " << theAffectedElems << " )";
5224 //================================================================================
5226 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5227 \param theElems - the list of elements (edges or faces) to be replicated
5228 The nodes for duplication could be found from these elements
5229 \param theNodesNot - list of nodes to NOT replicate
5230 \param theShape - shape to detect affected elements (element which geometric center
5231 located on or inside shape).
5232 The replicated nodes should be associated to affected elements.
5233 \return TRUE if operation has been completed successfully, FALSE otherwise
5234 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
5236 //================================================================================
5238 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
5239 const SMESH::long_array& theNodesNot,
5240 GEOM::GEOM_Object_ptr theShape )
5245 ::SMESH_MeshEditor aMeshEditor( myMesh );
5247 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5248 TIDSortedElemSet anElems, aNodes;
5249 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5250 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5252 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5253 bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5255 storeResult( aMeshEditor) ;
5257 myMesh->GetMeshDS()->Modified();
5259 myMesh->SetIsModified( true );
5261 // Update Python script
5262 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
5263 << theNodesNot << ", " << theShape << " )";
5267 //================================================================================
5269 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5270 \param theElems - group of of elements (edges or faces) to be replicated
5271 \param theNodesNot - group of nodes not to replicated
5272 \param theAffectedElems - group of elements to which the replicated nodes
5273 should be associated to.
5274 \return TRUE if operation has been completed successfully, FALSE otherwise
5275 \sa DoubleNodes(), DoubleNodeGroups()
5277 //================================================================================
5279 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
5280 SMESH::SMESH_GroupBase_ptr theNodesNot,
5281 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5283 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5288 ::SMESH_MeshEditor aMeshEditor( myMesh );
5290 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5291 TIDSortedElemSet anElems, aNodes, anAffected;
5292 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5293 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5294 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5296 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5298 storeResult( aMeshEditor) ;
5300 myMesh->GetMeshDS()->Modified();
5302 myMesh->SetIsModified( true );
5304 // Update Python script
5305 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
5306 << theNodesNot << ", " << theAffectedElems << " )";
5311 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5312 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
5313 * \param theElems - group of of elements (edges or faces) to be replicated
5314 * \param theNodesNot - group of nodes not to replicated
5315 * \param theAffectedElems - group of elements to which the replicated nodes
5316 * should be associated to.
5317 * \return a new group with newly created elements
5318 * \sa DoubleNodeElemGroup()
5320 SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
5321 SMESH::SMESH_GroupBase_ptr theNodesNot,
5322 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5324 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5327 SMESH::SMESH_Group_var aNewGroup;
5331 ::SMESH_MeshEditor aMeshEditor( myMesh );
5333 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5334 TIDSortedElemSet anElems, aNodes, anAffected;
5335 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5336 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5337 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5340 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5342 storeResult( aMeshEditor) ;
5345 myMesh->SetIsModified( true );
5347 // Create group with newly created elements
5348 SMESH::long_array_var anIds = GetLastCreatedElems();
5349 if (anIds->length() > 0) {
5350 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5351 string anUnindexedName (theElems->GetName());
5352 string aNewName = generateGroupName(anUnindexedName + "_double");
5353 aNewGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5354 aNewGroup->Add(anIds);
5358 // Update Python script
5359 TPythonDump() << "createdElems = " << this << ".DoubleNodeElemGroupNew( " << theElems << ", "
5360 << theNodesNot << ", " << theAffectedElems << " )";
5361 return aNewGroup._retn();
5364 //================================================================================
5366 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5367 \param theElems - group of of elements (edges or faces) to be replicated
5368 \param theNodesNot - group of nodes not to replicated
5369 \param theShape - shape to detect affected elements (element which geometric center
5370 located on or inside shape).
5371 The replicated nodes should be associated to affected elements.
5372 \return TRUE if operation has been completed successfully, FALSE otherwise
5373 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
5375 //================================================================================
5377 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
5378 SMESH::SMESH_GroupBase_ptr theNodesNot,
5379 GEOM::GEOM_Object_ptr theShape )
5382 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5387 ::SMESH_MeshEditor aMeshEditor( myMesh );
5389 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5390 TIDSortedElemSet anElems, aNodes, anAffected;
5391 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5392 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5394 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5395 bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5397 storeResult( aMeshEditor) ;
5399 myMesh->GetMeshDS()->Modified();
5401 myMesh->SetIsModified( true );
5403 // Update Python script
5404 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
5405 << theNodesNot << ", " << theShape << " )";
5409 //================================================================================
5411 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5412 This method provided for convenience works as DoubleNodes() described above.
5413 \param theElems - list of groups of elements (edges or faces) to be replicated
5414 \param theNodesNot - list of groups of nodes not to replicated
5415 \param theAffectedElems - group of elements to which the replicated nodes
5416 should be associated to.
5417 \return TRUE if operation has been completed successfully, FALSE otherwise
5418 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
5420 //================================================================================
5422 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
5423 SMESHDS_Mesh* theMeshDS,
5424 TIDSortedElemSet& theElemSet,
5425 const bool theIsNodeGrp)
5427 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
5429 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
5430 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
5431 : aGrp->GetType() != SMESH::NODE ) )
5433 SMESH::long_array_var anIDs = aGrp->GetIDs();
5434 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
5439 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
5440 const SMESH::ListOfGroups& theNodesNot,
5441 const SMESH::ListOfGroups& theAffectedElems)
5445 ::SMESH_MeshEditor aMeshEditor( myMesh );
5447 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5448 TIDSortedElemSet anElems, aNodes, anAffected;
5449 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5450 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5451 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5453 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5455 storeResult( aMeshEditor) ;
5457 myMesh->GetMeshDS()->Modified();
5459 myMesh->SetIsModified( true );
5461 // Update Python script
5462 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
5463 << &theNodesNot << ", " << &theAffectedElems << " )";
5467 //================================================================================
5469 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5470 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
5471 \param theElems - list of groups of elements (edges or faces) to be replicated
5472 \param theNodesNot - list of groups of nodes not to replicated
5473 \param theAffectedElems - group of elements to which the replicated nodes
5474 should be associated to.
5475 * \return a new group with newly created elements
5476 * \sa DoubleNodeElemGroups()
5478 //================================================================================
5480 SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
5481 const SMESH::ListOfGroups& theNodesNot,
5482 const SMESH::ListOfGroups& theAffectedElems)
5484 SMESH::SMESH_Group_var aNewGroup;
5488 ::SMESH_MeshEditor aMeshEditor( myMesh );
5490 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5491 TIDSortedElemSet anElems, aNodes, anAffected;
5492 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5493 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5494 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5496 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5498 storeResult( aMeshEditor) ;
5500 myMesh->GetMeshDS()->Modified();
5502 myMesh->SetIsModified( true );
5504 // Create group with newly created elements
5505 SMESH::long_array_var anIds = GetLastCreatedElems();
5506 if (anIds->length() > 0) {
5507 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5508 string anUnindexedName (theElems[0]->GetName());
5509 string aNewName = generateGroupName(anUnindexedName + "_double");
5510 aNewGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5511 aNewGroup->Add(anIds);
5515 // Update Python script
5516 TPythonDump() << "createdElems = " << this << ".DoubleNodeElemGroupsNew( " << &theElems << ", "
5517 << &theNodesNot << ", " << &theAffectedElems << " )";
5518 return aNewGroup._retn();
5521 //================================================================================
5523 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5524 This method provided for convenience works as DoubleNodes() described above.
5525 \param theElems - list of groups of elements (edges or faces) to be replicated
5526 \param theNodesNot - list of groups of nodes not to replicated
5527 \param theShape - shape to detect affected elements (element which geometric center
5528 located on or inside shape).
5529 The replicated nodes should be associated to affected elements.
5530 \return TRUE if operation has been completed successfully, FALSE otherwise
5531 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
5533 //================================================================================
5536 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
5537 const SMESH::ListOfGroups& theNodesNot,
5538 GEOM::GEOM_Object_ptr theShape )
5542 ::SMESH_MeshEditor aMeshEditor( myMesh );
5544 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5545 TIDSortedElemSet anElems, aNodes;
5546 listOfGroupToSet(theElems, aMeshDS, anElems,false );
5547 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5549 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5550 bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5552 storeResult( aMeshEditor) ;
5554 myMesh->GetMeshDS()->Modified();
5556 myMesh->SetIsModified( true );
5558 // Update Python script
5559 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
5560 << &theNodesNot << ", " << theShape << " )";
5564 //================================================================================
5566 \brief Generated skin mesh (containing 2D cells) from 3D mesh
5567 The created 2D mesh elements based on nodes of free faces of boundary volumes
5568 \return TRUE if operation has been completed successfully, FALSE otherwise
5570 //================================================================================
5572 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
5576 ::SMESH_MeshEditor aMeshEditor( myMesh );
5577 bool aResult = aMeshEditor.Make2DMeshFrom3D();
5578 storeResult( aMeshEditor) ;
5579 myMesh->GetMeshDS()->Modified();
5580 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
5584 //================================================================================
5586 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
5587 * The list of groups must describe a partition of the mesh volumes.
5588 * The nodes of the internal faces at the boundaries of the groups are doubled.
5589 * In option, the internal faces are replaced by flat elements.
5590 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
5591 * The flat elements are stored in groups of volumes.
5592 * @param theDomains - list of groups of volumes
5593 * @param createJointElems - if TRUE, create the elements
5594 * @return TRUE if operation has been completed successfully, FALSE otherwise
5596 //================================================================================
5598 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
5599 CORBA::Boolean createJointElems )
5603 ::SMESH_MeshEditor aMeshEditor( myMesh );
5605 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5607 vector<TIDSortedElemSet> domains;
5610 for ( int i = 0, n = theDomains.length(); i < n; i++ )
5612 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
5613 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
5615 TIDSortedElemSet domain;
5617 domains.push_back(domain);
5618 SMESH::long_array_var anIDs = aGrp->GetIDs();
5619 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
5623 bool aResult = aMeshEditor.DoubleNodesOnGroupBoundaries( domains, createJointElems );
5624 // TODO publish the groups of flat elements in study
5626 storeResult( aMeshEditor) ;
5627 myMesh->GetMeshDS()->Modified();
5629 // Update Python script
5630 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
5631 << ", " << createJointElems << " )";
5635 //================================================================================
5637 * \brief Double nodes on some external faces and create flat elements.
5638 * Flat elements are mainly used by some types of mechanic calculations.
5640 * Each group of the list must be constituted of faces.
5641 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
5642 * @param theGroupsOfFaces - list of groups of faces
5643 * @return TRUE if operation has been completed successfully, FALSE otherwise
5645 //================================================================================
5647 CORBA::Boolean SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
5651 ::SMESH_MeshEditor aMeshEditor( myMesh );
5653 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5655 vector<TIDSortedElemSet> faceGroups;
5658 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
5660 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
5661 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
5663 TIDSortedElemSet faceGroup;
5665 faceGroups.push_back(faceGroup);
5666 SMESH::long_array_var anIDs = aGrp->GetIDs();
5667 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
5671 bool aResult = aMeshEditor.CreateFlatElementsOnFacesGroups( faceGroups );
5672 // TODO publish the groups of flat elements in study
5674 storeResult( aMeshEditor) ;
5675 myMesh->GetMeshDS()->Modified();
5677 // Update Python script
5678 TPythonDump() << "isDone = " << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
5682 // issue 20749 ===================================================================
5684 * \brief Creates missing boundary elements
5685 * \param elements - elements whose boundary is to be checked
5686 * \param dimension - defines type of boundary elements to create
5687 * \param groupName - a name of group to store created boundary elements in,
5688 * "" means not to create the group
5689 * \param meshName - a name of new mesh to store created boundary elements in,
5690 * "" means not to create the new mesh
5691 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
5692 * \param toCopyExistingBondary - if true, not only new but also pre-existing
5693 * boundary elements will be copied into the new mesh
5694 * \param group - returns the create group, if any
5695 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
5697 // ================================================================================
5699 SMESH::SMESH_Mesh_ptr
5700 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
5701 SMESH::Bnd_Dimension dim,
5702 const char* groupName,
5703 const char* meshName,
5704 CORBA::Boolean toCopyElements,
5705 CORBA::Boolean toCopyExistingBondary,
5706 SMESH::SMESH_Group_out group)
5710 if ( dim > SMESH::BND_1DFROM2D )
5711 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
5713 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5715 SMESH::SMESH_Mesh_var mesh_var;
5716 SMESH::SMESH_Group_var group_var;
5720 TIDSortedElemSet elements;
5721 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
5722 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
5726 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
5727 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
5729 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
5731 // group of new boundary elements
5732 SMESH_Group* smesh_group = 0;
5733 if ( strlen(groupName) )
5735 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
5736 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
5737 smesh_group = group_i->GetSmeshGroup();
5741 ::SMESH_MeshEditor aMeshEditor( myMesh );
5742 aMeshEditor.MakeBoundaryMesh( elements,
5743 ::SMESH_MeshEditor::Bnd_Dimension(dim),
5747 toCopyExistingBondary);
5748 storeResult( aMeshEditor );
5751 smesh_mesh->GetMeshDS()->Modified();
5754 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
5756 // result of MakeBoundaryMesh() is a tuple (mesh, group)
5757 if ( mesh_var->_is_nil() )
5758 pyDump << myMesh_i->_this() << ", ";
5760 pyDump << mesh_var << ", ";
5761 if ( group_var->_is_nil() )
5762 pyDump << "_NoneGroup = "; // assignment to None is forbiden
5764 pyDump << group_var << " = ";
5765 pyDump << this << ".MakeBoundaryMesh( "
5767 << "SMESH." << dimName[int(dim)] << ", "
5768 << "'" << groupName << "', "
5769 << "'" << meshName<< "', "
5770 << toCopyElements << ", "
5771 << toCopyExistingBondary << ")";
5773 group = group_var._retn();
5774 return mesh_var._retn();
5777 //================================================================================
5779 * \brief Creates missing boundary elements
5780 * \param dimension - defines type of boundary elements to create
5781 * \param groupName - a name of group to store all boundary elements in,
5782 * "" means not to create the group
5783 * \param meshName - a name of a new mesh, which is a copy of the initial
5784 * mesh + created boundary elements; "" means not to create the new mesh
5785 * \param toCopyAll - if true, the whole initial mesh will be copied into
5786 * the new mesh else only boundary elements will be copied into the new mesh
5787 * \param groups - optional groups of elements to make boundary around
5788 * \param mesh - returns the mesh where elements were added to
5789 * \param group - returns the created group, if any
5790 * \retval long - number of added boundary elements
5792 //================================================================================
5794 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
5795 const char* groupName,
5796 const char* meshName,
5797 CORBA::Boolean toCopyAll,
5798 const SMESH::ListOfIDSources& groups,
5799 SMESH::SMESH_Mesh_out mesh,
5800 SMESH::SMESH_Group_out group)
5801 throw (SALOME::SALOME_Exception)
5803 Unexpect aCatch(SALOME_SalomeException);
5807 if ( dim > SMESH::BND_1DFROM2D )
5808 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
5810 // check that groups belongs to to this mesh and is not this mesh
5811 const int nbGroups = groups.length();
5812 for ( int i = 0; i < nbGroups; ++i )
5814 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
5815 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
5816 THROW_SALOME_CORBA_EXCEPTION("group does not belong to this mesh", SALOME::BAD_PARAM);
5817 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
5818 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
5824 SMESH::SMESH_Mesh_var mesh_var;
5825 SMESH::SMESH_Group_var group_var;
5828 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
5829 const bool toCopyMesh = ( strlen( meshName ) > 0 );
5833 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
5835 /*toCopyGroups=*/false,
5836 /*toKeepIDs=*/true);
5838 mesh_var = makeMesh(meshName);
5840 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
5841 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
5844 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
5845 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
5847 // group of boundary elements
5848 SMESH_Group* smesh_group = 0;
5849 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
5850 if ( strlen(groupName) )
5852 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
5853 group_var = mesh_i->CreateGroup( groupType, groupName );
5854 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
5855 smesh_group = group_i->GetSmeshGroup();
5858 TIDSortedElemSet elements;
5862 for ( int i = 0; i < nbGroups; ++i )
5865 if ( idSourceToSet( groups[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/false ))
5867 SMESH::Bnd_Dimension bdim =
5868 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
5869 ::SMESH_MeshEditor aMeshEditor( srcMesh );
5870 nbAdded += aMeshEditor.MakeBoundaryMesh( elements,
5871 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
5874 /*toCopyElements=*/false,
5875 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
5876 /*toAddExistingBondary=*/true,
5877 /*aroundElements=*/true);
5878 storeResult( aMeshEditor );
5884 ::SMESH_MeshEditor aMeshEditor( srcMesh );
5885 nbAdded += aMeshEditor.MakeBoundaryMesh( elements,
5886 ::SMESH_MeshEditor::Bnd_Dimension(dim),
5889 /*toCopyElements=*/false,
5890 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
5891 /*toAddExistingBondary=*/true);
5892 storeResult( aMeshEditor );
5894 tgtMesh->GetMeshDS()->Modified();
5896 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
5898 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
5899 pyDump << "nbAdded, ";
5900 if ( mesh_var->_is_nil() )
5901 pyDump << myMesh_i->_this() << ", ";
5903 pyDump << mesh_var << ", ";
5904 if ( group_var->_is_nil() )
5905 pyDump << "_NoneGroup = "; // assignment to None is forbiden
5907 pyDump << group_var << " = ";
5908 pyDump << this << ".MakeBoundaryElements( "
5909 << "SMESH." << dimName[int(dim)] << ", "
5910 << "'" << groupName << "', "
5911 << "'" << meshName<< "', "
5912 << toCopyAll << ", "
5915 mesh = mesh_var._retn();
5916 group = group_var._retn();