1 // Copyright (C) 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_MeshEditor_i.cxx
23 // Author : Nicolas REJNERI
30 #include "SMESH_MeshEditor_i.hxx"
32 #include "SMDS_Mesh0DElement.hxx"
33 #include "SMDS_LinearEdge.hxx"
34 #include "SMDS_MeshFace.hxx"
35 #include "SMDS_MeshVolume.hxx"
36 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
37 #include "SMESH_subMeshEventListener.hxx"
38 #include "SMESH_Gen_i.hxx"
39 #include "SMESH_Filter_i.hxx"
40 #include "SMESH_subMesh_i.hxx"
41 #include "SMESH_Group_i.hxx"
42 #include "SMESH_PythonDump.hxx"
43 #include "SMESH_ControlsDef.hxx"
45 #include "utilities.h"
46 #include "Utils_ExceptHandlers.hxx"
47 #include "Utils_CorbaException.hxx"
49 #include <BRepAdaptor_Surface.hxx>
50 #include <BRep_Tool.hxx>
51 #include <TopExp_Explorer.hxx>
53 #include <TopoDS_Edge.hxx>
54 #include <TopoDS_Face.hxx>
59 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
63 #include <Standard_Failure.hxx>
66 #include <Standard_ErrorHandler.hxx>
72 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
75 using SMESH::TPythonDump;
79 //=============================================================================
81 * \brief Mesh to apply modifications for preview purposes
83 //=============================================================================
85 struct TPreviewMesh: public SMESH_Mesh
87 SMDSAbs_ElementType myPreviewType; // type to show
89 TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
90 _isShapeToMesh = (_id =_studyId =_idDoc = 0);
91 _myMeshDS = new SMESHDS_Mesh( _id, true );
92 myPreviewType = previewElements;
95 virtual ~TPreviewMesh() { delete _myMeshDS; }
96 //!< Copy a set of elements
97 void Copy(const TIDSortedElemSet & theElements,
98 TIDSortedElemSet& theCopyElements,
99 SMDSAbs_ElementType theSelectType = SMDSAbs_All,
100 SMDSAbs_ElementType theAvoidType = SMDSAbs_All)
102 // loop on theIDsOfElements
103 TIDSortedElemSet::const_iterator eIt = theElements.begin();
104 for ( ; eIt != theElements.end(); ++eIt )
106 const SMDS_MeshElement* anElem = *eIt;
107 if ( !anElem ) continue;
108 SMDSAbs_ElementType type = anElem->GetType();
109 if ( type == theAvoidType ||
110 ( theSelectType != SMDSAbs_All && type != theSelectType ))
113 if ( const SMDS_MeshElement* anElemCopy = Copy( anElem ))
114 theCopyElements.insert( theCopyElements.end(), anElemCopy );
118 SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
120 // copy element nodes
121 int anElemNbNodes = anElem->NbNodes();
122 vector< int > anElemNodesID( anElemNbNodes ) ;
123 SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
124 for ( int i = 0; itElemNodes->more(); i++)
126 const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
128 anElemNodesID[i] = anElemNode->GetID();
131 // creates a corresponding element on copied nodes
132 SMDS_MeshElement* anElemCopy = 0;
133 if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
135 const SMDS_VtkVolume* ph =
136 dynamic_cast<const SMDS_VtkVolume*> (anElem);
138 anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
139 (anElemNodesID, ph->GetQuantities(),anElem->GetID());
142 anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
149 SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
151 return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(),
152 anElemNode->GetID());
154 };// struct TPreviewMesh
156 static SMESH_NodeSearcher * theNodeSearcher = 0;
157 static SMESH_ElementSearcher * theElementSearcher = 0;
159 //=============================================================================
161 * \brief Deleter of theNodeSearcher at any compute event occured
163 //=============================================================================
165 struct TSearchersDeleter : public SMESH_subMeshEventListener
169 TSearchersDeleter(): SMESH_subMeshEventListener( false ), // won't be deleted by submesh
171 //!< Delete theNodeSearcher
174 if ( theNodeSearcher ) delete theNodeSearcher; theNodeSearcher = 0;
175 if ( theElementSearcher ) delete theElementSearcher; theElementSearcher = 0;
177 typedef map < int, SMESH_subMesh * > TDependsOnMap;
178 //!< The meshod called by submesh: do my main job
179 void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
180 SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
182 if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
184 Unset( sm->GetFather() );
187 //!< set self on all submeshes and delete theNodeSearcher if other mesh is set
188 void Set(SMESH_Mesh* mesh)
190 if ( myMesh != mesh )
197 if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
198 const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
199 TDependsOnMap::const_iterator sm;
200 for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
201 sm->second->SetEventListener( this, 0, sm->second );
205 //!< delete self from all submeshes
206 void Unset(SMESH_Mesh* mesh)
208 if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
209 const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
210 TDependsOnMap::const_iterator sm;
211 for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
212 sm->second->DeleteEventListener( this );
217 } theSearchersDeleter;
219 TCollection_AsciiString mirrorTypeName( SMESH::SMESH_MeshEditor::MirrorType theMirrorType )
221 TCollection_AsciiString typeStr;
222 switch ( theMirrorType ) {
223 case SMESH::SMESH_MeshEditor::POINT:
224 typeStr = "SMESH.SMESH_MeshEditor.POINT";
226 case SMESH::SMESH_MeshEditor::AXIS:
227 typeStr = "SMESH.SMESH_MeshEditor.AXIS";
230 typeStr = "SMESH.SMESH_MeshEditor.PLANE";
234 //================================================================================
236 * \brief function for conversion of long_array to TIDSortedElemSet
237 * \param IDs - array of IDs
238 * \param aMesh - mesh
239 * \param aMap - collection to fill
240 * \param aType - element type
242 //================================================================================
244 void arrayToSet(const SMESH::long_array & IDs,
245 const SMESHDS_Mesh* aMesh,
246 TIDSortedElemSet& aMap,
247 const SMDSAbs_ElementType aType = SMDSAbs_All )
249 for (int i=0; i<IDs.length(); i++) {
250 CORBA::Long ind = IDs[i];
251 const SMDS_MeshElement * elem =
252 (aType == SMDSAbs_Node ? aMesh->FindNode(ind) : aMesh->FindElement(ind));
253 if ( elem && ( aType == SMDSAbs_All || elem->GetType() == aType ))
257 //================================================================================
259 * \brief Retrieve elements of given type from SMESH_IDSource
261 //================================================================================
263 bool idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource,
264 const SMESHDS_Mesh* theMeshDS,
265 TIDSortedElemSet& theElemSet,
266 const SMDSAbs_ElementType theType,
267 const bool emptyIfIsMesh=false)
270 if ( CORBA::is_nil( theIDSource ) )
272 if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
275 SMESH::long_array_var anIDs = theIDSource->GetIDs();
276 if ( anIDs->length() == 0 )
278 SMESH::array_of_ElementType_var types = theIDSource->GetTypes();
279 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
281 if ( theType == SMDSAbs_All || theType == SMDSAbs_Node )
282 arrayToSet( anIDs, theMeshDS, theElemSet, SMDSAbs_Node );
288 arrayToSet( anIDs, theMeshDS, theElemSet, theType);
292 //================================================================================
294 * \brief Retrieve nodes from SMESH_IDSource
296 //================================================================================
298 void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject,
299 const SMESHDS_Mesh* theMeshDS,
300 TIDSortedNodeSet& theNodeSet)
303 if ( CORBA::is_nil( theObject ) )
305 SMESH::array_of_ElementType_var types = theObject->GetTypes();
306 SMESH::long_array_var aElementsId = theObject->GetIDs();
307 if ( types->length() == 1 && types[0] == SMESH::NODE)
309 for(int i = 0; i < aElementsId->length(); i++)
310 if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] ))
311 theNodeSet.insert( theNodeSet.end(), n);
313 else if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
315 SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator();
316 while ( nIt->more( ))
317 if( const SMDS_MeshElement * elem = nIt->next() )
318 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
322 for(int i = 0; i < aElementsId->length(); i++)
323 if( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] ))
324 theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
328 //================================================================================
330 * \brief Returns elements connected to the given elements
332 //================================================================================
334 void getElementsAround(const TIDSortedElemSet& theElements,
335 const SMESHDS_Mesh* theMeshDS,
336 TIDSortedElemSet& theElementsAround)
338 if ( theElements.empty() ) return;
340 SMDSAbs_ElementType elemType = (*theElements.begin())->GetType();
341 bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() );
343 theMeshDS->GetMeshInfo().NbElements( elemType ) == theElements.size() )
344 return; // all the elements are in theElements
347 elemType = SMDSAbs_All;
349 TIDSortedElemSet visitedNodes;
350 TIDSortedElemSet::const_iterator elemIt = theElements.begin();
351 for ( ; elemIt != theElements.end(); ++elemIt )
353 const SMDS_MeshElement* e = *elemIt;
354 int i = e->NbCornerNodes();
357 const SMDS_MeshNode* n = e->GetNode( i );
358 if ( visitedNodes.insert( n ).second )
360 SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
361 while ( invIt->more() )
363 const SMDS_MeshElement* elemAround = invIt->next();
364 if ( !theElements.count( elemAround ))
365 theElementsAround.insert( elemAround );
373 //=============================================================================
377 //=============================================================================
379 SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview)
382 myMesh = & theMesh->GetImpl();
383 myPreviewMode = isPreview;
386 //================================================================================
390 //================================================================================
392 SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
396 //================================================================================
398 * \brief Clear members
400 //================================================================================
402 void SMESH_MeshEditor_i::initData(bool deleteSearchers)
404 if ( myPreviewMode ) {
405 myPreviewData = new SMESH::MeshPreviewStruct();
408 myLastCreatedElems = new SMESH::long_array();
409 myLastCreatedNodes = new SMESH::long_array();
410 if ( deleteSearchers )
411 TSearchersDeleter::Delete();
415 //=======================================================================
416 //function : MakeIDSource
417 //purpose : Wrap a sequence of ids in a SMESH_IDSource
418 //=======================================================================
420 struct _IDSource : public POA_SMESH::SMESH_IDSource
422 SMESH::long_array _ids;
423 SMESH::ElementType _type;
424 SMESH::SMESH_Mesh_ptr _mesh;
425 SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); }
426 SMESH::long_array* GetMeshInfo() { return 0; }
427 SMESH::SMESH_Mesh_ptr GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _mesh ); }
428 SMESH::array_of_ElementType* GetTypes()
430 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
433 return types._retn();
437 SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
438 SMESH::ElementType type)
440 _IDSource* anIDSource = new _IDSource;
441 anIDSource->_ids = ids;
442 anIDSource->_type = type;
443 anIDSource->_mesh = myMesh_i->_this();
444 SMESH::SMESH_IDSource_var anIDSourceVar = anIDSource->_this();
446 return anIDSourceVar._retn();
449 //=============================================================================
453 //=============================================================================
456 SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
460 ::SMESH_MeshEditor anEditor( myMesh );
463 for (int i = 0; i < IDsOfElements.length(); i++)
464 IdList.push_back( IDsOfElements[i] );
466 // Update Python script
467 TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
470 bool ret = anEditor.Remove( IdList, false );
471 myMesh->GetMeshDS()->Modified();
472 if ( IDsOfElements.length() )
473 myMesh->SetIsModified( true ); // issue 0020693
477 //=============================================================================
481 //=============================================================================
483 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
487 ::SMESH_MeshEditor anEditor( myMesh );
489 for (int i = 0; i < IDsOfNodes.length(); i++)
490 IdList.push_back( IDsOfNodes[i] );
492 // Update Python script
493 TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
495 bool ret = anEditor.Remove( IdList, true );
496 myMesh->GetMeshDS()->Modified();
497 if ( IDsOfNodes.length() )
498 myMesh->SetIsModified( true ); // issue 0020693
502 //=============================================================================
506 //=============================================================================
508 CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
512 ::SMESH_MeshEditor anEditor( myMesh );
514 // Update Python script
515 TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
517 // Create filter to find all orphan nodes
518 SMESH::Controls::Filter::TIdSequence seq;
519 SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
520 SMESH::Controls::Filter::GetElementsId( GetMeshDS(), predicate, seq );
522 // remove orphan nodes (if there are any)
524 for ( int i = 0; i < seq.size(); i++ )
525 IdList.push_back( seq[i] );
527 bool ret = anEditor.Remove( IdList, true );
528 myMesh->GetMeshDS()->Modified();
530 myMesh->SetIsModified( true );
535 //=============================================================================
539 //=============================================================================
541 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,
542 CORBA::Double y, CORBA::Double z)
546 const SMDS_MeshNode* N = GetMeshDS()->AddNode(x, y, z);
548 // Update Python script
549 TPythonDump() << "nodeID = " << this << ".AddNode( "
550 << x << ", " << y << ", " << z << " )";
552 myMesh->GetMeshDS()->Modified();
553 myMesh->SetIsModified( true ); // issue 0020693
557 //=============================================================================
561 //=============================================================================
562 CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
566 const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(IDOfNode);
567 SMDS_MeshElement* elem = GetMeshDS()->Add0DElement(aNode);
569 // Update Python script
570 TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
572 myMesh->GetMeshDS()->Modified();
573 myMesh->SetIsModified( true ); // issue 0020693
576 return elem->GetID();
581 //=============================================================================
585 //=============================================================================
587 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
591 int NbNodes = IDsOfNodes.length();
592 SMDS_MeshElement* elem = 0;
595 CORBA::Long index1 = IDsOfNodes[0];
596 CORBA::Long index2 = IDsOfNodes[1];
597 elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(index1), GetMeshDS()->FindNode(index2));
599 // Update Python script
600 TPythonDump() << "edge = " << this << ".AddEdge([ "
601 << index1 << ", " << index2 <<" ])";
604 CORBA::Long n1 = IDsOfNodes[0];
605 CORBA::Long n2 = IDsOfNodes[1];
606 CORBA::Long n12 = IDsOfNodes[2];
607 elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(n1),
608 GetMeshDS()->FindNode(n2),
609 GetMeshDS()->FindNode(n12));
610 // Update Python script
611 TPythonDump() << "edgeID = " << this << ".AddEdge([ "
612 <<n1<<", "<<n2<<", "<<n12<<" ])";
615 myMesh->GetMeshDS()->Modified();
617 return myMesh->SetIsModified( true ), elem->GetID();
622 //=============================================================================
626 //=============================================================================
628 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
632 int NbNodes = IDsOfNodes.length();
638 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
639 for (int i = 0; i < NbNodes; i++)
640 nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
642 SMDS_MeshElement* elem = 0;
644 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]);
646 else if (NbNodes == 4) {
647 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]);
649 else if (NbNodes == 6) {
650 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
653 else if (NbNodes == 8) {
654 elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
655 nodes[4], nodes[5], nodes[6], nodes[7]);
657 else if (NbNodes > 2) {
658 elem = GetMeshDS()->AddPolygonalFace(nodes);
661 // Update Python script
662 TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
664 myMesh->GetMeshDS()->Modified();
666 return myMesh->SetIsModified( true ), elem->GetID();
671 //=============================================================================
675 //=============================================================================
676 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
680 int NbNodes = IDsOfNodes.length();
681 std::vector<const SMDS_MeshNode*> nodes (NbNodes);
682 for (int i = 0; i < NbNodes; i++)
683 nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
685 const SMDS_MeshElement* elem = GetMeshDS()->AddPolygonalFace(nodes);
687 // Update Python script
688 TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
690 myMesh->GetMeshDS()->Modified();
691 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
694 //=============================================================================
698 //=============================================================================
700 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
704 int NbNodes = IDsOfNodes.length();
705 vector< const SMDS_MeshNode*> n(NbNodes);
706 for(int i=0;i<NbNodes;i++)
707 n[i]=GetMeshDS()->FindNode(IDsOfNodes[i]);
709 SMDS_MeshElement* elem = 0;
712 case 4 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3]); break;
713 case 5 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4]); break;
714 case 6 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5]); break;
715 case 8 :elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); break;
716 case 10:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
717 n[6],n[7],n[8],n[9]);
719 case 13:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
720 n[7],n[8],n[9],n[10],n[11],n[12]);
722 case 15:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],
723 n[9],n[10],n[11],n[12],n[13],n[14]);
725 case 20:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
726 n[8],n[9],n[10],n[11],n[12],n[13],n[14],
727 n[15],n[16],n[17],n[18],n[19]);
731 // Update Python script
732 TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
734 myMesh->GetMeshDS()->Modified();
736 return myMesh->SetIsModified( true ), elem->GetID();
741 //=============================================================================
743 * AddPolyhedralVolume
745 //=============================================================================
746 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
747 const SMESH::long_array & Quantities)
751 int NbNodes = IDsOfNodes.length();
752 std::vector<const SMDS_MeshNode*> n (NbNodes);
753 for (int i = 0; i < NbNodes; i++)
755 const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(IDsOfNodes[i]);
756 if (!aNode) return 0;
760 int NbFaces = Quantities.length();
761 std::vector<int> q (NbFaces);
762 for (int j = 0; j < NbFaces; j++)
763 q[j] = Quantities[j];
765 const SMDS_MeshElement* elem = GetMeshDS()->AddPolyhedralVolume(n, q);
767 // Update Python script
768 TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
769 << IDsOfNodes << ", " << Quantities << " )";
770 myMesh->GetMeshDS()->Modified();
772 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
775 //=============================================================================
777 * AddPolyhedralVolumeByFaces
779 //=============================================================================
780 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
784 int NbFaces = IdsOfFaces.length();
785 std::vector<const SMDS_MeshNode*> poly_nodes;
786 std::vector<int> quantities (NbFaces);
788 for (int i = 0; i < NbFaces; i++) {
789 const SMDS_MeshElement* aFace = GetMeshDS()->FindElement(IdsOfFaces[i]);
790 quantities[i] = aFace->NbNodes();
792 SMDS_ElemIteratorPtr It = aFace->nodesIterator();
794 poly_nodes.push_back(static_cast<const SMDS_MeshNode *>(It->next()));
798 const SMDS_MeshElement* elem = GetMeshDS()->AddPolyhedralVolume(poly_nodes, quantities);
800 // Update Python script
801 TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
802 << IdsOfFaces << " )";
803 myMesh->GetMeshDS()->Modified();
805 return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
808 //=============================================================================
810 * \brief Bind a node to a vertex
811 * \param NodeID - node ID
812 * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
813 * \retval boolean - false if NodeID or VertexID is invalid
815 //=============================================================================
817 void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexID)
818 throw (SALOME::SALOME_Exception)
820 Unexpect aCatch(SALOME_SalomeException);
822 SMESHDS_Mesh * mesh = GetMeshDS();
823 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
825 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
827 if ( mesh->MaxShapeIndex() < VertexID )
828 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
830 TopoDS_Shape shape = mesh->IndexToShape( VertexID );
831 if ( shape.ShapeType() != TopAbs_VERTEX )
832 THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
834 mesh->SetNodeOnVertex( node, VertexID );
836 myMesh->SetIsModified( true );
839 //=============================================================================
841 * \brief Store node position on an edge
842 * \param NodeID - node ID
843 * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
844 * \param paramOnEdge - parameter on edge where the node is located
845 * \retval boolean - false if any parameter is invalid
847 //=============================================================================
849 void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
850 CORBA::Double paramOnEdge)
851 throw (SALOME::SALOME_Exception)
853 Unexpect aCatch(SALOME_SalomeException);
855 SMESHDS_Mesh * mesh = GetMeshDS();
856 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
858 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
860 if ( mesh->MaxShapeIndex() < EdgeID )
861 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
863 TopoDS_Shape shape = mesh->IndexToShape( EdgeID );
864 if ( shape.ShapeType() != TopAbs_EDGE )
865 THROW_SALOME_CORBA_EXCEPTION("Invalid EdgeID", SALOME::BAD_PARAM);
868 BRep_Tool::Range( TopoDS::Edge( shape ), f,l);
869 if ( paramOnEdge < f || paramOnEdge > l )
870 THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
872 mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
874 myMesh->SetIsModified( true );
877 //=============================================================================
879 * \brief Store node position on a face
880 * \param NodeID - node ID
881 * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
882 * \param u - U parameter on face where the node is located
883 * \param v - V parameter on face where the node is located
884 * \retval boolean - false if any parameter is invalid
886 //=============================================================================
888 void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
889 CORBA::Double u, CORBA::Double v)
890 throw (SALOME::SALOME_Exception)
892 Unexpect aCatch(SALOME_SalomeException);
894 SMESHDS_Mesh * mesh = GetMeshDS();
895 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
897 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
899 if ( mesh->MaxShapeIndex() < FaceID )
900 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
902 TopoDS_Shape shape = mesh->IndexToShape( FaceID );
903 if ( shape.ShapeType() != TopAbs_FACE )
904 THROW_SALOME_CORBA_EXCEPTION("Invalid FaceID", SALOME::BAD_PARAM);
906 BRepAdaptor_Surface surf( TopoDS::Face( shape ));
907 bool isOut = ( u < surf.FirstUParameter() ||
908 u > surf.LastUParameter() ||
909 v < surf.FirstVParameter() ||
910 v > surf.LastVParameter() );
914 MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
915 << " u( " << surf.FirstUParameter()
916 << "," << surf.LastUParameter()
917 << ") v( " << surf.FirstVParameter()
918 << "," << surf.LastVParameter() << ")" );
920 THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
923 mesh->SetNodeOnFace( node, FaceID, u, v );
924 myMesh->SetIsModified( true );
927 //=============================================================================
929 * \brief Bind a node to a solid
930 * \param NodeID - node ID
931 * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
932 * \retval boolean - false if NodeID or SolidID is invalid
934 //=============================================================================
936 void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID)
937 throw (SALOME::SALOME_Exception)
939 Unexpect aCatch(SALOME_SalomeException);
941 SMESHDS_Mesh * mesh = GetMeshDS();
942 SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( mesh->FindNode(NodeID) );
944 THROW_SALOME_CORBA_EXCEPTION("Invalid NodeID", SALOME::BAD_PARAM);
946 if ( mesh->MaxShapeIndex() < SolidID )
947 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
949 TopoDS_Shape shape = mesh->IndexToShape( SolidID );
950 if ( shape.ShapeType() != TopAbs_SOLID &&
951 shape.ShapeType() != TopAbs_SHELL)
952 THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
954 mesh->SetNodeInVolume( node, SolidID );
956 // myMesh->SetIsModified( true ); - SetNodeInVolume() can't prevent re-compute, I believe
959 //=============================================================================
961 * \brief Bind an element to a shape
962 * \param ElementID - element ID
963 * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
964 * \retval boolean - false if ElementID or ShapeID is invalid
966 //=============================================================================
968 void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
970 throw (SALOME::SALOME_Exception)
972 Unexpect aCatch(SALOME_SalomeException);
974 SMESHDS_Mesh * mesh = GetMeshDS();
975 SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(mesh->FindElement(ElementID));
977 THROW_SALOME_CORBA_EXCEPTION("Invalid ElementID", SALOME::BAD_PARAM);
979 if ( mesh->MaxShapeIndex() < ShapeID )
980 THROW_SALOME_CORBA_EXCEPTION("Invalid ShapeID", SALOME::BAD_PARAM);
982 TopoDS_Shape shape = mesh->IndexToShape( ShapeID );
983 if ( shape.ShapeType() != TopAbs_EDGE &&
984 shape.ShapeType() != TopAbs_FACE &&
985 shape.ShapeType() != TopAbs_SOLID &&
986 shape.ShapeType() != TopAbs_SHELL )
987 THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
989 mesh->SetMeshElementOnShape( elem, ShapeID );
991 myMesh->SetIsModified( true );
994 //=============================================================================
998 //=============================================================================
1000 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
1001 CORBA::Long NodeID2)
1005 const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
1006 const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
1010 // Update Python script
1011 TPythonDump() << "isDone = " << this << ".InverseDiag( "
1012 << NodeID1 << ", " << NodeID2 << " )";
1015 ::SMESH_MeshEditor aMeshEditor( myMesh );
1016 int ret = aMeshEditor.InverseDiag ( n1, n2 );
1017 myMesh->GetMeshDS()->Modified();
1018 myMesh->SetIsModified( true );
1022 //=============================================================================
1026 //=============================================================================
1028 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
1029 CORBA::Long NodeID2)
1033 const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
1034 const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
1038 // Update Python script
1039 TPythonDump() << "isDone = " << this << ".DeleteDiag( "
1040 << NodeID1 << ", " << NodeID2 << " )";
1042 ::SMESH_MeshEditor aMeshEditor( myMesh );
1044 bool stat = aMeshEditor.DeleteDiag ( n1, n2 );
1046 myMesh->GetMeshDS()->Modified();
1048 myMesh->SetIsModified( true ); // issue 0020693
1050 storeResult(aMeshEditor);
1055 //=============================================================================
1059 //=============================================================================
1061 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
1065 ::SMESH_MeshEditor anEditor( myMesh );
1066 for (int i = 0; i < IDsOfElements.length(); i++)
1068 CORBA::Long index = IDsOfElements[i];
1069 const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
1071 anEditor.Reorient( elem );
1073 // Update Python script
1074 TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
1076 myMesh->GetMeshDS()->Modified();
1077 if ( IDsOfElements.length() )
1078 myMesh->SetIsModified( true ); // issue 0020693
1084 //=============================================================================
1088 //=============================================================================
1090 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
1094 TPythonDump aTPythonDump; // suppress dump in Reorient()
1096 SMESH::long_array_var anElementsId = theObject->GetIDs();
1097 CORBA::Boolean isDone = Reorient(anElementsId);
1099 // Update Python script
1100 aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
1105 //=============================================================================
1109 //=============================================================================
1110 CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array & IDsOfElements,
1111 SMESH::NumericalFunctor_ptr Criterion,
1112 CORBA::Double MaxAngle)
1116 SMESHDS_Mesh* aMesh = GetMeshDS();
1117 TIDSortedElemSet faces;
1118 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1120 SMESH::NumericalFunctor_i* aNumericalFunctor =
1121 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1122 SMESH::Controls::NumericalFunctorPtr aCrit;
1123 if ( !aNumericalFunctor )
1124 aCrit.reset( new SMESH::Controls::AspectRatio() );
1126 aCrit = aNumericalFunctor->GetNumericalFunctor();
1128 // Update Python script
1129 TPythonDump() << "isDone = " << this << ".TriToQuad( "
1130 << IDsOfElements << ", " << aNumericalFunctor << ", " << MaxAngle << " )";
1132 ::SMESH_MeshEditor anEditor( myMesh );
1134 bool stat = anEditor.TriToQuad( faces, aCrit, MaxAngle );
1135 myMesh->GetMeshDS()->Modified();
1137 myMesh->SetIsModified( true ); // issue 0020693
1139 storeResult(anEditor);
1145 //=============================================================================
1149 //=============================================================================
1150 CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1151 SMESH::NumericalFunctor_ptr Criterion,
1152 CORBA::Double MaxAngle)
1156 TPythonDump aTPythonDump; // suppress dump in TriToQuad()
1157 SMESH::long_array_var anElementsId = theObject->GetIDs();
1158 CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
1160 SMESH::NumericalFunctor_i* aNumericalFunctor =
1161 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1163 // Update Python script
1164 aTPythonDump << "isDone = " << this << ".TriToQuadObject("
1165 << theObject << ", " << aNumericalFunctor << ", " << MaxAngle << " )";
1171 //=============================================================================
1175 //=============================================================================
1176 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array & IDsOfElements,
1177 SMESH::NumericalFunctor_ptr Criterion)
1181 SMESHDS_Mesh* aMesh = GetMeshDS();
1182 TIDSortedElemSet faces;
1183 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1185 SMESH::NumericalFunctor_i* aNumericalFunctor =
1186 dynamic_cast<SMESH::NumericalFunctor_i*>( SMESH_Gen_i::GetServant( Criterion ).in() );
1187 SMESH::Controls::NumericalFunctorPtr aCrit;
1188 if ( !aNumericalFunctor )
1189 aCrit.reset( new SMESH::Controls::AspectRatio() );
1191 aCrit = aNumericalFunctor->GetNumericalFunctor();
1194 // Update Python script
1195 TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
1197 ::SMESH_MeshEditor anEditor( myMesh );
1198 CORBA::Boolean stat = anEditor.QuadToTri( faces, aCrit );
1199 myMesh->GetMeshDS()->Modified();
1201 myMesh->SetIsModified( true ); // issue 0020693
1203 storeResult(anEditor);
1209 //=============================================================================
1213 //=============================================================================
1214 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr theObject,
1215 SMESH::NumericalFunctor_ptr Criterion)
1219 TPythonDump aTPythonDump; // suppress dump in QuadToTri()
1221 SMESH::long_array_var anElementsId = theObject->GetIDs();
1222 CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
1224 SMESH::NumericalFunctor_i* aNumericalFunctor =
1225 SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
1227 // Update Python script
1228 aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
1234 //=============================================================================
1238 //=============================================================================
1239 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
1240 CORBA::Boolean Diag13)
1244 SMESHDS_Mesh* aMesh = GetMeshDS();
1245 TIDSortedElemSet faces;
1246 arrayToSet(IDsOfElements, aMesh, faces, SMDSAbs_Face);
1248 // Update Python script
1249 TPythonDump() << "isDone = " << this << ".SplitQuad( "
1250 << IDsOfElements << ", " << Diag13 << " )";
1252 ::SMESH_MeshEditor anEditor( myMesh );
1253 CORBA::Boolean stat = anEditor.QuadToTri( faces, Diag13 );
1254 myMesh->GetMeshDS()->Modified();
1256 myMesh->SetIsModified( true ); // issue 0020693
1259 storeResult(anEditor);
1265 //=============================================================================
1269 //=============================================================================
1270 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
1271 CORBA::Boolean Diag13)
1275 TPythonDump aTPythonDump; // suppress dump in SplitQuad()
1277 SMESH::long_array_var anElementsId = theObject->GetIDs();
1278 CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
1280 // Update Python script
1281 aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
1282 << theObject << ", " << Diag13 << " )";
1288 //=============================================================================
1292 //=============================================================================
1293 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad,
1294 SMESH::NumericalFunctor_ptr Criterion)
1298 const SMDS_MeshElement* quad = GetMeshDS()->FindElement(IDOfQuad);
1299 if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
1301 SMESH::NumericalFunctor_i* aNumericalFunctor =
1302 dynamic_cast<SMESH::NumericalFunctor_i*>(SMESH_Gen_i::GetServant(Criterion).in());
1303 SMESH::Controls::NumericalFunctorPtr aCrit;
1304 if (aNumericalFunctor)
1305 aCrit = aNumericalFunctor->GetNumericalFunctor();
1307 aCrit.reset(new SMESH::Controls::AspectRatio());
1309 ::SMESH_MeshEditor anEditor (myMesh);
1310 return anEditor.BestSplit(quad, aCrit);
1315 //================================================================================
1317 * \brief Split volumic elements into tetrahedrons
1319 //================================================================================
1321 void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
1322 CORBA::Short methodFlags)
1323 throw (SALOME::SALOME_Exception)
1325 Unexpect aCatch(SALOME_SalomeException);
1329 SMESH::long_array_var anElementsId = elems->GetIDs();
1330 TIDSortedElemSet elemSet;
1331 arrayToSet( anElementsId, GetMeshDS(), elemSet, SMDSAbs_Volume );
1333 ::SMESH_MeshEditor anEditor (myMesh);
1334 anEditor.SplitVolumesIntoTetra( elemSet, int( methodFlags ));
1335 myMesh->GetMeshDS()->Modified();
1337 storeResult(anEditor);
1339 // if ( myLastCreatedElems.length() ) - it does not influence Compute()
1340 // myMesh->SetIsModified( true ); // issue 0020693
1342 TPythonDump() << this << ".SplitVolumesIntoTetra( "
1343 << elems << ", " << methodFlags << " )";
1346 //=======================================================================
1349 //=======================================================================
1352 SMESH_MeshEditor_i::Smooth(const SMESH::long_array & IDsOfElements,
1353 const SMESH::long_array & IDsOfFixedNodes,
1354 CORBA::Long MaxNbOfIterations,
1355 CORBA::Double MaxAspectRatio,
1356 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1358 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1359 MaxAspectRatio, Method, false );
1363 //=======================================================================
1364 //function : SmoothParametric
1366 //=======================================================================
1369 SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array & IDsOfElements,
1370 const SMESH::long_array & IDsOfFixedNodes,
1371 CORBA::Long MaxNbOfIterations,
1372 CORBA::Double MaxAspectRatio,
1373 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1375 return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
1376 MaxAspectRatio, Method, true );
1380 //=======================================================================
1381 //function : SmoothObject
1383 //=======================================================================
1386 SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr theObject,
1387 const SMESH::long_array & IDsOfFixedNodes,
1388 CORBA::Long MaxNbOfIterations,
1389 CORBA::Double MaxAspectRatio,
1390 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1392 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1393 MaxAspectRatio, Method, false);
1397 //=======================================================================
1398 //function : SmoothParametricObject
1400 //=======================================================================
1403 SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr theObject,
1404 const SMESH::long_array & IDsOfFixedNodes,
1405 CORBA::Long MaxNbOfIterations,
1406 CORBA::Double MaxAspectRatio,
1407 SMESH::SMESH_MeshEditor::Smooth_Method Method)
1409 return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
1410 MaxAspectRatio, Method, true);
1414 //=============================================================================
1418 //=============================================================================
1421 SMESH_MeshEditor_i::smooth(const SMESH::long_array & IDsOfElements,
1422 const SMESH::long_array & IDsOfFixedNodes,
1423 CORBA::Long MaxNbOfIterations,
1424 CORBA::Double MaxAspectRatio,
1425 SMESH::SMESH_MeshEditor::Smooth_Method Method,
1430 SMESHDS_Mesh* aMesh = GetMeshDS();
1432 TIDSortedElemSet elements;
1433 arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
1435 set<const SMDS_MeshNode*> fixedNodes;
1436 for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
1437 CORBA::Long index = IDsOfFixedNodes[i];
1438 const SMDS_MeshNode * node = aMesh->FindNode(index);
1440 fixedNodes.insert( node );
1442 ::SMESH_MeshEditor::SmoothMethod method = ::SMESH_MeshEditor::LAPLACIAN;
1443 if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
1444 method = ::SMESH_MeshEditor::CENTROIDAL;
1446 ::SMESH_MeshEditor anEditor( myMesh );
1447 anEditor.Smooth(elements, fixedNodes, method,
1448 MaxNbOfIterations, MaxAspectRatio, IsParametric );
1450 myMesh->GetMeshDS()->Modified();
1451 myMesh->SetIsModified( true ); // issue 0020693
1453 storeResult(anEditor);
1455 // Update Python script
1456 TPythonDump() << "isDone = " << this << "."
1457 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
1458 << IDsOfElements << ", " << IDsOfFixedNodes << ", "
1459 << MaxNbOfIterations << ", " << MaxAspectRatio << ", "
1460 << "SMESH.SMESH_MeshEditor."
1461 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1462 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1468 //=============================================================================
1472 //=============================================================================
1475 SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr theObject,
1476 const SMESH::long_array & IDsOfFixedNodes,
1477 CORBA::Long MaxNbOfIterations,
1478 CORBA::Double MaxAspectRatio,
1479 SMESH::SMESH_MeshEditor::Smooth_Method Method,
1484 TPythonDump aTPythonDump; // suppress dump in smooth()
1486 SMESH::long_array_var anElementsId = theObject->GetIDs();
1487 CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
1488 MaxAspectRatio, Method, IsParametric);
1490 // Update Python script
1491 aTPythonDump << "isDone = " << this << "."
1492 << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
1493 << theObject << ", " << IDsOfFixedNodes << ", "
1494 << MaxNbOfIterations << ", " << MaxAspectRatio << ", "
1495 << "SMESH.SMESH_MeshEditor."
1496 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
1497 "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
1503 //=============================================================================
1507 //=============================================================================
1509 void SMESH_MeshEditor_i::RenumberNodes()
1511 // Update Python script
1512 TPythonDump() << this << ".RenumberNodes()";
1514 GetMeshDS()->Renumber( true );
1518 //=============================================================================
1522 //=============================================================================
1524 void SMESH_MeshEditor_i::RenumberElements()
1526 // Update Python script
1527 TPythonDump() << this << ".RenumberElements()";
1529 GetMeshDS()->Renumber( false );
1532 //=======================================================================
1534 * \brief Return groups by their IDs
1536 //=======================================================================
1538 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
1542 myMesh_i->CreateGroupServants();
1543 return myMesh_i->GetGroups( *groupIDs );
1546 //=======================================================================
1547 //function : rotationSweep
1549 //=======================================================================
1551 SMESH::ListOfGroups*
1552 SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
1553 const SMESH::AxisStruct & theAxis,
1554 CORBA::Double theAngleInRadians,
1555 CORBA::Long theNbOfSteps,
1556 CORBA::Double theTolerance,
1557 const bool theMakeGroups,
1558 const SMDSAbs_ElementType theElementType)
1562 TIDSortedElemSet inElements, copyElements;
1563 arrayToSet(theIDsOfElements, GetMeshDS(), inElements, theElementType);
1565 TIDSortedElemSet* workElements = & inElements;
1566 TPreviewMesh tmpMesh( SMDSAbs_Face );
1567 SMESH_Mesh* mesh = 0;
1568 bool makeWalls=true;
1569 if ( myPreviewMode )
1571 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
1572 tmpMesh.Copy( inElements, copyElements, select, avoid );
1574 workElements = & copyElements;
1575 //makeWalls = false;
1582 gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
1583 gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
1585 ::SMESH_MeshEditor anEditor( mesh );
1586 ::SMESH_MeshEditor::PGroupIDs groupIds =
1587 anEditor.RotationSweep (*workElements, Ax1, theAngleInRadians,
1588 theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
1589 storeResult(anEditor);
1590 myMesh->GetMeshDS()->Modified();
1592 // myMesh->SetIsModified( true ); -- it does not influence Compute()
1594 return theMakeGroups ? getGroups(groupIds.get()) : 0;
1597 //=======================================================================
1598 //function : RotationSweep
1600 //=======================================================================
1602 void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElements,
1603 const SMESH::AxisStruct & theAxis,
1604 CORBA::Double theAngleInRadians,
1605 CORBA::Long theNbOfSteps,
1606 CORBA::Double theTolerance)
1608 if ( !myPreviewMode ) {
1609 TPythonDump() << this << ".RotationSweep( "
1610 << theIDsOfElements << ", "
1612 << theAngleInRadians << ", "
1613 << theNbOfSteps << ", "
1614 << theTolerance << " )";
1616 rotationSweep(theIDsOfElements,
1624 //=======================================================================
1625 //function : RotationSweepMakeGroups
1627 //=======================================================================
1629 SMESH::ListOfGroups*
1630 SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
1631 const SMESH::AxisStruct& theAxis,
1632 CORBA::Double theAngleInRadians,
1633 CORBA::Long theNbOfSteps,
1634 CORBA::Double theTolerance)
1636 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1638 SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
1644 if (!myPreviewMode) {
1645 DumpGroupsList(aPythonDump, aGroups);
1646 aPythonDump << this << ".RotationSweepMakeGroups( "
1647 << theIDsOfElements << ", "
1649 << theAngleInRadians << ", "
1650 << theNbOfSteps << ", "
1651 << theTolerance << " )";
1656 //=======================================================================
1657 //function : RotationSweepObject
1659 //=======================================================================
1661 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
1662 const SMESH::AxisStruct & theAxis,
1663 CORBA::Double theAngleInRadians,
1664 CORBA::Long theNbOfSteps,
1665 CORBA::Double theTolerance)
1667 if ( !myPreviewMode ) {
1668 TPythonDump() << this << ".RotationSweepObject( "
1669 << theObject << ", "
1671 << theAngleInRadians << ", "
1672 << theNbOfSteps << ", "
1673 << theTolerance << " )";
1675 SMESH::long_array_var anElementsId = theObject->GetIDs();
1676 rotationSweep(anElementsId,
1684 //=======================================================================
1685 //function : RotationSweepObject1D
1687 //=======================================================================
1689 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
1690 const SMESH::AxisStruct & theAxis,
1691 CORBA::Double theAngleInRadians,
1692 CORBA::Long theNbOfSteps,
1693 CORBA::Double theTolerance)
1695 if ( !myPreviewMode ) {
1696 TPythonDump() << this << ".RotationSweepObject1D( "
1697 << theObject << ", "
1699 << theAngleInRadians << ", "
1700 << theNbOfSteps << ", "
1701 << theTolerance << " )";
1703 SMESH::long_array_var anElementsId = theObject->GetIDs();
1704 rotationSweep(anElementsId,
1713 //=======================================================================
1714 //function : RotationSweepObject2D
1716 //=======================================================================
1718 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
1719 const SMESH::AxisStruct & theAxis,
1720 CORBA::Double theAngleInRadians,
1721 CORBA::Long theNbOfSteps,
1722 CORBA::Double theTolerance)
1724 if ( !myPreviewMode ) {
1725 TPythonDump() << this << ".RotationSweepObject2D( "
1726 << theObject << ", "
1728 << theAngleInRadians << ", "
1729 << theNbOfSteps << ", "
1730 << theTolerance << " )";
1732 SMESH::long_array_var anElementsId = theObject->GetIDs();
1733 rotationSweep(anElementsId,
1742 //=======================================================================
1743 //function : RotationSweepObjectMakeGroups
1745 //=======================================================================
1747 SMESH::ListOfGroups*
1748 SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1749 const SMESH::AxisStruct& theAxis,
1750 CORBA::Double theAngleInRadians,
1751 CORBA::Long theNbOfSteps,
1752 CORBA::Double theTolerance)
1754 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1756 SMESH::long_array_var anElementsId = theObject->GetIDs();
1757 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
1763 if (!myPreviewMode) {
1764 DumpGroupsList(aPythonDump, aGroups);
1765 aPythonDump << this << ".RotationSweepObjectMakeGroups( "
1766 << theObject << ", "
1768 << theAngleInRadians << ", "
1769 << theNbOfSteps << ", "
1770 << theTolerance << " )";
1775 //=======================================================================
1776 //function : RotationSweepObject1DMakeGroups
1778 //=======================================================================
1780 SMESH::ListOfGroups*
1781 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1782 const SMESH::AxisStruct& theAxis,
1783 CORBA::Double theAngleInRadians,
1784 CORBA::Long theNbOfSteps,
1785 CORBA::Double theTolerance)
1787 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1789 SMESH::long_array_var anElementsId = theObject->GetIDs();
1790 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
1797 if (!myPreviewMode) {
1798 DumpGroupsList(aPythonDump, aGroups);
1799 aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
1800 << theObject << ", "
1802 << theAngleInRadians << ", "
1803 << theNbOfSteps << ", "
1804 << theTolerance << " )";
1809 //=======================================================================
1810 //function : RotationSweepObject2DMakeGroups
1812 //=======================================================================
1814 SMESH::ListOfGroups*
1815 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1816 const SMESH::AxisStruct& theAxis,
1817 CORBA::Double theAngleInRadians,
1818 CORBA::Long theNbOfSteps,
1819 CORBA::Double theTolerance)
1821 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1823 SMESH::long_array_var anElementsId = theObject->GetIDs();
1824 SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
1831 if (!myPreviewMode) {
1832 DumpGroupsList(aPythonDump, aGroups);
1833 aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
1834 << theObject << ", "
1836 << theAngleInRadians << ", "
1837 << theNbOfSteps << ", "
1838 << theTolerance << " )";
1844 //=======================================================================
1845 //function : extrusionSweep
1847 //=======================================================================
1849 SMESH::ListOfGroups*
1850 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
1851 const SMESH::DirStruct & theStepVector,
1852 CORBA::Long theNbOfSteps,
1854 const SMDSAbs_ElementType theElementType)
1862 TIDSortedElemSet elements, copyElements;
1863 arrayToSet(theIDsOfElements, GetMeshDS(), elements, theElementType);
1865 const SMESH::PointStruct * P = &theStepVector.PS;
1866 gp_Vec stepVec( P->x, P->y, P->z );
1868 TIDSortedElemSet* workElements = & elements;
1869 TPreviewMesh tmpMesh( SMDSAbs_Face );
1870 SMESH_Mesh* mesh = myMesh;
1872 if ( myPreviewMode ) {
1873 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
1874 tmpMesh.Copy( elements, copyElements, select, avoid );
1876 workElements = & copyElements;
1877 theMakeGroups = false;
1880 TElemOfElemListMap aHystory;
1881 ::SMESH_MeshEditor anEditor( mesh );
1882 ::SMESH_MeshEditor::PGroupIDs groupIds =
1883 anEditor.ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
1885 myMesh->GetMeshDS()->Modified();
1886 storeResult(anEditor);
1888 return theMakeGroups ? getGroups(groupIds.get()) : 0;
1890 } catch(Standard_Failure) {
1891 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1892 INFOS( "SMESH_MeshEditor_i::ExtrusionSweep fails - "<< aFail->GetMessageString() );
1897 //=======================================================================
1898 //function : ExtrusionSweep
1900 //=======================================================================
1902 void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElements,
1903 const SMESH::DirStruct & theStepVector,
1904 CORBA::Long theNbOfSteps)
1906 extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
1907 if (!myPreviewMode) {
1908 TPythonDump() << this << ".ExtrusionSweep( "
1909 << theIDsOfElements << ", " << theStepVector <<", " << theNbOfSteps << " )";
1914 //=======================================================================
1915 //function : ExtrusionSweepObject
1917 //=======================================================================
1919 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
1920 const SMESH::DirStruct & theStepVector,
1921 CORBA::Long theNbOfSteps)
1923 SMESH::long_array_var anElementsId = theObject->GetIDs();
1924 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
1925 if (!myPreviewMode) {
1926 TPythonDump() << this << ".ExtrusionSweepObject( "
1927 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
1931 //=======================================================================
1932 //function : ExtrusionSweepObject1D
1934 //=======================================================================
1936 void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
1937 const SMESH::DirStruct & theStepVector,
1938 CORBA::Long theNbOfSteps)
1940 SMESH::long_array_var anElementsId = theObject->GetIDs();
1941 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
1942 if ( !myPreviewMode ) {
1943 TPythonDump() << this << ".ExtrusionSweepObject1D( "
1944 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
1948 //=======================================================================
1949 //function : ExtrusionSweepObject2D
1951 //=======================================================================
1953 void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
1954 const SMESH::DirStruct & theStepVector,
1955 CORBA::Long theNbOfSteps)
1957 SMESH::long_array_var anElementsId = theObject->GetIDs();
1958 extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
1959 if ( !myPreviewMode ) {
1960 TPythonDump() << this << ".ExtrusionSweepObject2D( "
1961 << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
1965 //=======================================================================
1966 //function : ExtrusionSweepMakeGroups
1968 //=======================================================================
1970 SMESH::ListOfGroups*
1971 SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfElements,
1972 const SMESH::DirStruct& theStepVector,
1973 CORBA::Long theNbOfSteps)
1975 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1977 SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
1979 if (!myPreviewMode) {
1980 DumpGroupsList(aPythonDump, aGroups);
1981 aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
1982 << ", " << theStepVector <<", " << theNbOfSteps << " )";
1987 //=======================================================================
1988 //function : ExtrusionSweepObjectMakeGroups
1990 //=======================================================================
1992 SMESH::ListOfGroups*
1993 SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
1994 const SMESH::DirStruct& theStepVector,
1995 CORBA::Long theNbOfSteps)
1997 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
1999 SMESH::long_array_var anElementsId = theObject->GetIDs();
2000 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
2002 if (!myPreviewMode) {
2003 DumpGroupsList(aPythonDump, aGroups);
2004 aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
2005 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2010 //=======================================================================
2011 //function : ExtrusionSweepObject1DMakeGroups
2013 //=======================================================================
2015 SMESH::ListOfGroups*
2016 SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2017 const SMESH::DirStruct& theStepVector,
2018 CORBA::Long theNbOfSteps)
2020 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2022 SMESH::long_array_var anElementsId = theObject->GetIDs();
2023 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2024 theNbOfSteps, true, SMDSAbs_Edge);
2025 if (!myPreviewMode) {
2026 DumpGroupsList(aPythonDump, aGroups);
2027 aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
2028 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2033 //=======================================================================
2034 //function : ExtrusionSweepObject2DMakeGroups
2036 //=======================================================================
2038 SMESH::ListOfGroups*
2039 SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2040 const SMESH::DirStruct& theStepVector,
2041 CORBA::Long theNbOfSteps)
2043 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2045 SMESH::long_array_var anElementsId = theObject->GetIDs();
2046 SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
2047 theNbOfSteps, true, SMDSAbs_Face);
2048 if (!myPreviewMode) {
2049 DumpGroupsList(aPythonDump, aGroups);
2050 aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
2051 << ", " << theStepVector << ", " << theNbOfSteps << " )";
2057 //=======================================================================
2058 //function : advancedExtrusion
2060 //=======================================================================
2062 SMESH::ListOfGroups*
2063 SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements,
2064 const SMESH::DirStruct & theStepVector,
2065 CORBA::Long theNbOfSteps,
2066 CORBA::Long theExtrFlags,
2067 CORBA::Double theSewTolerance,
2068 const bool theMakeGroups)
2072 TIDSortedElemSet elements;
2073 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
2075 const SMESH::PointStruct * P = &theStepVector.PS;
2076 gp_Vec stepVec( P->x, P->y, P->z );
2078 ::SMESH_MeshEditor anEditor( myMesh );
2079 TElemOfElemListMap aHystory;
2080 ::SMESH_MeshEditor::PGroupIDs groupIds =
2081 anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
2082 theMakeGroups, theExtrFlags, theSewTolerance);
2083 storeResult(anEditor);
2085 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2088 //=======================================================================
2089 //function : AdvancedExtrusion
2091 //=======================================================================
2093 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
2094 const SMESH::DirStruct & theStepVector,
2095 CORBA::Long theNbOfSteps,
2096 CORBA::Long theExtrFlags,
2097 CORBA::Double theSewTolerance)
2099 if ( !myPreviewMode ) {
2100 TPythonDump() << "stepVector = " << theStepVector;
2101 TPythonDump() << this << ".AdvancedExtrusion("
2104 << theNbOfSteps << ","
2105 << theExtrFlags << ", "
2106 << theSewTolerance << " )";
2108 advancedExtrusion( theIDsOfElements,
2116 //=======================================================================
2117 //function : AdvancedExtrusionMakeGroups
2119 //=======================================================================
2120 SMESH::ListOfGroups*
2121 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
2122 const SMESH::DirStruct& theStepVector,
2123 CORBA::Long theNbOfSteps,
2124 CORBA::Long theExtrFlags,
2125 CORBA::Double theSewTolerance)
2127 if (!myPreviewMode) {
2128 TPythonDump() << "stepVector = " << theStepVector;
2130 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2132 SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
2139 if (!myPreviewMode) {
2140 DumpGroupsList(aPythonDump, aGroups);
2141 aPythonDump << this << ".AdvancedExtrusionMakeGroups("
2144 << theNbOfSteps << ","
2145 << theExtrFlags << ", "
2146 << theSewTolerance << " )";
2152 //================================================================================
2154 * \brief Convert extrusion error to IDL enum
2156 //================================================================================
2158 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
2160 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
2164 RETCASE( EXTR_NO_ELEMENTS );
2165 RETCASE( EXTR_PATH_NOT_EDGE );
2166 RETCASE( EXTR_BAD_PATH_SHAPE );
2167 RETCASE( EXTR_BAD_STARTING_NODE );
2168 RETCASE( EXTR_BAD_ANGLES_NUMBER );
2169 RETCASE( EXTR_CANT_GET_TANGENT );
2171 return SMESH::SMESH_MeshEditor::EXTR_OK;
2175 //=======================================================================
2176 //function : extrusionAlongPath
2178 //=======================================================================
2179 SMESH::ListOfGroups*
2180 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2181 SMESH::SMESH_Mesh_ptr thePathMesh,
2182 GEOM::GEOM_Object_ptr thePathShape,
2183 CORBA::Long theNodeStart,
2184 CORBA::Boolean theHasAngles,
2185 const SMESH::double_array & theAngles,
2186 CORBA::Boolean theHasRefPoint,
2187 const SMESH::PointStruct & theRefPoint,
2188 const bool theMakeGroups,
2189 SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
2190 const SMDSAbs_ElementType theElementType)
2192 MESSAGE("extrusionAlongPath");
2195 if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
2196 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2199 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2201 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2202 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2204 if ( !aSubMesh || !aSubMesh->GetSubMeshDS()) {
2205 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2209 SMDS_MeshNode* nodeStart = (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(theNodeStart);
2211 theError = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2215 TIDSortedElemSet elements;
2216 arrayToSet(theIDsOfElements, GetMeshDS(), elements, theElementType);
2218 list<double> angles;
2219 for (int i = 0; i < theAngles.length(); i++) {
2220 angles.push_back( theAngles[i] );
2223 gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
2225 int nbOldGroups = myMesh->NbGroup();
2227 ::SMESH_MeshEditor anEditor( myMesh );
2228 ::SMESH_MeshEditor::Extrusion_Error error =
2229 anEditor.ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
2230 theHasAngles, angles, false,
2231 theHasRefPoint, refPnt, theMakeGroups );
2232 myMesh->GetMeshDS()->Modified();
2233 storeResult(anEditor);
2234 theError = convExtrError( error );
2236 if ( theMakeGroups ) {
2237 list<int> groupIDs = myMesh->GetGroupIds();
2238 list<int>::iterator newBegin = groupIDs.begin();
2239 std::advance( newBegin, nbOldGroups ); // skip old groups
2240 groupIDs.erase( groupIDs.begin(), newBegin );
2241 return getGroups( & groupIDs );
2247 //=======================================================================
2248 //function : extrusionAlongPathX
2250 //=======================================================================
2251 SMESH::ListOfGroups*
2252 SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array & IDsOfElements,
2253 SMESH::SMESH_IDSource_ptr Path,
2254 CORBA::Long NodeStart,
2255 CORBA::Boolean HasAngles,
2256 const SMESH::double_array& Angles,
2257 CORBA::Boolean LinearVariation,
2258 CORBA::Boolean HasRefPoint,
2259 const SMESH::PointStruct& RefPoint,
2261 const SMDSAbs_ElementType ElementType,
2262 SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
2264 SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
2268 list<double> angles;
2269 for (int i = 0; i < Angles.length(); i++) {
2270 angles.push_back( Angles[i] );
2272 gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
2273 int nbOldGroups = myMesh->NbGroup();
2275 if ( Path->_is_nil() ) {
2276 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2280 TIDSortedElemSet elements, copyElements;
2281 arrayToSet(IDsOfElements, GetMeshDS(), elements, ElementType);
2283 TIDSortedElemSet* workElements = &elements;
2284 TPreviewMesh tmpMesh( SMDSAbs_Face );
2285 SMESH_Mesh* mesh = myMesh;
2287 if ( myPreviewMode )
2289 SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
2290 tmpMesh.Copy( elements, copyElements, select, avoid );
2292 workElements = & copyElements;
2296 ::SMESH_MeshEditor anEditor( mesh );
2297 ::SMESH_MeshEditor::Extrusion_Error error;
2299 if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path ))
2302 SMDS_MeshNode* aNodeStart =
2303 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2304 if ( !aNodeStart ) {
2305 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2308 error = anEditor.ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
2309 HasAngles, angles, LinearVariation,
2310 HasRefPoint, refPnt, MakeGroups );
2311 myMesh->GetMeshDS()->Modified();
2313 else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
2316 SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
2317 aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
2318 SMDS_MeshNode* aNodeStart =
2319 (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
2320 if ( !aNodeStart ) {
2321 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
2324 SMESH_subMesh* aSubMesh =
2325 aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
2326 error = anEditor.ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
2327 HasAngles, angles, LinearVariation,
2328 HasRefPoint, refPnt, MakeGroups );
2329 myMesh->GetMeshDS()->Modified();
2331 else if ( SMESH::DownCast<SMESH_Group_i*>( Path ))
2333 // path as group of 1D elements
2339 Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
2343 storeResult(anEditor);
2344 Error = convExtrError( error );
2347 list<int> groupIDs = myMesh->GetGroupIds();
2348 list<int>::iterator newBegin = groupIDs.begin();
2349 std::advance( newBegin, nbOldGroups ); // skip old groups
2350 groupIDs.erase( groupIDs.begin(), newBegin );
2351 return getGroups( & groupIDs );
2357 //=======================================================================
2358 //function : ExtrusionAlongPath
2360 //=======================================================================
2361 SMESH::SMESH_MeshEditor::Extrusion_Error
2362 SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array & theIDsOfElements,
2363 SMESH::SMESH_Mesh_ptr thePathMesh,
2364 GEOM::GEOM_Object_ptr thePathShape,
2365 CORBA::Long theNodeStart,
2366 CORBA::Boolean theHasAngles,
2367 const SMESH::double_array & theAngles,
2368 CORBA::Boolean theHasRefPoint,
2369 const SMESH::PointStruct & theRefPoint)
2371 MESSAGE("ExtrusionAlongPath");
2372 if ( !myPreviewMode ) {
2373 TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
2374 << theIDsOfElements << ", "
2375 << thePathMesh << ", "
2376 << thePathShape << ", "
2377 << theNodeStart << ", "
2378 << theHasAngles << ", "
2379 << theAngles << ", "
2380 << theHasRefPoint << ", "
2381 << "SMESH.PointStruct( "
2382 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2383 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2384 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2386 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2387 extrusionAlongPath( theIDsOfElements,
2400 //=======================================================================
2401 //function : ExtrusionAlongPathObject
2403 //=======================================================================
2404 SMESH::SMESH_MeshEditor::Extrusion_Error
2405 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr theObject,
2406 SMESH::SMESH_Mesh_ptr thePathMesh,
2407 GEOM::GEOM_Object_ptr thePathShape,
2408 CORBA::Long theNodeStart,
2409 CORBA::Boolean theHasAngles,
2410 const SMESH::double_array & theAngles,
2411 CORBA::Boolean theHasRefPoint,
2412 const SMESH::PointStruct & theRefPoint)
2414 if ( !myPreviewMode ) {
2415 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
2416 << theObject << ", "
2417 << thePathMesh << ", "
2418 << thePathShape << ", "
2419 << theNodeStart << ", "
2420 << theHasAngles << ", "
2421 << theAngles << ", "
2422 << theHasRefPoint << ", "
2423 << "SMESH.PointStruct( "
2424 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2425 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2426 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2428 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2429 SMESH::long_array_var anElementsId = theObject->GetIDs();
2430 extrusionAlongPath( anElementsId,
2443 //=======================================================================
2444 //function : ExtrusionAlongPathObject1D
2446 //=======================================================================
2447 SMESH::SMESH_MeshEditor::Extrusion_Error
2448 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr theObject,
2449 SMESH::SMESH_Mesh_ptr thePathMesh,
2450 GEOM::GEOM_Object_ptr thePathShape,
2451 CORBA::Long theNodeStart,
2452 CORBA::Boolean theHasAngles,
2453 const SMESH::double_array & theAngles,
2454 CORBA::Boolean theHasRefPoint,
2455 const SMESH::PointStruct & theRefPoint)
2457 if ( !myPreviewMode ) {
2458 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
2459 << theObject << ", "
2460 << thePathMesh << ", "
2461 << thePathShape << ", "
2462 << theNodeStart << ", "
2463 << theHasAngles << ", "
2464 << theAngles << ", "
2465 << theHasRefPoint << ", "
2466 << "SMESH.PointStruct( "
2467 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2468 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2469 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2471 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2472 SMESH::long_array_var anElementsId = theObject->GetIDs();
2473 extrusionAlongPath( anElementsId,
2487 //=======================================================================
2488 //function : ExtrusionAlongPathObject2D
2490 //=======================================================================
2491 SMESH::SMESH_MeshEditor::Extrusion_Error
2492 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr theObject,
2493 SMESH::SMESH_Mesh_ptr thePathMesh,
2494 GEOM::GEOM_Object_ptr thePathShape,
2495 CORBA::Long theNodeStart,
2496 CORBA::Boolean theHasAngles,
2497 const SMESH::double_array & theAngles,
2498 CORBA::Boolean theHasRefPoint,
2499 const SMESH::PointStruct & theRefPoint)
2501 if ( !myPreviewMode ) {
2502 TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
2503 << theObject << ", "
2504 << thePathMesh << ", "
2505 << thePathShape << ", "
2506 << theNodeStart << ", "
2507 << theHasAngles << ", "
2508 << theAngles << ", "
2509 << theHasRefPoint << ", "
2510 << "SMESH.PointStruct( "
2511 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2512 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2513 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2515 SMESH::SMESH_MeshEditor::Extrusion_Error anError;
2516 SMESH::long_array_var anElementsId = theObject->GetIDs();
2517 extrusionAlongPath( anElementsId,
2532 //=======================================================================
2533 //function : ExtrusionAlongPathMakeGroups
2535 //=======================================================================
2536 SMESH::ListOfGroups*
2537 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array& theIDsOfElements,
2538 SMESH::SMESH_Mesh_ptr thePathMesh,
2539 GEOM::GEOM_Object_ptr thePathShape,
2540 CORBA::Long theNodeStart,
2541 CORBA::Boolean theHasAngles,
2542 const SMESH::double_array& theAngles,
2543 CORBA::Boolean theHasRefPoint,
2544 const SMESH::PointStruct& theRefPoint,
2545 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2547 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2549 SMESH::ListOfGroups * aGroups = extrusionAlongPath( theIDsOfElements,
2559 if (!myPreviewMode) {
2560 bool isDumpGroups = aGroups && aGroups->length() > 0;
2562 aPythonDump << "(" << aGroups << ", error)";
2564 aPythonDump <<"error";
2566 aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
2567 << theIDsOfElements << ", "
2568 << thePathMesh << ", "
2569 << thePathShape << ", "
2570 << theNodeStart << ", "
2571 << theHasAngles << ", "
2572 << theAngles << ", "
2573 << theHasRefPoint << ", "
2574 << "SMESH.PointStruct( "
2575 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2576 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2577 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2582 //=======================================================================
2583 //function : ExtrusionAlongPathObjectMakeGroups
2585 //=======================================================================
2586 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2587 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2588 SMESH::SMESH_Mesh_ptr thePathMesh,
2589 GEOM::GEOM_Object_ptr thePathShape,
2590 CORBA::Long theNodeStart,
2591 CORBA::Boolean theHasAngles,
2592 const SMESH::double_array& theAngles,
2593 CORBA::Boolean theHasRefPoint,
2594 const SMESH::PointStruct& theRefPoint,
2595 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2597 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2599 SMESH::long_array_var anElementsId = theObject->GetIDs();
2600 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
2611 if (!myPreviewMode) {
2612 bool isDumpGroups = aGroups && aGroups->length() > 0;
2614 aPythonDump << "(" << aGroups << ", error)";
2616 aPythonDump <<"error";
2618 aPythonDump << " = " << this << ".ExtrusionAlongPathObjectMakeGroups( "
2619 << theObject << ", "
2620 << thePathMesh << ", "
2621 << thePathShape << ", "
2622 << theNodeStart << ", "
2623 << theHasAngles << ", "
2624 << theAngles << ", "
2625 << theHasRefPoint << ", "
2626 << "SMESH.PointStruct( "
2627 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2628 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2629 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2634 //=======================================================================
2635 //function : ExtrusionAlongPathObject1DMakeGroups
2637 //=======================================================================
2638 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2639 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2640 SMESH::SMESH_Mesh_ptr thePathMesh,
2641 GEOM::GEOM_Object_ptr thePathShape,
2642 CORBA::Long theNodeStart,
2643 CORBA::Boolean theHasAngles,
2644 const SMESH::double_array& theAngles,
2645 CORBA::Boolean theHasRefPoint,
2646 const SMESH::PointStruct& theRefPoint,
2647 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2649 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2651 SMESH::long_array_var anElementsId = theObject->GetIDs();
2652 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
2664 if (!myPreviewMode) {
2665 bool isDumpGroups = aGroups && aGroups->length() > 0;
2667 aPythonDump << "(" << aGroups << ", error)";
2669 aPythonDump << "error";
2671 aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
2672 << theObject << ", "
2673 << thePathMesh << ", "
2674 << thePathShape << ", "
2675 << theNodeStart << ", "
2676 << theHasAngles << ", "
2677 << theAngles << ", "
2678 << theHasRefPoint << ", "
2679 << "SMESH.PointStruct( "
2680 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2681 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2682 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2687 //=======================================================================
2688 //function : ExtrusionAlongPathObject2DMakeGroups
2690 //=======================================================================
2691 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2692 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
2693 SMESH::SMESH_Mesh_ptr thePathMesh,
2694 GEOM::GEOM_Object_ptr thePathShape,
2695 CORBA::Long theNodeStart,
2696 CORBA::Boolean theHasAngles,
2697 const SMESH::double_array& theAngles,
2698 CORBA::Boolean theHasRefPoint,
2699 const SMESH::PointStruct& theRefPoint,
2700 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2702 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2704 SMESH::long_array_var anElementsId = theObject->GetIDs();
2705 SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
2717 if (!myPreviewMode) {
2718 bool isDumpGroups = aGroups && aGroups->length() > 0;
2720 aPythonDump << "(" << aGroups << ", error)";
2722 aPythonDump << "error";
2724 aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
2725 << theObject << ", "
2726 << thePathMesh << ", "
2727 << thePathShape << ", "
2728 << theNodeStart << ", "
2729 << theHasAngles << ", "
2730 << theAngles << ", "
2731 << theHasRefPoint << ", "
2732 << "SMESH.PointStruct( "
2733 << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
2734 << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
2735 << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
2741 //=======================================================================
2742 //function : ExtrusionAlongPathObjX
2744 //=======================================================================
2745 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2746 ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr Object,
2747 SMESH::SMESH_IDSource_ptr Path,
2748 CORBA::Long NodeStart,
2749 CORBA::Boolean HasAngles,
2750 const SMESH::double_array& Angles,
2751 CORBA::Boolean LinearVariation,
2752 CORBA::Boolean HasRefPoint,
2753 const SMESH::PointStruct& RefPoint,
2754 CORBA::Boolean MakeGroups,
2755 SMESH::ElementType ElemType,
2756 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2758 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2760 SMESH::long_array_var anElementsId = Object->GetIDs();
2761 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
2770 (SMDSAbs_ElementType)ElemType,
2773 if (!myPreviewMode) {
2774 bool isDumpGroups = aGroups && aGroups->length() > 0;
2776 aPythonDump << "(" << *aGroups << ", error)";
2778 aPythonDump << "error";
2780 aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
2783 << NodeStart << ", "
2784 << HasAngles << ", "
2786 << LinearVariation << ", "
2787 << HasRefPoint << ", "
2788 << "SMESH.PointStruct( "
2789 << ( HasRefPoint ? RefPoint.x : 0 ) << ", "
2790 << ( HasRefPoint ? RefPoint.y : 0 ) << ", "
2791 << ( HasRefPoint ? RefPoint.z : 0 ) << " ), "
2792 << MakeGroups << ", "
2793 << ElemType << " )";
2799 //=======================================================================
2800 //function : ExtrusionAlongPathX
2802 //=======================================================================
2803 SMESH::ListOfGroups* SMESH_MeshEditor_i::
2804 ExtrusionAlongPathX(const SMESH::long_array& IDsOfElements,
2805 SMESH::SMESH_IDSource_ptr Path,
2806 CORBA::Long NodeStart,
2807 CORBA::Boolean HasAngles,
2808 const SMESH::double_array& Angles,
2809 CORBA::Boolean LinearVariation,
2810 CORBA::Boolean HasRefPoint,
2811 const SMESH::PointStruct& RefPoint,
2812 CORBA::Boolean MakeGroups,
2813 SMESH::ElementType ElemType,
2814 SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
2816 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
2818 SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
2827 (SMDSAbs_ElementType)ElemType,
2830 if (!myPreviewMode) {
2831 bool isDumpGroups = aGroups && aGroups->length() > 0;
2833 aPythonDump << "(" << *aGroups << ", error)";
2835 aPythonDump <<"error";
2837 aPythonDump << " = " << this << ".ExtrusionAlongPathX( "
2838 << IDsOfElements << ", "
2840 << NodeStart << ", "
2841 << HasAngles << ", "
2843 << LinearVariation << ", "
2844 << HasRefPoint << ", "
2845 << "SMESH.PointStruct( "
2846 << ( HasRefPoint ? RefPoint.x : 0 ) << ", "
2847 << ( HasRefPoint ? RefPoint.y : 0 ) << ", "
2848 << ( HasRefPoint ? RefPoint.z : 0 ) << " ), "
2849 << MakeGroups << ", "
2850 << ElemType << " )";
2856 //================================================================================
2858 * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
2859 * of given angles along path steps
2860 * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
2861 * which proceeds the extrusion
2862 * \param PathShape is shape(edge); as the mesh can be complex, the edge
2863 * is used to define the sub-mesh for the path
2865 //================================================================================
2867 SMESH::double_array*
2868 SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMesh,
2869 GEOM::GEOM_Object_ptr thePathShape,
2870 const SMESH::double_array & theAngles)
2872 SMESH::double_array_var aResult = new SMESH::double_array();
2873 int nbAngles = theAngles.length();
2874 if ( nbAngles > 0 && !thePathMesh->_is_nil() && !thePathShape->_is_nil() )
2876 SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( thePathMesh );
2877 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
2878 SMESH_subMesh* aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
2879 if ( !aSubMesh || !aSubMesh->GetSubMeshDS())
2880 return aResult._retn();
2881 int nbSteps = aSubMesh->GetSubMeshDS()->NbElements();
2882 if ( nbSteps == nbAngles )
2884 aResult.inout() = theAngles;
2888 aResult->length( nbSteps );
2889 double rAn2St = double( nbAngles ) / double( nbSteps );
2890 double angPrev = 0, angle;
2891 for ( int iSt = 0; iSt < nbSteps; ++iSt )
2893 double angCur = rAn2St * ( iSt+1 );
2894 double angCurFloor = floor( angCur );
2895 double angPrevFloor = floor( angPrev );
2896 if ( angPrevFloor == angCurFloor )
2897 angle = rAn2St * theAngles[ int( angCurFloor ) ];
2900 int iP = int( angPrevFloor );
2901 double angPrevCeil = ceil(angPrev);
2902 angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
2904 int iC = int( angCurFloor );
2905 if ( iC < nbAngles )
2906 angle += ( angCur - angCurFloor ) * theAngles[ iC ];
2908 iP = int( angPrevCeil );
2910 angle += theAngles[ iC ];
2912 aResult[ iSt ] = angle;
2917 // Update Python script
2918 TPythonDump() << "rotAngles = " << theAngles;
2919 TPythonDump() << "rotAngles = " << this << ".LinearAnglesVariation( "
2920 << thePathMesh << ", "
2921 << thePathShape << ", "
2924 return aResult._retn();
2928 //=======================================================================
2931 //=======================================================================
2933 SMESH::ListOfGroups*
2934 SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements,
2935 const SMESH::AxisStruct & theAxis,
2936 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
2937 CORBA::Boolean theCopy,
2939 ::SMESH_Mesh* theTargetMesh)
2943 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
2944 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
2946 if ( theTargetMesh )
2950 switch ( theMirrorType ) {
2951 case SMESH::SMESH_MeshEditor::POINT:
2952 aTrsf.SetMirror( P );
2954 case SMESH::SMESH_MeshEditor::AXIS:
2955 aTrsf.SetMirror( gp_Ax1( P, V ));
2958 aTrsf.SetMirror( gp_Ax2( P, V ));
2961 TIDSortedElemSet copyElements;
2962 TPreviewMesh tmpMesh;
2963 TIDSortedElemSet* workElements = & theElements;
2964 SMESH_Mesh* mesh = myMesh;
2966 if ( myPreviewMode )
2968 tmpMesh.Copy( theElements, copyElements);
2969 if ( !theCopy && !theTargetMesh )
2971 TIDSortedElemSet elemsAround, elemsAroundCopy;
2972 getElementsAround( theElements, GetMeshDS(), elemsAround );
2973 tmpMesh.Copy( elemsAround, elemsAroundCopy);
2976 workElements = & copyElements;
2977 theMakeGroups = false;
2980 ::SMESH_MeshEditor anEditor( mesh );
2981 ::SMESH_MeshEditor::PGroupIDs groupIds =
2982 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
2984 if(theCopy || myPreviewMode)
2985 storeResult(anEditor);
2988 myMesh->SetIsModified( true );
2989 myMesh->GetMeshDS()->Modified();
2991 return theMakeGroups ? getGroups(groupIds.get()) : 0;
2994 //=======================================================================
2997 //=======================================================================
2999 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElements,
3000 const SMESH::AxisStruct & theAxis,
3001 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3002 CORBA::Boolean theCopy)
3004 if ( !myPreviewMode ) {
3005 TPythonDump() << this << ".Mirror( "
3006 << theIDsOfElements << ", "
3008 << mirrorTypeName(theMirrorType) << ", "
3011 if ( theIDsOfElements.length() > 0 )
3013 TIDSortedElemSet elements;
3014 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3015 mirror(elements, theAxis, theMirrorType, theCopy, false);
3020 //=======================================================================
3021 //function : MirrorObject
3023 //=======================================================================
3025 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObject,
3026 const SMESH::AxisStruct & theAxis,
3027 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3028 CORBA::Boolean theCopy)
3030 if ( !myPreviewMode ) {
3031 TPythonDump() << this << ".MirrorObject( "
3032 << theObject << ", "
3034 << mirrorTypeName(theMirrorType) << ", "
3037 TIDSortedElemSet elements;
3039 bool emptyIfIsMesh = myPreviewMode ? false : true;
3041 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3042 mirror(elements, theAxis, theMirrorType, theCopy, false);
3045 //=======================================================================
3046 //function : MirrorMakeGroups
3048 //=======================================================================
3050 SMESH::ListOfGroups*
3051 SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsOfElements,
3052 const SMESH::AxisStruct& theMirror,
3053 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3055 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3057 SMESH::ListOfGroups * aGroups = 0;
3058 if ( theIDsOfElements.length() > 0 )
3060 TIDSortedElemSet elements;
3061 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3062 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3064 if (!myPreviewMode) {
3065 DumpGroupsList(aPythonDump, aGroups);
3066 aPythonDump << this << ".MirrorMakeGroups( "
3067 << theIDsOfElements << ", "
3068 << theMirror << ", "
3069 << mirrorTypeName(theMirrorType) << " )";
3074 //=======================================================================
3075 //function : MirrorObjectMakeGroups
3077 //=======================================================================
3079 SMESH::ListOfGroups*
3080 SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3081 const SMESH::AxisStruct& theMirror,
3082 SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
3084 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3086 SMESH::ListOfGroups * aGroups = 0;
3087 TIDSortedElemSet elements;
3088 if ( idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3089 aGroups = mirror(elements, theMirror, theMirrorType, true, true);
3093 DumpGroupsList(aPythonDump,aGroups);
3094 aPythonDump << this << ".MirrorObjectMakeGroups( "
3095 << theObject << ", "
3096 << theMirror << ", "
3097 << mirrorTypeName(theMirrorType) << " )";
3102 //=======================================================================
3103 //function : MirrorMakeMesh
3105 //=======================================================================
3107 SMESH::SMESH_Mesh_ptr
3108 SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfElements,
3109 const SMESH::AxisStruct& theMirror,
3110 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3111 CORBA::Boolean theCopyGroups,
3112 const char* theMeshName)
3114 SMESH_Mesh_i* mesh_i;
3115 SMESH::SMESH_Mesh_var mesh;
3116 { // open new scope to dump "MakeMesh" command
3117 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3119 TPythonDump pydump; // to prevent dump at mesh creation
3121 mesh = makeMesh( theMeshName );
3122 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3123 if (mesh_i && theIDsOfElements.length() > 0 )
3125 TIDSortedElemSet elements;
3126 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3127 mirror(elements, theMirror, theMirrorType,
3128 false, theCopyGroups, & mesh_i->GetImpl());
3129 mesh_i->CreateGroupServants();
3132 if (!myPreviewMode) {
3133 pydump << mesh << " = " << this << ".MirrorMakeMesh( "
3134 << theIDsOfElements << ", "
3135 << theMirror << ", "
3136 << mirrorTypeName(theMirrorType) << ", "
3137 << theCopyGroups << ", '"
3138 << theMeshName << "' )";
3143 if (!myPreviewMode && mesh_i)
3144 mesh_i->GetGroups();
3146 return mesh._retn();
3149 //=======================================================================
3150 //function : MirrorObjectMakeMesh
3152 //=======================================================================
3154 SMESH::SMESH_Mesh_ptr
3155 SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3156 const SMESH::AxisStruct& theMirror,
3157 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
3158 CORBA::Boolean theCopyGroups,
3159 const char* theMeshName)
3161 SMESH_Mesh_i* mesh_i;
3162 SMESH::SMESH_Mesh_var mesh;
3163 { // open new scope to dump "MakeMesh" command
3164 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3166 TPythonDump pydump; // to prevent dump at mesh creation
3168 mesh = makeMesh( theMeshName );
3169 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3170 TIDSortedElemSet elements;
3172 idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3174 mirror(elements, theMirror, theMirrorType,
3175 false, theCopyGroups, & mesh_i->GetImpl());
3176 mesh_i->CreateGroupServants();
3178 if (!myPreviewMode) {
3179 pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
3180 << theObject << ", "
3181 << theMirror << ", "
3182 << mirrorTypeName(theMirrorType) << ", "
3183 << theCopyGroups << ", '"
3184 << theMeshName << "' )";
3189 if (!myPreviewMode && mesh_i)
3190 mesh_i->GetGroups();
3192 return mesh._retn();
3195 //=======================================================================
3196 //function : translate
3198 //=======================================================================
3200 SMESH::ListOfGroups*
3201 SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements,
3202 const SMESH::DirStruct & theVector,
3203 CORBA::Boolean theCopy,
3205 ::SMESH_Mesh* theTargetMesh)
3209 if ( theTargetMesh )
3213 const SMESH::PointStruct * P = &theVector.PS;
3214 aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
3216 TIDSortedElemSet copyElements;
3217 TIDSortedElemSet* workElements = &theElements;
3218 TPreviewMesh tmpMesh;
3219 SMESH_Mesh* mesh = myMesh;
3221 if ( myPreviewMode )
3223 tmpMesh.Copy( theElements, copyElements);
3224 if ( !theCopy && !theTargetMesh )
3226 TIDSortedElemSet elemsAround, elemsAroundCopy;
3227 getElementsAround( theElements, GetMeshDS(), elemsAround );
3228 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3231 workElements = & copyElements;
3232 theMakeGroups = false;
3235 ::SMESH_MeshEditor anEditor( mesh );
3236 ::SMESH_MeshEditor::PGroupIDs groupIds =
3237 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3239 if(theCopy || myPreviewMode)
3240 storeResult(anEditor);
3243 myMesh->GetMeshDS()->Modified();
3244 myMesh->SetIsModified( true );
3247 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3250 //=======================================================================
3251 //function : Translate
3253 //=======================================================================
3255 void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
3256 const SMESH::DirStruct & theVector,
3257 CORBA::Boolean theCopy)
3259 if (!myPreviewMode) {
3260 TPythonDump() << this << ".Translate( "
3261 << theIDsOfElements << ", "
3262 << theVector << ", "
3265 if (theIDsOfElements.length()) {
3266 TIDSortedElemSet elements;
3267 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3268 translate(elements, theVector, theCopy, false);
3272 //=======================================================================
3273 //function : TranslateObject
3275 //=======================================================================
3277 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
3278 const SMESH::DirStruct & theVector,
3279 CORBA::Boolean theCopy)
3281 if (!myPreviewMode) {
3282 TPythonDump() << this << ".TranslateObject( "
3283 << theObject << ", "
3284 << theVector << ", "
3287 TIDSortedElemSet elements;
3289 bool emptyIfIsMesh = myPreviewMode ? false : true;
3291 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3292 translate(elements, theVector, theCopy, false);
3295 //=======================================================================
3296 //function : TranslateMakeGroups
3298 //=======================================================================
3300 SMESH::ListOfGroups*
3301 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
3302 const SMESH::DirStruct& theVector)
3304 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3306 SMESH::ListOfGroups * aGroups = 0;
3307 if (theIDsOfElements.length()) {
3308 TIDSortedElemSet elements;
3309 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3310 aGroups = translate(elements,theVector,true,true);
3312 if (!myPreviewMode) {
3313 DumpGroupsList(aPythonDump, aGroups);
3314 aPythonDump << this << ".TranslateMakeGroups( "
3315 << theIDsOfElements << ", "
3316 << theVector << " )";
3321 //=======================================================================
3322 //function : TranslateObjectMakeGroups
3324 //=======================================================================
3326 SMESH::ListOfGroups*
3327 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3328 const SMESH::DirStruct& theVector)
3330 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3332 SMESH::ListOfGroups * aGroups = 0;
3333 TIDSortedElemSet elements;
3334 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3335 aGroups = translate(elements, theVector, true, true);
3337 if (!myPreviewMode) {
3338 DumpGroupsList(aPythonDump, aGroups);
3339 aPythonDump << this << ".TranslateObjectMakeGroups( "
3340 << theObject << ", "
3341 << theVector << " )";
3346 //=======================================================================
3347 //function : TranslateMakeMesh
3349 //=======================================================================
3351 SMESH::SMESH_Mesh_ptr
3352 SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
3353 const SMESH::DirStruct& theVector,
3354 CORBA::Boolean theCopyGroups,
3355 const char* theMeshName)
3357 SMESH_Mesh_i* mesh_i;
3358 SMESH::SMESH_Mesh_var mesh;
3360 { // open new scope to dump "MakeMesh" command
3361 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3363 TPythonDump pydump; // to prevent dump at mesh creation
3365 mesh = makeMesh( theMeshName );
3366 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3368 if ( mesh_i && theIDsOfElements.length() )
3370 TIDSortedElemSet elements;
3371 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3372 translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
3373 mesh_i->CreateGroupServants();
3376 if ( !myPreviewMode ) {
3377 pydump << mesh << " = " << this << ".TranslateMakeMesh( "
3378 << theIDsOfElements << ", "
3379 << theVector << ", "
3380 << theCopyGroups << ", '"
3381 << theMeshName << "' )";
3386 if (!myPreviewMode && mesh_i)
3387 mesh_i->GetGroups();
3389 return mesh._retn();
3392 //=======================================================================
3393 //function : TranslateObjectMakeMesh
3395 //=======================================================================
3397 SMESH::SMESH_Mesh_ptr
3398 SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3399 const SMESH::DirStruct& theVector,
3400 CORBA::Boolean theCopyGroups,
3401 const char* theMeshName)
3403 SMESH_Mesh_i* mesh_i;
3404 SMESH::SMESH_Mesh_var mesh;
3405 { // open new scope to dump "MakeMesh" command
3406 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3408 TPythonDump pydump; // to prevent dump at mesh creation
3409 mesh = makeMesh( theMeshName );
3410 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3412 TIDSortedElemSet elements;
3414 idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3416 translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
3417 mesh_i->CreateGroupServants();
3419 if ( !myPreviewMode ) {
3420 pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
3421 << theObject << ", "
3422 << theVector << ", "
3423 << theCopyGroups << ", '"
3424 << theMeshName << "' )";
3429 if (!myPreviewMode && mesh_i)
3430 mesh_i->GetGroups();
3432 return mesh._retn();
3435 //=======================================================================
3438 //=======================================================================
3440 SMESH::ListOfGroups*
3441 SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements,
3442 const SMESH::AxisStruct & theAxis,
3443 CORBA::Double theAngle,
3444 CORBA::Boolean theCopy,
3446 ::SMESH_Mesh* theTargetMesh)
3450 if ( theTargetMesh )
3453 gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
3454 gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
3457 aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
3459 TIDSortedElemSet copyElements;
3460 TIDSortedElemSet* workElements = &theElements;
3461 TPreviewMesh tmpMesh;
3462 SMESH_Mesh* mesh = myMesh;
3464 if ( myPreviewMode ) {
3465 tmpMesh.Copy( theElements, copyElements );
3466 if ( !theCopy && !theTargetMesh )
3468 TIDSortedElemSet elemsAround, elemsAroundCopy;
3469 getElementsAround( theElements, GetMeshDS(), elemsAround );
3470 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3473 workElements = ©Elements;
3474 theMakeGroups = false;
3477 ::SMESH_MeshEditor anEditor( mesh );
3478 ::SMESH_MeshEditor::PGroupIDs groupIds =
3479 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3481 if(theCopy || myPreviewMode)
3482 storeResult(anEditor);
3485 myMesh->GetMeshDS()->Modified();
3486 myMesh->SetIsModified( true );
3489 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3492 //=======================================================================
3495 //=======================================================================
3497 void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
3498 const SMESH::AxisStruct & theAxis,
3499 CORBA::Double theAngle,
3500 CORBA::Boolean theCopy)
3502 if (!myPreviewMode) {
3503 TPythonDump() << this << ".Rotate( "
3504 << theIDsOfElements << ", "
3509 if (theIDsOfElements.length() > 0)
3511 TIDSortedElemSet elements;
3512 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3513 rotate(elements,theAxis,theAngle,theCopy,false);
3517 //=======================================================================
3518 //function : RotateObject
3520 //=======================================================================
3522 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
3523 const SMESH::AxisStruct & theAxis,
3524 CORBA::Double theAngle,
3525 CORBA::Boolean theCopy)
3527 if ( !myPreviewMode ) {
3528 TPythonDump() << this << ".RotateObject( "
3529 << theObject << ", "
3534 TIDSortedElemSet elements;
3535 bool emptyIfIsMesh = myPreviewMode ? false : true;
3536 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3537 rotate(elements,theAxis,theAngle,theCopy,false);
3540 //=======================================================================
3541 //function : RotateMakeGroups
3543 //=======================================================================
3545 SMESH::ListOfGroups*
3546 SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
3547 const SMESH::AxisStruct& theAxis,
3548 CORBA::Double theAngle)
3550 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3552 SMESH::ListOfGroups * aGroups = 0;
3553 if (theIDsOfElements.length() > 0)
3555 TIDSortedElemSet elements;
3556 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3557 aGroups = rotate(elements,theAxis,theAngle,true,true);
3559 if (!myPreviewMode) {
3560 DumpGroupsList(aPythonDump, aGroups);
3561 aPythonDump << this << ".RotateMakeGroups( "
3562 << theIDsOfElements << ", "
3564 << theAngle << " )";
3569 //=======================================================================
3570 //function : RotateObjectMakeGroups
3572 //=======================================================================
3574 SMESH::ListOfGroups*
3575 SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3576 const SMESH::AxisStruct& theAxis,
3577 CORBA::Double theAngle)
3579 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3581 SMESH::ListOfGroups * aGroups = 0;
3582 TIDSortedElemSet elements;
3583 if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3584 aGroups = rotate(elements, theAxis, theAngle, true, true);
3586 if (!myPreviewMode) {
3587 DumpGroupsList(aPythonDump, aGroups);
3588 aPythonDump << this << ".RotateObjectMakeGroups( "
3589 << theObject << ", "
3591 << theAngle << " )";
3596 //=======================================================================
3597 //function : RotateMakeMesh
3599 //=======================================================================
3601 SMESH::SMESH_Mesh_ptr
3602 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
3603 const SMESH::AxisStruct& theAxis,
3604 CORBA::Double theAngleInRadians,
3605 CORBA::Boolean theCopyGroups,
3606 const char* theMeshName)
3608 SMESH::SMESH_Mesh_var mesh;
3609 SMESH_Mesh_i* mesh_i;
3611 { // open new scope to dump "MakeMesh" command
3612 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3614 TPythonDump pydump; // to prevent dump at mesh creation
3616 mesh = makeMesh( theMeshName );
3617 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3619 if ( mesh_i && theIDsOfElements.length() > 0 )
3621 TIDSortedElemSet elements;
3622 arrayToSet(theIDsOfElements, GetMeshDS(), elements);
3623 rotate(elements, theAxis, theAngleInRadians,
3624 false, theCopyGroups, & mesh_i->GetImpl());
3625 mesh_i->CreateGroupServants();
3627 if ( !myPreviewMode ) {
3628 pydump << mesh << " = " << this << ".RotateMakeMesh( "
3629 << theIDsOfElements << ", "
3631 << theAngleInRadians << ", "
3632 << theCopyGroups << ", '"
3633 << theMeshName << "' )";
3638 if (!myPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
3639 mesh_i->GetGroups();
3641 return mesh._retn();
3644 //=======================================================================
3645 //function : RotateObjectMakeMesh
3647 //=======================================================================
3649 SMESH::SMESH_Mesh_ptr
3650 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3651 const SMESH::AxisStruct& theAxis,
3652 CORBA::Double theAngleInRadians,
3653 CORBA::Boolean theCopyGroups,
3654 const char* theMeshName)
3656 SMESH::SMESH_Mesh_var mesh;
3657 SMESH_Mesh_i* mesh_i;
3659 {// open new scope to dump "MakeMesh" command
3660 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3662 TPythonDump pydump; // to prevent dump at mesh creation
3663 mesh = makeMesh( theMeshName );
3664 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3666 TIDSortedElemSet elements;
3668 idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
3670 rotate(elements, theAxis, theAngleInRadians,
3671 false, theCopyGroups, & mesh_i->GetImpl());
3672 mesh_i->CreateGroupServants();
3674 if ( !myPreviewMode ) {
3675 pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
3676 << theObject << ", "
3678 << theAngleInRadians << ", "
3679 << theCopyGroups << ", '"
3680 << theMeshName << "' )";
3685 if (!myPreviewMode && mesh_i)
3686 mesh_i->GetGroups();
3688 return mesh._retn();
3691 //=======================================================================
3694 //=======================================================================
3696 SMESH::ListOfGroups*
3697 SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject,
3698 const SMESH::PointStruct& thePoint,
3699 const SMESH::double_array& theScaleFact,
3700 CORBA::Boolean theCopy,
3702 ::SMESH_Mesh* theTargetMesh)
3705 if ( theScaleFact.length() < 1 )
3706 THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
3707 if ( theScaleFact.length() == 2 )
3708 THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
3710 if ( theTargetMesh )
3713 TIDSortedElemSet elements;
3714 bool emptyIfIsMesh = myPreviewMode ? false : true;
3715 if ( !idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
3720 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
3721 (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
3723 double tol = std::numeric_limits<double>::max();
3725 aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
3726 0, S[1], 0, thePoint.y * (1-S[1]),
3727 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
3729 TIDSortedElemSet copyElements;
3730 TPreviewMesh tmpMesh;
3731 TIDSortedElemSet* workElements = &elements;
3732 SMESH_Mesh* mesh = myMesh;
3734 if ( myPreviewMode )
3736 tmpMesh.Copy( elements, copyElements);
3737 if ( !theCopy && !theTargetMesh )
3739 TIDSortedElemSet elemsAround, elemsAroundCopy;
3740 getElementsAround( elements, GetMeshDS(), elemsAround );
3741 tmpMesh.Copy( elemsAround, elemsAroundCopy);
3744 workElements = & copyElements;
3745 theMakeGroups = false;
3748 ::SMESH_MeshEditor anEditor( mesh );
3749 ::SMESH_MeshEditor::PGroupIDs groupIds =
3750 anEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
3752 if(theCopy || myPreviewMode )
3753 storeResult(anEditor);
3756 myMesh->GetMeshDS()->Modified();
3757 myMesh->SetIsModified( true );
3759 return theMakeGroups ? getGroups(groupIds.get()) : 0;
3762 //=======================================================================
3765 //=======================================================================
3767 void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject,
3768 const SMESH::PointStruct& thePoint,
3769 const SMESH::double_array& theScaleFact,
3770 CORBA::Boolean theCopy)
3772 if ( !myPreviewMode ) {
3773 TPythonDump() << this << ".Scale( "
3774 << theObject << ", "
3775 << "SMESH.PointStruct( " << thePoint.x << ", "
3776 << thePoint.y << ", " << thePoint.z << " ) ,"
3777 << theScaleFact << ", "
3780 scale(theObject, thePoint, theScaleFact, theCopy, false);
3784 //=======================================================================
3785 //function : ScaleMakeGroups
3787 //=======================================================================
3789 SMESH::ListOfGroups*
3790 SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
3791 const SMESH::PointStruct& thePoint,
3792 const SMESH::double_array& theScaleFact)
3794 TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
3796 SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
3797 if (!myPreviewMode) {
3798 DumpGroupsList(aPythonDump, aGroups);
3799 aPythonDump << this << ".Scale("
3801 << "SMESH.PointStruct(" <<thePoint.x << ","
3802 << thePoint.y << "," << thePoint.z << "),"
3803 << theScaleFact << ",True,True)";
3809 //=======================================================================
3810 //function : ScaleMakeMesh
3812 //=======================================================================
3814 SMESH::SMESH_Mesh_ptr
3815 SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
3816 const SMESH::PointStruct& thePoint,
3817 const SMESH::double_array& theScaleFact,
3818 CORBA::Boolean theCopyGroups,
3819 const char* theMeshName)
3821 SMESH_Mesh_i* mesh_i;
3822 SMESH::SMESH_Mesh_var mesh;
3823 { // open new scope to dump "MakeMesh" command
3824 // and then "GetGroups" using SMESH_Mesh::GetGroups()
3826 TPythonDump pydump; // to prevent dump at mesh creation
3827 mesh = makeMesh( theMeshName );
3828 mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
3832 scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
3833 mesh_i->CreateGroupServants();
3835 if ( !myPreviewMode )
3836 pydump << mesh << " = " << this << ".ScaleMakeMesh( "
3837 << theObject << ", "
3838 << "SMESH.PointStruct( " << thePoint.x << ", "
3839 << thePoint.y << ", " << thePoint.z << " ) ,"
3840 << theScaleFact << ", "
3841 << theCopyGroups << ", '"
3842 << theMeshName << "' )";
3846 if (!myPreviewMode && mesh_i)
3847 mesh_i->GetGroups();
3849 return mesh._retn();
3853 //=======================================================================
3854 //function : FindCoincidentNodes
3856 //=======================================================================
3858 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance,
3859 SMESH::array_of_long_array_out GroupsOfNodes)
3863 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3864 ::SMESH_MeshEditor anEditor( myMesh );
3865 TIDSortedNodeSet nodes; // no input nodes
3866 anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
3868 GroupsOfNodes = new SMESH::array_of_long_array;
3869 GroupsOfNodes->length( aListOfListOfNodes.size() );
3870 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
3871 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
3872 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
3873 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
3874 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
3875 aGroup.length( aListOfNodes.size() );
3876 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
3877 aGroup[ j ] = (*lIt)->GetID();
3879 TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
3880 << Tolerance << " )";
3883 //=======================================================================
3884 //function : FindCoincidentNodesOnPart
3886 //=======================================================================
3887 void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
3888 CORBA::Double Tolerance,
3889 SMESH::array_of_long_array_out GroupsOfNodes)
3893 TIDSortedNodeSet nodes;
3894 idSourceToNodeSet( theObject, GetMeshDS(), nodes );
3896 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3897 ::SMESH_MeshEditor anEditor( myMesh );
3899 anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
3901 GroupsOfNodes = new SMESH::array_of_long_array;
3902 GroupsOfNodes->length( aListOfListOfNodes.size() );
3903 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
3904 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
3906 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
3907 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
3908 SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
3909 aGroup.length( aListOfNodes.size() );
3910 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
3911 aGroup[ j ] = (*lIt)->GetID();
3913 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
3915 << Tolerance << " )";
3918 //================================================================================
3920 * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
3921 * ExceptSubMeshOrGroups
3923 //================================================================================
3925 void SMESH_MeshEditor_i::
3926 FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
3927 CORBA::Double theTolerance,
3928 SMESH::array_of_long_array_out theGroupsOfNodes,
3929 const SMESH::ListOfIDSources& theExceptSubMeshOrGroups)
3933 TIDSortedNodeSet nodes;
3934 idSourceToNodeSet( theObject, GetMeshDS(), nodes );
3936 for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
3938 TIDSortedNodeSet exceptNodes;
3939 idSourceToNodeSet( theExceptSubMeshOrGroups[i], GetMeshDS(), exceptNodes );
3940 TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
3941 for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
3942 nodes.erase( *avoidNode );
3944 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3945 ::SMESH_MeshEditor anEditor( myMesh );
3947 anEditor.FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
3949 theGroupsOfNodes = new SMESH::array_of_long_array;
3950 theGroupsOfNodes->length( aListOfListOfNodes.size() );
3951 ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
3952 for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
3954 list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
3955 list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
3956 SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
3957 aGroup.length( aListOfNodes.size() );
3958 for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
3959 aGroup[ j ] = (*lIt)->GetID();
3961 TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
3963 << theTolerance << ", "
3964 << theExceptSubMeshOrGroups << " )";
3967 //=======================================================================
3968 //function : MergeNodes
3970 //=======================================================================
3972 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
3976 SMESHDS_Mesh* aMesh = GetMeshDS();
3978 TPythonDump aTPythonDump;
3979 aTPythonDump << this << ".MergeNodes([";
3980 ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
3981 for (int i = 0; i < GroupsOfNodes.length(); i++)
3983 const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
3984 aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
3985 list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
3986 for ( int j = 0; j < aNodeGroup.length(); j++ )
3988 CORBA::Long index = aNodeGroup[ j ];
3989 const SMDS_MeshNode * node = aMesh->FindNode(index);
3991 aListOfNodes.push_back( node );
3993 if ( aListOfNodes.size() < 2 )
3994 aListOfListOfNodes.pop_back();
3996 if ( i > 0 ) aTPythonDump << ", ";
3997 aTPythonDump << aNodeGroup;
3999 ::SMESH_MeshEditor anEditor( myMesh );
4000 anEditor.MergeNodes( aListOfListOfNodes );
4002 aTPythonDump << "])";
4003 myMesh->GetMeshDS()->Modified();
4004 myMesh->SetIsModified( true );
4007 //=======================================================================
4008 //function : FindEqualElements
4010 //=======================================================================
4011 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject,
4012 SMESH::array_of_long_array_out GroupsOfElementsID)
4016 SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
4017 if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
4019 typedef list<int> TListOfIDs;
4020 set<const SMDS_MeshElement*> elems;
4021 SMESH::long_array_var aElementsId = theObject->GetIDs();
4022 SMESHDS_Mesh* aMesh = GetMeshDS();
4024 for(int i = 0; i < aElementsId->length(); i++) {
4025 CORBA::Long anID = aElementsId[i];
4026 const SMDS_MeshElement * elem = aMesh->FindElement(anID);
4032 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4033 ::SMESH_MeshEditor anEditor( myMesh );
4034 anEditor.FindEqualElements( elems, aListOfListOfElementsID );
4036 GroupsOfElementsID = new SMESH::array_of_long_array;
4037 GroupsOfElementsID->length( aListOfListOfElementsID.size() );
4039 ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt = aListOfListOfElementsID.begin();
4040 for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j) {
4041 SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ];
4042 TListOfIDs& listOfIDs = *arraysIt;
4043 aGroup.length( listOfIDs.size() );
4044 TListOfIDs::iterator idIt = listOfIDs.begin();
4045 for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k ) {
4046 aGroup[ k ] = *idIt;
4050 TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
4055 //=======================================================================
4056 //function : MergeElements
4058 //=======================================================================
4060 void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
4064 TPythonDump aTPythonDump;
4065 aTPythonDump << this << ".MergeElements( [";
4067 ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
4069 for (int i = 0; i < GroupsOfElementsID.length(); i++) {
4070 const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
4071 aListOfListOfElementsID.push_back( list< int >() );
4072 list< int >& aListOfElemsID = aListOfListOfElementsID.back();
4073 for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
4074 CORBA::Long id = anElemsIDGroup[ j ];
4075 aListOfElemsID.push_back( id );
4077 if ( aListOfElemsID.size() < 2 )
4078 aListOfListOfElementsID.pop_back();
4079 if ( i > 0 ) aTPythonDump << ", ";
4080 aTPythonDump << anElemsIDGroup;
4083 ::SMESH_MeshEditor anEditor( myMesh );
4084 anEditor.MergeElements(aListOfListOfElementsID);
4085 myMesh->GetMeshDS()->Modified();
4086 myMesh->SetIsModified( true );
4088 aTPythonDump << "] )";
4091 //=======================================================================
4092 //function : MergeEqualElements
4094 //=======================================================================
4096 void SMESH_MeshEditor_i::MergeEqualElements()
4100 ::SMESH_MeshEditor anEditor( myMesh );
4101 anEditor.MergeEqualElements();
4103 TPythonDump() << this << ".MergeEqualElements()";
4106 //=============================================================================
4108 * Move the node to a given point
4110 //=============================================================================
4112 CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID,
4117 initData(/*deleteSearchers=*/false);
4119 const SMDS_MeshNode * node = GetMeshDS()->FindNode( NodeID );
4123 if ( theNodeSearcher )
4124 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4126 if ( myPreviewMode ) // make preview data
4128 // in a preview mesh, make edges linked to a node
4129 TPreviewMesh tmpMesh;
4130 TIDSortedElemSet linkedNodes;
4131 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4132 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4133 SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
4134 for ( ; nIt != linkedNodes.end(); ++nIt )
4136 SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
4137 tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
4141 tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
4142 // fill preview data
4143 ::SMESH_MeshEditor anEditor( & tmpMesh );
4144 storeResult( anEditor );
4146 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4147 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4149 GetMeshDS()->MoveNode(node, x, y, z);
4151 if ( !myPreviewMode )
4153 // Update Python script
4154 TPythonDump() << "isDone = " << this << ".MoveNode( "
4155 << NodeID << ", " << x << ", " << y << ", " << z << " )";
4156 myMesh->GetMeshDS()->Modified();
4157 myMesh->SetIsModified( true );
4163 //================================================================================
4165 * \brief Return ID of node closest to a given point
4167 //================================================================================
4169 CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
4173 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4175 if ( !theNodeSearcher ) {
4176 ::SMESH_MeshEditor anEditor( myMesh );
4177 theNodeSearcher = anEditor.GetNodeSearcher();
4180 if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
4181 return node->GetID();
4186 //================================================================================
4188 * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
4189 * move the node closest to the point to point's location and return ID of the node
4191 //================================================================================
4193 CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
4196 CORBA::Long theNodeID)
4198 // We keep theNodeSearcher until any mesh modification:
4199 // 1) initData() deletes theNodeSearcher at any edition,
4200 // 2) TSearchersDeleter - at any mesh compute event and mesh change
4202 initData(/*deleteSearchers=*/false);
4204 theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
4206 int nodeID = theNodeID;
4207 const SMDS_MeshNode* node = GetMeshDS()->FindNode( nodeID );
4208 if ( !node ) // preview moving node
4210 if ( !theNodeSearcher ) {
4211 ::SMESH_MeshEditor anEditor( myMesh );
4212 theNodeSearcher = anEditor.GetNodeSearcher();
4215 node = theNodeSearcher->FindClosestTo( p );
4218 nodeID = node->GetID();
4219 if ( myPreviewMode ) // make preview data
4221 // in a preview mesh, make edges linked to a node
4222 TPreviewMesh tmpMesh;
4223 TIDSortedElemSet linkedNodes;
4224 ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
4225 TIDSortedElemSet::iterator nIt = linkedNodes.begin();
4226 for ( ; nIt != linkedNodes.end(); ++nIt )
4228 SMDS_LinearEdge edge( node, cast2Node( *nIt ));
4229 tmpMesh.Copy( &edge );
4232 node = tmpMesh.GetMeshDS()->FindNode( nodeID );
4234 tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
4235 // fill preview data
4236 ::SMESH_MeshEditor anEditor( & tmpMesh );
4237 storeResult( anEditor );
4239 else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
4241 theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
4245 GetMeshDS()->MoveNode(node, x, y, z);
4249 if ( !myPreviewMode )
4251 TPythonDump() << "nodeID = " << this
4252 << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
4253 << ", " << nodeID << " )";
4255 myMesh->GetMeshDS()->Modified();
4256 myMesh->SetIsModified( true );
4262 //=======================================================================
4264 * Return elements of given type where the given point is IN or ON.
4266 * 'ALL' type means elements of any type excluding nodes
4268 //=======================================================================
4270 SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double x,
4273 SMESH::ElementType type)
4275 SMESH::long_array_var res = new SMESH::long_array;
4276 vector< const SMDS_MeshElement* > foundElems;
4278 theSearchersDeleter.Set( myMesh );
4279 if ( !theElementSearcher ) {
4280 ::SMESH_MeshEditor anEditor( myMesh );
4281 theElementSearcher = anEditor.GetElementSearcher();
4283 theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
4284 SMDSAbs_ElementType( type ),
4286 res->length( foundElems.size() );
4287 for ( int i = 0; i < foundElems.size(); ++i )
4288 res[i] = foundElems[i]->GetID();
4290 if ( !myPreviewMode ) // call from tui
4291 TPythonDump() << res << " = " << this << ".FindElementsByPoint( "
4300 //=======================================================================
4301 //function : GetPointState
4302 //purpose : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
4303 // TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
4304 //=======================================================================
4306 CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
4310 theSearchersDeleter.Set( myMesh );
4311 if ( !theElementSearcher ) {
4312 ::SMESH_MeshEditor anEditor( myMesh );
4313 theElementSearcher = anEditor.GetElementSearcher();
4315 return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
4318 //=======================================================================
4319 //function : convError
4321 //=======================================================================
4323 #define RETCASE(enm) case ::SMESH_MeshEditor::enm: return SMESH::SMESH_MeshEditor::enm;
4325 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
4329 RETCASE( SEW_BORDER1_NOT_FOUND );
4330 RETCASE( SEW_BORDER2_NOT_FOUND );
4331 RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
4332 RETCASE( SEW_BAD_SIDE_NODES );
4333 RETCASE( SEW_VOLUMES_TO_SPLIT );
4334 RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
4335 RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
4336 RETCASE( SEW_BAD_SIDE1_NODES );
4337 RETCASE( SEW_BAD_SIDE2_NODES );
4339 return SMESH::SMESH_MeshEditor::SEW_OK;
4342 //=======================================================================
4343 //function : SewFreeBorders
4345 //=======================================================================
4347 SMESH::SMESH_MeshEditor::Sew_Error
4348 SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
4349 CORBA::Long SecondNodeID1,
4350 CORBA::Long LastNodeID1,
4351 CORBA::Long FirstNodeID2,
4352 CORBA::Long SecondNodeID2,
4353 CORBA::Long LastNodeID2,
4354 CORBA::Boolean CreatePolygons,
4355 CORBA::Boolean CreatePolyedrs)
4359 SMESHDS_Mesh* aMesh = GetMeshDS();
4361 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4362 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4363 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4364 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4365 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4366 const SMDS_MeshNode* aSide2ThirdNode = aMesh->FindNode( LastNodeID2 );
4368 if (!aBorderFirstNode ||
4369 !aBorderSecondNode||
4371 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4372 if (!aSide2FirstNode ||
4373 !aSide2SecondNode ||
4375 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4377 TPythonDump() << "error = " << this << ".SewFreeBorders( "
4378 << FirstNodeID1 << ", "
4379 << SecondNodeID1 << ", "
4380 << LastNodeID1 << ", "
4381 << FirstNodeID2 << ", "
4382 << SecondNodeID2 << ", "
4383 << LastNodeID2 << ", "
4384 << CreatePolygons<< ", "
4385 << CreatePolyedrs<< " )";
4387 ::SMESH_MeshEditor anEditor( myMesh );
4388 SMESH::SMESH_MeshEditor::Sew_Error error =
4389 convError( anEditor.SewFreeBorder (aBorderFirstNode,
4399 storeResult(anEditor);
4401 myMesh->GetMeshDS()->Modified();
4402 myMesh->SetIsModified( true );
4408 //=======================================================================
4409 //function : SewConformFreeBorders
4411 //=======================================================================
4413 SMESH::SMESH_MeshEditor::Sew_Error
4414 SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
4415 CORBA::Long SecondNodeID1,
4416 CORBA::Long LastNodeID1,
4417 CORBA::Long FirstNodeID2,
4418 CORBA::Long SecondNodeID2)
4422 SMESHDS_Mesh* aMesh = GetMeshDS();
4424 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeID1 );
4425 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeID1 );
4426 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeID1 );
4427 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeID2 );
4428 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( SecondNodeID2 );
4429 const SMDS_MeshNode* aSide2ThirdNode = 0;
4431 if (!aBorderFirstNode ||
4432 !aBorderSecondNode||
4434 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4435 if (!aSide2FirstNode ||
4437 return SMESH::SMESH_MeshEditor::SEW_BORDER2_NOT_FOUND;
4439 TPythonDump() << "error = " << this << ".SewConformFreeBorders( "
4440 << FirstNodeID1 << ", "
4441 << SecondNodeID1 << ", "
4442 << LastNodeID1 << ", "
4443 << FirstNodeID2 << ", "
4444 << SecondNodeID2 << " )";
4446 ::SMESH_MeshEditor anEditor( myMesh );
4447 SMESH::SMESH_MeshEditor::Sew_Error error =
4448 convError( anEditor.SewFreeBorder (aBorderFirstNode,
4457 storeResult(anEditor);
4459 myMesh->GetMeshDS()->Modified();
4460 myMesh->SetIsModified( true );
4466 //=======================================================================
4467 //function : SewBorderToSide
4469 //=======================================================================
4471 SMESH::SMESH_MeshEditor::Sew_Error
4472 SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
4473 CORBA::Long SecondNodeIDOnFreeBorder,
4474 CORBA::Long LastNodeIDOnFreeBorder,
4475 CORBA::Long FirstNodeIDOnSide,
4476 CORBA::Long LastNodeIDOnSide,
4477 CORBA::Boolean CreatePolygons,
4478 CORBA::Boolean CreatePolyedrs)
4482 SMESHDS_Mesh* aMesh = GetMeshDS();
4484 const SMDS_MeshNode* aBorderFirstNode = aMesh->FindNode( FirstNodeIDOnFreeBorder );
4485 const SMDS_MeshNode* aBorderSecondNode = aMesh->FindNode( SecondNodeIDOnFreeBorder );
4486 const SMDS_MeshNode* aBorderLastNode = aMesh->FindNode( LastNodeIDOnFreeBorder );
4487 const SMDS_MeshNode* aSide2FirstNode = aMesh->FindNode( FirstNodeIDOnSide );
4488 const SMDS_MeshNode* aSide2SecondNode = aMesh->FindNode( LastNodeIDOnSide );
4489 const SMDS_MeshNode* aSide2ThirdNode = 0;
4491 if (!aBorderFirstNode ||
4492 !aBorderSecondNode||
4494 return SMESH::SMESH_MeshEditor::SEW_BORDER1_NOT_FOUND;
4495 if (!aSide2FirstNode ||
4497 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE_NODES;
4499 TPythonDump() << "error = " << this << ".SewBorderToSide( "
4500 << FirstNodeIDOnFreeBorder << ", "
4501 << SecondNodeIDOnFreeBorder << ", "
4502 << LastNodeIDOnFreeBorder << ", "
4503 << FirstNodeIDOnSide << ", "
4504 << LastNodeIDOnSide << ", "
4505 << CreatePolygons << ", "
4506 << CreatePolyedrs << ") ";
4508 ::SMESH_MeshEditor anEditor( myMesh );
4509 SMESH::SMESH_MeshEditor::Sew_Error error =
4510 convError( anEditor.SewFreeBorder (aBorderFirstNode,
4520 storeResult(anEditor);
4522 myMesh->GetMeshDS()->Modified();
4523 myMesh->SetIsModified( true );
4529 //=======================================================================
4530 //function : SewSideElements
4532 //=======================================================================
4534 SMESH::SMESH_MeshEditor::Sew_Error
4535 SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
4536 const SMESH::long_array& IDsOfSide2Elements,
4537 CORBA::Long NodeID1OfSide1ToMerge,
4538 CORBA::Long NodeID1OfSide2ToMerge,
4539 CORBA::Long NodeID2OfSide1ToMerge,
4540 CORBA::Long NodeID2OfSide2ToMerge)
4544 SMESHDS_Mesh* aMesh = GetMeshDS();
4546 const SMDS_MeshNode* aFirstNode1ToMerge = aMesh->FindNode( NodeID1OfSide1ToMerge );
4547 const SMDS_MeshNode* aFirstNode2ToMerge = aMesh->FindNode( NodeID1OfSide2ToMerge );
4548 const SMDS_MeshNode* aSecondNode1ToMerge = aMesh->FindNode( NodeID2OfSide1ToMerge );
4549 const SMDS_MeshNode* aSecondNode2ToMerge = aMesh->FindNode( NodeID2OfSide2ToMerge );
4551 if (!aFirstNode1ToMerge ||
4552 !aFirstNode2ToMerge )
4553 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE1_NODES;
4554 if (!aSecondNode1ToMerge||
4555 !aSecondNode2ToMerge)
4556 return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
4558 TIDSortedElemSet aSide1Elems, aSide2Elems;
4559 arrayToSet(IDsOfSide1Elements, aMesh, aSide1Elems);
4560 arrayToSet(IDsOfSide2Elements, aMesh, aSide2Elems);
4562 TPythonDump() << "error = " << this << ".SewSideElements( "
4563 << IDsOfSide1Elements << ", "
4564 << IDsOfSide2Elements << ", "
4565 << NodeID1OfSide1ToMerge << ", "
4566 << NodeID1OfSide2ToMerge << ", "
4567 << NodeID2OfSide1ToMerge << ", "
4568 << NodeID2OfSide2ToMerge << ")";
4570 ::SMESH_MeshEditor anEditor( myMesh );
4571 SMESH::SMESH_MeshEditor::Sew_Error error =
4572 convError( anEditor.SewSideElements (aSide1Elems, aSide2Elems,
4575 aSecondNode1ToMerge,
4576 aSecondNode2ToMerge));
4578 storeResult(anEditor);
4580 myMesh->GetMeshDS()->Modified();
4581 myMesh->SetIsModified( true );
4586 //================================================================================
4588 * \brief Set new nodes for given element
4589 * \param ide - element id
4590 * \param newIDs - new node ids
4591 * \retval CORBA::Boolean - true if result is OK
4593 //================================================================================
4595 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
4596 const SMESH::long_array& newIDs)
4600 const SMDS_MeshElement* elem = GetMeshDS()->FindElement(ide);
4601 if(!elem) return false;
4603 int nbn = newIDs.length();
4605 vector<const SMDS_MeshNode*> aNodes(nbn);
4608 const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(newIDs[i]);
4611 aNodes[nbn1] = aNode;
4614 TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
4615 << ide << ", " << newIDs << " )";
4617 MESSAGE("ChangeElementNodes");
4618 bool res = GetMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
4620 myMesh->GetMeshDS()->Modified();
4622 myMesh->SetIsModified( true );
4627 //================================================================================
4629 * \brief Update myLastCreated* or myPreviewData
4630 * \param anEditor - it contains last modification results
4632 //================================================================================
4634 void SMESH_MeshEditor_i::storeResult(::SMESH_MeshEditor& anEditor)
4636 if ( myPreviewMode ) { // --- MeshPreviewStruct filling ---
4638 list<int> aNodesConnectivity;
4639 typedef map<int, int> TNodesMap;
4642 TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( anEditor.GetMesh() );
4643 SMDSAbs_ElementType previewType = aPreviewMesh->myPreviewType;
4645 SMESHDS_Mesh* aMeshDS = anEditor.GetMeshDS();
4646 int nbEdges = aMeshDS->NbEdges();
4647 int nbFaces = aMeshDS->NbFaces();
4648 int nbVolum = aMeshDS->NbVolumes();
4649 switch ( previewType ) {
4650 case SMDSAbs_Edge : nbFaces = nbVolum = 0; break;
4651 case SMDSAbs_Face : nbEdges = nbVolum = 0; break;
4652 case SMDSAbs_Volume: nbEdges = nbFaces = 0; break;
4655 myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
4656 myPreviewData->elementTypes.length(nbEdges + nbFaces + nbVolum);
4658 SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator();
4660 while ( itMeshElems->more() ) {
4661 const SMDS_MeshElement* aMeshElem = itMeshElems->next();
4662 if ( previewType != SMDSAbs_All && aMeshElem->GetType() != previewType )
4665 SMDS_ElemIteratorPtr itElemNodes = aMeshElem->nodesIterator();
4666 while ( itElemNodes->more() ) {
4667 const SMDS_MeshNode* aMeshNode =
4668 static_cast<const SMDS_MeshNode*>( itElemNodes->next() );
4669 int aNodeID = aMeshNode->GetID();
4670 TNodesMap::iterator anIter = nodesMap.find(aNodeID);
4671 if ( anIter == nodesMap.end() ) {
4672 // filling the nodes coordinates
4673 myPreviewData->nodesXYZ[j].x = aMeshNode->X();
4674 myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
4675 myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
4676 anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
4679 aNodesConnectivity.push_back(anIter->second);
4682 // filling the elements types
4683 SMDSAbs_ElementType aType;
4685 /*if (aMeshElem->GetType() == SMDSAbs_Volume) {
4686 aType = SMDSAbs_Node;
4690 aType = aMeshElem->GetType();
4691 isPoly = aMeshElem->IsPoly();
4694 myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
4695 myPreviewData->elementTypes[i].isPoly = isPoly;
4696 myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
4700 myPreviewData->nodesXYZ.length( j );
4702 // filling the elements connectivities
4703 list<int>::iterator aConnIter = aNodesConnectivity.begin();
4704 myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
4705 for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
4706 myPreviewData->elementConnectivities[i] = *aConnIter;
4712 // append new nodes into myLastCreatedNodes
4713 const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedNodes();
4714 int j = myLastCreatedNodes->length();
4715 int newLen = j + aSeq.Length();
4716 myLastCreatedNodes->length( newLen );
4717 for(int i=0; j<newLen; i++,j++)
4718 myLastCreatedNodes[j] = aSeq.Value(i+1)->GetID();
4721 // append new elements into myLastCreatedElems
4722 const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedElems();
4723 int j = myLastCreatedElems->length();
4724 int newLen = j + aSeq.Length();
4725 myLastCreatedElems->length( newLen );
4726 for(int i=0; j<newLen; i++,j++)
4727 myLastCreatedElems[j] = aSeq.Value(i+1)->GetID();
4731 //================================================================================
4733 * Return data of mesh edition preview
4735 //================================================================================
4737 SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
4739 return myPreviewData._retn();
4742 //================================================================================
4744 * \brief Returns list of it's IDs of created nodes
4745 * \retval SMESH::long_array* - list of node ID
4747 //================================================================================
4749 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
4751 return myLastCreatedNodes._retn();
4754 //================================================================================
4756 * \brief Returns list of it's IDs of created elements
4757 * \retval SMESH::long_array* - list of elements' ID
4759 //================================================================================
4761 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
4763 return myLastCreatedElems._retn();
4766 //=======================================================================
4767 //function : ConvertToQuadratic
4769 //=======================================================================
4771 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
4773 ::SMESH_MeshEditor anEditor( myMesh );
4774 anEditor.ConvertToQuadratic(theForce3d);
4775 TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )";
4776 myMesh->GetMeshDS()->Modified();
4777 myMesh->SetIsModified( true );
4780 //=======================================================================
4781 //function : ConvertFromQuadratic
4783 //=======================================================================
4785 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
4787 ::SMESH_MeshEditor anEditor( myMesh );
4788 CORBA::Boolean isDone = anEditor.ConvertFromQuadratic();
4789 TPythonDump() << this << ".ConvertFromQuadratic()";
4790 myMesh->GetMeshDS()->Modified();
4792 myMesh->SetIsModified( true );
4795 //================================================================================
4797 * \brief Makes a part of the mesh quadratic
4799 //================================================================================
4801 void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean theForce3d,
4802 SMESH::SMESH_IDSource_ptr theObject)
4803 throw (SALOME::SALOME_Exception)
4805 Unexpect aCatch(SALOME_SalomeException);
4807 TIDSortedElemSet elems;
4808 if ( idSourceToSet( theObject, GetMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
4810 if ( elems.empty() )
4812 ConvertToQuadratic( theForce3d );
4814 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
4816 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
4820 ::SMESH_MeshEditor anEditor( myMesh );
4821 anEditor.ConvertToQuadratic(theForce3d, elems);
4824 myMesh->GetMeshDS()->Modified();
4825 myMesh->SetIsModified( true );
4827 pyDump << this << ".ConvertToQuadraticObject( "<<theForce3d<<", "<<theObject<<" )";
4830 //================================================================================
4832 * \brief Makes a part of the mesh linear
4834 //================================================================================
4836 void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
4837 throw (SALOME::SALOME_Exception)
4839 Unexpect aCatch(SALOME_SalomeException);
4841 TIDSortedElemSet elems;
4842 if ( idSourceToSet( theObject, GetMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
4844 if ( elems.empty() )
4846 ConvertFromQuadratic();
4848 else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
4850 THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
4854 ::SMESH_MeshEditor anEditor( myMesh );
4855 anEditor.ConvertFromQuadratic(elems);
4858 myMesh->GetMeshDS()->Modified();
4859 myMesh->SetIsModified( true );
4861 pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
4864 //=======================================================================
4865 //function : makeMesh
4866 //purpose : create a named imported mesh
4867 //=======================================================================
4869 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
4871 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
4872 SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
4873 SALOMEDS::Study_var study = gen->GetCurrentStudy();
4874 SALOMEDS::SObject_var meshSO = gen->ObjectToSObject( study, mesh );
4875 gen->SetName( meshSO, theMeshName, "Mesh" );
4876 gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
4878 return mesh._retn();
4881 //=======================================================================
4882 //function : DumpGroupsList
4884 //=======================================================================
4885 void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump & theDumpPython,
4886 const SMESH::ListOfGroups * theGroupList)
4888 bool isDumpGroupList = theGroupList && theGroupList->length() > 0;
4889 if(isDumpGroupList) {
4890 theDumpPython << theGroupList << " = ";
4894 //================================================================================
4896 \brief Generates the unique group name.
4897 \param thePrefix name prefix
4900 //================================================================================
4901 string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
4903 SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
4904 set<string> groupNames;
4906 // Get existing group names
4907 for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
4908 SMESH::SMESH_GroupBase_var aGroup = groups[i];
4909 if (CORBA::is_nil(aGroup))
4912 groupNames.insert(aGroup->GetName());
4916 string name = thePrefix;
4919 while (!groupNames.insert(name).second) {
4924 TCollection_AsciiString nbStr(index+1);
4925 name.resize( name.rfind('_')+1 );
4926 name += nbStr.ToCString();
4934 //================================================================================
4936 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
4937 \param theNodes - identifiers of nodes to be doubled
4938 \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
4939 nodes. If list of element identifiers is empty then nodes are doubled but
4940 they not assigned to elements
4941 \return TRUE if operation has been completed successfully, FALSE otherwise
4942 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
4944 //================================================================================
4946 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
4947 const SMESH::long_array& theModifiedElems )
4951 ::SMESH_MeshEditor aMeshEditor( myMesh );
4952 list< int > aListOfNodes;
4954 for ( i = 0, n = theNodes.length(); i < n; i++ )
4955 aListOfNodes.push_back( theNodes[ i ] );
4957 list< int > aListOfElems;
4958 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
4959 aListOfElems.push_back( theModifiedElems[ i ] );
4961 bool aResult = aMeshEditor.DoubleNodes( aListOfNodes, aListOfElems );
4963 myMesh->GetMeshDS()->Modified();
4964 storeResult( aMeshEditor) ;
4966 myMesh->SetIsModified( true );
4968 // Update Python script
4969 TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
4974 //================================================================================
4976 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
4977 This method provided for convenience works as DoubleNodes() described above.
4978 \param theNodeId - identifier of node to be doubled.
4979 \param theModifiedElems - identifiers of elements to be updated.
4980 \return TRUE if operation has been completed successfully, FALSE otherwise
4981 \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
4983 //================================================================================
4985 CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeId,
4986 const SMESH::long_array& theModifiedElems )
4988 SMESH::long_array_var aNodes = new SMESH::long_array;
4989 aNodes->length( 1 );
4990 aNodes[ 0 ] = theNodeId;
4992 TPythonDump pyDump; // suppress dump by the next line
4994 CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
4996 pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
5001 //================================================================================
5003 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5004 This method provided for convenience works as DoubleNodes() described above.
5005 \param theNodes - group of nodes to be doubled.
5006 \param theModifiedElems - group of elements to be updated.
5007 \return TRUE if operation has been completed successfully, FALSE otherwise
5008 \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
5010 //================================================================================
5012 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
5013 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5015 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5018 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5019 SMESH::long_array_var aModifiedElems;
5020 if ( !CORBA::is_nil( theModifiedElems ) )
5021 aModifiedElems = theModifiedElems->GetListOfID();
5024 aModifiedElems = new SMESH::long_array;
5025 aModifiedElems->length( 0 );
5028 TPythonDump pyDump; // suppress dump by the next line
5030 bool done = DoubleNodes( aNodes, aModifiedElems );
5032 pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
5038 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5039 * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
5040 * \param theNodes - group of nodes to be doubled.
5041 * \param theModifiedElems - group of elements to be updated.
5042 * \return a new group with newly created nodes
5043 * \sa DoubleNodeGroup()
5045 SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
5046 SMESH::SMESH_GroupBase_ptr theModifiedElems )
5048 if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
5051 SMESH::SMESH_Group_var aNewGroup;
5054 SMESH::long_array_var aNodes = theNodes->GetListOfID();
5055 SMESH::long_array_var aModifiedElems;
5056 if ( !CORBA::is_nil( theModifiedElems ) )
5057 aModifiedElems = theModifiedElems->GetListOfID();
5059 aModifiedElems = new SMESH::long_array;
5060 aModifiedElems->length( 0 );
5063 TPythonDump pyDump; // suppress dump by the next line
5065 bool aResult = DoubleNodes( aNodes, aModifiedElems );
5069 // Create group with newly created nodes
5070 SMESH::long_array_var anIds = GetLastCreatedNodes();
5071 if (anIds->length() > 0) {
5072 string anUnindexedName (theNodes->GetName());
5073 string aNewName = generateGroupName(anUnindexedName + "_double");
5074 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5075 aNewGroup->Add(anIds);
5079 pyDump << "createdNodes = " << this << ".DoubleNodeGroupNew( " << theNodes << ", "
5080 << theModifiedElems << " )";
5082 return aNewGroup._retn();
5085 //================================================================================
5087 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5088 This method provided for convenience works as DoubleNodes() described above.
5089 \param theNodes - list of groups of nodes to be doubled
5090 \param theModifiedElems - list of groups of elements to be updated.
5091 \return TRUE if operation has been completed successfully, FALSE otherwise
5092 \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
5094 //================================================================================
5096 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
5097 const SMESH::ListOfGroups& theModifiedElems )
5101 ::SMESH_MeshEditor aMeshEditor( myMesh );
5103 std::list< int > aNodes;
5105 for ( i = 0, n = theNodes.length(); i < n; i++ )
5107 SMESH::SMESH_GroupBase_var aGrp = theNodes[ i ];
5108 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() == SMESH::NODE )
5110 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5111 for ( j = 0, m = aCurr->length(); j < m; j++ )
5112 aNodes.push_back( aCurr[ j ] );
5116 std::list< int > anElems;
5117 for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
5119 SMESH::SMESH_GroupBase_var aGrp = theModifiedElems[ i ];
5120 if ( !CORBA::is_nil( aGrp ) && aGrp->GetType() != SMESH::NODE )
5122 SMESH::long_array_var aCurr = aGrp->GetListOfID();
5123 for ( j = 0, m = aCurr->length(); j < m; j++ )
5124 anElems.push_back( aCurr[ j ] );
5128 bool aResult = aMeshEditor.DoubleNodes( aNodes, anElems );
5130 storeResult( aMeshEditor) ;
5132 myMesh->GetMeshDS()->Modified();
5134 myMesh->SetIsModified( true );
5137 TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
5142 //================================================================================
5144 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
5145 * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
5146 * \param theNodes - group of nodes to be doubled.
5147 * \param theModifiedElems - group of elements to be updated.
5148 * \return a new group with newly created nodes
5149 * \sa DoubleNodeGroups()
5151 //================================================================================
5153 SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
5154 const SMESH::ListOfGroups& theModifiedElems )
5156 SMESH::SMESH_Group_var aNewGroup;
5158 TPythonDump pyDump; // suppress dump by the next line
5160 bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
5164 // Create group with newly created nodes
5165 SMESH::long_array_var anIds = GetLastCreatedNodes();
5166 if (anIds->length() > 0) {
5167 string anUnindexedName (theNodes[0]->GetName());
5168 string aNewName = generateGroupName(anUnindexedName + "_double");
5169 aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
5170 aNewGroup->Add(anIds);
5174 pyDump << "createdNodes = " << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
5175 << theModifiedElems << " )";
5177 return aNewGroup._retn();
5181 //================================================================================
5183 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5184 \param theElems - the list of elements (edges or faces) to be replicated
5185 The nodes for duplication could be found from these elements
5186 \param theNodesNot - list of nodes to NOT replicate
5187 \param theAffectedElems - the list of elements (cells and edges) to which the
5188 replicated nodes should be associated to.
5189 \return TRUE if operation has been completed successfully, FALSE otherwise
5190 \sa DoubleNodeGroup(), DoubleNodeGroups()
5192 //================================================================================
5194 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
5195 const SMESH::long_array& theNodesNot,
5196 const SMESH::long_array& theAffectedElems )
5201 ::SMESH_MeshEditor aMeshEditor( myMesh );
5203 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5204 TIDSortedElemSet anElems, aNodes, anAffected;
5205 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5206 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5207 arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
5209 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5211 storeResult( aMeshEditor) ;
5213 myMesh->GetMeshDS()->Modified();
5215 myMesh->SetIsModified( true );
5217 // Update Python script
5218 TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
5219 << theNodesNot << ", " << theAffectedElems << " )";
5223 //================================================================================
5225 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5226 \param theElems - the list of elements (edges or faces) to be replicated
5227 The nodes for duplication could be found from these elements
5228 \param theNodesNot - list of nodes to NOT replicate
5229 \param theShape - shape to detect affected elements (element which geometric center
5230 located on or inside shape).
5231 The replicated nodes should be associated to affected elements.
5232 \return TRUE if operation has been completed successfully, FALSE otherwise
5233 \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
5235 //================================================================================
5237 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
5238 const SMESH::long_array& theNodesNot,
5239 GEOM::GEOM_Object_ptr theShape )
5244 ::SMESH_MeshEditor aMeshEditor( myMesh );
5246 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5247 TIDSortedElemSet anElems, aNodes;
5248 arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
5249 arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
5251 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5252 bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5254 storeResult( aMeshEditor) ;
5256 myMesh->GetMeshDS()->Modified();
5258 myMesh->SetIsModified( true );
5260 // Update Python script
5261 TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
5262 << theNodesNot << ", " << theShape << " )";
5266 //================================================================================
5268 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5269 \param theElems - group of of elements (edges or faces) to be replicated
5270 \param theNodesNot - group of nodes not to replicated
5271 \param theAffectedElems - group of elements to which the replicated nodes
5272 should be associated to.
5273 \return TRUE if operation has been completed successfully, FALSE otherwise
5274 \sa DoubleNodes(), DoubleNodeGroups()
5276 //================================================================================
5278 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
5279 SMESH::SMESH_GroupBase_ptr theNodesNot,
5280 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5282 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5287 ::SMESH_MeshEditor aMeshEditor( myMesh );
5289 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5290 TIDSortedElemSet anElems, aNodes, anAffected;
5291 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5292 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5293 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5295 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5297 storeResult( aMeshEditor) ;
5299 myMesh->GetMeshDS()->Modified();
5301 myMesh->SetIsModified( true );
5303 // Update Python script
5304 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
5305 << theNodesNot << ", " << theAffectedElems << " )";
5310 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5311 * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
5312 * \param theElems - group of of elements (edges or faces) to be replicated
5313 * \param theNodesNot - group of nodes not to replicated
5314 * \param theAffectedElems - group of elements to which the replicated nodes
5315 * should be associated to.
5316 * \return a new group with newly created elements
5317 * \sa DoubleNodeElemGroup()
5319 SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
5320 SMESH::SMESH_GroupBase_ptr theNodesNot,
5321 SMESH::SMESH_GroupBase_ptr theAffectedElems)
5323 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5326 SMESH::SMESH_Group_var aNewGroup;
5330 ::SMESH_MeshEditor aMeshEditor( myMesh );
5332 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5333 TIDSortedElemSet anElems, aNodes, anAffected;
5334 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5335 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5336 idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
5339 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5341 storeResult( aMeshEditor) ;
5344 myMesh->SetIsModified( true );
5346 // Create group with newly created elements
5347 SMESH::long_array_var anIds = GetLastCreatedElems();
5348 if (anIds->length() > 0) {
5349 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5350 string anUnindexedName (theElems->GetName());
5351 string aNewName = generateGroupName(anUnindexedName + "_double");
5352 aNewGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5353 aNewGroup->Add(anIds);
5357 // Update Python script
5358 TPythonDump() << "createdElems = " << this << ".DoubleNodeElemGroupNew( " << theElems << ", "
5359 << theNodesNot << ", " << theAffectedElems << " )";
5360 return aNewGroup._retn();
5363 //================================================================================
5365 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5366 \param theElems - group of of elements (edges or faces) to be replicated
5367 \param theNodesNot - group of nodes not to replicated
5368 \param theShape - shape to detect affected elements (element which geometric center
5369 located on or inside shape).
5370 The replicated nodes should be associated to affected elements.
5371 \return TRUE if operation has been completed successfully, FALSE otherwise
5372 \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
5374 //================================================================================
5376 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
5377 SMESH::SMESH_GroupBase_ptr theNodesNot,
5378 GEOM::GEOM_Object_ptr theShape )
5381 if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
5386 ::SMESH_MeshEditor aMeshEditor( myMesh );
5388 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5389 TIDSortedElemSet anElems, aNodes, anAffected;
5390 idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
5391 idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
5393 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5394 bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5396 storeResult( aMeshEditor) ;
5398 myMesh->GetMeshDS()->Modified();
5400 myMesh->SetIsModified( true );
5402 // Update Python script
5403 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
5404 << theNodesNot << ", " << theShape << " )";
5408 //================================================================================
5410 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5411 This method provided for convenience works as DoubleNodes() described above.
5412 \param theElems - list of groups of elements (edges or faces) to be replicated
5413 \param theNodesNot - list of groups of nodes not to replicated
5414 \param theAffectedElems - group of elements to which the replicated nodes
5415 should be associated to.
5416 \return TRUE if operation has been completed successfully, FALSE otherwise
5417 \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
5419 //================================================================================
5421 static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
5422 SMESHDS_Mesh* theMeshDS,
5423 TIDSortedElemSet& theElemSet,
5424 const bool theIsNodeGrp)
5426 for ( int i = 0, n = theGrpList.length(); i < n; i++ )
5428 SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
5429 if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
5430 : aGrp->GetType() != SMESH::NODE ) )
5432 SMESH::long_array_var anIDs = aGrp->GetIDs();
5433 arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
5438 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
5439 const SMESH::ListOfGroups& theNodesNot,
5440 const SMESH::ListOfGroups& theAffectedElems)
5444 ::SMESH_MeshEditor aMeshEditor( myMesh );
5446 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5447 TIDSortedElemSet anElems, aNodes, anAffected;
5448 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5449 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5450 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5452 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5454 storeResult( aMeshEditor) ;
5456 myMesh->GetMeshDS()->Modified();
5458 myMesh->SetIsModified( true );
5460 // Update Python script
5461 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
5462 << &theNodesNot << ", " << &theAffectedElems << " )";
5466 //================================================================================
5468 * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5469 * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
5470 \param theElems - list of groups of elements (edges or faces) to be replicated
5471 \param theNodesNot - list of groups of nodes not to replicated
5472 \param theAffectedElems - group of elements to which the replicated nodes
5473 should be associated to.
5474 * \return a new group with newly created elements
5475 * \sa DoubleNodeElemGroups()
5477 //================================================================================
5479 SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
5480 const SMESH::ListOfGroups& theNodesNot,
5481 const SMESH::ListOfGroups& theAffectedElems)
5483 SMESH::SMESH_Group_var aNewGroup;
5487 ::SMESH_MeshEditor aMeshEditor( myMesh );
5489 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5490 TIDSortedElemSet anElems, aNodes, anAffected;
5491 listOfGroupToSet(theElems, aMeshDS, anElems, false );
5492 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5493 listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
5495 bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected );
5497 storeResult( aMeshEditor) ;
5499 myMesh->GetMeshDS()->Modified();
5501 myMesh->SetIsModified( true );
5503 // Create group with newly created elements
5504 SMESH::long_array_var anIds = GetLastCreatedElems();
5505 if (anIds->length() > 0) {
5506 SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
5507 string anUnindexedName (theElems[0]->GetName());
5508 string aNewName = generateGroupName(anUnindexedName + "_double");
5509 aNewGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
5510 aNewGroup->Add(anIds);
5514 // Update Python script
5515 TPythonDump() << "createdElems = " << this << ".DoubleNodeElemGroupsNew( " << &theElems << ", "
5516 << &theNodesNot << ", " << &theAffectedElems << " )";
5517 return aNewGroup._retn();
5520 //================================================================================
5522 \brief Creates a hole in a mesh by doubling the nodes of some particular elements
5523 This method provided for convenience works as DoubleNodes() described above.
5524 \param theElems - list of groups of elements (edges or faces) to be replicated
5525 \param theNodesNot - list of groups of nodes not to replicated
5526 \param theShape - shape to detect affected elements (element which geometric center
5527 located on or inside shape).
5528 The replicated nodes should be associated to affected elements.
5529 \return TRUE if operation has been completed successfully, FALSE otherwise
5530 \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
5532 //================================================================================
5535 SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
5536 const SMESH::ListOfGroups& theNodesNot,
5537 GEOM::GEOM_Object_ptr theShape )
5541 ::SMESH_MeshEditor aMeshEditor( myMesh );
5543 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5544 TIDSortedElemSet anElems, aNodes;
5545 listOfGroupToSet(theElems, aMeshDS, anElems,false );
5546 listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
5548 TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
5549 bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
5551 storeResult( aMeshEditor) ;
5553 myMesh->GetMeshDS()->Modified();
5555 myMesh->SetIsModified( true );
5557 // Update Python script
5558 TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
5559 << &theNodesNot << ", " << theShape << " )";
5563 //================================================================================
5565 \brief Generated skin mesh (containing 2D cells) from 3D mesh
5566 The created 2D mesh elements based on nodes of free faces of boundary volumes
5567 \return TRUE if operation has been completed successfully, FALSE otherwise
5569 //================================================================================
5571 CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
5575 ::SMESH_MeshEditor aMeshEditor( myMesh );
5576 bool aResult = aMeshEditor.Make2DMeshFrom3D();
5577 storeResult( aMeshEditor) ;
5578 myMesh->GetMeshDS()->Modified();
5579 TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
5583 //================================================================================
5585 * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
5586 * The list of groups must describe a partition of the mesh volumes.
5587 * The nodes of the internal faces at the boundaries of the groups are doubled.
5588 * In option, the internal faces are replaced by flat elements.
5589 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
5590 * The flat elements are stored in groups of volumes.
5591 * @param theDomains - list of groups of volumes
5592 * @param createJointElems - if TRUE, create the elements
5593 * @return TRUE if operation has been completed successfully, FALSE otherwise
5595 //================================================================================
5597 CORBA::Boolean SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
5598 CORBA::Boolean createJointElems )
5602 ::SMESH_MeshEditor aMeshEditor( myMesh );
5604 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5606 vector<TIDSortedElemSet> domains;
5609 for ( int i = 0, n = theDomains.length(); i < n; i++ )
5611 SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
5612 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
5614 TIDSortedElemSet domain;
5616 domains.push_back(domain);
5617 SMESH::long_array_var anIDs = aGrp->GetIDs();
5618 arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
5622 bool aResult = aMeshEditor.DoubleNodesOnGroupBoundaries( domains, createJointElems );
5623 // TODO publish the groups of flat elements in study
5625 storeResult( aMeshEditor) ;
5626 myMesh->GetMeshDS()->Modified();
5628 // Update Python script
5629 TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
5630 << ", " << createJointElems << " )";
5634 //================================================================================
5636 * \brief Double nodes on some external faces and create flat elements.
5637 * Flat elements are mainly used by some types of mechanic calculations.
5639 * Each group of the list must be constituted of faces.
5640 * Triangles are transformed in prisms, and quadrangles in hexahedrons.
5641 * @param theGroupsOfFaces - list of groups of faces
5642 * @return TRUE if operation has been completed successfully, FALSE otherwise
5644 //================================================================================
5646 CORBA::Boolean SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
5650 ::SMESH_MeshEditor aMeshEditor( myMesh );
5652 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5654 vector<TIDSortedElemSet> faceGroups;
5657 for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
5659 SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
5660 if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
5662 TIDSortedElemSet faceGroup;
5664 faceGroups.push_back(faceGroup);
5665 SMESH::long_array_var anIDs = aGrp->GetIDs();
5666 arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
5670 bool aResult = aMeshEditor.CreateFlatElementsOnFacesGroups( faceGroups );
5671 // TODO publish the groups of flat elements in study
5673 storeResult( aMeshEditor) ;
5674 myMesh->GetMeshDS()->Modified();
5676 // Update Python script
5677 TPythonDump() << "isDone = " << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
5681 // issue 20749 ===================================================================
5683 * \brief Creates missing boundary elements
5684 * \param elements - elements whose boundary is to be checked
5685 * \param dimension - defines type of boundary elements to create
5686 * \param groupName - a name of group to store created boundary elements in,
5687 * "" means not to create the group
5688 * \param meshName - a name of new mesh to store created boundary elements in,
5689 * "" means not to create the new mesh
5690 * \param toCopyElements - if true, the checked elements will be copied into the new mesh
5691 * \param toCopyExistingBondary - if true, not only new but also pre-existing
5692 * boundary elements will be copied into the new mesh
5693 * \param group - returns the create group, if any
5694 * \retval SMESH::SMESH_Mesh - the mesh where elements were added to
5696 // ================================================================================
5698 SMESH::SMESH_Mesh_ptr
5699 SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
5700 SMESH::Bnd_Dimension dim,
5701 const char* groupName,
5702 const char* meshName,
5703 CORBA::Boolean toCopyElements,
5704 CORBA::Boolean toCopyExistingBondary,
5705 SMESH::SMESH_Group_out group)
5709 if ( dim > SMESH::BND_1DFROM2D )
5710 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
5712 SMESHDS_Mesh* aMeshDS = GetMeshDS();
5714 SMESH::SMESH_Mesh_var mesh_var;
5715 SMESH::SMESH_Group_var group_var;
5719 TIDSortedElemSet elements;
5720 SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
5721 if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
5725 strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
5726 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
5728 SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
5730 // group of new boundary elements
5731 SMESH_Group* smesh_group = 0;
5732 if ( strlen(groupName) )
5734 group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
5735 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
5736 smesh_group = group_i->GetSmeshGroup();
5740 ::SMESH_MeshEditor aMeshEditor( myMesh );
5741 aMeshEditor.MakeBoundaryMesh( elements,
5742 ::SMESH_MeshEditor::Bnd_Dimension(dim),
5746 toCopyExistingBondary);
5747 storeResult( aMeshEditor );
5750 smesh_mesh->GetMeshDS()->Modified();
5753 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
5755 // result of MakeBoundaryMesh() is a tuple (mesh, group)
5756 if ( mesh_var->_is_nil() )
5757 pyDump << myMesh_i->_this() << ", ";
5759 pyDump << mesh_var << ", ";
5760 if ( group_var->_is_nil() )
5761 pyDump << "_NoneGroup = "; // assignment to None is forbiden
5763 pyDump << group_var << " = ";
5764 pyDump << this << ".MakeBoundaryMesh( "
5766 << "SMESH." << dimName[int(dim)] << ", "
5767 << "'" << groupName << "', "
5768 << "'" << meshName<< "', "
5769 << toCopyElements << ", "
5770 << toCopyExistingBondary << ")";
5772 group = group_var._retn();
5773 return mesh_var._retn();
5776 //================================================================================
5778 * \brief Creates missing boundary elements
5779 * \param dimension - defines type of boundary elements to create
5780 * \param groupName - a name of group to store all boundary elements in,
5781 * "" means not to create the group
5782 * \param meshName - a name of a new mesh, which is a copy of the initial
5783 * mesh + created boundary elements; "" means not to create the new mesh
5784 * \param toCopyAll - if true, the whole initial mesh will be copied into
5785 * the new mesh else only boundary elements will be copied into the new mesh
5786 * \param groups - optional groups of elements to make boundary around
5787 * \param mesh - returns the mesh where elements were added to
5788 * \param group - returns the created group, if any
5789 * \retval long - number of added boundary elements
5791 //================================================================================
5793 CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
5794 const char* groupName,
5795 const char* meshName,
5796 CORBA::Boolean toCopyAll,
5797 const SMESH::ListOfIDSources& groups,
5798 SMESH::SMESH_Mesh_out mesh,
5799 SMESH::SMESH_Group_out group)
5800 throw (SALOME::SALOME_Exception)
5802 Unexpect aCatch(SALOME_SalomeException);
5806 if ( dim > SMESH::BND_1DFROM2D )
5807 THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
5809 // check that groups belongs to to this mesh and is not this mesh
5810 const int nbGroups = groups.length();
5811 for ( int i = 0; i < nbGroups; ++i )
5813 SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
5814 if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
5815 THROW_SALOME_CORBA_EXCEPTION("group does not belong to this mesh", SALOME::BAD_PARAM);
5816 if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
5817 THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
5823 SMESH::SMESH_Mesh_var mesh_var;
5824 SMESH::SMESH_Group_var group_var;
5827 mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
5828 const bool toCopyMesh = ( strlen( meshName ) > 0 );
5832 mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
5834 /*toCopyGroups=*/false,
5835 /*toKeepIDs=*/true);
5837 mesh_var = makeMesh(meshName);
5839 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
5840 SMESH_Mesh* tgtMesh = &mesh_i->GetImpl();
5843 SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
5844 SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
5846 // group of boundary elements
5847 SMESH_Group* smesh_group = 0;
5848 SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
5849 if ( strlen(groupName) )
5851 SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
5852 group_var = mesh_i->CreateGroup( groupType, groupName );
5853 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
5854 smesh_group = group_i->GetSmeshGroup();
5857 TIDSortedElemSet elements;
5861 for ( int i = 0; i < nbGroups; ++i )
5864 if ( idSourceToSet( groups[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/false ))
5866 SMESH::Bnd_Dimension bdim =
5867 ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
5868 ::SMESH_MeshEditor aMeshEditor( srcMesh );
5869 nbAdded += aMeshEditor.MakeBoundaryMesh( elements,
5870 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
5873 /*toCopyElements=*/false,
5874 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
5875 /*toAddExistingBondary=*/true,
5876 /*aroundElements=*/true);
5877 storeResult( aMeshEditor );
5883 ::SMESH_MeshEditor aMeshEditor( srcMesh );
5884 nbAdded += aMeshEditor.MakeBoundaryMesh( elements,
5885 ::SMESH_MeshEditor::Bnd_Dimension(dim),
5888 /*toCopyElements=*/false,
5889 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
5890 /*toAddExistingBondary=*/true);
5891 storeResult( aMeshEditor );
5893 tgtMesh->GetMeshDS()->Modified();
5895 const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
5897 // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
5898 pyDump << "nbAdded, ";
5899 if ( mesh_var->_is_nil() )
5900 pyDump << myMesh_i->_this() << ", ";
5902 pyDump << mesh_var << ", ";
5903 if ( group_var->_is_nil() )
5904 pyDump << "_NoneGroup = "; // assignment to None is forbiden
5906 pyDump << group_var << " = ";
5907 pyDump << this << ".MakeBoundaryElements( "
5908 << "SMESH." << dimName[int(dim)] << ", "
5909 << "'" << groupName << "', "
5910 << "'" << meshName<< "', "
5911 << toCopyAll << ", "
5914 mesh = mesh_var._retn();
5915 group = group_var._retn();